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                            classPK);
234            }
235    
236            /**
237             * Imports the staged model that is referenced by another staged model. To
238             * import a staged model referenced by a portlet, use {@link
239             * #importReferenceStagedModel(PortletDataContext, Class, long)}.
240             *
241             * @param  portletDataContext the portlet data context of the current
242             *         process
243             * @param  referrerStagedModel the staged model that references the staged
244             *         model to be imported
245             * @param  stagedModelClass the class of the referenced staged model to be
246             *         imported
247             * @param  classPK the primary key of the referenced staged model to be
248             *         imported
249             * @throws PortletDataException if a portlet data exception occurred
250             */
251            public static <T extends StagedModel> void importReferenceStagedModel(
252                            PortletDataContext portletDataContext, T referrerStagedModel,
253                            Class<?> stagedModelClass, long classPK)
254                    throws PortletDataException {
255    
256                    importReferenceStagedModel(
257                            portletDataContext, referrerStagedModel, stagedModelClass.getName(),
258                            classPK);
259            }
260    
261            /**
262             * Imports the staged model that is referenced by another staged model. To
263             * import a staged model referenced by a portlet, use {@link
264             * #importReferenceStagedModel(PortletDataContext, String, long)}.
265             *
266             * @param  portletDataContext the portlet data context of the current
267             *         process
268             * @param  referrerStagedModel the staged model that references the staged
269             *         model to be imported
270             * @param  stagedModelClassName the class name of the referenced staged
271             *         model to be imported
272             * @param  classPK the primary key of the referenced staged model to be
273             *         imported
274             * @throws PortletDataException if a portlet data exception occurred
275             */
276            public static <T extends StagedModel> void importReferenceStagedModel(
277                            PortletDataContext portletDataContext, T referrerStagedModel,
278                            String stagedModelClassName, long classPK)
279                    throws PortletDataException {
280    
281                    Element referenceElement = portletDataContext.getReferenceElement(
282                            referrerStagedModel, stagedModelClassName, classPK);
283    
284                    doImportReferenceStagedModel(
285                            portletDataContext, referenceElement, stagedModelClassName,
286                            classPK);
287            }
288    
289            public static void importReferenceStagedModels(
290                            PortletDataContext portletDataContext, Class<?> stagedModelClass)
291                    throws PortletDataException {
292    
293                    Element importDataRootElement =
294                            portletDataContext.getImportDataRootElement();
295    
296                    Element referencesElement = importDataRootElement.element("references");
297    
298                    if (referencesElement == null) {
299                            return;
300                    }
301    
302                    List<Element> referenceElements = referencesElement.elements();
303    
304                    for (Element referenceElement : referenceElements) {
305                            String className = referenceElement.attributeValue("class-name");
306                            String stagedModelClassName = stagedModelClass.getName();
307    
308                            if (!stagedModelClassName.equals(className)) {
309                                    continue;
310                            }
311    
312                            boolean missing = portletDataContext.isMissingReference(
313                                    referenceElement);
314    
315                            StagedModelDataHandler<?> stagedModelDataHandler =
316                                    StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
317                                            stagedModelClassName);
318    
319                            if (stagedModelDataHandler == null) {
320                                    continue;
321                            }
322    
323                            if (missing) {
324                                    stagedModelDataHandler.importMissingReference(
325                                            portletDataContext, referenceElement);
326    
327                                    continue;
328                            }
329    
330                            importStagedModel(portletDataContext, referenceElement);
331                    }
332            }
333    
334            public static <T extends StagedModel> void importReferenceStagedModels(
335                            PortletDataContext portletDataContext, T referrerStagedModel,
336                            Class<?> stagedModelClass)
337                    throws PortletDataException {
338    
339                    List<Element> referenceElements =
340                            portletDataContext.getReferenceElements(
341                                    referrerStagedModel, stagedModelClass);
342    
343                    for (Element referenceElement : referenceElements) {
344                            long classPK = GetterUtil.getLong(
345                                    referenceElement.attributeValue("class-pk"));
346    
347                            importReferenceStagedModel(
348                                    portletDataContext, referrerStagedModel, stagedModelClass,
349                                    classPK);
350                    }
351            }
352    
353            public static void importStagedModel(
354                            PortletDataContext portletDataContext, Element element)
355                    throws PortletDataException {
356    
357                    StagedModel stagedModel = _getStagedModel(portletDataContext, element);
358    
359                    importStagedModel(portletDataContext, stagedModel);
360            }
361    
362            public static <T extends StagedModel> void importStagedModel(
363                            PortletDataContext portletDataContext, T stagedModel)
364                    throws PortletDataException {
365    
366                    StagedModelDataHandler<T> stagedModelDataHandler =
367                            _getStagedModelDataHandler(stagedModel);
368    
369                    if (stagedModelDataHandler == null) {
370                            return;
371                    }
372    
373                    stagedModelDataHandler.importStagedModel(
374                            portletDataContext, stagedModel);
375    
376                    LastSessionRecorderHelperUtil.syncLastSessionState();
377            }
378    
379            protected static void doImportReferenceStagedModel(
380                            PortletDataContext portletDataContext, Element referenceElement,
381                            String stagedModelClassName, long classPK)
382                    throws PortletDataException {
383    
384                    if (referenceElement == null) {
385                            return;
386                    }
387    
388                    boolean missing = portletDataContext.isMissingReference(
389                            referenceElement);
390    
391                    StagedModelDataHandler<?> stagedModelDataHandler =
392                            StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
393                                    stagedModelClassName);
394    
395                    if (stagedModelDataHandler == null) {
396                            return;
397                    }
398    
399                    if (missing) {
400                            stagedModelDataHandler.importMissingReference(
401                                    portletDataContext, referenceElement);
402    
403                            return;
404                    }
405    
406                    if (referenceElement != null) {
407                            importStagedModel(portletDataContext, referenceElement);
408    
409                            return;
410                    }
411    
412                    long groupId = GetterUtil.getLong(
413                            referenceElement.attributeValue("group-id"),
414                            portletDataContext.getSourceGroupId());
415    
416                    String stagedModelPath = ExportImportPathUtil.getModelPath(
417                            groupId, stagedModelClassName, classPK);
418    
419                    StagedModel stagedModel =
420                            (StagedModel)portletDataContext.getZipEntryAsObject(
421                                    stagedModelPath);
422    
423                    if (stagedModel != null) {
424                            importStagedModel(portletDataContext, stagedModel);
425                    }
426            }
427    
428            private static StagedModel _getReferenceStagedModel(
429                    PortletDataContext portletDataContext, Element element) {
430    
431                    long groupId = GetterUtil.getLong(element.attributeValue("group-id"));
432                    String className = element.attributeValue("class-name");
433                    long classPK = GetterUtil.getLong(element.attributeValue("class-pk"));
434    
435                    String path = ExportImportPathUtil.getModelPath(
436                            groupId, className, classPK);
437    
438                    StagedModel stagedModel =
439                            (StagedModel)portletDataContext.getZipEntryAsObject(path);
440    
441                    if (stagedModel != null) {
442                            return stagedModel;
443                    }
444    
445                    path = ExportImportPathUtil.getCompanyModelPath(
446                            portletDataContext.getSourceCompanyId(), className, classPK);
447    
448                    return (StagedModel)portletDataContext.getZipEntryAsObject(path);
449            }
450    
451            private static StagedModel _getStagedModel(
452                    PortletDataContext portletDataContext, Element element) {
453    
454                    StagedModel stagedModel = null;
455                    Attribute classNameAttribute = null;
456    
457                    String elementName = element.getName();
458    
459                    if (elementName.equals("reference")) {
460                            stagedModel = _getReferenceStagedModel(portletDataContext, element);
461    
462                            Element referenceStagedModelElement =
463                                    portletDataContext.getImportDataElement(stagedModel);
464    
465                            if (referenceStagedModelElement != null) {
466                                    classNameAttribute = referenceStagedModelElement.attribute(
467                                            "class-name");
468                            }
469                    }
470                    else {
471                            String path = element.attributeValue("path");
472    
473                            stagedModel = (StagedModel)portletDataContext.getZipEntryAsObject(
474                                    element, path);
475    
476                            classNameAttribute = element.attribute("class-name");
477                    }
478    
479                    if ((classNameAttribute != null) &&
480                            (stagedModel instanceof TypedModel)) {
481    
482                            String className = classNameAttribute.getValue();
483    
484                            if (Validator.isNotNull(className)) {
485                                    long classNameId = PortalUtil.getClassNameId(className);
486    
487                                    TypedModel typedModel = (TypedModel)stagedModel;
488    
489                                    typedModel.setClassNameId(classNameId);
490                            }
491                    }
492    
493                    return stagedModel;
494            }
495    
496            private static <T extends StagedModel> StagedModelDataHandler<T>
497                    _getStagedModelDataHandler(T stagedModel) {
498    
499                    StagedModelDataHandler<T> stagedModelDataHandler =
500                            (StagedModelDataHandler<T>)
501                                    StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
502                                            ExportImportClassedModelUtil.getClassName(stagedModel));
503    
504                    return stagedModelDataHandler;
505            }
506    
507    }