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