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.comment.CommentManagerUtil;
026    import com.liferay.portal.kernel.comment.DiscussionStagingHandler;
027    import com.liferay.portal.kernel.exception.PortalException;
028    import com.liferay.portal.kernel.log.Log;
029    import com.liferay.portal.kernel.log.LogFactoryUtil;
030    import com.liferay.portal.kernel.util.ArrayUtil;
031    import com.liferay.portal.kernel.util.GetterUtil;
032    import com.liferay.portal.kernel.util.MapUtil;
033    import com.liferay.portal.kernel.util.TransientValue;
034    import com.liferay.portal.kernel.workflow.WorkflowConstants;
035    import com.liferay.portal.kernel.xml.Element;
036    import com.liferay.portal.model.Group;
037    import com.liferay.portal.model.LocalizedModel;
038    import com.liferay.portal.model.StagedGroupedModel;
039    import com.liferay.portal.model.StagedModel;
040    import com.liferay.portal.model.TrashedModel;
041    import com.liferay.portal.model.WorkflowedModel;
042    import com.liferay.portal.model.adapter.StagedGroup;
043    import com.liferay.portal.service.GroupLocalServiceUtil;
044    import com.liferay.portlet.asset.model.AssetCategory;
045    import com.liferay.portlet.asset.model.AssetTag;
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.ExportImportLifecycleManagerUtil;
050    import com.liferay.portlet.ratings.model.RatingsEntry;
051    import com.liferay.portlet.ratings.service.RatingsEntryLocalServiceUtil;
052    import com.liferay.portlet.trash.util.TrashUtil;
053    
054    import java.util.ArrayList;
055    import java.util.HashMap;
056    import java.util.HashSet;
057    import java.util.List;
058    import java.util.Map;
059    import java.util.Set;
060    
061    /**
062     * @author Mate Thurzo
063     * @author Daniel Kocsis
064     * @author Zsolt Berentey
065     */
066    public abstract class BaseStagedModelDataHandler<T extends StagedModel>
067            implements StagedModelDataHandler<T> {
068    
069            @Override
070            public abstract void deleteStagedModel(
071                            String uuid, long groupId, String className, String extraData)
072                    throws PortalException;
073    
074            @Override
075            public abstract void deleteStagedModel(T stagedModel)
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                            ExportImportLifecycleManagerUtil.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                            ExportImportLifecycleManagerUtil.fireExportImportLifecycleEvent(
119                                    EVENT_STAGED_MODEL_EXPORT_SUCCEEDED, getProcessFlag(),
120                                    PortletDataContextFactoryUtil.clonePortletDataContext(
121                                            portletDataContext),
122                                    new TransientValue<T>(stagedModel));
123                    }
124                    catch (PortletDataException pde) {
125                            ExportImportLifecycleManagerUtil.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                            ExportImportLifecycleManagerUtil.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                            ExportImportLifecycleManagerUtil.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                            ExportImportLifecycleManagerUtil.fireExportImportLifecycleEvent(
378                                    EVENT_STAGED_MODEL_IMPORT_SUCCEEDED, getProcessFlag(),
379                                    PortletDataContextFactoryUtil.clonePortletDataContext(
380                                            portletDataContext),
381                                    new TransientValue<T>(stagedModel));
382                    }
383                    catch (PortletDataException pde) {
384                            ExportImportLifecycleManagerUtil.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                            ExportImportLifecycleManagerUtil.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                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
501                                    portletDataContext, stagedModel, assetTag,
502                                    PortletDataContext.REFERENCE_TYPE_WEAK);
503                    }
504            }
505    
506            protected void exportComments(
507                            PortletDataContext portletDataContext, T stagedModel)
508                    throws PortletDataException {
509    
510                    if (!MapUtil.getBoolean(
511                                    portletDataContext.getParameterMap(),
512                                    PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
513                            !MapUtil.getBoolean(
514                                    portletDataContext.getParameterMap(),
515                                    PortletDataHandlerKeys.COMMENTS)) {
516    
517                            return;
518                    }
519    
520                    DiscussionStagingHandler discussionStagingHandler =
521                            CommentManagerUtil.getDiscussionStagingHandler();
522    
523                    if (discussionStagingHandler != null) {
524                            discussionStagingHandler.exportReferenceDiscussions(
525                                    portletDataContext, stagedModel);
526                    }
527            }
528    
529            protected void exportRatings(
530                            PortletDataContext portletDataContext, T stagedModel)
531                    throws PortletDataException {
532    
533                    if (!MapUtil.getBoolean(
534                                    portletDataContext.getParameterMap(),
535                                    PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
536                            !MapUtil.getBoolean(
537                                    portletDataContext.getParameterMap(),
538                                    PortletDataHandlerKeys.RATINGS)) {
539    
540                            return;
541                    }
542    
543                    List<RatingsEntry> ratingsEntries =
544                            RatingsEntryLocalServiceUtil.getEntries(
545                                    ExportImportClassedModelUtil.getClassName(stagedModel),
546                                    ExportImportClassedModelUtil.getClassPK(stagedModel));
547    
548                    if (ratingsEntries.isEmpty()) {
549                            return;
550                    }
551    
552                    for (RatingsEntry ratingsEntry : ratingsEntries) {
553                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
554                                    portletDataContext, stagedModel, ratingsEntry,
555                                    PortletDataContext.REFERENCE_TYPE_WEAK);
556                    }
557            }
558    
559            protected int getProcessFlag() {
560    
561                    // Ordered by precedence
562    
563                    if (ExportImportThreadLocal.isLayoutStagingInProcess()) {
564                            return ExportImportLifecycleConstants.
565                                    PROCESS_FLAG_LAYOUT_STAGING_IN_PROCESS;
566                    }
567                    else if (ExportImportThreadLocal.isPortletStagingInProcess()) {
568                            return ExportImportLifecycleConstants.
569                                    PROCESS_FLAG_PORTLET_STAGING_IN_PROCESS;
570                    }
571                    else if (ExportImportThreadLocal.isLayoutExportInProcess()) {
572                            return ExportImportLifecycleConstants.
573                                    PROCESS_FLAG_LAYOUT_EXPORT_IN_PROCESS;
574                    }
575                    else if (ExportImportThreadLocal.isLayoutImportInProcess()) {
576                            return ExportImportLifecycleConstants.
577                                    PROCESS_FLAG_LAYOUT_IMPORT_IN_PROCESS;
578                    }
579                    else if (ExportImportThreadLocal.isPortletExportInProcess()) {
580                            return ExportImportLifecycleConstants.
581                                    PROCESS_FLAG_PORTLET_EXPORT_IN_PROCESS;
582                    }
583                    else if (ExportImportThreadLocal.isPortletImportInProcess()) {
584                            return ExportImportLifecycleConstants.
585                                    PROCESS_FLAG_PORTLET_IMPORT_IN_PROCESS;
586                    }
587    
588                    return 0;
589            }
590    
591            protected void importAssetCategories(
592                            PortletDataContext portletDataContext, T stagedModel)
593                    throws PortletDataException {
594    
595                    List<Element> referenceElements =
596                            portletDataContext.getReferenceElements(
597                                    stagedModel, AssetCategory.class);
598    
599                    List<Long> assetCategoryIds = new ArrayList<>(referenceElements.size());
600    
601                    for (Element referenceElement : referenceElements) {
602                            long classPK = GetterUtil.getLong(
603                                    referenceElement.attributeValue("class-pk"));
604    
605                            StagedModelDataHandlerUtil.importReferenceStagedModel(
606                                    portletDataContext, stagedModel, AssetCategory.class, classPK);
607    
608                            assetCategoryIds.add(classPK);
609                    }
610    
611                    Map<Long, Long> assetCategoryIdsMap =
612                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
613                                    AssetCategory.class);
614    
615                    long[] importedAssetCategoryIds = new long[assetCategoryIds.size()];
616    
617                    for (int i = 0; i < assetCategoryIds.size(); i++) {
618                            long categoryId = assetCategoryIds.get(i);
619    
620                            importedAssetCategoryIds[i] = MapUtil.getLong(
621                                    assetCategoryIdsMap, categoryId, categoryId);
622                    }
623    
624                    portletDataContext.addAssetCategories(
625                            ExportImportClassedModelUtil.getClassName(stagedModel),
626                            ExportImportClassedModelUtil.getClassPK(stagedModel),
627                            importedAssetCategoryIds);
628            }
629    
630            protected void importAssetTags(
631                            PortletDataContext portletDataContext, T stagedModel)
632                    throws PortletDataException {
633    
634                    List<Element> referenceElements =
635                            portletDataContext.getReferenceElements(
636                                    stagedModel, AssetTag.class);
637    
638                    List<Long> assetTagIds = new ArrayList<>(referenceElements.size());
639    
640                    for (Element referenceElement : referenceElements) {
641                            long classPK = GetterUtil.getLong(
642                                    referenceElement.attributeValue("class-pk"));
643    
644                            StagedModelDataHandlerUtil.importReferenceStagedModel(
645                                    portletDataContext, stagedModel, AssetTag.class, classPK);
646    
647                            assetTagIds.add(classPK);
648                    }
649    
650                    Map<Long, Long> assetTagIdsMap =
651                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
652                                    AssetTag.class);
653    
654                    Set<String> assetTagNames = new HashSet<>();
655    
656                    for (long assetTagId : assetTagIds) {
657                            long importedStagedAssetTagId = MapUtil.getLong(
658                                    assetTagIdsMap, assetTagId, assetTagId);
659    
660                            AssetTag assetTag = AssetTagLocalServiceUtil.fetchAssetTag(
661                                    importedStagedAssetTagId);
662    
663                            if (assetTag != null) {
664                                    assetTagNames.add(assetTag.getName());
665                            }
666                    }
667    
668                    portletDataContext.addAssetTags(
669                            ExportImportClassedModelUtil.getClassName(stagedModel),
670                            ExportImportClassedModelUtil.getClassPK(stagedModel),
671                            assetTagNames.toArray(new String[assetTagNames.size()]));
672            }
673    
674            protected void importComments(
675                            PortletDataContext portletDataContext, T stagedModel)
676                    throws PortalException {
677    
678                    if (!MapUtil.getBoolean(
679                                    portletDataContext.getParameterMap(),
680                                    PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
681                            !MapUtil.getBoolean(
682                                    portletDataContext.getParameterMap(),
683                                    PortletDataHandlerKeys.COMMENTS)) {
684    
685                            return;
686                    }
687    
688                    DiscussionStagingHandler discussionStagingDataHandler =
689                            CommentManagerUtil.getDiscussionStagingHandler();
690    
691                    if (discussionStagingDataHandler != null) {
692                            discussionStagingDataHandler.importReferenceDiscussions(
693                                    portletDataContext, stagedModel);
694                    }
695            }
696    
697            protected void importMissingGroupReference(
698                            PortletDataContext portletDataContext, Element referenceElement)
699                    throws PortletDataException {
700    
701                    StagedModelDataHandler<StagedGroup> stagedModelDataHandler =
702                            (StagedModelDataHandler<StagedGroup>)
703                                    StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
704                                            StagedGroup.class.getName());
705    
706                    stagedModelDataHandler.importMissingReference(
707                            portletDataContext, referenceElement);
708            }
709    
710            protected void importRatings(
711                            PortletDataContext portletDataContext, T stagedModel)
712                    throws PortalException {
713    
714                    if (!MapUtil.getBoolean(
715                                    portletDataContext.getParameterMap(),
716                                    PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
717                            !MapUtil.getBoolean(
718                                    portletDataContext.getParameterMap(),
719                                    PortletDataHandlerKeys.RATINGS)) {
720    
721                            return;
722                    }
723    
724                    StagedModelDataHandlerUtil.importReferenceStagedModels(
725                            portletDataContext, stagedModel, RatingsEntry.class);
726            }
727    
728            protected void importReferenceStagedModels(
729                            PortletDataContext portletDataContext, T stagedModel)
730                    throws PortletDataException {
731    
732                    Element stagedModelElement =
733                            portletDataContext.getImportDataStagedModelElement(stagedModel);
734    
735                    Element referencesElement = stagedModelElement.element("references");
736    
737                    if (referencesElement == null) {
738                            return;
739                    }
740    
741                    DiscussionStagingHandler discussionStagingHandler =
742                            CommentManagerUtil.getDiscussionStagingHandler();
743    
744                    String stagedModelClassName = null;
745    
746                    if (discussionStagingHandler != null) {
747                            stagedModelClassName = discussionStagingHandler.getClassName();
748                    }
749    
750                    List<Element> referenceElements = referencesElement.elements();
751    
752                    for (Element referenceElement : referenceElements) {
753                            String className = referenceElement.attributeValue("class-name");
754    
755                            if (className.equals(AssetCategory.class.getName()) ||
756                                    className.equals(RatingsEntry.class.getName()) ||
757                                    className.equals(stagedModelClassName)) {
758    
759                                    continue;
760                            }
761    
762                            long classPK = GetterUtil.getLong(
763                                    referenceElement.attributeValue("class-pk"));
764    
765                            StagedModelDataHandlerUtil.importReferenceStagedModel(
766                                    portletDataContext, stagedModel, className, classPK);
767                    }
768            }
769    
770            protected boolean isStagedModelInTrash(T stagedModel) {
771                    String className = ExportImportClassedModelUtil.getClassName(
772                            stagedModel);
773                    long classPK = ExportImportClassedModelUtil.getClassPK(stagedModel);
774    
775                    try {
776                            return TrashUtil.isInTrash(className, classPK);
777                    }
778                    catch (PortalException pe) {
779                            if (_log.isDebugEnabled()) {
780                                    _log.debug(pe, pe);
781                            }
782                    }
783    
784                    return false;
785            }
786    
787            protected void validateExport(
788                            PortletDataContext portletDataContext, T stagedModel)
789                    throws PortletDataException {
790    
791                    if (!portletDataContext.isInitialPublication() &&
792                            (stagedModel instanceof WorkflowedModel)) {
793    
794                            WorkflowedModel workflowedModel = (WorkflowedModel)stagedModel;
795    
796                            if (!ArrayUtil.contains(
797                                            getExportableStatuses(), workflowedModel.getStatus())) {
798    
799                                    PortletDataException pde = new PortletDataException(
800                                            PortletDataException.STATUS_UNAVAILABLE);
801    
802                                    pde.setStagedModel(stagedModel);
803    
804                                    throw pde;
805                            }
806                    }
807    
808                    if (stagedModel instanceof TrashedModel) {
809                            TrashedModel trashedModel = (TrashedModel)stagedModel;
810    
811                            if (trashedModel.isInTrash()) {
812                                    PortletDataException pde = new PortletDataException(
813                                            PortletDataException.STATUS_IN_TRASH);
814    
815                                    pde.setStagedModel(stagedModel);
816    
817                                    throw pde;
818                            }
819                    }
820            }
821    
822            protected boolean validateMissingGroupReference(
823                    PortletDataContext portletDataContext, Element referenceElement) {
824    
825                    StagedModelDataHandler<StagedGroup> stagedModelDataHandler =
826                            (StagedModelDataHandler<StagedGroup>)
827                                    StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
828                                            StagedGroup.class.getName());
829    
830                    return stagedModelDataHandler.validateReference(
831                            portletDataContext, referenceElement);
832            }
833    
834            protected boolean validateMissingReference(String uuid, long groupId) {
835                    T existingStagedModel = fetchMissingReference(uuid, groupId);
836    
837                    if (existingStagedModel == null) {
838                            return false;
839                    }
840    
841                    return true;
842            }
843    
844            private static final Log _log = LogFactoryUtil.getLog(
845                    BaseStagedModelDataHandler.class);
846    
847    }