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