001    /**
002     * Copyright (c) 2000-2013 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.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.DateUtil;
027    import com.liferay.portal.kernel.util.GetterUtil;
028    import com.liferay.portal.kernel.util.LocaleUtil;
029    import com.liferay.portal.kernel.util.LocalizationUtil;
030    import com.liferay.portal.kernel.util.MapUtil;
031    import com.liferay.portal.kernel.util.Validator;
032    import com.liferay.portal.kernel.xml.Element;
033    import com.liferay.portal.service.ServiceContext;
034    import com.liferay.portal.service.UserLocalServiceUtil;
035    import com.liferay.portal.util.PortalUtil;
036    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
037    import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
038    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
039    
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            protected void doImportGroupStagedModel(
156                            PortletDataContext portletDataContext, Element referenceElement,
157                            long groupId)
158                    throws Exception {
159    
160                    String uuid = referenceElement.attributeValue("uuid");
161                    long classNameId = PortalUtil.getClassNameId(
162                            referenceElement.attributeValue("referenced-class-name"));
163                    String structureKey = referenceElement.attributeValue("structure-key");
164                    boolean preloaded = GetterUtil.getBoolean(
165                            referenceElement.attributeValue("preloaded"));
166    
167                    DDMStructure existingStructure = null;
168    
169                    try {
170                            existingStructure = getExistingStructure(
171                                    uuid, groupId, classNameId, structureKey, preloaded);
172                    }
173                    catch (Exception e) {
174                            throw new PortletDataException(e);
175                    }
176    
177                    if (existingStructure == null) {
178                            return;
179                    }
180    
181                    Map<Long, Long> structureIds =
182                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
183                                    DDMStructure.class);
184    
185                    long structureId = GetterUtil.getLong(
186                            referenceElement.attributeValue("class-pk"));
187    
188                    structureIds.put(structureId, existingStructure.getStructureId());
189    
190                    Map<String, String> structureKeys =
191                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
192                                    DDMStructure.class + ".ddmStructureKey");
193    
194                    structureKeys.put(structureKey, existingStructure.getStructureKey());
195    
196                    Map<Long, Long> structureIdsUnmodified =
197                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
198                                    DDMStructure.class + ".unmodified");
199    
200                    structureIdsUnmodified.put(
201                            structureId, existingStructure.getStructureId());
202            }
203    
204            @Override
205            public boolean validateReference(
206                    PortletDataContext portletDataContext, Element referenceElement) {
207    
208                    String uuid = referenceElement.attributeValue("uuid");
209                    long classNameId = PortalUtil.getClassNameId(
210                            referenceElement.attributeValue("referenced-class-name"));
211                    String structureKey = referenceElement.attributeValue("structure-key");
212                    boolean preloaded = GetterUtil.getBoolean(
213                            referenceElement.attributeValue("preloaded"));
214    
215                    try {
216                            DDMStructure existingStructure = getExistingStructure(
217                                    uuid, portletDataContext.getScopeGroupId(), classNameId,
218                                    structureKey, preloaded);
219    
220                            if (existingStructure == null) {
221                                    existingStructure = getExistingStructure(
222                                            uuid, portletDataContext.getCompanyGroupId(), classNameId,
223                                            structureKey, preloaded);
224                            }
225    
226                            if (existingStructure == null) {
227                                    return false;
228                            }
229    
230                            return true;
231                    }
232                    catch (Exception e) {
233                            return false;
234                    }
235            }
236    
237            @Override
238            protected void doExportStagedModel(
239                            PortletDataContext portletDataContext, DDMStructure structure)
240                    throws Exception {
241    
242                    Element structureElement = portletDataContext.getExportDataElement(
243                            structure);
244    
245                    if (structure.getParentStructureId() !=
246                                    DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID) {
247    
248                            DDMStructure parentStructure =
249                                    DDMStructureLocalServiceUtil.getStructure(
250                                            structure.getParentStructureId());
251    
252                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
253                                    portletDataContext, structure, parentStructure,
254                                    PortletDataContext.REFERENCE_TYPE_PARENT);
255                    }
256    
257                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
258                            structure.getCompanyId());
259    
260                    if (defaultUserId == structure.getUserId()) {
261                            structureElement.addAttribute("preloaded", "true");
262                    }
263    
264                    portletDataContext.addClassedModel(
265                            structureElement, ExportImportPathUtil.getModelPath(structure),
266                            structure);
267            }
268    
269            @Override
270            protected void doImportStagedModel(
271                            PortletDataContext portletDataContext, DDMStructure structure)
272                    throws Exception {
273    
274                    prepareLanguagesForImport(structure);
275    
276                    long userId = portletDataContext.getUserId(structure.getUserUuid());
277    
278                    if (structure.getParentStructureId() !=
279                                    DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID) {
280    
281                            StagedModelDataHandlerUtil.importReferenceStagedModel(
282                                    portletDataContext, structure, DDMStructure.class,
283                                    structure.getParentStructureId());
284                    }
285    
286                    Map<Long, Long> structureIds =
287                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
288                                    DDMStructure.class);
289    
290                    long parentStructureId = MapUtil.getLong(
291                            structureIds, structure.getParentStructureId(),
292                            structure.getParentStructureId());
293    
294                    Map<String, String> structureKeys =
295                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
296                                    DDMStructure.class + ".ddmStructureKey");
297    
298                    ServiceContext serviceContext = portletDataContext.createServiceContext(
299                            structure);
300    
301                    DDMStructure importedStructure = null;
302    
303                    if (portletDataContext.isDataStrategyMirror()) {
304                            Element element =
305                                    portletDataContext.getImportDataStagedModelElement(structure);
306    
307                            boolean preloaded = GetterUtil.getBoolean(
308                                    element.attributeValue("preloaded"));
309    
310                            DDMStructure existingStructure = getExistingStructure(
311                                    structure.getUuid(), portletDataContext.getScopeGroupId(),
312                                    structure.getClassNameId(), structure.getStructureKey(),
313                                    preloaded);
314    
315                            if (existingStructure == null) {
316                                    serviceContext.setUuid(structure.getUuid());
317    
318                                    // Force a new structure key if a structure with the same key
319                                    // already exists
320    
321                                    existingStructure = DDMStructureLocalServiceUtil.fetchStructure(
322                                            portletDataContext.getScopeGroupId(),
323                                            structure.getClassNameId(), structure.getStructureKey());
324    
325                                    if (existingStructure != null) {
326                                            structure.setStructureKey(null);
327                                    }
328    
329                                    importedStructure = DDMStructureLocalServiceUtil.addStructure(
330                                            userId, portletDataContext.getScopeGroupId(),
331                                            parentStructureId, structure.getClassNameId(),
332                                            structure.getStructureKey(), structure.getNameMap(),
333                                            structure.getDescriptionMap(), structure.getXsd(),
334                                            structure.getStorageType(), structure.getType(),
335                                            serviceContext);
336                            }
337                            else if (isModifiedStructure(existingStructure, structure)) {
338                                    importedStructure =
339                                            DDMStructureLocalServiceUtil.updateStructure(
340                                                    existingStructure.getStructureId(), parentStructureId,
341                                                    structure.getNameMap(), structure.getDescriptionMap(),
342                                                    structure.getXsd(), serviceContext);
343                            }
344                            else {
345                                    if (_log.isDebugEnabled()) {
346                                            _log.debug(
347                                                    "Not importing DDM structure with key " +
348                                                            structure.getStructureKey() +
349                                                                    " since it was not modified");
350                                    }
351    
352                                    importedStructure = existingStructure;
353    
354                                    Map<Long, Long> structureIdsUnmodified =
355                                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
356                                                    DDMStructure.class + ".unmodified");
357    
358                                    structureIdsUnmodified.put(
359                                            structure.getStructureId(),
360                                            existingStructure.getStructureId());
361                            }
362                    }
363                    else {
364                            importedStructure = DDMStructureLocalServiceUtil.addStructure(
365                                    userId, portletDataContext.getScopeGroupId(), parentStructureId,
366                                    structure.getClassNameId(), null, structure.getNameMap(),
367                                    structure.getDescriptionMap(), structure.getXsd(),
368                                    structure.getStorageType(), structure.getType(),
369                                    serviceContext);
370                    }
371    
372                    portletDataContext.importClassedModel(structure, importedStructure);
373    
374                    structureKeys.put(
375                            structure.getStructureKey(), importedStructure.getStructureKey());
376            }
377    
378            protected boolean isModifiedStructure(
379                    DDMStructure existingStructure, DDMStructure structure) {
380    
381                    if (DateUtil.compareTo(
382                                    structure.getModifiedDate(),
383                                    existingStructure.getModifiedDate()) > 0) {
384    
385                            return true;
386                    }
387    
388                    if (!Validator.equals(
389                                    structure.getNameMap(), existingStructure.getNameMap())) {
390    
391                            return true;
392                    }
393    
394                    if (!Validator.equals(
395                                    structure.getDescriptionMap(),
396                                    existingStructure.getDescriptionMap())) {
397    
398                            return true;
399                    }
400    
401                    if (!Validator.equals(structure.getXsd(), existingStructure.getXsd())) {
402                            return true;
403                    }
404    
405                    if (!Validator.equals(
406                                    structure.getStorageType(),
407                                    existingStructure.getStorageType())) {
408    
409                            return true;
410                    }
411    
412                    if (!Validator.equals(
413                                    structure.getType(), existingStructure.getType())) {
414    
415                            return true;
416                    }
417    
418                    return false;
419            }
420    
421            protected DDMStructure getExistingStructure(
422                            String uuid, long groupId, long classNameId, String structureKey,
423                            boolean preloaded)
424                    throws Exception {
425    
426                    DDMStructure existingStructure = null;
427    
428                    if (!preloaded) {
429                            existingStructure =
430                                    DDMStructureLocalServiceUtil.fetchDDMStructureByUuidAndGroupId(
431                                            uuid, groupId);
432                    }
433                    else {
434                            existingStructure = DDMStructureLocalServiceUtil.fetchStructure(
435                                    groupId, classNameId, structureKey);
436                    }
437    
438                    return existingStructure;
439            }
440    
441            protected void prepareLanguagesForImport(DDMStructure structure)
442                    throws PortalException {
443    
444                    Locale defaultLocale = LocaleUtil.fromLanguageId(
445                            structure.getDefaultLanguageId());
446    
447                    Locale[] availableLocales = LocaleUtil.fromLanguageIds(
448                            structure.getAvailableLanguageIds());
449    
450                    Locale defaultImportLocale = LocalizationUtil.getDefaultImportLocale(
451                            DDMStructure.class.getName(), structure.getPrimaryKey(),
452                            defaultLocale, availableLocales);
453    
454                    structure.prepareLocalizedFieldsForImport(defaultImportLocale);
455            }
456    
457            private static Log _log = LogFactoryUtil.getLog(
458                    DDMStructureStagedModelDataHandler.class);
459    
460    }