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