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