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