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