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.lar;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.lar.BaseStagedModelDataHandler;
020    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
021    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
022    import com.liferay.portal.kernel.lar.PortletDataContext;
023    import com.liferay.portal.kernel.lar.PortletDataException;
024    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.util.FileUtil;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.MapUtil;
030    import com.liferay.portal.kernel.util.StringBundler;
031    import com.liferay.portal.kernel.util.StringPool;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.kernel.xml.Element;
034    import com.liferay.portal.model.Image;
035    import com.liferay.portal.service.ImageLocalServiceUtil;
036    import com.liferay.portal.service.ServiceContext;
037    import com.liferay.portal.service.UserLocalServiceUtil;
038    import com.liferay.portal.util.PortalUtil;
039    import com.liferay.portlet.dynamicdatamapping.TemplateDuplicateTemplateKeyException;
040    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
041    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
042    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
043    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
044    
045    import java.io.File;
046    
047    import java.util.HashMap;
048    import java.util.Map;
049    
050    /**
051     * @author Mate Thurzo
052     * @author Daniel Kocsis
053     */
054    public class DDMTemplateStagedModelDataHandler
055            extends BaseStagedModelDataHandler<DDMTemplate> {
056    
057            public static final String[] CLASS_NAMES = {DDMTemplate.class.getName()};
058    
059            @Override
060            public void deleteStagedModel(
061                            String uuid, long groupId, String className, String extraData)
062                    throws PortalException, SystemException {
063    
064                    DDMTemplate ddmTemplate =
065                            DDMTemplateLocalServiceUtil.fetchDDMTemplateByUuidAndGroupId(
066                                    uuid, groupId);
067    
068                    if (ddmTemplate != null) {
069                            DDMTemplateLocalServiceUtil.deleteTemplate(ddmTemplate);
070                    }
071            }
072    
073            @Override
074            public String[] getClassNames() {
075                    return CLASS_NAMES;
076            }
077    
078            @Override
079            public String getDisplayName(DDMTemplate template) {
080                    return template.getNameCurrentValue();
081            }
082    
083            @Override
084            public Map<String, String> getReferenceAttributes(
085                    PortletDataContext portletDataContext, DDMTemplate template) {
086    
087                    Map<String, String> referenceAttributes = new HashMap<String, String>();
088    
089                    referenceAttributes.put(
090                            "referenced-class-name", template.getClassName());
091                    referenceAttributes.put("template-key", template.getTemplateKey());
092    
093                    long defaultUserId = 0;
094    
095                    try {
096                            defaultUserId = UserLocalServiceUtil.getDefaultUserId(
097                                    template.getCompanyId());
098                    }
099                    catch (Exception e) {
100                            return referenceAttributes;
101                    }
102    
103                    boolean preloaded = false;
104    
105                    if (defaultUserId == template.getUserId()) {
106                            preloaded = true;
107                    }
108    
109                    referenceAttributes.put("preloaded", String.valueOf(preloaded));
110    
111                    return referenceAttributes;
112            }
113    
114            @Override
115            public void importCompanyStagedModel(
116                            PortletDataContext portletDataContext, Element element)
117                    throws PortletDataException {
118    
119                    String uuid = element.attributeValue("uuid");
120                    long classNameId = PortalUtil.getClassNameId(
121                            element.attributeValue("referenced-class-name"));
122                    String templateKey = element.attributeValue("template-key");
123                    boolean preloaded = GetterUtil.getBoolean(
124                            element.attributeValue("preloaded"));
125    
126                    DDMTemplate existingTemplate = null;
127    
128                    try {
129                            existingTemplate = getExistingTemplate(
130                                    uuid, portletDataContext.getCompanyGroupId(), classNameId,
131                                    templateKey, preloaded);
132                    }
133                    catch (Exception e) {
134                            throw new PortletDataException(e);
135                    }
136    
137                    Map<Long, Long> templateIds =
138                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
139                                    DDMTemplate.class);
140    
141                    long templateId = GetterUtil.getLong(
142                            element.attributeValue("class-pk"));
143    
144                    templateIds.put(templateId, existingTemplate.getTemplateId());
145    
146                    Map<String, String> templateKeys =
147                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
148                                    DDMTemplate.class + ".ddmTemplateKey");
149    
150                    templateKeys.put(templateKey, existingTemplate.getTemplateKey());
151            }
152    
153            @Override
154            public boolean validateReference(
155                    PortletDataContext portletDataContext, Element referenceElement) {
156    
157                    String uuid = referenceElement.attributeValue("uuid");
158                    long classNameId = PortalUtil.getClassNameId(
159                            referenceElement.attributeValue("referenced-class-name"));
160                    String templateKey = referenceElement.attributeValue("template-key");
161                    boolean preloaded = GetterUtil.getBoolean(
162                            referenceElement.attributeValue("preloaded"));
163    
164                    try {
165                            DDMTemplate existingTemplate = getExistingTemplate(
166                                    uuid, portletDataContext.getScopeGroupId(), classNameId,
167                                    templateKey, preloaded);
168    
169                            if (existingTemplate == null) {
170                                    existingTemplate = getExistingTemplate(
171                                            uuid, portletDataContext.getCompanyGroupId(), classNameId,
172                                            templateKey, preloaded);
173                            }
174    
175                            if (existingTemplate == null) {
176                                    return false;
177                            }
178    
179                            return true;
180                    }
181                    catch (Exception e) {
182                            return false;
183                    }
184            }
185    
186            protected DDMTemplate addTemplate(
187                            long userId, long groupId, DDMTemplate template, long classPK,
188                            File smallFile, ServiceContext serviceContext)
189                    throws Exception {
190    
191                    DDMTemplate newTemplate = null;
192    
193                    try {
194                            return DDMTemplateLocalServiceUtil.addTemplate(
195                                    userId, groupId, template.getClassNameId(), classPK,
196                                    template.getTemplateKey(), template.getNameMap(),
197                                    template.getDescriptionMap(), template.getType(),
198                                    template.getMode(), template.getLanguage(),
199                                    template.getScript(), template.isCacheable(),
200                                    template.isSmallImage(), template.getSmallImageURL(), smallFile,
201                                    serviceContext);
202                    }
203                    catch (TemplateDuplicateTemplateKeyException tdtke) {
204                            newTemplate = DDMTemplateLocalServiceUtil.addTemplate(
205                                    userId, groupId, template.getClassNameId(), classPK, null,
206                                    template.getNameMap(), template.getDescriptionMap(),
207                                    template.getType(), template.getMode(), template.getLanguage(),
208                                    template.getScript(), template.isCacheable(),
209                                    template.isSmallImage(), template.getSmallImageURL(), smallFile,
210                                    serviceContext);
211    
212                            if (_log.isWarnEnabled()) {
213                                    StringBundler sb = new StringBundler(4);
214    
215                                    sb.append("A template with the key ");
216                                    sb.append(template.getTemplateKey());
217                                    sb.append(" already exists. The new generated key is ");
218                                    sb.append(newTemplate.getTemplateKey());
219    
220                                    _log.warn(sb.toString());
221                            }
222                    }
223    
224                    return newTemplate;
225            }
226    
227            @Override
228            protected void doExportStagedModel(
229                            PortletDataContext portletDataContext, DDMTemplate template)
230                    throws Exception {
231    
232                    Element templateElement = portletDataContext.getExportDataElement(
233                            template);
234    
235                    DDMStructure structure = DDMStructureLocalServiceUtil.fetchStructure(
236                            template.getClassPK());
237    
238                    if (structure != null) {
239                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
240                                    portletDataContext, template, structure,
241                                    PortletDataContext.REFERENCE_TYPE_STRONG);
242                    }
243    
244                    if (template.isSmallImage()) {
245                            Image smallImage = ImageLocalServiceUtil.fetchImage(
246                                    template.getSmallImageId());
247    
248                            if (Validator.isNotNull(template.getSmallImageURL())) {
249                                    String smallImageURL =
250                                            ExportImportHelperUtil.replaceExportContentReferences(
251                                                    portletDataContext, template, templateElement,
252                                                    template.getSmallImageURL().concat(StringPool.SPACE),
253                                                    true);
254    
255                                    template.setSmallImageURL(smallImageURL);
256                            }
257                            else if (smallImage != null) {
258                                    String smallImagePath = ExportImportPathUtil.getModelPath(
259                                            template,
260                                            smallImage.getImageId() + StringPool.PERIOD +
261                                                    template.getSmallImageType());
262    
263                                    templateElement.addAttribute(
264                                            "small-image-path", smallImagePath);
265    
266                                    template.setSmallImageType(smallImage.getType());
267    
268                                    portletDataContext.addZipEntry(
269                                            smallImagePath, smallImage.getTextObj());
270                            }
271                    }
272    
273                    if (portletDataContext.getBooleanParameter(
274                                    DDMPortletDataHandler.NAMESPACE, "referenced-content")) {
275    
276                            String content =
277                                    ExportImportHelperUtil.replaceExportContentReferences(
278                                            portletDataContext, template, templateElement,
279                                            template.getScript(), true);
280    
281                            template.setScript(content);
282                    }
283    
284                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
285                            template.getCompanyId());
286    
287                    if (defaultUserId == template.getUserId()) {
288                            templateElement.addAttribute("preloaded", "true");
289                    }
290    
291                    portletDataContext.addClassedModel(
292                            templateElement, ExportImportPathUtil.getModelPath(template),
293                            template);
294            }
295    
296            @Override
297            protected void doImportStagedModel(
298                            PortletDataContext portletDataContext, DDMTemplate template)
299                    throws Exception {
300    
301                    long userId = portletDataContext.getUserId(template.getUserUuid());
302    
303                    long classPK = template.getClassPK();
304    
305                    if (classPK > 0) {
306                            StagedModelDataHandlerUtil.importReferenceStagedModel(
307                                    portletDataContext, template, DDMStructure.class, classPK);
308    
309                            Map<Long, Long> structureIds =
310                                    (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
311                                            DDMStructure.class);
312    
313                            classPK = MapUtil.getLong(structureIds, classPK, classPK);
314                    }
315    
316                    File smallFile = null;
317    
318                    try {
319                            if (template.isSmallImage()) {
320                                    Element element =
321                                            portletDataContext.getImportDataStagedModelElement(
322                                                    template);
323    
324                                    String smallImagePath = element.attributeValue(
325                                            "small-image-path");
326    
327                                    if (Validator.isNotNull(template.getSmallImageURL())) {
328                                            String smallImageURL =
329                                                    ExportImportHelperUtil.replaceImportContentReferences(
330                                                            portletDataContext, element,
331                                                            template.getSmallImageURL(), true);
332    
333                                            template.setSmallImageURL(smallImageURL);
334                                    }
335                                    else if (Validator.isNotNull(smallImagePath)) {
336                                            byte[] bytes = portletDataContext.getZipEntryAsByteArray(
337                                                    smallImagePath);
338    
339                                            if (bytes != null) {
340                                                    smallFile = FileUtil.createTempFile(
341                                                            template.getSmallImageType());
342    
343                                                    FileUtil.write(smallFile, bytes);
344                                            }
345                                    }
346                            }
347    
348                            ServiceContext serviceContext =
349                                    portletDataContext.createServiceContext(template);
350    
351                            DDMTemplate importedTemplate = null;
352    
353                            if (portletDataContext.isDataStrategyMirror()) {
354                                    Element element =
355                                            portletDataContext.getImportDataStagedModelElement(
356                                                    template);
357    
358                                    boolean preloaded = GetterUtil.getBoolean(
359                                            element.attributeValue("preloaded"));
360    
361                                    DDMTemplate existingTemplate = getExistingTemplate(
362                                            template.getUuid(), portletDataContext.getScopeGroupId(),
363                                            template.getClassNameId(), template.getTemplateKey(),
364                                            preloaded);
365    
366                                    if (existingTemplate == null) {
367                                            serviceContext.setUuid(template.getUuid());
368    
369                                            importedTemplate = addTemplate(
370                                                    userId, portletDataContext.getScopeGroupId(), template,
371                                                    classPK, smallFile, serviceContext);
372                                    }
373                                    else {
374                                            importedTemplate =
375                                                    DDMTemplateLocalServiceUtil.updateTemplate(
376                                                            existingTemplate.getTemplateId(),
377                                                            template.getClassPK(), template.getNameMap(),
378                                                            template.getDescriptionMap(), template.getType(),
379                                                            template.getMode(), template.getLanguage(),
380                                                            template.getScript(), template.isCacheable(),
381                                                            template.isSmallImage(),
382                                                            template.getSmallImageURL(), smallFile,
383                                                            serviceContext);
384                                    }
385                            }
386                            else {
387                                    importedTemplate = addTemplate(
388                                            userId, portletDataContext.getScopeGroupId(), template,
389                                            classPK, smallFile, serviceContext);
390                            }
391    
392                            portletDataContext.importClassedModel(template, importedTemplate);
393    
394                            Map<String, String> ddmTemplateKeys =
395                                    (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
396                                            DDMTemplate.class + ".ddmTemplateKey");
397    
398                            ddmTemplateKeys.put(
399                                    template.getTemplateKey(), importedTemplate.getTemplateKey());
400                    }
401                    finally {
402                            if (smallFile != null) {
403                                    smallFile.delete();
404                            }
405                    }
406            }
407    
408            protected DDMTemplate getExistingTemplate(
409                            String uuid, long groupId, long classNameId, String templateKey,
410                            boolean preloaded)
411                    throws Exception {
412    
413                    DDMTemplate existingTemplate = null;
414    
415                    if (!preloaded) {
416                            existingTemplate =
417                                    DDMTemplateLocalServiceUtil.fetchDDMTemplateByUuidAndGroupId(
418                                            uuid, groupId);
419                    }
420                    else {
421                            existingTemplate = DDMTemplateLocalServiceUtil.fetchTemplate(
422                                    groupId, classNameId, templateKey);
423                    }
424    
425                    return existingTemplate;
426            }
427    
428            private static Log _log = LogFactoryUtil.getLog(
429                    DDMTemplateStagedModelDataHandler.class);
430    
431    }