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