1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   * 
13   */
14  
15  package com.liferay.portlet.journal.service.impl;
16  
17  import com.liferay.portal.PortalException;
18  import com.liferay.portal.SystemException;
19  import com.liferay.portal.kernel.log.Log;
20  import com.liferay.portal.kernel.log.LogFactoryUtil;
21  import com.liferay.portal.kernel.util.CharPool;
22  import com.liferay.portal.kernel.util.OrderByComparator;
23  import com.liferay.portal.kernel.util.StringPool;
24  import com.liferay.portal.kernel.util.StringUtil;
25  import com.liferay.portal.kernel.util.Validator;
26  import com.liferay.portal.kernel.xml.Document;
27  import com.liferay.portal.kernel.xml.Element;
28  import com.liferay.portal.kernel.xml.SAXReaderUtil;
29  import com.liferay.portal.model.ResourceConstants;
30  import com.liferay.portal.model.User;
31  import com.liferay.portal.util.PortalUtil;
32  import com.liferay.portlet.journal.DuplicateStructureIdException;
33  import com.liferay.portlet.journal.NoSuchStructureException;
34  import com.liferay.portlet.journal.RequiredStructureException;
35  import com.liferay.portlet.journal.StructureDescriptionException;
36  import com.liferay.portlet.journal.StructureIdException;
37  import com.liferay.portlet.journal.StructureNameException;
38  import com.liferay.portlet.journal.StructureXsdException;
39  import com.liferay.portlet.journal.model.JournalStructure;
40  import com.liferay.portlet.journal.model.impl.JournalStructureImpl;
41  import com.liferay.portlet.journal.service.base.JournalStructureLocalServiceBaseImpl;
42  import com.liferay.portlet.journal.util.JournalUtil;
43  
44  import java.util.Date;
45  import java.util.HashSet;
46  import java.util.List;
47  import java.util.Set;
48  
49  /**
50   * <a href="JournalStructureLocalServiceImpl.java.html"><b><i>View Source</i>
51   * </b></a>
52   *
53   * @author Brian Wing Shun Chan
54   */
55  public class JournalStructureLocalServiceImpl
56      extends JournalStructureLocalServiceBaseImpl {
57  
58      public JournalStructure addStructure(
59              long userId, String structureId, boolean autoStructureId, long plid,
60              String name, String description, String xsd,
61              boolean addCommunityPermissions, boolean addGuestPermissions)
62          throws PortalException, SystemException {
63  
64          return addStructure(
65              null, userId, structureId, autoStructureId, plid, name, description,
66              xsd, Boolean.valueOf(addCommunityPermissions),
67              Boolean.valueOf(addGuestPermissions), null, null);
68      }
69  
70      public JournalStructure addStructure(
71              String uuid, long userId, String structureId,
72              boolean autoStructureId, long plid, String name, String description,
73              String xsd, boolean addCommunityPermissions,
74              boolean addGuestPermissions)
75          throws PortalException, SystemException {
76  
77          return addStructure(
78              uuid, userId, structureId, autoStructureId, plid, name, description,
79              xsd, Boolean.valueOf(addCommunityPermissions),
80              Boolean.valueOf(addGuestPermissions), null, null);
81      }
82  
83      public JournalStructure addStructure(
84              long userId, String structureId, boolean autoStructureId, long plid,
85              String name, String description, String xsd,
86              String[] communityPermissions, String[] guestPermissions)
87          throws PortalException, SystemException {
88  
89          return addStructure(
90              null, userId, structureId, autoStructureId, plid, name, description,
91              xsd, null, null, communityPermissions, guestPermissions);
92      }
93  
94      public JournalStructure addStructure(
95              String uuid, long userId, String structureId,
96              boolean autoStructureId, long plid, String name,
97              String description, String xsd, Boolean addCommunityPermissions,
98              Boolean addGuestPermissions, String[] communityPermissions,
99              String[] guestPermissions)
100         throws PortalException, SystemException {
101 
102         long groupId = PortalUtil.getScopeGroupId(plid);
103 
104         return addStructureToGroup(
105             uuid, userId, structureId, autoStructureId, groupId, name,
106             description, xsd, addCommunityPermissions, addGuestPermissions,
107             communityPermissions, guestPermissions);
108     }
109 
110     public JournalStructure addStructureToGroup(
111             String uuid, long userId, String structureId,
112             boolean autoStructureId, long groupId, String name,
113             String description, String xsd, Boolean addCommunityPermissions,
114             Boolean addGuestPermissions, String[] communityPermissions,
115             String[] guestPermissions)
116         throws PortalException, SystemException {
117 
118         // Structure
119 
120         User user = userPersistence.findByPrimaryKey(userId);
121         structureId = structureId.trim().toUpperCase();
122         Date now = new Date();
123 
124         try {
125             xsd = JournalUtil.formatXML(xsd);
126         }
127         catch (Exception e) {
128             throw new StructureXsdException();
129         }
130 
131         validate(
132             groupId, structureId, autoStructureId, name, description, xsd);
133 
134         if (autoStructureId) {
135             structureId = String.valueOf(counterLocalService.increment());
136         }
137 
138         long id = counterLocalService.increment();
139 
140         JournalStructure structure = journalStructurePersistence.create(id);
141 
142         structure.setUuid(uuid);
143         structure.setGroupId(groupId);
144         structure.setCompanyId(user.getCompanyId());
145         structure.setUserId(user.getUserId());
146         structure.setUserName(user.getFullName());
147         structure.setCreateDate(now);
148         structure.setModifiedDate(now);
149         structure.setStructureId(structureId);
150         structure.setName(name);
151         structure.setDescription(description);
152         structure.setXsd(xsd);
153 
154         journalStructurePersistence.update(structure, false);
155 
156         // Resources
157 
158         if ((addCommunityPermissions != null) &&
159             (addGuestPermissions != null)) {
160 
161             addStructureResources(
162                 structure, addCommunityPermissions.booleanValue(),
163                 addGuestPermissions.booleanValue());
164         }
165         else {
166             addStructureResources(
167                 structure, communityPermissions, guestPermissions);
168         }
169 
170         return structure;
171     }
172 
173     public void addStructureResources(
174             long groupId, String structureId, boolean addCommunityPermissions,
175             boolean addGuestPermissions)
176         throws PortalException, SystemException {
177 
178         JournalStructure structure = journalStructurePersistence.findByG_S(
179             groupId, structureId);
180 
181         addStructureResources(
182             structure, addCommunityPermissions, addGuestPermissions);
183     }
184 
185     public void addStructureResources(
186             JournalStructure structure, boolean addCommunityPermissions,
187             boolean addGuestPermissions)
188         throws PortalException, SystemException {
189 
190         resourceLocalService.addResources(
191             structure.getCompanyId(), structure.getGroupId(),
192             structure.getUserId(), JournalStructure.class.getName(),
193             structure.getId(), false, addCommunityPermissions,
194             addGuestPermissions);
195     }
196 
197     public void addStructureResources(
198             long groupId, String structureId, String[] communityPermissions,
199             String[] guestPermissions)
200         throws PortalException, SystemException {
201 
202         JournalStructure structure = journalStructurePersistence.findByG_S(
203             groupId, structureId);
204 
205         addStructureResources(
206             structure, communityPermissions, guestPermissions);
207     }
208 
209     public void addStructureResources(
210             JournalStructure structure, String[] communityPermissions,
211             String[] guestPermissions)
212         throws PortalException, SystemException {
213 
214         resourceLocalService.addModelResources(
215             structure.getCompanyId(), structure.getGroupId(),
216             structure.getUserId(), JournalStructure.class.getName(),
217             structure.getId(), communityPermissions, guestPermissions);
218     }
219 
220     public void checkNewLine(long groupId, String structureId)
221         throws PortalException, SystemException {
222 
223         JournalStructure structure = journalStructurePersistence.findByG_S(
224             groupId, structureId);
225 
226         String xsd = structure.getXsd();
227 
228         if ((xsd != null) && (xsd.indexOf("\\n") != -1)) {
229             xsd = StringUtil.replace(
230                 xsd,
231                 new String[] {"\\n", "\\r"},
232                 new String[] {"\n", "\r"});
233 
234             structure.setXsd(xsd);
235 
236             journalStructurePersistence.update(structure, false);
237         }
238     }
239 
240     public JournalStructure copyStructure(
241             long userId, long groupId, String oldStructureId,
242             String newStructureId, boolean autoStructureId)
243         throws PortalException, SystemException {
244 
245         // Structure
246 
247         User user = userPersistence.findByPrimaryKey(userId);
248         oldStructureId = oldStructureId.trim().toUpperCase();
249         newStructureId = newStructureId.trim().toUpperCase();
250         Date now = new Date();
251 
252         JournalStructure oldStructure = journalStructurePersistence.findByG_S(
253             groupId, oldStructureId);
254 
255         if (autoStructureId) {
256             newStructureId = String.valueOf(counterLocalService.increment());
257         }
258         else {
259             validate(newStructureId);
260 
261             JournalStructure newStructure =
262                 journalStructurePersistence.fetchByG_S(groupId, newStructureId);
263 
264             if (newStructure != null) {
265                 throw new DuplicateStructureIdException();
266             }
267         }
268 
269         long id = counterLocalService.increment();
270 
271         JournalStructure newStructure = journalStructurePersistence.create(id);
272 
273         newStructure.setGroupId(groupId);
274         newStructure.setCompanyId(user.getCompanyId());
275         newStructure.setUserId(user.getUserId());
276         newStructure.setUserName(user.getFullName());
277         newStructure.setCreateDate(now);
278         newStructure.setModifiedDate(now);
279         newStructure.setStructureId(newStructureId);
280         newStructure.setName(oldStructure.getName());
281         newStructure.setDescription(oldStructure.getDescription());
282         newStructure.setXsd(oldStructure.getXsd());
283 
284         journalStructurePersistence.update(newStructure, false);
285 
286         // Resources
287 
288         addStructureResources(newStructure, true, true);
289 
290         return newStructure;
291     }
292 
293     public void deleteStructure(long groupId, String structureId)
294         throws PortalException, SystemException {
295 
296         structureId = structureId.trim().toUpperCase();
297 
298         JournalStructure structure = journalStructurePersistence.findByG_S(
299             groupId, structureId);
300 
301         deleteStructure(structure);
302     }
303 
304     public void deleteStructure(JournalStructure structure)
305         throws PortalException, SystemException {
306 
307         if (journalArticlePersistence.countByG_S(
308                 structure.getGroupId(), structure.getStructureId()) > 0) {
309 
310             throw new RequiredStructureException();
311         }
312 
313         if (journalTemplatePersistence.countByG_S(
314                 structure.getGroupId(), structure.getStructureId()) > 0) {
315 
316             throw new RequiredStructureException();
317         }
318 
319         // WebDAVProps
320 
321         webDAVPropsLocalService.deleteWebDAVProps(
322             JournalStructure.class.getName(), structure.getPrimaryKey());
323 
324         // Resources
325 
326         resourceLocalService.deleteResource(
327             structure.getCompanyId(), JournalStructure.class.getName(),
328             ResourceConstants.SCOPE_INDIVIDUAL, structure.getId());
329 
330         // Structure
331 
332         journalStructurePersistence.remove(structure);
333     }
334 
335     public void deleteStructures(long groupId)
336         throws PortalException, SystemException {
337 
338         for (JournalStructure structure :
339                 journalStructurePersistence.findByGroupId(groupId)) {
340 
341             deleteStructure(structure);
342         }
343     }
344 
345     public JournalStructure getStructure(long id)
346         throws PortalException, SystemException {
347 
348         return journalStructurePersistence.findByPrimaryKey(id);
349     }
350 
351     public JournalStructure getStructure(long groupId, String structureId)
352         throws PortalException, SystemException {
353 
354         structureId = structureId.trim().toUpperCase();
355 
356         if (groupId == 0) {
357             _log.error(
358                 "No group id was passed for " + structureId + ". Group id is " +
359                     "required since 4.2.0. Please update all custom code and " +
360                         "data that references structures without a group id.");
361 
362             List<JournalStructure> structures =
363                 journalStructurePersistence.findByStructureId(structureId);
364 
365             if (structures.size() == 0) {
366                 throw new NoSuchStructureException(
367                     "No JournalStructure exists with the structure id " +
368                         structureId);
369             }
370             else {
371                 return structures.get(0);
372             }
373         }
374         else {
375             return journalStructurePersistence.findByG_S(groupId, structureId);
376         }
377     }
378 
379     public List<JournalStructure> getStructures() throws SystemException {
380         return journalStructurePersistence.findAll();
381     }
382 
383     public List<JournalStructure> getStructures(long groupId)
384         throws SystemException {
385 
386         return journalStructurePersistence.findByGroupId(groupId);
387     }
388 
389     public List<JournalStructure> getStructures(
390             long groupId, int start, int end)
391         throws SystemException {
392 
393         return journalStructurePersistence.findByGroupId(groupId, start, end);
394     }
395 
396     public int getStructuresCount(long groupId) throws SystemException {
397         return journalStructurePersistence.countByGroupId(groupId);
398     }
399 
400     public List<JournalStructure> search(
401             long companyId, long groupId, String keywords, int start, int end,
402             OrderByComparator obc)
403         throws SystemException {
404 
405         return journalStructureFinder.findByKeywords(
406             companyId, groupId, keywords, start, end, obc);
407     }
408 
409     public List<JournalStructure> search(
410             long companyId, long groupId, String structureId, String name,
411             String description, boolean andOperator, int start, int end,
412             OrderByComparator obc)
413         throws SystemException {
414 
415         return journalStructureFinder.findByC_G_S_N_D(
416             companyId, groupId, structureId, name, description, andOperator,
417             start, end, obc);
418     }
419 
420     public int searchCount(long companyId, long groupId, String keywords)
421         throws SystemException {
422 
423         return journalStructureFinder.countByKeywords(
424             companyId, groupId, keywords);
425     }
426 
427     public int searchCount(
428             long companyId, long groupId, String structureId, String name,
429             String description, boolean andOperator)
430         throws SystemException {
431 
432         return journalStructureFinder.countByC_G_S_N_D(
433             companyId, groupId, structureId, name, description, andOperator);
434     }
435 
436     public JournalStructure updateStructure(
437             long groupId, String structureId, String name, String description,
438             String xsd)
439         throws PortalException, SystemException {
440 
441         structureId = structureId.trim().toUpperCase();
442 
443         try {
444             xsd = JournalUtil.formatXML(xsd);
445         }
446         catch (Exception e) {
447             throw new StructureXsdException();
448         }
449 
450         validate(name, description, xsd);
451 
452         JournalStructure structure = journalStructurePersistence.findByG_S(
453             groupId, structureId);
454 
455         structure.setModifiedDate(new Date());
456         structure.setName(name);
457         structure.setDescription(description);
458         structure.setXsd(xsd);
459 
460         journalStructurePersistence.update(structure, false);
461 
462         return structure;
463     }
464 
465     protected void validate(String structureId) throws PortalException {
466         if ((Validator.isNull(structureId)) ||
467             (Validator.isNumber(structureId)) ||
468             (structureId.indexOf(StringPool.SPACE) != -1)) {
469 
470             throw new StructureIdException();
471         }
472     }
473 
474     protected void validate(
475             long groupId, String structureId, boolean autoStructureId,
476             String name, String description, String xsd)
477         throws PortalException, SystemException {
478 
479         if (!autoStructureId) {
480             validate(structureId);
481 
482             JournalStructure structure = journalStructurePersistence.fetchByG_S(
483                 groupId, structureId);
484 
485             if (structure != null) {
486                 throw new DuplicateStructureIdException();
487             }
488         }
489 
490         validate(name, description, xsd);
491     }
492 
493     protected void validate(String name, String description, String xsd)
494         throws PortalException {
495 
496         if (Validator.isNull(name)) {
497             throw new StructureNameException();
498         }
499         else if (Validator.isNull(description)) {
500             throw new StructureDescriptionException();
501         }
502 
503         if (Validator.isNull(xsd)) {
504             throw new StructureXsdException();
505         }
506         else {
507             try {
508                 Document doc = SAXReaderUtil.read(xsd);
509 
510                 Element root = doc.getRootElement();
511 
512                 List<Element> children = root.elements();
513 
514                 if (children.size() == 0) {
515                     throw new StructureXsdException();
516                 }
517 
518                 Set<String> elNames = new HashSet<String>();
519 
520                 validate(children, elNames);
521             }
522             catch (Exception e) {
523                 throw new StructureXsdException();
524             }
525         }
526     }
527 
528     protected void validate(List<Element> children, Set<String> elNames)
529         throws PortalException {
530 
531         for (Element el : children) {
532             String elName = el.attributeValue("name", StringPool.BLANK);
533             String elType = el.attributeValue("type", StringPool.BLANK);
534 
535             if (Validator.isNull(elName) ||
536                 elName.startsWith(JournalStructureImpl.RESERVED)) {
537 
538                 throw new StructureXsdException();
539             }
540             else {
541                 char[] c = elName.toCharArray();
542 
543                 for (int i = 0; i < c.length; i++) {
544                     if ((!Validator.isChar(c[i])) &&
545                         (!Validator.isDigit(c[i])) && (c[i] != CharPool.DASH) &&
546                         (c[i] != CharPool.UNDERLINE)) {
547 
548                         throw new StructureXsdException();
549                     }
550                 }
551 
552                 String completePath = elName;
553 
554                 Element parent = el.getParent();
555 
556                 while (!parent.isRootElement()) {
557                     completePath =
558                         parent.attributeValue("name", StringPool.BLANK) +
559                             StringPool.SLASH + completePath;
560 
561                     parent = parent.getParent();
562                 }
563 
564                 String elNameLowerCase = completePath.toLowerCase();
565 
566                 if (elNames.contains(elNameLowerCase)) {
567                     throw new StructureXsdException();
568                 }
569                 else {
570                     elNames.add(elNameLowerCase);
571                 }
572             }
573 
574             if (Validator.isNull(elType)) {
575                 throw new StructureXsdException();
576             }
577 
578             validate(el.elements(), elNames);
579         }
580     }
581 
582     private static Log _log = LogFactoryUtil.getLog(
583         JournalStructureLocalServiceImpl.class);
584 
585 }