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