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