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