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.ExportImportPathUtil;
021    import com.liferay.portal.kernel.lar.PortletDataContext;
022    import com.liferay.portal.kernel.lar.PortletDataException;
023    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.util.GetterUtil;
027    import com.liferay.portal.kernel.util.LocaleUtil;
028    import com.liferay.portal.kernel.util.LocalizationUtil;
029    import com.liferay.portal.kernel.util.MapUtil;
030    import com.liferay.portal.kernel.util.Validator;
031    import com.liferay.portal.kernel.xml.Element;
032    import com.liferay.portal.service.ServiceContext;
033    import com.liferay.portal.service.UserLocalServiceUtil;
034    import com.liferay.portal.util.PortalUtil;
035    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
036    import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
037    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
038    
039    import java.util.Date;
040    import java.util.HashMap;
041    import java.util.Locale;
042    import java.util.Map;
043    
044    /**
045     * @author Mate Thurzo
046     * @author Daniel Kocsis
047     */
048    public class DDMStructureStagedModelDataHandler
049            extends BaseStagedModelDataHandler<DDMStructure> {
050    
051            public static final String[] CLASS_NAMES = {DDMStructure.class.getName()};
052    
053            @Override
054            public void deleteStagedModel(
055                            String uuid, long groupId, String className, String extraData)
056                    throws PortalException, SystemException {
057    
058                    DDMStructure ddmStructure =
059                            DDMStructureLocalServiceUtil.fetchDDMStructureByUuidAndGroupId(
060                                    uuid, groupId);
061    
062                    if (ddmStructure != null) {
063                            DDMStructureLocalServiceUtil.deleteStructure(ddmStructure);
064                    }
065            }
066    
067            @Override
068            public String[] getClassNames() {
069                    return CLASS_NAMES;
070            }
071    
072            @Override
073            public String getDisplayName(DDMStructure structure) {
074                    return structure.getNameCurrentValue();
075            }
076    
077            @Override
078            public Map<String, String> getReferenceAttributes(
079                    PortletDataContext portletDataContext, DDMStructure structure) {
080    
081                    Map<String, String> referenceAttributes = new HashMap<String, String>();
082    
083                    referenceAttributes.put(
084                            "referenced-class-name", structure.getClassName());
085                    referenceAttributes.put("structure-key", structure.getStructureKey());
086    
087                    long defaultUserId = 0;
088    
089                    try {
090                            defaultUserId = UserLocalServiceUtil.getDefaultUserId(
091                                    structure.getCompanyId());
092                    }
093                    catch (Exception e) {
094                            return referenceAttributes;
095                    }
096    
097                    boolean preloaded = false;
098    
099                    if (defaultUserId == structure.getUserId()) {
100                            preloaded = true;
101                    }
102    
103                    referenceAttributes.put("preloaded", String.valueOf(preloaded));
104    
105                    return referenceAttributes;
106            }
107    
108            @Override
109            public void importCompanyStagedModel(
110                            PortletDataContext portletDataContext, Element element)
111                    throws PortletDataException {
112    
113                    String uuid = element.attributeValue("uuid");
114                    long classNameId = PortalUtil.getClassNameId(
115                            element.attributeValue("referenced-class-name"));
116                    String structureKey = element.attributeValue("structure-key");
117                    boolean preloaded = GetterUtil.getBoolean(
118                            element.attributeValue("preloaded"));
119    
120                    DDMStructure existingStructure = null;
121    
122                    try {
123                            existingStructure = getExistingStructure(
124                                    uuid, portletDataContext.getCompanyGroupId(), classNameId,
125                                    structureKey, preloaded);
126                    }
127                    catch (Exception e) {
128                            throw new PortletDataException(e);
129                    }
130    
131                    Map<Long, Long> structureIds =
132                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
133                                    DDMStructure.class);
134    
135                    long structureId = GetterUtil.getLong(
136                            element.attributeValue("class-pk"));
137    
138                    structureIds.put(structureId, existingStructure.getStructureId());
139    
140                    Map<String, String> structureKeys =
141                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
142                                    DDMStructure.class + ".ddmStructureKey");
143    
144                    structureKeys.put(structureKey, existingStructure.getStructureKey());
145    
146                    Map<Long, Long> structureIdsUnmodified =
147                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
148                                    DDMStructure.class + ".unmodified");
149    
150                    structureIdsUnmodified.put(
151                            structureId, existingStructure.getStructureId());
152            }
153    
154            @Override
155            public boolean validateReference(
156                    PortletDataContext portletDataContext, Element referenceElement) {
157    
158                    String uuid = referenceElement.attributeValue("uuid");
159                    long classNameId = PortalUtil.getClassNameId(
160                            referenceElement.attributeValue("referenced-class-name"));
161                    String structureKey = referenceElement.attributeValue("structure-key");
162                    boolean preloaded = GetterUtil.getBoolean(
163                            referenceElement.attributeValue("preloaded"));
164    
165                    try {
166                            DDMStructure existingStructure = getExistingStructure(
167                                    uuid, portletDataContext.getScopeGroupId(), classNameId,
168                                    structureKey, preloaded);
169    
170                            if (existingStructure == null) {
171                                    existingStructure = getExistingStructure(
172                                            uuid, portletDataContext.getCompanyGroupId(), classNameId,
173                                            structureKey, preloaded);
174                            }
175    
176                            if (existingStructure == null) {
177                                    return false;
178                            }
179    
180                            return true;
181                    }
182                    catch (Exception e) {
183                            return false;
184                    }
185            }
186    
187            @Override
188            protected void doExportStagedModel(
189                            PortletDataContext portletDataContext, DDMStructure structure)
190                    throws Exception {
191    
192                    Element structureElement = portletDataContext.getExportDataElement(
193                            structure);
194    
195                    if (structure.getParentStructureId() !=
196                                    DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID) {
197    
198                            DDMStructure parentStructure =
199                                    DDMStructureLocalServiceUtil.getStructure(
200                                            structure.getParentStructureId());
201    
202                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
203                                    portletDataContext, structure, parentStructure,
204                                    PortletDataContext.REFERENCE_TYPE_PARENT);
205                    }
206    
207                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
208                            structure.getCompanyId());
209    
210                    if (defaultUserId == structure.getUserId()) {
211                            structureElement.addAttribute("preloaded", "true");
212                    }
213    
214                    portletDataContext.addClassedModel(
215                            structureElement, ExportImportPathUtil.getModelPath(structure),
216                            structure);
217            }
218    
219            @Override
220            protected void doImportStagedModel(
221                            PortletDataContext portletDataContext, DDMStructure structure)
222                    throws Exception {
223    
224                    prepareLanguagesForImport(structure);
225    
226                    long userId = portletDataContext.getUserId(structure.getUserUuid());
227    
228                    if (structure.getParentStructureId() !=
229                                    DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID) {
230    
231                            StagedModelDataHandlerUtil.importReferenceStagedModel(
232                                    portletDataContext, structure, DDMStructure.class,
233                                    structure.getParentStructureId());
234                    }
235    
236                    Map<Long, Long> structureIds =
237                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
238                                    DDMStructure.class);
239    
240                    long parentStructureId = MapUtil.getLong(
241                            structureIds, structure.getParentStructureId(),
242                            structure.getParentStructureId());
243    
244                    Map<String, String> structureKeys =
245                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
246                                    DDMStructure.class + ".ddmStructureKey");
247    
248                    ServiceContext serviceContext = portletDataContext.createServiceContext(
249                            structure);
250    
251                    DDMStructure importedStructure = null;
252    
253                    if (portletDataContext.isDataStrategyMirror()) {
254                            Element element =
255                                    portletDataContext.getImportDataStagedModelElement(structure);
256    
257                            boolean preloaded = GetterUtil.getBoolean(
258                                    element.attributeValue("preloaded"));
259    
260                            DDMStructure existingStructure = getExistingStructure(
261                                    structure.getUuid(), portletDataContext.getScopeGroupId(),
262                                    structure.getClassNameId(), structure.getStructureKey(),
263                                    preloaded);
264    
265                            if (existingStructure == null) {
266                                    serviceContext.setUuid(structure.getUuid());
267    
268                                    importedStructure = DDMStructureLocalServiceUtil.addStructure(
269                                            userId, portletDataContext.getScopeGroupId(),
270                                            parentStructureId, structure.getClassNameId(),
271                                            structure.getStructureKey(), structure.getNameMap(),
272                                            structure.getDescriptionMap(), structure.getXsd(),
273                                            structure.getStorageType(), structure.getType(),
274                                            serviceContext);
275                            }
276                            else if (isModifiedStructure(existingStructure, structure)) {
277                                    importedStructure =
278                                            DDMStructureLocalServiceUtil.updateStructure(
279                                                    existingStructure.getStructureId(), parentStructureId,
280                                                    structure.getNameMap(), structure.getDescriptionMap(),
281                                                    structure.getXsd(), serviceContext);
282                            }
283                            else {
284                                    if (_log.isDebugEnabled()) {
285                                            _log.debug(
286                                                    "Not importing DDM structure with key " +
287                                                            structure.getStructureKey() +
288                                                                    " since it was not modified");
289                                    }
290    
291                                    importedStructure = existingStructure;
292    
293                                    Map<Long, Long> structureIdsUnmodified =
294                                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
295                                                    DDMStructure.class + ".unmodified");
296    
297                                    structureIdsUnmodified.put(
298                                            structure.getStructureId(),
299                                            existingStructure.getStructureId());
300                            }
301                    }
302                    else {
303                            importedStructure = DDMStructureLocalServiceUtil.addStructure(
304                                    userId, portletDataContext.getScopeGroupId(), parentStructureId,
305                                    structure.getClassNameId(), structure.getStructureKey(),
306                                    structure.getNameMap(), structure.getDescriptionMap(),
307                                    structure.getXsd(), structure.getStorageType(),
308                                    structure.getType(), serviceContext);
309                    }
310    
311                    portletDataContext.importClassedModel(structure, importedStructure);
312    
313                    structureKeys.put(
314                            structure.getStructureKey(), importedStructure.getStructureKey());
315            }
316    
317            protected boolean isModifiedStructure(
318                    DDMStructure existingStructure, DDMStructure structure) {
319    
320                    Date modifiedDate = structure.getModifiedDate();
321    
322                    if (modifiedDate.after(existingStructure.getModifiedDate())) {
323                            return true;
324                    }
325    
326                    if (!Validator.equals(
327                                    structure.getNameMap(), existingStructure.getNameMap())) {
328    
329                            return true;
330                    }
331    
332                    if (!Validator.equals(
333                                    structure.getDescriptionMap(),
334                                    existingStructure.getDescriptionMap())) {
335    
336                            return true;
337                    }
338    
339                    if (!Validator.equals(structure.getXsd(), existingStructure.getXsd())) {
340                            return true;
341                    }
342    
343                    if (!Validator.equals(
344                                    structure.getStorageType(),
345                                    existingStructure.getStorageType())) {
346    
347                            return true;
348                    }
349    
350                    if (!Validator.equals(
351                                    structure.getType(), existingStructure.getType())) {
352    
353                            return true;
354                    }
355    
356                    return false;
357            }
358    
359            protected DDMStructure getExistingStructure(
360                            String uuid, long groupId, long classNameId, String structureKey,
361                            boolean preloaded)
362                    throws Exception {
363    
364                    DDMStructure existingStructure = null;
365    
366                    if (!preloaded) {
367                            existingStructure =
368                                    DDMStructureLocalServiceUtil.fetchDDMStructureByUuidAndGroupId(
369                                            uuid, groupId);
370                    }
371                    else {
372                            existingStructure = DDMStructureLocalServiceUtil.fetchStructure(
373                                    groupId, classNameId, structureKey);
374                    }
375    
376                    return existingStructure;
377            }
378    
379            protected void prepareLanguagesForImport(DDMStructure structure)
380                    throws PortalException {
381    
382                    Locale defaultLocale = LocaleUtil.fromLanguageId(
383                            structure.getDefaultLanguageId());
384    
385                    Locale[] availableLocales = LocaleUtil.fromLanguageIds(
386                            structure.getAvailableLanguageIds());
387    
388                    Locale defaultImportLocale = LocalizationUtil.getDefaultImportLocale(
389                            DDMStructure.class.getName(), structure.getPrimaryKey(),
390                            defaultLocale, availableLocales);
391    
392                    structure.prepareLocalizedFieldsForImport(defaultImportLocale);
393            }
394    
395            private static Log _log = LogFactoryUtil.getLog(
396                    DDMStructureStagedModelDataHandler.class);
397    
398    }