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