001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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(path);
104    
105                    prepareLanguagesForImport(structure);
106    
107                    long userId = portletDataContext.getUserId(structure.getUserUuid());
108    
109                    ServiceContext serviceContext = portletDataContext.createServiceContext(
110                            structureElement, structure, _NAMESPACE);
111    
112                    DDMStructure importedStructure = null;
113    
114                    if (portletDataContext.isDataStrategyMirror()) {
115                            boolean preloaded = GetterUtil.getBoolean(
116                                    structureElement.attributeValue("preloaded"));
117    
118                            DDMStructure existingStructure = null;
119    
120                            if (!preloaded) {
121                                    existingStructure = DDMStructureUtil.fetchByUUID_G(
122                                            structure.getUuid(), portletDataContext.getScopeGroupId());
123                            }
124                            else {
125                                    existingStructure = DDMStructureUtil.fetchByG_S(
126                                            portletDataContext.getScopeGroupId(),
127                                            structure.getStructureKey());
128                            }
129    
130                            if (existingStructure == null) {
131                                    serviceContext.setUuid(structure.getUuid());
132    
133                                    importedStructure = DDMStructureLocalServiceUtil.addStructure(
134                                            userId, portletDataContext.getScopeGroupId(),
135                                            structure.getClassNameId(), structure.getStructureKey(),
136                                            structure.getNameMap(), structure.getDescriptionMap(),
137                                            structure.getXsd(), structure.getStorageType(),
138                                            structure.getType(), serviceContext);
139                            }
140                            else {
141                                    importedStructure =
142                                            DDMStructureLocalServiceUtil.updateStructure(
143                                                    existingStructure.getStructureId(),
144                                                    structure.getNameMap(), structure.getDescriptionMap(),
145                                                    structure.getXsd(), serviceContext);
146                            }
147                    }
148                    else {
149                            importedStructure = DDMStructureLocalServiceUtil.addStructure(
150                                    userId, portletDataContext.getScopeGroupId(),
151                                    structure.getClassNameId(), structure.getStructureKey(),
152                                    structure.getNameMap(), structure.getDescriptionMap(),
153                                    structure.getXsd(), structure.getStorageType(),
154                                    structure.getType(), serviceContext);
155                    }
156    
157                    portletDataContext.importClassedModel(
158                            structure, importedStructure, _NAMESPACE);
159            }
160    
161            public static void importTemplate(
162                            PortletDataContext portletDataContext, Element templateElement)
163                    throws Exception {
164    
165                    String path = templateElement.attributeValue("path");
166    
167                    if (!portletDataContext.isPathNotProcessed(path)) {
168                            return;
169                    }
170    
171                    DDMTemplate template =
172                            (DDMTemplate)portletDataContext.getZipEntryAsObject(path);
173    
174                    long userId = portletDataContext.getUserId(template.getUserUuid());
175    
176                    Map<Long, Long> structureIds =
177                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
178                                    DDMStructure.class);
179    
180                    long structureId = MapUtil.getLong(
181                            structureIds, template.getStructureId(), template.getStructureId());
182    
183                    ServiceContext serviceContext = portletDataContext.createServiceContext(
184                            templateElement, template, _NAMESPACE);
185    
186                    DDMTemplate importedTemplate = null;
187    
188                    if (portletDataContext.isDataStrategyMirror()) {
189                            DDMTemplate existingTemplate = DDMTemplateUtil.fetchByUUID_G(
190                                    template.getUuid(), portletDataContext.getScopeGroupId());
191    
192                            if (existingTemplate == null) {
193                                    serviceContext.setUuid(template.getUuid());
194    
195                                    importedTemplate = DDMTemplateLocalServiceUtil.addTemplate(
196                                            userId, portletDataContext.getScopeGroupId(), structureId,
197                                            template.getNameMap(), template.getDescriptionMap(),
198                                            template.getType(), template.getMode(),
199                                            template.getLanguage(), template.getScript(),
200                                            serviceContext);
201                            }
202                            else {
203                                    importedTemplate = DDMTemplateLocalServiceUtil.updateTemplate(
204                                            existingTemplate.getTemplateId(), template.getNameMap(),
205                                            template.getDescriptionMap(), template.getType(),
206                                            template.getMode(), template.getLanguage(),
207                                            template.getScript(), serviceContext);
208                            }
209                    }
210                    else {
211                            importedTemplate = DDMTemplateLocalServiceUtil.addTemplate(
212                                    userId, portletDataContext.getScopeGroupId(), structureId,
213                                    template.getNameMap(), template.getDescriptionMap(),
214                                    template.getType(), template.getMode(), template.getLanguage(),
215                                    template.getScript(), serviceContext);
216                    }
217    
218                    portletDataContext.importClassedModel(
219                            template, importedTemplate, _NAMESPACE);
220            }
221    
222            @Override
223            public PortletDataHandlerControl[] getExportControls() {
224                    return new PortletDataHandlerControl[] {_structures, _templates};
225            }
226    
227            @Override
228            public PortletDataHandlerControl[] getImportControls() {
229                    return new PortletDataHandlerControl[] {_structures, _templates};
230            }
231    
232            @Override
233            public boolean isAlwaysExportable() {
234                    return _ALWAYS_EXPORTABLE;
235            }
236    
237            @Override
238            public boolean isDataLocalized() {
239                    return _DATA_LOCALIZED;
240            }
241    
242            protected static String getStructurePath(
243                    PortletDataContext portletDataContext, DDMStructure structure) {
244    
245                    StringBundler sb = new StringBundler(4);
246    
247                    sb.append(
248                            portletDataContext.getPortletPath(
249                                    PortletKeys.DYNAMIC_DATA_MAPPING));
250                    sb.append("/structures/");
251                    sb.append(structure.getStructureId());
252                    sb.append(".xml");
253    
254                    return sb.toString();
255            }
256    
257            protected static String getTemplatePath(
258                    PortletDataContext portletDataContext, DDMTemplate template) {
259    
260                    StringBundler sb = new StringBundler(4);
261    
262                    sb.append(
263                            portletDataContext.getPortletPath(
264                                    PortletKeys.DYNAMIC_DATA_MAPPING));
265                    sb.append("/templates/");
266                    sb.append(template.getTemplateId());
267                    sb.append(".xml");
268    
269                    return sb.toString();
270            }
271    
272            protected static void prepareLanguagesForImport(DDMStructure structure)
273                    throws PortalException {
274    
275                    Locale structureDefaultLocale = LocaleUtil.fromLanguageId(
276                            structure.getDefaultLocale());
277    
278                    Locale[] structureAvailableLocales = LocaleUtil.fromLanguageIds(
279                            structure.getAvailableLocales());
280    
281                    Locale defaultImportLocale = LocalizationUtil.getDefaultImportLocale(
282                            DDMStructure.class.getName(), structure.getPrimaryKey(),
283                            structureDefaultLocale, structureAvailableLocales);
284    
285                    structure.prepareLocalizedFieldsForImport(defaultImportLocale);
286            }
287    
288            @Override
289            protected PortletPreferences doDeleteData(
290                            PortletDataContext portletDataContext, String portletId,
291                            PortletPreferences portletPreferences)
292                    throws Exception {
293    
294                    if (!portletDataContext.addPrimaryKey(
295                                    DDMPortletDataHandlerImpl.class, "deleteData")) {
296    
297                            DDMTemplateLocalServiceUtil.deleteTemplates(
298                                    portletDataContext.getScopeGroupId());
299    
300                            DDMStructureLocalServiceUtil.deleteStructures(
301                                    portletDataContext.getScopeGroupId());
302                    }
303    
304                    return portletPreferences;
305            }
306    
307            @Override
308            protected String doExportData(
309                            PortletDataContext portletDataContext, String portletId,
310                            PortletPreferences portletPreferences)
311                    throws Exception {
312    
313                    portletDataContext.addPermissions(
314                            "com.liferay.portlet.dynamicdatamapping",
315                            portletDataContext.getScopeGroupId());
316    
317                    Document document = SAXReaderUtil.createDocument();
318    
319                    Element rootElement = document.addElement("ddm-data");
320    
321                    rootElement.addAttribute(
322                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
323    
324                    Element structuresElement = rootElement.addElement("structures");
325    
326                    List<DDMStructure> ddmStructures = DDMStructureUtil.findByGroupId(
327                            portletDataContext.getScopeGroupId());
328    
329                    for (DDMStructure structure : ddmStructures) {
330                            if (portletDataContext.isWithinDateRange(
331                                            structure.getModifiedDate())) {
332    
333                                    exportStructure(
334                                            portletDataContext, structuresElement, structure);
335                            }
336                    }
337    
338                    Element templatesElement = rootElement.addElement("templates");
339    
340                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "templates")) {
341                            List<DDMTemplate> templates = DDMTemplateUtil.findByGroupId(
342                                    portletDataContext.getScopeGroupId());
343    
344                            for (DDMTemplate template : templates) {
345                                    if (portletDataContext.isWithinDateRange(
346                                                    template.getModifiedDate())) {
347    
348                                            exportTemplate(
349                                                    portletDataContext, templatesElement, template);
350                                    }
351                            }
352                    }
353    
354                    return document.formattedString();
355            }
356    
357            @Override
358            protected PortletPreferences doImportData(
359                            PortletDataContext portletDataContext, String portletId,
360                            PortletPreferences portletPreferences, String data)
361                    throws Exception {
362    
363                    portletDataContext.importPermissions(
364                            "com.liferay.portlet.dynamicdatamapping",
365                            portletDataContext.getSourceGroupId(),
366                            portletDataContext.getScopeGroupId());
367    
368                    Document document = SAXReaderUtil.read(data);
369    
370                    Element rootElement = document.getRootElement();
371    
372                    Element structuresElement = rootElement.element("structures");
373    
374                    List<Element> structureElements = structuresElement.elements(
375                            "structure");
376    
377                    for (Element structureElement : structureElements) {
378                            importStructure(portletDataContext, structureElement);
379                    }
380    
381                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "templates")) {
382                            Element templatesElement = rootElement.element("templates");
383    
384                            List<Element> templateElements = templatesElement.elements(
385                                    "template");
386    
387                            for (Element templateElement : templateElements) {
388                                    importTemplate(portletDataContext, templateElement);
389                            }
390                    }
391    
392                    return portletPreferences;
393            }
394    
395            private static final boolean _ALWAYS_EXPORTABLE = true;
396    
397            private static final boolean _DATA_LOCALIZED = true;
398    
399            private static final String _NAMESPACE = "ddm";
400    
401            private static PortletDataHandlerBoolean _structures =
402                    new PortletDataHandlerBoolean(_NAMESPACE, "structures", true, true);
403    
404            private static PortletDataHandlerBoolean _templates =
405                    new PortletDataHandlerBoolean(_NAMESPACE, "templates");
406    
407    }