001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.journal.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.util.CharPool;
022    import com.liferay.portal.kernel.util.FileUtil;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.LocaleUtil;
025    import com.liferay.portal.kernel.util.OrderByComparator;
026    import com.liferay.portal.kernel.util.PropsKeys;
027    import com.liferay.portal.kernel.util.StringPool;
028    import com.liferay.portal.kernel.util.StringUtil;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.model.Image;
031    import com.liferay.portal.model.ResourceConstants;
032    import com.liferay.portal.model.User;
033    import com.liferay.portal.service.ServiceContext;
034    import com.liferay.portal.util.PortalUtil;
035    import com.liferay.portal.util.PrefsPropsUtil;
036    import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
037    import com.liferay.portlet.expando.model.ExpandoBridge;
038    import com.liferay.portlet.journal.DuplicateTemplateIdException;
039    import com.liferay.portlet.journal.NoSuchTemplateException;
040    import com.liferay.portlet.journal.RequiredTemplateException;
041    import com.liferay.portlet.journal.TemplateIdException;
042    import com.liferay.portlet.journal.TemplateNameException;
043    import com.liferay.portlet.journal.TemplateSmallImageNameException;
044    import com.liferay.portlet.journal.TemplateSmallImageSizeException;
045    import com.liferay.portlet.journal.TemplateXslException;
046    import com.liferay.portlet.journal.model.JournalStructure;
047    import com.liferay.portlet.journal.model.JournalTemplate;
048    import com.liferay.portlet.journal.model.JournalTemplateConstants;
049    import com.liferay.portlet.journal.service.base.JournalTemplateLocalServiceBaseImpl;
050    import com.liferay.portlet.journal.util.JournalUtil;
051    
052    import java.io.File;
053    import java.io.IOException;
054    
055    import java.util.Date;
056    import java.util.List;
057    import java.util.Locale;
058    import java.util.Map;
059    
060    /**
061     * @author Brian Wing Shun Chan
062     * @author Raymond Augé
063     */
064    public class JournalTemplateLocalServiceImpl
065            extends JournalTemplateLocalServiceBaseImpl {
066    
067            public JournalTemplate addTemplate(
068                            long userId, long groupId, String templateId,
069                            boolean autoTemplateId, String structureId,
070                            Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
071                            String xsl, boolean formatXsl, String langType, boolean cacheable,
072                            boolean smallImage, String smallImageURL, File smallImageFile,
073                            ServiceContext serviceContext)
074                    throws PortalException, SystemException {
075    
076                    // Template
077    
078                    User user = userPersistence.findByPrimaryKey(userId);
079                    templateId = templateId.trim().toUpperCase();
080                    Date now = new Date();
081    
082                    try {
083                            if (formatXsl) {
084                                    if (langType.equals(JournalTemplateConstants.LANG_TYPE_VM)) {
085                                            xsl = JournalUtil.formatVM(xsl);
086                                    }
087                                    else {
088                                            xsl = DDMXMLUtil.formatXML(xsl);
089                                    }
090                            }
091                    }
092                    catch (Exception e) {
093                            throw new TemplateXslException();
094                    }
095    
096                    byte[] smallImageBytes = null;
097    
098                    try {
099                            smallImageBytes = FileUtil.getBytes(smallImageFile);
100                    }
101                    catch (IOException ioe) {
102                    }
103    
104                    validate(
105                            groupId, templateId, autoTemplateId, nameMap, xsl, smallImage,
106                            smallImageURL, smallImageFile, smallImageBytes);
107    
108                    if (autoTemplateId) {
109                            templateId = String.valueOf(counterLocalService.increment());
110                    }
111    
112                    long id = counterLocalService.increment();
113    
114                    JournalTemplate template = journalTemplatePersistence.create(id);
115    
116                    template.setUuid(serviceContext.getUuid());
117                    template.setGroupId(groupId);
118                    template.setCompanyId(user.getCompanyId());
119                    template.setUserId(user.getUserId());
120                    template.setUserName(user.getFullName());
121                    template.setCreateDate(serviceContext.getCreateDate(now));
122                    template.setModifiedDate(serviceContext.getModifiedDate(now));
123                    template.setTemplateId(templateId);
124                    template.setStructureId(structureId);
125                    template.setNameMap(nameMap);
126                    template.setDescriptionMap(descriptionMap);
127                    template.setXsl(xsl);
128                    template.setLangType(langType);
129                    template.setCacheable(cacheable);
130                    template.setSmallImage(smallImage);
131                    template.setSmallImageId(counterLocalService.increment());
132                    template.setSmallImageURL(smallImageURL);
133    
134                    journalTemplatePersistence.update(template, false);
135    
136                    // Resources
137    
138                    if (serviceContext.getAddGroupPermissions() ||
139                            serviceContext.getAddGuestPermissions()) {
140    
141                            addTemplateResources(
142                                    template, serviceContext.getAddGroupPermissions(),
143                                    serviceContext.getAddGuestPermissions());
144                    }
145                    else {
146                            addTemplateResources(
147                                    template, serviceContext.getGroupPermissions(),
148                                    serviceContext.getGuestPermissions());
149                    }
150    
151                    // Expando
152    
153                    ExpandoBridge expandoBridge = template.getExpandoBridge();
154    
155                    expandoBridge.setAttributes(serviceContext);
156    
157                    // Small image
158    
159                    saveImages(
160                            smallImage, template.getSmallImageId(), smallImageFile,
161                            smallImageBytes);
162    
163                    return template;
164            }
165    
166            public void addTemplateResources(
167                            long groupId, String templateId, boolean addGroupPermissions,
168                            boolean addGuestPermissions)
169                    throws PortalException, SystemException {
170    
171                    JournalTemplate template = journalTemplatePersistence.findByG_T(
172                            groupId, templateId);
173    
174                    addTemplateResources(
175                            template, addGroupPermissions, addGuestPermissions);
176            }
177    
178            public void addTemplateResources(
179                            JournalTemplate template, boolean addGroupPermissions,
180                            boolean addGuestPermissions)
181                    throws PortalException, SystemException {
182    
183                    resourceLocalService.addResources(
184                            template.getCompanyId(), template.getGroupId(),
185                            template.getUserId(), JournalTemplate.class.getName(),
186                            template.getId(), false, addGroupPermissions,
187                            addGuestPermissions);
188            }
189    
190            public void addTemplateResources(
191                            long groupId, String templateId, String[] groupPermissions,
192                            String[] guestPermissions)
193                    throws PortalException, SystemException {
194    
195                    JournalTemplate template = journalTemplatePersistence.findByG_T(
196                            groupId, templateId);
197    
198                    addTemplateResources(template, groupPermissions, guestPermissions);
199            }
200    
201            public void addTemplateResources(
202                            JournalTemplate template, String[] groupPermissions,
203                            String[] guestPermissions)
204                    throws PortalException, SystemException {
205    
206                    resourceLocalService.addModelResources(
207                            template.getCompanyId(), template.getGroupId(),
208                            template.getUserId(), JournalTemplate.class.getName(),
209                            template.getId(), groupPermissions, guestPermissions);
210            }
211    
212            public void checkNewLine(long groupId, String templateId)
213                    throws PortalException, SystemException {
214    
215                    JournalTemplate template = journalTemplatePersistence.findByG_T(
216                            groupId, templateId);
217    
218                    String xsl = template.getXsl();
219    
220                    if ((xsl != null) && (xsl.indexOf("\\n") != -1)) {
221                            xsl = StringUtil.replace(
222                                    xsl,
223                                    new String[] {"\\n", "\\r"},
224                                    new String[] {"\n", "\r"});
225    
226                            template.setXsl(xsl);
227    
228                            journalTemplatePersistence.update(template, false);
229                    }
230            }
231    
232            public JournalTemplate copyTemplate(
233                            long userId, long groupId, String oldTemplateId,
234                            String newTemplateId, boolean autoTemplateId)
235                    throws PortalException, SystemException {
236    
237                    // Template
238    
239                    User user = userPersistence.findByPrimaryKey(userId);
240                    oldTemplateId = oldTemplateId.trim().toUpperCase();
241                    newTemplateId = newTemplateId.trim().toUpperCase();
242                    Date now = new Date();
243    
244                    JournalTemplate oldTemplate = journalTemplatePersistence.findByG_T(
245                            groupId, oldTemplateId);
246    
247                    if (autoTemplateId) {
248                            newTemplateId = String.valueOf(counterLocalService.increment());
249                    }
250                    else {
251                            validate(newTemplateId);
252    
253                            JournalTemplate newTemplate = journalTemplatePersistence.fetchByG_T(
254                                    groupId, newTemplateId);
255    
256                            if (newTemplate != null) {
257                                    throw new DuplicateTemplateIdException();
258                            }
259                    }
260    
261                    long id = counterLocalService.increment();
262    
263                    JournalTemplate newTemplate = journalTemplatePersistence.create(id);
264    
265                    newTemplate.setGroupId(groupId);
266                    newTemplate.setCompanyId(user.getCompanyId());
267                    newTemplate.setUserId(user.getUserId());
268                    newTemplate.setUserName(user.getFullName());
269                    newTemplate.setCreateDate(now);
270                    newTemplate.setModifiedDate(now);
271                    newTemplate.setTemplateId(newTemplateId);
272                    newTemplate.setStructureId(oldTemplate.getStructureId());
273                    newTemplate.setNameMap(oldTemplate.getNameMap());
274                    newTemplate.setDescriptionMap(oldTemplate.getDescriptionMap());
275                    newTemplate.setXsl(oldTemplate.getXsl());
276                    newTemplate.setLangType(oldTemplate.getLangType());
277                    newTemplate.setCacheable(oldTemplate.isCacheable());
278                    newTemplate.setSmallImage(oldTemplate.isSmallImage());
279                    newTemplate.setSmallImageId(counterLocalService.increment());
280                    newTemplate.setSmallImageURL(oldTemplate.getSmallImageURL());
281    
282                    journalTemplatePersistence.update(newTemplate, false);
283    
284                    // Small image
285    
286                    if (oldTemplate.getSmallImage()) {
287                            Image image = imageLocalService.getImage(
288                                    oldTemplate.getSmallImageId());
289    
290                            byte[] smallImageBytes = image.getTextObj();
291    
292                            imageLocalService.updateImage(
293                                    newTemplate.getSmallImageId(), smallImageBytes);
294                    }
295    
296                    // Resources
297    
298                    addTemplateResources(newTemplate, true, true);
299    
300                    return newTemplate;
301            }
302    
303            public void deleteTemplate(long groupId, String templateId)
304                    throws PortalException, SystemException {
305    
306                    templateId = templateId.trim().toUpperCase();
307    
308                    JournalTemplate template = journalTemplatePersistence.findByG_T(
309                            groupId, templateId);
310    
311                    deleteTemplate(template);
312            }
313    
314            public void deleteTemplate(JournalTemplate template)
315                    throws PortalException, SystemException {
316    
317                    if (journalArticlePersistence.countByG_C_T(
318                                    template.getGroupId(), 0, template.getTemplateId()) > 0) {
319    
320                            throw new RequiredTemplateException();
321                    }
322    
323                    // WebDAVProps
324    
325                    webDAVPropsLocalService.deleteWebDAVProps(
326                            JournalTemplate.class.getName(), template.getId());
327    
328                    // Small image
329    
330                    imageLocalService.deleteImage(template.getSmallImageId());
331    
332                    // Expando
333    
334                    expandoValueLocalService.deleteValues(
335                            JournalTemplate.class.getName(), template.getId());
336    
337                    // Resources
338    
339                    resourceLocalService.deleteResource(
340                            template.getCompanyId(), JournalTemplate.class.getName(),
341                            ResourceConstants.SCOPE_INDIVIDUAL, template.getId());
342    
343                    // Article
344    
345                    journalArticleLocalService.updateTemplateId(
346                            template.getGroupId(),
347                            PortalUtil.getClassNameId(JournalStructure.class.getName()),
348                            template.getTemplateId(), StringPool.BLANK);
349    
350                    // Template
351    
352                    journalTemplatePersistence.remove(template);
353            }
354    
355            public void deleteTemplates(long groupId)
356                    throws PortalException, SystemException {
357    
358                    for (JournalTemplate template :
359                                    journalTemplatePersistence.findByGroupId(groupId)) {
360    
361                            deleteTemplate(template);
362                    }
363            }
364    
365            public List<JournalTemplate> getStructureTemplates(
366                            long groupId, String structureId)
367                    throws SystemException {
368    
369                    return journalTemplatePersistence.findByG_S(groupId, structureId);
370            }
371    
372            public List<JournalTemplate> getStructureTemplates(
373                            long groupId, String structureId, int start, int end)
374                    throws SystemException {
375    
376                    return journalTemplatePersistence.findByG_S(
377                            groupId, structureId, start, end);
378            }
379    
380            public int getStructureTemplatesCount(long groupId, String structureId)
381                    throws SystemException {
382    
383                    return journalTemplatePersistence.countByG_S(groupId, structureId);
384            }
385    
386            public JournalTemplate getTemplate(long id)
387                    throws PortalException, SystemException {
388    
389                    return journalTemplatePersistence.findByPrimaryKey(id);
390            }
391    
392            public JournalTemplate getTemplate(long groupId, String templateId)
393                    throws PortalException, SystemException {
394    
395                    templateId = GetterUtil.getString(templateId).toUpperCase();
396    
397                    if (groupId == 0) {
398                            _log.error(
399                                    "No group id was passed for " + templateId + ". Group id is " +
400                                            "required since 4.2.0. Please update all custom code and " +
401                                                    "data that references templates without a group id.");
402    
403                            List<JournalTemplate> templates =
404                                    journalTemplatePersistence.findByTemplateId(templateId);
405    
406                            if (templates.size() == 0) {
407                                    throw new NoSuchTemplateException(
408                                            "No JournalTemplate exists with the template id " +
409                                                    templateId);
410                            }
411                            else {
412                                    return templates.get(0);
413                            }
414                    }
415                    else {
416                            return journalTemplatePersistence.findByG_T(groupId, templateId);
417                    }
418            }
419    
420            public JournalTemplate getTemplateBySmallImageId(long smallImageId)
421                    throws PortalException, SystemException {
422    
423                    return journalTemplatePersistence.findBySmallImageId(smallImageId);
424            }
425    
426            public List<JournalTemplate> getTemplates() throws SystemException {
427                    return journalTemplatePersistence.findAll();
428            }
429    
430            public List<JournalTemplate> getTemplates(long groupId)
431                    throws SystemException {
432    
433                    return journalTemplatePersistence.findByGroupId(groupId);
434            }
435    
436            public List<JournalTemplate> getTemplates(long groupId, int start, int end)
437                    throws SystemException {
438    
439                    return journalTemplatePersistence.findByGroupId(groupId, start, end);
440            }
441    
442            public int getTemplatesCount(long groupId) throws SystemException {
443                    return journalTemplatePersistence.countByGroupId(groupId);
444            }
445    
446            public boolean hasTemplate(long groupId, String templateId)
447                    throws SystemException {
448    
449                    try {
450                            getTemplate(groupId, templateId);
451    
452                            return true;
453                    }
454                    catch (PortalException pe) {
455                            return false;
456                    }
457            }
458    
459            public List<JournalTemplate> search(
460                            long companyId, long[] groupIds, String keywords,
461                            String structureId, String structureIdComparator, int start,
462                            int end, OrderByComparator obc)
463                    throws SystemException {
464    
465                    return journalTemplateFinder.findByKeywords(
466                            companyId, groupIds, keywords, structureId, structureIdComparator,
467                            start, end, obc);
468            }
469    
470            public List<JournalTemplate> search(
471                            long companyId, long[] groupIds, String templateId,
472                            String structureId, String structureIdComparator, String name,
473                            String description, boolean andOperator, int start, int end,
474                            OrderByComparator obc)
475                    throws SystemException {
476    
477                    return journalTemplateFinder.findByC_G_T_S_N_D(
478                            companyId, groupIds, templateId, structureId, structureIdComparator,
479                            name, description, andOperator, start, end, obc);
480            }
481    
482            public int searchCount(
483                            long companyId, long[] groupIds, String keywords,
484                            String structureId, String structureIdComparator)
485                    throws SystemException {
486    
487                    return journalTemplateFinder.countByKeywords(
488                            companyId, groupIds, keywords, structureId, structureIdComparator);
489            }
490    
491            public int searchCount(
492                            long companyId, long[] groupIds, String templateId,
493                            String structureId, String structureIdComparator, String name,
494                            String description,
495                            boolean andOperator)
496                    throws SystemException {
497    
498                    return journalTemplateFinder.countByC_G_T_S_N_D(
499                            companyId, groupIds, templateId, structureId, structureIdComparator,
500                            name, description, andOperator);
501            }
502    
503            public JournalTemplate updateTemplate(
504                            long groupId, String templateId, String structureId,
505                            Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
506                            String xsl, boolean formatXsl, String langType, boolean cacheable,
507                            boolean smallImage, String smallImageURL, File smallImageFile,
508                            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 = DDMXMLUtil.formatXML(xsl);
522                                    }
523                            }
524                    }
525                    catch (Exception e) {
526                            throw new TemplateXslException();
527                    }
528    
529                    byte[] smallImageBytes = null;
530    
531                    try {
532                            smallImageBytes = FileUtil.getBytes(smallImageFile);
533                    }
534                    catch (IOException ioe) {
535                    }
536    
537                    validate(
538                            nameMap, xsl, smallImage, smallImageURL, smallImageFile,
539                            smallImageBytes);
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.setNameMap(nameMap);
558                    template.setDescriptionMap(descriptionMap);
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(), smallImageFile,
578                            smallImageBytes);
579    
580                    return template;
581            }
582    
583            protected void saveImages(
584                            boolean smallImage, long smallImageId, File smallImageFile,
585                            byte[] smallImageBytes)
586                    throws PortalException, SystemException {
587    
588                    if (smallImage) {
589                            if ((smallImageFile != null) && (smallImageBytes != null)) {
590                                    imageLocalService.updateImage(smallImageId, smallImageBytes);
591                            }
592                    }
593                    else {
594                            imageLocalService.deleteImage(smallImageId);
595                    }
596            }
597    
598            protected void validate(String templateId) throws PortalException {
599                    if ((Validator.isNull(templateId)) ||
600                            (Validator.isNumber(templateId)) ||
601                            (templateId.indexOf(CharPool.SPACE) != -1)) {
602    
603                            throw new TemplateIdException();
604                    }
605            }
606    
607            protected void validate(
608                            long groupId, String templateId, boolean autoTemplateId,
609                            Map<Locale, String> nameMap, String xsl, boolean smallImage,
610                            String smallImageURL, File smallImageFile, byte[] smallImageBytes)
611                    throws PortalException, SystemException {
612    
613                    if (!autoTemplateId) {
614                            validate(templateId);
615    
616                            JournalTemplate template = journalTemplatePersistence.fetchByG_T(
617                                    groupId, templateId);
618    
619                            if (template != null) {
620                                    throw new DuplicateTemplateIdException();
621                            }
622                    }
623    
624                    validate(
625                            nameMap, xsl, smallImage, smallImageURL, smallImageFile,
626                            smallImageBytes);
627            }
628    
629            protected void validate(
630                            Map<Locale, String> nameMap, String xsl, boolean smallImage,
631                            String smallImageURL, File smallImageFile, byte[] smallImageBytes)
632                    throws PortalException, SystemException {
633    
634                    Locale locale = LocaleUtil.getDefault();
635    
636                    if (nameMap.isEmpty() || Validator.isNull(nameMap.get(locale))) {
637                            throw new TemplateNameException();
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                            (smallImageFile != null) && (smallImageBytes != null)) {
648    
649                            String smallImageName = smallImageFile.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                                    ((smallImageBytes == null) ||
675                                     (smallImageBytes.length > smallImageMaxSize))) {
676    
677                                    throw new TemplateSmallImageSizeException();
678                            }
679                    }
680            }
681    
682            private static Log _log = LogFactoryUtil.getLog(
683                    JournalTemplateLocalServiceImpl.class);
684    
685    }