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 static com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleConstants.EVENT_STAGED_MODEL_EXPORT_FAILED;
018    import static com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleConstants.EVENT_STAGED_MODEL_EXPORT_STARTED;
019    import static com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleConstants.EVENT_STAGED_MODEL_EXPORT_SUCCEEDED;
020    import static com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleConstants.EVENT_STAGED_MODEL_IMPORT_FAILED;
021    import static com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleConstants.EVENT_STAGED_MODEL_IMPORT_STARTED;
022    import static com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleConstants.EVENT_STAGED_MODEL_IMPORT_SUCCEEDED;
023    
024    import com.liferay.portal.NoSuchModelException;
025    import com.liferay.portal.kernel.exception.PortalException;
026    import com.liferay.portal.kernel.log.Log;
027    import com.liferay.portal.kernel.log.LogFactoryUtil;
028    import com.liferay.portal.kernel.util.ArrayUtil;
029    import com.liferay.portal.kernel.util.GetterUtil;
030    import com.liferay.portal.kernel.util.MapUtil;
031    import com.liferay.portal.kernel.util.TransientValue;
032    import com.liferay.portal.kernel.workflow.WorkflowConstants;
033    import com.liferay.portal.kernel.xml.Element;
034    import com.liferay.portal.model.Group;
035    import com.liferay.portal.model.LocalizedModel;
036    import com.liferay.portal.model.StagedGroupedModel;
037    import com.liferay.portal.model.StagedModel;
038    import com.liferay.portal.model.TrashedModel;
039    import com.liferay.portal.model.WorkflowedModel;
040    import com.liferay.portal.model.adapter.ModelAdapterUtil;
041    import com.liferay.portal.model.adapter.StagedGroup;
042    import com.liferay.portal.service.GroupLocalServiceUtil;
043    import com.liferay.portlet.asset.model.AssetCategory;
044    import com.liferay.portlet.asset.model.AssetTag;
045    import com.liferay.portlet.asset.model.adapter.StagedAssetTag;
046    import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
047    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
048    import com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleConstants;
049    import com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleManager;
050    import com.liferay.portlet.messageboards.model.MBDiscussion;
051    import com.liferay.portlet.messageboards.model.MBMessage;
052    import com.liferay.portlet.messageboards.service.MBDiscussionLocalServiceUtil;
053    import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
054    import com.liferay.portlet.ratings.model.RatingsEntry;
055    import com.liferay.portlet.ratings.service.RatingsEntryLocalServiceUtil;
056    import com.liferay.portlet.trash.util.TrashUtil;
057    
058    import java.util.ArrayList;
059    import java.util.HashMap;
060    import java.util.HashSet;
061    import java.util.List;
062    import java.util.Map;
063    import java.util.Set;
064    
065    /**
066     * @author Mate Thurzo
067     * @author Daniel Kocsis
068     * @author Zsolt Berentey
069     */
070    public abstract class BaseStagedModelDataHandler<T extends StagedModel>
071            implements StagedModelDataHandler<T> {
072    
073            @Override
074            public abstract void deleteStagedModel(
075                            String uuid, long groupId, String className, String extraData)
076                    throws PortalException;
077    
078            @Override
079            public void exportStagedModel(
080                            PortletDataContext portletDataContext, T stagedModel)
081                    throws PortletDataException {
082    
083                    validateExport(portletDataContext, stagedModel);
084    
085                    String path = ExportImportPathUtil.getModelPath(stagedModel);
086    
087                    if (portletDataContext.isPathExportedInScope(path)) {
088                            return;
089                    }
090    
091                    try {
092                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
093                                    EVENT_STAGED_MODEL_EXPORT_STARTED, getProcessFlag(),
094                                    PortletDataContextFactoryUtil.clonePortletDataContext(
095                                            portletDataContext),
096                                    new TransientValue<T>(stagedModel));
097    
098                            ManifestSummary manifestSummary =
099                                    portletDataContext.getManifestSummary();
100    
101                            PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
102                                    "stagedModel", stagedModel, manifestSummary);
103    
104                            doExportStagedModel(portletDataContext, (T)stagedModel.clone());
105    
106                            exportAssetCategories(portletDataContext, stagedModel);
107                            exportAssetTags(portletDataContext, stagedModel);
108                            exportComments(portletDataContext, stagedModel);
109                            exportRatings(portletDataContext, stagedModel);
110    
111                            if (countStagedModel(portletDataContext, stagedModel)) {
112                                    manifestSummary.incrementModelAdditionCount(
113                                            stagedModel.getStagedModelType());
114                            }
115    
116                            portletDataContext.cleanUpMissingReferences(stagedModel);
117    
118                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
119                                    EVENT_STAGED_MODEL_EXPORT_SUCCEEDED, getProcessFlag(),
120                                    PortletDataContextFactoryUtil.clonePortletDataContext(
121                                            portletDataContext),
122                                    new TransientValue<T>(stagedModel));
123                    }
124                    catch (PortletDataException pde) {
125                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
126                                    EVENT_STAGED_MODEL_EXPORT_FAILED, getProcessFlag(),
127                                    PortletDataContextFactoryUtil.clonePortletDataContext(
128                                            portletDataContext),
129                                    new TransientValue<T>(stagedModel), pde);
130    
131                            throw pde;
132                    }
133                    catch (Throwable t) {
134                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
135                                    EVENT_STAGED_MODEL_EXPORT_FAILED, getProcessFlag(),
136                                    PortletDataContextFactoryUtil.clonePortletDataContext(
137                                            portletDataContext),
138                                    new TransientValue<T>(stagedModel), t);
139    
140                            PortletDataException pde = new PortletDataException(t);
141    
142                            if (t instanceof NoSuchModelException) {
143                                    pde.setStagedModel(stagedModel);
144                                    pde.setType(PortletDataException.MISSING_DEPENDENCY);
145                            }
146    
147                            throw pde;
148                    }
149            }
150    
151            @Override
152            public T fetchMissingReference(String uuid, long groupId) {
153    
154                    // Try to fetch the existing staged model from the importing group
155    
156                    T existingStagedModel = fetchStagedModelByUuidAndGroupId(uuid, groupId);
157    
158                    if ((existingStagedModel != null) &&
159                            !isStagedModelInTrash(existingStagedModel)) {
160    
161                            return existingStagedModel;
162                    }
163    
164                    try {
165    
166                            // Try to fetch the existing staged model from the parent sites
167    
168                            Group originalGroup = GroupLocalServiceUtil.getGroup(groupId);
169    
170                            Group group = originalGroup.getParentGroup();
171    
172                            while (group != null) {
173                                    existingStagedModel = fetchStagedModelByUuidAndGroupId(
174                                            uuid, group.getGroupId());
175    
176                                    if (existingStagedModel != null) {
177                                            break;
178                                    }
179    
180                                    group = group.getParentGroup();
181                            }
182    
183                            if ((existingStagedModel != null) &&
184                                    !isStagedModelInTrash(existingStagedModel)) {
185    
186                                    return existingStagedModel;
187                            }
188    
189                            List<T> existingStagedModels = fetchStagedModelsByUuidAndCompanyId(
190                                    uuid, originalGroup.getCompanyId());
191    
192                            for (T stagedModel : existingStagedModels) {
193                                    try {
194                                            if (stagedModel instanceof StagedGroupedModel) {
195                                                    StagedGroupedModel stagedGroupedModel =
196                                                            (StagedGroupedModel)stagedModel;
197    
198                                                    group = GroupLocalServiceUtil.getGroup(
199                                                            stagedGroupedModel.getGroupId());
200    
201                                                    if (!group.isStagingGroup() &&
202                                                            !isStagedModelInTrash(stagedModel)) {
203    
204                                                            return stagedModel;
205                                                    }
206                                            }
207                                            else if (!isStagedModelInTrash(stagedModel)) {
208                                                    return stagedModel;
209                                            }
210                                    }
211                                    catch (PortalException pe) {
212                                            if (_log.isDebugEnabled()) {
213                                                    _log.debug(pe, pe);
214                                            }
215                                    }
216                            }
217                    }
218                    catch (Exception e) {
219                            if (_log.isDebugEnabled()) {
220                                    _log.debug(e, e);
221                            }
222                            else if (_log.isWarnEnabled()) {
223                                    _log.warn(
224                                            "Unable to fetch missing reference staged model from " +
225                                                    "group " + groupId);
226                            }
227                    }
228    
229                    return null;
230            }
231    
232            @Override
233            public T fetchStagedModelByUuidAndGroupId(String uuid, long groupId) {
234                    return null;
235            }
236    
237            @Override
238            public abstract List<T> fetchStagedModelsByUuidAndCompanyId(
239                    String uuid, long companyId);
240    
241            @Override
242            public abstract String[] getClassNames();
243    
244            @Override
245            public String getDisplayName(T stagedModel) {
246                    return stagedModel.getUuid();
247            }
248    
249            @Override
250            public int[] getExportableStatuses() {
251                    return new int[] {WorkflowConstants.STATUS_APPROVED};
252            }
253    
254            @Override
255            public Map<String, String> getReferenceAttributes(
256                    PortletDataContext portletDataContext, T stagedModel) {
257    
258                    return new HashMap<>();
259            }
260    
261            /**
262             * @deprecated As of 7.0.0, replaced by {@link
263             *             #importMissingReference(PortletDataContext, Element)}
264             */
265            @Deprecated
266            @Override
267            public void importCompanyStagedModel(
268                            PortletDataContext portletDataContext, Element referenceElement)
269                    throws PortletDataException {
270    
271                    importMissingReference(portletDataContext, referenceElement);
272            }
273    
274            /**
275             * @deprecated As of 7.0.0, replaced by {@link
276             *             #importMissingReference(PortletDataContext, String, long,
277             *             long)}
278             */
279            @Deprecated
280            @Override
281            public void importCompanyStagedModel(
282                            PortletDataContext portletDataContext, String uuid, long classPK)
283                    throws PortletDataException {
284    
285                    importMissingReference(
286                            portletDataContext, uuid, portletDataContext.getCompanyGroupId(),
287                            classPK);
288            }
289    
290            @Override
291            public void importMissingReference(
292                            PortletDataContext portletDataContext, Element referenceElement)
293                    throws PortletDataException {
294    
295                    importMissingGroupReference(portletDataContext, referenceElement);
296    
297                    String uuid = referenceElement.attributeValue("uuid");
298    
299                    Map<Long, Long> groupIds =
300                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
301                                    Group.class);
302    
303                    long groupId = GetterUtil.getLong(
304                            referenceElement.attributeValue("group-id"));
305    
306                    groupId = MapUtil.getLong(groupIds, groupId);
307    
308                    long classPK = GetterUtil.getLong(
309                            referenceElement.attributeValue("class-pk"));
310    
311                    importMissingReference(portletDataContext, uuid, groupId, classPK);
312            }
313    
314            @Override
315            public void importMissingReference(
316                            PortletDataContext portletDataContext, String uuid, long groupId,
317                            long classPK)
318                    throws PortletDataException {
319    
320                    try {
321                            doImportMissingReference(
322                                    portletDataContext, uuid, groupId, classPK);
323                    }
324                    catch (PortletDataException pde) {
325                            throw pde;
326                    }
327                    catch (Exception e) {
328                            throw new PortletDataException(e);
329                    }
330            }
331    
332            @Override
333            public void importStagedModel(
334                            PortletDataContext portletDataContext, T stagedModel)
335                    throws PortletDataException {
336    
337                    String path = ExportImportPathUtil.getModelPath(stagedModel);
338    
339                    if (portletDataContext.isPathProcessed(path)) {
340                            return;
341                    }
342    
343                    try {
344                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
345                                    EVENT_STAGED_MODEL_IMPORT_STARTED, getProcessFlag(),
346                                    PortletDataContextFactoryUtil.clonePortletDataContext(
347                                            portletDataContext),
348                                    new TransientValue<T>(stagedModel));
349    
350                            ManifestSummary manifestSummary =
351                                    portletDataContext.getManifestSummary();
352    
353                            PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
354                                    "stagedModel", stagedModel, manifestSummary);
355    
356                            if (stagedModel instanceof LocalizedModel) {
357                                    LocalizedModel localizedModel = (LocalizedModel)stagedModel;
358    
359                                    localizedModel.prepareLocalizedFieldsForImport();
360                            }
361    
362                            restoreStagedModel(portletDataContext, stagedModel);
363    
364                            importAssetCategories(portletDataContext, stagedModel);
365                            importAssetTags(portletDataContext, stagedModel);
366    
367                            importReferenceStagedModels(portletDataContext, stagedModel);
368    
369                            doImportStagedModel(portletDataContext, stagedModel);
370    
371                            importComments(portletDataContext, stagedModel);
372                            importRatings(portletDataContext, stagedModel);
373    
374                            manifestSummary.incrementModelAdditionCount(
375                                    stagedModel.getStagedModelType());
376    
377                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
378                                    EVENT_STAGED_MODEL_IMPORT_SUCCEEDED, getProcessFlag(),
379                                    PortletDataContextFactoryUtil.clonePortletDataContext(
380                                            portletDataContext),
381                                    new TransientValue<T>(stagedModel));
382                    }
383                    catch (PortletDataException pde) {
384                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
385                                    EVENT_STAGED_MODEL_IMPORT_FAILED, getProcessFlag(),
386                                    PortletDataContextFactoryUtil.clonePortletDataContext(
387                                            portletDataContext),
388                                    new TransientValue<T>(stagedModel), pde);
389    
390                            throw pde;
391                    }
392                    catch (Throwable t) {
393                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
394                                    EVENT_STAGED_MODEL_IMPORT_FAILED, getProcessFlag(),
395                                    PortletDataContextFactoryUtil.clonePortletDataContext(
396                                            portletDataContext),
397                                    new TransientValue<T>(stagedModel), t);
398    
399                            throw new PortletDataException(t);
400                    }
401            }
402    
403            @Override
404            public void restoreStagedModel(
405                            PortletDataContext portletDataContext, T stagedModel)
406                    throws PortletDataException {
407    
408                    try {
409                            if (stagedModel instanceof TrashedModel) {
410                                    doRestoreStagedModel(portletDataContext, stagedModel);
411                            }
412                    }
413                    catch (PortletDataException pde) {
414                            throw pde;
415                    }
416                    catch (Exception e) {
417                            throw new PortletDataException(e);
418                    }
419            }
420    
421            @Override
422            public boolean validateReference(
423                    PortletDataContext portletDataContext, Element referenceElement) {
424    
425                    validateMissingGroupReference(portletDataContext, referenceElement);
426    
427                    String uuid = referenceElement.attributeValue("uuid");
428    
429                    Map<Long, Long> groupIds =
430                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
431                                    Group.class);
432    
433                    long groupId = GetterUtil.getLong(
434                            referenceElement.attributeValue("group-id"));
435    
436                    groupId = MapUtil.getLong(groupIds, groupId);
437    
438                    try {
439                            return validateMissingReference(uuid, groupId);
440                    }
441                    catch (Exception e) {
442                            return false;
443                    }
444            }
445    
446            protected boolean countStagedModel(
447                    PortletDataContext portletDataContext, T stagedModel) {
448    
449                    return !portletDataContext.isStagedModelCounted(stagedModel);
450            }
451    
452            protected abstract void doExportStagedModel(
453                            PortletDataContext portletDataContext, T stagedModel)
454                    throws Exception;
455    
456            protected void doImportMissingReference(
457                            PortletDataContext portletDataContext, String uuid, long groupId,
458                            long classPK)
459                    throws Exception {
460    
461                    throw new UnsupportedOperationException();
462            }
463    
464            protected abstract void doImportStagedModel(
465                            PortletDataContext portletDataContext, T stagedModel)
466                    throws Exception;
467    
468            protected void doRestoreStagedModel(
469                            PortletDataContext portletDataContext, T stagedModel)
470                    throws Exception {
471    
472                    throw new UnsupportedOperationException();
473            }
474    
475            protected void exportAssetCategories(
476                            PortletDataContext portletDataContext, T stagedModel)
477                    throws PortletDataException {
478    
479                    List<AssetCategory> assetCategories =
480                            AssetCategoryLocalServiceUtil.getCategories(
481                                    ExportImportClassedModelUtil.getClassName(stagedModel),
482                                    ExportImportClassedModelUtil.getClassPK(stagedModel));
483    
484                    for (AssetCategory assetCategory : assetCategories) {
485                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
486                                    portletDataContext, stagedModel, assetCategory,
487                                    PortletDataContext.REFERENCE_TYPE_WEAK);
488                    }
489            }
490    
491            protected void exportAssetTags(
492                            PortletDataContext portletDataContext, T stagedModel)
493                    throws PortletDataException {
494    
495                    List<AssetTag> assetTags = AssetTagLocalServiceUtil.getTags(
496                            ExportImportClassedModelUtil.getClassName(stagedModel),
497                            ExportImportClassedModelUtil.getClassPK(stagedModel));
498    
499                    for (AssetTag assetTag : assetTags) {
500                            StagedAssetTag stagedAssetTag = ModelAdapterUtil.adapt(
501                                    assetTag, AssetTag.class, StagedAssetTag.class);
502    
503                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
504                                    portletDataContext, stagedModel, stagedAssetTag,
505                                    PortletDataContext.REFERENCE_TYPE_WEAK);
506                    }
507            }
508    
509            protected void exportComments(
510                            PortletDataContext portletDataContext, T stagedModel)
511                    throws PortletDataException {
512    
513                    if (!MapUtil.getBoolean(
514                                    portletDataContext.getParameterMap(),
515                                    PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
516                            !MapUtil.getBoolean(
517                                    portletDataContext.getParameterMap(),
518                                    PortletDataHandlerKeys.COMMENTS)) {
519    
520                            return;
521                    }
522    
523                    MBDiscussion mbDiscussion =
524                            MBDiscussionLocalServiceUtil.fetchDiscussion(
525                                    ExportImportClassedModelUtil.getClassName(stagedModel),
526                                    ExportImportClassedModelUtil.getClassPK(stagedModel));
527    
528                    if (mbDiscussion == null) {
529                            return;
530                    }
531    
532                    List<MBMessage> mbMessages =
533                            MBMessageLocalServiceUtil.getThreadMessages(
534                                    mbDiscussion.getThreadId(), WorkflowConstants.STATUS_APPROVED);
535    
536                    if (mbMessages.isEmpty()) {
537                            return;
538                    }
539    
540                    MBMessage firstMBMessage = mbMessages.get(0);
541    
542                    if ((mbMessages.size() == 1) && firstMBMessage.isRoot()) {
543                            return;
544                    }
545    
546                    for (MBMessage mbMessage : mbMessages) {
547                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
548                                    portletDataContext, stagedModel, mbMessage,
549                                    PortletDataContext.REFERENCE_TYPE_WEAK);
550                    }
551            }
552    
553            protected void exportRatings(
554                            PortletDataContext portletDataContext, T stagedModel)
555                    throws PortletDataException {
556    
557                    if (!MapUtil.getBoolean(
558                                    portletDataContext.getParameterMap(),
559                                    PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
560                            !MapUtil.getBoolean(
561                                    portletDataContext.getParameterMap(),
562                                    PortletDataHandlerKeys.RATINGS)) {
563    
564                            return;
565                    }
566    
567                    List<RatingsEntry> ratingsEntries =
568                            RatingsEntryLocalServiceUtil.getEntries(
569                                    ExportImportClassedModelUtil.getClassName(stagedModel),
570                                    ExportImportClassedModelUtil.getClassPK(stagedModel));
571    
572                    if (ratingsEntries.isEmpty()) {
573                            return;
574                    }
575    
576                    for (RatingsEntry ratingsEntry : ratingsEntries) {
577                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
578                                    portletDataContext, stagedModel, ratingsEntry,
579                                    PortletDataContext.REFERENCE_TYPE_WEAK);
580                    }
581            }
582    
583            protected int getProcessFlag() {
584    
585                    // Ordered by precedence
586    
587                    if (ExportImportThreadLocal.isLayoutStagingInProcess()) {
588                            return ExportImportLifecycleConstants.
589                                    PROCESS_FLAG_LAYOUT_STAGING_IN_PROCESS;
590                    }
591                    else if (ExportImportThreadLocal.isPortletStagingInProcess()) {
592                            return ExportImportLifecycleConstants.
593                                    PROCESS_FLAG_PORTLET_STAGING_IN_PROCESS;
594                    }
595                    else if (ExportImportThreadLocal.isLayoutExportInProcess()) {
596                            return ExportImportLifecycleConstants.
597                                    PROCESS_FLAG_LAYOUT_EXPORT_IN_PROCESS;
598                    }
599                    else if (ExportImportThreadLocal.isLayoutImportInProcess()) {
600                            return ExportImportLifecycleConstants.
601                                    PROCESS_FLAG_LAYOUT_IMPORT_IN_PROCESS;
602                    }
603                    else if (ExportImportThreadLocal.isPortletExportInProcess()) {
604                            return ExportImportLifecycleConstants.
605                                    PROCESS_FLAG_PORTLET_EXPORT_IN_PROCESS;
606                    }
607                    else if (ExportImportThreadLocal.isPortletImportInProcess()) {
608                            return ExportImportLifecycleConstants.
609                                    PROCESS_FLAG_PORTLET_IMPORT_IN_PROCESS;
610                    }
611    
612                    return 0;
613            }
614    
615            protected void importAssetCategories(
616                            PortletDataContext portletDataContext, T stagedModel)
617                    throws PortletDataException {
618    
619                    List<Element> referenceElements =
620                            portletDataContext.getReferenceElements(
621                                    stagedModel, AssetCategory.class);
622    
623                    List<Long> assetCategoryIds = new ArrayList<>(referenceElements.size());
624    
625                    for (Element referenceElement : referenceElements) {
626                            long classPK = GetterUtil.getLong(
627                                    referenceElement.attributeValue("class-pk"));
628    
629                            StagedModelDataHandlerUtil.importReferenceStagedModel(
630                                    portletDataContext, stagedModel, AssetCategory.class, classPK);
631    
632                            assetCategoryIds.add(classPK);
633                    }
634    
635                    Map<Long, Long> assetCategoryIdsMap =
636                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
637                                    AssetCategory.class);
638    
639                    long[] importedAssetCategoryIds = new long[assetCategoryIds.size()];
640    
641                    for (int i = 0; i < assetCategoryIds.size(); i++) {
642                            long categoryId = assetCategoryIds.get(i);
643    
644                            importedAssetCategoryIds[i] = MapUtil.getLong(
645                                    assetCategoryIdsMap, categoryId, categoryId);
646                    }
647    
648                    portletDataContext.addAssetCategories(
649                            ExportImportClassedModelUtil.getClassName(stagedModel),
650                            ExportImportClassedModelUtil.getClassPK(stagedModel),
651                            importedAssetCategoryIds);
652            }
653    
654            protected void importAssetTags(
655                            PortletDataContext portletDataContext, T stagedModel)
656                    throws PortletDataException {
657    
658                    List<Element> referenceElements =
659                            portletDataContext.getReferenceElements(
660                                    stagedModel, StagedAssetTag.class);
661    
662                    List<Long> stagedAssetTagIds = new ArrayList<>(
663                            referenceElements.size());
664    
665                    for (Element referenceElement : referenceElements) {
666                            long classPK = GetterUtil.getLong(
667                                    referenceElement.attributeValue("class-pk"));
668    
669                            StagedModelDataHandlerUtil.importReferenceStagedModel(
670                                    portletDataContext, stagedModel, StagedAssetTag.class, classPK);
671    
672                            stagedAssetTagIds.add(classPK);
673                    }
674    
675                    Map<Long, Long> stagedAssetTagIdsMap =
676                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
677                                    StagedAssetTag.class);
678    
679                    Set<String> assetTagNames = new HashSet<>();
680    
681                    for (long stagedAssetTagId : stagedAssetTagIds) {
682                            long importedStagedAssetTagId = MapUtil.getLong(
683                                    stagedAssetTagIdsMap, stagedAssetTagId, stagedAssetTagId);
684    
685                            AssetTag assetTag = AssetTagLocalServiceUtil.fetchAssetTag(
686                                    importedStagedAssetTagId);
687    
688                            if (assetTag != null) {
689                                    assetTagNames.add(assetTag.getName());
690                            }
691                    }
692    
693                    portletDataContext.addAssetTags(
694                            ExportImportClassedModelUtil.getClassName(stagedModel),
695                            ExportImportClassedModelUtil.getClassPK(stagedModel),
696                            assetTagNames.toArray(new String[assetTagNames.size()]));
697            }
698    
699            protected void importComments(
700                            PortletDataContext portletDataContext, T stagedModel)
701                    throws PortalException {
702    
703                    if (!MapUtil.getBoolean(
704                                    portletDataContext.getParameterMap(),
705                                    PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
706                            !MapUtil.getBoolean(
707                                    portletDataContext.getParameterMap(),
708                                    PortletDataHandlerKeys.COMMENTS)) {
709    
710                            return;
711                    }
712    
713                    StagedModelDataHandlerUtil.importReferenceStagedModels(
714                            portletDataContext, stagedModel, MBMessage.class);
715            }
716    
717            protected void importMissingGroupReference(
718                            PortletDataContext portletDataContext, Element referenceElement)
719                    throws PortletDataException {
720    
721                    StagedModelDataHandler<StagedGroup> stagedModelDataHandler =
722                            (StagedModelDataHandler<StagedGroup>)
723                                    StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
724                                            StagedGroup.class.getName());
725    
726                    stagedModelDataHandler.importMissingReference(
727                            portletDataContext, referenceElement);
728            }
729    
730            protected void importRatings(
731                            PortletDataContext portletDataContext, T stagedModel)
732                    throws PortalException {
733    
734                    if (!MapUtil.getBoolean(
735                                    portletDataContext.getParameterMap(),
736                                    PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
737                            !MapUtil.getBoolean(
738                                    portletDataContext.getParameterMap(),
739                                    PortletDataHandlerKeys.RATINGS)) {
740    
741                            return;
742                    }
743    
744                    StagedModelDataHandlerUtil.importReferenceStagedModels(
745                            portletDataContext, stagedModel, RatingsEntry.class);
746            }
747    
748            protected void importReferenceStagedModels(
749                            PortletDataContext portletDataContext, T stagedModel)
750                    throws PortletDataException {
751    
752                    Element stagedModelElement =
753                            portletDataContext.getImportDataStagedModelElement(stagedModel);
754    
755                    Element referencesElement = stagedModelElement.element("references");
756    
757                    if (referencesElement == null) {
758                            return;
759                    }
760    
761                    List<Element> referenceElements = referencesElement.elements();
762    
763                    for (Element referenceElement : referenceElements) {
764                            String className = referenceElement.attributeValue("class-name");
765    
766                            if (className.equals(AssetCategory.class.getName()) ||
767                                    className.equals(RatingsEntry.class.getName()) ||
768                                    className.equals(MBMessage.class.getName())) {
769    
770                                    continue;
771                            }
772    
773                            long classPK = GetterUtil.getLong(
774                                    referenceElement.attributeValue("class-pk"));
775    
776                            StagedModelDataHandlerUtil.importReferenceStagedModel(
777                                    portletDataContext, stagedModel, className, classPK);
778                    }
779            }
780    
781            protected boolean isStagedModelInTrash(T stagedModel) {
782                    String className = ExportImportClassedModelUtil.getClassName(
783                            stagedModel);
784                    long classPK = ExportImportClassedModelUtil.getClassPK(stagedModel);
785    
786                    try {
787                            return TrashUtil.isInTrash(className, classPK);
788                    }
789                    catch (PortalException pe) {
790                            if (_log.isDebugEnabled()) {
791                                    _log.debug(pe, pe);
792                            }
793                    }
794    
795                    return false;
796            }
797    
798            protected void validateExport(
799                            PortletDataContext portletDataContext, T stagedModel)
800                    throws PortletDataException {
801    
802                    if (!portletDataContext.isInitialPublication() &&
803                            (stagedModel instanceof WorkflowedModel)) {
804    
805                            WorkflowedModel workflowedModel = (WorkflowedModel)stagedModel;
806    
807                            if (!ArrayUtil.contains(
808                                            getExportableStatuses(), workflowedModel.getStatus())) {
809    
810                                    PortletDataException pde = new PortletDataException(
811                                            PortletDataException.STATUS_UNAVAILABLE);
812    
813                                    pde.setStagedModel(stagedModel);
814    
815                                    throw pde;
816                            }
817                    }
818    
819                    if (stagedModel instanceof TrashedModel) {
820                            TrashedModel trashedModel = (TrashedModel)stagedModel;
821    
822                            if (trashedModel.isInTrash()) {
823                                    PortletDataException pde = new PortletDataException(
824                                            PortletDataException.STATUS_IN_TRASH);
825    
826                                    pde.setStagedModel(stagedModel);
827    
828                                    throw pde;
829                            }
830                    }
831            }
832    
833            protected boolean validateMissingGroupReference(
834                    PortletDataContext portletDataContext, Element referenceElement) {
835    
836                    StagedModelDataHandler<StagedGroup> stagedModelDataHandler =
837                            (StagedModelDataHandler<StagedGroup>)
838                                    StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
839                                            StagedGroup.class.getName());
840    
841                    return stagedModelDataHandler.validateReference(
842                            portletDataContext, referenceElement);
843            }
844    
845            protected boolean validateMissingReference(String uuid, long groupId) {
846                    T existingStagedModel = fetchMissingReference(uuid, groupId);
847    
848                    if (existingStagedModel == null) {
849                            return false;
850                    }
851    
852                    return true;
853            }
854    
855            private static final Log _log = LogFactoryUtil.getLog(
856                    BaseStagedModelDataHandler.class);
857    
858    }