1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.journal.service.impl;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.log.Log;
28  import com.liferay.portal.kernel.log.LogFactoryUtil;
29  import com.liferay.portal.kernel.util.FileUtil;
30  import com.liferay.portal.kernel.util.GetterUtil;
31  import com.liferay.portal.kernel.util.OrderByComparator;
32  import com.liferay.portal.kernel.util.StringPool;
33  import com.liferay.portal.kernel.util.StringUtil;
34  import com.liferay.portal.kernel.util.Validator;
35  import com.liferay.portal.model.Image;
36  import com.liferay.portal.model.ResourceConstants;
37  import com.liferay.portal.model.User;
38  import com.liferay.portal.util.PropsKeys;
39  import com.liferay.portal.util.PropsUtil;
40  import com.liferay.portlet.journal.DuplicateTemplateIdException;
41  import com.liferay.portlet.journal.NoSuchTemplateException;
42  import com.liferay.portlet.journal.RequiredTemplateException;
43  import com.liferay.portlet.journal.TemplateDescriptionException;
44  import com.liferay.portlet.journal.TemplateIdException;
45  import com.liferay.portlet.journal.TemplateNameException;
46  import com.liferay.portlet.journal.TemplateSmallImageNameException;
47  import com.liferay.portlet.journal.TemplateSmallImageSizeException;
48  import com.liferay.portlet.journal.TemplateXslException;
49  import com.liferay.portlet.journal.model.JournalTemplate;
50  import com.liferay.portlet.journal.model.impl.JournalTemplateImpl;
51  import com.liferay.portlet.journal.service.base.JournalTemplateLocalServiceBaseImpl;
52  import com.liferay.portlet.journal.util.JournalUtil;
53  
54  import java.io.File;
55  import java.io.IOException;
56  
57  import java.util.Date;
58  import java.util.List;
59  
60  /**
61   * <a href="JournalTemplateLocalServiceImpl.java.html"><b><i>View Source</i></b>
62   * </a>
63   *
64   * @author Brian Wing Shun Chan
65   *
66   */
67  public class JournalTemplateLocalServiceImpl
68      extends JournalTemplateLocalServiceBaseImpl {
69  
70      public JournalTemplate addTemplate(
71              long userId, long groupId, String templateId,
72              boolean autoTemplateId, String structureId, String name,
73              String description, String xsl, boolean formatXsl, String langType,
74              boolean cacheable, boolean smallImage, String smallImageURL,
75              File smallFile, boolean addCommunityPermissions,
76              boolean addGuestPermissions)
77          throws PortalException, SystemException {
78  
79          return addTemplate(
80              null, userId, groupId, templateId, autoTemplateId, structureId,
81              name, description, xsl, formatXsl, langType, cacheable, smallImage,
82              smallImageURL, smallFile, Boolean.valueOf(addCommunityPermissions),
83              Boolean.valueOf(addGuestPermissions), null, null);
84      }
85  
86      public JournalTemplate addTemplate(
87              String uuid, long userId, long groupId, String templateId,
88              boolean autoTemplateId, String structureId, String name,
89              String description, String xsl, boolean formatXsl, String langType,
90              boolean cacheable, boolean smallImage, String smallImageURL,
91              File smallFile, boolean addCommunityPermissions,
92              boolean addGuestPermissions)
93          throws PortalException, SystemException {
94  
95          return addTemplate(
96              uuid, userId, groupId, templateId, autoTemplateId, structureId,
97              name, description, xsl, formatXsl, langType, cacheable, smallImage,
98              smallImageURL, smallFile, Boolean.valueOf(addCommunityPermissions),
99              Boolean.valueOf(addGuestPermissions), null, null);
100     }
101 
102     public JournalTemplate addTemplate(
103             long userId, long groupId, String templateId,
104             boolean autoTemplateId, String structureId, String name,
105             String description, String xsl, boolean formatXsl, String langType,
106             boolean cacheable, boolean smallImage, String smallImageURL,
107             File smallFile, String[] communityPermissions,
108             String[] guestPermissions)
109         throws PortalException, SystemException {
110 
111         return addTemplate(
112             null, userId, groupId, templateId, autoTemplateId, structureId,
113             name, 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, long groupId, String templateId,
120             boolean autoTemplateId, String structureId, String name,
121             String description, String xsl, boolean formatXsl, String langType,
122             boolean cacheable, boolean smallImage, String smallImageURL,
123             File smallFile, Boolean addCommunityPermissions,
124             Boolean addGuestPermissions, String[] communityPermissions,
125             String[] guestPermissions)
126         throws PortalException, SystemException {
127 
128         // Template
129 
130         User user = userPersistence.findByPrimaryKey(userId);
131         templateId = templateId.trim().toUpperCase();
132         Date now = new Date();
133 
134         try {
135             if (formatXsl) {
136                 if (langType.equals(JournalTemplateImpl.LANG_TYPE_VM)) {
137                     xsl = JournalUtil.formatVM(xsl);
138                 }
139                 else {
140                     xsl = JournalUtil.formatXML(xsl);
141                 }
142             }
143         }
144         catch (Exception e) {
145             throw new TemplateXslException();
146         }
147 
148         byte[] smallBytes = null;
149 
150         try {
151             smallBytes = FileUtil.getBytes(smallFile);
152         }
153         catch (IOException ioe) {
154         }
155 
156         validate(
157             groupId, templateId, autoTemplateId, name, description, xsl,
158             smallImage, smallImageURL, smallFile, smallBytes);
159 
160         if (autoTemplateId) {
161             templateId = String.valueOf(counterLocalService.increment());
162         }
163 
164         long id = counterLocalService.increment();
165 
166         JournalTemplate template = journalTemplatePersistence.create(id);
167 
168         template.setUuid(uuid);
169         template.setGroupId(groupId);
170         template.setCompanyId(user.getCompanyId());
171         template.setUserId(user.getUserId());
172         template.setUserName(user.getFullName());
173         template.setCreateDate(now);
174         template.setModifiedDate(now);
175         template.setTemplateId(templateId);
176         template.setStructureId(structureId);
177         template.setName(name);
178         template.setDescription(description);
179         template.setXsl(xsl);
180         template.setLangType(langType);
181         template.setCacheable(cacheable);
182         template.setSmallImage(smallImage);
183         template.setSmallImageId(counterLocalService.increment());
184         template.setSmallImageURL(smallImageURL);
185 
186         journalTemplatePersistence.update(template, false);
187 
188         // Small image
189 
190         saveImages(
191             smallImage, template.getSmallImageId(), smallFile, smallBytes);
192 
193         // Resources
194 
195         if ((addCommunityPermissions != null) &&
196             (addGuestPermissions != null)) {
197 
198             addTemplateResources(
199                 template, addCommunityPermissions.booleanValue(),
200                 addGuestPermissions.booleanValue());
201         }
202         else {
203             addTemplateResources(
204                 template, communityPermissions, guestPermissions);
205         }
206 
207         return template;
208     }
209 
210     public void addTemplateResources(
211             long groupId, String templateId, boolean addCommunityPermissions,
212             boolean addGuestPermissions)
213         throws PortalException, SystemException {
214 
215         JournalTemplate template = journalTemplatePersistence.findByG_T(
216             groupId, templateId);
217 
218         addTemplateResources(
219             template, addCommunityPermissions, addGuestPermissions);
220     }
221 
222     public void addTemplateResources(
223             JournalTemplate template, boolean addCommunityPermissions,
224             boolean addGuestPermissions)
225         throws PortalException, SystemException {
226 
227         resourceLocalService.addResources(
228             template.getCompanyId(), template.getGroupId(),
229             template.getUserId(), JournalTemplate.class.getName(),
230             template.getId(), false, addCommunityPermissions,
231             addGuestPermissions);
232     }
233 
234     public void addTemplateResources(
235             long groupId, String templateId, String[] communityPermissions,
236             String[] guestPermissions)
237         throws PortalException, SystemException {
238 
239         JournalTemplate template = journalTemplatePersistence.findByG_T(
240             groupId, templateId);
241 
242         addTemplateResources(template, communityPermissions, guestPermissions);
243     }
244 
245     public void addTemplateResources(
246             JournalTemplate template, String[] communityPermissions,
247             String[] guestPermissions)
248         throws PortalException, SystemException {
249 
250         resourceLocalService.addModelResources(
251             template.getCompanyId(), template.getGroupId(),
252             template.getUserId(), JournalTemplate.class.getName(),
253             template.getId(), communityPermissions, guestPermissions);
254     }
255 
256     public void checkNewLine(long groupId, String templateId)
257         throws PortalException, SystemException {
258 
259         JournalTemplate template = journalTemplatePersistence.findByG_T(
260             groupId, templateId);
261 
262         String xsl = template.getXsl();
263 
264         if ((xsl != null) && (xsl.indexOf("\\n") != -1)) {
265             xsl = StringUtil.replace(
266                 xsl,
267                 new String[] {"\\n", "\\r"},
268                 new String[] {"\n", "\r"});
269 
270             template.setXsl(xsl);
271 
272             journalTemplatePersistence.update(template, false);
273         }
274     }
275 
276     public JournalTemplate copyTemplate(
277             long userId, long groupId, String oldTemplateId,
278             String newTemplateId, boolean autoTemplateId)
279         throws PortalException, SystemException {
280 
281         // Template
282 
283         User user = userPersistence.findByPrimaryKey(userId);
284         oldTemplateId = oldTemplateId.trim().toUpperCase();
285         newTemplateId = newTemplateId.trim().toUpperCase();
286         Date now = new Date();
287 
288         JournalTemplate oldTemplate = journalTemplatePersistence.findByG_T(
289             groupId, oldTemplateId);
290 
291         if (autoTemplateId) {
292             newTemplateId = String.valueOf(counterLocalService.increment());
293         }
294         else {
295             validate(newTemplateId);
296 
297             JournalTemplate newTemplate = journalTemplatePersistence.fetchByG_T(
298                 groupId, newTemplateId);
299 
300             if (newTemplate != null) {
301                 throw new DuplicateTemplateIdException();
302             }
303         }
304 
305         long id = counterLocalService.increment();
306 
307         JournalTemplate newTemplate = journalTemplatePersistence.create(id);
308 
309         newTemplate.setGroupId(groupId);
310         newTemplate.setCompanyId(user.getCompanyId());
311         newTemplate.setUserId(user.getUserId());
312         newTemplate.setUserName(user.getFullName());
313         newTemplate.setCreateDate(now);
314         newTemplate.setModifiedDate(now);
315         newTemplate.setTemplateId(newTemplateId);
316         newTemplate.setStructureId(oldTemplate.getStructureId());
317         newTemplate.setName(oldTemplate.getName());
318         newTemplate.setDescription(oldTemplate.getDescription());
319         newTemplate.setXsl(oldTemplate.getXsl());
320         newTemplate.setLangType(oldTemplate.getLangType());
321         newTemplate.setCacheable(oldTemplate.isCacheable());
322         newTemplate.setSmallImage(oldTemplate.isSmallImage());
323         newTemplate.setSmallImageId(counterLocalService.increment());
324         newTemplate.setSmallImageURL(oldTemplate.getSmallImageURL());
325 
326         journalTemplatePersistence.update(newTemplate, false);
327 
328         // Small image
329 
330         if (oldTemplate.getSmallImage()) {
331             Image image = imageLocalService.getImage(
332                 oldTemplate.getSmallImageId());
333 
334             byte[] smallBytes = image.getTextObj();
335 
336             imageLocalService.updateImage(
337                 newTemplate.getSmallImageId(), smallBytes);
338         }
339 
340         // Resources
341 
342         addTemplateResources(newTemplate, true, true);
343 
344         return newTemplate;
345     }
346 
347     public void deleteTemplate(long groupId, String templateId)
348         throws PortalException, SystemException {
349 
350         templateId = templateId.trim().toUpperCase();
351 
352         JournalTemplate template = journalTemplatePersistence.findByG_T(
353             groupId, templateId);
354 
355         deleteTemplate(template);
356     }
357 
358     public void deleteTemplate(JournalTemplate template)
359         throws PortalException, SystemException {
360 
361         if (journalArticlePersistence.countByG_T(
362                 template.getGroupId(), template.getTemplateId()) > 0) {
363 
364             throw new RequiredTemplateException();
365         }
366 
367         // Small image
368 
369         imageLocalService.deleteImage(template.getSmallImageId());
370 
371         // WebDAVProps
372 
373         webDAVPropsLocalService.deleteWebDAVProps(
374             JournalTemplate.class.getName(), template.getPrimaryKey());
375 
376         // Resources
377 
378         resourceLocalService.deleteResource(
379             template.getCompanyId(), JournalTemplate.class.getName(),
380             ResourceConstants.SCOPE_INDIVIDUAL, template.getId());
381 
382         // Template
383 
384         journalTemplatePersistence.remove(template);
385     }
386 
387     public void deleteTemplates(long groupId)
388         throws PortalException, SystemException {
389 
390         for (JournalTemplate template :
391                 journalTemplatePersistence.findByGroupId(groupId)) {
392 
393             deleteTemplate(template);
394         }
395     }
396 
397     public List<JournalTemplate> getStructureTemplates(
398             long groupId, String structureId)
399         throws SystemException {
400 
401         return journalTemplatePersistence.findByG_S(groupId, structureId);
402     }
403 
404     public List<JournalTemplate> getStructureTemplates(
405             long groupId, String structureId, int start, int end)
406         throws SystemException {
407 
408         return journalTemplatePersistence.findByG_S(
409             groupId, structureId, start, end);
410     }
411 
412     public int getStructureTemplatesCount(long groupId, String structureId)
413         throws SystemException {
414 
415         return journalTemplatePersistence.countByG_S(groupId, structureId);
416     }
417 
418     public JournalTemplate getTemplate(long id)
419         throws PortalException, SystemException {
420 
421         return journalTemplatePersistence.findByPrimaryKey(id);
422     }
423 
424     public JournalTemplate getTemplate(long groupId, String templateId)
425         throws PortalException, SystemException {
426 
427         templateId = GetterUtil.getString(templateId).toUpperCase();
428 
429         if (groupId == 0) {
430             _log.error(
431                 "No group id was passed for " + templateId + ". Group id is " +
432                     "required since 4.2.0. Please update all custom code and " +
433                         "data that references templates without a group id.");
434 
435             List<JournalTemplate> templates =
436                 journalTemplatePersistence.findByTemplateId(
437                     templateId);
438 
439             if (templates.size() == 0) {
440                 throw new NoSuchTemplateException(
441                     "No JournalTemplate exists with the template id " +
442                         templateId);
443             }
444             else {
445                 return templates.get(0);
446             }
447         }
448         else {
449             return journalTemplatePersistence.findByG_T(groupId, templateId);
450         }
451     }
452 
453     public JournalTemplate getTemplateBySmallImageId(long smallImageId)
454         throws PortalException, SystemException {
455 
456         return journalTemplatePersistence.findBySmallImageId(smallImageId);
457     }
458 
459     public List<JournalTemplate> getTemplates() throws SystemException {
460         return journalTemplatePersistence.findAll();
461     }
462 
463     public List<JournalTemplate> getTemplates(long groupId)
464         throws SystemException {
465 
466         return journalTemplatePersistence.findByGroupId(groupId);
467     }
468 
469     public List<JournalTemplate> getTemplates(long groupId, int start, int end)
470         throws SystemException {
471 
472         return journalTemplatePersistence.findByGroupId(groupId, start, end);
473     }
474 
475     public int getTemplatesCount(long groupId) throws SystemException {
476         return journalTemplatePersistence.countByGroupId(groupId);
477     }
478 
479     public boolean hasTemplate(long groupId, String templateId)
480         throws SystemException {
481 
482         try {
483             getTemplate(groupId, templateId);
484 
485             return true;
486         }
487         catch (PortalException pe) {
488             return false;
489         }
490     }
491 
492     public List<JournalTemplate> search(
493             long companyId, long groupId, String keywords, String structureId,
494             String structureIdComparator, int start, int end,
495             OrderByComparator obc)
496         throws SystemException {
497 
498         return journalTemplateFinder.findByKeywords(
499             companyId, groupId, keywords, structureId, structureIdComparator,
500             start, end, obc);
501     }
502 
503     public List<JournalTemplate> search(
504             long companyId, long groupId, String templateId, String structureId,
505             String structureIdComparator, String name, String description,
506             boolean andOperator, int start, int end, OrderByComparator obc)
507         throws SystemException {
508 
509         return journalTemplateFinder.findByC_G_T_S_N_D(
510             companyId, groupId, templateId, structureId, structureIdComparator,
511             name, description, andOperator, start, end, obc);
512     }
513 
514     public int searchCount(
515             long companyId, long groupId, String keywords, String structureId,
516             String structureIdComparator)
517         throws SystemException {
518 
519         return journalTemplateFinder.countByKeywords(
520             companyId, groupId, keywords, structureId, structureIdComparator);
521     }
522 
523     public int searchCount(
524             long companyId, long groupId, String templateId, String structureId,
525             String structureIdComparator, String name, String description,
526             boolean andOperator)
527         throws SystemException {
528 
529         return journalTemplateFinder.countByC_G_T_S_N_D(
530             companyId, groupId, templateId, structureId, structureIdComparator,
531             name, description, andOperator);
532     }
533 
534     public JournalTemplate updateTemplate(
535             long groupId, String templateId, String structureId, String name,
536             String description, String xsl, boolean formatXsl, String langType,
537             boolean cacheable, boolean smallImage, String smallImageURL,
538             File smallFile)
539         throws PortalException, SystemException {
540 
541         // Template
542 
543         templateId = templateId.trim().toUpperCase();
544 
545         try {
546             if (formatXsl) {
547                 if (langType.equals(JournalTemplateImpl.LANG_TYPE_VM)) {
548                     xsl = JournalUtil.formatVM(xsl);
549                 }
550                 else {
551                     xsl = JournalUtil.formatXML(xsl);
552                 }
553             }
554         }
555         catch (Exception e) {
556             throw new TemplateXslException();
557         }
558 
559         byte[] smallBytes = null;
560 
561         try {
562             smallBytes = FileUtil.getBytes(smallFile);
563         }
564         catch (IOException ioe) {
565         }
566 
567         validate(
568             name, description, xsl, smallImage, smallImageURL, smallFile,
569             smallBytes);
570 
571         JournalTemplate template = journalTemplatePersistence.findByG_T(
572             groupId, templateId);
573 
574         template.setModifiedDate(new Date());
575 
576         if (Validator.isNull(template.getStructureId()) &&
577             Validator.isNotNull(structureId)) {
578 
579             // Allow users to set the structure if and only if it currently
580             // does not have one. Otherwise, you can have bad data because there
581             // may be an existing article that has chosen to use a structure and
582             // template combination that no longer exists.
583 
584             template.setStructureId(structureId);
585         }
586 
587         template.setName(name);
588         template.setDescription(description);
589         template.setXsl(xsl);
590         template.setLangType(langType);
591         template.setCacheable(cacheable);
592         template.setSmallImage(smallImage);
593         template.setSmallImageURL(smallImageURL);
594 
595         journalTemplatePersistence.update(template, false);
596 
597         // Small image
598 
599         saveImages(
600             smallImage, template.getSmallImageId(), smallFile, smallBytes);
601 
602         return template;
603     }
604 
605     protected void saveImages(
606             boolean smallImage, long smallImageId, File smallFile,
607             byte[] smallBytes)
608         throws PortalException, SystemException {
609 
610         if (smallImage) {
611             if ((smallFile != null) && (smallBytes != null)) {
612                 imageLocalService.updateImage(smallImageId, smallBytes);
613             }
614         }
615         else {
616             imageLocalService.deleteImage(smallImageId);
617         }
618     }
619 
620     protected void validate(String templateId) throws PortalException {
621         if ((Validator.isNull(templateId)) ||
622             (Validator.isNumber(templateId)) ||
623             (templateId.indexOf(StringPool.SPACE) != -1)) {
624 
625             throw new TemplateIdException();
626         }
627     }
628 
629     protected void validate(
630             long groupId, String templateId, boolean autoTemplateId,
631             String name, String description, String xsl, boolean smallImage,
632             String smallImageURL, File smallFile, byte[] smallBytes)
633         throws PortalException, SystemException {
634 
635         if (!autoTemplateId) {
636             validate(templateId);
637 
638             JournalTemplate template = journalTemplatePersistence.fetchByG_T(
639                 groupId, templateId);
640 
641             if (template != null) {
642                 throw new DuplicateTemplateIdException();
643             }
644         }
645 
646         validate(
647             name, description, xsl, smallImage, smallImageURL, smallFile,
648             smallBytes);
649     }
650 
651     protected void validate(
652             String name, String description, String xsl, boolean smallImage,
653             String smallImageURL, File smallFile, byte[] smallBytes)
654         throws PortalException {
655 
656         if (Validator.isNull(name)) {
657             throw new TemplateNameException();
658         }
659         else if (Validator.isNull(description)) {
660             throw new TemplateDescriptionException();
661         }
662         else if (Validator.isNull(xsl)) {
663             throw new TemplateXslException();
664         }
665 
666         String[] imageExtensions =
667             PropsUtil.getArray(PropsKeys.JOURNAL_IMAGE_EXTENSIONS);
668 
669         if (smallImage && Validator.isNull(smallImageURL) &&
670             smallFile != null && smallBytes != null) {
671 
672             String smallImageName = smallFile.getName();
673 
674             if (smallImageName != null) {
675                 boolean validSmallImageExtension = false;
676 
677                 for (int i = 0; i < imageExtensions.length; i++) {
678                     if (StringPool.STAR.equals(imageExtensions[i]) ||
679                         StringUtil.endsWith(
680                             smallImageName, imageExtensions[i])) {
681 
682                         validSmallImageExtension = true;
683 
684                         break;
685                     }
686                 }
687 
688                 if (!validSmallImageExtension) {
689                     throw new TemplateSmallImageNameException(smallImageName);
690                 }
691             }
692 
693             long smallImageMaxSize = GetterUtil.getLong(
694                 PropsUtil.get(PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE));
695 
696             if ((smallImageMaxSize > 0) &&
697                 ((smallBytes == null) ||
698                     (smallBytes.length > smallImageMaxSize))) {
699 
700                 throw new TemplateSmallImageSizeException();
701             }
702         }
703     }
704 
705     private static Log _log =
706         LogFactoryUtil.getLog(JournalTemplateLocalServiceImpl.class);
707 
708 }