001    /**
002     * Copyright (c) 2000-2012 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.Group;
031    import com.liferay.portal.model.Image;
032    import com.liferay.portal.model.ResourceConstants;
033    import com.liferay.portal.model.User;
034    import com.liferay.portal.service.ServiceContext;
035    import com.liferay.portal.util.PortalUtil;
036    import com.liferay.portal.util.PrefsPropsUtil;
037    import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
038    import com.liferay.portlet.expando.model.ExpandoBridge;
039    import com.liferay.portlet.journal.DuplicateTemplateIdException;
040    import com.liferay.portlet.journal.NoSuchTemplateException;
041    import com.liferay.portlet.journal.RequiredTemplateException;
042    import com.liferay.portlet.journal.TemplateIdException;
043    import com.liferay.portlet.journal.TemplateNameException;
044    import com.liferay.portlet.journal.TemplateSmallImageNameException;
045    import com.liferay.portlet.journal.TemplateSmallImageSizeException;
046    import com.liferay.portlet.journal.TemplateXslException;
047    import com.liferay.portlet.journal.model.JournalStructure;
048    import com.liferay.portlet.journal.model.JournalTemplate;
049    import com.liferay.portlet.journal.model.JournalTemplateConstants;
050    import com.liferay.portlet.journal.service.base.JournalTemplateLocalServiceBaseImpl;
051    import com.liferay.portlet.journal.util.JournalUtil;
052    
053    import java.io.File;
054    import java.io.IOException;
055    
056    import java.util.Date;
057    import java.util.List;
058    import java.util.Locale;
059    import java.util.Map;
060    
061    /**
062     * @author Brian Wing Shun Chan
063     * @author Raymond Augé
064     */
065    public class JournalTemplateLocalServiceImpl
066            extends JournalTemplateLocalServiceBaseImpl {
067    
068            public JournalTemplate addTemplate(
069                            long userId, long groupId, String templateId,
070                            boolean autoTemplateId, String structureId,
071                            Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
072                            String xsl, boolean formatXsl, String langType, boolean cacheable,
073                            boolean smallImage, String smallImageURL, File smallImageFile,
074                            ServiceContext serviceContext)
075                    throws PortalException, SystemException {
076    
077                    // Template
078    
079                    User user = userPersistence.findByPrimaryKey(userId);
080                    templateId = templateId.trim().toUpperCase();
081                    Date now = new Date();
082    
083                    try {
084                            if (formatXsl) {
085                                    if (langType.equals(JournalTemplateConstants.LANG_TYPE_VM)) {
086                                            xsl = JournalUtil.formatVM(xsl);
087                                    }
088                                    else {
089                                            xsl = DDMXMLUtil.formatXML(xsl);
090                                    }
091                            }
092                    }
093                    catch (Exception e) {
094                            throw new TemplateXslException();
095                    }
096    
097                    byte[] smallImageBytes = null;
098    
099                    try {
100                            smallImageBytes = FileUtil.getBytes(smallImageFile);
101                    }
102                    catch (IOException ioe) {
103                    }
104    
105                    validate(
106                            groupId, templateId, autoTemplateId, nameMap, xsl, smallImage,
107                            smallImageURL, smallImageFile, smallImageBytes);
108    
109                    if (autoTemplateId) {
110                            templateId = String.valueOf(counterLocalService.increment());
111                    }
112    
113                    long id = counterLocalService.increment();
114    
115                    JournalTemplate template = journalTemplatePersistence.create(id);
116    
117                    template.setUuid(serviceContext.getUuid());
118                    template.setGroupId(groupId);
119                    template.setCompanyId(user.getCompanyId());
120                    template.setUserId(user.getUserId());
121                    template.setUserName(user.getFullName());
122                    template.setCreateDate(serviceContext.getCreateDate(now));
123                    template.setModifiedDate(serviceContext.getModifiedDate(now));
124                    template.setTemplateId(templateId);
125                    template.setStructureId(structureId);
126                    template.setNameMap(nameMap);
127                    template.setDescriptionMap(descriptionMap);
128                    template.setXsl(xsl);
129                    template.setLangType(langType);
130                    template.setCacheable(cacheable);
131                    template.setSmallImage(smallImage);
132                    template.setSmallImageId(counterLocalService.increment());
133                    template.setSmallImageURL(smallImageURL);
134    
135                    journalTemplatePersistence.update(template, false);
136    
137                    // Resources
138    
139                    if (serviceContext.isAddGroupPermissions() ||
140                            serviceContext.isAddGuestPermissions()) {
141    
142                            addTemplateResources(
143                                    template, serviceContext.isAddGroupPermissions(),
144                                    serviceContext.isAddGuestPermissions());
145                    }
146                    else {
147                            addTemplateResources(
148                                    template, serviceContext.getGroupPermissions(),
149                                    serviceContext.getGuestPermissions());
150                    }
151    
152                    // Expando
153    
154                    ExpandoBridge expandoBridge = template.getExpandoBridge();
155    
156                    expandoBridge.setAttributes(serviceContext);
157    
158                    // Small image
159    
160                    saveImages(
161                            smallImage, template.getSmallImageId(), smallImageFile,
162                            smallImageBytes);
163    
164                    return template;
165            }
166    
167            public void addTemplateResources(
168                            JournalTemplate template, boolean addGroupPermissions,
169                            boolean addGuestPermissions)
170                    throws PortalException, SystemException {
171    
172                    resourceLocalService.addResources(
173                            template.getCompanyId(), template.getGroupId(),
174                            template.getUserId(), JournalTemplate.class.getName(),
175                            template.getId(), false, addGroupPermissions, addGuestPermissions);
176            }
177    
178            public void addTemplateResources(
179                            JournalTemplate template, String[] groupPermissions,
180                            String[] guestPermissions)
181                    throws PortalException, SystemException {
182    
183                    resourceLocalService.addModelResources(
184                            template.getCompanyId(), template.getGroupId(),
185                            template.getUserId(), JournalTemplate.class.getName(),
186                            template.getId(), groupPermissions, guestPermissions);
187            }
188    
189            public void addTemplateResources(
190                            long groupId, String templateId, boolean addGroupPermissions,
191                            boolean addGuestPermissions)
192                    throws PortalException, SystemException {
193    
194                    JournalTemplate template = journalTemplatePersistence.findByG_T(
195                            groupId, templateId);
196    
197                    addTemplateResources(
198                            template, addGroupPermissions, addGuestPermissions);
199            }
200    
201            public void addTemplateResources(
202                            long groupId, String templateId, String[] groupPermissions,
203                            String[] guestPermissions)
204                    throws PortalException, SystemException {
205    
206                    JournalTemplate template = journalTemplatePersistence.findByG_T(
207                            groupId, templateId);
208    
209                    addTemplateResources(template, 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(JournalTemplate template)
304                    throws PortalException, SystemException {
305    
306                    Group companyGroup = groupLocalService.getCompanyGroup(
307                            template.getCompanyId());
308    
309                    if (template.getGroupId() == companyGroup.getGroupId()) {
310                            if (journalArticlePersistence.countByTemplateId(
311                                            template.getTemplateId()) > 0) {
312    
313                                    throw new RequiredTemplateException();
314                            }
315                    }
316                    else {
317                            if (journalArticlePersistence.countByG_C_T(
318                                            template.getGroupId(), 0, template.getTemplateId()) > 0) {
319    
320                                    throw new RequiredTemplateException();
321                            }
322                    }
323    
324                    // WebDAVProps
325    
326                    webDAVPropsLocalService.deleteWebDAVProps(
327                            JournalTemplate.class.getName(), template.getId());
328    
329                    // Small image
330    
331                    imageLocalService.deleteImage(template.getSmallImageId());
332    
333                    // Expando
334    
335                    expandoValueLocalService.deleteValues(
336                            JournalTemplate.class.getName(), template.getId());
337    
338                    // Resources
339    
340                    resourceLocalService.deleteResource(
341                            template.getCompanyId(), JournalTemplate.class.getName(),
342                            ResourceConstants.SCOPE_INDIVIDUAL, template.getId());
343    
344                    // Article
345    
346                    journalArticleLocalService.updateTemplateId(
347                            template.getGroupId(),
348                            PortalUtil.getClassNameId(JournalStructure.class.getName()),
349                            template.getTemplateId(), StringPool.BLANK);
350    
351                    // Template
352    
353                    journalTemplatePersistence.remove(template);
354            }
355    
356            public void deleteTemplate(long groupId, String templateId)
357                    throws PortalException, SystemException {
358    
359                    templateId = templateId.trim().toUpperCase();
360    
361                    JournalTemplate template = journalTemplatePersistence.findByG_T(
362                            groupId, templateId);
363    
364                    deleteTemplate(template);
365            }
366    
367            public void deleteTemplates(long groupId)
368                    throws PortalException, SystemException {
369    
370                    for (JournalTemplate template :
371                                    journalTemplatePersistence.findByGroupId(groupId)) {
372    
373                            deleteTemplate(template);
374                    }
375            }
376    
377            public List<JournalTemplate> getStructureTemplates(
378                            long groupId, String structureId)
379                    throws SystemException {
380    
381                    return journalTemplatePersistence.findByG_S(groupId, structureId);
382            }
383    
384            public List<JournalTemplate> getStructureTemplates(
385                            long groupId, String structureId, int start, int end)
386                    throws SystemException {
387    
388                    return journalTemplatePersistence.findByG_S(
389                            groupId, structureId, start, end);
390            }
391    
392            public int getStructureTemplatesCount(long groupId, String structureId)
393                    throws SystemException {
394    
395                    return journalTemplatePersistence.countByG_S(groupId, structureId);
396            }
397    
398            public JournalTemplate getTemplate(long id)
399                    throws PortalException, SystemException {
400    
401                    return journalTemplatePersistence.findByPrimaryKey(id);
402            }
403    
404            public JournalTemplate getTemplate(long groupId, String templateId)
405                    throws PortalException, SystemException {
406    
407                    templateId = GetterUtil.getString(templateId).toUpperCase();
408    
409                    if (groupId == 0) {
410                            _log.error(
411                                    "No group id was passed for " + templateId + ". Group id is " +
412                                            "required since 4.2.0. Please update all custom code and " +
413                                                    "data that references templates without a group id.");
414    
415                            List<JournalTemplate> templates =
416                                    journalTemplatePersistence.findByTemplateId(templateId);
417    
418                            if (templates.size() == 0) {
419                                    throw new NoSuchTemplateException(
420                                            "No JournalTemplate exists with the template id " +
421                                                    templateId);
422                            }
423                            else {
424                                    return templates.get(0);
425                            }
426                    }
427                    else {
428                            return journalTemplatePersistence.findByG_T(groupId, templateId);
429                    }
430            }
431    
432            public JournalTemplate getTemplateBySmallImageId(long smallImageId)
433                    throws PortalException, SystemException {
434    
435                    return journalTemplatePersistence.findBySmallImageId(smallImageId);
436            }
437    
438            public List<JournalTemplate> getTemplates() throws SystemException {
439                    return journalTemplatePersistence.findAll();
440            }
441    
442            public List<JournalTemplate> getTemplates(long groupId)
443                    throws SystemException {
444    
445                    return journalTemplatePersistence.findByGroupId(groupId);
446            }
447    
448            public List<JournalTemplate> getTemplates(long groupId, int start, int end)
449                    throws SystemException {
450    
451                    return journalTemplatePersistence.findByGroupId(groupId, start, end);
452            }
453    
454            public int getTemplatesCount(long groupId) throws SystemException {
455                    return journalTemplatePersistence.countByGroupId(groupId);
456            }
457    
458            public boolean hasTemplate(long groupId, String templateId)
459                    throws SystemException {
460    
461                    try {
462                            getTemplate(groupId, templateId);
463    
464                            return true;
465                    }
466                    catch (PortalException pe) {
467                            return false;
468                    }
469            }
470    
471            public List<JournalTemplate> search(
472                            long companyId, long[] groupIds, String keywords,
473                            String structureId, String structureIdComparator, int start,
474                            int end, OrderByComparator obc)
475                    throws SystemException {
476    
477                    return journalTemplateFinder.findByKeywords(
478                            companyId, groupIds, keywords, structureId, structureIdComparator,
479                            start, end, obc);
480            }
481    
482            public List<JournalTemplate> search(
483                            long companyId, long[] groupIds, String templateId,
484                            String structureId, String structureIdComparator, String name,
485                            String description, boolean andOperator, int start, int end,
486                            OrderByComparator obc)
487                    throws SystemException {
488    
489                    return journalTemplateFinder.findByC_G_T_S_N_D(
490                            companyId, groupIds, templateId, structureId, structureIdComparator,
491                            name, description, andOperator, start, end, obc);
492            }
493    
494            public int searchCount(
495                            long companyId, long[] groupIds, String keywords,
496                            String structureId, String structureIdComparator)
497                    throws SystemException {
498    
499                    return journalTemplateFinder.countByKeywords(
500                            companyId, groupIds, keywords, structureId, structureIdComparator);
501            }
502    
503            public int searchCount(
504                            long companyId, long[] groupIds, String templateId,
505                            String structureId, String structureIdComparator, String name,
506                            String description, boolean andOperator)
507                    throws SystemException {
508    
509                    return journalTemplateFinder.countByC_G_T_S_N_D(
510                            companyId, groupIds, templateId, structureId, structureIdComparator,
511                            name, description, andOperator);
512            }
513    
514            public JournalTemplate updateTemplate(
515                            long groupId, String templateId, String structureId,
516                            Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
517                            String xsl, boolean formatXsl, String langType, boolean cacheable,
518                            boolean smallImage, String smallImageURL, File smallImageFile,
519                            ServiceContext serviceContext)
520                    throws PortalException, SystemException {
521    
522                    // Template
523    
524                    templateId = templateId.trim().toUpperCase();
525    
526                    try {
527                            if (formatXsl) {
528                                    if (langType.equals(JournalTemplateConstants.LANG_TYPE_VM)) {
529                                            xsl = JournalUtil.formatVM(xsl);
530                                    }
531                                    else {
532                                            xsl = DDMXMLUtil.formatXML(xsl);
533                                    }
534                            }
535                    }
536                    catch (Exception e) {
537                            throw new TemplateXslException();
538                    }
539    
540                    byte[] smallImageBytes = null;
541    
542                    try {
543                            smallImageBytes = FileUtil.getBytes(smallImageFile);
544                    }
545                    catch (IOException ioe) {
546                    }
547    
548                    validate(
549                            nameMap, xsl, smallImage, smallImageURL, smallImageFile,
550                            smallImageBytes);
551    
552                    JournalTemplate template = journalTemplatePersistence.findByG_T(
553                            groupId, templateId);
554    
555                    template.setModifiedDate(new Date());
556    
557                    if (Validator.isNull(template.getStructureId()) &&
558                            Validator.isNotNull(structureId)) {
559    
560                            // Allow users to set the structure if and only if it currently
561                            // does not have one. Otherwise, you can have bad data because there
562                            // may be an existing article that has chosen to use a structure and
563                            // template combination that no longer exists.
564    
565                            template.setStructureId(structureId);
566                    }
567    
568                    template.setNameMap(nameMap);
569                    template.setDescriptionMap(descriptionMap);
570                    template.setXsl(xsl);
571                    template.setLangType(langType);
572                    template.setCacheable(cacheable);
573                    template.setSmallImage(smallImage);
574                    template.setSmallImageURL(smallImageURL);
575                    template.setModifiedDate(serviceContext.getModifiedDate(null));
576    
577                    journalTemplatePersistence.update(template, false);
578    
579                    // Expando
580    
581                    ExpandoBridge expandoBridge = template.getExpandoBridge();
582    
583                    expandoBridge.setAttributes(serviceContext);
584    
585                    // Small image
586    
587                    saveImages(
588                            smallImage, template.getSmallImageId(), smallImageFile,
589                            smallImageBytes);
590    
591                    return template;
592            }
593    
594            protected void saveImages(
595                            boolean smallImage, long smallImageId, File smallImageFile,
596                            byte[] smallImageBytes)
597                    throws PortalException, SystemException {
598    
599                    if (smallImage) {
600                            if ((smallImageFile != null) && (smallImageBytes != null)) {
601                                    imageLocalService.updateImage(smallImageId, smallImageBytes);
602                            }
603                    }
604                    else {
605                            imageLocalService.deleteImage(smallImageId);
606                    }
607            }
608    
609            protected void validate(
610                            long groupId, String templateId, boolean autoTemplateId,
611                            Map<Locale, String> nameMap, String xsl, boolean smallImage,
612                            String smallImageURL, File smallImageFile, byte[] smallImageBytes)
613                    throws PortalException, SystemException {
614    
615                    if (!autoTemplateId) {
616                            validate(templateId);
617    
618                            JournalTemplate template = journalTemplatePersistence.fetchByG_T(
619                                    groupId, templateId);
620    
621                            if (template != null) {
622                                    throw new DuplicateTemplateIdException();
623                            }
624                    }
625    
626                    validate(
627                            nameMap, xsl, smallImage, smallImageURL, smallImageFile,
628                            smallImageBytes);
629            }
630    
631            protected void validate(
632                            Map<Locale, String> nameMap, String xsl, boolean smallImage,
633                            String smallImageURL, File smallImageFile, byte[] smallImageBytes)
634                    throws PortalException, SystemException {
635    
636                    Locale locale = LocaleUtil.getDefault();
637    
638                    if (nameMap.isEmpty() || Validator.isNull(nameMap.get(locale))) {
639                            throw new TemplateNameException();
640                    }
641                    else if (Validator.isNull(xsl)) {
642                            throw new TemplateXslException();
643                    }
644    
645                    String[] imageExtensions = PrefsPropsUtil.getStringArray(
646                            PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
647    
648                    if (smallImage && Validator.isNull(smallImageURL) &&
649                            (smallImageFile != null) && (smallImageBytes != null)) {
650    
651                            String smallImageName = smallImageFile.getName();
652    
653                            if (smallImageName != null) {
654                                    boolean validSmallImageExtension = false;
655    
656                                    for (int i = 0; i < imageExtensions.length; i++) {
657                                            if (StringPool.STAR.equals(imageExtensions[i]) ||
658                                                    StringUtil.endsWith(
659                                                            smallImageName, imageExtensions[i])) {
660    
661                                                    validSmallImageExtension = true;
662    
663                                                    break;
664                                            }
665                                    }
666    
667                                    if (!validSmallImageExtension) {
668                                            throw new TemplateSmallImageNameException(smallImageName);
669                                    }
670                            }
671    
672                            long smallImageMaxSize = PrefsPropsUtil.getLong(
673                                    PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
674    
675                            if ((smallImageMaxSize > 0) &&
676                                    ((smallImageBytes == null) ||
677                                     (smallImageBytes.length > smallImageMaxSize))) {
678    
679                                    throw new TemplateSmallImageSizeException();
680                            }
681                    }
682            }
683    
684            protected void validate(String templateId) throws PortalException {
685                    if ((Validator.isNull(templateId)) ||
686                            (Validator.isNumber(templateId)) ||
687                            (templateId.indexOf(CharPool.SPACE) != -1)) {
688    
689                            throw new TemplateIdException();
690                    }
691            }
692    
693            private static Log _log = LogFactoryUtil.getLog(
694                    JournalTemplateLocalServiceImpl.class);
695    
696    }