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