001
014
015 package com.liferay.portlet.journal.lar;
016
017 import com.liferay.portal.NoSuchImageException;
018 import com.liferay.portal.kernel.dao.orm.QueryUtil;
019 import com.liferay.portal.kernel.exception.PortalException;
020 import com.liferay.portal.kernel.exception.SystemException;
021 import com.liferay.portal.kernel.lar.BasePortletDataHandler;
022 import com.liferay.portal.kernel.lar.ExportImportPathUtil;
023 import com.liferay.portal.kernel.lar.PortletDataContext;
024 import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
025 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
026 import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
027 import com.liferay.portal.kernel.log.Log;
028 import com.liferay.portal.kernel.log.LogFactoryUtil;
029 import com.liferay.portal.kernel.repository.model.FileEntry;
030 import com.liferay.portal.kernel.util.ArrayUtil;
031 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
032 import com.liferay.portal.kernel.util.CharPool;
033 import com.liferay.portal.kernel.util.FileUtil;
034 import com.liferay.portal.kernel.util.GetterUtil;
035 import com.liferay.portal.kernel.util.LocaleUtil;
036 import com.liferay.portal.kernel.util.LocalizationUtil;
037 import com.liferay.portal.kernel.util.MapUtil;
038 import com.liferay.portal.kernel.util.StringBundler;
039 import com.liferay.portal.kernel.util.StringPool;
040 import com.liferay.portal.kernel.util.StringUtil;
041 import com.liferay.portal.kernel.util.Validator;
042 import com.liferay.portal.kernel.workflow.WorkflowConstants;
043 import com.liferay.portal.kernel.xml.Element;
044 import com.liferay.portal.model.Group;
045 import com.liferay.portal.model.Image;
046 import com.liferay.portal.model.Layout;
047 import com.liferay.portal.model.Repository;
048 import com.liferay.portal.model.RepositoryEntry;
049 import com.liferay.portal.model.User;
050 import com.liferay.portal.service.GroupLocalServiceUtil;
051 import com.liferay.portal.service.ServiceContext;
052 import com.liferay.portal.service.UserLocalServiceUtil;
053 import com.liferay.portal.service.persistence.ImageUtil;
054 import com.liferay.portal.service.persistence.LayoutUtil;
055 import com.liferay.portal.util.PortalUtil;
056 import com.liferay.portal.util.PortletKeys;
057 import com.liferay.portal.util.PropsValues;
058 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
059 import com.liferay.portlet.documentlibrary.model.DLFileRank;
060 import com.liferay.portlet.documentlibrary.model.DLFolder;
061 import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
062 import com.liferay.portlet.documentlibrary.util.DLUtil;
063 import com.liferay.portlet.dynamicdatamapping.lar.DDMPortletDataHandler;
064 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
065 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
066 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
067 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
068 import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMStructureUtil;
069 import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMTemplateUtil;
070 import com.liferay.portlet.dynamicdatamapping.util.comparator.StructureIdComparator;
071 import com.liferay.portlet.journal.ArticleContentException;
072 import com.liferay.portlet.journal.FeedTargetLayoutFriendlyUrlException;
073 import com.liferay.portlet.journal.NoSuchArticleException;
074 import com.liferay.portlet.journal.model.JournalArticle;
075 import com.liferay.portlet.journal.model.JournalArticleConstants;
076 import com.liferay.portlet.journal.model.JournalArticleImage;
077 import com.liferay.portlet.journal.model.JournalArticleResource;
078 import com.liferay.portlet.journal.model.JournalFeed;
079 import com.liferay.portlet.journal.model.JournalFolder;
080 import com.liferay.portlet.journal.model.JournalFolderConstants;
081 import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
082 import com.liferay.portlet.journal.service.JournalFeedLocalServiceUtil;
083 import com.liferay.portlet.journal.service.JournalFolderLocalServiceUtil;
084 import com.liferay.portlet.journal.service.persistence.JournalArticleImageUtil;
085 import com.liferay.portlet.journal.service.persistence.JournalArticleResourceUtil;
086 import com.liferay.portlet.journal.service.persistence.JournalArticleUtil;
087 import com.liferay.portlet.journal.service.persistence.JournalFeedUtil;
088 import com.liferay.portlet.journal.service.persistence.JournalFolderUtil;
089 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
090
091 import java.io.File;
092
093 import java.util.ArrayList;
094 import java.util.Calendar;
095 import java.util.Date;
096 import java.util.HashMap;
097 import java.util.List;
098 import java.util.Locale;
099 import java.util.Map;
100 import java.util.regex.Matcher;
101 import java.util.regex.Pattern;
102
103 import javax.portlet.PortletPreferences;
104
105
135 public class JournalPortletDataHandler extends BasePortletDataHandler {
136
137 public static final String NAMESPACE = "journal";
138
139 public static void exportArticle(
140 PortletDataContext portletDataContext, Element articlesElement,
141 Element ddmStructuresElement, Element ddmTemplatesElement,
142 Element dlFileEntryTypesElement, Element dlFoldersElement,
143 Element dlFileEntriesElement, Element dlFileRanksElement,
144 Element dlRepositoriesElement, Element dlRepositoryEntriesElement,
145 JournalArticle article, boolean checkDateRange)
146 throws Exception {
147
148 if (checkDateRange &&
149 !portletDataContext.isWithinDateRange(article.getModifiedDate())) {
150
151 return;
152 }
153
154 if ((article.getStatus() != WorkflowConstants.STATUS_APPROVED) &&
155 (article.getStatus() != WorkflowConstants.STATUS_EXPIRED)) {
156
157 return;
158 }
159
160 String path = getArticlePath(portletDataContext, article);
161
162 if (!portletDataContext.isPathNotProcessed(path)) {
163 return;
164 }
165
166
167
168
169 article = (JournalArticle)article.clone();
170
171 Element articleElement = (Element)articlesElement.selectSingleNode(
172 "
173
174 if (articleElement == null) {
175 articleElement = articlesElement.addElement("article");
176 }
177
178 articleElement.addAttribute(
179 "article-resource-uuid", article.getArticleResourceUuid());
180
181 if (Validator.isNotNull(article.getStructureId())) {
182 DDMStructure ddmStructure =
183 DDMStructureLocalServiceUtil.getStructure(
184 article.getGroupId(),
185 PortalUtil.getClassNameId(JournalArticle.class),
186 article.getStructureId(), true);
187
188 articleElement.addAttribute(
189 "ddm-structure-uuid", ddmStructure.getUuid());
190
191 StagedModelDataHandlerUtil.exportStagedModel(
192 portletDataContext, ddmStructure);
193 }
194
195 if (Validator.isNotNull(article.getTemplateId())) {
196 DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
197 article.getGroupId(),
198 PortalUtil.getClassNameId(DDMStructure.class),
199 article.getTemplateId(), true);
200
201 articleElement.addAttribute(
202 "ddm-template-uuid", ddmTemplate.getUuid());
203
204 StagedModelDataHandlerUtil.exportStagedModel(
205 portletDataContext, ddmTemplate);
206 }
207
208 if (article.isSmallImage()) {
209 Image smallImage = ImageUtil.fetchByPrimaryKey(
210 article.getSmallImageId());
211
212 if (Validator.isNotNull(article.getSmallImageURL())) {
213 String smallImageURL =
214 DDMPortletDataHandler.exportReferencedContent(
215 portletDataContext, dlFileEntryTypesElement,
216 dlFoldersElement, dlFileEntriesElement,
217 dlFileRanksElement, dlRepositoriesElement,
218 dlRepositoryEntriesElement, articleElement,
219 article.getSmallImageURL().concat(StringPool.SPACE));
220
221 article.setSmallImageURL(smallImageURL);
222 }
223 else if (smallImage != null) {
224 String smallImagePath = getArticleSmallImagePath(
225 portletDataContext, article);
226
227 articleElement.addAttribute("small-image-path", smallImagePath);
228
229 article.setSmallImageType(smallImage.getType());
230
231 portletDataContext.addZipEntry(
232 smallImagePath, smallImage.getTextObj());
233 }
234 }
235
236 if (portletDataContext.getBooleanParameter(NAMESPACE, "images")) {
237 String imagePath = getArticleImagePath(portletDataContext, article);
238
239 articleElement.addAttribute("image-path", imagePath);
240
241 List<JournalArticleImage> articleImages =
242 JournalArticleImageUtil.findByG_A_V(
243 article.getGroupId(), article.getArticleId(),
244 article.getVersion());
245
246 for (JournalArticleImage articleImage : articleImages) {
247 Image image = null;
248
249 try {
250 image = ImageUtil.findByPrimaryKey(
251 articleImage.getArticleImageId());
252 }
253 catch (NoSuchImageException nsie) {
254 continue;
255 }
256
257 if (image.getTextObj() == null) {
258 continue;
259 }
260
261 String articleImagePath = getArticleImagePath(
262 portletDataContext, article, articleImage, image);
263
264 if (!portletDataContext.isPathNotProcessed(articleImagePath)) {
265 continue;
266 }
267
268 portletDataContext.addZipEntry(
269 articleImagePath, image.getTextObj());
270 }
271 }
272
273 article.setStatusByUserUuid(article.getStatusByUserUuid());
274
275 if (portletDataContext.getBooleanParameter(
276 NAMESPACE, "embedded-assets")) {
277
278 String content = DDMPortletDataHandler.exportReferencedContent(
279 portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
280 dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
281 dlRepositoryEntriesElement, articleElement,
282 article.getContent());
283
284 article.setContent(content);
285 }
286
287 portletDataContext.addClassedModel(
288 articleElement, path, article, NAMESPACE);
289 }
290
291 public static String getArticlePath(
292 PortletDataContext portletDataContext, JournalArticle article)
293 throws Exception {
294
295 StringBundler sb = new StringBundler(8);
296
297 sb.append(
298 ExportImportPathUtil.getPortletPath(
299 portletDataContext, PortletKeys.JOURNAL));
300 sb.append("/articles/");
301 sb.append(article.getArticleResourceUuid());
302 sb.append(StringPool.SLASH);
303 sb.append(article.getVersion());
304 sb.append(StringPool.SLASH);
305 sb.append("article.xml");
306
307 return sb.toString();
308 }
309
310 public static void importArticle(
311 PortletDataContext portletDataContext, Element articleElement)
312 throws Exception {
313
314 String path = articleElement.attributeValue("path");
315
316 if (!portletDataContext.isPathNotProcessed(path)) {
317 return;
318 }
319
320 JournalArticle article =
321 (JournalArticle)portletDataContext.getZipEntryAsObject(
322 articleElement, path);
323
324 prepareLanguagesForImport(article);
325
326 long userId = portletDataContext.getUserId(article.getUserUuid());
327
328 JournalCreationStrategy creationStrategy =
329 JournalCreationStrategyFactory.getInstance();
330
331 long authorId = creationStrategy.getAuthorUserId(
332 portletDataContext, article);
333
334 if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
335 userId = authorId;
336 }
337
338 User user = UserLocalServiceUtil.getUser(userId);
339
340 Map<Long, Long> folderIds =
341 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
342 JournalFolder.class);
343
344 long folderId = MapUtil.getLong(
345 folderIds, article.getFolderId(), article.getFolderId());
346
347 if ((folderId != JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
348 (folderId == article.getFolderId())) {
349
350 String folderPath = getImportFolderPath(
351 portletDataContext, folderId);
352
353 JournalFolder folder =
354 (JournalFolder)portletDataContext.getZipEntryAsObject(
355 folderPath);
356
357 importFolder(portletDataContext, folderPath, folder);
358
359 folderId = MapUtil.getLong(
360 folderIds, article.getFolderId(), article.getFolderId());
361 }
362
363 String articleId = article.getArticleId();
364 boolean autoArticleId = false;
365
366 if (Validator.isNumber(articleId) ||
367 (JournalArticleUtil.fetchByG_A_V(
368 portletDataContext.getScopeGroupId(), articleId,
369 JournalArticleConstants.VERSION_DEFAULT) != null)) {
370
371 autoArticleId = true;
372 }
373
374 Map<String, String> articleIds =
375 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
376 JournalArticle.class + ".articleId");
377
378 String newArticleId = articleIds.get(articleId);
379
380 if (Validator.isNotNull(newArticleId)) {
381
382
383
384
385 articleId = newArticleId;
386 autoArticleId = false;
387 }
388
389 String content = article.getContent();
390
391 content = importReferencedContent(
392 portletDataContext, articleElement, content);
393
394 article.setContent(content);
395
396 String newContent = creationStrategy.getTransformedContent(
397 portletDataContext, article);
398
399 if (newContent != JournalCreationStrategy.ARTICLE_CONTENT_UNCHANGED) {
400 article.setContent(newContent);
401 }
402
403 Map<String, String> ddmStructureKeys =
404 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
405 DDMStructure.class);
406
407 String parentDDMStructureKey = MapUtil.getString(
408 ddmStructureKeys, article.getStructureId(),
409 article.getStructureId());
410
411 Map<String, String> ddmTemplateKeys =
412 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
413 DDMTemplate.class);
414
415 String parentDDMTemplateKey = MapUtil.getString(
416 ddmTemplateKeys, article.getTemplateId(), article.getTemplateId());
417
418 Date displayDate = article.getDisplayDate();
419
420 int displayDateMonth = 0;
421 int displayDateDay = 0;
422 int displayDateYear = 0;
423 int displayDateHour = 0;
424 int displayDateMinute = 0;
425
426 if (displayDate != null) {
427 Calendar displayCal = CalendarFactoryUtil.getCalendar(
428 user.getTimeZone());
429
430 displayCal.setTime(displayDate);
431
432 displayDateMonth = displayCal.get(Calendar.MONTH);
433 displayDateDay = displayCal.get(Calendar.DATE);
434 displayDateYear = displayCal.get(Calendar.YEAR);
435 displayDateHour = displayCal.get(Calendar.HOUR);
436 displayDateMinute = displayCal.get(Calendar.MINUTE);
437
438 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
439 displayDateHour += 12;
440 }
441 }
442
443 Date expirationDate = article.getExpirationDate();
444
445 int expirationDateMonth = 0;
446 int expirationDateDay = 0;
447 int expirationDateYear = 0;
448 int expirationDateHour = 0;
449 int expirationDateMinute = 0;
450 boolean neverExpire = true;
451
452 if (expirationDate != null) {
453 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
454 user.getTimeZone());
455
456 expirationCal.setTime(expirationDate);
457
458 expirationDateMonth = expirationCal.get(Calendar.MONTH);
459 expirationDateDay = expirationCal.get(Calendar.DATE);
460 expirationDateYear = expirationCal.get(Calendar.YEAR);
461 expirationDateHour = expirationCal.get(Calendar.HOUR);
462 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
463 neverExpire = false;
464
465 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
466 expirationDateHour += 12;
467 }
468 }
469
470 Date reviewDate = article.getReviewDate();
471
472 int reviewDateMonth = 0;
473 int reviewDateDay = 0;
474 int reviewDateYear = 0;
475 int reviewDateHour = 0;
476 int reviewDateMinute = 0;
477 boolean neverReview = true;
478
479 if (reviewDate != null) {
480 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
481 user.getTimeZone());
482
483 reviewCal.setTime(reviewDate);
484
485 reviewDateMonth = reviewCal.get(Calendar.MONTH);
486 reviewDateDay = reviewCal.get(Calendar.DATE);
487 reviewDateYear = reviewCal.get(Calendar.YEAR);
488 reviewDateHour = reviewCal.get(Calendar.HOUR);
489 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
490 neverReview = false;
491
492 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
493 reviewDateHour += 12;
494 }
495 }
496
497 long ddmStructureId = 0;
498
499 if (Validator.isNotNull(article.getStructureId())) {
500 String ddmStructureUuid = articleElement.attributeValue(
501 "ddm-structure-uuid");
502
503 DDMStructure existingDDMStructure = DDMStructureUtil.fetchByUUID_G(
504 ddmStructureUuid, portletDataContext.getScopeGroupId());
505
506 if (existingDDMStructure == null) {
507 Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
508 portletDataContext.getCompanyId());
509
510 long companyGroupId = companyGroup.getGroupId();
511
512 existingDDMStructure = DDMStructureUtil.fetchByUUID_G(
513 ddmStructureUuid, companyGroupId);
514 }
515
516 if (existingDDMStructure == null) {
517 String newStructureId = ddmStructureKeys.get(
518 article.getStructureId());
519
520 if (Validator.isNotNull(newStructureId)) {
521 existingDDMStructure = DDMStructureUtil.fetchByG_C_S(
522 portletDataContext.getScopeGroupId(),
523 PortalUtil.getClassNameId(JournalArticle.class),
524 String.valueOf(newStructureId));
525 }
526
527 if (existingDDMStructure == null) {
528 if (_log.isWarnEnabled()) {
529 StringBundler sb = new StringBundler();
530
531 sb.append("Structure ");
532 sb.append(article.getStructureId());
533 sb.append(" is missing for article ");
534 sb.append(article.getArticleId());
535 sb.append(", skipping this article.");
536
537 _log.warn(sb.toString());
538 }
539
540 return;
541 }
542 }
543
544 ddmStructureId = existingDDMStructure.getStructureId();
545
546 parentDDMStructureKey = existingDDMStructure.getStructureKey();
547 }
548
549 if (Validator.isNotNull(article.getTemplateId())) {
550 String ddmTemplateUuid = articleElement.attributeValue(
551 "ddm-template-uuid");
552
553 DDMTemplate existingDDMTemplate = DDMTemplateUtil.fetchByUUID_G(
554 ddmTemplateUuid, portletDataContext.getScopeGroupId());
555
556 if (existingDDMTemplate == null) {
557 Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
558 portletDataContext.getCompanyId());
559
560 long companyGroupId = companyGroup.getGroupId();
561
562 existingDDMTemplate = DDMTemplateUtil.fetchByUUID_G(
563 ddmTemplateUuid, companyGroupId);
564 }
565
566 if (existingDDMTemplate == null) {
567 String newTemplateId = ddmTemplateKeys.get(
568 article.getTemplateId());
569
570 if (Validator.isNotNull(newTemplateId)) {
571 existingDDMTemplate = DDMTemplateUtil.fetchByG_C_T(
572 portletDataContext.getScopeGroupId(),
573 PortalUtil.getClassNameId(DDMStructure.class),
574 newTemplateId);
575 }
576
577 if (existingDDMTemplate == null) {
578 if (_log.isWarnEnabled()) {
579 StringBundler sb = new StringBundler();
580
581 sb.append("Template ");
582 sb.append(article.getTemplateId());
583 sb.append(" is missing for article ");
584 sb.append(article.getArticleId());
585 sb.append(", skipping this article.");
586
587 _log.warn(sb.toString());
588 }
589
590 return;
591 }
592 }
593
594 parentDDMTemplateKey = existingDDMTemplate.getTemplateKey();
595 }
596
597 File smallFile = null;
598
599 if (article.isSmallImage()) {
600 String smallImagePath = articleElement.attributeValue(
601 "small-image-path");
602
603 if (Validator.isNotNull(article.getSmallImageURL())) {
604 String smallImageURL = importReferencedContent(
605 portletDataContext, articleElement,
606 article.getSmallImageURL());
607
608 article.setSmallImageURL(smallImageURL);
609 }
610 else if (Validator.isNotNull(smallImagePath)) {
611 byte[] bytes = portletDataContext.getZipEntryAsByteArray(
612 smallImagePath);
613
614 if (bytes != null) {
615 smallFile = FileUtil.createTempFile(
616 article.getSmallImageType());
617
618 FileUtil.write(smallFile, bytes);
619 }
620 }
621 }
622
623 Map<String, byte[]> images = new HashMap<String, byte[]>();
624
625 String imagePath = articleElement.attributeValue("image-path");
626
627 if (portletDataContext.getBooleanParameter(NAMESPACE, "images") &&
628 Validator.isNotNull(imagePath)) {
629
630 List<String> imageFiles = portletDataContext.getZipFolderEntries(
631 imagePath);
632
633 for (String imageFile : imageFiles) {
634 String fileName = imageFile;
635
636 if (fileName.contains(StringPool.SLASH)) {
637 fileName = fileName.substring(
638 fileName.lastIndexOf(CharPool.SLASH) + 1);
639 }
640
641 if (fileName.endsWith(".xml")) {
642 continue;
643 }
644
645 int pos = fileName.lastIndexOf(CharPool.PERIOD);
646
647 if (pos != -1) {
648 fileName = fileName.substring(0, pos);
649 }
650
651 images.put(
652 fileName,
653 portletDataContext.getZipEntryAsByteArray(imageFile));
654 }
655 }
656
657 String articleURL = null;
658
659 boolean addGroupPermissions = creationStrategy.addGroupPermissions(
660 portletDataContext, article);
661 boolean addGuestPermissions = creationStrategy.addGuestPermissions(
662 portletDataContext, article);
663
664 ServiceContext serviceContext = portletDataContext.createServiceContext(
665 articleElement, article, NAMESPACE);
666
667 serviceContext.setAddGroupPermissions(addGroupPermissions);
668 serviceContext.setAddGuestPermissions(addGuestPermissions);
669
670 if (article.getStatus() != WorkflowConstants.STATUS_APPROVED) {
671 serviceContext.setWorkflowAction(
672 WorkflowConstants.ACTION_SAVE_DRAFT);
673 }
674
675 JournalArticle importedArticle = null;
676
677 String articleResourceUuid = articleElement.attributeValue(
678 "article-resource-uuid");
679
680 if (portletDataContext.isDataStrategyMirror()) {
681 JournalArticleResource articleResource =
682 JournalArticleResourceUtil.fetchByUUID_G(
683 articleResourceUuid, portletDataContext.getScopeGroupId());
684
685 if (articleResource == null) {
686 Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
687 portletDataContext.getCompanyId());
688
689 long companyGroupId = companyGroup.getGroupId();
690
691 articleResource = JournalArticleResourceUtil.fetchByUUID_G(
692 articleResourceUuid, companyGroupId);
693 }
694
695 serviceContext.setUuid(articleResourceUuid);
696 serviceContext.setAttribute("urlTitle", article.getUrlTitle());
697
698 JournalArticle existingArticle = null;
699
700 if (articleResource != null) {
701 try {
702 existingArticle =
703 JournalArticleLocalServiceUtil.getLatestArticle(
704 articleResource.getResourcePrimKey(),
705 WorkflowConstants.STATUS_ANY, false);
706 }
707 catch (NoSuchArticleException nsae) {
708 }
709 }
710
711 if (existingArticle == null) {
712 existingArticle = JournalArticleUtil.fetchByG_A_V(
713 portletDataContext.getScopeGroupId(), newArticleId,
714 article.getVersion());
715 }
716
717 if (existingArticle == null) {
718 importedArticle = JournalArticleLocalServiceUtil.addArticle(
719 userId, portletDataContext.getScopeGroupId(), folderId,
720 article.getClassNameId(), ddmStructureId, articleId,
721 autoArticleId, article.getVersion(), article.getTitleMap(),
722 article.getDescriptionMap(), article.getContent(),
723 article.getType(), parentDDMStructureKey,
724 parentDDMTemplateKey, article.getLayoutUuid(),
725 displayDateMonth, displayDateDay, displayDateYear,
726 displayDateHour, displayDateMinute, expirationDateMonth,
727 expirationDateDay, expirationDateYear, expirationDateHour,
728 expirationDateMinute, neverExpire, reviewDateMonth,
729 reviewDateDay, reviewDateYear, reviewDateHour,
730 reviewDateMinute, neverReview, article.isIndexable(),
731 article.isSmallImage(), article.getSmallImageURL(),
732 smallFile, images, articleURL, serviceContext);
733 }
734 else {
735 importedArticle = JournalArticleLocalServiceUtil.updateArticle(
736 userId, existingArticle.getGroupId(), folderId,
737 existingArticle.getArticleId(), article.getVersion(),
738 article.getTitleMap(), article.getDescriptionMap(),
739 article.getContent(), article.getType(),
740 parentDDMStructureKey, parentDDMTemplateKey,
741 article.getLayoutUuid(), displayDateMonth, displayDateDay,
742 displayDateYear, displayDateHour, displayDateMinute,
743 expirationDateMonth, expirationDateDay, expirationDateYear,
744 expirationDateHour, expirationDateMinute, neverExpire,
745 reviewDateMonth, reviewDateDay, reviewDateYear,
746 reviewDateHour, reviewDateMinute, neverReview,
747 article.isIndexable(), article.isSmallImage(),
748 article.getSmallImageURL(), smallFile, images, articleURL,
749 serviceContext);
750 }
751 }
752 else {
753 importedArticle = JournalArticleLocalServiceUtil.addArticle(
754 userId, portletDataContext.getScopeGroupId(), folderId,
755 article.getClassNameId(), ddmStructureId, articleId,
756 autoArticleId, article.getVersion(), article.getTitleMap(),
757 article.getDescriptionMap(), article.getContent(),
758 article.getType(), parentDDMStructureKey, parentDDMTemplateKey,
759 article.getLayoutUuid(), displayDateMonth, displayDateDay,
760 displayDateYear, displayDateHour, displayDateMinute,
761 expirationDateMonth, expirationDateDay, expirationDateYear,
762 expirationDateHour, expirationDateMinute, neverExpire,
763 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
764 reviewDateMinute, neverReview, article.isIndexable(),
765 article.isSmallImage(), article.getSmallImageURL(), smallFile,
766 images, articleURL, serviceContext);
767 }
768
769 if (smallFile != null) {
770 smallFile.delete();
771 }
772
773 portletDataContext.importClassedModel(
774 article, importedArticle, NAMESPACE);
775
776 if (Validator.isNull(newArticleId)) {
777 articleIds.put(
778 article.getArticleId(), importedArticle.getArticleId());
779 }
780
781 if (!articleId.equals(importedArticle.getArticleId())) {
782 if (_log.isWarnEnabled()) {
783 _log.warn(
784 "An article with the ID " + articleId + " already " +
785 "exists. The new generated ID is " +
786 importedArticle.getArticleId());
787 }
788 }
789 }
790
791 public static void importFeed(
792 PortletDataContext portletDataContext, Element feedElement)
793 throws Exception {
794
795 String path = feedElement.attributeValue("path");
796
797 if (!portletDataContext.isPathNotProcessed(path)) {
798 return;
799 }
800
801 JournalFeed feed = (JournalFeed)portletDataContext.getZipEntryAsObject(
802 path);
803
804 long userId = portletDataContext.getUserId(feed.getUserUuid());
805
806 JournalCreationStrategy creationStrategy =
807 JournalCreationStrategyFactory.getInstance();
808
809 long authorId = creationStrategy.getAuthorUserId(
810 portletDataContext, feed);
811
812 if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
813 userId = authorId;
814 }
815
816 Group group = GroupLocalServiceUtil.getGroup(
817 portletDataContext.getScopeGroupId());
818
819 String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
820
821 String[] friendlyUrlParts = StringUtil.split(
822 feed.getTargetLayoutFriendlyUrl(), '/');
823
824 String oldGroupFriendlyURL = friendlyUrlParts[2];
825
826 if (oldGroupFriendlyURL.equals("@data_handler_group_friendly_url@")) {
827 feed.setTargetLayoutFriendlyUrl(
828 StringUtil.replace(
829 feed.getTargetLayoutFriendlyUrl(),
830 "@data_handler_group_friendly_url@", newGroupFriendlyURL));
831 }
832
833 String feedId = feed.getFeedId();
834 boolean autoFeedId = false;
835
836 if (Validator.isNumber(feedId) ||
837 (JournalFeedUtil.fetchByG_F(
838 portletDataContext.getScopeGroupId(), feedId) != null)) {
839
840 autoFeedId = true;
841 }
842
843 Map<String, String> ddmStructureKeys =
844 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
845 DDMStructure.class + ".structureKey");
846
847 String parentDDMStructureKey = MapUtil.getString(
848 ddmStructureKeys, feed.getStructureId(), feed.getStructureId());
849
850 Map<String, String> ddmTemplateKeys =
851 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
852 DDMTemplate.class + ".templateKey");
853
854 String parentDDMTemplateKey = MapUtil.getString(
855 ddmTemplateKeys, feed.getTemplateId(), feed.getTemplateId());
856 String parentRenderDDMTemplateKey = MapUtil.getString(
857 ddmTemplateKeys, feed.getRendererTemplateId(),
858 feed.getRendererTemplateId());
859
860 boolean addGroupPermissions = creationStrategy.addGroupPermissions(
861 portletDataContext, feed);
862 boolean addGuestPermissions = creationStrategy.addGuestPermissions(
863 portletDataContext, feed);
864
865 ServiceContext serviceContext = portletDataContext.createServiceContext(
866 feedElement, feed, NAMESPACE);
867
868 serviceContext.setAddGroupPermissions(addGroupPermissions);
869 serviceContext.setAddGuestPermissions(addGuestPermissions);
870
871 JournalFeed importedFeed = null;
872
873 try {
874 if (portletDataContext.isDataStrategyMirror()) {
875 JournalFeed existingFeed = JournalFeedUtil.fetchByUUID_G(
876 feed.getUuid(), portletDataContext.getScopeGroupId());
877
878 if (existingFeed == null) {
879 serviceContext.setUuid(feed.getUuid());
880
881 importedFeed = JournalFeedLocalServiceUtil.addFeed(
882 userId, portletDataContext.getScopeGroupId(), feedId,
883 autoFeedId, feed.getName(), feed.getDescription(),
884 feed.getType(), parentDDMStructureKey,
885 parentDDMTemplateKey, parentRenderDDMTemplateKey,
886 feed.getDelta(), feed.getOrderByCol(),
887 feed.getOrderByType(),
888 feed.getTargetLayoutFriendlyUrl(),
889 feed.getTargetPortletId(), feed.getContentField(),
890 feed.getFeedFormat(), feed.getFeedVersion(),
891 serviceContext);
892 }
893 else {
894 importedFeed = JournalFeedLocalServiceUtil.updateFeed(
895 existingFeed.getGroupId(), existingFeed.getFeedId(),
896 feed.getName(), feed.getDescription(), feed.getType(),
897 parentDDMStructureKey, parentDDMTemplateKey,
898 parentRenderDDMTemplateKey, feed.getDelta(),
899 feed.getOrderByCol(), feed.getOrderByType(),
900 feed.getTargetLayoutFriendlyUrl(),
901 feed.getTargetPortletId(), feed.getContentField(),
902 feed.getFeedFormat(), feed.getFeedVersion(),
903 serviceContext);
904 }
905 }
906 else {
907 importedFeed = JournalFeedLocalServiceUtil.addFeed(
908 userId, portletDataContext.getScopeGroupId(), feedId,
909 autoFeedId, feed.getName(), feed.getDescription(),
910 feed.getType(), parentDDMStructureKey, parentDDMTemplateKey,
911 parentRenderDDMTemplateKey, feed.getDelta(),
912 feed.getOrderByCol(), feed.getOrderByType(),
913 feed.getTargetLayoutFriendlyUrl(),
914 feed.getTargetPortletId(), feed.getContentField(),
915 feed.getFeedFormat(), feed.getFeedVersion(),
916 serviceContext);
917 }
918
919 portletDataContext.importClassedModel(
920 feed, importedFeed, NAMESPACE);
921
922 if (!feedId.equals(importedFeed.getFeedId())) {
923 if (_log.isWarnEnabled()) {
924 StringBundler sb = new StringBundler(5);
925
926 sb.append("A feed with the ID ");
927 sb.append(feedId);
928 sb.append(" already exists. The new generated ID is ");
929 sb.append(importedFeed.getFeedId());
930 sb.append(".");
931
932 _log.warn(sb.toString());
933 }
934 }
935 }
936 catch (FeedTargetLayoutFriendlyUrlException ftlfurle) {
937 if (_log.isWarnEnabled()) {
938 StringBundler sb = new StringBundler(6);
939
940 sb.append("A feed with the ID ");
941 sb.append(feedId);
942 sb.append(" cannot be imported because layout with friendly ");
943 sb.append("URL ");
944 sb.append(feed.getTargetLayoutFriendlyUrl());
945 sb.append(" does not exist");
946
947 _log.warn(sb.toString());
948 }
949 }
950 }
951
952 public static String importReferencedContent(
953 PortletDataContext portletDataContext, Element parentElement,
954 String content)
955 throws Exception {
956
957 content = importDLFileEntries(
958 portletDataContext, parentElement, content);
959 content = importLayoutFriendlyURLs(portletDataContext, content);
960 content = importLinksToLayout(portletDataContext, content);
961
962 return content;
963 }
964
965 public static void importReferencedData(
966 PortletDataContext portletDataContext, Element entityElement)
967 throws Exception {
968
969 Element dlRepositoriesElement =
970 portletDataContext.getImportDataGroupElement(Repository.class);
971
972 List<Element> dlRepositoryElements = dlRepositoriesElement.elements();
973
974 for (Element repositoryElement : dlRepositoryElements) {
975 StagedModelDataHandlerUtil.importStagedModel(
976 portletDataContext, repositoryElement);
977 }
978
979 Element dlRepositoryEntriesElement =
980 portletDataContext.getImportDataGroupElement(RepositoryEntry.class);
981
982 List<Element> dlRepositoryEntryElements =
983 dlRepositoryEntriesElement.elements();
984
985 for (Element dlRepositoryEntryElement : dlRepositoryEntryElements) {
986 StagedModelDataHandlerUtil.importStagedModel(
987 portletDataContext, dlRepositoryEntryElement);
988 }
989
990 Element dlFoldersElement = portletDataContext.getImportDataGroupElement(
991 DLFolder.class);
992
993 List<Element> dlFolderElements = dlFoldersElement.elements();
994
995 for (Element folderElement : dlFolderElements) {
996 StagedModelDataHandlerUtil.importStagedModel(
997 portletDataContext, folderElement);
998 }
999
1000 Element dlFileEntriesElement =
1001 portletDataContext.getImportDataGroupElement(DLFileEntry.class);
1002
1003 List<Element> dlFileEntryElements = dlFileEntriesElement.elements();
1004
1005 for (Element dlFileEntryElement : dlFileEntryElements) {
1006 StagedModelDataHandlerUtil.importStagedModel(
1007 portletDataContext, dlFileEntryElement);
1008 }
1009
1010 Element dlFileRanksElement =
1011 portletDataContext.getImportDataGroupElement(DLFileRank.class);
1012
1013 List<Element> dlFileRankElements = dlFileRanksElement.elements();
1014
1015 for (Element dlFileRankElement : dlFileRankElements) {
1016 StagedModelDataHandlerUtil.importStagedModel(
1017 portletDataContext, dlFileRankElement);
1018 }
1019 }
1020
1021 public JournalPortletDataHandler() {
1022 setAlwaysExportable(true);
1023 setDataLocalized(true);
1024 setExportControls(
1025 new PortletDataHandlerBoolean(NAMESPACE, "web-content"),
1026 new PortletDataHandlerBoolean(
1027 NAMESPACE, "structures-templates-and-feeds", true, true),
1028 new PortletDataHandlerBoolean(NAMESPACE, "embedded-assets"),
1029 new PortletDataHandlerBoolean(
1030 NAMESPACE, "version-history",
1031 PropsValues.JOURNAL_PUBLISH_VERSION_HISTORY_BY_DEFAULT));
1032 setExportMetadataControls(
1033 new PortletDataHandlerBoolean(
1034 NAMESPACE, "web-content", true,
1035 new PortletDataHandlerControl[] {
1036 new PortletDataHandlerBoolean(NAMESPACE, "images"),
1037 new PortletDataHandlerBoolean(NAMESPACE, "categories"),
1038 new PortletDataHandlerBoolean(NAMESPACE, "comments"),
1039 new PortletDataHandlerBoolean(NAMESPACE, "ratings"),
1040 new PortletDataHandlerBoolean(NAMESPACE, "tags")
1041 }));
1042 setImportControls(getExportControls()[0], getExportControls()[1]);
1043 setPublishToLiveByDefault(
1044 PropsValues.JOURNAL_PUBLISH_TO_LIVE_BY_DEFAULT);
1045 }
1046
1047 protected static void exportFeed(
1048 PortletDataContext portletDataContext, Element feedsElement,
1049 JournalFeed feed)
1050 throws Exception {
1051
1052 if (!portletDataContext.isWithinDateRange(feed.getModifiedDate())) {
1053 return;
1054 }
1055
1056 String path = getFeedPath(portletDataContext, feed);
1057
1058 if (!portletDataContext.isPathNotProcessed(path)) {
1059 return;
1060 }
1061
1062 feed = (JournalFeed)feed.clone();
1063
1064 Element feedElement = feedsElement.addElement("feed");
1065
1066 Group group = GroupLocalServiceUtil.getGroup(
1067 portletDataContext.getScopeGroupId());
1068
1069 String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
1070
1071 String[] friendlyUrlParts = StringUtil.split(
1072 feed.getTargetLayoutFriendlyUrl(), '/');
1073
1074 String oldGroupFriendlyURL = friendlyUrlParts[2];
1075
1076 if (newGroupFriendlyURL.equals(oldGroupFriendlyURL)) {
1077 String targetLayoutFriendlyUrl = StringUtil.replaceFirst(
1078 feed.getTargetLayoutFriendlyUrl(),
1079 StringPool.SLASH + newGroupFriendlyURL + StringPool.SLASH,
1080 "/@data_handler_group_friendly_url@/");
1081
1082 feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
1083 }
1084
1085 portletDataContext.addClassedModel(feedElement, path, feed, NAMESPACE);
1086 }
1087
1088 protected static void exportFolder(
1089 PortletDataContext portletDataContext, Element foldersElement,
1090 Element articlesElement, Element ddmStructuresElement,
1091 Element ddmTemplatesElement, Element dlFileEntryTypesElement,
1092 Element dlFoldersElement, Element dlFileEntriesElement,
1093 Element dlFileRanksElement, Element dlRepositoriesElement,
1094 Element dlRepositoryEntriesElement, JournalFolder folder,
1095 boolean checkDateRange)
1096 throws Exception {
1097
1098 if (checkDateRange &&
1099 !portletDataContext.isWithinDateRange(folder.getModifiedDate())) {
1100
1101 return;
1102 }
1103
1104 exportParentFolder(
1105 portletDataContext, foldersElement, folder.getParentFolderId());
1106
1107 String path = getFolderPath(portletDataContext, folder);
1108
1109 if (portletDataContext.isPathNotProcessed(path)) {
1110 Element folderElement = foldersElement.addElement("folder");
1111
1112 portletDataContext.addClassedModel(
1113 folderElement, path, folder, NAMESPACE);
1114 }
1115
1116 List<JournalArticle> articles = JournalArticleUtil.findByG_F(
1117 folder.getGroupId(), folder.getFolderId());
1118
1119 for (JournalArticle article : articles) {
1120 exportArticle(
1121 portletDataContext, articlesElement, ddmStructuresElement,
1122 ddmTemplatesElement, dlFileEntryTypesElement, dlFoldersElement,
1123 dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
1124 dlRepositoryEntriesElement, article, true);
1125 }
1126 }
1127
1128 protected static void exportParentFolder(
1129 PortletDataContext portletDataContext, Element foldersElement,
1130 long folderId)
1131 throws Exception {
1132
1133 if (folderId == JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1134 return;
1135 }
1136
1137 JournalFolder folder = JournalFolderUtil.findByPrimaryKey(folderId);
1138
1139 exportParentFolder(
1140 portletDataContext, foldersElement, folder.getParentFolderId());
1141
1142 String path = getFolderPath(portletDataContext, folder);
1143
1144 if (portletDataContext.isPathNotProcessed(path)) {
1145 Element folderElement = foldersElement.addElement("folder");
1146
1147 portletDataContext.addClassedModel(
1148 folderElement, path, folder, NAMESPACE);
1149 }
1150 }
1151
1152 protected static String getArticleImagePath(
1153 PortletDataContext portletDataContext, JournalArticle article)
1154 throws Exception {
1155
1156 StringBundler sb = new StringBundler(6);
1157
1158 sb.append(
1159 ExportImportPathUtil.getPortletPath(
1160 portletDataContext, PortletKeys.JOURNAL));
1161 sb.append("/articles/");
1162 sb.append(article.getArticleResourceUuid());
1163 sb.append(StringPool.SLASH);
1164 sb.append(article.getVersion());
1165 sb.append(StringPool.SLASH);
1166
1167 return sb.toString();
1168 }
1169
1170 protected static String getArticleImagePath(
1171 PortletDataContext portletDataContext, JournalArticle article,
1172 JournalArticleImage articleImage, Image image)
1173 throws Exception {
1174
1175 StringBundler sb = new StringBundler(12);
1176
1177 sb.append(
1178 ExportImportPathUtil.getPortletPath(
1179 portletDataContext, PortletKeys.JOURNAL));
1180 sb.append("/articles/");
1181 sb.append(article.getArticleResourceUuid());
1182 sb.append(StringPool.SLASH);
1183 sb.append(article.getVersion());
1184 sb.append(StringPool.SLASH);
1185 sb.append(articleImage.getElInstanceId());
1186 sb.append(StringPool.UNDERLINE);
1187 sb.append(articleImage.getElName());
1188
1189 if (Validator.isNotNull(articleImage.getLanguageId())) {
1190 sb.append(articleImage.getLanguageId());
1191 }
1192
1193 sb.append(StringPool.PERIOD);
1194 sb.append(image.getType());
1195
1196 return sb.toString();
1197 }
1198
1199 protected static String getArticleSmallImagePath(
1200 PortletDataContext portletDataContext, JournalArticle article)
1201 throws Exception {
1202
1203 StringBundler sb = new StringBundler(6);
1204
1205 sb.append(
1206 ExportImportPathUtil.getPortletPath(
1207 portletDataContext, PortletKeys.JOURNAL));
1208 sb.append("/articles/");
1209 sb.append(article.getArticleResourceUuid());
1210 sb.append("/thumbnail");
1211 sb.append(StringPool.PERIOD);
1212 sb.append(article.getSmallImageType());
1213
1214 return sb.toString();
1215 }
1216
1217 protected static String getDDMStructurePath(
1218 PortletDataContext portletDataContext, String uuid) {
1219
1220 StringBundler sb = new StringBundler(4);
1221
1222 sb.append(
1223 ExportImportPathUtil.getPortletPath(
1224 portletDataContext, PortletKeys.JOURNAL));
1225 sb.append("/ddm-structures/");
1226 sb.append(uuid);
1227 sb.append(".xml");
1228
1229 return sb.toString();
1230 }
1231
1232 protected static String getDDMTemplatePath(
1233 PortletDataContext portletDataContext, DDMTemplate ddmTemplate) {
1234
1235 StringBundler sb = new StringBundler(4);
1236
1237 sb.append(
1238 ExportImportPathUtil.getPortletPath(
1239 portletDataContext, PortletKeys.JOURNAL));
1240 sb.append("/ddm-templates/");
1241 sb.append(ddmTemplate.getUuid());
1242 sb.append(".xml");
1243
1244 return sb.toString();
1245 }
1246
1247 protected static String getFeedPath(
1248 PortletDataContext portletDataContext, JournalFeed feed) {
1249
1250 StringBundler sb = new StringBundler(4);
1251
1252 sb.append(
1253 ExportImportPathUtil.getPortletPath(
1254 portletDataContext, PortletKeys.JOURNAL));
1255 sb.append("/feeds/");
1256 sb.append(feed.getUuid());
1257 sb.append(".xml");
1258
1259 return sb.toString();
1260 }
1261
1262 protected static String getFolderPath(
1263 PortletDataContext portletDataContext, JournalFolder folder) {
1264
1265 StringBundler sb = new StringBundler(4);
1266
1267 sb.append(
1268 ExportImportPathUtil.getPortletPath(
1269 portletDataContext, PortletKeys.JOURNAL));
1270 sb.append("/folders/");
1271 sb.append(folder.getFolderId());
1272 sb.append(".xml");
1273
1274 return sb.toString();
1275 }
1276
1277 protected static String getImportFolderPath(
1278 PortletDataContext portletDataContext, long folderId) {
1279
1280 StringBundler sb = new StringBundler(4);
1281
1282 sb.append(
1283 ExportImportPathUtil.getPortletPath(
1284 portletDataContext, PortletKeys.JOURNAL));
1285 sb.append("/folders/");
1286 sb.append(folderId);
1287 sb.append(".xml");
1288
1289 return sb.toString();
1290 }
1291
1292 protected static String importDLFileEntries(
1293 PortletDataContext portletDataContext, Element parentElement,
1294 String content)
1295 throws Exception {
1296
1297 List<Element> dlReferenceElements = parentElement.elements(
1298 "dl-reference");
1299
1300 for (Element dlReferenceElement : dlReferenceElements) {
1301 String dlReferencePath = dlReferenceElement.attributeValue("path");
1302
1303 String fileEntryUUID = null;
1304
1305 try {
1306 Object zipEntryObject = portletDataContext.getZipEntryAsObject(
1307 dlReferencePath);
1308
1309 if (zipEntryObject == null) {
1310 if (_log.isWarnEnabled()) {
1311 _log.warn("Unable to reference " + dlReferencePath);
1312 }
1313
1314 continue;
1315 }
1316
1317 boolean defaultRepository = GetterUtil.getBoolean(
1318 dlReferenceElement.attributeValue("default-repository"));
1319
1320 if (defaultRepository) {
1321 FileEntry fileEntry = (FileEntry)zipEntryObject;
1322
1323 fileEntryUUID = fileEntry.getUuid();
1324 }
1325 else {
1326 RepositoryEntry repositoryEntry =
1327 (RepositoryEntry)zipEntryObject;
1328
1329 fileEntryUUID = repositoryEntry.getUuid();
1330 }
1331 }
1332 catch (Exception e) {
1333 if (_log.isDebugEnabled()) {
1334 _log.debug(e, e);
1335 }
1336 else if (_log.isWarnEnabled()) {
1337 _log.warn(e.getMessage());
1338 }
1339 }
1340
1341 if (fileEntryUUID == null) {
1342 continue;
1343 }
1344
1345 FileEntry fileEntry =
1346 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1347 fileEntryUUID, portletDataContext.getScopeGroupId());
1348
1349 if (fileEntry == null) {
1350 continue;
1351 }
1352
1353 String dlReference = "[$dl-reference=" + dlReferencePath + "$]";
1354
1355 String url = DLUtil.getPreviewURL(
1356 fileEntry, fileEntry.getFileVersion(), null, StringPool.BLANK,
1357 false, false);
1358
1359 content = StringUtil.replace(content, dlReference, url);
1360 }
1361
1362 return content;
1363 }
1364
1365 protected static void importFolder(
1366 PortletDataContext portletDataContext, Element folderElement)
1367 throws Exception {
1368
1369 String path = folderElement.attributeValue("path");
1370
1371 if (!portletDataContext.isPathNotProcessed(path)) {
1372 return;
1373 }
1374
1375 JournalFolder folder =
1376 (JournalFolder)portletDataContext.getZipEntryAsObject(path);
1377
1378 importFolder(portletDataContext, path, folder);
1379 }
1380
1381 protected static void importFolder(
1382 PortletDataContext portletDataContext, String folderPath,
1383 JournalFolder folder)
1384 throws Exception {
1385
1386 long userId = portletDataContext.getUserId(folder.getUserUuid());
1387
1388 Map<Long, Long> folderIds =
1389 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1390 JournalFolder.class);
1391
1392 long parentFolderId = MapUtil.getLong(
1393 folderIds, folder.getParentFolderId(), folder.getParentFolderId());
1394
1395 if ((parentFolderId !=
1396 JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
1397 (parentFolderId == folder.getParentFolderId())) {
1398
1399 String path = getImportFolderPath(
1400 portletDataContext, parentFolderId);
1401
1402 JournalFolder parentFolder =
1403 (JournalFolder)portletDataContext.getZipEntryAsObject(path);
1404
1405 importFolder(portletDataContext, path, parentFolder);
1406
1407 parentFolderId = MapUtil.getLong(
1408 folderIds, folder.getParentFolderId(),
1409 folder.getParentFolderId());
1410 }
1411
1412 ServiceContext serviceContext = portletDataContext.createServiceContext(
1413 folderPath, folder, NAMESPACE);
1414
1415 JournalFolder importedFolder = null;
1416
1417 long groupId = portletDataContext.getScopeGroupId();
1418
1419 if (portletDataContext.isDataStrategyMirror()) {
1420 JournalFolder existingFolder = JournalFolderUtil.fetchByUUID_G(
1421 folder.getUuid(), groupId);
1422
1423 if (existingFolder == null) {
1424 serviceContext.setUuid(folder.getUuid());
1425
1426 importedFolder = JournalFolderLocalServiceUtil.addFolder(
1427 userId, groupId, parentFolderId, folder.getName(),
1428 folder.getDescription(), serviceContext);
1429 }
1430 else {
1431 importedFolder = JournalFolderLocalServiceUtil.updateFolder(
1432 userId, existingFolder.getFolderId(), parentFolderId,
1433 folder.getName(), folder.getDescription(), false,
1434 serviceContext);
1435 }
1436 }
1437 else {
1438 importedFolder = JournalFolderLocalServiceUtil.addFolder(
1439 userId, groupId, parentFolderId, folder.getName(),
1440 folder.getDescription(), serviceContext);
1441 }
1442
1443 portletDataContext.importClassedModel(
1444 folder, importedFolder, NAMESPACE);
1445 }
1446
1447 protected static String importLayoutFriendlyURLs(
1448 PortletDataContext portletDataContext, String content)
1449 throws Exception {
1450
1451 String privateGroupServletMapping =
1452 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
1453 String privateUserServletMapping =
1454 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
1455 String publicServletMapping =
1456 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
1457
1458 String portalContextPath = PortalUtil.getPathContext();
1459
1460 if (Validator.isNotNull(portalContextPath)) {
1461 privateGroupServletMapping = portalContextPath.concat(
1462 privateGroupServletMapping);
1463 privateUserServletMapping = portalContextPath.concat(
1464 privateUserServletMapping);
1465 publicServletMapping = portalContextPath.concat(
1466 publicServletMapping);
1467 }
1468
1469 content = StringUtil.replace(
1470 content, "@data_handler_private_group_servlet_mapping@",
1471 privateGroupServletMapping);
1472 content = StringUtil.replace(
1473 content, "@data_handler_private_user_servlet_mapping@",
1474 privateUserServletMapping);
1475 content = StringUtil.replace(
1476 content, "@data_handler_public_servlet_mapping@",
1477 publicServletMapping);
1478
1479 Group group = GroupLocalServiceUtil.getGroup(
1480 portletDataContext.getScopeGroupId());
1481
1482 content = StringUtil.replace(
1483 content, "@data_handler_group_friendly_url@",
1484 group.getFriendlyURL());
1485
1486 return content;
1487 }
1488
1489 protected static String importLinksToLayout(
1490 PortletDataContext portletDataContext, String content)
1491 throws Exception {
1492
1493 List<String> oldLinksToLayout = new ArrayList<String>();
1494 List<String> newLinksToLayout = new ArrayList<String>();
1495
1496 Matcher matcher = _importLinksToLayoutPattern.matcher(content);
1497
1498 while (matcher.find()) {
1499 long oldLayoutId = GetterUtil.getLong(matcher.group(1));
1500
1501 long newLayoutId = oldLayoutId;
1502
1503 String type = matcher.group(2);
1504
1505 boolean privateLayout = type.startsWith("private");
1506
1507 String layoutUuid = matcher.group(3);
1508
1509 String friendlyURL = matcher.group(4);
1510
1511 try {
1512 Layout layout = LayoutUtil.fetchByUUID_G_P(
1513 layoutUuid, portletDataContext.getScopeGroupId(),
1514 privateLayout);
1515
1516 if (layout == null) {
1517 layout = LayoutUtil.fetchByG_P_F(
1518 portletDataContext.getScopeGroupId(), privateLayout,
1519 friendlyURL);
1520 }
1521
1522 if (layout == null) {
1523 layout = LayoutUtil.fetchByG_P_L(
1524 portletDataContext.getScopeGroupId(), privateLayout,
1525 oldLayoutId);
1526 }
1527
1528 if (layout == null) {
1529 if (_log.isWarnEnabled()) {
1530 StringBundler sb = new StringBundler(9);
1531
1532 sb.append("Unable to get layout with UUID ");
1533 sb.append(layoutUuid);
1534 sb.append(", friendly URL ");
1535 sb.append(friendlyURL);
1536 sb.append(", or ");
1537 sb.append("layoutId ");
1538 sb.append(oldLayoutId);
1539 sb.append(" in group ");
1540 sb.append(portletDataContext.getScopeGroupId());
1541
1542 _log.warn(sb.toString());
1543 }
1544 }
1545 else {
1546 newLayoutId = layout.getLayoutId();
1547 }
1548 }
1549 catch (SystemException se) {
1550 if (_log.isWarnEnabled()) {
1551 _log.warn(
1552 "Unable to get layout in group " +
1553 portletDataContext.getScopeGroupId(), se);
1554 }
1555 }
1556
1557 String oldLinkToLayout = matcher.group(0);
1558
1559 StringBundler sb = new StringBundler(4);
1560
1561 sb.append(StringPool.AT);
1562 sb.append(layoutUuid);
1563 sb.append(StringPool.AT);
1564 sb.append(friendlyURL);
1565
1566 String newLinkToLayout = StringUtil.replace(
1567 oldLinkToLayout,
1568 new String[] {sb.toString(), String.valueOf(oldLayoutId)},
1569 new String[] {StringPool.BLANK, String.valueOf(newLayoutId)});
1570
1571 oldLinksToLayout.add(oldLinkToLayout);
1572 newLinksToLayout.add(newLinkToLayout);
1573 }
1574
1575 content = StringUtil.replace(
1576 content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
1577 ArrayUtil.toStringArray(newLinksToLayout.toArray()));
1578
1579 return content;
1580 }
1581
1582 protected static void prepareLanguagesForImport(JournalArticle article)
1583 throws PortalException {
1584
1585 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
1586 article.getDefaultLocale());
1587
1588 Locale[] articleAvailableLocales = LocaleUtil.fromLanguageIds(
1589 article.getAvailableLocales());
1590
1591 Locale defaultImportLocale = LocalizationUtil.getDefaultImportLocale(
1592 JournalArticle.class.getName(), article.getPrimaryKey(),
1593 articleDefaultLocale, articleAvailableLocales);
1594
1595 article.prepareLocalizedFieldsForImport(defaultImportLocale);
1596 }
1597
1598 @Override
1599 protected PortletPreferences doDeleteData(
1600 PortletDataContext portletDataContext, String portletId,
1601 PortletPreferences portletPreferences)
1602 throws Exception {
1603
1604 if (portletDataContext.addPrimaryKey(
1605 JournalPortletDataHandler.class, "deleteData")) {
1606
1607 return portletPreferences;
1608 }
1609
1610 JournalArticleLocalServiceUtil.deleteArticles(
1611 portletDataContext.getScopeGroupId());
1612
1613 DDMTemplateLocalServiceUtil.deleteTemplates(
1614 portletDataContext.getScopeGroupId());
1615
1616 DDMStructureLocalServiceUtil.deleteStructures(
1617 portletDataContext.getScopeGroupId());
1618
1619 return portletPreferences;
1620 }
1621
1622 @Override
1623 protected String doExportData(
1624 PortletDataContext portletDataContext, String portletId,
1625 PortletPreferences portletPreferences)
1626 throws Exception {
1627
1628 portletDataContext.addPermissions(
1629 "com.liferay.portlet.journal",
1630 portletDataContext.getScopeGroupId());
1631
1632 Element rootElement = addExportDataRootElement(portletDataContext);
1633
1634 rootElement.addAttribute(
1635 "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
1636
1637 Element ddmStructuresElement =
1638 portletDataContext.getExportDataGroupElement(DDMStructure.class);
1639
1640 List<DDMStructure> ddmStructures = DDMStructureUtil.findByG_C(
1641 portletDataContext.getScopeGroupId(),
1642 PortalUtil.getClassNameId(JournalArticle.class), QueryUtil.ALL_POS,
1643 QueryUtil.ALL_POS, new StructureIdComparator(true));
1644
1645 List<DDMTemplate> ddmTemplates = new ArrayList<DDMTemplate>();
1646
1647 for (DDMStructure ddmStructure : ddmStructures) {
1648 if (portletDataContext.isWithinDateRange(
1649 ddmStructure.getModifiedDate())) {
1650
1651 StagedModelDataHandlerUtil.exportStagedModel(
1652 portletDataContext, ddmStructure);
1653 }
1654
1655 ddmTemplates.addAll(ddmStructure.getTemplates());
1656 }
1657
1658 Element ddmTemplatesElement =
1659 portletDataContext.getExportDataGroupElement(DDMTemplate.class);
1660
1661
1662
1663 Element dlFileEntryTypesElement = rootElement.addElement(
1664 "dl-file-entry-types");
1665 Element dlFoldersElement = rootElement.addElement("dl-folders");
1666 Element dlFilesElement = rootElement.addElement("dl-file-entries");
1667 Element dlFileRanksElement = rootElement.addElement("dl-file-ranks");
1668 Element dlRepositoriesElement = rootElement.addElement(
1669 "dl-repositories");
1670 Element dlRepositoryEntriesElement = rootElement.addElement(
1671 "dl-repository-entries");
1672
1673 for (DDMTemplate ddmTemplate : ddmTemplates) {
1674 if (portletDataContext.isWithinDateRange(
1675 ddmTemplate.getModifiedDate())) {
1676
1677 StagedModelDataHandlerUtil.exportStagedModel(
1678 portletDataContext, ddmTemplate);
1679 }
1680 }
1681
1682 Element feedsElement = rootElement.addElement("feeds");
1683
1684 List<JournalFeed> feeds = JournalFeedUtil.findByGroupId(
1685 portletDataContext.getScopeGroupId());
1686
1687 for (JournalFeed feed : feeds) {
1688 if (portletDataContext.isWithinDateRange(feed.getModifiedDate())) {
1689 exportFeed(portletDataContext, feedsElement, feed);
1690 }
1691 }
1692
1693 Element foldersElement = rootElement.addElement("folders");
1694 Element articlesElement = rootElement.addElement("articles");
1695
1696 if (portletDataContext.getBooleanParameter(NAMESPACE, "web-content")) {
1697 List<JournalFolder> folders = JournalFolderUtil.findByGroupId(
1698 portletDataContext.getScopeGroupId());
1699
1700 for (JournalFolder folder : folders) {
1701 exportFolder(
1702 portletDataContext, foldersElement, articlesElement,
1703 ddmStructuresElement, ddmTemplatesElement,
1704 dlFileEntryTypesElement, dlFoldersElement, dlFilesElement,
1705 dlFileRanksElement, dlRepositoriesElement,
1706 dlRepositoryEntriesElement, folder, true);
1707 }
1708
1709 List<JournalArticle> articles = JournalArticleUtil.findByG_F(
1710 portletDataContext.getScopeGroupId(),
1711 JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID,
1712 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1713 new ArticleIDComparator(true));
1714
1715 for (JournalArticle article : articles) {
1716 if (portletDataContext.getBooleanParameter(
1717 NAMESPACE, "version-history") ||
1718 JournalArticleLocalServiceUtil.isLatestVersion(
1719 article.getGroupId(), article.getArticleId(),
1720 article.getVersion(),
1721 WorkflowConstants.STATUS_APPROVED)) {
1722
1723 exportArticle(
1724 portletDataContext, articlesElement,
1725 ddmStructuresElement, ddmTemplatesElement,
1726 dlFileEntryTypesElement, dlFoldersElement,
1727 dlFilesElement, dlFileRanksElement,
1728 dlRepositoriesElement, dlRepositoryEntriesElement,
1729 article, true);
1730 }
1731 }
1732 }
1733
1734 return getExportDataRootElementString(rootElement);
1735 }
1736
1737 @Override
1738 protected PortletPreferences doImportData(
1739 PortletDataContext portletDataContext, String portletId,
1740 PortletPreferences portletPreferences, String data)
1741 throws Exception {
1742
1743 portletDataContext.importPermissions(
1744 "com.liferay.portlet.journal",
1745 portletDataContext.getSourceGroupId(),
1746 portletDataContext.getScopeGroupId());
1747
1748 Element rootElement = portletDataContext.getImportDataRootElement();
1749
1750 importReferencedData(portletDataContext, rootElement);
1751
1752 Element ddmStructuresElement =
1753 portletDataContext.getImportDataGroupElement(DDMStructure.class);
1754
1755 List<Element> ddmStructureElements = ddmStructuresElement.elements();
1756
1757 for (Element ddmStructureElement : ddmStructureElements) {
1758 StagedModelDataHandlerUtil.importStagedModel(
1759 portletDataContext, ddmStructureElement);
1760 }
1761
1762 Element ddmTemplatesElement =
1763 portletDataContext.getImportDataGroupElement(DDMTemplate.class);
1764
1765 List<Element> ddmTemplateElements = ddmTemplatesElement.elements();
1766
1767 for (Element ddmTemplateElement : ddmTemplateElements) {
1768 StagedModelDataHandlerUtil.importStagedModel(
1769 portletDataContext, ddmTemplateElement);
1770 }
1771
1772 Element feedsElement = rootElement.element("feeds");
1773
1774 List<Element> feedElements = feedsElement.elements("feed");
1775
1776 for (Element feedElement : feedElements) {
1777 importFeed(portletDataContext, feedElement);
1778 }
1779
1780 if (portletDataContext.getBooleanParameter(NAMESPACE, "web-content")) {
1781 Element foldersElement = rootElement.element("folders");
1782
1783 List<Element> folderElements = foldersElement.elements("folder");
1784
1785 for (Element folderElement : folderElements) {
1786 importFolder(portletDataContext, folderElement);
1787 }
1788
1789 Element articlesElement = rootElement.element("articles");
1790
1791 List<Element> articleElements = articlesElement.elements("article");
1792
1793 for (Element articleElement : articleElements) {
1794 try {
1795 importArticle(portletDataContext, articleElement);
1796 }
1797 catch (ArticleContentException ace) {
1798 if (_log.isWarnEnabled()) {
1799 String path = articleElement.attributeValue("path");
1800
1801 _log.warn(
1802 "Skipping article with path " + path +
1803 " because of invalid content");
1804 }
1805 }
1806 }
1807 }
1808
1809 return portletPreferences;
1810 }
1811
1812 private static Log _log = LogFactoryUtil.getLog(
1813 JournalPortletDataHandler.class);
1814
1815 private static Pattern _importLinksToLayoutPattern = Pattern.compile(
1816 "\\[([0-9]+)@(public|private\\-[a-z]*)@(\\p{XDigit}{8}\\-" +
1817 "(?:\\p{XDigit}{4}\\-){3}\\p{XDigit}{12})@([^\\]]*)\\]");
1818
1819 }