001
014
015 package com.liferay.portal.lar;
016
017 import com.liferay.portal.kernel.lar.ExportImportClassedModelUtil;
018 import com.liferay.portal.kernel.lar.ExportImportPathUtil;
019 import com.liferay.portal.kernel.lar.PortletDataContext;
020 import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
021 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
022 import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
023 import com.liferay.portal.kernel.lar.UserIdStrategy;
024 import com.liferay.portal.kernel.util.ListUtil;
025 import com.liferay.portal.kernel.util.Time;
026 import com.liferay.portal.kernel.workflow.WorkflowConstants;
027 import com.liferay.portal.kernel.xml.Document;
028 import com.liferay.portal.kernel.xml.Element;
029 import com.liferay.portal.kernel.xml.SAXReaderUtil;
030 import com.liferay.portal.kernel.zip.ZipReader;
031 import com.liferay.portal.kernel.zip.ZipReaderFactoryUtil;
032 import com.liferay.portal.kernel.zip.ZipWriter;
033 import com.liferay.portal.kernel.zip.ZipWriterFactoryUtil;
034 import com.liferay.portal.model.Company;
035 import com.liferay.portal.model.Group;
036 import com.liferay.portal.model.StagedModel;
037 import com.liferay.portal.service.CompanyLocalServiceUtil;
038 import com.liferay.portal.service.GroupLocalServiceUtil;
039 import com.liferay.portal.service.ServiceContext;
040 import com.liferay.portal.service.ServiceContextThreadLocal;
041 import com.liferay.portal.test.DeleteAfterTestRun;
042 import com.liferay.portal.util.test.GroupTestUtil;
043 import com.liferay.portal.util.test.ServiceContextTestUtil;
044 import com.liferay.portal.util.test.TestPropsValues;
045 import com.liferay.portlet.asset.model.AssetCategory;
046 import com.liferay.portlet.asset.model.AssetEntry;
047 import com.liferay.portlet.asset.model.AssetTag;
048 import com.liferay.portlet.asset.model.AssetVocabulary;
049 import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
050 import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
051 import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
052 import com.liferay.portlet.asset.service.AssetVocabularyLocalServiceUtil;
053 import com.liferay.portlet.asset.util.test.AssetTestUtil;
054 import com.liferay.portlet.messageboards.model.MBMessage;
055 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
056 import com.liferay.portlet.messageboards.util.test.MBTestUtil;
057 import com.liferay.portlet.ratings.model.RatingsEntry;
058 import com.liferay.portlet.ratings.service.RatingsEntryLocalServiceUtil;
059 import com.liferay.portlet.ratings.util.test.RatingsTestUtil;
060
061 import java.io.Serializable;
062
063 import java.util.ArrayList;
064 import java.util.Date;
065 import java.util.HashMap;
066 import java.util.Iterator;
067 import java.util.LinkedHashMap;
068 import java.util.List;
069 import java.util.Map;
070
071 import org.junit.After;
072 import org.junit.Assert;
073 import org.junit.Before;
074 import org.junit.Test;
075
076
080 public abstract class BaseStagedModelDataHandlerTestCase {
081
082 @Before
083 public void setUp() throws Exception {
084 liveGroup = GroupTestUtil.addGroup();
085 stagingGroup = GroupTestUtil.addGroup();
086
087 ServiceContext serviceContext =
088 ServiceContextTestUtil.getServiceContext(stagingGroup.getGroupId());
089
090 ServiceContextThreadLocal.pushServiceContext(serviceContext);
091 }
092
093 @After
094 public void tearDown() throws Exception {
095 ServiceContextThreadLocal.popServiceContext();
096 }
097
098 @Test
099 public void testStagedModelDataHandler() throws Exception {
100
101
102
103 initExport();
104
105 Map<String, List<StagedModel>> dependentStagedModelsMap =
106 addDependentStagedModelsMap(stagingGroup);
107
108 StagedModel stagedModel = addStagedModel(
109 stagingGroup, dependentStagedModelsMap);
110
111
112
113 StagedModelAssets stagedModelAssets = updateAssetEntry(
114 stagedModel, stagingGroup);
115
116
117
118 addComments(stagedModel);
119
120
121
122 addRatings(stagedModel);
123
124 StagedModelDataHandlerUtil.exportStagedModel(
125 portletDataContext, stagedModel);
126
127 validateExport(
128 portletDataContext, stagedModel, dependentStagedModelsMap);
129
130
131
132 initImport();
133
134 deleteStagedModel(stagedModel, dependentStagedModelsMap, stagingGroup);
135
136
137
138 StagedModel exportedStagedModel = readExportedStagedModel(stagedModel);
139
140 Assert.assertNotNull(exportedStagedModel);
141
142 StagedModelDataHandlerUtil.importStagedModel(
143 portletDataContext, exportedStagedModel);
144
145 validateImport(
146 stagedModel, stagedModelAssets, dependentStagedModelsMap,
147 liveGroup);
148 }
149
150 protected void addComments(StagedModel stagedModel) throws Exception {
151 if (!isCommentableStagedModel()) {
152 return;
153 }
154
155 MBTestUtil.addDiscussionMessage(
156 stagingGroup.getGroupId(),
157 ExportImportClassedModelUtil.getClassName(stagedModel),
158 ExportImportClassedModelUtil.getClassPK(stagedModel));
159 }
160
161 protected List<StagedModel> addDependentStagedModel(
162 Map<String, List<StagedModel>> dependentStagedModelsMap, Class<?> clazz,
163 StagedModel dependentStagedModel) {
164
165 List<StagedModel> dependentStagedModels = dependentStagedModelsMap.get(
166 clazz.getSimpleName());
167
168 if (dependentStagedModels == null) {
169 dependentStagedModels = new ArrayList<StagedModel>();
170
171 dependentStagedModelsMap.put(
172 clazz.getSimpleName(), dependentStagedModels);
173 }
174
175 dependentStagedModels.add(dependentStagedModel);
176
177 return dependentStagedModels;
178 }
179
180 protected Map<String, List<StagedModel>> addDependentStagedModelsMap(
181 Group group)
182 throws Exception {
183
184 return new HashMap<String, List<StagedModel>>();
185 }
186
187 protected void addRatings(StagedModel stagedModel) throws Exception {
188 RatingsTestUtil.addEntry(
189 ExportImportClassedModelUtil.getClassName(stagedModel),
190 ExportImportClassedModelUtil.getClassPK(stagedModel));
191 }
192
193 protected abstract StagedModel addStagedModel(
194 Group group,
195 Map<String, List<StagedModel>> dependentStagedModelsMap)
196 throws Exception;
197
198 protected void deleteStagedModel(
199 StagedModel stagedModel,
200 Map<String, List<StagedModel>> dependentStagedModelsMap,
201 Group group)
202 throws Exception {
203 }
204
205 protected AssetEntry fetchAssetEntry(StagedModel stagedModel, Group group)
206 throws Exception {
207
208 return AssetEntryLocalServiceUtil.fetchEntry(
209 group.getGroupId(), stagedModel.getUuid());
210 }
211
212 protected Date getEndDate() {
213 return new Date();
214 }
215
216 protected Map<String, String[]> getParameterMap() {
217 Map<String, String[]> parameterMap =
218 new LinkedHashMap<String, String[]>();
219
220 parameterMap.put(
221 PortletDataHandlerKeys.DATA_STRATEGY,
222 new String[] {
223 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR_OVERWRITE});
224 parameterMap.put(
225 PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
226 new String[] {Boolean.TRUE.toString()});
227 parameterMap.put(
228 PortletDataHandlerKeys.PORTLET_CONFIGURATION,
229 new String[] {Boolean.TRUE.toString()});
230 parameterMap.put(
231 PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL,
232 new String[] {Boolean.TRUE.toString()});
233 parameterMap.put(
234 PortletDataHandlerKeys.PORTLET_DATA,
235 new String[] {Boolean.TRUE.toString()});
236 parameterMap.put(
237 PortletDataHandlerKeys.PORTLET_DATA_ALL,
238 new String[] {Boolean.TRUE.toString()});
239 parameterMap.put(
240 PortletDataHandlerKeys.PORTLET_SETUP_ALL,
241 new String[] {Boolean.TRUE.toString()});
242
243 return parameterMap;
244 }
245
246 protected abstract StagedModel getStagedModel(String uuid, Group group);
247
248 protected abstract Class<? extends StagedModel> getStagedModelClass();
249
250 protected Date getStartDate() {
251 return new Date(System.currentTimeMillis() - Time.HOUR);
252 }
253
254 protected void initExport() throws Exception {
255 zipWriter = ZipWriterFactoryUtil.getZipWriter();
256
257 portletDataContext =
258 PortletDataContextFactoryUtil.createExportPortletDataContext(
259 stagingGroup.getCompanyId(), stagingGroup.getGroupId(),
260 getParameterMap(), getStartDate(), getEndDate(), zipWriter);
261
262 rootElement = SAXReaderUtil.createElement("root");
263
264 portletDataContext.setExportDataRootElement(rootElement);
265
266 missingReferencesElement = SAXReaderUtil.createElement(
267 "missing-references");
268
269 portletDataContext.setMissingReferencesElement(
270 missingReferencesElement);
271 }
272
273 protected void initImport() throws Exception {
274 PortletExporter portletExporter = PortletExporter.getInstance();
275
276 portletExporter.exportAssetTags(portletDataContext);
277
278 userIdStrategy = new CurrentUserIdStrategy(TestPropsValues.getUser());
279 zipReader = ZipReaderFactoryUtil.getZipReader(zipWriter.getFile());
280
281 String xml = zipReader.getEntryAsString("/manifest.xml");
282
283 if (xml == null) {
284 Document document = SAXReaderUtil.createDocument();
285
286 Element rootElement = document.addElement("root");
287
288 rootElement.addElement("header");
289
290 zipWriter.addEntry("/manifest.xml", document.asXML());
291
292 zipReader = ZipReaderFactoryUtil.getZipReader(zipWriter.getFile());
293 }
294
295 portletDataContext =
296 PortletDataContextFactoryUtil.createImportPortletDataContext(
297 liveGroup.getCompanyId(), liveGroup.getGroupId(),
298 getParameterMap(), userIdStrategy, zipReader);
299
300 portletDataContext.setImportDataRootElement(rootElement);
301
302 Group sourceCompanyGroup = GroupLocalServiceUtil.getCompanyGroup(
303 stagingGroup.getCompanyId());
304
305 portletDataContext.setSourceCompanyGroupId(
306 sourceCompanyGroup.getGroupId());
307
308 portletDataContext.setSourceCompanyId(stagingGroup.getCompanyId());
309 portletDataContext.setSourceGroupId(stagingGroup.getGroupId());
310
311 PortletImporter portletImporter = PortletImporter.getInstance();
312
313 portletImporter.readAssetTags(portletDataContext);
314 }
315
316 protected boolean isCommentableStagedModel() {
317 return false;
318 }
319
320 protected StagedModel readExportedStagedModel(StagedModel stagedModel) {
321 String stagedModelPath = ExportImportPathUtil.getModelPath(stagedModel);
322
323 StagedModel exportedStagedModel =
324 (StagedModel)portletDataContext.getZipEntryAsObject(
325 stagedModelPath);
326
327 return exportedStagedModel;
328 }
329
330 protected StagedModelAssets updateAssetEntry(
331 StagedModel stagedModel, Group group)
332 throws Exception {
333
334 AssetEntry assetEntry = fetchAssetEntry(stagedModel, group);
335
336 if (assetEntry == null) {
337 return null;
338 }
339
340 AssetVocabulary assetVocabulary = AssetTestUtil.addVocabulary(
341 stagingGroup.getGroupId());
342
343 AssetCategory assetCategory = AssetTestUtil.addCategory(
344 stagingGroup.getGroupId(), assetVocabulary.getVocabularyId());
345
346 Company company = CompanyLocalServiceUtil.getCompany(
347 stagedModel.getCompanyId());
348
349 Group companyGroup = company.getGroup();
350
351 AssetVocabulary companyAssetVocabulary = AssetTestUtil.addVocabulary(
352 companyGroup.getGroupId());
353
354 AssetCategory companyAssetCategory = AssetTestUtil.addCategory(
355 companyGroup.getGroupId(),
356 companyAssetVocabulary.getVocabularyId());
357
358 AssetTag assetTag = AssetTestUtil.addTag(stagingGroup.getGroupId());
359
360 AssetEntryLocalServiceUtil.updateEntry(
361 TestPropsValues.getUserId(), stagingGroup.getGroupId(),
362 assetEntry.getClassName(), assetEntry.getClassPK(),
363 new long[] {
364 assetCategory.getCategoryId(),
365 companyAssetCategory.getCategoryId()
366 },
367 new String[] {assetTag.getName()});
368
369 return new StagedModelAssets(assetCategory, assetTag, assetVocabulary);
370 }
371
372 protected void validateAssets(
373 StagedModel stagedModel, StagedModelAssets stagedModelAssets,
374 Group group)
375 throws Exception {
376
377 if (stagedModelAssets == null) {
378 return;
379 }
380
381 AssetEntry assetEntry = fetchAssetEntry(stagedModel, group);
382
383 List<AssetCategory> assetCategories =
384 AssetCategoryLocalServiceUtil.getEntryCategories(
385 assetEntry.getEntryId());
386
387 Assert.assertEquals(2, assetCategories.size());
388
389 AssetCategory stagedAssetCategory =
390 stagedModelAssets.getAssetCategory();
391
392 AssetCategory importedAssetCategory = null;
393
394 Company company = CompanyLocalServiceUtil.getCompany(
395 group.getCompanyId());
396
397 long companyGroupId = company.getGroupId();
398
399 for (AssetCategory assetCategory : assetCategories) {
400 long groupId = assetCategory.getGroupId();
401
402 if (groupId != companyGroupId) {
403 importedAssetCategory = assetCategory;
404
405 break;
406 }
407 }
408
409 Assert.assertEquals(
410 stagedAssetCategory.getUuid(), importedAssetCategory.getUuid());
411
412 List<AssetTag> assetTags = AssetTagLocalServiceUtil.getEntryTags(
413 assetEntry.getEntryId());
414
415 Assert.assertEquals(1, assetTags.size());
416
417 AssetTag assetTag = stagedModelAssets.getAssetTag();
418 AssetTag importedAssetTag = assetTags.get(0);
419
420 Assert.assertEquals(assetTag.getName(), importedAssetTag.getName());
421
422 AssetVocabulary assetVocabulary =
423 stagedModelAssets.getAssetVocabulary();
424 AssetVocabulary importedAssetVocabulary =
425 AssetVocabularyLocalServiceUtil.getVocabulary(
426 importedAssetCategory.getVocabularyId());
427
428 Assert.assertEquals(
429 assetVocabulary.getUuid(), importedAssetVocabulary.getUuid());
430 }
431
432 protected void validateComments(
433 StagedModel stagedModel, StagedModel importedStagedModel,
434 Group group)
435 throws Exception {
436
437 if (!isCommentableStagedModel()) {
438 return;
439 }
440
441 List<MBMessage> discussionMBMessages =
442 MBMessageLocalServiceUtil.getMessages(
443 ExportImportClassedModelUtil.getClassName(stagedModel),
444 ExportImportClassedModelUtil.getClassPK(stagedModel),
445 WorkflowConstants.STATUS_ANY);
446
447 if (ListUtil.isEmpty(discussionMBMessages)) {
448 return;
449 }
450
451 int importedDiscussionMBMessagesCount =
452 MBMessageLocalServiceUtil.getDiscussionMessagesCount(
453 ExportImportClassedModelUtil.getClassName(importedStagedModel),
454 ExportImportClassedModelUtil.getClassPK(importedStagedModel),
455 WorkflowConstants.STATUS_ANY);
456
457 Assert.assertEquals(
458 discussionMBMessages.size(), importedDiscussionMBMessagesCount + 1);
459
460 for (MBMessage discussionMBMessage : discussionMBMessages) {
461 if (discussionMBMessage.isRoot()) {
462 continue;
463 }
464
465 MBMessage importedDiscussionMBMessage =
466 MBMessageLocalServiceUtil.fetchMBMessageByUuidAndGroupId(
467 discussionMBMessage.getUuid(), group.getGroupId());
468
469 Assert.assertNotNull(importedDiscussionMBMessage);
470 }
471 }
472
473 protected void validateExport(
474 PortletDataContext portletDataContext, StagedModel stagedModel,
475 Map<String, List<StagedModel>> dependentStagedModelsMap)
476 throws Exception {
477
478 Element rootElement = portletDataContext.getExportDataRootElement();
479
480 List<Element> stagedModelGroupElements = new ArrayList<Element>();
481
482 Class<?> stagedModelClass = getStagedModelClass();
483
484 String stagedModelClassSimpleName = stagedModelClass.getSimpleName();
485
486 stagedModelGroupElements.addAll(
487 rootElement.elements(stagedModelClassSimpleName));
488
489 for (String dependentStagedModelClassSimpleName :
490 dependentStagedModelsMap.keySet()) {
491
492 stagedModelGroupElements.addAll(
493 rootElement.elements(dependentStagedModelClassSimpleName));
494 }
495
496 for (Element stagedModelGroupElement : stagedModelGroupElements) {
497 String className = stagedModelGroupElement.getName();
498
499 List<StagedModel> dependentStagedModels =
500 dependentStagedModelsMap.get(className);
501
502 if (dependentStagedModels == null) {
503 dependentStagedModels = new ArrayList<StagedModel>();
504 }
505 else {
506 dependentStagedModels = ListUtil.copy(dependentStagedModels);
507 }
508
509 if (className.equals(stagedModelClassSimpleName)) {
510 dependentStagedModels.add(stagedModel);
511 }
512
513 List<Element> elements = stagedModelGroupElement.elements();
514
515 Assert.assertEquals(dependentStagedModels.size(), elements.size());
516
517 for (Element element : elements) {
518 String path = element.attributeValue("path");
519
520 Assert.assertNotNull(path);
521
522 Iterator<StagedModel> iterator =
523 dependentStagedModels.iterator();
524
525 while (iterator.hasNext()) {
526 StagedModel dependentStagedModel = iterator.next();
527
528 String dependentStagedModelPath =
529 ExportImportPathUtil.getModelPath(dependentStagedModel);
530
531 if (path.equals(dependentStagedModelPath)) {
532 iterator.remove();
533 }
534 }
535 }
536
537 Assert.assertTrue(
538 "There is more than one element exported with the same path",
539 dependentStagedModels.isEmpty());
540 }
541 }
542
543 protected void validateImport(
544 Map<String, List<StagedModel>> dependentStagedModelsMap,
545 Group group)
546 throws Exception {
547 }
548
549 protected void validateImport(
550 StagedModel stagedModel, StagedModelAssets stagedModelAssets,
551 Map<String, List<StagedModel>> dependentStagedModelsMap,
552 Group group)
553 throws Exception {
554
555 StagedModel importedStagedModel = getStagedModel(
556 stagedModel.getUuid(), group);
557
558 Assert.assertNotNull(importedStagedModel);
559
560 validateAssets(importedStagedModel, stagedModelAssets, group);
561
562 validateComments(stagedModel, importedStagedModel, group);
563
564 validateImport(dependentStagedModelsMap, group);
565
566 validateRatings(stagedModel, importedStagedModel);
567 }
568
569 protected void validateRatings(
570 StagedModel stagedModel, StagedModel importedStagedModel)
571 throws Exception {
572
573 List<RatingsEntry> ratingsEntries =
574 RatingsEntryLocalServiceUtil.getEntries(
575 ExportImportClassedModelUtil.getClassName(stagedModel),
576 ExportImportClassedModelUtil.getClassPK(stagedModel),
577 WorkflowConstants.STATUS_ANY);
578
579 List<RatingsEntry> importedRatingsEntries =
580 RatingsEntryLocalServiceUtil.getEntries(
581 ExportImportClassedModelUtil.getClassName(importedStagedModel),
582 ExportImportClassedModelUtil.getClassPK(importedStagedModel),
583 WorkflowConstants.STATUS_ANY);
584
585 Assert.assertEquals(
586 ratingsEntries.size(), importedRatingsEntries.size());
587
588 for (RatingsEntry ratingsEntry : ratingsEntries) {
589 Iterator<RatingsEntry> iterator = importedRatingsEntries.iterator();
590
591 while (iterator.hasNext()) {
592 RatingsEntry importedRatingsEntry = iterator.next();
593
594 if (ratingsEntry.getScore() ==
595 importedRatingsEntry.getScore()) {
596
597 iterator.remove();
598
599 break;
600 }
601 }
602 }
603
604 Assert.assertTrue(importedRatingsEntries.isEmpty());
605 }
606
607 @DeleteAfterTestRun
608 protected Group liveGroup;
609
610 protected Element missingReferencesElement;
611 protected PortletDataContext portletDataContext;
612 protected Element rootElement;
613
614 @DeleteAfterTestRun
615 protected Group stagingGroup;
616
617 protected UserIdStrategy userIdStrategy;
618 protected ZipReader zipReader;
619 protected ZipWriter zipWriter;
620
621 protected class StagedModelAssets implements Serializable {
622
623 public StagedModelAssets(
624 AssetCategory assetCategory, AssetTag assetTag,
625 AssetVocabulary assetVocabulary) {
626
627 _assetCategory = assetCategory;
628 _assetTag = assetTag;
629 _assetVocabulary = assetVocabulary;
630 }
631
632 public AssetCategory getAssetCategory() {
633 return _assetCategory;
634 }
635
636 public AssetTag getAssetTag() {
637 return _assetTag;
638 }
639
640 public AssetVocabulary getAssetVocabulary() {
641 return _assetVocabulary;
642 }
643
644 public void setAssetCategory(AssetCategory assetCategory) {
645 _assetCategory = assetCategory;
646 }
647
648 public void setAssetTag(AssetTag assetTag) {
649 _assetTag = assetTag;
650 }
651
652 public void setAssetVocabulary(AssetVocabulary assetVocabulary) {
653 _assetVocabulary = assetVocabulary;
654 }
655
656 private AssetCategory _assetCategory;
657 private AssetTag _assetTag;
658 private AssetVocabulary _assetVocabulary;
659
660 }
661
662 }