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(now);
132         template.setModifiedDate(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 
565         journalTemplatePersistence.update(template, false);
566 
567         // Expando
568 
569         ExpandoBridge expandoBridge = template.getExpandoBridge();
570 
571         expandoBridge.setAttributes(serviceContext);
572 
573         // Small image
574 
575         saveImages(
576             smallImage, template.getSmallImageId(), smallFile, smallBytes);
577 
578         return template;
579     }
580 
581     protected void saveImages(
582             boolean smallImage, long smallImageId, File smallFile,
583             byte[] smallBytes)
584         throws PortalException, SystemException {
585 
586         if (smallImage) {
587             if ((smallFile != null) && (smallBytes != null)) {
588                 imageLocalService.updateImage(smallImageId, smallBytes);
589             }
590         }
591         else {
592             imageLocalService.deleteImage(smallImageId);
593         }
594     }
595 
596     protected void validate(String templateId) throws PortalException {
597         if ((Validator.isNull(templateId)) ||
598             (Validator.isNumber(templateId)) ||
599             (templateId.indexOf(StringPool.SPACE) != -1)) {
600 
601             throw new TemplateIdException();
602         }
603     }
604 
605     protected void validate(
606             long groupId, String templateId, boolean autoTemplateId,
607             String name, String description, String xsl, boolean smallImage,
608             String smallImageURL, File smallFile, byte[] smallBytes)
609         throws PortalException, SystemException {
610 
611         if (!autoTemplateId) {
612             validate(templateId);
613 
614             JournalTemplate template = journalTemplatePersistence.fetchByG_T(
615                 groupId, templateId);
616 
617             if (template != null) {
618                 throw new DuplicateTemplateIdException();
619             }
620         }
621 
622         validate(
623             name, description, xsl, smallImage, smallImageURL, smallFile,
624             smallBytes);
625     }
626 
627     protected void validate(
628             String name, String description, String xsl, boolean smallImage,
629             String smallImageURL, File smallFile, byte[] smallBytes)
630         throws PortalException, SystemException {
631 
632         if (Validator.isNull(name)) {
633             throw new TemplateNameException();
634         }
635         else if (Validator.isNull(description)) {
636             throw new TemplateDescriptionException();
637         }
638         else if (Validator.isNull(xsl)) {
639             throw new TemplateXslException();
640         }
641 
642         String[] imageExtensions = PrefsPropsUtil.getStringArray(
643             PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
644 
645         if (smallImage && Validator.isNull(smallImageURL) &&
646             smallFile != null && smallBytes != null) {
647 
648             String smallImageName = smallFile.getName();
649 
650             if (smallImageName != null) {
651                 boolean validSmallImageExtension = false;
652 
653                 for (int i = 0; i < imageExtensions.length; i++) {
654                     if (StringPool.STAR.equals(imageExtensions[i]) ||
655                         StringUtil.endsWith(
656                             smallImageName, imageExtensions[i])) {
657 
658                         validSmallImageExtension = true;
659 
660                         break;
661                     }
662                 }
663 
664                 if (!validSmallImageExtension) {
665                     throw new TemplateSmallImageNameException(smallImageName);
666                 }
667             }
668 
669             long smallImageMaxSize = PrefsPropsUtil.getLong(
670                 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
671 
672             if ((smallImageMaxSize > 0) &&
673                 ((smallBytes == null) ||
674                     (smallBytes.length > smallImageMaxSize))) {
675 
676                 throw new TemplateSmallImageSizeException();
677             }
678         }
679     }
680 
681     private static Log _log = LogFactoryUtil.getLog(
682         JournalTemplateLocalServiceImpl.class);
683 
684 }