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