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