001    /**
002     * Copyright (c) 2000-present 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.dynamicdatamapping.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.systemevent.SystemEvent;
021    import com.liferay.portal.kernel.template.TemplateConstants;
022    import com.liferay.portal.kernel.util.FileUtil;
023    import com.liferay.portal.kernel.util.LocaleUtil;
024    import com.liferay.portal.kernel.util.OrderByComparator;
025    import com.liferay.portal.kernel.util.PropsKeys;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.util.StringUtil;
028    import com.liferay.portal.kernel.util.Validator;
029    import com.liferay.portal.model.Group;
030    import com.liferay.portal.model.Image;
031    import com.liferay.portal.model.ResourceConstants;
032    import com.liferay.portal.model.SystemEventConstants;
033    import com.liferay.portal.model.User;
034    import com.liferay.portal.service.ServiceContext;
035    import com.liferay.portal.service.persistence.ImageUtil;
036    import com.liferay.portal.util.PortalUtil;
037    import com.liferay.portal.util.PrefsPropsUtil;
038    import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
039    import com.liferay.portlet.dynamicdatamapping.RequiredTemplateException;
040    import com.liferay.portlet.dynamicdatamapping.TemplateDuplicateTemplateKeyException;
041    import com.liferay.portlet.dynamicdatamapping.TemplateNameException;
042    import com.liferay.portlet.dynamicdatamapping.TemplateScriptException;
043    import com.liferay.portlet.dynamicdatamapping.TemplateSmallImageNameException;
044    import com.liferay.portlet.dynamicdatamapping.TemplateSmallImageSizeException;
045    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
046    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
047    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
048    import com.liferay.portlet.dynamicdatamapping.service.base.DDMTemplateLocalServiceBaseImpl;
049    import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
050    import com.liferay.portlet.journal.model.JournalArticle;
051    import com.liferay.portlet.journal.model.JournalArticleConstants;
052    import com.liferay.portlet.journal.service.persistence.JournalArticleUtil;
053    
054    import java.io.File;
055    import java.io.IOException;
056    
057    import java.util.ArrayList;
058    import java.util.Date;
059    import java.util.List;
060    import java.util.Locale;
061    import java.util.Map;
062    
063    /**
064     * Provides the local service for accessing, adding, copying, deleting, and
065     * updating dynamic data mapping (DDM) templates.
066     *
067     * <p>
068     * DDM templates (templates) are used in Liferay to render templated content
069     * like applications, forms, dynamic data lists, or web contents.
070     * </p>
071     *
072     * <p>
073     * Templates support a variety of templating languages, like Velocity or
074     * FreeMarker. They also support multi-language names and descriptions.
075     * </p>
076     *
077     * <p>
078     * Templates can be related to many models in Liferay, such as those for
079     * structures, dynamic data lists, and applications. This relationship can be
080     * established via the class name ID and class PK.
081     * </p>
082     *
083     * @author Brian Wing Shun Chan
084     * @author Eduardo Lundgren
085     * @author Marcellus Tavares
086     */
087    public class DDMTemplateLocalServiceImpl
088            extends DDMTemplateLocalServiceBaseImpl {
089    
090            /**
091             * Adds a template.
092             *
093             * @param  userId the primary key of the template's creator/owner
094             * @param  groupId the primary key of the group
095             * @param  classNameId the primary key of the class name for the template's
096             *         related model
097             * @param  classPK the primary key of the template's related entity
098             * @param  nameMap the template's locales and localized names
099             * @param  descriptionMap the template's locales and localized descriptions
100             * @param  type the template's type. For more information, see {@link
101             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
102             * @param  mode the template's mode. For more information, see {@link
103             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
104             * @param  language the template's script language. For more information,
105             *         see {@link
106             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
107             * @param  script the template's script
108             * @param  serviceContext the service context to be applied. Can set the
109             *         UUID, creation date, modification date, guest permissions, and
110             *         group permissions for the template.
111             * @return the template
112             * @throws PortalException if a portal exception occurred
113             */
114            @Override
115            public DDMTemplate addTemplate(
116                            long userId, long groupId, long classNameId, long classPK,
117                            Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
118                            String type, String mode, String language, String script,
119                            ServiceContext serviceContext)
120                    throws PortalException {
121    
122                    return addTemplate(
123                            userId, groupId, classNameId, classPK, null, nameMap,
124                            descriptionMap, type, mode, language, script, false, false, null,
125                            null, serviceContext);
126            }
127    
128            /**
129             * Adds a template with additional parameters.
130             *
131             * @param  userId the primary key of the template's creator/owner
132             * @param  groupId the primary key of the group
133             * @param  classNameId the primary key of the class name for the template's
134             *         related model
135             * @param  classPK the primary key of the template's related entity
136             * @param  templateKey the unique string identifying the template
137             *         (optionally <code>null</code>)
138             * @param  nameMap the template's locales and localized names
139             * @param  descriptionMap the template's locales and localized descriptions
140             * @param  type the template's type. For more information, see {@link
141             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
142             * @param  mode the template's mode. For more information, see {@link
143             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
144             * @param  language the template's script language. For more information,
145             *         see {@link
146             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
147             * @param  script the template's script
148             * @param  cacheable whether the template is cacheable
149             * @param  smallImage whether the template has a small image
150             * @param  smallImageURL the template's small image URL (optionally
151             *         <code>null</code>)
152             * @param  smallImageFile the template's small image file (optionally
153             *         <code>null</code>)
154             * @param  serviceContext the service context to be applied. Can set the
155             *         UUID, creation date, modification date, guest permissions, and
156             *         group permissions for the template.
157             * @return the template
158             * @throws PortalException if a portal exception occurred
159             */
160            @Override
161            public DDMTemplate addTemplate(
162                            long userId, long groupId, long classNameId, long classPK,
163                            String templateKey, Map<Locale, String> nameMap,
164                            Map<Locale, String> descriptionMap, String type, String mode,
165                            String language, String script, boolean cacheable,
166                            boolean smallImage, String smallImageURL, File smallImageFile,
167                            ServiceContext serviceContext)
168                    throws PortalException {
169    
170                    // Template
171    
172                    User user = userPersistence.findByPrimaryKey(userId);
173                    Date now = new Date();
174    
175                    if (Validator.isNull(templateKey)) {
176                            templateKey = String.valueOf(counterLocalService.increment());
177                    }
178                    else {
179                            templateKey = StringUtil.toUpperCase(templateKey.trim());
180                    }
181    
182                    script = formatScript(type, language, script);
183    
184                    byte[] smallImageBytes = null;
185    
186                    if (smallImage) {
187                            try {
188                                    smallImageBytes = FileUtil.getBytes(smallImageFile);
189                            }
190                            catch (IOException ioe) {
191                            }
192    
193                            if ((smallImageBytes == null) || Validator.isUrl(smallImageURL)) {
194                                    smallImage = false;
195                            }
196                    }
197    
198                    validate(
199                            groupId, classNameId, templateKey, nameMap, script, smallImage,
200                            smallImageURL, smallImageFile, smallImageBytes);
201    
202                    long templateId = counterLocalService.increment();
203    
204                    DDMTemplate template = ddmTemplatePersistence.create(templateId);
205    
206                    template.setUuid(serviceContext.getUuid());
207                    template.setGroupId(groupId);
208                    template.setCompanyId(user.getCompanyId());
209                    template.setUserId(user.getUserId());
210                    template.setUserName(user.getFullName());
211                    template.setCreateDate(serviceContext.getCreateDate(now));
212                    template.setModifiedDate(serviceContext.getModifiedDate(now));
213                    template.setClassNameId(classNameId);
214                    template.setClassPK(classPK);
215                    template.setTemplateKey(templateKey);
216                    template.setNameMap(nameMap);
217                    template.setDescriptionMap(descriptionMap);
218                    template.setType(type);
219                    template.setMode(mode);
220                    template.setLanguage(language);
221                    template.setScript(script);
222                    template.setCacheable(cacheable);
223                    template.setSmallImage(smallImage);
224                    template.setSmallImageId(counterLocalService.increment());
225                    template.setSmallImageURL(smallImageURL);
226    
227                    ddmTemplatePersistence.update(template);
228    
229                    // Resources
230    
231                    if (serviceContext.isAddGroupPermissions() ||
232                            serviceContext.isAddGuestPermissions()) {
233    
234                            addTemplateResources(
235                                    template, serviceContext.isAddGroupPermissions(),
236                                    serviceContext.isAddGuestPermissions());
237                    }
238                    else {
239                            addTemplateResources(
240                                    template, serviceContext.getGroupPermissions(),
241                                    serviceContext.getGuestPermissions());
242                    }
243    
244                    // Small image
245    
246                    saveImages(
247                            smallImage, template.getSmallImageId(), smallImageFile,
248                            smallImageBytes);
249    
250                    return template;
251            }
252    
253            /**
254             * Adds the resources to the template.
255             *
256             * @param  template the template to add resources to
257             * @param  addGroupPermissions whether to add group permissions
258             * @param  addGuestPermissions whether to add guest permissions
259             * @throws PortalException if a portal exception occurred
260             */
261            @Override
262            public void addTemplateResources(
263                            DDMTemplate template, boolean addGroupPermissions,
264                            boolean addGuestPermissions)
265                    throws PortalException {
266    
267                    resourceLocalService.addResources(
268                            template.getCompanyId(), template.getGroupId(),
269                            template.getUserId(), DDMTemplate.class.getName(),
270                            template.getTemplateId(), false, addGroupPermissions,
271                            addGuestPermissions);
272            }
273    
274            /**
275             * Adds the model resources with the permissions to the template.
276             *
277             * @param  template the template to add resources to
278             * @param  groupPermissions the group permissions to be added
279             * @param  guestPermissions the guest permissions to be added
280             * @throws PortalException if a portal exception occurred
281             */
282            @Override
283            public void addTemplateResources(
284                            DDMTemplate template, String[] groupPermissions,
285                            String[] guestPermissions)
286                    throws PortalException {
287    
288                    resourceLocalService.addModelResources(
289                            template.getCompanyId(), template.getGroupId(),
290                            template.getUserId(), DDMTemplate.class.getName(),
291                            template.getTemplateId(), groupPermissions, guestPermissions);
292            }
293    
294            /**
295             * Copies the template, creating a new template with all the values
296             * extracted from the original one. This method supports defining a new name
297             * and description.
298             *
299             * @param  userId the primary key of the template's creator/owner
300             * @param  templateId the primary key of the template to be copied
301             * @param  nameMap the new template's locales and localized names
302             * @param  descriptionMap the new template's locales and localized
303             *         descriptions
304             * @param  serviceContext the service context to be applied. Can set the
305             *         UUID, creation date, modification date, guest permissions, and
306             *         group permissions for the template.
307             * @return the new template
308             * @throws PortalException if a portal exception occurred
309             */
310            @Override
311            public DDMTemplate copyTemplate(
312                            long userId, long templateId, Map<Locale, String> nameMap,
313                            Map<Locale, String> descriptionMap, ServiceContext serviceContext)
314                    throws PortalException {
315    
316                    DDMTemplate template = ddmTemplatePersistence.findByPrimaryKey(
317                            templateId);
318    
319                    return copyTemplate(
320                            userId, template, template.getClassPK(), nameMap, descriptionMap,
321                            serviceContext);
322            }
323    
324            @Override
325            public DDMTemplate copyTemplate(
326                            long userId, long templateId, ServiceContext serviceContext)
327                    throws PortalException {
328    
329                    DDMTemplate template = ddmTemplatePersistence.findByPrimaryKey(
330                            templateId);
331    
332                    return copyTemplate(
333                            userId, template, template.getClassPK(), template.getNameMap(),
334                            template.getDescriptionMap(), serviceContext);
335            }
336    
337            /**
338             * Copies all the templates matching the class name ID, class PK, and type.
339             * This method creates new templates, extracting all the values from the old
340             * ones and updating their class PKs.
341             *
342             * @param  userId the primary key of the template's creator/owner
343             * @param  classNameId the primary key of the class name for the template's
344             *         related model
345             * @param  oldClassPK the primary key of the old template's related entity
346             * @param  newClassPK the primary key of the new template's related entity
347             * @param  type the template's type. For more information, see {@link
348             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
349             * @param  serviceContext the service context to be applied. Can set the
350             *         creation date, modification date, guest permissions, and group
351             *         permissions for the new templates.
352             * @return the new templates
353             * @throws PortalException if a portal exception occurred
354             */
355            @Override
356            public List<DDMTemplate> copyTemplates(
357                            long userId, long classNameId, long oldClassPK, long newClassPK,
358                            String type, ServiceContext serviceContext)
359                    throws PortalException {
360    
361                    List<DDMTemplate> newTemplates = new ArrayList<DDMTemplate>();
362    
363                    List<DDMTemplate> oldTemplates = ddmTemplatePersistence.findByC_C_T(
364                            classNameId, oldClassPK, type);
365    
366                    for (DDMTemplate oldTemplate : oldTemplates) {
367                            DDMTemplate newTemplate = copyTemplate(
368                                    userId, oldTemplate, newClassPK, oldTemplate.getNameMap(),
369                                    oldTemplate.getDescriptionMap(), serviceContext);
370    
371                            newTemplates.add(newTemplate);
372                    }
373    
374                    return newTemplates;
375            }
376    
377            /**
378             * Deletes the template and its resources.
379             *
380             * @param  template the template to be deleted
381             * @throws PortalException if a portal exception occurred
382             */
383            @Override
384            @SystemEvent(type = SystemEventConstants.TYPE_DELETE)
385            public void deleteTemplate(DDMTemplate template) throws PortalException {
386    
387                    // Template
388    
389                    if (template.getClassNameId() ==
390                                    classNameLocalService.getClassNameId(
391                                            DDMStructure.class.getName())) {
392    
393                            DDMStructure structure = ddmStructureLocalService.fetchDDMStructure(
394                                    template.getClassPK());
395    
396                            if ((structure != null) &&
397                                    (structure.getClassNameId() ==
398                                            classNameLocalService.getClassNameId(
399                                                    JournalArticle.class.getName()))) {
400    
401                                    Group companyGroup = groupLocalService.getCompanyGroup(
402                                            template.getCompanyId());
403    
404                                    if (template.getGroupId() == companyGroup.getGroupId()) {
405                                            if (JournalArticleUtil.countByC_T(
406                                                            JournalArticleConstants.CLASSNAME_ID_DEFAULT,
407                                                            template.getTemplateKey()) > 0) {
408    
409                                                    throw new RequiredTemplateException();
410                                            }
411                                    }
412                                    else {
413                                            if (JournalArticleUtil.countByG_C_T(
414                                                            template.getGroupId(),
415                                                            JournalArticleConstants.CLASSNAME_ID_DEFAULT,
416                                                            template.getTemplateKey()) > 0) {
417    
418                                                    throw new RequiredTemplateException();
419                                            }
420                                    }
421                            }
422                    }
423    
424                    ddmTemplatePersistence.remove(template);
425    
426                    // Resources
427    
428                    resourceLocalService.deleteResource(
429                            template.getCompanyId(), DDMTemplate.class.getName(),
430                            ResourceConstants.SCOPE_INDIVIDUAL, template.getTemplateId());
431            }
432    
433            /**
434             * Deletes the template and its resources.
435             *
436             * @param  templateId the primary key of the template to be deleted
437             * @throws PortalException if a portal exception occurred
438             */
439            @Override
440            public void deleteTemplate(long templateId) throws PortalException {
441                    DDMTemplate template = ddmTemplatePersistence.findByPrimaryKey(
442                            templateId);
443    
444                    ddmTemplateLocalService.deleteTemplate(template);
445            }
446    
447            /**
448             * Deletes all the templates of the group.
449             *
450             * @param  groupId the primary key of the group
451             * @throws PortalException if a portal exception occurred
452             */
453            @Override
454            public void deleteTemplates(long groupId) throws PortalException {
455                    List<DDMTemplate> templates = ddmTemplatePersistence.findByGroupId(
456                            groupId);
457    
458                    for (DDMTemplate template : templates) {
459                            ddmTemplateLocalService.deleteTemplate(template);
460                    }
461            }
462    
463            @Override
464            public void deleteTemplates(long groupId, long classNameId)
465                    throws PortalException {
466    
467                    List<DDMTemplate> templates = ddmTemplatePersistence.findByG_C(
468                            groupId, classNameId);
469    
470                    for (DDMTemplate template : templates) {
471                            ddmTemplateLocalService.deleteTemplate(template);
472                    }
473            }
474    
475            /**
476             * Returns the template matching the group and template key.
477             *
478             * @param  groupId the primary key of the group
479             * @param  classNameId the primary key of the class name for the template's
480             *         related model
481             * @param  templateKey the unique string identifying the template
482             * @return the matching template, or <code>null</code> if a matching
483             *         template could not be found
484             */
485            @Override
486            public DDMTemplate fetchTemplate(
487                    long groupId, long classNameId, String templateKey) {
488    
489                    templateKey = StringUtil.toUpperCase(templateKey.trim());
490    
491                    return ddmTemplatePersistence.fetchByG_C_T(
492                            groupId, classNameId, templateKey);
493            }
494    
495            /**
496             * Returns the template matching the group and template key, optionally
497             * searching ancestor sites (that have sharing enabled) and global scoped
498             * sites.
499             *
500             * <p>
501             * This method first searches in the given group. If the template is still
502             * not found and <code>includeAncestorTemplates</code> is set to
503             * <code>true</code>, this method searches the group's ancestor sites (that
504             * have sharing enabled) and lastly searches global scoped sites.
505             * </p>
506             *
507             * @param  groupId the primary key of the group
508             * @param  classNameId the primary key of the class name for the template's
509             *         related model
510             * @param  templateKey the unique string identifying the template
511             * @param  includeAncestorTemplates whether to include ancestor sites (that
512             *         have sharing enabled) and include global scoped sites in the
513             *         search in the search
514             * @return the matching template, or <code>null</code> if a matching
515             *         template could not be found
516             * @throws PortalException if a portal exception occurred
517             */
518            @Override
519            public DDMTemplate fetchTemplate(
520                            long groupId, long classNameId, String templateKey,
521                            boolean includeAncestorTemplates)
522                    throws PortalException {
523    
524                    templateKey = StringUtil.toUpperCase(templateKey.trim());
525    
526                    DDMTemplate template = ddmTemplatePersistence.fetchByG_C_T(
527                            groupId, classNameId, templateKey);
528    
529                    if (template != null) {
530                            return template;
531                    }
532    
533                    if (!includeAncestorTemplates) {
534                            return null;
535                    }
536    
537                    for (long ancestorSiteGroupId :
538                                    PortalUtil.getAncestorSiteGroupIds(groupId)) {
539    
540                            template = ddmTemplatePersistence.fetchByG_C_T(
541                                    ancestorSiteGroupId, classNameId, templateKey);
542    
543                            if (template != null) {
544                                    return template;
545                            }
546                    }
547    
548                    return null;
549            }
550    
551            /**
552             * Returns the template with the ID.
553             *
554             * @param  templateId the primary key of the template
555             * @return the template with the ID
556             * @throws PortalException if a matching template could not be found
557             */
558            @Override
559            public DDMTemplate getTemplate(long templateId) throws PortalException {
560                    return ddmTemplatePersistence.findByPrimaryKey(templateId);
561            }
562    
563            /**
564             * Returns the template matching the group and template key.
565             *
566             * @param  groupId the primary key of the group
567             * @param  classNameId the primary key of the class name for the template's
568             *         related model
569             * @param  templateKey the unique string identifying the template
570             * @return the matching template
571             * @throws PortalException if a matching template could not be found
572             */
573            @Override
574            public DDMTemplate getTemplate(
575                            long groupId, long classNameId, String templateKey)
576                    throws PortalException {
577    
578                    templateKey = StringUtil.toUpperCase(templateKey.trim());
579    
580                    return ddmTemplatePersistence.findByG_C_T(
581                            groupId, classNameId, templateKey);
582            }
583    
584            /**
585             * Returns the template matching the group and template key, optionally
586             * searching ancestor sites (that have sharing enabled) and global scoped
587             * sites.
588             *
589             * <p>
590             * This method first searches in the group. If the template is still not
591             * found and <code>includeAncestorTemplates</code> is set to
592             * <code>true</code>, this method searches the group's ancestor sites (that
593             * have sharing enabled) and lastly searches global scoped sites.
594             * </p>
595             *
596             * @param  groupId the primary key of the group
597             * @param  classNameId the primary key of the class name for the template's
598             *         related model
599             * @param  templateKey the unique string identifying the template
600             * @param  includeAncestorTemplates whether to include ancestor sites (that
601             *         have sharing enabled) and include global scoped sites in the
602             *         search in the search
603             * @return the matching template
604             * @throws PortalException if a matching template could not be found
605             */
606            @Override
607            public DDMTemplate getTemplate(
608                            long groupId, long classNameId, String templateKey,
609                            boolean includeAncestorTemplates)
610                    throws PortalException {
611    
612                    templateKey = StringUtil.toUpperCase(templateKey.trim());
613    
614                    DDMTemplate template = ddmTemplatePersistence.fetchByG_C_T(
615                            groupId, classNameId, templateKey);
616    
617                    if (template != null) {
618                            return template;
619                    }
620    
621                    if (!includeAncestorTemplates) {
622                            throw new NoSuchTemplateException(
623                                    "No DDMTemplate exists with the template key " + templateKey);
624                    }
625    
626                    for (long ancestorSiteGroupId :
627                                    PortalUtil.getAncestorSiteGroupIds(groupId)) {
628    
629                            template = ddmTemplatePersistence.fetchByG_C_T(
630                                    ancestorSiteGroupId, classNameId, templateKey);
631    
632                            if (template != null) {
633                                    return template;
634                            }
635                    }
636    
637                    throw new NoSuchTemplateException(
638                            "No DDMTemplate exists with the template key " + templateKey +
639                                    " in the ancestor groups");
640            }
641    
642            @Override
643            public DDMTemplate getTemplateBySmallImageId(long smallImageId)
644                    throws PortalException {
645    
646                    return ddmTemplatePersistence.findBySmallImageId(smallImageId);
647            }
648    
649            /**
650             * Returns all the templates with the class PK.
651             *
652             * @param  classPK the primary key of the template's related entity
653             * @return the templates with the class PK
654             */
655            @Override
656            public List<DDMTemplate> getTemplates(long classPK) {
657                    return ddmTemplatePersistence.findByClassPK(classPK);
658            }
659    
660            /**
661             * Returns all the templates matching the group and class name ID.
662             *
663             * @param  groupId the primary key of the group
664             * @param  classNameId the primary key of the class name for the template's
665             *         related model
666             * @return the matching templates
667             */
668            @Override
669            public List<DDMTemplate> getTemplates(long groupId, long classNameId) {
670                    return ddmTemplatePersistence.findByG_C(groupId, classNameId);
671            }
672    
673            /**
674             * Returns all the templates matching the group, class name ID, and class
675             * PK.
676             *
677             * @param  groupId the primary key of the group
678             * @param  classNameId the primary key of the class name for the template's
679             *         related model
680             * @param  classPK the primary key of the template's related entity
681             * @return the matching templates
682             */
683            @Override
684            public List<DDMTemplate> getTemplates(
685                    long groupId, long classNameId, long classPK) {
686    
687                    return ddmTemplatePersistence.findByG_C_C(
688                            groupId, classNameId, classPK);
689            }
690    
691            @Override
692            public List<DDMTemplate> getTemplates(
693                            long groupId, long classNameId, long classPK,
694                            boolean includeAncestorTemplates)
695                    throws PortalException {
696    
697                    List<DDMTemplate> ddmTemplates = new ArrayList<DDMTemplate>();
698    
699                    ddmTemplates.addAll(
700                            ddmTemplatePersistence.findByG_C_C(groupId, classNameId, classPK));
701    
702                    if (!includeAncestorTemplates) {
703                            return ddmTemplates;
704                    }
705    
706                    ddmTemplates.addAll(
707                            ddmTemplatePersistence.findByG_C_C(
708                                    PortalUtil.getAncestorSiteGroupIds(groupId), classNameId,
709                                    classPK));
710    
711                    return ddmTemplates;
712            }
713    
714            /**
715             * Returns all the templates matching the group, class name ID, class PK,
716             * and type.
717             *
718             * @param  groupId the primary key of the group
719             * @param  classNameId the primary key of the class name for the template's
720             *         related model
721             * @param  classPK the primary key of the template's related entity
722             * @param  type the template's type. For more information, see {@link
723             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
724             * @return the matching templates
725             */
726            @Override
727            public List<DDMTemplate> getTemplates(
728                    long groupId, long classNameId, long classPK, String type) {
729    
730                    return ddmTemplatePersistence.findByG_C_C_T(
731                            groupId, classNameId, classPK, type);
732            }
733    
734            /**
735             * Returns all the templates matching the group, class name ID, class PK,
736             * type, and mode.
737             *
738             * @param  groupId the primary key of the group
739             * @param  classNameId the primary key of the class name for the template's
740             *         related model
741             * @param  classPK the primary key of the template's related entity
742             * @param  type the template's type. For more information, see {@link
743             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
744             * @param  mode the template's mode. For more information, see {@link
745             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
746             * @return the matching templates
747             */
748            @Override
749            public List<DDMTemplate> getTemplates(
750                    long groupId, long classNameId, long classPK, String type,
751                    String mode) {
752    
753                    return ddmTemplatePersistence.findByG_C_C_T_M(
754                            groupId, classNameId, classPK, type, mode);
755            }
756    
757            @Override
758            public List<DDMTemplate> getTemplates(
759                    long[] groupIds, long classNameId, long classPK) {
760    
761                    return ddmTemplatePersistence.findByG_C_C(
762                            groupIds, classNameId, classPK);
763            }
764    
765            @Override
766            public List<DDMTemplate> getTemplatesByClassPK(long groupId, long classPK) {
767                    return ddmTemplatePersistence.findByG_CPK(groupId, classPK);
768            }
769    
770            @Override
771            public List<DDMTemplate> getTemplatesByClassPK(
772                    long groupId, long classPK, int start, int end) {
773    
774                    return ddmTemplatePersistence.findByG_CPK(groupId, classPK, start, end);
775            }
776    
777            @Override
778            public List<DDMTemplate> getTemplatesByClassPK(
779                    long[] groupIds, long classPK) {
780    
781                    return ddmTemplatePersistence.findByG_CPK(groupIds, classPK);
782            }
783    
784            /**
785             * Returns the number of templates matching the group and class PK.
786             *
787             * @param  groupId the primary key of the group
788             * @param  classPK the primary key of the template's related entity
789             * @return the number of templates belonging to the group and class PK
790             */
791            @Override
792            public int getTemplatesByClassPKCount(long groupId, long classPK) {
793                    return ddmTemplatePersistence.countByG_CPK(groupId, classPK);
794            }
795    
796            /**
797             * Returns an ordered range of all the templates matching the group and
798             * structure class name ID.
799             *
800             * <p>
801             * Useful when paginating results. Returns a maximum of <code>end -
802             * start</code> instances. <code>start</code> and <code>end</code> are not
803             * primary keys, they are indexes in the result set. Thus, <code>0</code>
804             * refers to the first result in the set. Setting both <code>start</code>
805             * and <code>end</code> to {@link
806             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
807             * result set.
808             * </p>
809             *
810             * @param  groupId the primary key of the group
811             * @param  structureClassNameId the primary key of the class name for the
812             *         template's related structure
813             * @param  start the lower bound of the range of templates to return
814             * @param  end the upper bound of the range of templates to return (not
815             *         inclusive)
816             * @param  orderByComparator the comparator to order the templates
817             *         (optionally <code>null</code>)
818             * @return the range of matching templates ordered by the comparator
819             */
820            @Override
821            public List<DDMTemplate> getTemplatesByStructureClassNameId(
822                    long groupId, long structureClassNameId, int start, int end,
823                    OrderByComparator<DDMTemplate> orderByComparator) {
824    
825                    return ddmTemplateFinder.findByG_SC(
826                            groupId, structureClassNameId, start, end, orderByComparator);
827            }
828    
829            /**
830             * Returns the number of templates matching the group and structure class
831             * name ID, including Generic Templates.
832             *
833             * @param  groupId the primary key of the group
834             * @param  structureClassNameId the primary key of the class name for the
835             *         template's related structure
836             * @return the number of matching templates
837             */
838            @Override
839            public int getTemplatesByStructureClassNameIdCount(
840                    long groupId, long structureClassNameId) {
841    
842                    return ddmTemplateFinder.countByG_SC(groupId, structureClassNameId);
843            }
844    
845            /**
846             * Returns the number of templates belonging to the group.
847             *
848             * @param  groupId the primary key of the group
849             * @return the number of templates belonging to the group
850             */
851            @Override
852            public int getTemplatesCount(long groupId) {
853                    return ddmTemplatePersistence.countByGroupId(groupId);
854            }
855    
856            /**
857             * Returns the number of templates matching the group and class name ID.
858             *
859             * @param  groupId the primary key of the group
860             * @param  classNameId the primary key of the class name for the template's
861             *         related model
862             * @return the number of matching templates
863             */
864            @Override
865            public int getTemplatesCount(long groupId, long classNameId) {
866                    return ddmTemplatePersistence.countByG_C(groupId, classNameId);
867            }
868    
869            /**
870             * Returns the number of templates matching the group, class name ID, and
871             * class PK.
872             *
873             * @param  groupId the primary key of the group
874             * @param  classNameId the primary key of the class name for the template's
875             *         related model
876             * @param  classPK the primary key of the template's related entity
877             * @return the number of matching templates
878             */
879            @Override
880            public int getTemplatesCount(long groupId, long classNameId, long classPK) {
881                    return ddmTemplatePersistence.countByG_C_C(
882                            groupId, classNameId, classPK);
883            }
884    
885            /**
886             * Returns an ordered range of all the templates matching the group, class
887             * name ID, class PK, type, and mode, and matching the keywords in the
888             * template names and descriptions.
889             *
890             * <p>
891             * Useful when paginating results. Returns a maximum of <code>end -
892             * start</code> instances. <code>start</code> and <code>end</code> are not
893             * primary keys, they are indexes in the result set. Thus, <code>0</code>
894             * refers to the first result in the set. Setting both <code>start</code>
895             * and <code>end</code> to {@link
896             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
897             * result set.
898             * </p>
899             *
900             * @param  companyId the primary key of the template's company
901             * @param  groupId the primary key of the group
902             * @param  classNameId the primary key of the class name for the template's
903             *         related model
904             * @param  classPK the primary key of the template's related entity
905             * @param  keywords the keywords (space separated), which may occur in the
906             *         template's name or description (optionally <code>null</code>)
907             * @param  type the template's type (optionally <code>null</code>). For more
908             *         information, see {@link
909             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
910             * @param  mode the template's mode (optionally <code>null</code>). For more
911             *         information, see {@link
912             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
913             * @param  start the lower bound of the range of templates to return
914             * @param  end the upper bound of the range of templates to return (not
915             *         inclusive)
916             * @param  orderByComparator the comparator to order the templates
917             *         (optionally <code>null</code>)
918             * @return the range of matching templates ordered by the comparator
919             */
920            @Override
921            public List<DDMTemplate> search(
922                    long companyId, long groupId, long classNameId, long classPK,
923                    String keywords, String type, String mode, int start, int end,
924                    OrderByComparator<DDMTemplate> orderByComparator) {
925    
926                    return ddmTemplateFinder.findByKeywords(
927                            companyId, groupId, classNameId, classPK, keywords, type, mode,
928                            start, end, orderByComparator);
929            }
930    
931            /**
932             * Returns an ordered range of all the templates matching the group, class
933             * name ID, class PK, name keyword, description keyword, type, mode, and
934             * language.
935             *
936             * <p>
937             * Useful when paginating results. Returns a maximum of <code>end -
938             * start</code> instances. <code>start</code> and <code>end</code> are not
939             * primary keys, they are indexes in the result set. Thus, <code>0</code>
940             * refers to the first result in the set. Setting both <code>start</code>
941             * and <code>end</code> to {@link
942             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
943             * result set.
944             * </p>
945             *
946             * @param  companyId the primary key of the template's company
947             * @param  groupId the primary key of the group
948             * @param  classNameId the primary key of the class name for the template's
949             *         related model
950             * @param  classPK the primary key of the template's related entity
951             * @param  name the name keywords (optionally <code>null</code>)
952             * @param  description the description keywords (optionally
953             *         <code>null</code>)
954             * @param  type the template's type (optionally <code>null</code>). For more
955             *         information, see {@link
956             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
957             * @param  mode the template's mode (optionally <code>null</code>). For more
958             *         information, see {@link
959             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
960             * @param  language the template's script language (optionally
961             *         <code>null</code>). For more information, see {@link
962             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
963             * @param  andOperator whether every field must match its keywords, or just
964             *         one field
965             * @param  start the lower bound of the range of templates to return
966             * @param  end the upper bound of the range of templates to return (not
967             *         inclusive)
968             * @param  orderByComparator the comparator to order the templates
969             *         (optionally <code>null</code>)
970             * @return the range of matching templates ordered by the comparator
971             */
972            @Override
973            public List<DDMTemplate> search(
974                    long companyId, long groupId, long classNameId, long classPK,
975                    String name, String description, String type, String mode,
976                    String language, boolean andOperator, int start, int end,
977                    OrderByComparator<DDMTemplate> orderByComparator) {
978    
979                    return ddmTemplateFinder.findByC_G_C_C_N_D_T_M_L(
980                            companyId, groupId, classNameId, classPK, name, description, type,
981                            mode, language, andOperator, start, end, orderByComparator);
982            }
983    
984            /**
985             * Returns an ordered range of all the templates matching the group IDs,
986             * class Name IDs, class PK, type, and mode, and include the keywords on its
987             * names and descriptions.
988             *
989             * <p>
990             * Useful when paginating results. Returns a maximum of <code>end -
991             * start</code> instances. <code>start</code> and <code>end</code> are not
992             * primary keys, they are indexes in the result set. Thus, <code>0</code>
993             * refers to the first result in the set. Setting both <code>start</code>
994             * and <code>end</code> to {@link
995             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
996             * result set.
997             * </p>
998             *
999             * @param  companyId the primary key of the template's company
1000             * @param  groupIds the primary keys of the groups
1001             * @param  classNameIds the primary keys of the entity's instances the
1002             *         templates are related to
1003             * @param  classPKs the primary keys of the template's related entities
1004             * @param  keywords the keywords (space separated), which may occur in the
1005             *         template's name or description (optionally <code>null</code>)
1006             * @param  type the template's type (optionally <code>null</code>). For more
1007             *         information, see {@link
1008             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1009             * @param  mode the template's mode (optionally <code>null</code>). For more
1010             *         information, see {@link
1011             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1012             * @param  start the lower bound of the range of templates to return
1013             * @param  end the upper bound of the range of templates to return (not
1014             *         inclusive)
1015             * @param  orderByComparator the comparator to order the templates
1016             *         (optionally <code>null</code>)
1017             * @return the range of matching templates ordered by the comparator
1018             */
1019            @Override
1020            public List<DDMTemplate> search(
1021                    long companyId, long[] groupIds, long[] classNameIds, long[] classPKs,
1022                    String keywords, String type, String mode, int start, int end,
1023                    OrderByComparator<DDMTemplate> orderByComparator) {
1024    
1025                    return ddmTemplateFinder.findByKeywords(
1026                            companyId, groupIds, classNameIds, classPKs, keywords, type, mode,
1027                            start, end, orderByComparator);
1028            }
1029    
1030            /**
1031             * Returns an ordered range of all the templates matching the group IDs,
1032             * class name IDs, class PK, name keyword, description keyword, type, mode,
1033             * and language.
1034             *
1035             * <p>
1036             * Useful when paginating results. Returns a maximum of <code>end -
1037             * start</code> instances. <code>start</code> and <code>end</code> are not
1038             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1039             * refers to the first result in the set. Setting both <code>start</code>
1040             * and <code>end</code> to {@link
1041             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1042             * result set.
1043             * </p>
1044             *
1045             * @param  companyId the primary key of the template's company
1046             * @param  groupIds the primary keys of the groups
1047             * @param  classNameIds the primary keys of the entity's instances the
1048             *         templates are related to
1049             * @param  classPKs the primary keys of the template's related entities
1050             * @param  name the name keywords (optionally <code>null</code>)
1051             * @param  description the description keywords (optionally
1052             *         <code>null</code>)
1053             * @param  type the template's type (optionally <code>null</code>). For more
1054             *         information, see {@link
1055             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1056             * @param  mode the template's mode (optionally <code>null</code>). For more
1057             *         information, see {@link
1058             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1059             * @param  language the template's script language (optionally
1060             *         <code>null</code>). For more information, see {@link
1061             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1062             * @param  andOperator whether every field must match its keywords, or just
1063             *         one field.
1064             * @param  start the lower bound of the range of templates to return
1065             * @param  end the upper bound of the range of templates to return (not
1066             *         inclusive)
1067             * @param  orderByComparator the comparator to order the templates
1068             *         (optionally <code>null</code>)
1069             * @return the range of matching templates ordered by the comparator
1070             */
1071            @Override
1072            public List<DDMTemplate> search(
1073                    long companyId, long[] groupIds, long[] classNameIds, long[] classPKs,
1074                    String name, String description, String type, String mode,
1075                    String language, boolean andOperator, int start, int end,
1076                    OrderByComparator<DDMTemplate> orderByComparator) {
1077    
1078                    return ddmTemplateFinder.findByC_G_C_C_N_D_T_M_L(
1079                            companyId, groupIds, classNameIds, classPKs, name, description,
1080                            type, mode, language, andOperator, start, end, orderByComparator);
1081            }
1082    
1083            /**
1084             * Returns the number of templates matching the group, class name ID, class
1085             * PK, type, and matching the keywords in the template names and
1086             * descriptions.
1087             *
1088             * @param  companyId the primary key of the template's company
1089             * @param  groupId the primary key of the group
1090             * @param  classNameId the primary key of the class name for the template's
1091             *         related model
1092             * @param  classPK the primary key of the template's related entity
1093             * @param  keywords the keywords (space separated), which may occur in the
1094             *         template's name or description (optionally <code>null</code>)
1095             * @param  type the template's type (optionally <code>null</code>). For more
1096             *         information, see {@link
1097             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1098             * @param  mode the template's mode (optionally <code>null</code>). For more
1099             *         information, see {@link
1100             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1101             * @return the number of matching templates
1102             */
1103            @Override
1104            public int searchCount(
1105                    long companyId, long groupId, long classNameId, long classPK,
1106                    String keywords, String type, String mode) {
1107    
1108                    return ddmTemplateFinder.countByKeywords(
1109                            companyId, groupId, classNameId, classPK, keywords, type, mode);
1110            }
1111    
1112            /**
1113             * Returns the number of templates matching the group, class name ID, class
1114             * PK, name keyword, description keyword, type, mode, and language.
1115             *
1116             * @param  companyId the primary key of the template's company
1117             * @param  groupId the primary key of the group
1118             * @param  classNameId the primary key of the class name for the template's
1119             *         related model
1120             * @param  classPK the primary key of the template's related entity
1121             * @param  name the name keywords (optionally <code>null</code>)
1122             * @param  description the description keywords (optionally
1123             *         <code>null</code>)
1124             * @param  type the template's type (optionally <code>null</code>). For more
1125             *         information, see {@link
1126             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1127             * @param  mode the template's mode (optionally <code>null</code>). For more
1128             *         information, see {@link
1129             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1130             * @param  language the template's script language (optionally
1131             *         <code>null</code>). For more information, see {@link
1132             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1133             * @param  andOperator whether every field must match its keywords, or just
1134             *         one field.
1135             * @return the number of matching templates
1136             */
1137            @Override
1138            public int searchCount(
1139                    long companyId, long groupId, long classNameId, long classPK,
1140                    String name, String description, String type, String mode,
1141                    String language, boolean andOperator) {
1142    
1143                    return ddmTemplateFinder.countByC_G_C_C_N_D_T_M_L(
1144                            companyId, groupId, classNameId, classPK, name, description, type,
1145                            mode, language, andOperator);
1146            }
1147    
1148            /**
1149             * Returns the number of templates matching the group IDs, class name IDs,
1150             * class PK, type, and mode, and matching the keywords in the template names
1151             * and descriptions.
1152             *
1153             * @param  companyId the primary key of the template's company
1154             * @param  groupIds the primary keys of the groups
1155             * @param  classNameIds the primary keys of the entity's instance the
1156             *         templates are related to
1157             * @param  classPKs the primary keys of the template's related entities
1158             * @param  keywords the keywords (space separated), which may occur in the
1159             *         template's name or description (optionally <code>null</code>)
1160             * @param  type the template's type (optionally <code>null</code>). For more
1161             *         information, see {@link
1162             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1163             * @param  mode the template's mode (optionally <code>null</code>). For more
1164             *         information, see {@link
1165             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1166             * @return the number of matching templates
1167             */
1168            @Override
1169            public int searchCount(
1170                    long companyId, long[] groupIds, long[] classNameIds, long[] classPKs,
1171                    String keywords, String type, String mode) {
1172    
1173                    return ddmTemplateFinder.countByKeywords(
1174                            companyId, groupIds, classNameIds, classPKs, keywords, type, mode);
1175            }
1176    
1177            /**
1178             * Returns the number of templates matching the group IDs, class name IDs,
1179             * class PKs, name keyword, description keyword, type, mode, and language.
1180             *
1181             * @param  companyId the primary key of the templates company
1182             * @param  groupIds the primary keys of the groups
1183             * @param  classNameIds the primary keys of the entity's instance the
1184             *         templates are related to
1185             * @param  classPKs the primary keys of the template's related entities
1186             * @param  name the name keywords (optionally <code>null</code>)
1187             * @param  description the description keywords (optionally
1188             *         <code>null</code>)
1189             * @param  type the template's type (optionally <code>null</code>). For more
1190             *         information, see {@link
1191             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1192             * @param  mode the template's mode (optionally <code>null</code>). For more
1193             *         information, see {@link
1194             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1195             * @param  language the template's script language (optionally
1196             *         <code>null</code>). For more information, see {@link
1197             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1198             * @param  andOperator whether every field must match its keywords, or just
1199             *         one field.
1200             * @return the number of matching templates
1201             */
1202            @Override
1203            public int searchCount(
1204                    long companyId, long[] groupIds, long[] classNameIds, long[] classPKs,
1205                    String name, String description, String type, String mode,
1206                    String language, boolean andOperator) {
1207    
1208                    return ddmTemplateFinder.countByC_G_C_C_N_D_T_M_L(
1209                            companyId, groupIds, classNameIds, classPKs, name, description,
1210                            type, mode, language, andOperator);
1211            }
1212    
1213            /**
1214             * Updates the template matching the ID.
1215             *
1216             * @param  templateId the primary key of the template
1217             * @param  classPK the primary key of the template's related entity
1218             * @param  nameMap the template's new locales and localized names
1219             * @param  descriptionMap the template's new locales and localized
1220             *         description
1221             * @param  type the template's type. For more information, see {@link
1222             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1223             * @param  mode the template's mode. For more information, see {@link
1224             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1225             * @param  language the template's script language. For more information,
1226             *         see {@link
1227             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1228             * @param  script the template's script
1229             * @param  cacheable whether the template is cacheable
1230             * @param  smallImage whether the template has a small image
1231             * @param  smallImageURL the template's small image URL (optionally
1232             *         <code>null</code>)
1233             * @param  smallImageFile the template's small image file (optionally
1234             *         <code>null</code>)
1235             * @param  serviceContext the service context to be applied. Can set the
1236             *         modification date.
1237             * @return the updated template
1238             * @throws PortalException if a portal exception occurred
1239             */
1240            @Override
1241            public DDMTemplate updateTemplate(
1242                            long templateId, long classPK, Map<Locale, String> nameMap,
1243                            Map<Locale, String> descriptionMap, String type, String mode,
1244                            String language, String script, boolean cacheable,
1245                            boolean smallImage, String smallImageURL, File smallImageFile,
1246                            ServiceContext serviceContext)
1247                    throws PortalException {
1248    
1249                    script = formatScript(type, language, script);
1250    
1251                    byte[] smallImageBytes = null;
1252    
1253                    try {
1254                            smallImageBytes = FileUtil.getBytes(smallImageFile);
1255                    }
1256                    catch (IOException ioe) {
1257                    }
1258    
1259                    validate(
1260                            nameMap, script, smallImage, smallImageURL, smallImageFile,
1261                            smallImageBytes);
1262    
1263                    DDMTemplate template = ddmTemplateLocalService.getDDMTemplate(
1264                            templateId);
1265    
1266                    template.setModifiedDate(serviceContext.getModifiedDate(null));
1267    
1268                    if ((template.getClassPK() == 0) && (classPK > 0)) {
1269    
1270                            // Allow users to set the structure if and only if it currently does
1271                            // not have one. Otherwise, you can have bad data because there may
1272                            // be an existing content that has chosen to use a structure and
1273                            // template combination that no longer exists.
1274    
1275                            template.setClassPK(classPK);
1276                    }
1277    
1278                    template.setNameMap(nameMap);
1279                    template.setDescriptionMap(descriptionMap);
1280                    template.setType(type);
1281                    template.setMode(mode);
1282                    template.setLanguage(language);
1283                    template.setScript(script);
1284                    template.setCacheable(cacheable);
1285                    template.setSmallImage(smallImage);
1286                    template.setSmallImageURL(smallImageURL);
1287    
1288                    ddmTemplatePersistence.update(template);
1289    
1290                    // Small image
1291    
1292                    saveImages(
1293                            smallImage, template.getSmallImageId(), smallImageFile,
1294                            smallImageBytes);
1295    
1296                    return template;
1297            }
1298    
1299            /**
1300             * Updates the template matching the ID.
1301             *
1302             * @param  templateId the primary key of the template
1303             * @param  classPK the primary key of the template's related entity
1304             * @param  nameMap the template's new locales and localized names
1305             * @param  descriptionMap the template's new locales and localized
1306             *         description
1307             * @param  type the template's type. For more information, see {@link
1308             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1309             * @param  mode the template's mode. For more information, see {@link
1310             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1311             * @param  language the template's script language. For more information,
1312             *         see {@link
1313             *         com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants}.
1314             * @param  script the template's script
1315             * @param  cacheable whether the template is cacheable
1316             * @param  serviceContext the service context to be applied. Can set the
1317             *         modification date.
1318             * @return the updated template
1319             * @throws PortalException if a portal exception occurred
1320             */
1321            @Override
1322            public DDMTemplate updateTemplate(
1323                            long templateId, long classPK, Map<Locale, String> nameMap,
1324                            Map<Locale, String> descriptionMap, String type, String mode,
1325                            String language, String script, boolean cacheable,
1326                            ServiceContext serviceContext)
1327                    throws PortalException {
1328    
1329                    DDMTemplate template = ddmTemplateLocalService.getDDMTemplate(
1330                            templateId);
1331    
1332                    File smallImageFile = getSmallImageFile(template);
1333    
1334                    return updateTemplate(
1335                            templateId, classPK, nameMap, descriptionMap, type, mode, language,
1336                            script, cacheable, template.isSmallImage(),
1337                            template.getSmallImageURL(), smallImageFile, serviceContext);
1338            }
1339    
1340            protected DDMTemplate copyTemplate(
1341                            long userId, DDMTemplate template, long classPK,
1342                            Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
1343                            ServiceContext serviceContext)
1344                    throws PortalException {
1345    
1346                    File smallImageFile = getSmallImageFile(template);
1347    
1348                    return addTemplate(
1349                            userId, template.getGroupId(), template.getClassNameId(), classPK,
1350                            null, nameMap, descriptionMap, template.getType(),
1351                            template.getMode(), template.getLanguage(), template.getScript(),
1352                            template.isCacheable(), template.isSmallImage(),
1353                            template.getSmallImageURL(), smallImageFile, serviceContext);
1354            }
1355    
1356            protected String formatScript(String type, String language, String script)
1357                    throws PortalException {
1358    
1359                    if (type.equals(DDMTemplateConstants.TEMPLATE_TYPE_FORM) ||
1360                            language.equals(TemplateConstants.LANG_TYPE_XSL)) {
1361    
1362                            try {
1363                                    script = DDMXMLUtil.validateXML(script);
1364                                    script = DDMXMLUtil.formatXML(script);
1365                            }
1366                            catch (Exception e) {
1367                                    throw new TemplateScriptException();
1368                            }
1369                    }
1370    
1371                    return script;
1372            }
1373    
1374            protected File getSmallImageFile(DDMTemplate template) {
1375                    File smallImageFile = null;
1376    
1377                    if (template.isSmallImage() &&
1378                            Validator.isNull(template.getSmallImageURL())) {
1379    
1380                            Image smallImage = ImageUtil.fetchByPrimaryKey(
1381                                    template.getSmallImageId());
1382    
1383                            if (smallImage != null) {
1384                                    smallImageFile = FileUtil.createTempFile(smallImage.getType());
1385    
1386                                    try {
1387                                            FileUtil.write(smallImageFile, smallImage.getTextObj());
1388                                    }
1389                                    catch (IOException ioe) {
1390                                            _log.error(ioe, ioe);
1391                                    }
1392                            }
1393                    }
1394    
1395                    return smallImageFile;
1396            }
1397    
1398            protected void saveImages(
1399                            boolean smallImage, long smallImageId, File smallImageFile,
1400                            byte[] smallImageBytes)
1401                    throws PortalException {
1402    
1403                    if (smallImage) {
1404                            if ((smallImageFile != null) && (smallImageBytes != null)) {
1405                                    imageLocalService.updateImage(smallImageId, smallImageBytes);
1406                            }
1407                    }
1408                    else {
1409                            imageLocalService.deleteImage(smallImageId);
1410                    }
1411            }
1412    
1413            protected void validate(
1414                            long groupId, long classNameId, String templateKey,
1415                            Map<Locale, String> nameMap, String script, boolean smallImage,
1416                            String smallImageURL, File smallImageFile, byte[] smallImageBytes)
1417                    throws PortalException {
1418    
1419                    templateKey = StringUtil.toUpperCase(templateKey.trim());
1420    
1421                    DDMTemplate template = ddmTemplatePersistence.fetchByG_C_T(
1422                            groupId, classNameId, templateKey);
1423    
1424                    if (template != null) {
1425                            throw new TemplateDuplicateTemplateKeyException();
1426                    }
1427    
1428                    validate(
1429                            nameMap, script, smallImage, smallImageURL, smallImageFile,
1430                            smallImageBytes);
1431            }
1432    
1433            protected void validate(Map<Locale, String> nameMap, String script)
1434                    throws PortalException {
1435    
1436                    validateName(nameMap);
1437    
1438                    if (Validator.isNull(script)) {
1439                            throw new TemplateScriptException();
1440                    }
1441            }
1442    
1443            protected void validate(
1444                            Map<Locale, String> nameMap, String script, boolean smallImage,
1445                            String smallImageURL, File smallImageFile, byte[] smallImageBytes)
1446                    throws PortalException {
1447    
1448                    validate(nameMap, script);
1449    
1450                    String[] imageExtensions = PrefsPropsUtil.getStringArray(
1451                            PropsKeys.DYNAMIC_DATA_MAPPING_IMAGE_EXTENSIONS, StringPool.COMMA);
1452    
1453                    if (!smallImage || Validator.isNotNull(smallImageURL) ||
1454                            (smallImageFile == null) || (smallImageBytes == null)) {
1455    
1456                            return;
1457                    }
1458    
1459                    String smallImageName = smallImageFile.getName();
1460    
1461                    if (smallImageName != null) {
1462                            boolean validSmallImageExtension = false;
1463    
1464                            for (int i = 0; i < imageExtensions.length; i++) {
1465                                    if (StringPool.STAR.equals(imageExtensions[i]) ||
1466                                            StringUtil.endsWith(
1467                                                    smallImageName, imageExtensions[i])) {
1468    
1469                                            validSmallImageExtension = true;
1470    
1471                                            break;
1472                                    }
1473                            }
1474    
1475                            if (!validSmallImageExtension) {
1476                                    throw new TemplateSmallImageNameException(smallImageName);
1477                            }
1478                    }
1479    
1480                    long smallImageMaxSize = PrefsPropsUtil.getLong(
1481                            PropsKeys.DYNAMIC_DATA_MAPPING_IMAGE_SMALL_MAX_SIZE);
1482    
1483                    if ((smallImageMaxSize > 0) &&
1484                            ((smallImageBytes == null) ||
1485                             (smallImageBytes.length > smallImageMaxSize))) {
1486    
1487                            throw new TemplateSmallImageSizeException();
1488                    }
1489            }
1490    
1491            protected void validateName(Map<Locale, String> nameMap)
1492                    throws PortalException {
1493    
1494                    String name = nameMap.get(LocaleUtil.getSiteDefault());
1495    
1496                    if (Validator.isNull(name)) {
1497                            throw new TemplateNameException();
1498                    }
1499            }
1500    
1501            private static Log _log = LogFactoryUtil.getLog(
1502                    DDMTemplateLocalServiceImpl.class);
1503    
1504    }