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.GetterUtil;
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.model.User;
33  import com.liferay.portal.model.impl.ResourceImpl;
34  import com.liferay.portal.service.impl.ImageLocalUtil;
35  import com.liferay.portal.util.PortalUtil;
36  import com.liferay.portal.util.PropsUtil;
37  import com.liferay.portlet.journal.DuplicateTemplateIdException;
38  import com.liferay.portlet.journal.NoSuchTemplateException;
39  import com.liferay.portlet.journal.RequiredTemplateException;
40  import com.liferay.portlet.journal.TemplateDescriptionException;
41  import com.liferay.portlet.journal.TemplateIdException;
42  import com.liferay.portlet.journal.TemplateNameException;
43  import com.liferay.portlet.journal.TemplateSmallImageNameException;
44  import com.liferay.portlet.journal.TemplateSmallImageSizeException;
45  import com.liferay.portlet.journal.TemplateXslException;
46  import com.liferay.portlet.journal.model.JournalTemplate;
47  import com.liferay.portlet.journal.model.impl.JournalTemplateImpl;
48  import com.liferay.portlet.journal.service.base.JournalTemplateLocalServiceBaseImpl;
49  import com.liferay.portlet.journal.util.JournalUtil;
50  import com.liferay.util.FileUtil;
51  
52  import java.io.File;
53  import java.io.IOException;
54  
55  import java.util.Date;
56  import java.util.Iterator;
57  import java.util.List;
58  
59  import org.apache.commons.logging.Log;
60  import org.apache.commons.logging.LogFactory;
61  
62  import org.dom4j.DocumentException;
63  
64  /**
65   * <a href="JournalTemplateLocalServiceImpl.java.html"><b><i>View Source</i></b>
66   * </a>
67   *
68   * @author Brian Wing Shun Chan
69   *
70   */
71  public class JournalTemplateLocalServiceImpl
72      extends JournalTemplateLocalServiceBaseImpl {
73  
74      public JournalTemplate addTemplate(
75              long userId, String templateId, boolean autoTemplateId, long plid,
76              String structureId, String name, String description, String xsl,
77              boolean formatXsl, String langType, boolean cacheable,
78              boolean smallImage, String smallImageURL, File smallFile,
79              boolean addCommunityPermissions, boolean addGuestPermissions)
80          throws PortalException, SystemException {
81  
82          return addTemplate(
83              null, userId, templateId, autoTemplateId, plid, structureId, name,
84              description, xsl, formatXsl, langType, cacheable, smallImage,
85              smallImageURL, smallFile, Boolean.valueOf(addCommunityPermissions),
86              Boolean.valueOf(addGuestPermissions), null, null);
87      }
88  
89      public JournalTemplate addTemplate(
90              String uuid, long userId, String templateId, boolean autoTemplateId,
91              long plid, String structureId, String name, String description,
92              String xsl, boolean formatXsl, String langType, boolean cacheable,
93              boolean smallImage, String smallImageURL, File smallFile,
94              boolean addCommunityPermissions, boolean addGuestPermissions)
95          throws PortalException, SystemException {
96  
97          return addTemplate(
98              uuid, userId, templateId, autoTemplateId, plid, structureId, name,
99              description, xsl, formatXsl, langType, cacheable, smallImage,
100             smallImageURL, smallFile, Boolean.valueOf(addCommunityPermissions),
101             Boolean.valueOf(addGuestPermissions), null, null);
102     }
103 
104     public JournalTemplate addTemplate(
105             long userId, String templateId, boolean autoTemplateId, long plid,
106             String structureId, String name, String description, String xsl,
107             boolean formatXsl, String langType, boolean cacheable,
108             boolean smallImage, String smallImageURL, File smallFile,
109             String[] communityPermissions, String[] guestPermissions)
110         throws PortalException, SystemException {
111 
112         return addTemplate(
113             null, userId, templateId, autoTemplateId, plid, structureId, name,
114             description, xsl, formatXsl, langType, cacheable, smallImage,
115             smallImageURL, smallFile, null, null, communityPermissions,
116             guestPermissions);
117     }
118 
119     public JournalTemplate addTemplate(
120             String uuid, long userId, String templateId, boolean autoTemplateId,
121             long plid, String structureId, String name, String description,
122             String xsl, boolean formatXsl, String langType, boolean cacheable,
123             boolean smallImage, String smallImageURL, File smallFile,
124             Boolean addCommunityPermissions, Boolean addGuestPermissions,
125             String[] communityPermissions, String[] guestPermissions)
126         throws PortalException, SystemException {
127 
128         long groupId = PortalUtil.getPortletGroupId(plid);
129 
130         return addTemplateToGroup(
131             uuid, userId, templateId, autoTemplateId, groupId, structureId,
132             name, description, xsl, formatXsl, langType, cacheable, smallImage,
133             smallImageURL, smallFile, addCommunityPermissions,
134             addGuestPermissions, communityPermissions, guestPermissions);
135     }
136 
137     public JournalTemplate addTemplateToGroup(
138             String uuid, long userId, String templateId, boolean autoTemplateId,
139             long groupId, String structureId, String name, String description,
140             String xsl, boolean formatXsl, String langType, boolean cacheable,
141             boolean smallImage, String smallImageURL, File smallFile,
142             Boolean addCommunityPermissions, Boolean addGuestPermissions,
143             String[] communityPermissions, String[] guestPermissions)
144         throws PortalException, SystemException {
145 
146         // Template
147 
148         User user = userPersistence.findByPrimaryKey(userId);
149         templateId = templateId.trim().toUpperCase();
150         Date now = new Date();
151 
152         try {
153             if (formatXsl) {
154                 if (langType.equals(JournalTemplateImpl.LANG_TYPE_VM)) {
155                     xsl = JournalUtil.formatVM(xsl);
156                 }
157                 else {
158                     xsl = JournalUtil.formatXML(xsl);
159                 }
160             }
161         }
162         catch (DocumentException de) {
163             throw new TemplateXslException();
164         }
165         catch (IOException ioe) {
166             throw new TemplateXslException();
167         }
168 
169         byte[] smallBytes = null;
170 
171         try {
172             smallBytes = FileUtil.getBytes(smallFile);
173         }
174         catch (IOException ioe) {
175         }
176 
177         validate(
178             groupId, templateId, autoTemplateId, name, description, xsl,
179             smallImage, smallImageURL, smallFile, smallBytes);
180 
181         if (autoTemplateId) {
182             templateId = String.valueOf(counterLocalService.increment());
183         }
184 
185         long id = counterLocalService.increment();
186 
187         JournalTemplate template = journalTemplatePersistence.create(id);
188 
189         template.setUuid(uuid);
190         template.setGroupId(groupId);
191         template.setCompanyId(user.getCompanyId());
192         template.setUserId(user.getUserId());
193         template.setUserName(user.getFullName());
194         template.setCreateDate(now);
195         template.setModifiedDate(now);
196         template.setTemplateId(templateId);
197         template.setStructureId(structureId);
198         template.setName(name);
199         template.setDescription(description);
200         template.setXsl(xsl);
201         template.setLangType(langType);
202         template.setCacheable(cacheable);
203         template.setSmallImage(smallImage);
204         template.setSmallImageId(counterLocalService.increment());
205         template.setSmallImageURL(smallImageURL);
206 
207         journalTemplatePersistence.update(template);
208 
209         // Small image
210 
211         saveImages(
212             smallImage, template.getSmallImageId(), smallFile, smallBytes);
213 
214         // Resources
215 
216         if ((addCommunityPermissions != null) &&
217             (addGuestPermissions != null)) {
218 
219             addTemplateResources(
220                 template, addCommunityPermissions.booleanValue(),
221                 addGuestPermissions.booleanValue());
222         }
223         else {
224             addTemplateResources(
225                 template, communityPermissions, guestPermissions);
226         }
227 
228         return template;
229     }
230 
231     public void addTemplateResources(
232             long groupId, String templateId, boolean addCommunityPermissions,
233             boolean addGuestPermissions)
234         throws PortalException, SystemException {
235 
236         JournalTemplate template = journalTemplatePersistence.findByG_T(
237             groupId, templateId);
238 
239         addTemplateResources(
240             template, addCommunityPermissions, addGuestPermissions);
241     }
242 
243     public void addTemplateResources(
244             JournalTemplate template, boolean addCommunityPermissions,
245             boolean addGuestPermissions)
246         throws PortalException, SystemException {
247 
248         resourceLocalService.addResources(
249             template.getCompanyId(), template.getGroupId(),
250             template.getUserId(), JournalTemplate.class.getName(),
251             template.getId(), false, addCommunityPermissions,
252             addGuestPermissions);
253     }
254 
255     public void addTemplateResources(
256             long groupId, String templateId, String[] communityPermissions,
257             String[] guestPermissions)
258         throws PortalException, SystemException {
259 
260         JournalTemplate template = journalTemplatePersistence.findByG_T(
261             groupId, templateId);
262 
263         addTemplateResources(template, communityPermissions, guestPermissions);
264     }
265 
266     public void addTemplateResources(
267             JournalTemplate template, String[] communityPermissions,
268             String[] guestPermissions)
269         throws PortalException, SystemException {
270 
271         resourceLocalService.addModelResources(
272             template.getCompanyId(), template.getGroupId(),
273             template.getUserId(), JournalTemplate.class.getName(),
274             template.getId(), communityPermissions, guestPermissions);
275     }
276 
277     public void checkNewLine(long groupId, String templateId)
278         throws PortalException, SystemException {
279 
280         JournalTemplate template = journalTemplatePersistence.findByG_T(
281             groupId, templateId);
282 
283         String xsl = template.getXsl();
284 
285         if ((xsl != null) && (xsl.indexOf("\\n") != -1)) {
286             xsl = StringUtil.replace(
287                 xsl,
288                 new String[] {"\\n", "\\r"},
289                 new String[] {"\n", "\r"});
290 
291             template.setXsl(xsl);
292 
293             journalTemplatePersistence.update(template);
294         }
295     }
296 
297     public void deleteTemplate(long groupId, String templateId)
298         throws PortalException, SystemException {
299 
300         templateId = templateId.trim().toUpperCase();
301 
302         JournalTemplate template = journalTemplatePersistence.findByG_T(
303             groupId, templateId);
304 
305         deleteTemplate(template);
306     }
307 
308     public void deleteTemplate(JournalTemplate template)
309         throws PortalException, SystemException {
310 
311         if (journalArticlePersistence.countByG_T(
312                 template.getGroupId(), template.getTemplateId()) > 0) {
313 
314             throw new RequiredTemplateException();
315         }
316 
317         // Small image
318 
319         ImageLocalUtil.deleteImage(template.getSmallImageId());
320 
321         // Resources
322 
323         resourceLocalService.deleteResource(
324             template.getCompanyId(), JournalTemplate.class.getName(),
325             ResourceImpl.SCOPE_INDIVIDUAL, template.getId());
326 
327         // WebDAVProps
328 
329         webDAVPropsLocalService.deleteWebDAVProps(
330             JournalTemplate.class.getName(), template.getPrimaryKey());
331 
332         // Template
333 
334         journalTemplatePersistence.remove(template.getPrimaryKey());
335     }
336 
337     public void deleteTemplates(long groupId)
338         throws PortalException, SystemException {
339 
340         Iterator itr = journalTemplatePersistence.findByGroupId(
341             groupId).iterator();
342 
343         while (itr.hasNext()) {
344             JournalTemplate template = (JournalTemplate)itr.next();
345 
346             deleteTemplate(template);
347         }
348     }
349 
350     public List getStructureTemplates(long groupId, String structureId)
351         throws SystemException {
352 
353         return journalTemplatePersistence.findByG_S(groupId, structureId);
354     }
355 
356     public List getStructureTemplates(
357             long groupId, String structureId, int begin, int end)
358         throws SystemException {
359 
360         return journalTemplatePersistence.findByG_S(
361             groupId, structureId, begin, end);
362     }
363 
364     public int getStructureTemplatesCount(long groupId, String structureId)
365         throws SystemException {
366 
367         return journalTemplatePersistence.countByG_S(groupId, structureId);
368     }
369 
370     public JournalTemplate getTemplate(long id)
371         throws PortalException, SystemException {
372 
373         return journalTemplatePersistence.findByPrimaryKey(id);
374     }
375 
376     public JournalTemplate getTemplate(long groupId, String templateId)
377         throws PortalException, SystemException {
378 
379         templateId = GetterUtil.getString(templateId).toUpperCase();
380 
381         if (groupId == 0) {
382             _log.error(
383                 "No group id was passed for " + templateId + ". Group id is " +
384                     "required since 4.2.0. Please update all custom code and " +
385                         "data that references templates without a group id.");
386 
387             List templates = journalTemplatePersistence.findByTemplateId(
388                 templateId);
389 
390             if (templates.size() == 0) {
391                 throw new NoSuchTemplateException(
392                     "No JournalTemplate exists with the template id " +
393                         templateId);
394             }
395             else {
396                 return (JournalTemplate)templates.get(0);
397             }
398         }
399         else {
400             return journalTemplatePersistence.findByG_T(groupId, templateId);
401         }
402     }
403 
404     public JournalTemplate getTemplateBySmallImageId(long smallImageId)
405         throws PortalException, SystemException {
406 
407         return journalTemplatePersistence.findBySmallImageId(smallImageId);
408     }
409 
410     public List getTemplates() throws SystemException {
411         return journalTemplatePersistence.findAll();
412     }
413 
414     public List getTemplates(long groupId) throws SystemException {
415         return journalTemplatePersistence.findByGroupId(groupId);
416     }
417 
418     public List getTemplates(long groupId, int begin, int end)
419         throws SystemException {
420 
421         return journalTemplatePersistence.findByGroupId(groupId, begin, end);
422     }
423 
424     public int getTemplatesCount(long groupId) throws SystemException {
425         return journalTemplatePersistence.countByGroupId(groupId);
426     }
427 
428     public boolean hasTemplate(long groupId, String templateId)
429         throws SystemException {
430 
431         try {
432             getTemplate(groupId, templateId);
433 
434             return true;
435         }
436         catch (PortalException pe) {
437             return false;
438         }
439     }
440 
441     public List search(
442             long companyId, long groupId, String keywords, String structureId,
443             String structureIdComparator, int begin, int end,
444             OrderByComparator obc)
445         throws SystemException {
446 
447         return journalTemplateFinder.findByKeywords(
448             companyId, groupId, keywords, structureId, structureIdComparator,
449             begin, end, obc);
450     }
451 
452     public List search(
453             long companyId, long groupId, String templateId, String structureId,
454             String structureIdComparator, String name, String description,
455             boolean andOperator, int begin, int end, OrderByComparator obc)
456         throws SystemException {
457 
458         return journalTemplateFinder.findByC_G_T_S_N_D(
459             companyId, groupId, templateId, structureId, structureIdComparator,
460             name, description, andOperator, begin, end, obc);
461     }
462 
463     public int searchCount(
464             long companyId, long groupId, String keywords, String structureId,
465             String structureIdComparator)
466         throws SystemException {
467 
468         return journalTemplateFinder.countByKeywords(
469             companyId, groupId, keywords, structureId, structureIdComparator);
470     }
471 
472     public int searchCount(
473             long companyId, long groupId, String templateId, String structureId,
474             String structureIdComparator, String name, String description,
475             boolean andOperator)
476         throws SystemException {
477 
478         return journalTemplateFinder.countByC_G_T_S_N_D(
479             companyId, groupId, templateId, structureId, structureIdComparator,
480             name, description, andOperator);
481     }
482 
483     public JournalTemplate updateTemplate(
484             long groupId, String templateId, String structureId, String name,
485             String description, String xsl, boolean formatXsl, String langType,
486             boolean cacheable, boolean smallImage, String smallImageURL,
487             File smallFile)
488         throws PortalException, SystemException {
489 
490         // Template
491 
492         templateId = templateId.trim().toUpperCase();
493 
494         try {
495             if (formatXsl) {
496                 if (langType.equals(JournalTemplateImpl.LANG_TYPE_VM)) {
497                     xsl = JournalUtil.formatVM(xsl);
498                 }
499                 else {
500                     xsl = JournalUtil.formatXML(xsl);
501                 }
502             }
503         }
504         catch (DocumentException de) {
505             throw new TemplateXslException();
506         }
507         catch (IOException ioe) {
508             throw new TemplateXslException();
509         }
510 
511         byte[] smallBytes = null;
512 
513         try {
514             smallBytes = FileUtil.getBytes(smallFile);
515         }
516         catch (IOException ioe) {
517         }
518 
519         validate(
520             name, description, xsl, smallImage, smallImageURL, smallFile,
521             smallBytes);
522 
523         JournalTemplate template = journalTemplatePersistence.findByG_T(
524             groupId, templateId);
525 
526         template.setModifiedDate(new Date());
527 
528         if (Validator.isNull(template.getStructureId()) &&
529             Validator.isNotNull(structureId)) {
530 
531             // Allow users to set the structure if and only if it currently
532             // does not have one. Otherwise, you can have bad data because there
533             // may be an existing article that has chosen to use a structure and
534             // template combination that no longer exists.
535 
536             template.setStructureId(structureId);
537         }
538 
539         template.setName(name);
540         template.setDescription(description);
541         template.setXsl(xsl);
542         template.setLangType(langType);
543         template.setCacheable(cacheable);
544         template.setSmallImage(smallImage);
545         template.setSmallImageURL(smallImageURL);
546 
547         journalTemplatePersistence.update(template);
548 
549         // Small image
550 
551         saveImages(
552             smallImage, template.getSmallImageId(), smallFile, smallBytes);
553 
554         return template;
555     }
556 
557     protected void saveImages(
558             boolean smallImage, long smallImageId, File smallFile,
559             byte[] smallBytes)
560         throws SystemException {
561 
562         if (smallImage) {
563             if ((smallFile != null) && (smallBytes != null)) {
564                 ImageLocalUtil.updateImage(smallImageId, smallBytes);
565             }
566         }
567         else {
568             ImageLocalUtil.deleteImage(smallImageId);
569         }
570     }
571 
572     protected void validate(
573             long groupId, String templateId, boolean autoTemplateId,
574             String name, String description, String xsl, boolean smallImage,
575             String smallImageURL, File smallFile, byte[] smallBytes)
576         throws PortalException, SystemException {
577 
578         if (!autoTemplateId) {
579             if ((Validator.isNull(templateId)) ||
580                 (Validator.isNumber(templateId)) ||
581                 (templateId.indexOf(StringPool.SPACE) != -1)) {
582 
583                 throw new TemplateIdException();
584             }
585 
586             try {
587                 journalTemplatePersistence.findByG_T(groupId, templateId);
588 
589                 throw new DuplicateTemplateIdException();
590             }
591             catch (NoSuchTemplateException nste) {
592             }
593         }
594 
595         validate(
596             name, description, xsl, smallImage, smallImageURL, smallFile,
597             smallBytes);
598     }
599 
600     protected void validate(
601             String name, String description, String xsl, boolean smallImage,
602             String smallImageURL, File smallFile, byte[] smallBytes)
603         throws PortalException {
604 
605         if (Validator.isNull(name)) {
606             throw new TemplateNameException();
607         }
608         else if (Validator.isNull(description)) {
609             throw new TemplateDescriptionException();
610         }
611         else if (Validator.isNull(xsl)) {
612             throw new TemplateXslException();
613         }
614 
615         String[] imageExtensions =
616             PropsUtil.getArray(PropsUtil.JOURNAL_IMAGE_EXTENSIONS);
617 
618         if (smallImage && Validator.isNull(smallImageURL) &&
619             smallFile != null && smallBytes != null) {
620 
621             String smallImageName = smallFile.getName();
622 
623             if (smallImageName != null) {
624                 boolean validSmallImageExtension = false;
625 
626                 for (int i = 0; i < imageExtensions.length; i++) {
627                     if (StringPool.STAR.equals(imageExtensions[i]) ||
628                         StringUtil.endsWith(
629                             smallImageName, imageExtensions[i])) {
630 
631                         validSmallImageExtension = true;
632 
633                         break;
634                     }
635                 }
636 
637                 if (!validSmallImageExtension) {
638                     throw new TemplateSmallImageNameException(smallImageName);
639                 }
640             }
641 
642             long smallImageMaxSize = GetterUtil.getLong(
643                 PropsUtil.get(PropsUtil.JOURNAL_IMAGE_SMALL_MAX_SIZE));
644 
645             if ((smallImageMaxSize > 0) &&
646                 ((smallBytes == null) ||
647                     (smallBytes.length > smallImageMaxSize))) {
648 
649                 throw new TemplateSmallImageSizeException();
650             }
651         }
652     }
653 
654     private static Log _log =
655         LogFactory.getLog(JournalTemplateLocalServiceImpl.class);
656 
657 }