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