001
014
015 package com.liferay.portal.kernel.lar;
016
017 import com.liferay.portal.NoSuchModelException;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.ArrayUtil;
022 import com.liferay.portal.kernel.util.GetterUtil;
023 import com.liferay.portal.kernel.util.MapUtil;
024 import com.liferay.portal.kernel.workflow.WorkflowConstants;
025 import com.liferay.portal.kernel.xml.Element;
026 import com.liferay.portal.model.Group;
027 import com.liferay.portal.model.LocalizedModel;
028 import com.liferay.portal.model.StagedModel;
029 import com.liferay.portal.model.TrashedModel;
030 import com.liferay.portal.model.WorkflowedModel;
031 import com.liferay.portal.service.GroupLocalServiceUtil;
032 import com.liferay.portlet.asset.model.AssetCategory;
033 import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
034 import com.liferay.portlet.messageboards.model.MBDiscussion;
035 import com.liferay.portlet.messageboards.model.MBMessage;
036 import com.liferay.portlet.messageboards.service.MBDiscussionLocalServiceUtil;
037 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
038 import com.liferay.portlet.ratings.model.RatingsEntry;
039 import com.liferay.portlet.ratings.service.RatingsEntryLocalServiceUtil;
040 import com.liferay.portlet.sitesadmin.lar.StagedGroup;
041
042 import java.util.ArrayList;
043 import java.util.HashMap;
044 import java.util.List;
045 import java.util.Map;
046
047
052 public abstract class BaseStagedModelDataHandler<T extends StagedModel>
053 implements StagedModelDataHandler<T> {
054
055 @Override
056 public abstract void deleteStagedModel(
057 String uuid, long groupId, String className, String extraData)
058 throws PortalException;
059
060 @Override
061 public void exportStagedModel(
062 PortletDataContext portletDataContext, T stagedModel)
063 throws PortletDataException {
064
065 validateExport(portletDataContext, stagedModel);
066
067 String path = ExportImportPathUtil.getModelPath(stagedModel);
068
069 if (portletDataContext.isPathExportedInScope(path)) {
070 return;
071 }
072
073 try {
074 ManifestSummary manifestSummary =
075 portletDataContext.getManifestSummary();
076
077 PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
078 "stagedModel", stagedModel, manifestSummary);
079
080 doExportStagedModel(portletDataContext, (T)stagedModel.clone());
081
082 exportAssetCategories(portletDataContext, stagedModel);
083 exportComments(portletDataContext, stagedModel);
084 exportRatings(portletDataContext, stagedModel);
085
086 if (countStagedModel(portletDataContext, stagedModel)) {
087 manifestSummary.incrementModelAdditionCount(
088 stagedModel.getStagedModelType());
089 }
090
091 portletDataContext.cleanUpMissingReferences(stagedModel);
092 }
093 catch (PortletDataException pde) {
094 throw pde;
095 }
096 catch (Exception e) {
097 PortletDataException pde = new PortletDataException(e);
098
099 if (e instanceof NoSuchModelException) {
100 pde.setStagedModel(stagedModel);
101 pde.setType(PortletDataException.MISSING_DEPENDENCY);
102 }
103
104 throw pde;
105 }
106 }
107
108 @Override
109 public T fetchMissingReference(String uuid, long groupId) {
110
111
112
113 T existingStagedModel = fetchStagedModelByUuidAndGroupId(uuid, groupId);
114
115 if (existingStagedModel != null) {
116 return existingStagedModel;
117 }
118
119 try {
120
121
122
123 Group originalGroup = GroupLocalServiceUtil.getGroup(groupId);
124
125 Group group = originalGroup.getParentGroup();
126
127 while (group != null) {
128 existingStagedModel = fetchStagedModelByUuidAndGroupId(
129 uuid, group.getGroupId());
130
131 if (existingStagedModel != null) {
132 break;
133 }
134
135 group = group.getParentGroup();
136 }
137
138 if (existingStagedModel == null) {
139 existingStagedModel = fetchStagedModelByUuidAndCompanyId(
140 uuid, originalGroup.getCompanyId());
141 }
142
143 return existingStagedModel;
144 }
145 catch (Exception e) {
146 if (_log.isDebugEnabled()) {
147 _log.debug(e, e);
148 }
149 else if (_log.isWarnEnabled()) {
150 _log.warn(
151 "Unable to fetch missing reference staged model from " +
152 "group " + groupId);
153 }
154
155 return null;
156 }
157 }
158
159 @Override
160 public abstract T fetchStagedModelByUuidAndCompanyId(
161 String uuid, long companyId);
162
163 @Override
164 public T fetchStagedModelByUuidAndGroupId(String uuid, long groupId) {
165 return null;
166 }
167
168 @Override
169 public abstract String[] getClassNames();
170
171 @Override
172 public String getDisplayName(T stagedModel) {
173 return stagedModel.getUuid();
174 }
175
176 @Override
177 public int[] getExportableStatuses() {
178 return new int[] {WorkflowConstants.STATUS_APPROVED};
179 }
180
181 @Override
182 public Map<String, String> getReferenceAttributes(
183 PortletDataContext portletDataContext, T stagedModel) {
184
185 return new HashMap<String, String>();
186 }
187
188
192 @Deprecated
193 @Override
194 public void importCompanyStagedModel(
195 PortletDataContext portletDataContext, Element referenceElement)
196 throws PortletDataException {
197
198 importMissingReference(portletDataContext, referenceElement);
199 }
200
201
206 @Deprecated
207 @Override
208 public void importCompanyStagedModel(
209 PortletDataContext portletDataContext, String uuid, long classPK)
210 throws PortletDataException {
211
212 importMissingReference(
213 portletDataContext, uuid, portletDataContext.getCompanyGroupId(),
214 classPK);
215 }
216
217 @Override
218 public void importMissingReference(
219 PortletDataContext portletDataContext, Element referenceElement)
220 throws PortletDataException {
221
222 importMissingGroupReference(portletDataContext, referenceElement);
223
224 String uuid = referenceElement.attributeValue("uuid");
225
226 Map<Long, Long> groupIds =
227 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
228 Group.class);
229
230 long liveGroupId = GetterUtil.getLong(
231 referenceElement.attributeValue("live-group-id"));
232
233 liveGroupId = MapUtil.getLong(groupIds, liveGroupId);
234
235 long classPK = GetterUtil.getLong(
236 referenceElement.attributeValue("class-pk"));
237
238 importMissingReference(portletDataContext, uuid, liveGroupId, classPK);
239 }
240
241 @Override
242 public void importMissingReference(
243 PortletDataContext portletDataContext, String uuid, long groupId,
244 long classPK)
245 throws PortletDataException {
246
247 try {
248 doImportMissingReference(
249 portletDataContext, uuid, groupId, classPK);
250 }
251 catch (PortletDataException pde) {
252 throw pde;
253 }
254 catch (Exception e) {
255 throw new PortletDataException(e);
256 }
257 }
258
259 @Override
260 public void importStagedModel(
261 PortletDataContext portletDataContext, T stagedModel)
262 throws PortletDataException {
263
264 String path = ExportImportPathUtil.getModelPath(stagedModel);
265
266 if (portletDataContext.isPathProcessed(path)) {
267 return;
268 }
269
270 try {
271 ManifestSummary manifestSummary =
272 portletDataContext.getManifestSummary();
273
274 PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
275 "stagedModel", stagedModel, manifestSummary);
276
277 if (stagedModel instanceof LocalizedModel) {
278 LocalizedModel localizedModel = (LocalizedModel)stagedModel;
279
280 localizedModel.prepareLocalizedFieldsForImport();
281 }
282
283 if (stagedModel instanceof TrashedModel) {
284 restoreStagedModel(portletDataContext, stagedModel);
285 }
286
287 importAssetCategories(portletDataContext, stagedModel);
288
289 importReferenceStagedModels(portletDataContext, stagedModel);
290
291 doImportStagedModel(portletDataContext, stagedModel);
292
293 importComments(portletDataContext, stagedModel);
294 importRatings(portletDataContext, stagedModel);
295
296 manifestSummary.incrementModelAdditionCount(
297 stagedModel.getStagedModelType());
298 }
299 catch (PortletDataException pde) {
300 throw pde;
301 }
302 catch (Exception e) {
303 throw new PortletDataException(e);
304 }
305 }
306
307 @Override
308 public void restoreStagedModel(
309 PortletDataContext portletDataContext, T stagedModel)
310 throws PortletDataException {
311
312 try {
313 doRestoreStagedModel(portletDataContext, stagedModel);
314 }
315 catch (PortletDataException pde) {
316 throw pde;
317 }
318 catch (Exception e) {
319 throw new PortletDataException(e);
320 }
321 }
322
323 @Override
324 public boolean validateReference(
325 PortletDataContext portletDataContext, Element referenceElement) {
326
327 validateMissingGroupReference(portletDataContext, referenceElement);
328
329 String uuid = referenceElement.attributeValue("uuid");
330
331 Map<Long, Long> groupIds =
332 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
333 Group.class);
334
335 long liveGroupId = GetterUtil.getLong(
336 referenceElement.attributeValue("live-group-id"));
337
338 liveGroupId = MapUtil.getLong(groupIds, liveGroupId);
339
340 try {
341 return validateMissingReference(uuid, liveGroupId);
342 }
343 catch (Exception e) {
344 return false;
345 }
346 }
347
348 protected boolean countStagedModel(
349 PortletDataContext portletDataContext, T stagedModel) {
350
351 return !portletDataContext.isStagedModelCounted(stagedModel);
352 }
353
354 protected abstract void doExportStagedModel(
355 PortletDataContext portletDataContext, T stagedModel)
356 throws Exception;
357
358 protected void doImportMissingReference(
359 PortletDataContext portletDataContext, String uuid, long groupId,
360 long classPK)
361 throws Exception {
362
363 throw new UnsupportedOperationException();
364 }
365
366 protected abstract void doImportStagedModel(
367 PortletDataContext portletDataContext, T stagedModel)
368 throws Exception;
369
370 protected void doRestoreStagedModel(
371 PortletDataContext portletDataContext, T stagedModel)
372 throws Exception {
373
374 throw new UnsupportedOperationException();
375 }
376
377 protected void exportAssetCategories(
378 PortletDataContext portletDataContext, T stagedModel)
379 throws PortletDataException {
380
381 List<AssetCategory> assetCategories =
382 AssetCategoryLocalServiceUtil.getCategories(
383 ExportImportClassedModelUtil.getClassName(stagedModel),
384 ExportImportClassedModelUtil.getClassPK(stagedModel));
385
386 for (AssetCategory assetCategory : assetCategories) {
387 StagedModelDataHandlerUtil.exportReferenceStagedModel(
388 portletDataContext, stagedModel, assetCategory,
389 PortletDataContext.REFERENCE_TYPE_WEAK);
390 }
391 }
392
393 protected void exportComments(
394 PortletDataContext portletDataContext, T stagedModel)
395 throws PortletDataException {
396
397 if (!MapUtil.getBoolean(
398 portletDataContext.getParameterMap(),
399 PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
400 !MapUtil.getBoolean(
401 portletDataContext.getParameterMap(),
402 PortletDataHandlerKeys.COMMENTS)) {
403
404 return;
405 }
406
407 MBDiscussion mbDiscussion =
408 MBDiscussionLocalServiceUtil.fetchDiscussion(
409 ExportImportClassedModelUtil.getClassName(stagedModel),
410 ExportImportClassedModelUtil.getClassPK(stagedModel));
411
412 if (mbDiscussion == null) {
413 return;
414 }
415
416 List<MBMessage> mbMessages =
417 MBMessageLocalServiceUtil.getThreadMessages(
418 mbDiscussion.getThreadId(), WorkflowConstants.STATUS_APPROVED);
419
420 if (mbMessages.isEmpty()) {
421 return;
422 }
423
424 MBMessage firstMBMessage = mbMessages.get(0);
425
426 if ((mbMessages.size() == 1) && firstMBMessage.isRoot()) {
427 return;
428 }
429
430 for (MBMessage mbMessage : mbMessages) {
431 StagedModelDataHandlerUtil.exportReferenceStagedModel(
432 portletDataContext, stagedModel, mbMessage,
433 PortletDataContext.REFERENCE_TYPE_WEAK);
434 }
435 }
436
437 protected void exportRatings(
438 PortletDataContext portletDataContext, T stagedModel)
439 throws PortletDataException {
440
441 if (!MapUtil.getBoolean(
442 portletDataContext.getParameterMap(),
443 PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
444 !MapUtil.getBoolean(
445 portletDataContext.getParameterMap(),
446 PortletDataHandlerKeys.RATINGS)) {
447
448 return;
449 }
450
451 List<RatingsEntry> ratingsEntries =
452 RatingsEntryLocalServiceUtil.getEntries(
453 ExportImportClassedModelUtil.getClassName(stagedModel),
454 ExportImportClassedModelUtil.getClassPK(stagedModel));
455
456 if (ratingsEntries.isEmpty()) {
457 return;
458 }
459
460 for (RatingsEntry ratingsEntry : ratingsEntries) {
461 StagedModelDataHandlerUtil.exportReferenceStagedModel(
462 portletDataContext, stagedModel, ratingsEntry,
463 PortletDataContext.REFERENCE_TYPE_WEAK);
464 }
465 }
466
467 protected void importAssetCategories(
468 PortletDataContext portletDataContext, T stagedModel)
469 throws PortletDataException {
470
471 List<Element> referenceElements =
472 portletDataContext.getReferenceElements(
473 stagedModel, AssetCategory.class);
474
475 List<Long> assetCategoryIds = new ArrayList<Long>(
476 referenceElements.size());
477
478 for (Element referenceElement : referenceElements) {
479 long classPK = GetterUtil.getLong(
480 referenceElement.attributeValue("class-pk"));
481
482 StagedModelDataHandlerUtil.importReferenceStagedModel(
483 portletDataContext, stagedModel, AssetCategory.class, classPK);
484
485 assetCategoryIds.add(classPK);
486 }
487
488 Map<Long, Long> assetCategoryIdsMap =
489 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
490 AssetCategory.class);
491
492 long[] importedAssetCategoryIds = new long[assetCategoryIds.size()];
493
494 for (int i = 0; i < assetCategoryIds.size(); i++) {
495 long categoryId = assetCategoryIds.get(i);
496
497 importedAssetCategoryIds[i] = MapUtil.getLong(
498 assetCategoryIdsMap, categoryId, categoryId);
499 }
500
501 portletDataContext.addAssetCategories(
502 ExportImportClassedModelUtil.getClassName(stagedModel),
503 ExportImportClassedModelUtil.getClassPK(stagedModel),
504 importedAssetCategoryIds);
505 }
506
507 protected void importComments(
508 PortletDataContext portletDataContext, T stagedModel)
509 throws PortalException {
510
511 if (!MapUtil.getBoolean(
512 portletDataContext.getParameterMap(),
513 PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
514 !MapUtil.getBoolean(
515 portletDataContext.getParameterMap(),
516 PortletDataHandlerKeys.COMMENTS)) {
517
518 return;
519 }
520
521 StagedModelDataHandlerUtil.importReferenceStagedModels(
522 portletDataContext, stagedModel, MBMessage.class);
523 }
524
525 protected void importMissingGroupReference(
526 PortletDataContext portletDataContext, Element referenceElement)
527 throws PortletDataException {
528
529 StagedModelDataHandler<StagedGroup> stagedModelDataHandler =
530 (StagedModelDataHandler<StagedGroup>)
531 StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
532 StagedGroup.class.getName());
533
534 stagedModelDataHandler.importMissingReference(
535 portletDataContext, referenceElement);
536 }
537
538 protected void importRatings(
539 PortletDataContext portletDataContext, T stagedModel)
540 throws PortalException {
541
542 if (!MapUtil.getBoolean(
543 portletDataContext.getParameterMap(),
544 PortletDataHandlerKeys.PORTLET_DATA_ALL) &&
545 !MapUtil.getBoolean(
546 portletDataContext.getParameterMap(),
547 PortletDataHandlerKeys.RATINGS)) {
548
549 return;
550 }
551
552 StagedModelDataHandlerUtil.importReferenceStagedModels(
553 portletDataContext, stagedModel, RatingsEntry.class);
554 }
555
556 protected void importReferenceStagedModels(
557 PortletDataContext portletDataContext, T stagedModel)
558 throws PortletDataException {
559
560 Element stagedModelElement =
561 portletDataContext.getImportDataStagedModelElement(stagedModel);
562
563 Element referencesElement = stagedModelElement.element("references");
564
565 if (referencesElement == null) {
566 return;
567 }
568
569 List<Element> referenceElements = referencesElement.elements();
570
571 for (Element referenceElement : referenceElements) {
572 String className = referenceElement.attributeValue("class-name");
573
574 if (className.equals(AssetCategory.class.getName()) ||
575 className.equals(RatingsEntry.class.getName()) ||
576 className.equals(MBMessage.class.getName())) {
577
578 continue;
579 }
580
581 long classPK = GetterUtil.getLong(
582 referenceElement.attributeValue("class-pk"));
583
584 StagedModelDataHandlerUtil.importReferenceStagedModel(
585 portletDataContext, stagedModel, className, classPK);
586 }
587 }
588
589 protected void validateExport(
590 PortletDataContext portletDataContext, T stagedModel)
591 throws PortletDataException {
592
593 if (stagedModel instanceof WorkflowedModel) {
594 WorkflowedModel workflowedModel = (WorkflowedModel)stagedModel;
595
596 if (!ArrayUtil.contains(
597 getExportableStatuses(), workflowedModel.getStatus())) {
598
599 PortletDataException pde = new PortletDataException(
600 PortletDataException.STATUS_UNAVAILABLE);
601
602 pde.setStagedModel(stagedModel);
603
604 throw pde;
605 }
606 }
607
608 if (stagedModel instanceof TrashedModel) {
609 TrashedModel trashedModel = (TrashedModel)stagedModel;
610
611 if (trashedModel.isInTrash()) {
612 PortletDataException pde = new PortletDataException(
613 PortletDataException.STATUS_IN_TRASH);
614
615 pde.setStagedModel(stagedModel);
616
617 throw pde;
618 }
619 }
620 }
621
622 protected boolean validateMissingGroupReference(
623 PortletDataContext portletDataContext, Element referenceElement) {
624
625 StagedModelDataHandler<StagedGroup> stagedModelDataHandler =
626 (StagedModelDataHandler<StagedGroup>)
627 StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
628 StagedGroup.class.getName());
629
630 return stagedModelDataHandler.validateReference(
631 portletDataContext, referenceElement);
632 }
633
634 protected boolean validateMissingReference(String uuid, long groupId) {
635 T existingStagedModel = fetchMissingReference(uuid, groupId);
636
637 if (existingStagedModel == null) {
638 return false;
639 }
640
641 return true;
642 }
643
644 private static Log _log = LogFactoryUtil.getLog(
645 BaseStagedModelDataHandler.class);
646
647 }