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