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.ResourceConstants;
33  import com.liferay.portal.model.User;
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.List;
57  
58  import org.apache.commons.logging.Log;
59  import org.apache.commons.logging.LogFactory;
60  
61  import org.dom4j.DocumentException;
62  
63  /**
64   * <a href="JournalTemplateLocalServiceImpl.java.html"><b><i>View Source</i></b>
65   * </a>
66   *
67   * @author Brian Wing Shun Chan
68   *
69   */
70  public class JournalTemplateLocalServiceImpl
71      extends JournalTemplateLocalServiceBaseImpl {
72  
73      public JournalTemplate addTemplate(
74              long userId, String templateId, boolean autoTemplateId, long plid,
75              String structureId, String name, String description, String xsl,
76              boolean formatXsl, String langType, boolean cacheable,
77              boolean smallImage, String smallImageURL, File smallFile,
78              boolean addCommunityPermissions, boolean addGuestPermissions)
79          throws PortalException, SystemException {
80  
81          return addTemplate(
82              null, userId, templateId, autoTemplateId, plid, structureId, name,
83              description, xsl, formatXsl, langType, cacheable, smallImage,
84              smallImageURL, smallFile, Boolean.valueOf(addCommunityPermissions),
85              Boolean.valueOf(addGuestPermissions), null, null);
86      }
87  
88      public JournalTemplate addTemplate(
89              String uuid, long userId, String templateId, boolean autoTemplateId,
90              long plid, String structureId, String name, String description,
91              String xsl, boolean formatXsl, String langType, boolean cacheable,
92              boolean smallImage, String smallImageURL, File smallFile,
93              boolean addCommunityPermissions, boolean addGuestPermissions)
94          throws PortalException, SystemException {
95  
96          return addTemplate(
97              uuid, userId, templateId, autoTemplateId, plid, structureId, name,
98              description, xsl, formatXsl, langType, cacheable, smallImage,
99              smallImageURL, smallFile, Boolean.valueOf(addCommunityPermissions),
100             Boolean.valueOf(addGuestPermissions), null, null);
101     }
102 
103     public JournalTemplate addTemplate(
104             long userId, String templateId, boolean autoTemplateId, long plid,
105             String structureId, String name, String description, String xsl,
106             boolean formatXsl, String langType, boolean cacheable,
107             boolean smallImage, String smallImageURL, File smallFile,
108             String[] communityPermissions, String[] guestPermissions)
109         throws PortalException, SystemException {
110 
111         return addTemplate(
112             null, userId, templateId, autoTemplateId, plid, structureId, name,
113             description, xsl, formatXsl, langType, cacheable, smallImage,
114             smallImageURL, smallFile, null, null, communityPermissions,
115             guestPermissions);
116     }
117 
118     public JournalTemplate addTemplate(
119             String uuid, long userId, String templateId, boolean autoTemplateId,
120             long plid, String structureId, String name, String description,
121             String xsl, boolean formatXsl, String langType, boolean cacheable,
122             boolean smallImage, String smallImageURL, File smallFile,
123             Boolean addCommunityPermissions, Boolean addGuestPermissions,
124             String[] communityPermissions, String[] guestPermissions)
125         throws PortalException, SystemException {
126 
127         long groupId = PortalUtil.getPortletGroupId(plid);
128 
129         return addTemplateToGroup(
130             uuid, userId, templateId, autoTemplateId, groupId, structureId,
131             name, description, xsl, formatXsl, langType, cacheable, smallImage,
132             smallImageURL, smallFile, addCommunityPermissions,
133             addGuestPermissions, communityPermissions, guestPermissions);
134     }
135 
136     public JournalTemplate addTemplateToGroup(
137             String uuid, long userId, String templateId, boolean autoTemplateId,
138             long groupId, String structureId, String name, String description,
139             String xsl, boolean formatXsl, String langType, boolean cacheable,
140             boolean smallImage, String smallImageURL, File smallFile,
141             Boolean addCommunityPermissions, Boolean addGuestPermissions,
142             String[] communityPermissions, String[] guestPermissions)
143         throws PortalException, SystemException {
144 
145         // Template
146 
147         User user = userPersistence.findByPrimaryKey(userId);
148         templateId = templateId.trim().toUpperCase();
149         Date now = new Date();
150 
151         try {
152             if (formatXsl) {
153                 if (langType.equals(JournalTemplateImpl.LANG_TYPE_VM)) {
154                     xsl = JournalUtil.formatVM(xsl);
155                 }
156                 else {
157                     xsl = JournalUtil.formatXML(xsl);
158                 }
159             }
160         }
161         catch (DocumentException de) {
162             throw new TemplateXslException();
163         }
164         catch (IOException ioe) {
165             throw new TemplateXslException();
166         }
167 
168         byte[] smallBytes = null;
169 
170         try {
171             smallBytes = FileUtil.getBytes(smallFile);
172         }
173         catch (IOException ioe) {
174         }
175 
176         validate(
177             groupId, templateId, autoTemplateId, name, description, xsl,
178             smallImage, smallImageURL, smallFile, smallBytes);
179 
180         if (autoTemplateId) {
181             templateId = String.valueOf(counterLocalService.increment());
182         }
183 
184         long id = counterLocalService.increment();
185 
186         JournalTemplate template = journalTemplatePersistence.create(id);
187 
188         template.setUuid(uuid);
189         template.setGroupId(groupId);
190         template.setCompanyId(user.getCompanyId());
191         template.setUserId(user.getUserId());
192         template.setUserName(user.getFullName());
193         template.setCreateDate(now);
194         template.setModifiedDate(now);
195         template.setTemplateId(templateId);
196         template.setStructureId(structureId);
197         template.setName(name);
198         template.setDescription(description);
199         template.setXsl(xsl);
200         template.setLangType(langType);
201         template.setCacheable(cacheable);
202         template.setSmallImage(smallImage);
203         template.setSmallImageId(counterLocalService.increment());
204         template.setSmallImageURL(smallImageURL);
205 
206         journalTemplatePersistence.update(template, false);
207 
208         // Small image
209 
210         saveImages(
211             smallImage, template.getSmallImageId(), smallFile, smallBytes);
212 
213         // Resources
214 
215         if ((addCommunityPermissions != null) &&
216             (addGuestPermissions != null)) {
217 
218             addTemplateResources(
219                 template, addCommunityPermissions.booleanValue(),
220                 addGuestPermissions.booleanValue());
221         }
222         else {
223             addTemplateResources(
224                 template, communityPermissions, guestPermissions);
225         }
226 
227         return template;
228     }
229 
230     public void addTemplateResources(
231             long groupId, String templateId, boolean addCommunityPermissions,
232             boolean addGuestPermissions)
233         throws PortalException, SystemException {
234 
235         JournalTemplate template = journalTemplatePersistence.findByG_T(
236             groupId, templateId);
237 
238         addTemplateResources(
239             template, addCommunityPermissions, addGuestPermissions);
240     }
241 
242     public void addTemplateResources(
243             JournalTemplate template, boolean addCommunityPermissions,
244             boolean addGuestPermissions)
245         throws PortalException, SystemException {
246 
247         resourceLocalService.addResources(
248             template.getCompanyId(), template.getGroupId(),
249             template.getUserId(), JournalTemplate.class.getName(),
250             template.getId(), false, addCommunityPermissions,
251             addGuestPermissions);
252     }
253 
254     public void addTemplateResources(
255             long groupId, String templateId, String[] communityPermissions,
256             String[] guestPermissions)
257         throws PortalException, SystemException {
258 
259         JournalTemplate template = journalTemplatePersistence.findByG_T(
260             groupId, templateId);
261 
262         addTemplateResources(template, communityPermissions, guestPermissions);
263     }
264 
265     public void addTemplateResources(
266             JournalTemplate template, String[] communityPermissions,
267             String[] guestPermissions)
268         throws PortalException, SystemException {
269 
270         resourceLocalService.addModelResources(
271             template.getCompanyId(), template.getGroupId(),
272             template.getUserId(), JournalTemplate.class.getName(),
273             template.getId(), communityPermissions, guestPermissions);
274     }
275 
276     public void checkNewLine(long groupId, String templateId)
277         throws PortalException, SystemException {
278 
279         JournalTemplate template = journalTemplatePersistence.findByG_T(
280             groupId, templateId);
281 
282         String xsl = template.getXsl();
283 
284         if ((xsl != null) && (xsl.indexOf("\\n") != -1)) {
285             xsl = StringUtil.replace(
286                 xsl,
287                 new String[] {"\\n", "\\r"},
288                 new String[] {"\n", "\r"});
289 
290             template.setXsl(xsl);
291 
292             journalTemplatePersistence.update(template, false);
293         }
294     }
295 
296     public void deleteTemplate(long groupId, String templateId)
297         throws PortalException, SystemException {
298 
299         templateId = templateId.trim().toUpperCase();
300 
301         JournalTemplate template = journalTemplatePersistence.findByG_T(
302             groupId, templateId);
303 
304         deleteTemplate(template);
305     }
306 
307     public void deleteTemplate(JournalTemplate template)
308         throws PortalException, SystemException {
309 
310         if (journalArticlePersistence.countByG_T(
311                 template.getGroupId(), template.getTemplateId()) > 0) {
312 
313             throw new RequiredTemplateException();
314         }
315 
316         // Small image
317 
318         ImageLocalUtil.deleteImage(template.getSmallImageId());
319 
320         // WebDAVProps
321 
322         webDAVPropsLocalService.deleteWebDAVProps(
323             JournalTemplate.class.getName(), template.getPrimaryKey());
324 
325         // Resources
326 
327         resourceLocalService.deleteResource(
328             template.getCompanyId(), JournalTemplate.class.getName(),
329             ResourceConstants.SCOPE_INDIVIDUAL, template.getId());
330 
331         // Template
332 
333         journalTemplatePersistence.remove(template.getPrimaryKey());
334     }
335 
336     public void deleteTemplates(long groupId)
337         throws PortalException, SystemException {
338 
339         for (JournalTemplate template :
340                 journalTemplatePersistence.findByGroupId(groupId)) {
341 
342             deleteTemplate(template);
343         }
344     }
345 
346     public List<JournalTemplate> getStructureTemplates(
347             long groupId, String structureId)
348         throws SystemException {
349 
350         return journalTemplatePersistence.findByG_S(groupId, structureId);
351     }
352 
353     public List<JournalTemplate> getStructureTemplates(
354             long groupId, String structureId, int begin, int end)
355         throws SystemException {
356 
357         return journalTemplatePersistence.findByG_S(
358             groupId, structureId, begin, end);
359     }
360 
361     public int getStructureTemplatesCount(long groupId, String structureId)
362         throws SystemException {
363 
364         return journalTemplatePersistence.countByG_S(groupId, structureId);
365     }
366 
367     public JournalTemplate getTemplate(long id)
368         throws PortalException, SystemException {
369 
370         return journalTemplatePersistence.findByPrimaryKey(id);
371     }
372 
373     public JournalTemplate getTemplate(long groupId, String templateId)
374         throws PortalException, SystemException {
375 
376         templateId = GetterUtil.getString(templateId).toUpperCase();
377 
378         if (groupId == 0) {
379             _log.error(
380                 "No group id was passed for " + templateId + ". Group id is " +
381                     "required since 4.2.0. Please update all custom code and " +
382                         "data that references templates without a group id.");
383 
384             List<JournalTemplate> templates =
385                 journalTemplatePersistence.findByTemplateId(
386                     templateId);
387 
388             if (templates.size() == 0) {
389                 throw new NoSuchTemplateException(
390                     "No JournalTemplate exists with the template id " +
391                         templateId);
392             }
393             else {
394                 return templates.get(0);
395             }
396         }
397         else {
398             return journalTemplatePersistence.findByG_T(groupId, templateId);
399         }
400     }
401 
402     public JournalTemplate getTemplateBySmallImageId(long smallImageId)
403         throws PortalException, SystemException {
404 
405         return journalTemplatePersistence.findBySmallImageId(smallImageId);
406     }
407 
408     public List<JournalTemplate> getTemplates() throws SystemException {
409         return journalTemplatePersistence.findAll();
410     }
411 
412     public List<JournalTemplate> getTemplates(long groupId)
413         throws SystemException {
414 
415         return journalTemplatePersistence.findByGroupId(groupId);
416     }
417 
418     public List<JournalTemplate> 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<JournalTemplate> 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<JournalTemplate> 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, false);
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 }