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.PortletDataContext;
023 import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
024 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
025 import com.liferay.portal.kernel.log.Log;
026 import com.liferay.portal.kernel.log.LogFactoryUtil;
027 import com.liferay.portal.kernel.repository.model.FileEntry;
028 import com.liferay.portal.kernel.util.ArrayUtil;
029 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
030 import com.liferay.portal.kernel.util.CharPool;
031 import com.liferay.portal.kernel.util.FileUtil;
032 import com.liferay.portal.kernel.util.GetterUtil;
033 import com.liferay.portal.kernel.util.HttpUtil;
034 import com.liferay.portal.kernel.util.LocaleUtil;
035 import com.liferay.portal.kernel.util.LocalizationUtil;
036 import com.liferay.portal.kernel.util.MapUtil;
037 import com.liferay.portal.kernel.util.StringBundler;
038 import com.liferay.portal.kernel.util.StringPool;
039 import com.liferay.portal.kernel.util.StringUtil;
040 import com.liferay.portal.kernel.util.Validator;
041 import com.liferay.portal.kernel.workflow.WorkflowConstants;
042 import com.liferay.portal.kernel.xml.Document;
043 import com.liferay.portal.kernel.xml.Element;
044 import com.liferay.portal.kernel.xml.SAXReaderUtil;
045 import com.liferay.portal.model.Group;
046 import com.liferay.portal.model.Image;
047 import com.liferay.portal.model.Layout;
048 import com.liferay.portal.model.RepositoryEntry;
049 import com.liferay.portal.model.User;
050 import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
051 import com.liferay.portal.service.GroupLocalServiceUtil;
052 import com.liferay.portal.service.LayoutLocalServiceUtil;
053 import com.liferay.portal.service.ServiceContext;
054 import com.liferay.portal.service.UserLocalServiceUtil;
055 import com.liferay.portal.service.persistence.ImageUtil;
056 import com.liferay.portal.service.persistence.LayoutUtil;
057 import com.liferay.portal.util.PortletKeys;
058 import com.liferay.portal.util.PropsValues;
059 import com.liferay.portlet.documentlibrary.lar.DLPortletDataHandlerImpl;
060 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
061 import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
062 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
063 import com.liferay.portlet.documentlibrary.util.DLUtil;
064 import com.liferay.portlet.journal.ArticleContentException;
065 import com.liferay.portlet.journal.FeedTargetLayoutFriendlyUrlException;
066 import com.liferay.portlet.journal.NoSuchArticleException;
067 import com.liferay.portlet.journal.NoSuchStructureException;
068 import com.liferay.portlet.journal.model.JournalArticle;
069 import com.liferay.portlet.journal.model.JournalArticleConstants;
070 import com.liferay.portlet.journal.model.JournalArticleImage;
071 import com.liferay.portlet.journal.model.JournalArticleResource;
072 import com.liferay.portlet.journal.model.JournalFeed;
073 import com.liferay.portlet.journal.model.JournalFolder;
074 import com.liferay.portlet.journal.model.JournalFolderConstants;
075 import com.liferay.portlet.journal.model.JournalStructure;
076 import com.liferay.portlet.journal.model.JournalTemplate;
077 import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
078 import com.liferay.portlet.journal.service.JournalFeedLocalServiceUtil;
079 import com.liferay.portlet.journal.service.JournalFolderLocalServiceUtil;
080 import com.liferay.portlet.journal.service.JournalStructureLocalServiceUtil;
081 import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
082 import com.liferay.portlet.journal.service.persistence.JournalArticleImageUtil;
083 import com.liferay.portlet.journal.service.persistence.JournalArticleResourceUtil;
084 import com.liferay.portlet.journal.service.persistence.JournalArticleUtil;
085 import com.liferay.portlet.journal.service.persistence.JournalFeedUtil;
086 import com.liferay.portlet.journal.service.persistence.JournalFolderUtil;
087 import com.liferay.portlet.journal.service.persistence.JournalStructureUtil;
088 import com.liferay.portlet.journal.service.persistence.JournalTemplateUtil;
089 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
090 import com.liferay.portlet.journal.util.comparator.StructurePKComparator;
091
092 import java.io.File;
093
094 import java.util.ArrayList;
095 import java.util.Calendar;
096 import java.util.Collections;
097 import java.util.Date;
098 import java.util.HashMap;
099 import java.util.List;
100 import java.util.Locale;
101 import java.util.Map;
102 import java.util.regex.Matcher;
103 import java.util.regex.Pattern;
104
105 import javax.portlet.PortletPreferences;
106
107
137 public class JournalPortletDataHandlerImpl extends BasePortletDataHandler {
138
139 public static void exportArticle(
140 PortletDataContext portletDataContext, Element articlesElement,
141 Element structuresElement, Element templatesElement,
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 JournalStructure structure =
183 JournalStructureLocalServiceUtil.getStructure(
184 article.getGroupId(), article.getStructureId(), true);
185
186 articleElement.addAttribute("structure-uuid", structure.getUuid());
187
188 exportStructure(portletDataContext, structuresElement, structure);
189 }
190
191 String templateId = article.getTemplateId();
192
193 if (Validator.isNotNull(templateId)) {
194 JournalTemplate template =
195 JournalTemplateLocalServiceUtil.getTemplate(
196 article.getGroupId(), templateId, true);
197
198 articleElement.addAttribute("template-uuid", template.getUuid());
199
200 exportTemplate(
201 portletDataContext, templatesElement, dlFileEntryTypesElement,
202 dlFoldersElement, dlFileEntriesElement, dlFileRanksElement,
203 dlRepositoriesElement, dlRepositoryEntriesElement, template);
204 }
205
206 Image smallImage = ImageUtil.fetchByPrimaryKey(
207 article.getSmallImageId());
208
209 if (article.isSmallImage() && (smallImage != null)) {
210 String smallImagePath = getArticleSmallImagePath(
211 portletDataContext, article);
212
213 articleElement.addAttribute("small-image-path", smallImagePath);
214
215 article.setSmallImageType(smallImage.getType());
216
217 portletDataContext.addZipEntry(
218 smallImagePath, smallImage.getTextObj());
219 }
220
221 if (portletDataContext.getBooleanParameter(_NAMESPACE, "images")) {
222 String imagePath = getArticleImagePath(portletDataContext, article);
223
224 articleElement.addAttribute("image-path", imagePath);
225
226 List<JournalArticleImage> articleImages =
227 JournalArticleImageUtil.findByG_A_V(
228 article.getGroupId(), article.getArticleId(),
229 article.getVersion());
230
231 for (JournalArticleImage articleImage : articleImages) {
232 Image image = null;
233
234 try {
235 image = ImageUtil.findByPrimaryKey(
236 articleImage.getArticleImageId());
237 }
238 catch (NoSuchImageException nsie) {
239 continue;
240 }
241
242 if (image.getTextObj() == null) {
243 continue;
244 }
245
246 String articleImagePath = getArticleImagePath(
247 portletDataContext, article, articleImage, image);
248
249 if (!portletDataContext.isPathNotProcessed(articleImagePath)) {
250 continue;
251 }
252
253 portletDataContext.addZipEntry(
254 articleImagePath, image.getTextObj());
255 }
256 }
257
258 article.setStatusByUserUuid(article.getStatusByUserUuid());
259
260 if (portletDataContext.getBooleanParameter(
261 _NAMESPACE, "embedded-assets")) {
262
263 String content = exportReferencedContent(
264 portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
265 dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
266 dlRepositoryEntriesElement, articleElement,
267 article.getContent());
268
269 article.setContent(content);
270 }
271
272 portletDataContext.addClassedModel(
273 articleElement, path, article, _NAMESPACE);
274 }
275
276 public static String exportReferencedContent(
277 PortletDataContext portletDataContext,
278 Element dlFileEntryTypesElement, Element dlFoldersElement,
279 Element dlFileEntriesElement, Element dlFileRanksElement,
280 Element dlRepositoriesElement, Element dlRepositoryEntriesElement,
281 Element entityElement, String content)
282 throws Exception {
283
284 content = exportDLFileEntries(
285 portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
286 dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
287 dlRepositoryEntriesElement, entityElement, content, false);
288 content = exportLayoutFriendlyURLs(portletDataContext, content);
289 content = exportLinksToLayout(portletDataContext, content);
290
291 String entityElementName = entityElement.getName();
292
293 if (!entityElementName.equals("article")) {
294 content = StringUtil.replace(
295 content, StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
296 }
297
298 return content;
299 }
300
301 public static String getArticlePath(
302 PortletDataContext portletDataContext, JournalArticle article)
303 throws Exception {
304
305 StringBundler sb = new StringBundler(8);
306
307 sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
308 sb.append("/articles/");
309 sb.append(article.getArticleResourceUuid());
310 sb.append(StringPool.SLASH);
311 sb.append(article.getVersion());
312 sb.append(StringPool.SLASH);
313 sb.append("article.xml");
314
315 return sb.toString();
316 }
317
318 public static PortletDataHandlerControl[] getMetadataControls() {
319 return _metadataControls;
320 }
321
322 public static void importArticle(
323 PortletDataContext portletDataContext, Element articleElement)
324 throws Exception {
325
326 String path = articleElement.attributeValue("path");
327
328 if (!portletDataContext.isPathNotProcessed(path)) {
329 return;
330 }
331
332 JournalArticle article =
333 (JournalArticle)portletDataContext.getZipEntryAsObject(
334 articleElement, path);
335
336 prepareLanguagesForImport(article);
337
338 long userId = portletDataContext.getUserId(article.getUserUuid());
339
340 JournalCreationStrategy creationStrategy =
341 JournalCreationStrategyFactory.getInstance();
342
343 long authorId = creationStrategy.getAuthorUserId(
344 portletDataContext, article);
345
346 if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
347 userId = authorId;
348 }
349
350 User user = UserLocalServiceUtil.getUser(userId);
351
352 Map<Long, Long> folderIds =
353 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
354 JournalFolder.class);
355
356 long folderId = MapUtil.getLong(
357 folderIds, article.getFolderId(), article.getFolderId());
358
359 if ((folderId != JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
360 (folderId == article.getFolderId())) {
361
362 String folderPath = getImportFolderPath(
363 portletDataContext, folderId);
364
365 JournalFolder folder =
366 (JournalFolder)portletDataContext.getZipEntryAsObject(
367 folderPath);
368
369 importFolder(portletDataContext, folderPath, folder);
370
371 folderId = MapUtil.getLong(
372 folderIds, article.getFolderId(), article.getFolderId());
373 }
374
375 String articleId = article.getArticleId();
376 boolean autoArticleId = false;
377
378 if (Validator.isNumber(articleId) ||
379 (JournalArticleUtil.fetchByG_A_V(
380 portletDataContext.getScopeGroupId(), articleId,
381 JournalArticleConstants.VERSION_DEFAULT) != null)) {
382
383 autoArticleId = true;
384 }
385
386 Map<String, String> articleIds =
387 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
388 JournalArticle.class + ".articleId");
389
390 String newArticleId = articleIds.get(articleId);
391
392 if (Validator.isNotNull(newArticleId)) {
393
394
395
396
397 articleId = newArticleId;
398 autoArticleId = false;
399 }
400
401 String content = article.getContent();
402
403 content = importDLFileEntries(
404 portletDataContext, articleElement, content);
405
406 Group group = GroupLocalServiceUtil.getGroup(
407 portletDataContext.getScopeGroupId());
408
409 content = StringUtil.replace(
410 content, "@data_handler_group_friendly_url@",
411 group.getFriendlyURL());
412
413 content = importLinksToLayout(portletDataContext, content);
414
415 article.setContent(content);
416
417 String newContent = creationStrategy.getTransformedContent(
418 portletDataContext, article);
419
420 if (newContent != JournalCreationStrategy.ARTICLE_CONTENT_UNCHANGED) {
421 article.setContent(newContent);
422 }
423
424 Map<String, String> structureIds =
425 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
426 JournalStructure.class);
427
428 String parentStructureId = MapUtil.getString(
429 structureIds, article.getStructureId(), article.getStructureId());
430
431 Map<String, String> templateIds =
432 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
433 JournalTemplate.class);
434
435 String parentTemplateId = MapUtil.getString(
436 templateIds, article.getTemplateId(), article.getTemplateId());
437
438 Date displayDate = article.getDisplayDate();
439
440 int displayDateMonth = 0;
441 int displayDateDay = 0;
442 int displayDateYear = 0;
443 int displayDateHour = 0;
444 int displayDateMinute = 0;
445
446 if (displayDate != null) {
447 Calendar displayCal = CalendarFactoryUtil.getCalendar(
448 user.getTimeZone());
449
450 displayCal.setTime(displayDate);
451
452 displayDateMonth = displayCal.get(Calendar.MONTH);
453 displayDateDay = displayCal.get(Calendar.DATE);
454 displayDateYear = displayCal.get(Calendar.YEAR);
455 displayDateHour = displayCal.get(Calendar.HOUR);
456 displayDateMinute = displayCal.get(Calendar.MINUTE);
457
458 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
459 displayDateHour += 12;
460 }
461 }
462
463 Date expirationDate = article.getExpirationDate();
464
465 int expirationDateMonth = 0;
466 int expirationDateDay = 0;
467 int expirationDateYear = 0;
468 int expirationDateHour = 0;
469 int expirationDateMinute = 0;
470 boolean neverExpire = true;
471
472 if (expirationDate != null) {
473 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
474 user.getTimeZone());
475
476 expirationCal.setTime(expirationDate);
477
478 expirationDateMonth = expirationCal.get(Calendar.MONTH);
479 expirationDateDay = expirationCal.get(Calendar.DATE);
480 expirationDateYear = expirationCal.get(Calendar.YEAR);
481 expirationDateHour = expirationCal.get(Calendar.HOUR);
482 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
483 neverExpire = false;
484
485 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
486 expirationDateHour += 12;
487 }
488 }
489
490 Date reviewDate = article.getReviewDate();
491
492 int reviewDateMonth = 0;
493 int reviewDateDay = 0;
494 int reviewDateYear = 0;
495 int reviewDateHour = 0;
496 int reviewDateMinute = 0;
497 boolean neverReview = true;
498
499 if (reviewDate != null) {
500 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
501 user.getTimeZone());
502
503 reviewCal.setTime(reviewDate);
504
505 reviewDateMonth = reviewCal.get(Calendar.MONTH);
506 reviewDateDay = reviewCal.get(Calendar.DATE);
507 reviewDateYear = reviewCal.get(Calendar.YEAR);
508 reviewDateHour = reviewCal.get(Calendar.HOUR);
509 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
510 neverReview = false;
511
512 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
513 reviewDateHour += 12;
514 }
515 }
516
517 long structurePrimaryKey = 0;
518
519 if (Validator.isNotNull(article.getStructureId())) {
520 String structureUuid = articleElement.attributeValue(
521 "structure-uuid");
522
523 JournalStructure existingStructure =
524 JournalStructureUtil.fetchByUUID_G(
525 structureUuid, portletDataContext.getScopeGroupId());
526
527 if (existingStructure == null) {
528 Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
529 portletDataContext.getCompanyId());
530
531 long companyGroupId = companyGroup.getGroupId();
532
533 existingStructure = JournalStructureUtil.fetchByUUID_G(
534 structureUuid, companyGroupId);
535 }
536
537 if (existingStructure == null) {
538 String newStructureId = structureIds.get(
539 article.getStructureId());
540
541 if (Validator.isNotNull(newStructureId)) {
542 existingStructure = JournalStructureUtil.fetchByG_S(
543 portletDataContext.getScopeGroupId(),
544 String.valueOf(newStructureId));
545 }
546
547 if (existingStructure == null) {
548 if (_log.isWarnEnabled()) {
549 StringBundler sb = new StringBundler();
550
551 sb.append("Structure ");
552 sb.append(article.getStructureId());
553 sb.append(" is missing for article ");
554 sb.append(article.getArticleId());
555 sb.append(", skipping this article.");
556
557 _log.warn(sb.toString());
558 }
559
560 return;
561 }
562 }
563
564 structurePrimaryKey = existingStructure.getPrimaryKey();
565
566 parentStructureId = existingStructure.getStructureId();
567 }
568
569 if (Validator.isNotNull(article.getTemplateId())) {
570 String templateUuid = articleElement.attributeValue(
571 "template-uuid");
572
573 JournalTemplate existingTemplate =
574 JournalTemplateUtil.fetchByUUID_G(
575 templateUuid, portletDataContext.getScopeGroupId());
576
577 if (existingTemplate == null) {
578 Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
579 portletDataContext.getCompanyId());
580
581 long companyGroupId = companyGroup.getGroupId();
582
583 existingTemplate = JournalTemplateUtil.fetchByUUID_G(
584 templateUuid, companyGroupId);
585 }
586
587 if (existingTemplate == null) {
588 String newTemplateId = templateIds.get(article.getTemplateId());
589
590 if (Validator.isNotNull(newTemplateId)) {
591 existingTemplate = JournalTemplateUtil.fetchByG_T(
592 portletDataContext.getScopeGroupId(), newTemplateId);
593 }
594
595 if (existingTemplate == null) {
596 if (_log.isWarnEnabled()) {
597 StringBundler sb = new StringBundler();
598
599 sb.append("Template ");
600 sb.append(article.getTemplateId());
601 sb.append(" is missing for article ");
602 sb.append(article.getArticleId());
603 sb.append(", skipping this article.");
604
605 _log.warn(sb.toString());
606 }
607
608 return;
609 }
610 }
611
612 parentTemplateId = existingTemplate.getTemplateId();
613 }
614
615 File smallFile = null;
616
617 String smallImagePath = articleElement.attributeValue(
618 "small-image-path");
619
620 if (article.isSmallImage() && Validator.isNotNull(smallImagePath)) {
621 byte[] bytes = portletDataContext.getZipEntryAsByteArray(
622 smallImagePath);
623
624 smallFile = FileUtil.createTempFile(article.getSmallImageType());
625
626 FileUtil.write(smallFile, bytes);
627 }
628
629 Map<String, byte[]> images = new HashMap<String, byte[]>();
630
631 String imagePath = articleElement.attributeValue("image-path");
632
633 if (portletDataContext.getBooleanParameter(_NAMESPACE, "images") &&
634 Validator.isNotNull(imagePath)) {
635
636 List<String> imageFiles = portletDataContext.getZipFolderEntries(
637 imagePath);
638
639 for (String imageFile : imageFiles) {
640 String fileName = imageFile;
641
642 if (fileName.contains(StringPool.SLASH)) {
643 fileName = fileName.substring(
644 fileName.lastIndexOf(CharPool.SLASH) + 1);
645 }
646
647 if (fileName.endsWith(".xml")) {
648 continue;
649 }
650
651 int pos = fileName.lastIndexOf(CharPool.PERIOD);
652
653 if (pos != -1) {
654 fileName = fileName.substring(0, pos);
655 }
656
657 images.put(
658 fileName,
659 portletDataContext.getZipEntryAsByteArray(imageFile));
660 }
661 }
662
663 String articleURL = null;
664
665 boolean addGroupPermissions = creationStrategy.addGroupPermissions(
666 portletDataContext, article);
667 boolean addGuestPermissions = creationStrategy.addGuestPermissions(
668 portletDataContext, article);
669
670 ServiceContext serviceContext = portletDataContext.createServiceContext(
671 articleElement, article, _NAMESPACE);
672
673 serviceContext.setAddGroupPermissions(addGroupPermissions);
674 serviceContext.setAddGuestPermissions(addGuestPermissions);
675 serviceContext.setAttribute("imported", Boolean.TRUE.toString());
676
677 if (article.getStatus() != WorkflowConstants.STATUS_APPROVED) {
678 serviceContext.setWorkflowAction(
679 WorkflowConstants.ACTION_SAVE_DRAFT);
680 }
681
682 JournalArticle importedArticle = null;
683
684 String articleResourceUuid = articleElement.attributeValue(
685 "article-resource-uuid");
686
687 if (portletDataContext.isDataStrategyMirror()) {
688 JournalArticleResource articleResource =
689 JournalArticleResourceUtil.fetchByUUID_G(
690 articleResourceUuid, portletDataContext.getScopeGroupId());
691
692 if (articleResource == null) {
693 Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
694 portletDataContext.getCompanyId());
695
696 long companyGroupId = companyGroup.getGroupId();
697
698 articleResource = JournalArticleResourceUtil.fetchByUUID_G(
699 articleResourceUuid, companyGroupId);
700 }
701
702 serviceContext.setUuid(articleResourceUuid);
703 serviceContext.setAttribute("urlTitle", article.getUrlTitle());
704
705 JournalArticle existingArticle = null;
706
707 if (articleResource != null) {
708 try {
709 existingArticle =
710 JournalArticleLocalServiceUtil.getLatestArticle(
711 articleResource.getResourcePrimKey(),
712 WorkflowConstants.STATUS_ANY, false);
713 }
714 catch (NoSuchArticleException nsae) {
715 }
716 }
717
718 if (existingArticle == null) {
719 existingArticle = JournalArticleUtil.fetchByG_A_V(
720 portletDataContext.getScopeGroupId(), newArticleId,
721 article.getVersion());
722 }
723
724 if (existingArticle == null) {
725 importedArticle = JournalArticleLocalServiceUtil.addArticle(
726 userId, portletDataContext.getScopeGroupId(), folderId,
727 article.getClassNameId(), structurePrimaryKey, articleId,
728 autoArticleId, article.getVersion(), article.getTitleMap(),
729 article.getDescriptionMap(), article.getContent(),
730 article.getType(), parentStructureId, parentTemplateId,
731 article.getLayoutUuid(), displayDateMonth, displayDateDay,
732 displayDateYear, displayDateHour, displayDateMinute,
733 expirationDateMonth, expirationDateDay, expirationDateYear,
734 expirationDateHour, expirationDateMinute, neverExpire,
735 reviewDateMonth, reviewDateDay, reviewDateYear,
736 reviewDateHour, reviewDateMinute, neverReview,
737 article.isIndexable(), article.isSmallImage(),
738 article.getSmallImageURL(), smallFile, images, articleURL,
739 serviceContext);
740 }
741 else {
742 importedArticle = JournalArticleLocalServiceUtil.updateArticle(
743 userId, existingArticle.getGroupId(), folderId,
744 existingArticle.getArticleId(), article.getVersion(),
745 article.getTitleMap(), article.getDescriptionMap(),
746 article.getContent(), article.getType(), parentStructureId,
747 parentTemplateId, article.getLayoutUuid(), displayDateMonth,
748 displayDateDay, displayDateYear, displayDateHour,
749 displayDateMinute, expirationDateMonth, expirationDateDay,
750 expirationDateYear, expirationDateHour,
751 expirationDateMinute, neverExpire, reviewDateMonth,
752 reviewDateDay, reviewDateYear, reviewDateHour,
753 reviewDateMinute, neverReview, article.isIndexable(),
754 article.isSmallImage(), article.getSmallImageURL(),
755 smallFile, images, articleURL, serviceContext);
756 }
757 }
758 else {
759 importedArticle = JournalArticleLocalServiceUtil.addArticle(
760 userId, portletDataContext.getScopeGroupId(), folderId,
761 article.getClassNameId(), structurePrimaryKey, articleId,
762 autoArticleId, article.getVersion(), article.getTitleMap(),
763 article.getDescriptionMap(), article.getContent(),
764 article.getType(), parentStructureId, parentTemplateId,
765 article.getLayoutUuid(), displayDateMonth, displayDateDay,
766 displayDateYear, displayDateHour, displayDateMinute,
767 expirationDateMonth, expirationDateDay, expirationDateYear,
768 expirationDateHour, expirationDateMinute, neverExpire,
769 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
770 reviewDateMinute, neverReview, article.isIndexable(),
771 article.isSmallImage(), article.getSmallImageURL(), smallFile,
772 images, articleURL, serviceContext);
773 }
774
775 if (smallFile != null) {
776 smallFile.delete();
777 }
778
779 portletDataContext.importClassedModel(
780 article, importedArticle, _NAMESPACE);
781
782 if (Validator.isNull(newArticleId)) {
783 articleIds.put(
784 article.getArticleId(), importedArticle.getArticleId());
785 }
786
787 if (!articleId.equals(importedArticle.getArticleId())) {
788 if (_log.isWarnEnabled()) {
789 _log.warn(
790 "An article with the ID " + articleId + " already " +
791 "exists. The new generated ID is " +
792 importedArticle.getArticleId());
793 }
794 }
795 }
796
797 public static void importFeed(
798 PortletDataContext portletDataContext, Element feedElement)
799 throws Exception {
800
801 String path = feedElement.attributeValue("path");
802
803 if (!portletDataContext.isPathNotProcessed(path)) {
804 return;
805 }
806
807 JournalFeed feed = (JournalFeed)portletDataContext.getZipEntryAsObject(
808 path);
809
810 long userId = portletDataContext.getUserId(feed.getUserUuid());
811
812 JournalCreationStrategy creationStrategy =
813 JournalCreationStrategyFactory.getInstance();
814
815 long authorId = creationStrategy.getAuthorUserId(
816 portletDataContext, feed);
817
818 if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
819 userId = authorId;
820 }
821
822 Group group = GroupLocalServiceUtil.getGroup(
823 portletDataContext.getScopeGroupId());
824
825 String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
826
827 String[] friendlyUrlParts = StringUtil.split(
828 feed.getTargetLayoutFriendlyUrl(), '/');
829
830 String oldGroupFriendlyURL = friendlyUrlParts[2];
831
832 if (oldGroupFriendlyURL.equals("@data_handler_group_friendly_url@")) {
833 feed.setTargetLayoutFriendlyUrl(
834 StringUtil.replace(
835 feed.getTargetLayoutFriendlyUrl(),
836 "@data_handler_group_friendly_url@", newGroupFriendlyURL));
837 }
838
839 String feedId = feed.getFeedId();
840 boolean autoFeedId = false;
841
842 if (Validator.isNumber(feedId) ||
843 (JournalFeedUtil.fetchByG_F(
844 portletDataContext.getScopeGroupId(), feedId) != null)) {
845
846 autoFeedId = true;
847 }
848
849 Map<String, String> structureIds =
850 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
851 JournalStructure.class + ".structureId");
852
853 String parentStructureId = MapUtil.getString(
854 structureIds, feed.getStructureId(), feed.getStructureId());
855
856 Map<String, String> templateIds =
857 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
858 JournalTemplate.class + ".templateId");
859
860 String parentTemplateId = MapUtil.getString(
861 templateIds, feed.getTemplateId(), feed.getTemplateId());
862 String parentRenderTemplateId = MapUtil.getString(
863 templateIds, feed.getRendererTemplateId(),
864 feed.getRendererTemplateId());
865
866 boolean addGroupPermissions = creationStrategy.addGroupPermissions(
867 portletDataContext, feed);
868 boolean addGuestPermissions = creationStrategy.addGuestPermissions(
869 portletDataContext, feed);
870
871 ServiceContext serviceContext = portletDataContext.createServiceContext(
872 feedElement, feed, _NAMESPACE);
873
874 serviceContext.setAddGroupPermissions(addGroupPermissions);
875 serviceContext.setAddGuestPermissions(addGuestPermissions);
876
877 JournalFeed importedFeed = null;
878
879 try {
880 if (portletDataContext.isDataStrategyMirror()) {
881 JournalFeed existingFeed = JournalFeedUtil.fetchByUUID_G(
882 feed.getUuid(), portletDataContext.getScopeGroupId());
883
884 if (existingFeed == null) {
885 serviceContext.setUuid(feed.getUuid());
886
887 importedFeed = JournalFeedLocalServiceUtil.addFeed(
888 userId, portletDataContext.getScopeGroupId(), feedId,
889 autoFeedId, feed.getName(), feed.getDescription(),
890 feed.getType(), parentStructureId, parentTemplateId,
891 parentRenderTemplateId, feed.getDelta(),
892 feed.getOrderByCol(), feed.getOrderByType(),
893 feed.getTargetLayoutFriendlyUrl(),
894 feed.getTargetPortletId(), feed.getContentField(),
895 feed.getFeedType(), feed.getFeedVersion(),
896 serviceContext);
897 }
898 else {
899 importedFeed = JournalFeedLocalServiceUtil.updateFeed(
900 existingFeed.getGroupId(), existingFeed.getFeedId(),
901 feed.getName(), feed.getDescription(), feed.getType(),
902 parentStructureId, parentTemplateId,
903 parentRenderTemplateId, feed.getDelta(),
904 feed.getOrderByCol(), feed.getOrderByType(),
905 feed.getTargetLayoutFriendlyUrl(),
906 feed.getTargetPortletId(), feed.getContentField(),
907 feed.getFeedType(), feed.getFeedVersion(),
908 serviceContext);
909 }
910 }
911 else {
912 importedFeed = JournalFeedLocalServiceUtil.addFeed(
913 userId, portletDataContext.getScopeGroupId(), feedId,
914 autoFeedId, feed.getName(), feed.getDescription(),
915 feed.getType(), parentStructureId, parentTemplateId,
916 parentRenderTemplateId, feed.getDelta(),
917 feed.getOrderByCol(), feed.getOrderByType(),
918 feed.getTargetLayoutFriendlyUrl(),
919 feed.getTargetPortletId(), feed.getContentField(),
920 feed.getFeedType(), feed.getFeedVersion(), serviceContext);
921 }
922
923 portletDataContext.importClassedModel(
924 feed, importedFeed, _NAMESPACE);
925
926 if (!feedId.equals(importedFeed.getFeedId())) {
927 if (_log.isWarnEnabled()) {
928 StringBundler sb = new StringBundler(5);
929
930 sb.append("A feed with the ID ");
931 sb.append(feedId);
932 sb.append(" already exists. The new generated ID is ");
933 sb.append(importedFeed.getFeedId());
934 sb.append(".");
935
936 _log.warn(sb.toString());
937 }
938 }
939 }
940 catch (FeedTargetLayoutFriendlyUrlException ftlfurle) {
941 if (_log.isWarnEnabled()) {
942 StringBundler sb = new StringBundler(6);
943
944 sb.append("A feed with the ID ");
945 sb.append(feedId);
946 sb.append(" cannot be imported because layout with friendly ");
947 sb.append("URL ");
948 sb.append(feed.getTargetLayoutFriendlyUrl());
949 sb.append(" does not exist");
950
951 _log.warn(sb.toString());
952 }
953 }
954 }
955
956 public static String importReferencedContent(
957 PortletDataContext portletDataContext, Element parentElement,
958 String content)
959 throws Exception {
960
961 content = importDLFileEntries(
962 portletDataContext, parentElement, content);
963
964 Group group = GroupLocalServiceUtil.getGroup(
965 portletDataContext.getScopeGroupId());
966
967 content = StringUtil.replace(
968 content, "@data_handler_group_friendly_url@",
969 group.getFriendlyURL());
970
971 content = importLinksToLayout(portletDataContext, content);
972
973 return content;
974 }
975
976 public static void importReferencedData(
977 PortletDataContext portletDataContext, Element entityElement)
978 throws Exception {
979
980 Element dlRepositoriesElement = entityElement.element(
981 "dl-repositories");
982
983 List<Element> dlRepositoryElements = Collections.emptyList();
984
985 if (dlRepositoriesElement != null) {
986 dlRepositoryElements = dlRepositoriesElement.elements("repository");
987 }
988
989 for (Element repositoryElement : dlRepositoryElements) {
990 DLPortletDataHandlerImpl.importRepository(
991 portletDataContext, repositoryElement);
992 }
993
994 Element dlRepositoryEntriesElement = entityElement.element(
995 "dl-repository-entries");
996
997 List<Element> dlRepositoryEntryElements = Collections.emptyList();
998
999 if (dlRepositoryEntriesElement != null) {
1000 dlRepositoryEntryElements = dlRepositoryEntriesElement.elements(
1001 "repository-entry");
1002 }
1003
1004 for (Element repositoryEntryElement : dlRepositoryEntryElements) {
1005 DLPortletDataHandlerImpl.importRepositoryEntry(
1006 portletDataContext, repositoryEntryElement);
1007 }
1008
1009 Element dlFoldersElement = entityElement.element("dl-folders");
1010
1011 List<Element> dlFolderElements = Collections.emptyList();
1012
1013 if (dlFoldersElement != null) {
1014 dlFolderElements = dlFoldersElement.elements("folder");
1015 }
1016
1017 for (Element folderElement : dlFolderElements) {
1018 DLPortletDataHandlerImpl.importFolder(
1019 portletDataContext, folderElement);
1020 }
1021
1022 Element dlFileEntriesElement = entityElement.element("dl-file-entries");
1023
1024 List<Element> dlFileEntryElements = Collections.emptyList();
1025
1026 if (dlFileEntriesElement != null) {
1027 dlFileEntryElements = dlFileEntriesElement.elements("file-entry");
1028 }
1029
1030 for (Element fileEntryElement : dlFileEntryElements) {
1031 DLPortletDataHandlerImpl.importFileEntry(
1032 portletDataContext, fileEntryElement);
1033 }
1034
1035 Element dlFileRanksElement = entityElement.element("dl-file-ranks");
1036
1037 List<Element> dlFileRankElements = Collections.emptyList();
1038
1039 if (dlFileRanksElement != null) {
1040 dlFileRankElements = dlFileRanksElement.elements("file-rank");
1041 }
1042
1043 for (Element fileRankElement : dlFileRankElements) {
1044 DLPortletDataHandlerImpl.importFileRank(
1045 portletDataContext, fileRankElement);
1046 }
1047 }
1048
1049 public static void importStructure(
1050 PortletDataContext portletDataContext, Element structureElement)
1051 throws Exception {
1052
1053 String path = structureElement.attributeValue("path");
1054
1055 if (!portletDataContext.isPathNotProcessed(path)) {
1056 return;
1057 }
1058
1059 JournalStructure structure =
1060 (JournalStructure)portletDataContext.getZipEntryAsObject(path);
1061
1062 long userId = portletDataContext.getUserId(structure.getUserUuid());
1063
1064 JournalCreationStrategy creationStrategy =
1065 JournalCreationStrategyFactory.getInstance();
1066
1067 long authorId = creationStrategy.getAuthorUserId(
1068 portletDataContext, structure);
1069
1070 if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
1071 userId = authorId;
1072 }
1073
1074 String structureId = structure.getStructureId();
1075 boolean autoStructureId = false;
1076
1077 if (Validator.isNumber(structureId) ||
1078 (JournalStructureUtil.fetchByG_S(
1079 portletDataContext.getScopeGroupId(), structureId) != null)) {
1080
1081 autoStructureId = true;
1082 }
1083
1084 Map<String, String> structureIds =
1085 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
1086 JournalStructure.class + ".structureId");
1087
1088 String parentStructureId = MapUtil.getString(
1089 structureIds, structure.getParentStructureId(),
1090 structure.getParentStructureId());
1091
1092 Document document = structureElement.getDocument();
1093
1094 Element rootElement = document.getRootElement();
1095
1096 String parentStructureUuid = GetterUtil.getString(
1097 structureElement.attributeValue("parent-structure-uuid"));
1098
1099 String parentPath = getStructurePath(
1100 portletDataContext, parentStructureUuid);
1101
1102 Element parentStructureElement = (Element)rootElement.selectSingleNode(
1103 "
1104
1105 if ((parentStructureElement != null) &&
1106 Validator.isNotNull(parentStructureId)) {
1107
1108 importStructure(portletDataContext, parentStructureElement);
1109
1110 parentStructureId = structureIds.get(parentStructureId);
1111 }
1112
1113 boolean addGroupPermissions = creationStrategy.addGroupPermissions(
1114 portletDataContext, structure);
1115 boolean addGuestPermissions = creationStrategy.addGuestPermissions(
1116 portletDataContext, structure);
1117
1118 ServiceContext serviceContext = portletDataContext.createServiceContext(
1119 structureElement, structure, _NAMESPACE);
1120
1121 serviceContext.setAddGroupPermissions(addGroupPermissions);
1122 serviceContext.setAddGuestPermissions(addGuestPermissions);
1123
1124 JournalStructure importedStructure = null;
1125
1126 if (portletDataContext.isDataStrategyMirror()) {
1127 JournalStructure existingStructure =
1128 JournalStructureUtil.fetchByUUID_G(
1129 structure.getUuid(), portletDataContext.getScopeGroupId());
1130
1131 if (existingStructure == null) {
1132 Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
1133 portletDataContext.getCompanyId());
1134
1135 long companyGroupId = companyGroup.getGroupId();
1136
1137 existingStructure = JournalStructureUtil.fetchByUUID_G(
1138 structure.getUuid(), companyGroupId);
1139 }
1140
1141 if (existingStructure == null) {
1142 serviceContext.setUuid(structure.getUuid());
1143
1144 importedStructure =
1145 JournalStructureLocalServiceUtil.addStructure(
1146 userId, portletDataContext.getScopeGroupId(),
1147 structureId, autoStructureId, parentStructureId,
1148 structure.getNameMap(), structure.getDescriptionMap(),
1149 structure.getXsd(), serviceContext);
1150 }
1151 else {
1152 importedStructure =
1153 JournalStructureLocalServiceUtil.updateStructure(
1154 existingStructure.getGroupId(),
1155 existingStructure.getStructureId(), parentStructureId,
1156 structure.getNameMap(), structure.getDescriptionMap(),
1157 structure.getXsd(), serviceContext);
1158 }
1159 }
1160 else {
1161 importedStructure = JournalStructureLocalServiceUtil.addStructure(
1162 userId, portletDataContext.getScopeGroupId(), structureId,
1163 autoStructureId, parentStructureId, structure.getNameMap(),
1164 structure.getDescriptionMap(), structure.getXsd(),
1165 serviceContext);
1166 }
1167
1168 portletDataContext.importClassedModel(
1169 structure, importedStructure, _NAMESPACE);
1170
1171 structureIds.put(structureId, importedStructure.getStructureId());
1172
1173 if (!structureId.equals(importedStructure.getStructureId())) {
1174 if (_log.isWarnEnabled()) {
1175 _log.warn(
1176 "A structure with the ID " + structureId + " already " +
1177 "exists. The new generated ID is " +
1178 importedStructure.getStructureId());
1179 }
1180 }
1181 }
1182
1183 public static void importTemplate(
1184 PortletDataContext portletDataContext, Element templateElement)
1185 throws Exception {
1186
1187 String path = templateElement.attributeValue("path");
1188
1189 if (!portletDataContext.isPathNotProcessed(path)) {
1190 return;
1191 }
1192
1193 JournalTemplate template =
1194 (JournalTemplate)portletDataContext.getZipEntryAsObject(path);
1195
1196 long userId = portletDataContext.getUserId(template.getUserUuid());
1197
1198 JournalCreationStrategy creationStrategy =
1199 JournalCreationStrategyFactory.getInstance();
1200
1201 long authorId = creationStrategy.getAuthorUserId(
1202 portletDataContext, template);
1203
1204 if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
1205 userId = authorId;
1206 }
1207
1208 String templateId = template.getTemplateId();
1209 boolean autoTemplateId = false;
1210
1211 if (Validator.isNumber(templateId) ||
1212 (JournalTemplateUtil.fetchByG_T(
1213 portletDataContext.getScopeGroupId(), templateId) != null)) {
1214
1215 autoTemplateId = true;
1216 }
1217
1218 Map<String, String> structureIds =
1219 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
1220 JournalStructure.class + ".structureId");
1221
1222 String parentStructureId = MapUtil.getString(
1223 structureIds, template.getStructureId(), template.getStructureId());
1224
1225 String xsl = template.getXsl();
1226
1227 xsl = importDLFileEntries(portletDataContext, templateElement, xsl);
1228
1229 Group group = GroupLocalServiceUtil.getGroup(
1230 portletDataContext.getScopeGroupId());
1231
1232 xsl = StringUtil.replace(
1233 xsl, "@data_handler_group_friendly_url@", group.getFriendlyURL());
1234
1235 template.setXsl(xsl);
1236
1237 boolean formatXsl = false;
1238
1239 boolean addGroupPermissions = creationStrategy.addGroupPermissions(
1240 portletDataContext, template);
1241 boolean addGuestPermissions = creationStrategy.addGuestPermissions(
1242 portletDataContext, template);
1243
1244 ServiceContext serviceContext = portletDataContext.createServiceContext(
1245 templateElement, template, _NAMESPACE);
1246
1247 serviceContext.setAddGroupPermissions(addGroupPermissions);
1248 serviceContext.setAddGuestPermissions(addGuestPermissions);
1249
1250 File smallFile = null;
1251
1252 String smallImagePath = templateElement.attributeValue(
1253 "small-image-path");
1254
1255 if (template.isSmallImage() && Validator.isNotNull(smallImagePath)) {
1256 if (smallImagePath.endsWith(StringPool.PERIOD)) {
1257 smallImagePath += template.getSmallImageType();
1258 }
1259
1260 byte[] bytes = portletDataContext.getZipEntryAsByteArray(
1261 smallImagePath);
1262
1263 if (bytes != null) {
1264 smallFile = FileUtil.createTempFile(
1265 template.getSmallImageType());
1266
1267 FileUtil.write(smallFile, bytes);
1268 }
1269 }
1270
1271 JournalTemplate importedTemplate = null;
1272
1273 if (portletDataContext.isDataStrategyMirror()) {
1274 JournalTemplate existingTemplate =
1275 JournalTemplateUtil.fetchByUUID_G(
1276 template.getUuid(), portletDataContext.getScopeGroupId());
1277
1278 if (existingTemplate == null) {
1279 Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
1280 portletDataContext.getCompanyId());
1281
1282 long companyGroupId = companyGroup.getGroupId();
1283
1284 existingTemplate = JournalTemplateUtil.fetchByUUID_G(
1285 template.getUuid(), companyGroupId);
1286 }
1287
1288 if (existingTemplate == null) {
1289 serviceContext.setUuid(template.getUuid());
1290
1291 importedTemplate = JournalTemplateLocalServiceUtil.addTemplate(
1292 userId, portletDataContext.getScopeGroupId(), templateId,
1293 autoTemplateId, parentStructureId, template.getNameMap(),
1294 template.getDescriptionMap(), template.getXsl(), formatXsl,
1295 template.getLangType(), template.getCacheable(),
1296 template.isSmallImage(), template.getSmallImageURL(),
1297 smallFile, serviceContext);
1298 }
1299 else {
1300 String structureId = existingTemplate.getStructureId();
1301
1302 if (Validator.isNull(structureId) &&
1303 Validator.isNotNull(template.getStructureId())) {
1304
1305 JournalStructure structure =
1306 JournalStructureUtil.fetchByG_S(
1307 template.getGroupId(), template.getStructureId());
1308
1309 if (structure == null) {
1310 structureId = template.getStructureId();
1311 }
1312 else {
1313 JournalStructure existingStructure =
1314 JournalStructureUtil.findByUUID_G(
1315 structure.getUuid(),
1316 portletDataContext.getScopeGroupId());
1317
1318 structureId = existingStructure.getStructureId();
1319 }
1320 }
1321
1322 importedTemplate =
1323 JournalTemplateLocalServiceUtil.updateTemplate(
1324 existingTemplate.getGroupId(),
1325 existingTemplate.getTemplateId(), structureId,
1326 template.getNameMap(), template.getDescriptionMap(),
1327 template.getXsl(), formatXsl, template.getLangType(),
1328 template.getCacheable(), template.isSmallImage(),
1329 template.getSmallImageURL(), smallFile, serviceContext);
1330 }
1331 }
1332 else {
1333 importedTemplate = JournalTemplateLocalServiceUtil.addTemplate(
1334 userId, portletDataContext.getScopeGroupId(), templateId,
1335 autoTemplateId, parentStructureId, template.getNameMap(),
1336 template.getDescriptionMap(), template.getXsl(), formatXsl,
1337 template.getLangType(), template.getCacheable(),
1338 template.isSmallImage(), template.getSmallImageURL(), smallFile,
1339 serviceContext);
1340 }
1341
1342 if (smallFile != null) {
1343 smallFile.delete();
1344 }
1345
1346 portletDataContext.importClassedModel(
1347 template, importedTemplate, _NAMESPACE);
1348
1349 Map<String, String> templateIds =
1350 (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
1351 JournalTemplate.class + ".templateId");
1352
1353 templateIds.put(
1354 template.getTemplateId(), importedTemplate.getTemplateId());
1355
1356 if (!templateId.equals(importedTemplate.getTemplateId())) {
1357 if (_log.isWarnEnabled()) {
1358 _log.warn(
1359 "A template with the ID " + templateId + " already " +
1360 "exists. The new generated ID is " +
1361 importedTemplate.getTemplateId());
1362 }
1363 }
1364 }
1365
1366 @Override
1367 public PortletDataHandlerControl[] getExportControls() {
1368 return new PortletDataHandlerControl[] {
1369 _articles, _structuresTemplatesAndFeeds, _embeddedAssets,
1370 _versionHistory
1371 };
1372 }
1373
1374 @Override
1375 public PortletDataHandlerControl[] getExportMetadataControls() {
1376 return new PortletDataHandlerControl[] {
1377 new PortletDataHandlerBoolean(
1378 _NAMESPACE, "web-content", true, _metadataControls)
1379 };
1380 }
1381
1382 @Override
1383 public PortletDataHandlerControl[] getImportControls() {
1384 return new PortletDataHandlerControl[] {
1385 _articles, _structuresTemplatesAndFeeds
1386 };
1387 }
1388
1389 @Override
1390 public PortletDataHandlerControl[] getImportMetadataControls() {
1391 return new PortletDataHandlerControl[] {
1392 new PortletDataHandlerBoolean(
1393 _NAMESPACE, "web-content", true, _metadataControls)
1394 };
1395 }
1396
1397 @Override
1398 public boolean isAlwaysExportable() {
1399 return _ALWAYS_EXPORTABLE;
1400 }
1401
1402 @Override
1403 public boolean isDataLocalized() {
1404 return _DATA_LOCALIZED;
1405 }
1406
1407 @Override
1408 public boolean isPublishToLiveByDefault() {
1409 return PropsValues.JOURNAL_PUBLISH_TO_LIVE_BY_DEFAULT;
1410 }
1411
1412 protected static String exportDLFileEntries(
1413 PortletDataContext portletDataContext,
1414 Element dlFileEntryTypesElement, Element dlFoldersElement,
1415 Element dlFileEntriesElement, Element dlFileRanksElement,
1416 Element dlRepositoriesElement, Element dlRepositoryEntriesElement,
1417 Element entityElement, String content, boolean checkDateRange)
1418 throws Exception {
1419
1420 Group group = GroupLocalServiceUtil.getGroup(
1421 portletDataContext.getGroupId());
1422
1423 if (group.isStagingGroup()) {
1424 group = group.getLiveGroup();
1425 }
1426
1427 if (group.isStaged() && !group.isStagedRemotely() &&
1428 !group.isStagedPortlet(PortletKeys.DOCUMENT_LIBRARY)) {
1429
1430 return content;
1431 }
1432
1433 StringBuilder sb = new StringBuilder(content);
1434
1435 int beginPos = content.length();
1436 int currentLocation = -1;
1437
1438 boolean legacyURL = true;
1439
1440 while (true) {
1441 currentLocation = content.lastIndexOf(
1442 "/c/document_library/get_file?", beginPos);
1443
1444 if (currentLocation == -1) {
1445 currentLocation = content.lastIndexOf(
1446 "/image/image_gallery?", beginPos);
1447 }
1448
1449 if (currentLocation == -1) {
1450 currentLocation = content.lastIndexOf("/documents/", beginPos);
1451
1452 legacyURL = false;
1453 }
1454
1455 if (currentLocation == -1) {
1456 return sb.toString();
1457 }
1458
1459 beginPos = currentLocation;
1460
1461 int endPos1 = content.indexOf(CharPool.APOSTROPHE, beginPos);
1462 int endPos2 = content.indexOf(CharPool.CLOSE_BRACKET, beginPos);
1463 int endPos3 = content.indexOf(CharPool.CLOSE_CURLY_BRACE, beginPos);
1464 int endPos4 = content.indexOf(CharPool.CLOSE_PARENTHESIS, beginPos);
1465 int endPos5 = content.indexOf(CharPool.LESS_THAN, beginPos);
1466 int endPos6 = content.indexOf(CharPool.QUESTION, beginPos);
1467 int endPos7 = content.indexOf(CharPool.QUOTE, beginPos);
1468 int endPos8 = content.indexOf(CharPool.SPACE, beginPos);
1469
1470 int endPos = endPos1;
1471
1472 if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
1473 endPos = endPos2;
1474 }
1475
1476 if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
1477 endPos = endPos3;
1478 }
1479
1480 if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
1481 endPos = endPos4;
1482 }
1483
1484 if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
1485 endPos = endPos5;
1486 }
1487
1488 if ((endPos == -1) ||
1489 ((endPos6 != -1) && (endPos6 < endPos) && !legacyURL)) {
1490
1491 endPos = endPos6;
1492 }
1493
1494 if ((endPos == -1) || ((endPos7 != -1) && (endPos7 < endPos))) {
1495 endPos = endPos7;
1496 }
1497
1498 if ((endPos == -1) || ((endPos8 != -1) && (endPos8 < endPos))) {
1499 endPos = endPos8;
1500 }
1501
1502 if ((beginPos == -1) || (endPos == -1)) {
1503 break;
1504 }
1505
1506 try {
1507 String oldParameters = content.substring(beginPos, endPos);
1508
1509 while (oldParameters.contains(StringPool.AMPERSAND_ENCODED)) {
1510 oldParameters = oldParameters.replace(
1511 StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
1512 }
1513
1514 Map<String, String[]> map = new HashMap<String, String[]>();
1515
1516 if (oldParameters.startsWith("/documents/")) {
1517 String[] pathArray = oldParameters.split(StringPool.SLASH);
1518
1519 map.put("groupId", new String[] {pathArray[2]});
1520
1521 if (pathArray.length == 4) {
1522 map.put("uuid", new String[] {pathArray[3]});
1523 }
1524 else if (pathArray.length == 5) {
1525 map.put("folderId", new String[] {pathArray[3]});
1526
1527 String title = HttpUtil.decodeURL(pathArray[4]);
1528
1529 int pos = title.indexOf(StringPool.QUESTION);
1530
1531 if (pos != -1) {
1532 title = title.substring(0, pos);
1533 }
1534
1535 map.put("title", new String[] {title});
1536 }
1537 else if (pathArray.length > 5) {
1538 String uuid = pathArray[5];
1539
1540 int pos = uuid.indexOf(StringPool.QUESTION);
1541
1542 if (pos != -1) {
1543 uuid = uuid.substring(0, pos);
1544 }
1545
1546 map.put("uuid", new String[] {uuid});
1547 }
1548 }
1549 else {
1550 oldParameters = oldParameters.substring(
1551 oldParameters.indexOf(CharPool.QUESTION) + 1);
1552
1553 map = HttpUtil.parameterMapFromString(oldParameters);
1554 }
1555
1556 FileEntry fileEntry = null;
1557
1558 String uuid = MapUtil.getString(map, "uuid");
1559
1560 if (Validator.isNotNull(uuid)) {
1561 String groupIdString = MapUtil.getString(map, "groupId");
1562
1563 long groupId = GetterUtil.getLong(groupIdString);
1564
1565 if (groupIdString.equals("@group_id@")) {
1566 groupId = portletDataContext.getScopeGroupId();
1567 }
1568
1569 fileEntry =
1570 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1571 uuid, groupId);
1572 }
1573 else {
1574 String folderIdString = MapUtil.getString(map, "folderId");
1575
1576 if (Validator.isNotNull(folderIdString)) {
1577 long folderId = GetterUtil.getLong(folderIdString);
1578 String name = MapUtil.getString(map, "name");
1579 String title = MapUtil.getString(map, "title");
1580
1581 String groupIdString = MapUtil.getString(
1582 map, "groupId");
1583
1584 long groupId = GetterUtil.getLong(groupIdString);
1585
1586 if (groupIdString.equals("@group_id@")) {
1587 groupId = portletDataContext.getScopeGroupId();
1588 }
1589
1590 if (Validator.isNotNull(title)) {
1591 fileEntry = DLAppLocalServiceUtil.getFileEntry(
1592 groupId, folderId, title);
1593 }
1594 else {
1595 DLFileEntry dlFileEntry =
1596 DLFileEntryLocalServiceUtil.getFileEntryByName(
1597 groupId, folderId, name);
1598
1599 fileEntry = new LiferayFileEntry(dlFileEntry);
1600 }
1601 }
1602 else if (map.containsKey("image_id") ||
1603 map.containsKey("img_id") ||
1604 map.containsKey("i_id")) {
1605
1606 long imageId = MapUtil.getLong(map, "image_id");
1607
1608 if (imageId <= 0) {
1609 imageId = MapUtil.getLong(map, "img_id");
1610
1611 if (imageId <= 0) {
1612 imageId = MapUtil.getLong(map, "i_id");
1613 }
1614 }
1615
1616 DLFileEntry dlFileEntry =
1617 DLFileEntryLocalServiceUtil.
1618 fetchFileEntryByAnyImageId(imageId);
1619
1620 if (dlFileEntry != null) {
1621 fileEntry = new LiferayFileEntry(dlFileEntry);
1622 }
1623 }
1624 }
1625
1626 if (fileEntry == null) {
1627 beginPos--;
1628
1629 continue;
1630 }
1631
1632 DLPortletDataHandlerImpl.exportFileEntry(
1633 portletDataContext, dlFileEntryTypesElement,
1634 dlFoldersElement, dlFileEntriesElement, dlFileRanksElement,
1635 dlRepositoriesElement, dlRepositoryEntriesElement,
1636 fileEntry, checkDateRange);
1637
1638 Element dlReferenceElement = entityElement.addElement(
1639 "dl-reference");
1640
1641 dlReferenceElement.addAttribute(
1642 "default-repository",
1643 String.valueOf(fileEntry.isDefaultRepository()));
1644
1645 String path = null;
1646
1647 if (fileEntry.isDefaultRepository()) {
1648 path = DLPortletDataHandlerImpl.getFileEntryPath(
1649 portletDataContext, fileEntry);
1650
1651 }
1652 else {
1653 path = DLPortletDataHandlerImpl.getRepositoryEntryPath(
1654 portletDataContext, fileEntry.getFileEntryId());
1655 }
1656
1657 dlReferenceElement.addAttribute("path", path);
1658
1659 String dlReference = "[$dl-reference=" + path + "$]";
1660
1661 sb.replace(beginPos, endPos, dlReference);
1662 }
1663 catch (Exception e) {
1664 if (_log.isDebugEnabled()) {
1665 _log.debug(e, e);
1666 }
1667 else if (_log.isWarnEnabled()) {
1668 _log.warn(e.getMessage());
1669 }
1670 }
1671
1672 beginPos--;
1673 }
1674
1675 return sb.toString();
1676 }
1677
1678 protected static void exportFeed(
1679 PortletDataContext portletDataContext, Element feedsElement,
1680 JournalFeed feed)
1681 throws Exception {
1682
1683 if (!portletDataContext.isWithinDateRange(feed.getModifiedDate())) {
1684 return;
1685 }
1686
1687 String path = getFeedPath(portletDataContext, feed);
1688
1689 if (!portletDataContext.isPathNotProcessed(path)) {
1690 return;
1691 }
1692
1693 feed = (JournalFeed)feed.clone();
1694
1695 Element feedElement = feedsElement.addElement("feed");
1696
1697 Group group = GroupLocalServiceUtil.getGroup(
1698 portletDataContext.getScopeGroupId());
1699
1700 String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
1701
1702 String[] friendlyUrlParts = StringUtil.split(
1703 feed.getTargetLayoutFriendlyUrl(), '/');
1704
1705 String oldGroupFriendlyURL = friendlyUrlParts[2];
1706
1707 if (newGroupFriendlyURL.equals(oldGroupFriendlyURL)) {
1708 String targetLayoutFriendlyUrl = StringUtil.replaceFirst(
1709 feed.getTargetLayoutFriendlyUrl(),
1710 StringPool.SLASH + newGroupFriendlyURL + StringPool.SLASH,
1711 "/@data_handler_group_friendly_url@/");
1712
1713 feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
1714 }
1715
1716 portletDataContext.addClassedModel(feedElement, path, feed, _NAMESPACE);
1717 }
1718
1719 protected static void exportFolder(
1720 PortletDataContext portletDataContext, Element foldersElement,
1721 Element articlesElement, Element structuresElement,
1722 Element templatesElement, Element dlFileEntryTypesElement,
1723 Element dlFoldersElement, Element dlFileEntriesElement,
1724 Element dlFileRanksElement, Element dlRepositoriesElement,
1725 Element dlRepositoryEntriesElement, JournalFolder folder,
1726 boolean checkDateRange)
1727 throws Exception {
1728
1729 if (checkDateRange &&
1730 !portletDataContext.isWithinDateRange(folder.getModifiedDate())) {
1731
1732 return;
1733 }
1734
1735 exportParentFolder(
1736 portletDataContext, foldersElement, folder.getParentFolderId());
1737
1738 String path = getFolderPath(portletDataContext, folder);
1739
1740 if (portletDataContext.isPathNotProcessed(path)) {
1741 Element folderElement = foldersElement.addElement("folder");
1742
1743 portletDataContext.addClassedModel(
1744 folderElement, path, folder, _NAMESPACE);
1745 }
1746
1747 List<JournalArticle> articles = JournalArticleUtil.findByG_F(
1748 folder.getGroupId(), folder.getFolderId());
1749
1750 for (JournalArticle article : articles) {
1751 exportArticle(
1752 portletDataContext, articlesElement, structuresElement,
1753 templatesElement, dlFileEntryTypesElement, dlFoldersElement,
1754 dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
1755 dlRepositoryEntriesElement, article, true);
1756 }
1757 }
1758
1759 protected static String exportLayoutFriendlyURLs(
1760 PortletDataContext portletDataContext, String content) {
1761
1762 Group group = null;
1763
1764 try {
1765 group = GroupLocalServiceUtil.getGroup(
1766 portletDataContext.getScopeGroupId());
1767 }
1768 catch (Exception e) {
1769 if (_log.isWarnEnabled()) {
1770 _log.warn(e);
1771 }
1772
1773 return content;
1774 }
1775
1776 StringBuilder sb = new StringBuilder(content);
1777
1778 String friendlyURLPrivateGroupPath =
1779 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
1780 String friendlyURLPrivateUserPath =
1781 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
1782 String friendlyURLPublicPath =
1783 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
1784
1785 String href = "href=";
1786
1787 int beginPos = content.length();
1788
1789 while (true) {
1790 int hrefLength = href.length();
1791
1792 beginPos = content.lastIndexOf(href, beginPos);
1793
1794 if (beginPos == -1) {
1795 break;
1796 }
1797
1798 char c = content.charAt(beginPos + hrefLength);
1799
1800 if ((c == CharPool.APOSTROPHE) || (c == CharPool.QUOTE)) {
1801 hrefLength++;
1802 }
1803
1804 int endPos1 = content.indexOf(
1805 CharPool.APOSTROPHE, beginPos + hrefLength);
1806 int endPos2 = content.indexOf(
1807 CharPool.CLOSE_BRACKET, beginPos + hrefLength);
1808 int endPos3 = content.indexOf(
1809 CharPool.CLOSE_CURLY_BRACE, beginPos + hrefLength);
1810 int endPos4 = content.indexOf(
1811 CharPool.CLOSE_PARENTHESIS, beginPos + hrefLength);
1812 int endPos5 = content.indexOf(
1813 CharPool.LESS_THAN, beginPos + hrefLength);
1814 int endPos6 = content.indexOf(
1815 CharPool.QUESTION, beginPos + hrefLength);
1816 int endPos7 = content.indexOf(
1817 CharPool.QUOTE, beginPos + hrefLength);
1818 int endPos8 = content.indexOf(
1819 CharPool.SPACE, beginPos + hrefLength);
1820
1821 int endPos = endPos1;
1822
1823 if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
1824 endPos = endPos2;
1825 }
1826
1827 if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
1828 endPos = endPos3;
1829 }
1830
1831 if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
1832 endPos = endPos4;
1833 }
1834
1835 if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
1836 endPos = endPos5;
1837 }
1838
1839 if ((endPos == -1) || ((endPos6 != -1) && (endPos6 < endPos))) {
1840 endPos = endPos6;
1841 }
1842
1843 if ((endPos == -1) || ((endPos7 != -1) && (endPos7 < endPos))) {
1844 endPos = endPos7;
1845 }
1846
1847 if ((endPos == -1) || ((endPos8 != -1) && (endPos8 < endPos))) {
1848 endPos = endPos8;
1849 }
1850
1851 if (endPos == -1) {
1852 beginPos--;
1853
1854 continue;
1855 }
1856
1857 String url = content.substring(beginPos + hrefLength, endPos);
1858
1859 if (!url.startsWith(friendlyURLPrivateGroupPath) &&
1860 !url.startsWith(friendlyURLPrivateUserPath) &&
1861 !url.startsWith(friendlyURLPublicPath)) {
1862
1863 beginPos--;
1864
1865 continue;
1866 }
1867
1868 int beginGroupPos = content.indexOf(
1869 CharPool.SLASH, beginPos + hrefLength + 1);
1870
1871 if (beginGroupPos == -1) {
1872 beginPos--;
1873
1874 continue;
1875 }
1876
1877 int endGroupPos = content.indexOf(
1878 CharPool.SLASH, beginGroupPos + 1);
1879
1880 if (endGroupPos == -1) {
1881 beginPos--;
1882
1883 continue;
1884 }
1885
1886 String groupFriendlyURL = content.substring(
1887 beginGroupPos, endGroupPos);
1888
1889 if (groupFriendlyURL.equals(group.getFriendlyURL())) {
1890 sb.replace(
1891 beginGroupPos, endGroupPos,
1892 "@data_handler_group_friendly_url@");
1893 }
1894
1895 beginPos--;
1896 }
1897
1898 return sb.toString();
1899 }
1900
1901 protected static String exportLinksToLayout(
1902 PortletDataContext portletDataContext, String content)
1903 throws Exception {
1904
1905 List<String> oldLinksToLayout = new ArrayList<String>();
1906 List<String> newLinksToLayout = new ArrayList<String>();
1907
1908 Matcher matcher = _exportLinksToLayoutPattern.matcher(content);
1909
1910 while (matcher.find()) {
1911 long layoutId = GetterUtil.getLong(matcher.group(1));
1912
1913 String type = matcher.group(2);
1914
1915 boolean privateLayout = type.startsWith("private");
1916
1917 try {
1918 Layout layout = LayoutLocalServiceUtil.getLayout(
1919 portletDataContext.getScopeGroupId(), privateLayout,
1920 layoutId);
1921
1922 String oldLinkToLayout = matcher.group(0);
1923
1924 StringBundler sb = new StringBundler(5);
1925
1926 sb.append(type);
1927 sb.append(StringPool.AT);
1928 sb.append(layout.getUuid());
1929 sb.append(StringPool.AT);
1930 sb.append(layout.getFriendlyURL());
1931
1932 String newLinkToLayout = StringUtil.replace(
1933 oldLinkToLayout, type, sb.toString());
1934
1935 oldLinksToLayout.add(oldLinkToLayout);
1936 newLinksToLayout.add(newLinkToLayout);
1937 }
1938 catch (Exception e) {
1939 if (_log.isDebugEnabled() || _log.isWarnEnabled()) {
1940 String message =
1941 "Unable to get layout with ID " + layoutId +
1942 " in group " + portletDataContext.getScopeGroupId();
1943
1944 if (_log.isWarnEnabled()) {
1945 _log.warn(message);
1946 }
1947 else {
1948 _log.debug(message, e);
1949 }
1950 }
1951 }
1952 }
1953
1954 content = StringUtil.replace(
1955 content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
1956 ArrayUtil.toStringArray(newLinksToLayout.toArray()));
1957
1958 return content;
1959 }
1960
1961 protected static void exportParentFolder(
1962 PortletDataContext portletDataContext, Element foldersElement,
1963 long folderId)
1964 throws Exception {
1965
1966 if (folderId == JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1967 return;
1968 }
1969
1970 JournalFolder folder = JournalFolderUtil.findByPrimaryKey(folderId);
1971
1972 exportParentFolder(
1973 portletDataContext, foldersElement, folder.getParentFolderId());
1974
1975 String path = getFolderPath(portletDataContext, folder);
1976
1977 if (portletDataContext.isPathNotProcessed(path)) {
1978 Element folderElement = foldersElement.addElement("folder");
1979
1980 portletDataContext.addClassedModel(
1981 folderElement, path, folder, _NAMESPACE);
1982 }
1983 }
1984
1985 protected static void exportStructure(
1986 PortletDataContext portletDataContext, Element structuresElement,
1987 JournalStructure structure)
1988 throws Exception {
1989
1990 String path = getStructurePath(portletDataContext, structure.getUuid());
1991
1992 if (!portletDataContext.isPathNotProcessed(path)) {
1993 return;
1994 }
1995
1996 JournalStructure parentStructure = null;
1997
1998 String parentStructureId = structure.getParentStructureId();
1999
2000 if (Validator.isNotNull(parentStructureId)) {
2001 try {
2002 parentStructure =
2003 JournalStructureLocalServiceUtil.getStructure(
2004 structure.getGroupId(), parentStructureId, true);
2005
2006 exportStructure(
2007 portletDataContext, structuresElement, parentStructure);
2008 }
2009 catch (NoSuchStructureException nsse) {
2010 }
2011 }
2012
2013 Element structureElement = structuresElement.addElement("structure");
2014
2015 if (parentStructure != null) {
2016 structureElement.addAttribute(
2017 "parent-structure-uuid", parentStructure.getUuid());
2018 }
2019
2020 portletDataContext.addClassedModel(
2021 structureElement, path, structure, _NAMESPACE);
2022 }
2023
2024 protected static void exportTemplate(
2025 PortletDataContext portletDataContext, Element templatesElement,
2026 Element dlFileEntryTypesElement, Element dlFoldersElement,
2027 Element dlFileEntriesElement, Element dlFileRanksElement,
2028 Element dlRepositoriesElement, Element dlRepositoryEntriesElement,
2029 JournalTemplate template)
2030 throws Exception {
2031
2032 String path = getTemplatePath(portletDataContext, template);
2033
2034 if (!portletDataContext.isPathNotProcessed(path)) {
2035 return;
2036 }
2037
2038
2039
2040
2041 template = (JournalTemplate)template.clone();
2042
2043 Element templateElement = templatesElement.addElement("template");
2044
2045 if (template.isSmallImage()) {
2046 String smallImagePath = getTemplateSmallImagePath(
2047 portletDataContext, template);
2048
2049 templateElement.addAttribute("small-image-path", smallImagePath);
2050
2051 Image smallImage = ImageUtil.fetchByPrimaryKey(
2052 template.getSmallImageId());
2053
2054 template.setSmallImageType(smallImage.getType());
2055
2056 portletDataContext.addZipEntry(
2057 smallImagePath, smallImage.getTextObj());
2058 }
2059
2060 if (portletDataContext.getBooleanParameter(
2061 _NAMESPACE, "embedded-assets")) {
2062
2063 String content = exportReferencedContent(
2064 portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
2065 dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
2066 dlRepositoryEntriesElement, templateElement, template.getXsl());
2067
2068 template.setXsl(content);
2069 }
2070
2071 portletDataContext.addClassedModel(
2072 templateElement, path, template, _NAMESPACE);
2073 }
2074
2075 protected static String getArticleImagePath(
2076 PortletDataContext portletDataContext, JournalArticle article)
2077 throws Exception {
2078
2079 StringBundler sb = new StringBundler(6);
2080
2081 sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2082 sb.append("/articles/");
2083 sb.append(article.getArticleResourceUuid());
2084 sb.append(StringPool.SLASH);
2085 sb.append(article.getVersion());
2086 sb.append(StringPool.SLASH);
2087
2088 return sb.toString();
2089 }
2090
2091 protected static String getArticleImagePath(
2092 PortletDataContext portletDataContext, JournalArticle article,
2093 JournalArticleImage articleImage, Image image)
2094 throws Exception {
2095
2096 StringBundler sb = new StringBundler(12);
2097
2098 sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2099 sb.append("/articles/");
2100 sb.append(article.getArticleResourceUuid());
2101 sb.append(StringPool.SLASH);
2102 sb.append(article.getVersion());
2103 sb.append(StringPool.SLASH);
2104 sb.append(articleImage.getElInstanceId());
2105 sb.append(StringPool.UNDERLINE);
2106 sb.append(articleImage.getElName());
2107
2108 if (Validator.isNotNull(articleImage.getLanguageId())) {
2109 sb.append(articleImage.getLanguageId());
2110 }
2111
2112 sb.append(StringPool.PERIOD);
2113 sb.append(image.getType());
2114
2115 return sb.toString();
2116 }
2117
2118 protected static String getArticleSmallImagePath(
2119 PortletDataContext portletDataContext, JournalArticle article)
2120 throws Exception {
2121
2122 StringBundler sb = new StringBundler(6);
2123
2124 sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2125 sb.append("/articles/");
2126 sb.append(article.getArticleResourceUuid());
2127 sb.append("/thumbnail");
2128 sb.append(StringPool.PERIOD);
2129 sb.append(article.getSmallImageType());
2130
2131 return sb.toString();
2132 }
2133
2134 protected static String getFeedPath(
2135 PortletDataContext portletDataContext, JournalFeed feed) {
2136
2137 StringBundler sb = new StringBundler(4);
2138
2139 sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2140 sb.append("/feeds/");
2141 sb.append(feed.getUuid());
2142 sb.append(".xml");
2143
2144 return sb.toString();
2145 }
2146
2147 protected static String getFolderPath(
2148 PortletDataContext portletDataContext, JournalFolder folder) {
2149
2150 StringBundler sb = new StringBundler(4);
2151
2152 sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2153 sb.append("/folders/");
2154 sb.append(folder.getFolderId());
2155 sb.append(".xml");
2156
2157 return sb.toString();
2158 }
2159
2160 protected static String getImportFolderPath(
2161 PortletDataContext portletDataContext, long folderId) {
2162
2163 StringBundler sb = new StringBundler(4);
2164
2165 sb.append(portletDataContext.getSourcePortletPath(PortletKeys.JOURNAL));
2166 sb.append("/folders/");
2167 sb.append(folderId);
2168 sb.append(".xml");
2169
2170 return sb.toString();
2171 }
2172
2173 protected static String getStructurePath(
2174 PortletDataContext portletDataContext, String uuid) {
2175
2176 StringBundler sb = new StringBundler(4);
2177
2178 sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2179 sb.append("/structures/");
2180 sb.append(uuid);
2181 sb.append(".xml");
2182
2183 return sb.toString();
2184 }
2185
2186 protected static String getTemplatePath(
2187 PortletDataContext portletDataContext, JournalTemplate template) {
2188
2189 StringBundler sb = new StringBundler(4);
2190
2191 sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2192 sb.append("/templates/");
2193 sb.append(template.getUuid());
2194 sb.append(".xml");
2195
2196 return sb.toString();
2197 }
2198
2199 protected static String getTemplateSmallImagePath(
2200 PortletDataContext portletDataContext, JournalTemplate template)
2201 throws Exception {
2202
2203 StringBundler sb = new StringBundler(5);
2204
2205 sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2206 sb.append("/templates/thumbnail-");
2207 sb.append(template.getUuid());
2208 sb.append(StringPool.PERIOD);
2209 sb.append(template.getSmallImageType());
2210
2211 return sb.toString();
2212 }
2213
2214 protected static String importDLFileEntries(
2215 PortletDataContext portletDataContext, Element parentElement,
2216 String content)
2217 throws Exception {
2218
2219 List<Element> dlReferenceElements = parentElement.elements(
2220 "dl-reference");
2221
2222 for (Element dlReferenceElement : dlReferenceElements) {
2223 String dlReferencePath = dlReferenceElement.attributeValue("path");
2224
2225 String fileEntryUUID = null;
2226
2227 try {
2228 Object zipEntryObject = portletDataContext.getZipEntryAsObject(
2229 dlReferencePath);
2230
2231 if (zipEntryObject == null) {
2232 if (_log.isWarnEnabled()) {
2233 _log.warn("Unable to reference " + dlReferencePath);
2234 }
2235
2236 continue;
2237 }
2238
2239 boolean defaultRepository = GetterUtil.getBoolean(
2240 dlReferenceElement.attributeValue("default-repository"));
2241
2242 if (defaultRepository) {
2243 FileEntry fileEntry = (FileEntry)zipEntryObject;
2244
2245 fileEntryUUID = fileEntry.getUuid();
2246 }
2247 else {
2248 RepositoryEntry repositoryEntry =
2249 (RepositoryEntry)zipEntryObject;
2250
2251 fileEntryUUID = repositoryEntry.getUuid();
2252 }
2253 }
2254 catch (Exception e) {
2255 if (_log.isDebugEnabled()) {
2256 _log.debug(e, e);
2257 }
2258 else if (_log.isWarnEnabled()) {
2259 _log.warn(e.getMessage());
2260 }
2261 }
2262
2263 if (fileEntryUUID == null) {
2264 continue;
2265 }
2266
2267 FileEntry fileEntry =
2268 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
2269 fileEntryUUID, portletDataContext.getGroupId());
2270
2271 if (fileEntry == null) {
2272 continue;
2273 }
2274
2275 String dlReference = "[$dl-reference=" + dlReferencePath + "$]";
2276
2277 String url = DLUtil.getPreviewURL(
2278 fileEntry, fileEntry.getFileVersion(), null, StringPool.BLANK,
2279 false, false);
2280
2281 content = StringUtil.replace(content, dlReference, url);
2282 }
2283
2284 return content;
2285 }
2286
2287 protected static void importFolder(
2288 PortletDataContext portletDataContext, Element folderElement)
2289 throws Exception {
2290
2291 String path = folderElement.attributeValue("path");
2292
2293 if (!portletDataContext.isPathNotProcessed(path)) {
2294 return;
2295 }
2296
2297 JournalFolder folder =
2298 (JournalFolder)portletDataContext.getZipEntryAsObject(path);
2299
2300 importFolder(portletDataContext, path, folder);
2301 }
2302
2303 protected static void importFolder(
2304 PortletDataContext portletDataContext, String folderPath,
2305 JournalFolder folder)
2306 throws Exception {
2307
2308 long userId = portletDataContext.getUserId(folder.getUserUuid());
2309
2310 Map<Long, Long> folderIds =
2311 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
2312 JournalFolder.class);
2313
2314 long parentFolderId = MapUtil.getLong(
2315 folderIds, folder.getParentFolderId(), folder.getParentFolderId());
2316
2317 if ((parentFolderId !=
2318 JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
2319 (parentFolderId == folder.getParentFolderId())) {
2320
2321 String path = getImportFolderPath(
2322 portletDataContext, parentFolderId);
2323
2324 JournalFolder parentFolder =
2325 (JournalFolder)portletDataContext.getZipEntryAsObject(path);
2326
2327 importFolder(portletDataContext, path, parentFolder);
2328
2329 parentFolderId = MapUtil.getLong(
2330 folderIds, folder.getParentFolderId(),
2331 folder.getParentFolderId());
2332 }
2333
2334 ServiceContext serviceContext = portletDataContext.createServiceContext(
2335 folderPath, folder, _NAMESPACE);
2336
2337 JournalFolder importedFolder = null;
2338
2339 long groupId = portletDataContext.getScopeGroupId();
2340
2341 if (portletDataContext.isDataStrategyMirror()) {
2342 JournalFolder existingFolder = JournalFolderUtil.fetchByUUID_G(
2343 folder.getUuid(), groupId);
2344
2345 if (existingFolder == null) {
2346 serviceContext.setUuid(folder.getUuid());
2347
2348 importedFolder = JournalFolderLocalServiceUtil.addFolder(
2349 userId, groupId, parentFolderId, folder.getName(),
2350 folder.getDescription(), serviceContext);
2351 }
2352 else {
2353 importedFolder = JournalFolderLocalServiceUtil.updateFolder(
2354 existingFolder.getFolderId(), parentFolderId,
2355 folder.getName(), folder.getDescription(), false,
2356 serviceContext);
2357 }
2358 }
2359 else {
2360 importedFolder = JournalFolderLocalServiceUtil.addFolder(
2361 userId, groupId, parentFolderId, folder.getName(),
2362 folder.getDescription(), serviceContext);
2363 }
2364
2365 portletDataContext.importClassedModel(
2366 folder, importedFolder, _NAMESPACE);
2367 }
2368
2369 protected static String importLinksToLayout(
2370 PortletDataContext portletDataContext, String content)
2371 throws Exception {
2372
2373 List<String> oldLinksToLayout = new ArrayList<String>();
2374 List<String> newLinksToLayout = new ArrayList<String>();
2375
2376 Matcher matcher = _importLinksToLayoutPattern.matcher(content);
2377
2378 while (matcher.find()) {
2379 long oldLayoutId = GetterUtil.getLong(matcher.group(1));
2380
2381 long newLayoutId = oldLayoutId;
2382
2383 String type = matcher.group(2);
2384
2385 boolean privateLayout = type.startsWith("private");
2386
2387 String layoutUuid = matcher.group(3);
2388
2389 String friendlyURL = matcher.group(4);
2390
2391 try {
2392 Layout layout = LayoutUtil.fetchByUUID_G(
2393 layoutUuid, portletDataContext.getScopeGroupId());
2394
2395 if (layout == null) {
2396 layout = LayoutUtil.fetchByG_P_F(
2397 portletDataContext.getScopeGroupId(), privateLayout,
2398 friendlyURL);
2399 }
2400
2401 if (layout == null) {
2402 layout = LayoutUtil.fetchByG_P_L(
2403 portletDataContext.getScopeGroupId(), privateLayout,
2404 oldLayoutId);
2405 }
2406
2407 if (layout == null) {
2408 if (_log.isWarnEnabled()) {
2409 StringBundler sb = new StringBundler(9);
2410
2411 sb.append("Unable to get layout with UUID ");
2412 sb.append(layoutUuid);
2413 sb.append(", friendly URL ");
2414 sb.append(friendlyURL);
2415 sb.append(", or ");
2416 sb.append("layoutId ");
2417 sb.append(oldLayoutId);
2418 sb.append(" in group ");
2419 sb.append(portletDataContext.getScopeGroupId());
2420
2421 _log.warn(sb.toString());
2422 }
2423 }
2424 else {
2425 newLayoutId = layout.getLayoutId();
2426 }
2427 }
2428 catch (SystemException se) {
2429 if (_log.isWarnEnabled()) {
2430 _log.warn(
2431 "Unable to get layout in group " +
2432 portletDataContext.getScopeGroupId(), se);
2433 }
2434 }
2435
2436 String oldLinkToLayout = matcher.group(0);
2437
2438 StringBundler sb = new StringBundler(4);
2439
2440 sb.append(StringPool.AT);
2441 sb.append(layoutUuid);
2442 sb.append(StringPool.AT);
2443 sb.append(friendlyURL);
2444
2445 String newLinkToLayout = StringUtil.replace(
2446 oldLinkToLayout,
2447 new String[] {sb.toString(), String.valueOf(oldLayoutId)},
2448 new String[] {StringPool.BLANK, String.valueOf(newLayoutId)});
2449
2450 oldLinksToLayout.add(oldLinkToLayout);
2451 newLinksToLayout.add(newLinkToLayout);
2452 }
2453
2454 content = StringUtil.replace(
2455 content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
2456 ArrayUtil.toStringArray(newLinksToLayout.toArray()));
2457
2458 return content;
2459 }
2460
2461 protected static void prepareLanguagesForImport(JournalArticle article)
2462 throws PortalException {
2463
2464 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
2465 article.getDefaultLocale());
2466
2467 Locale[] articleAvailableLocales = LocaleUtil.fromLanguageIds(
2468 article.getAvailableLocales());
2469
2470 Locale defaultImportLocale = LocalizationUtil.getDefaultImportLocale(
2471 JournalArticle.class.getName(), article.getPrimaryKey(),
2472 articleDefaultLocale, articleAvailableLocales);
2473
2474 article.prepareLocalizedFieldsForImport(defaultImportLocale);
2475 }
2476
2477 @Override
2478 protected PortletPreferences doDeleteData(
2479 PortletDataContext portletDataContext, String portletId,
2480 PortletPreferences portletPreferences)
2481 throws Exception {
2482
2483 if (!portletDataContext.addPrimaryKey(
2484 JournalPortletDataHandlerImpl.class, "deleteData")) {
2485
2486 JournalArticleLocalServiceUtil.deleteArticles(
2487 portletDataContext.getScopeGroupId());
2488
2489 JournalTemplateLocalServiceUtil.deleteTemplates(
2490 portletDataContext.getScopeGroupId());
2491
2492 JournalStructureLocalServiceUtil.deleteStructures(
2493 portletDataContext.getScopeGroupId());
2494 }
2495
2496 return portletPreferences;
2497 }
2498
2499 @Override
2500 protected String doExportData(
2501 PortletDataContext portletDataContext, String portletId,
2502 PortletPreferences portletPreferences)
2503 throws Exception {
2504
2505 portletDataContext.addPermissions(
2506 "com.liferay.portlet.journal",
2507 portletDataContext.getScopeGroupId());
2508
2509 Document document = SAXReaderUtil.createDocument();
2510
2511 Element rootElement = document.addElement("journal-data");
2512
2513 rootElement.addAttribute(
2514 "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
2515
2516 Element structuresElement = rootElement.addElement("structures");
2517
2518 List<JournalStructure> structures = JournalStructureUtil.findByGroupId(
2519 portletDataContext.getScopeGroupId(), QueryUtil.ALL_POS,
2520 QueryUtil.ALL_POS, new StructurePKComparator(true));
2521
2522 for (JournalStructure structure : structures) {
2523 if (portletDataContext.isWithinDateRange(
2524 structure.getModifiedDate())) {
2525
2526 exportStructure(
2527 portletDataContext, structuresElement, structure);
2528 }
2529 }
2530
2531 Element templatesElement = rootElement.addElement("templates");
2532 Element dlFileEntryTypesElement = rootElement.addElement(
2533 "dl-file-entry-types");
2534 Element dlFoldersElement = rootElement.addElement("dl-folders");
2535 Element dlFilesElement = rootElement.addElement("dl-file-entries");
2536 Element dlFileRanksElement = rootElement.addElement("dl-file-ranks");
2537 Element dlRepositoriesElement = rootElement.addElement(
2538 "dl-repositories");
2539 Element dlRepositoryEntriesElement = rootElement.addElement(
2540 "dl-repository-entries");
2541
2542 List<JournalTemplate> templates = JournalTemplateUtil.findByGroupId(
2543 portletDataContext.getScopeGroupId());
2544
2545 for (JournalTemplate template : templates) {
2546 if (portletDataContext.isWithinDateRange(
2547 template.getModifiedDate())) {
2548
2549 exportTemplate(
2550 portletDataContext, templatesElement,
2551 dlFileEntryTypesElement, dlFoldersElement, dlFilesElement,
2552 dlFileRanksElement, dlRepositoriesElement,
2553 dlRepositoryEntriesElement, template);
2554 }
2555 }
2556
2557 Element feedsElement = rootElement.addElement("feeds");
2558
2559 List<JournalFeed> feeds = JournalFeedUtil.findByGroupId(
2560 portletDataContext.getScopeGroupId());
2561
2562 for (JournalFeed feed : feeds) {
2563 if (portletDataContext.isWithinDateRange(feed.getModifiedDate())) {
2564 exportFeed(portletDataContext, feedsElement, feed);
2565 }
2566 }
2567
2568 Element foldersElement = rootElement.addElement("folders");
2569 Element articlesElement = rootElement.addElement("articles");
2570
2571 if (portletDataContext.getBooleanParameter(_NAMESPACE, "web-content")) {
2572 List<JournalFolder> folders = JournalFolderUtil.findByGroupId(
2573 portletDataContext.getScopeGroupId());
2574
2575 for (JournalFolder folder : folders) {
2576 exportFolder(
2577 portletDataContext, foldersElement, articlesElement,
2578 structuresElement, templatesElement,
2579 dlFileEntryTypesElement, dlFoldersElement, dlFilesElement,
2580 dlFileRanksElement, dlRepositoriesElement,
2581 dlRepositoryEntriesElement, folder, true);
2582 }
2583
2584 List<JournalArticle> articles = JournalArticleUtil.findByG_F(
2585 portletDataContext.getScopeGroupId(),
2586 JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID,
2587 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
2588 new ArticleIDComparator(true));
2589
2590 for (JournalArticle article : articles) {
2591 if (portletDataContext.getBooleanParameter(
2592 _NAMESPACE, "version-history") ||
2593 JournalArticleLocalServiceUtil.isLatestVersion(
2594 article.getGroupId(), article.getArticleId(),
2595 article.getVersion(),
2596 WorkflowConstants.STATUS_APPROVED)) {
2597
2598 exportArticle(
2599 portletDataContext, articlesElement, structuresElement,
2600 templatesElement, dlFileEntryTypesElement,
2601 dlFoldersElement, dlFilesElement, dlFileRanksElement,
2602 dlRepositoriesElement, dlRepositoryEntriesElement,
2603 article, true);
2604 }
2605 }
2606 }
2607
2608 return document.formattedString();
2609 }
2610
2611 @Override
2612 protected PortletPreferences doImportData(
2613 PortletDataContext portletDataContext, String portletId,
2614 PortletPreferences portletPreferences, String data)
2615 throws Exception {
2616
2617 portletDataContext.importPermissions(
2618 "com.liferay.portlet.journal",
2619 portletDataContext.getSourceGroupId(),
2620 portletDataContext.getScopeGroupId());
2621
2622 Document document = SAXReaderUtil.read(data);
2623
2624 Element rootElement = document.getRootElement();
2625
2626 importReferencedData(portletDataContext, rootElement);
2627
2628 Element structuresElement = rootElement.element("structures");
2629
2630 List<Element> structureElements = structuresElement.elements(
2631 "structure");
2632
2633 for (Element structureElement : structureElements) {
2634 importStructure(portletDataContext, structureElement);
2635 }
2636
2637 Element templatesElement = rootElement.element("templates");
2638
2639 List<Element> templateElements = templatesElement.elements("template");
2640
2641 for (Element templateElement : templateElements) {
2642 importTemplate(portletDataContext, templateElement);
2643 }
2644
2645 Element feedsElement = rootElement.element("feeds");
2646
2647 List<Element> feedElements = feedsElement.elements("feed");
2648
2649 for (Element feedElement : feedElements) {
2650 importFeed(portletDataContext, feedElement);
2651 }
2652
2653 if (portletDataContext.getBooleanParameter(_NAMESPACE, "web-content")) {
2654 Element foldersElement = rootElement.element("folders");
2655
2656 List<Element> folderElements = foldersElement.elements("folder");
2657
2658 for (Element folderElement : folderElements) {
2659 importFolder(portletDataContext, folderElement);
2660 }
2661
2662 Element articlesElement = rootElement.element("articles");
2663
2664 List<Element> articleElements = articlesElement.elements("article");
2665
2666 for (Element articleElement : articleElements) {
2667 try {
2668 importArticle(portletDataContext, articleElement);
2669 }
2670 catch (ArticleContentException ace) {
2671 if (_log.isWarnEnabled()) {
2672 String path = articleElement.attributeValue("path");
2673
2674 _log.warn(
2675 "Skipping article with path " + path +
2676 " because of invalid content");
2677 }
2678 }
2679 }
2680 }
2681
2682 return portletPreferences;
2683 }
2684
2685 private static final boolean _ALWAYS_EXPORTABLE = true;
2686
2687 private static final boolean _DATA_LOCALIZED = true;
2688
2689 private static final String _NAMESPACE = "journal";
2690
2691 private static Log _log = LogFactoryUtil.getLog(
2692 JournalPortletDataHandlerImpl.class);
2693
2694 private static PortletDataHandlerBoolean _articles =
2695 new PortletDataHandlerBoolean(_NAMESPACE, "web-content");
2696
2697 private static PortletDataHandlerBoolean _embeddedAssets =
2698 new PortletDataHandlerBoolean(_NAMESPACE, "embedded-assets");
2699
2700 private static Pattern _exportLinksToLayoutPattern = Pattern.compile(
2701 "\\[([0-9]+)@(public|private\\-[a-z]*)\\]");
2702
2703 private static Pattern _importLinksToLayoutPattern = Pattern.compile(
2704 "\\[([0-9]+)@(public|private\\-[a-z]*)@(\\p{XDigit}{8}\\-" +
2705 "(?:\\p{XDigit}{4}\\-){3}\\p{XDigit}{12})@([^\\]]*)\\]");
2706
2707 private static PortletDataHandlerControl[] _metadataControls =
2708 new PortletDataHandlerControl[] {
2709 new PortletDataHandlerBoolean(_NAMESPACE, "images"),
2710 new PortletDataHandlerBoolean(_NAMESPACE, "categories"),
2711 new PortletDataHandlerBoolean(_NAMESPACE, "comments"),
2712 new PortletDataHandlerBoolean(_NAMESPACE, "ratings"),
2713 new PortletDataHandlerBoolean(_NAMESPACE, "tags")
2714 };
2715
2716 private static PortletDataHandlerBoolean _structuresTemplatesAndFeeds =
2717 new PortletDataHandlerBoolean(
2718 _NAMESPACE, "structures-templates-and-feeds", true, true);
2719
2720 private static PortletDataHandlerBoolean _versionHistory =
2721 new PortletDataHandlerBoolean(
2722 _NAMESPACE, "version-history",
2723 PropsValues.JOURNAL_PUBLISH_VERSION_HISTORY_BY_DEFAULT);
2724
2725 }