001
014
015 package com.liferay.portlet.journal.service.impl;
016
017 import com.liferay.portal.kernel.dao.orm.QueryUtil;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.util.CharPool;
023 import com.liferay.portal.kernel.util.LocaleUtil;
024 import com.liferay.portal.kernel.util.OrderByComparator;
025 import com.liferay.portal.kernel.util.StringPool;
026 import com.liferay.portal.kernel.util.StringUtil;
027 import com.liferay.portal.kernel.util.Validator;
028 import com.liferay.portal.kernel.xml.Document;
029 import com.liferay.portal.kernel.xml.Element;
030 import com.liferay.portal.kernel.xml.SAXReaderUtil;
031 import com.liferay.portal.model.Group;
032 import com.liferay.portal.model.ResourceConstants;
033 import com.liferay.portal.model.User;
034 import com.liferay.portal.service.ServiceContext;
035 import com.liferay.portal.util.PortalUtil;
036 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
037 import com.liferay.portlet.journal.DuplicateStructureElementException;
038 import com.liferay.portlet.journal.DuplicateStructureIdException;
039 import com.liferay.portlet.journal.NoSuchArticleException;
040 import com.liferay.portlet.journal.NoSuchStructureException;
041 import com.liferay.portlet.journal.RequiredStructureException;
042 import com.liferay.portlet.journal.StructureIdException;
043 import com.liferay.portlet.journal.StructureInheritanceException;
044 import com.liferay.portlet.journal.StructureNameException;
045 import com.liferay.portlet.journal.StructureXsdException;
046 import com.liferay.portlet.journal.model.JournalArticle;
047 import com.liferay.portlet.journal.model.JournalArticleConstants;
048 import com.liferay.portlet.journal.model.JournalStructure;
049 import com.liferay.portlet.journal.model.JournalStructureConstants;
050 import com.liferay.portlet.journal.service.base.JournalStructureLocalServiceBaseImpl;
051 import com.liferay.portlet.journal.util.JournalUtil;
052 import com.liferay.portlet.journal.util.comparator.StructurePKComparator;
053
054 import java.util.ArrayList;
055 import java.util.Date;
056 import java.util.HashSet;
057 import java.util.List;
058 import java.util.Locale;
059 import java.util.Map;
060 import java.util.Set;
061
062
066 public class JournalStructureLocalServiceImpl
067 extends JournalStructureLocalServiceBaseImpl {
068
069 public JournalStructure addStructure(
070 long userId, long groupId, String structureId,
071 boolean autoStructureId, String parentStructureId,
072 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
073 String xsd, ServiceContext serviceContext)
074 throws PortalException, SystemException {
075
076
077
078 User user = userPersistence.findByPrimaryKey(userId);
079 structureId = structureId.trim().toUpperCase();
080 Date now = new Date();
081
082 try {
083 xsd = JournalUtil.validateXSD(xsd);
084 xsd = DDMXMLUtil.formatXML(xsd);
085 }
086 catch (Exception e) {
087 throw new StructureXsdException();
088 }
089
090 if (autoStructureId) {
091 structureId = String.valueOf(counterLocalService.increment());
092 }
093
094 validate(
095 groupId, structureId, autoStructureId, parentStructureId, nameMap,
096 xsd);
097
098 long id = counterLocalService.increment();
099
100 JournalStructure structure = journalStructurePersistence.create(id);
101
102 structure.setUuid(serviceContext.getUuid());
103 structure.setGroupId(groupId);
104 structure.setCompanyId(user.getCompanyId());
105 structure.setUserId(user.getUserId());
106 structure.setUserName(user.getFullName());
107 structure.setCreateDate(serviceContext.getCreateDate(now));
108 structure.setModifiedDate(serviceContext.getModifiedDate(now));
109 structure.setStructureId(structureId);
110 structure.setParentStructureId(parentStructureId);
111 structure.setNameMap(nameMap);
112 structure.setDescriptionMap(descriptionMap);
113 structure.setXsd(xsd);
114 structure.setExpandoBridgeAttributes(serviceContext);
115
116 journalStructurePersistence.update(structure);
117
118
119
120 if (serviceContext.isAddGroupPermissions() ||
121 serviceContext.isAddGuestPermissions()) {
122
123 addStructureResources(
124 structure, serviceContext.isAddGroupPermissions(),
125 serviceContext.isAddGuestPermissions());
126 }
127 else {
128 addStructureResources(
129 structure, serviceContext.getGroupPermissions(),
130 serviceContext.getGuestPermissions());
131 }
132
133 return structure;
134 }
135
136 public void addStructureResources(
137 JournalStructure structure, boolean addGroupPermissions,
138 boolean addGuestPermissions)
139 throws PortalException, SystemException {
140
141 resourceLocalService.addResources(
142 structure.getCompanyId(), structure.getGroupId(),
143 structure.getUserId(), JournalStructure.class.getName(),
144 structure.getId(), false, addGroupPermissions, addGuestPermissions);
145 }
146
147 public void addStructureResources(
148 JournalStructure structure, String[] groupPermissions,
149 String[] guestPermissions)
150 throws PortalException, SystemException {
151
152 resourceLocalService.addModelResources(
153 structure.getCompanyId(), structure.getGroupId(),
154 structure.getUserId(), JournalStructure.class.getName(),
155 structure.getId(), groupPermissions, guestPermissions);
156 }
157
158 public void addStructureResources(
159 long groupId, String structureId, boolean addGroupPermissions,
160 boolean addGuestPermissions)
161 throws PortalException, SystemException {
162
163 JournalStructure structure = journalStructurePersistence.findByG_S(
164 groupId, structureId);
165
166 addStructureResources(
167 structure, addGroupPermissions, addGuestPermissions);
168 }
169
170 public void addStructureResources(
171 long groupId, String structureId, String[] groupPermissions,
172 String[] guestPermissions)
173 throws PortalException, SystemException {
174
175 JournalStructure structure = journalStructurePersistence.findByG_S(
176 groupId, structureId);
177
178 addStructureResources(structure, groupPermissions, guestPermissions);
179 }
180
181 public void checkNewLine(long groupId, String structureId)
182 throws PortalException, SystemException {
183
184 JournalStructure structure = journalStructurePersistence.findByG_S(
185 groupId, structureId);
186
187 String xsd = structure.getXsd();
188
189 if ((xsd != null) && xsd.contains("\\n")) {
190 xsd = StringUtil.replace(
191 xsd, new String[] {"\\n", "\\r"}, new String[] {"\n", "\r"});
192
193 structure.setXsd(xsd);
194
195 journalStructurePersistence.update(structure);
196 }
197 }
198
199 public JournalStructure copyStructure(
200 long userId, long groupId, String oldStructureId,
201 String newStructureId, boolean autoStructureId)
202 throws PortalException, SystemException {
203
204
205
206 User user = userPersistence.findByPrimaryKey(userId);
207 oldStructureId = oldStructureId.trim().toUpperCase();
208 newStructureId = newStructureId.trim().toUpperCase();
209 Date now = new Date();
210
211 JournalStructure oldStructure = journalStructurePersistence.findByG_S(
212 groupId, oldStructureId);
213
214 if (autoStructureId) {
215 newStructureId = String.valueOf(counterLocalService.increment());
216 }
217 else {
218 validateStructureId(newStructureId);
219
220 JournalStructure newStructure =
221 journalStructurePersistence.fetchByG_S(groupId, newStructureId);
222
223 if (newStructure != null) {
224 throw new DuplicateStructureIdException();
225 }
226 }
227
228 long id = counterLocalService.increment();
229
230 JournalStructure newStructure = journalStructurePersistence.create(id);
231
232 newStructure.setGroupId(groupId);
233 newStructure.setCompanyId(user.getCompanyId());
234 newStructure.setUserId(user.getUserId());
235 newStructure.setUserName(user.getFullName());
236 newStructure.setCreateDate(now);
237 newStructure.setModifiedDate(now);
238 newStructure.setStructureId(newStructureId);
239 newStructure.setNameMap(oldStructure.getNameMap());
240 newStructure.setDescriptionMap(oldStructure.getDescriptionMap());
241 newStructure.setXsd(oldStructure.getXsd());
242 newStructure.setExpandoBridgeAttributes(oldStructure);
243
244 journalStructurePersistence.update(newStructure);
245
246
247
248 addStructureResources(newStructure, true, true);
249
250 return newStructure;
251 }
252
253 public void deleteStructure(JournalStructure structure)
254 throws PortalException, SystemException {
255
256 Group companyGroup = groupLocalService.getCompanyGroup(
257 structure.getCompanyId());
258
259 if (structure.getGroupId() == companyGroup.getGroupId()) {
260 if (journalArticlePersistence.countByStructureId(
261 structure.getStructureId()) > 0) {
262
263 throw new RequiredStructureException(
264 RequiredStructureException.REFERENCED_WEB_CONTENT);
265 }
266
267 if (journalStructurePersistence.countByParentStructureId(
268 structure.getStructureId()) > 0) {
269
270 throw new RequiredStructureException(
271 RequiredStructureException.REFERENCED_STRUCTURE);
272 }
273
274 if (journalTemplatePersistence.countByStructureId(
275 structure.getStructureId()) > 0) {
276
277 throw new RequiredStructureException(
278 RequiredStructureException.REFERENCED_TEMPLATE);
279 }
280 }
281 else {
282 if (journalArticlePersistence.countByG_C_S(
283 structure.getGroupId(),
284 JournalArticleConstants.CLASSNAME_ID_DEFAULT,
285 structure.getStructureId()) > 0) {
286
287 throw new RequiredStructureException(
288 RequiredStructureException.REFERENCED_WEB_CONTENT);
289 }
290
291 if (journalStructurePersistence.countByG_P(
292 structure.getGroupId(), structure.getStructureId()) > 0) {
293
294 throw new RequiredStructureException(
295 RequiredStructureException.REFERENCED_STRUCTURE);
296 }
297
298 if (journalTemplatePersistence.countByG_S(
299 structure.getGroupId(), structure.getStructureId()) > 0) {
300
301 throw new RequiredStructureException(
302 RequiredStructureException.REFERENCED_TEMPLATE);
303 }
304 }
305
306
307
308 webDAVPropsLocalService.deleteWebDAVProps(
309 JournalStructure.class.getName(), structure.getId());
310
311
312
313 expandoValueLocalService.deleteValues(
314 JournalStructure.class.getName(), structure.getId());
315
316
317
318 resourceLocalService.deleteResource(
319 structure.getCompanyId(), JournalStructure.class.getName(),
320 ResourceConstants.SCOPE_INDIVIDUAL, structure.getId());
321
322
323
324 try {
325 long classNameId = PortalUtil.getClassNameId(
326 JournalStructure.class.getName());
327
328 List<JournalArticle> articles =
329 journalArticlePersistence.findByG_C_C(
330 structure.getGroupId(), classNameId, structure.getId());
331
332 for (JournalArticle article : articles) {
333 journalArticleLocalService.deleteArticle(article, null, null);
334 }
335 }
336 catch (NoSuchArticleException nsae) {
337 }
338
339
340
341 journalStructurePersistence.remove(structure);
342 }
343
344 public void deleteStructure(long groupId, String structureId)
345 throws PortalException, SystemException {
346
347 structureId = structureId.trim().toUpperCase();
348
349 JournalStructure structure = journalStructurePersistence.findByG_S(
350 groupId, structureId);
351
352 deleteStructure(structure);
353 }
354
355 public void deleteStructures(long groupId)
356 throws PortalException, SystemException {
357
358 List<JournalStructure> structures =
359 journalStructurePersistence.findByGroupId(
360 groupId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
361 new StructurePKComparator());
362
363 for (JournalStructure structure : structures) {
364 deleteStructure(structure);
365 }
366 }
367
368 public JournalStructure getStructure(long id)
369 throws PortalException, SystemException {
370
371 return journalStructurePersistence.findByPrimaryKey(id);
372 }
373
374 public JournalStructure getStructure(long groupId, String structureId)
375 throws PortalException, SystemException {
376
377 return getStructure(groupId, structureId, false);
378 }
379
380 public JournalStructure getStructure(
381 long groupId, String structureId, boolean includeGlobalStructures)
382 throws PortalException, SystemException {
383
384 structureId = structureId.trim().toUpperCase();
385
386 if (groupId == 0) {
387 _log.error(
388 "No group ID was passed for " + structureId + ". Group ID is " +
389 "required since 4.2.0. Please update all custom code and " +
390 "data that references structures without a group ID.");
391
392 List<JournalStructure> structures =
393 journalStructurePersistence.findByStructureId(structureId);
394
395 if (!structures.isEmpty()) {
396 return structures.get(0);
397 }
398
399 throw new NoSuchStructureException(
400 "No JournalStructure exists with the structure ID " +
401 structureId);
402 }
403
404 JournalStructure structure = journalStructurePersistence.fetchByG_S(
405 groupId, structureId);
406
407 if (structure != null) {
408 return structure;
409 }
410
411 if (!includeGlobalStructures) {
412 throw new NoSuchStructureException(
413 "No JournalStructure exists with the structure ID " +
414 structureId);
415 }
416
417 Group group = groupPersistence.findByPrimaryKey(groupId);
418
419 Group companyGroup = groupLocalService.getCompanyGroup(
420 group.getCompanyId());
421
422 return journalStructurePersistence.findByG_S(
423 companyGroup.getGroupId(), structureId);
424 }
425
426 public List<JournalStructure> getStructures() throws SystemException {
427 return journalStructurePersistence.findAll();
428 }
429
430 public List<JournalStructure> getStructures(long groupId)
431 throws SystemException {
432
433 return journalStructurePersistence.findByGroupId(groupId);
434 }
435
436 public List<JournalStructure> getStructures(
437 long groupId, int start, int end)
438 throws SystemException {
439
440 return journalStructurePersistence.findByGroupId(groupId, start, end);
441 }
442
443 public int getStructuresCount(long groupId) throws SystemException {
444 return journalStructurePersistence.countByGroupId(groupId);
445 }
446
447 public List<JournalStructure> search(
448 long companyId, long[] groupIds, String keywords, int start,
449 int end, OrderByComparator obc)
450 throws SystemException {
451
452 return journalStructureFinder.findByKeywords(
453 companyId, groupIds, keywords, start, end, obc);
454 }
455
456 public List<JournalStructure> search(
457 long companyId, long[] groupIds, String structureId, String name,
458 String description, boolean andOperator, int start, int end,
459 OrderByComparator obc)
460 throws SystemException {
461
462 return journalStructureFinder.findByC_G_S_N_D(
463 companyId, groupIds, structureId, name, description, andOperator,
464 start, end, obc);
465 }
466
467 public int searchCount(long companyId, long[] groupIds, String keywords)
468 throws SystemException {
469
470 return journalStructureFinder.countByKeywords(
471 companyId, groupIds, keywords);
472 }
473
474 public int searchCount(
475 long companyId, long[] groupIds, String structureId, String name,
476 String description, boolean andOperator)
477 throws SystemException {
478
479 return journalStructureFinder.countByC_G_S_N_D(
480 companyId, groupIds, structureId, name, description, andOperator);
481 }
482
483 public JournalStructure updateStructure(
484 long groupId, String structureId, String parentStructureId,
485 Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
486 String xsd, ServiceContext serviceContext)
487 throws PortalException, SystemException {
488
489 structureId = structureId.trim().toUpperCase();
490
491 try {
492 xsd = JournalUtil.validateXSD(xsd);
493 xsd = DDMXMLUtil.formatXML(xsd);
494 }
495 catch (Exception e) {
496 throw new StructureXsdException();
497 }
498
499 validateParentStructureId(groupId, structureId, parentStructureId);
500 validate(groupId, parentStructureId, nameMap, xsd);
501
502 JournalStructure structure = journalStructurePersistence.findByG_S(
503 groupId, structureId);
504
505 structure.setModifiedDate(serviceContext.getModifiedDate(null));
506 structure.setParentStructureId(parentStructureId);
507 structure.setNameMap(nameMap);
508 structure.setDescriptionMap(descriptionMap);
509 structure.setXsd(xsd);
510 structure.setExpandoBridgeAttributes(serviceContext);
511
512 journalStructurePersistence.update(structure);
513
514 return structure;
515 }
516
517 protected void appendParentStructureElements(
518 long groupId, String parentStructureId, List<Element> elements)
519 throws Exception {
520
521 if (Validator.isNull(parentStructureId)) {
522 return;
523 }
524
525 JournalStructure parentStructure = getParentStructure(
526 groupId, parentStructureId);
527
528 appendParentStructureElements(
529 groupId, parentStructure.getParentStructureId(), elements);
530
531 Document document = SAXReaderUtil.read(parentStructure.getXsd());
532
533 Element rootElement = document.getRootElement();
534
535 elements.addAll(rootElement.elements());
536 }
537
538 protected JournalStructure getParentStructure(
539 long groupId, String parentStructureId)
540 throws PortalException, SystemException {
541
542 JournalStructure parentStructure =
543 journalStructurePersistence.fetchByG_S(groupId, parentStructureId);
544
545 if (parentStructure != null) {
546 return parentStructure;
547 }
548
549 Group group = groupPersistence.findByPrimaryKey(groupId);
550
551 Group companyGroup = groupLocalService.getCompanyGroup(
552 group.getCompanyId());
553
554 if (groupId != companyGroup.getGroupId()) {
555 parentStructure = journalStructurePersistence.findByG_S(
556 companyGroup.getGroupId(), parentStructureId);
557 }
558
559 return parentStructure;
560 }
561
562 protected void validate(List<Element> elements, Set<String> elNames)
563 throws PortalException {
564
565 for (Element element : elements) {
566 if (element.getName().equals("meta-data")) {
567 continue;
568 }
569
570 String elName = element.attributeValue("name", StringPool.BLANK);
571 String elType = element.attributeValue("type", StringPool.BLANK);
572
573 if (Validator.isNull(elName) ||
574 elName.startsWith(JournalStructureConstants.RESERVED)) {
575
576 throw new StructureXsdException();
577 }
578 else {
579 String completePath = elName;
580
581 Element parentElement = element.getParent();
582
583 while (!parentElement.isRootElement()) {
584 completePath =
585 parentElement.attributeValue("name", StringPool.BLANK) +
586 StringPool.SLASH + completePath;
587
588 parentElement = parentElement.getParent();
589 }
590
591 String elNameLowerCase = completePath.toLowerCase();
592
593 if (elNames.contains(elNameLowerCase)) {
594 throw new DuplicateStructureElementException();
595 }
596 else {
597 elNames.add(elNameLowerCase);
598 }
599 }
600
601 if (Validator.isNull(elType)) {
602 throw new StructureXsdException();
603 }
604
605 validate(element.elements(), elNames);
606 }
607 }
608
609 protected void validate(
610 long groupId, String structureId, boolean autoStructureId,
611 String parentStructureId, Map<Locale, String> nameMap, String xsd)
612 throws PortalException, SystemException {
613
614 if (!autoStructureId) {
615 validateStructureId(structureId);
616
617 JournalStructure structure = journalStructurePersistence.fetchByG_S(
618 groupId, structureId);
619
620 if (structure != null) {
621 throw new DuplicateStructureIdException();
622 }
623 }
624
625 validateParentStructureId(groupId, structureId, parentStructureId);
626 validate(groupId, parentStructureId, nameMap, xsd);
627 }
628
629 protected void validate(
630 long groupId, String parentStructureId, Map<Locale, String> nameMap,
631 String xsd)
632 throws PortalException {
633
634 Locale locale = LocaleUtil.getDefault();
635
636 if (nameMap.isEmpty() || Validator.isNull(nameMap.get(locale))) {
637 throw new StructureNameException();
638 }
639
640 if (Validator.isNull(xsd)) {
641 throw new StructureXsdException();
642 }
643 else {
644 try {
645 List<Element> elements = new ArrayList<Element>();
646
647 appendParentStructureElements(
648 groupId, parentStructureId, elements);
649
650 Document document = SAXReaderUtil.read(xsd);
651
652 Element rootElement = document.getRootElement();
653
654 if (rootElement.elements().isEmpty()) {
655 throw new StructureXsdException();
656 }
657
658 elements.addAll(rootElement.elements());
659
660 Set<String> elNames = new HashSet<String>();
661
662 validate(elements, elNames);
663 }
664 catch (DuplicateStructureElementException dsee) {
665 throw dsee;
666 }
667 catch (StructureXsdException sxe) {
668 throw sxe;
669 }
670 catch (Exception e) {
671 throw new StructureXsdException();
672 }
673 }
674 }
675
676 protected void validateParentStructureId(
677 long groupId, String structureId, String parentStructureId)
678 throws PortalException, SystemException {
679
680 if (Validator.isNull(parentStructureId)) {
681 return;
682 }
683
684 if (parentStructureId.equals(structureId)) {
685 throw new StructureInheritanceException();
686 }
687
688 JournalStructure parentStructure = getParentStructure(
689 groupId, parentStructureId);
690
691 while (parentStructure != null) {
692 if ((parentStructure != null) &&
693 (parentStructure.getStructureId().equals(structureId) ||
694 parentStructure.getParentStructureId().equals(structureId))) {
695
696 throw new StructureInheritanceException();
697 }
698
699 try {
700 parentStructure = getParentStructure(
701 groupId, parentStructure.getParentStructureId());
702 }
703 catch (NoSuchStructureException nsse) {
704 break;
705 }
706 }
707 }
708
709 protected void validateStructureId(String structureId)
710 throws PortalException {
711
712 if (Validator.isNull(structureId) ||
713 Validator.isNumber(structureId) ||
714 (structureId.indexOf(CharPool.SPACE) != -1)) {
715
716 throw new StructureIdException();
717 }
718 }
719
720 private static Log _log = LogFactoryUtil.getLog(
721 JournalStructureLocalServiceImpl.class);
722
723 }