001    /**
002     * Copyright (c) 2000-present 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.exportimport.lar;
016    
017    import aQute.bnd.annotation.ProviderType;
018    
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.spring.orm.LastSessionRecorderHelperUtil;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.Validator;
024    import com.liferay.portal.kernel.xml.Attribute;
025    import com.liferay.portal.kernel.xml.Element;
026    import com.liferay.portal.model.Portlet;
027    import com.liferay.portal.model.StagedModel;
028    import com.liferay.portal.model.TypedModel;
029    import com.liferay.portal.service.PortletLocalServiceUtil;
030    import com.liferay.portal.util.PortalUtil;
031    
032    import java.util.Collections;
033    import java.util.List;
034    import java.util.Map;
035    
036    /**
037     * @author Brian Wing Shun Chan
038     * @author Mate Thurzo
039     */
040    @ProviderType
041    public class StagedModelDataHandlerUtil {
042    
043            public static void deleteStagedModel(
044                            PortletDataContext portletDataContext, Element deletionElement)
045                    throws PortalException {
046    
047                    String className = deletionElement.attributeValue("class-name");
048                    String extraData = deletionElement.attributeValue("extra-data");
049                    String uuid = deletionElement.attributeValue("uuid");
050    
051                    StagedModelDataHandler<?> stagedModelDataHandler =
052                            StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
053                                    className);
054    
055                    if (stagedModelDataHandler != null) {
056                            stagedModelDataHandler.deleteStagedModel(
057                                    uuid, portletDataContext.getScopeGroupId(), className,
058                                    extraData);
059                    }
060            }
061    
062            public static <T extends StagedModel> Element exportReferenceStagedModel(
063                            PortletDataContext portletDataContext, String referrerPortletId,
064                            T stagedModel)
065                    throws PortletDataException {
066    
067                    Portlet referrerPortlet = PortletLocalServiceUtil.getPortletById(
068                            referrerPortletId);
069    
070                    if (!ExportImportHelperUtil.isReferenceWithinExportScope(
071                                    portletDataContext, stagedModel)) {
072    
073                            return portletDataContext.addReferenceElement(
074                                    referrerPortlet, portletDataContext.getExportDataRootElement(),
075                                    stagedModel, PortletDataContext.REFERENCE_TYPE_DEPENDENCY,
076                                    true);
077                    }
078    
079                    exportStagedModel(portletDataContext, stagedModel);
080    
081                    return portletDataContext.addReferenceElement(
082                            referrerPortlet, portletDataContext.getExportDataRootElement(),
083                            stagedModel, PortletDataContext.REFERENCE_TYPE_DEPENDENCY, false);
084            }
085    
086            /**
087             * @deprecated As of 7.0.0, replaced by {@link
088             *             #exportReferenceStagedModel(PortletDataContext, StagedModel,
089             *             StagedModel, String)}
090             */
091            @Deprecated
092            public static <T extends StagedModel, U extends StagedModel> Element
093                            exportReferenceStagedModel(
094                                    PortletDataContext portletDataContext, T referrerStagedModel,
095                                    Class<?> referrerStagedModelClass, U stagedModel,
096                                    Class<?> stagedModelClass, String referenceType)
097                    throws PortletDataException {
098    
099                    return exportReferenceStagedModel(
100                            portletDataContext, referrerStagedModel, stagedModel,
101                            referenceType);
102            }
103    
104            /**
105             * @deprecated As of 7.0.0, replaced by {@link
106             *             #exportReferenceStagedModel(PortletDataContext, StagedModel,
107             *             StagedModel, String)}
108             */
109            @Deprecated
110            public static <T extends StagedModel, U extends StagedModel> Element
111                            exportReferenceStagedModel(
112                                    PortletDataContext portletDataContext, T referrerStagedModel,
113                                    Element referrerStagedModelElement, U stagedModel,
114                                    Class<?> stagedModelClass, String referenceType)
115                    throws PortletDataException {
116    
117                    return exportReferenceStagedModel(
118                            portletDataContext, referrerStagedModel, stagedModel,
119                            referenceType);
120            }
121    
122            public static <T extends StagedModel, U extends StagedModel> Element
123                            exportReferenceStagedModel(
124                                    PortletDataContext portletDataContext, T referrerStagedModel,
125                                    U stagedModel, String referenceType)
126                    throws PortletDataException {
127    
128                    Element referrerStagedModelElement =
129                            portletDataContext.getExportDataElement(referrerStagedModel);
130    
131                    if (!ExportImportHelperUtil.isReferenceWithinExportScope(
132                                    portletDataContext, stagedModel)) {
133    
134                            return portletDataContext.addReferenceElement(
135                                    referrerStagedModel, referrerStagedModelElement, stagedModel,
136                                    PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
137                    }
138    
139                    exportStagedModel(portletDataContext, stagedModel);
140    
141                    return portletDataContext.addReferenceElement(
142                            referrerStagedModel, referrerStagedModelElement, stagedModel,
143                            referenceType, false);
144            }
145    
146            public static <T extends StagedModel> void exportStagedModel(
147                            PortletDataContext portletDataContext, T stagedModel)
148                    throws PortletDataException {
149    
150                    StagedModelDataHandler<T> stagedModelDataHandler =
151                            _getStagedModelDataHandler(stagedModel);
152    
153                    if (stagedModelDataHandler == null) {
154                            return;
155                    }
156    
157                    stagedModelDataHandler.exportStagedModel(
158                            portletDataContext, stagedModel);
159            }
160    
161            public static <T extends StagedModel> String getDisplayName(T stagedModel) {
162                    StagedModelDataHandler<T> stagedModelDataHandler =
163                            _getStagedModelDataHandler(stagedModel);
164    
165                    if (stagedModelDataHandler == null) {
166                            return StringPool.BLANK;
167                    }
168    
169                    return stagedModelDataHandler.getDisplayName(stagedModel);
170            }
171    
172            public static Map<String, String> getReferenceAttributes(
173                    PortletDataContext portletDataContext, StagedModel stagedModel) {
174    
175                    StagedModelDataHandler<StagedModel> stagedModelDataHandler =
176                            _getStagedModelDataHandler(stagedModel);
177    
178                    if (stagedModelDataHandler == null) {
179                            return Collections.emptyMap();
180                    }
181    
182                    return stagedModelDataHandler.getReferenceAttributes(
183                            portletDataContext, stagedModel);
184            }
185    
186            /**
187             * Imports the staged model that is referenced by a portlet. To import a
188             * staged model referenced by another staged model, use {@link
189             * #importReferenceStagedModel(PortletDataContext, StagedModel, Class,
190             * long)}.
191             *
192             * @param  portletDataContext the portlet data context of the current
193             *         process
194             * @param  stagedModelClass the class of the referenced staged model to be
195             *         imported
196             * @param  classPK the primary key of the referenced staged model to be
197             *         imported
198             * @throws PortletDataException if a portlet data exception occurred
199             */
200            public static void importReferenceStagedModel(
201                            PortletDataContext portletDataContext, Class<?> stagedModelClass,
202                            long classPK)
203                    throws PortletDataException {
204    
205                    importReferenceStagedModel(
206                            portletDataContext, stagedModelClass.getName(), classPK);
207            }
208    
209            /**
210             * Imports the staged model that is referenced by a portlet. To import a
211             * staged model referenced by another staged model, use {@link
212             * #importReferenceStagedModel(PortletDataContext, StagedModel, String,
213             * long)}.
214             *
215             * @param  portletDataContext the portlet data context of the current
216             *         process
217             * @param  stagedModelClassName the class name of the referenced staged
218             *         model to be imported
219             * @param  classPK the primary key of the referenced staged model to be
220             *         imported
221             * @throws PortletDataException if a portlet data exception occurred
222             */
223            public static void importReferenceStagedModel(
224                            PortletDataContext portletDataContext, String stagedModelClassName,
225                            long classPK)
226                    throws PortletDataException {
227    
228                    Element referenceElement = portletDataContext.getReferenceElement(
229                            stagedModelClassName, classPK);
230    
231                    doImportReferenceStagedModel(
232                            portletDataContext, referenceElement, stagedModelClassName);
233            }
234    
235            /**
236             * Imports the staged model that is referenced by another staged model. To
237             * import a staged model referenced by a portlet, use {@link
238             * #importReferenceStagedModel(PortletDataContext, Class, long)}.
239             *
240             * @param  portletDataContext the portlet data context of the current
241             *         process
242             * @param  referrerStagedModel the staged model that references the staged
243             *         model to be imported
244             * @param  stagedModelClass the class of the referenced staged model to be
245             *         imported
246             * @param  classPK the primary key of the referenced staged model to be
247             *         imported
248             * @throws PortletDataException if a portlet data exception occurred
249             */
250            public static <T extends StagedModel> void importReferenceStagedModel(
251                            PortletDataContext portletDataContext, T referrerStagedModel,
252                            Class<?> stagedModelClass, long classPK)
253                    throws PortletDataException {
254    
255                    importReferenceStagedModel(
256                            portletDataContext, referrerStagedModel, stagedModelClass.getName(),
257                            classPK);
258            }
259    
260            /**
261             * Imports the staged model that is referenced by another staged model. To
262             * import a staged model referenced by a portlet, use {@link
263             * #importReferenceStagedModel(PortletDataContext, String, long)}.
264             *
265             * @param  portletDataContext the portlet data context of the current
266             *         process
267             * @param  referrerStagedModel the staged model that references the staged
268             *         model to be imported
269             * @param  stagedModelClassName the class name of the referenced staged
270             *         model to be imported
271             * @param  classPK the primary key of the referenced staged model to be
272             *         imported
273             * @throws PortletDataException if a portlet data exception occurred
274             */
275            public static <T extends StagedModel> void importReferenceStagedModel(
276                            PortletDataContext portletDataContext, T referrerStagedModel,
277                            String stagedModelClassName, long classPK)
278                    throws PortletDataException {
279    
280                    Element referenceElement = portletDataContext.getReferenceElement(
281                            referrerStagedModel, stagedModelClassName, classPK);
282    
283                    doImportReferenceStagedModel(
284                            portletDataContext, referenceElement, stagedModelClassName);
285            }
286    
287            public static void importReferenceStagedModels(
288                            PortletDataContext portletDataContext, Class<?> stagedModelClass)
289                    throws PortletDataException {
290    
291                    Element importDataRootElement =
292                            portletDataContext.getImportDataRootElement();
293    
294                    Element referencesElement = importDataRootElement.element("references");
295    
296                    if (referencesElement == null) {
297                            return;
298                    }
299    
300                    List<Element> referenceElements = referencesElement.elements();
301    
302                    for (Element referenceElement : referenceElements) {
303                            String className = referenceElement.attributeValue("class-name");
304                            String stagedModelClassName = stagedModelClass.getName();
305    
306                            if (!stagedModelClassName.equals(className)) {
307                                    continue;
308                            }
309    
310                            boolean missing = GetterUtil.getBoolean(
311                                    referenceElement.attributeValue("missing"));
312    
313                            StagedModelDataHandler<?> stagedModelDataHandler =
314                                    StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
315                                            stagedModelClassName);
316    
317                            if (stagedModelDataHandler == null) {
318                                    continue;
319                            }
320    
321                            if (missing) {
322                                    stagedModelDataHandler.importMissingReference(
323                                            portletDataContext, referenceElement);
324    
325                                    continue;
326                            }
327    
328                            importStagedModel(portletDataContext, referenceElement);
329                    }
330            }
331    
332            public static <T extends StagedModel> void importReferenceStagedModels(
333                            PortletDataContext portletDataContext, T referrerStagedModel,
334                            Class<?> stagedModelClass)
335                    throws PortletDataException {
336    
337                    List<Element> referenceElements =
338                            portletDataContext.getReferenceElements(
339                                    referrerStagedModel, stagedModelClass);
340    
341                    for (Element referenceElement : referenceElements) {
342                            long classPK = GetterUtil.getLong(
343                                    referenceElement.attributeValue("class-pk"));
344    
345                            importReferenceStagedModel(
346                                    portletDataContext, referrerStagedModel, stagedModelClass,
347                                    classPK);
348                    }
349            }
350    
351            public static void importStagedModel(
352                            PortletDataContext portletDataContext, Element element)
353                    throws PortletDataException {
354    
355                    StagedModel stagedModel = _getStagedModel(portletDataContext, element);
356    
357                    importStagedModel(portletDataContext, stagedModel);
358            }
359    
360            public static <T extends StagedModel> void importStagedModel(
361                            PortletDataContext portletDataContext, T stagedModel)
362                    throws PortletDataException {
363    
364                    StagedModelDataHandler<T> stagedModelDataHandler =
365                            _getStagedModelDataHandler(stagedModel);
366    
367                    if (stagedModelDataHandler == null) {
368                            return;
369                    }
370    
371                    stagedModelDataHandler.importStagedModel(
372                            portletDataContext, stagedModel);
373    
374                    LastSessionRecorderHelperUtil.syncLastSessionState();
375            }
376    
377            protected static void doImportReferenceStagedModel(
378                            PortletDataContext portletDataContext, Element referenceElement,
379                            String stagedModelClassName)
380                    throws PortletDataException {
381    
382                    if (referenceElement == null) {
383                            return;
384                    }
385    
386                    boolean missing = GetterUtil.getBoolean(
387                            referenceElement.attributeValue("missing"));
388    
389                    StagedModelDataHandler<?> stagedModelDataHandler =
390                            StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
391                                    stagedModelClassName);
392    
393                    if (stagedModelDataHandler == null) {
394                            return;
395                    }
396    
397                    if (missing) {
398                            stagedModelDataHandler.importMissingReference(
399                                    portletDataContext, referenceElement);
400    
401                            return;
402                    }
403    
404                    importStagedModel(portletDataContext, referenceElement);
405            }
406    
407            private static StagedModel _getReferenceStagedModel(
408                    PortletDataContext portletDataContext, Element element) {
409    
410                    long groupId = GetterUtil.getLong(element.attributeValue("group-id"));
411                    String className = element.attributeValue("class-name");
412                    long classPK = GetterUtil.getLong(element.attributeValue("class-pk"));
413    
414                    String path = ExportImportPathUtil.getModelPath(
415                            groupId, className, classPK);
416    
417                    StagedModel stagedModel =
418                            (StagedModel)portletDataContext.getZipEntryAsObject(path);
419    
420                    if (stagedModel != null) {
421                            return stagedModel;
422                    }
423    
424                    path = ExportImportPathUtil.getCompanyModelPath(
425                            portletDataContext.getSourceCompanyId(), className, classPK);
426    
427                    return (StagedModel)portletDataContext.getZipEntryAsObject(path);
428            }
429    
430            private static StagedModel _getStagedModel(
431                    PortletDataContext portletDataContext, Element element) {
432    
433                    StagedModel stagedModel = null;
434                    Attribute classNameAttribute = null;
435    
436                    String elementName = element.getName();
437    
438                    if (elementName.equals("reference")) {
439                            stagedModel = _getReferenceStagedModel(portletDataContext, element);
440    
441                            Element referenceStagedModelElement =
442                                    portletDataContext.getImportDataElement(stagedModel);
443    
444                            if (referenceStagedModelElement != null) {
445                                    classNameAttribute = referenceStagedModelElement.attribute(
446                                            "class-name");
447                            }
448                    }
449                    else {
450                            String path = element.attributeValue("path");
451    
452                            stagedModel = (StagedModel)portletDataContext.getZipEntryAsObject(
453                                    element, path);
454    
455                            classNameAttribute = element.attribute("class-name");
456                    }
457    
458                    if ((classNameAttribute != null) &&
459                            (stagedModel instanceof TypedModel)) {
460    
461                            String className = classNameAttribute.getValue();
462    
463                            if (Validator.isNotNull(className)) {
464                                    long classNameId = PortalUtil.getClassNameId(className);
465    
466                                    TypedModel typedModel = (TypedModel)stagedModel;
467    
468                                    typedModel.setClassNameId(classNameId);
469                            }
470                    }
471    
472                    return stagedModel;
473            }
474    
475            private static <T extends StagedModel> StagedModelDataHandler<T>
476                    _getStagedModelDataHandler(T stagedModel) {
477    
478                    StagedModelDataHandler<T> stagedModelDataHandler =
479                            (StagedModelDataHandler<T>)
480                                    StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
481                                            ExportImportClassedModelUtil.getClassName(stagedModel));
482    
483                    return stagedModelDataHandler;
484            }
485    
486    }