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.lar.BasePortletDataHandler;
019    import com.liferay.portal.kernel.lar.PortletDataContext;
020    import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
021    import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.LocaleUtil;
024    import com.liferay.portal.kernel.util.LocalizationUtil;
025    import com.liferay.portal.kernel.util.MapUtil;
026    import com.liferay.portal.kernel.util.StringBundler;
027    import com.liferay.portal.kernel.xml.Document;
028    import com.liferay.portal.kernel.xml.Element;
029    import com.liferay.portal.kernel.xml.SAXReaderUtil;
030    import com.liferay.portal.service.ServiceContext;
031    import com.liferay.portal.service.UserLocalServiceUtil;
032    import com.liferay.portal.util.PortletKeys;
033    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
034    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
035    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
036    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
037    import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMStructureUtil;
038    import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMTemplateUtil;
039    
040    import java.util.List;
041    import java.util.Locale;
042    import java.util.Map;
043    
044    import javax.portlet.PortletPreferences;
045    
046    /**
047     * @author Marcellus Tavares
048     */
049    public class DDMPortletDataHandlerImpl extends BasePortletDataHandler {
050    
051            public static void exportStructure(
052                            PortletDataContext portletDataContext, Element structuresElement,
053                            DDMStructure structure)
054                    throws Exception {
055    
056                    String path = getStructurePath(portletDataContext, structure);
057    
058                    if (!portletDataContext.isPathNotProcessed(path)) {
059                            return;
060                    }
061    
062                    Element structureElement = structuresElement.addElement("structure");
063    
064                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
065                            structure.getCompanyId());
066    
067                    if (defaultUserId == structure.getUserId()) {
068                            structureElement.addAttribute("preloaded", "true");
069                    }
070    
071                    portletDataContext.addClassedModel(
072                            structureElement, path, structure, _NAMESPACE);
073            }
074    
075            public static void exportTemplate(
076                            PortletDataContext portletDataContext, Element templatesElement,
077                            DDMTemplate template)
078                    throws Exception {
079    
080                    String path = getTemplatePath(portletDataContext, template);
081    
082                    if (!portletDataContext.isPathNotProcessed(path)) {
083                            return;
084                    }
085    
086                    Element templateElement = templatesElement.addElement("template");
087    
088                    portletDataContext.addClassedModel(
089                            templateElement, path, template, _NAMESPACE);
090            }
091    
092            public static void importStructure(
093                            PortletDataContext portletDataContext, Element structureElement)
094                    throws Exception {
095    
096                    String path = structureElement.attributeValue("path");
097    
098                    if (!portletDataContext.isPathNotProcessed(path)) {
099                            return;
100                    }
101    
102                    DDMStructure structure =
103                            (DDMStructure)portletDataContext.getZipEntryAsObject(
104                                    structureElement, path);
105    
106                    prepareLanguagesForImport(structure);
107    
108                    long userId = portletDataContext.getUserId(structure.getUserUuid());
109    
110                    ServiceContext serviceContext = portletDataContext.createServiceContext(
111                            structureElement, structure, _NAMESPACE);
112    
113                    DDMStructure importedStructure = null;
114    
115                    if (portletDataContext.isDataStrategyMirror()) {
116                            boolean preloaded = GetterUtil.getBoolean(
117                                    structureElement.attributeValue("preloaded"));
118    
119                            DDMStructure existingStructure = null;
120    
121                            if (!preloaded) {
122                                    existingStructure = DDMStructureUtil.fetchByUUID_G(
123                                            structure.getUuid(), portletDataContext.getScopeGroupId());
124                            }
125                            else {
126                                    existingStructure = DDMStructureUtil.fetchByG_S(
127                                            portletDataContext.getScopeGroupId(),
128                                            structure.getStructureKey());
129                            }
130    
131                            if (existingStructure == null) {
132                                    serviceContext.setUuid(structure.getUuid());
133    
134                                    importedStructure = DDMStructureLocalServiceUtil.addStructure(
135                                            userId, portletDataContext.getScopeGroupId(),
136                                            structure.getClassNameId(), structure.getStructureKey(),
137                                            structure.getNameMap(), structure.getDescriptionMap(),
138                                            structure.getXsd(), structure.getStorageType(),
139                                            structure.getType(), serviceContext);
140                            }
141                            else {
142                                    importedStructure =
143                                            DDMStructureLocalServiceUtil.updateStructure(
144                                                    existingStructure.getStructureId(),
145                                                    structure.getNameMap(), structure.getDescriptionMap(),
146                                                    structure.getXsd(), serviceContext);
147                            }
148                    }
149                    else {
150                            importedStructure = DDMStructureLocalServiceUtil.addStructure(
151                                    userId, portletDataContext.getScopeGroupId(),
152                                    structure.getClassNameId(), structure.getStructureKey(),
153                                    structure.getNameMap(), structure.getDescriptionMap(),
154                                    structure.getXsd(), structure.getStorageType(),
155                                    structure.getType(), serviceContext);
156                    }
157    
158                    portletDataContext.importClassedModel(
159                            structure, importedStructure, _NAMESPACE);
160            }
161    
162            public static void importTemplate(
163                            PortletDataContext portletDataContext, Element templateElement)
164                    throws Exception {
165    
166                    String path = templateElement.attributeValue("path");
167    
168                    if (!portletDataContext.isPathNotProcessed(path)) {
169                            return;
170                    }
171    
172                    DDMTemplate template =
173                            (DDMTemplate)portletDataContext.getZipEntryAsObject(
174                                    templateElement, path);
175    
176                    long userId = portletDataContext.getUserId(template.getUserUuid());
177    
178                    Map<Long, Long> structureIds =
179                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
180                                    DDMStructure.class);
181    
182                    long structureId = MapUtil.getLong(
183                            structureIds, template.getStructureId(), template.getStructureId());
184    
185                    ServiceContext serviceContext = portletDataContext.createServiceContext(
186                            templateElement, template, _NAMESPACE);
187    
188                    DDMTemplate importedTemplate = null;
189    
190                    if (portletDataContext.isDataStrategyMirror()) {
191                            DDMTemplate existingTemplate = DDMTemplateUtil.fetchByUUID_G(
192                                    template.getUuid(), portletDataContext.getScopeGroupId());
193    
194                            if (existingTemplate == null) {
195                                    serviceContext.setUuid(template.getUuid());
196    
197                                    importedTemplate = DDMTemplateLocalServiceUtil.addTemplate(
198                                            userId, portletDataContext.getScopeGroupId(), structureId,
199                                            template.getNameMap(), template.getDescriptionMap(),
200                                            template.getType(), template.getMode(),
201                                            template.getLanguage(), template.getScript(),
202                                            serviceContext);
203                            }
204                            else {
205                                    importedTemplate = DDMTemplateLocalServiceUtil.updateTemplate(
206                                            existingTemplate.getTemplateId(), template.getNameMap(),
207                                            template.getDescriptionMap(), template.getType(),
208                                            template.getMode(), template.getLanguage(),
209                                            template.getScript(), serviceContext);
210                            }
211                    }
212                    else {
213                            importedTemplate = DDMTemplateLocalServiceUtil.addTemplate(
214                                    userId, portletDataContext.getScopeGroupId(), structureId,
215                                    template.getNameMap(), template.getDescriptionMap(),
216                                    template.getType(), template.getMode(), template.getLanguage(),
217                                    template.getScript(), serviceContext);
218                    }
219    
220                    portletDataContext.importClassedModel(
221                            template, importedTemplate, _NAMESPACE);
222            }
223    
224            @Override
225            public PortletDataHandlerControl[] getExportControls() {
226                    return new PortletDataHandlerControl[] {_structures, _templates};
227            }
228    
229            @Override
230            public PortletDataHandlerControl[] getImportControls() {
231                    return new PortletDataHandlerControl[] {_structures, _templates};
232            }
233    
234            @Override
235            public boolean isAlwaysExportable() {
236                    return _ALWAYS_EXPORTABLE;
237            }
238    
239            @Override
240            public boolean isDataLocalized() {
241                    return _DATA_LOCALIZED;
242            }
243    
244            protected static String getStructurePath(
245                    PortletDataContext portletDataContext, DDMStructure structure) {
246    
247                    StringBundler sb = new StringBundler(4);
248    
249                    sb.append(
250                            portletDataContext.getPortletPath(
251                                    PortletKeys.DYNAMIC_DATA_MAPPING));
252                    sb.append("/structures/");
253                    sb.append(structure.getStructureId());
254                    sb.append(".xml");
255    
256                    return sb.toString();
257            }
258    
259            protected static String getTemplatePath(
260                    PortletDataContext portletDataContext, DDMTemplate template) {
261    
262                    StringBundler sb = new StringBundler(4);
263    
264                    sb.append(
265                            portletDataContext.getPortletPath(
266                                    PortletKeys.DYNAMIC_DATA_MAPPING));
267                    sb.append("/templates/");
268                    sb.append(template.getTemplateId());
269                    sb.append(".xml");
270    
271                    return sb.toString();
272            }
273    
274            protected static void prepareLanguagesForImport(DDMStructure structure)
275                    throws PortalException {
276    
277                    Locale structureDefaultLocale = LocaleUtil.fromLanguageId(
278                            structure.getDefaultLocale());
279    
280                    Locale[] structureAvailableLocales = LocaleUtil.fromLanguageIds(
281                            structure.getAvailableLocales());
282    
283                    Locale defaultImportLocale = LocalizationUtil.getDefaultImportLocale(
284                            DDMStructure.class.getName(), structure.getPrimaryKey(),
285                            structureDefaultLocale, structureAvailableLocales);
286    
287                    structure.prepareLocalizedFieldsForImport(defaultImportLocale);
288            }
289    
290            @Override
291            protected PortletPreferences doDeleteData(
292                            PortletDataContext portletDataContext, String portletId,
293                            PortletPreferences portletPreferences)
294                    throws Exception {
295    
296                    if (!portletDataContext.addPrimaryKey(
297                                    DDMPortletDataHandlerImpl.class, "deleteData")) {
298    
299                            DDMTemplateLocalServiceUtil.deleteTemplates(
300                                    portletDataContext.getScopeGroupId());
301    
302                            DDMStructureLocalServiceUtil.deleteStructures(
303                                    portletDataContext.getScopeGroupId());
304                    }
305    
306                    return portletPreferences;
307            }
308    
309            @Override
310            protected String doExportData(
311                            PortletDataContext portletDataContext, String portletId,
312                            PortletPreferences portletPreferences)
313                    throws Exception {
314    
315                    portletDataContext.addPermissions(
316                            "com.liferay.portlet.dynamicdatamapping",
317                            portletDataContext.getScopeGroupId());
318    
319                    Document document = SAXReaderUtil.createDocument();
320    
321                    Element rootElement = document.addElement("ddm-data");
322    
323                    rootElement.addAttribute(
324                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
325    
326                    Element structuresElement = rootElement.addElement("structures");
327    
328                    List<DDMStructure> ddmStructures = DDMStructureUtil.findByGroupId(
329                            portletDataContext.getScopeGroupId());
330    
331                    for (DDMStructure structure : ddmStructures) {
332                            if (portletDataContext.isWithinDateRange(
333                                            structure.getModifiedDate())) {
334    
335                                    exportStructure(
336                                            portletDataContext, structuresElement, structure);
337                            }
338                    }
339    
340                    Element templatesElement = rootElement.addElement("templates");
341    
342                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "templates")) {
343                            List<DDMTemplate> templates = DDMTemplateUtil.findByGroupId(
344                                    portletDataContext.getScopeGroupId());
345    
346                            for (DDMTemplate template : templates) {
347                                    if (portletDataContext.isWithinDateRange(
348                                                    template.getModifiedDate())) {
349    
350                                            exportTemplate(
351                                                    portletDataContext, templatesElement, template);
352                                    }
353                            }
354                    }
355    
356                    return document.formattedString();
357            }
358    
359            @Override
360            protected PortletPreferences doImportData(
361                            PortletDataContext portletDataContext, String portletId,
362                            PortletPreferences portletPreferences, String data)
363                    throws Exception {
364    
365                    portletDataContext.importPermissions(
366                            "com.liferay.portlet.dynamicdatamapping",
367                            portletDataContext.getSourceGroupId(),
368                            portletDataContext.getScopeGroupId());
369    
370                    Document document = SAXReaderUtil.read(data);
371    
372                    Element rootElement = document.getRootElement();
373    
374                    Element structuresElement = rootElement.element("structures");
375    
376                    List<Element> structureElements = structuresElement.elements(
377                            "structure");
378    
379                    for (Element structureElement : structureElements) {
380                            importStructure(portletDataContext, structureElement);
381                    }
382    
383                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "templates")) {
384                            Element templatesElement = rootElement.element("templates");
385    
386                            List<Element> templateElements = templatesElement.elements(
387                                    "template");
388    
389                            for (Element templateElement : templateElements) {
390                                    importTemplate(portletDataContext, templateElement);
391                            }
392                    }
393    
394                    return portletPreferences;
395            }
396    
397            private static final boolean _ALWAYS_EXPORTABLE = true;
398    
399            private static final boolean _DATA_LOCALIZED = true;
400    
401            private static final String _NAMESPACE = "ddm";
402    
403            private static PortletDataHandlerBoolean _structures =
404                    new PortletDataHandlerBoolean(_NAMESPACE, "structures", true, true);
405            private static PortletDataHandlerBoolean _templates =
406                    new PortletDataHandlerBoolean(_NAMESPACE, "templates");
407    
408    }