1
22
23 package com.liferay.portlet.journal.lar;
24
25 import com.liferay.portal.NoSuchImageException;
26 import com.liferay.portal.PortalException;
27 import com.liferay.portal.SystemException;
28 import com.liferay.portal.kernel.lar.PortletDataContext;
29 import com.liferay.portal.kernel.lar.PortletDataException;
30 import com.liferay.portal.kernel.lar.PortletDataHandler;
31 import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
32 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
33 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
34 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
35 import com.liferay.portal.kernel.util.FileUtil;
36 import com.liferay.portal.kernel.util.GetterUtil;
37 import com.liferay.portal.kernel.util.ObjectValuePair;
38 import com.liferay.portal.kernel.util.StringPool;
39 import com.liferay.portal.kernel.util.Validator;
40 import com.liferay.portal.model.Image;
41 import com.liferay.portal.service.persistence.ImageUtil;
42 import com.liferay.portal.util.DocumentUtil;
43 import com.liferay.portal.util.PortletKeys;
44 import com.liferay.portlet.documentlibrary.lar.DLPortletDataHandlerImpl;
45 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
46 import com.liferay.portlet.documentlibrary.model.DLFileRank;
47 import com.liferay.portlet.documentlibrary.model.DLFolder;
48 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
49 import com.liferay.portlet.imagegallery.lar.IGPortletDataHandlerImpl;
50 import com.liferay.portlet.imagegallery.model.IGFolder;
51 import com.liferay.portlet.imagegallery.model.IGImage;
52 import com.liferay.portlet.imagegallery.service.IGImageLocalServiceUtil;
53 import com.liferay.portlet.journal.model.JournalArticle;
54 import com.liferay.portlet.journal.model.JournalArticleImage;
55 import com.liferay.portlet.journal.model.JournalFeed;
56 import com.liferay.portlet.journal.model.JournalStructure;
57 import com.liferay.portlet.journal.model.JournalTemplate;
58 import com.liferay.portlet.journal.model.impl.JournalArticleImpl;
59 import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
60 import com.liferay.portlet.journal.service.JournalFeedLocalServiceUtil;
61 import com.liferay.portlet.journal.service.JournalStructureLocalServiceUtil;
62 import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
63 import com.liferay.portlet.journal.service.persistence.JournalArticleImageUtil;
64 import com.liferay.portlet.journal.service.persistence.JournalArticleUtil;
65 import com.liferay.portlet.journal.service.persistence.JournalFeedUtil;
66 import com.liferay.portlet.journal.service.persistence.JournalStructureUtil;
67 import com.liferay.portlet.journal.service.persistence.JournalTemplateUtil;
68 import com.liferay.util.MapUtil;
69 import com.liferay.util.xml.XMLFormatter;
70
71 import java.io.File;
72 import java.io.StringReader;
73
74 import java.util.Calendar;
75 import java.util.Date;
76 import java.util.HashMap;
77 import java.util.List;
78 import java.util.Map;
79 import java.util.regex.Matcher;
80 import java.util.regex.Pattern;
81
82 import javax.portlet.PortletPreferences;
83
84 import org.apache.commons.logging.Log;
85 import org.apache.commons.logging.LogFactory;
86
87 import org.dom4j.Document;
88 import org.dom4j.DocumentHelper;
89 import org.dom4j.Element;
90 import org.dom4j.XPath;
91 import org.dom4j.io.SAXReader;
92
93
125 public class JournalPortletDataHandlerImpl implements PortletDataHandler {
126
127 public static void exportArticle(
128 PortletDataContext context, Element articlesEl, Element dlFoldersEl,
129 Element dlFileEntriesEl, Element dlFileRanks, Element igFoldersEl,
130 Element igImagesEl, JournalArticle article)
131 throws PortalException, SystemException {
132
133 if (!context.isWithinDateRange(article.getModifiedDate())) {
134 return;
135 }
136
137 String path = getArticlePath(context, article);
138
139 Element articleEl = articlesEl.addElement("article");
140
141 articleEl.addAttribute("path", path);
142
143 if (!context.isPathNotProcessed(path)) {
144 return;
145 }
146
147 if (article.isSmallImage()) {
148 Image smallImage = ImageUtil.fetchByPrimaryKey(
149 article.getSmallImageId());
150
151 article.setSmallImageType(smallImage.getType());
152
153 context.addZipEntry(
154 getArticleSmallImagePath(context, article),
155 smallImage.getTextObj());
156 }
157
158 if (context.getBooleanParameter(_NAMESPACE, "images")) {
159 List<JournalArticleImage> articleImages =
160 JournalArticleImageUtil.findByG_A_V(
161 context.getGroupId(), article.getArticleId(),
162 article.getVersion());
163
164 for (JournalArticleImage articleImage : articleImages) {
165 try {
166 Image image = ImageUtil.findByPrimaryKey(
167 articleImage.getArticleImageId());
168
169 String imagePath = getArticleImagePath(
170 context, article, articleImage, image);
171
172 context.addZipEntry(imagePath, image.getTextObj());
173 }
174 catch (NoSuchImageException nsie) {
175 }
176 }
177 }
178
179 if (context.getBooleanParameter(_NAMESPACE, "comments")) {
180 context.addComments(
181 JournalArticle.class, article.getResourcePrimKey());
182 }
183
184 if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
185 context.addRatingsEntries(
186 JournalArticle.class, article.getResourcePrimKey());
187 }
188
189 if (context.getBooleanParameter(_NAMESPACE, "tags")) {
190 context.addTagsEntries(
191 JournalArticle.class, article.getResourcePrimKey());
192 }
193
194 try {
195 SAXReader reader = new SAXReader();
196
197 Document doc = reader.read(new StringReader(article.getContent()));
198
199 Element root = doc.getRootElement();
200
201 if (context.getBooleanParameter(_NAMESPACE, "embedded-assets")) {
202 List<Element> contentEls = root.elements("static-content");
203
204 for (Element contentEl : contentEls) {
205 String text = contentEl.getText();
206
207 text = exportDLFileEntries(
208 context, dlFoldersEl, dlFileEntriesEl, dlFileRanks,
209 text);
210 text = exportIGImages(
211 context, igFoldersEl, igImagesEl, text);
212
213 contentEl.setText(text);
214 }
215
216 XPath xpathSelector = DocumentHelper.createXPath(
217 "//dynamic-content");
218
219 contentEls = xpathSelector.selectNodes(doc);
220
221 for (Element contentEl : contentEls) {
222 String text = contentEl.getText();
223
224 text = exportDLFileEntries(
225 context, dlFoldersEl, dlFileEntriesEl, dlFileRanks,
226 text);
227 text = exportIGImages(
228 context, igFoldersEl, igImagesEl, text);
229
230 contentEl.setText(text);
231 }
232
233 }
234
235 article.setContent(XMLFormatter.toString(doc));
236 }
237 catch (Exception e) {
238 if (_log.isWarnEnabled()) {
239 _log.warn(e, e);
240 }
241 }
242
243 article.setUserUuid(article.getUserUuid());
244 article.setApprovedByUserUuid(article.getApprovedByUserUuid());
245
246 context.addZipEntry(path, article);
247 }
248
249 public static void exportFeed(
250 PortletDataContext context, Element feedsEl, JournalFeed feed)
251 throws SystemException {
252
253 if (!context.isWithinDateRange(feed.getModifiedDate())) {
254 return;
255 }
256
257 String path = getFeedPath(context, feed);
258
259 Element feedEl = feedsEl.addElement("feed");
260
261 feedEl.addAttribute("path", path);
262
263 if (context.isPathNotProcessed(path)) {
264 feed.setUserUuid(feed.getUserUuid());
265
266 context.addZipEntry(path, feed);
267 }
268 }
269
270 public static String exportDLFileEntries(
271 PortletDataContext context, Element foldersEl, Element fileEntriesEl,
272 Element fileRanks, String text) {
273
274 StringBuffer sb = new StringBuffer(text);
275
276 Pattern pattern = Pattern.compile("/get_file\\?([^\"']+)[\"']?");
277
278 Matcher matcher = pattern.matcher(text);
279
280 while (matcher.find()) {
281 try {
282 Map<String, String> detail = MapUtil.toLinkedHashMap(
283 matcher.group(1).replace("&", "&").split("&"),
284 StringPool.EQUAL);
285
286 DLFileEntry fileEntry = null;
287
288 if (detail.containsKey("uuid")) {
289 String uuid = detail.get("uuid");
290 long groupId = GetterUtil.getLong(detail.get("groupId"));
291
292 fileEntry = DLFileEntryLocalServiceUtil.
293 getFileEntryByUuidAndGroupId(uuid, groupId);
294 }
295 else if (detail.containsKey("folderId")) {
296 long folderId = GetterUtil.getLong(detail.get("folderId"));
297 String name = detail.get("name");
298
299 fileEntry = DLFileEntryLocalServiceUtil.getFileEntry(
300 folderId, name);
301 }
302
303 if (fileEntry == null) {
304 continue;
305 }
306
307 DLPortletDataHandlerImpl.exportFileEntry(
308 context, foldersEl, fileEntriesEl, fileRanks, fileEntry);
309
310 sb.replace(
311 matcher.start(1), matcher.end(1),
312 "uuid=" + fileEntry.getUuid() + "&groupId=@group_id@");
313 }
314 catch (Exception e) {
315 if (_log.isWarnEnabled()) {
316 _log.warn(e, e);
317 }
318 }
319 }
320
321 return sb.toString();
322 }
323
324 public static String exportIGImages(
325 PortletDataContext context, Element foldersEl, Element imagesEl,
326 String text) {
327
328 StringBuffer sb = new StringBuffer(text);
329
330 Pattern pattern = Pattern.compile("/image_gallery\\?(.*?)&(amp;)?t=");
331
332 Matcher matcher = pattern.matcher(text);
333
334 while (matcher.find()) {
335 try {
336 Map<String, String> detail = MapUtil.toLinkedHashMap(
337 matcher.group(1).replace("&", "&").split("&"),
338 StringPool.EQUAL);
339
340 IGImage image = null;
341
342 if (detail.containsKey("uuid")) {
343 String uuid = detail.get("uuid");
344 long groupId = GetterUtil.getLong(detail.get("groupId"));
345
346 image = IGImageLocalServiceUtil.getImageByUuidAndGroupId(
347 uuid, groupId);
348 }
349 else if (detail.containsKey("image_id") ||
350 detail.containsKey("img_id") ||
351 detail.containsKey("i_id")) {
352
353 long imageId = GetterUtil.getLong(detail.get("image_id"));
354
355 if (imageId <= 0) {
356 imageId = GetterUtil.getLong(detail.get("img_id"));
357
358 if (imageId <= 0) {
359 imageId = GetterUtil.getLong(detail.get("i_id"));
360 }
361 }
362
363 image = IGImageLocalServiceUtil.getIGImage(imageId);
364 }
365
366 if (image == null) {
367 continue;
368 }
369
370 IGPortletDataHandlerImpl.exportImage(
371 context, foldersEl, imagesEl, image);
372
373 sb.replace(
374 matcher.start(1), matcher.end(1),
375 "uuid=" + image.getUuid() + "&groupId=@group_id@");
376 }
377 catch (Exception e) {
378 if (_log.isWarnEnabled()) {
379 _log.warn(e, e);
380 }
381 }
382 }
383
384 return sb.toString();
385 }
386
387 public static void exportStructure(
388 PortletDataContext context, Element structuresEl,
389 JournalStructure structure)
390 throws SystemException {
391
392 if (!context.isWithinDateRange(structure.getModifiedDate())) {
393 return;
394 }
395
396 String path = getStructurePath(context, structure);
397
398 Element structureEl = structuresEl.addElement("structure");
399
400 structureEl.addAttribute("path", path);
401
402 if (context.isPathNotProcessed(path)) {
403 structure.setUserUuid(structure.getUserUuid());
404
405 context.addZipEntry(path, structure);
406 }
407 }
408
409 public static void exportTemplate(
410 PortletDataContext context, Element templatesEl,
411 JournalTemplate template)
412 throws PortalException, SystemException {
413
414 if (!context.isWithinDateRange(template.getModifiedDate())) {
415 return;
416 }
417
418 String path = getTemplatePath(context, template);
419
420 Element templateEl = templatesEl.addElement("template");
421
422 templateEl.addAttribute("path", path);
423
424 if (!context.isPathNotProcessed(path)) {
425 return;
426 }
427
428 if (template.isSmallImage()) {
429 Image smallImage = ImageUtil.fetchByPrimaryKey(
430 template.getSmallImageId());
431
432 template.setSmallImageType(smallImage.getType());
433
434 context.addZipEntry(
435 getTemplateSmallImagePath(context, template),
436 smallImage.getTextObj());
437 }
438
439 template.setUserUuid(template.getUserUuid());
440
441 context.addZipEntry(path, template);
442 }
443
444 public static void importArticle(
445 PortletDataContext context, Map<String, String> structureIds,
446 Map<String, String> templateIds, Map<String, String> articleIds,
447 Element articleEl)
448 throws Exception {
449
450 String path = articleEl.attributeValue("path");
451
452 if (!context.isPathNotProcessed(path)) {
453 return;
454 }
455
456 JournalArticle article = (JournalArticle)context.getZipEntryAsObject(
457 path);
458
459 long userId = context.getUserId(article.getUserUuid());
460 long plid = context.getPlid();
461
462 String articleId = article.getArticleId();
463 boolean autoArticleId = false;
464
465 if ((Validator.isNumber(articleId)) ||
466 (JournalArticleUtil.fetchByG_A_V(
467 context.getGroupId(), articleId,
468 JournalArticleImpl.DEFAULT_VERSION) != null)) {
469
470 autoArticleId = true;
471 }
472
473 String newArticleId = articleIds.get(articleId);
474
475 if (Validator.isNotNull(newArticleId)) {
476
477
480 articleId = newArticleId;
481 autoArticleId = false;
482 }
483
484 boolean incrementVersion = false;
485
486 String parentStructureId = MapUtil.getString(
487 structureIds, article.getStructureId(), article.getStructureId());
488 String parentTemplateId = MapUtil.getString(
489 templateIds, article.getTemplateId(), article.getTemplateId());
490
491 Date displayDate = article.getDisplayDate();
492
493 int displayDateMonth = 0;
494 int displayDateDay = 0;
495 int displayDateYear = 0;
496 int displayDateHour = 0;
497 int displayDateMinute = 0;
498
499 if (displayDate != null) {
500 Calendar displayCal = CalendarFactoryUtil.getCalendar();
501
502 displayCal.setTime(displayDate);
503
504 displayDateMonth = displayCal.get(Calendar.MONTH);
505 displayDateDay = displayCal.get(Calendar.DATE);
506 displayDateYear = displayCal.get(Calendar.YEAR);
507 displayDateHour = displayCal.get(Calendar.HOUR);
508 displayDateMinute = displayCal.get(Calendar.MINUTE);
509
510 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
511 displayDateHour += 12;
512 }
513 }
514
515 Date expirationDate = article.getExpirationDate();
516
517 int expirationDateMonth = 0;
518 int expirationDateDay = 0;
519 int expirationDateYear = 0;
520 int expirationDateHour = 0;
521 int expirationDateMinute = 0;
522 boolean neverExpire = true;
523
524 if (expirationDate != null) {
525 Calendar expirationCal = CalendarFactoryUtil.getCalendar();
526
527 expirationCal.setTime(expirationDate);
528
529 expirationDateMonth = expirationCal.get(Calendar.MONTH);
530 expirationDateDay = expirationCal.get(Calendar.DATE);
531 expirationDateYear = expirationCal.get(Calendar.YEAR);
532 expirationDateHour = expirationCal.get(Calendar.HOUR);
533 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
534 neverExpire = false;
535
536 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
537 expirationDateHour += 12;
538 }
539 }
540
541 Date reviewDate = article.getReviewDate();
542
543 int reviewDateMonth = 0;
544 int reviewDateDay = 0;
545 int reviewDateYear = 0;
546 int reviewDateHour = 0;
547 int reviewDateMinute = 0;
548 boolean neverReview = true;
549
550 if (reviewDate != null) {
551 Calendar reviewCal = CalendarFactoryUtil.getCalendar();
552
553 reviewCal.setTime(reviewDate);
554
555 reviewDateMonth = reviewCal.get(Calendar.MONTH);
556 reviewDateDay = reviewCal.get(Calendar.DATE);
557 reviewDateYear = reviewCal.get(Calendar.YEAR);
558 reviewDateHour = reviewCal.get(Calendar.HOUR);
559 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
560 neverReview = false;
561
562 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
563 reviewDateHour += 12;
564 }
565 }
566
567 File smallFile = null;
568
569 if (article.isSmallImage()) {
570 byte[] bytes = context.getZipEntryAsByteArray(
571 getArticleSmallImagePath(context, article));
572
573 smallFile = File.createTempFile(
574 String.valueOf(article.getSmallImageId()),
575 StringPool.PERIOD + article.getSmallImageType());
576
577 FileUtil.write(smallFile, bytes);
578 }
579
580 Map<String, byte[]> images = new HashMap<String, byte[]>();
581
582 if (context.getBooleanParameter(_NAMESPACE, "images")) {
583 List<ObjectValuePair<String, byte[]>> imageFiles =
584 context.getZipFolderEntries(
585 getArticleImagePath(context, article));
586
587 if (imageFiles != null) {
588 for (ObjectValuePair<String, byte[]> imageFile : imageFiles) {
589 String fileName = imageFile.getKey();
590
591 if (!fileName.endsWith(".xml")) {
592 int pos = fileName.lastIndexOf(StringPool.PERIOD);
593
594 if (pos != -1) {
595 fileName = fileName.substring(0, pos);
596 }
597
598 images.put(fileName, imageFile.getValue());
599 }
600 }
601 }
602 }
603
604 String articleURL = null;
605
606 PortletPreferences prefs = null;
607
608 String[] tagsEntries = null;
609
610 if (context.getBooleanParameter(_NAMESPACE, "tags")) {
611 tagsEntries = context.getTagsEntries(
612 JournalArticle.class, article.getResourcePrimKey());
613 }
614
615 JournalCreationStrategy creationStrategy =
616 JournalCreationStrategyFactory.getInstance();
617
618 long authorId = creationStrategy.getAuthorUserId(context, article);
619
620 if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
621 userId = authorId;
622 }
623
624 String newContent = creationStrategy.getTransformedContent(
625 context, article);
626
627 if (newContent != JournalCreationStrategy.ARTICLE_CONTENT_UNCHANGED) {
628 article.setContent(newContent);
629 }
630
631 boolean addCommunityPermissions =
632 creationStrategy.addCommunityPermissions(context, article);
633 boolean addGuestPermissions = creationStrategy.addGuestPermissions(
634 context, article);
635
636 JournalArticle existingArticle = null;
637
638 if (context.getDataStrategy().equals(
639 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
640
641 existingArticle = JournalArticleUtil.fetchByUUID_G(
642 article.getUuid(), context.getGroupId());
643
644 if (existingArticle == null) {
645 existingArticle = JournalArticleLocalServiceUtil.addArticle(
646 article.getUuid(), userId, articleId, autoArticleId,
647 plid, article.getVersion(), article.getTitle(),
648 article.getDescription(), article.getContent(),
649 article.getType(), parentStructureId, parentTemplateId,
650 displayDateMonth, displayDateDay, displayDateYear,
651 displayDateHour, displayDateMinute, expirationDateMonth,
652 expirationDateDay, expirationDateYear, expirationDateHour,
653 expirationDateMinute, neverExpire, reviewDateMonth,
654 reviewDateDay, reviewDateYear, reviewDateHour,
655 reviewDateMinute, neverReview, article.getIndexable(),
656 article.getSmallImage(), article.getSmallImageURL(),
657 smallFile, images, articleURL, prefs, tagsEntries,
658 addCommunityPermissions, addGuestPermissions);
659 }
660 else {
661 existingArticle = JournalArticleLocalServiceUtil.updateArticle(
662 userId, existingArticle.getGroupId(),
663 existingArticle.getArticleId(),
664 existingArticle.getVersion(), incrementVersion,
665 article.getTitle(), article.getDescription(),
666 article.getContent(), article.getType(),
667 existingArticle.getStructureId(),
668 existingArticle.getTemplateId(), displayDateMonth,
669 displayDateDay, displayDateYear, displayDateHour,
670 displayDateMinute, expirationDateMonth, expirationDateDay,
671 expirationDateYear, expirationDateHour,
672 expirationDateMinute, neverExpire, reviewDateMonth,
673 reviewDateDay, reviewDateYear, reviewDateHour,
674 reviewDateMinute, neverReview, article.getIndexable(),
675 article.getSmallImage(), article.getSmallImageURL(),
676 smallFile, images, articleURL, prefs, tagsEntries);
677 }
678 }
679 else {
680 existingArticle = JournalArticleLocalServiceUtil.addArticle(
681 userId, articleId, autoArticleId, plid, article.getVersion(),
682 article.getTitle(), article.getDescription(),
683 article.getContent(), article.getType(), parentStructureId,
684 parentTemplateId, displayDateMonth, displayDateDay,
685 displayDateYear, displayDateHour, displayDateMinute,
686 expirationDateMonth, expirationDateDay, expirationDateYear,
687 expirationDateHour, expirationDateMinute, neverExpire,
688 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
689 reviewDateMinute, neverReview, article.getIndexable(),
690 article.getSmallImage(), article.getSmallImageURL(), smallFile,
691 images, articleURL, prefs, tagsEntries, addCommunityPermissions,
692 addGuestPermissions);
693 }
694
695 long strategyApprovalUserId = creationStrategy.getApprovalUserId(
696 context, article);
697
698 if ((strategyApprovalUserId !=
699 JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) ||
700 (article.isApproved() && !existingArticle.isApproved())) {
701
702 long approvedByUserId = strategyApprovalUserId;
703
704 if (approvedByUserId == 0) {
705 approvedByUserId = context.getUserId(
706 article.getApprovedByUserUuid());
707 }
708
709 JournalArticleLocalServiceUtil.approveArticle(
710 approvedByUserId, context.getGroupId(),
711 existingArticle.getArticleId(), existingArticle.getVersion(),
712 articleURL, prefs);
713 }
714
715 if (context.getBooleanParameter(_NAMESPACE, "comments")) {
716 context.importComments(
717 JournalArticle.class, article.getResourcePrimKey(),
718 existingArticle.getResourcePrimKey(), context.getGroupId());
719 }
720
721 if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
722 context.importRatingsEntries(
723 JournalArticle.class, article.getResourcePrimKey(),
724 existingArticle.getResourcePrimKey());
725 }
726
727 articleIds.put(articleId, existingArticle.getArticleId());
728
729 if (!articleId.equals(existingArticle.getArticleId())) {
730 if (_log.isWarnEnabled()) {
731 _log.warn(
732 "An article with the ID " + articleId + " already " +
733 "exists. The new generated ID is " +
734 existingArticle.getArticleId());
735 }
736 }
737 }
738
739 public static void importFeed(
740 PortletDataContext context, Map<String, String> structureIds,
741 Map<String, String> templateIds, Map<String, String> feedIds,
742 Element feedEl)
743 throws Exception {
744
745 String path = feedEl.attributeValue("path");
746
747 if (!context.isPathNotProcessed(path)) {
748 return;
749 }
750
751 JournalFeed feed = (JournalFeed)context.getZipEntryAsObject(path);
752
753 long userId = context.getUserId(feed.getUserUuid());
754 long plid = context.getPlid();
755
756 String feedId = feed.getFeedId();
757 boolean autoFeedId = false;
758
759 if ((Validator.isNumber(feedId)) ||
760 (JournalFeedUtil.fetchByG_F(
761 context.getGroupId(), feedId) != null)) {
762
763 autoFeedId = true;
764 }
765
766 String parentStructureId = MapUtil.getString(
767 structureIds, feed.getStructureId(), feed.getStructureId());
768 String parentTemplateId = MapUtil.getString(
769 templateIds, feed.getTemplateId(), feed.getTemplateId());
770 String parentRenderTemplateId = MapUtil.getString(
771 templateIds, feed.getRendererTemplateId(),
772 feed.getRendererTemplateId());
773
774 JournalCreationStrategy creationStrategy =
775 JournalCreationStrategyFactory.getInstance();
776
777 long authorId = creationStrategy.getAuthorUserId(context, feed);
778
779 if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
780 userId = authorId;
781 }
782
783 boolean addCommunityPermissions =
784 creationStrategy.addCommunityPermissions(context, feed);
785 boolean addGuestPermissions = creationStrategy.addGuestPermissions(
786 context, feed);
787
788 JournalFeed existingFeed = null;
789
790 if (context.getDataStrategy().equals(
791 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
792
793 existingFeed = JournalFeedUtil.fetchByUUID_G(
794 feed.getUuid(), context.getGroupId());
795
796 if (existingFeed == null) {
797 existingFeed = JournalFeedLocalServiceUtil.addFeed(
798 feed.getUuid(), userId, plid, feedId, autoFeedId,
799 feed.getName(), feed.getDescription(), feed.getType(),
800 parentStructureId, parentTemplateId, parentRenderTemplateId,
801 feed.getDelta(), feed.getOrderByCol(),
802 feed.getOrderByType(), feed.getTargetLayoutFriendlyUrl(),
803 feed.getTargetPortletId(), feed.getContentField(),
804 feed.getFeedType(), feed.getFeedVersion(),
805 addCommunityPermissions, addGuestPermissions);
806 }
807 else {
808 existingFeed = JournalFeedLocalServiceUtil.updateFeed(
809 existingFeed.getGroupId(), existingFeed.getFeedId(),
810 feed.getName(), feed.getDescription(), feed.getType(),
811 parentStructureId, parentTemplateId, parentRenderTemplateId,
812 feed.getDelta(), feed.getOrderByCol(),
813 feed.getOrderByType(), feed.getTargetLayoutFriendlyUrl(),
814 feed.getTargetPortletId(), feed.getContentField(),
815 feed.getFeedType(), feed.getFeedVersion());
816 }
817 }
818 else {
819 existingFeed = JournalFeedLocalServiceUtil.addFeed(
820 userId, plid, feedId, autoFeedId, feed.getName(),
821 feed.getDescription(), feed.getType(), parentStructureId,
822 parentTemplateId, parentRenderTemplateId, feed.getDelta(),
823 feed.getOrderByCol(), feed.getOrderByType(),
824 feed.getTargetLayoutFriendlyUrl(), feed.getTargetPortletId(),
825 feed.getContentField(), feed.getFeedType(),
826 feed.getFeedVersion(), addCommunityPermissions,
827 addGuestPermissions);
828 }
829
830 feedIds.put(feedId, existingFeed.getFeedId());
831
832 if (!feedId.equals(existingFeed.getStructureId())) {
833 if (_log.isWarnEnabled()) {
834 _log.warn(
835 "A feed with the ID " + feedId + " already " +
836 "exists. The new generated ID is " +
837 existingFeed.getFeedId());
838 }
839 }
840 }
841
842 public static void importStructure(
843 PortletDataContext context, Map<String, String> structureIds,
844 Element structureEl)
845 throws Exception {
846
847 String path = structureEl.attributeValue("path");
848
849 if (!context.isPathNotProcessed(path)) {
850 return;
851 }
852
853 JournalStructure structure =
854 (JournalStructure)context.getZipEntryAsObject(path);
855
856 long userId = context.getUserId(structure.getUserUuid());
857 long plid = context.getPlid();
858
859 String structureId = structure.getStructureId();
860 boolean autoStructureId = false;
861
862 if ((Validator.isNumber(structureId)) ||
863 (JournalStructureUtil.fetchByG_S(
864 context.getGroupId(), structureId) != null)) {
865
866 autoStructureId = true;
867 }
868
869 JournalCreationStrategy creationStrategy =
870 JournalCreationStrategyFactory.getInstance();
871
872 long authorId = creationStrategy.getAuthorUserId(context, structure);
873
874 if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
875 userId = authorId;
876 }
877
878 boolean addCommunityPermissions =
879 creationStrategy.addCommunityPermissions(context, structure);
880 boolean addGuestPermissions = creationStrategy.addGuestPermissions(
881 context, structure);
882
883 JournalStructure existingStructure = null;
884
885 if (context.getDataStrategy().equals(
886 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
887
888 existingStructure = JournalStructureUtil.fetchByUUID_G(
889 structure.getUuid(), context.getGroupId());
890
891 if (existingStructure == null) {
892 existingStructure =
893 JournalStructureLocalServiceUtil.addStructure(
894 structure.getUuid(), userId, structureId,
895 autoStructureId, plid, structure.getName(),
896 structure.getDescription(), structure.getXsd(),
897 addCommunityPermissions, addGuestPermissions);
898 }
899 else {
900 existingStructure =
901 JournalStructureLocalServiceUtil.updateStructure(
902 existingStructure.getGroupId(),
903 existingStructure.getStructureId(), structure.getName(),
904 structure.getDescription(), structure.getXsd());
905 }
906 }
907 else {
908 existingStructure = JournalStructureLocalServiceUtil.addStructure(
909 userId, structureId, autoStructureId, plid, structure.getName(),
910 structure.getDescription(), structure.getXsd(),
911 addCommunityPermissions, addGuestPermissions);
912 }
913
914 structureIds.put(structureId, existingStructure.getStructureId());
915
916 if (!structureId.equals(existingStructure.getStructureId())) {
917 if (_log.isWarnEnabled()) {
918 _log.warn(
919 "A structure with the ID " + structureId + " already " +
920 "exists. The new generated ID is " +
921 existingStructure.getStructureId());
922 }
923 }
924 }
925
926 public static void importTemplate(
927 PortletDataContext context, Map<String, String> structureIds,
928 Map<String, String> templateIds, Element templateEl)
929 throws Exception {
930
931 String path = templateEl.attributeValue("path");
932
933 if (!context.isPathNotProcessed(path)) {
934 return;
935 }
936
937 JournalTemplate template = (JournalTemplate)context.getZipEntryAsObject(
938 path);
939
940 long userId = context.getUserId(template.getUserUuid());
941 long plid = context.getPlid();
942
943 String templateId = template.getTemplateId();
944 boolean autoTemplateId = false;
945
946 if ((Validator.isNumber(templateId)) ||
947 (JournalTemplateUtil.fetchByG_T(
948 context.getGroupId(), templateId) != null)) {
949
950 autoTemplateId = true;
951 }
952
953 String parentStructureId = MapUtil.getString(
954 structureIds, template.getStructureId(), template.getStructureId());
955
956 boolean formatXsl = false;
957
958 JournalCreationStrategy creationStrategy =
959 JournalCreationStrategyFactory.getInstance();
960
961 long authorId = creationStrategy.getAuthorUserId(context, template);
962
963 if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
964 userId = authorId;
965 }
966
967 boolean addCommunityPermissions =
968 creationStrategy.addCommunityPermissions(context, template);
969 boolean addGuestPermissions = creationStrategy.addGuestPermissions(
970 context, template);
971
972 File smallFile = null;
973
974 if (template.isSmallImage()) {
975 byte[] bytes = context.getZipEntryAsByteArray(
976 getTemplateSmallImagePath(context, template));
977
978 smallFile = File.createTempFile(
979 String.valueOf(template.getSmallImageId()),
980 StringPool.PERIOD + template.getSmallImageType());
981
982 FileUtil.write(smallFile, bytes);
983 }
984
985 JournalTemplate existingTemplate = null;
986
987 if (context.getDataStrategy().equals(
988 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
989
990 existingTemplate = JournalTemplateUtil.fetchByUUID_G(
991 template.getUuid(), context.getGroupId());
992
993 if (existingTemplate == null) {
994 existingTemplate = JournalTemplateLocalServiceUtil.addTemplate(
995 template.getUuid(), userId, templateId, autoTemplateId,
996 plid, parentStructureId, template.getName(),
997 template.getDescription(), template.getXsl(), formatXsl,
998 template.getLangType(), template.getCacheable(),
999 template.isSmallImage(), template.getSmallImageURL(),
1000 smallFile, addCommunityPermissions, addGuestPermissions);
1001 }
1002 else {
1003 existingTemplate =
1004 JournalTemplateLocalServiceUtil.updateTemplate(
1005 existingTemplate.getGroupId(),
1006 existingTemplate.getTemplateId(),
1007 existingTemplate.getStructureId(), template.getName(),
1008 template.getDescription(), template.getXsl(), formatXsl,
1009 template.getLangType(), template.getCacheable(),
1010 template.isSmallImage(), template.getSmallImageURL(),
1011 smallFile);
1012 }
1013 }
1014 else {
1015 existingTemplate = JournalTemplateLocalServiceUtil.addTemplate(
1016 userId, templateId, autoTemplateId, plid, parentStructureId,
1017 template.getName(), template.getDescription(),
1018 template.getXsl(), formatXsl, template.getLangType(),
1019 template.getCacheable(), template.isSmallImage(),
1020 template.getSmallImageURL(), smallFile, addCommunityPermissions,
1021 addGuestPermissions);
1022 }
1023
1024 templateIds.put(templateId, existingTemplate.getTemplateId());
1025
1026 if (!templateId.equals(existingTemplate.getTemplateId())) {
1027 if (_log.isWarnEnabled()) {
1028 _log.warn(
1029 "A template with the ID " + templateId + " already " +
1030 "exists. The new generated ID is " +
1031 existingTemplate.getTemplateId());
1032 }
1033 }
1034 }
1035
1036 public PortletPreferences deleteData(
1037 PortletDataContext context, String portletId,
1038 PortletPreferences prefs)
1039 throws PortletDataException {
1040
1041 try {
1042 if (!context.addPrimaryKey(
1043 JournalPortletDataHandlerImpl.class, "deleteData")) {
1044
1045 JournalArticleLocalServiceUtil.deleteArticles(
1046 context.getGroupId());
1047
1048 JournalTemplateLocalServiceUtil.deleteTemplates(
1049 context.getGroupId());
1050
1051 JournalStructureLocalServiceUtil.deleteStructures(
1052 context.getGroupId());
1053 }
1054
1055 return prefs;
1056 }
1057 catch (Exception e) {
1058 throw new PortletDataException(e);
1059 }
1060 }
1061
1062 public String exportData(
1063 PortletDataContext context, String portletId,
1064 PortletPreferences prefs)
1065 throws PortletDataException {
1066
1067 try {
1068 Document doc = DocumentHelper.createDocument();
1069
1070 Element root = doc.addElement("journal-data");
1071
1072 root.addAttribute("group-id", String.valueOf(context.getGroupId()));
1073
1074 Element structuresEl = root.addElement("structures");
1075
1076 List<JournalStructure> structures =
1077 JournalStructureUtil.findByGroupId(context.getGroupId());
1078
1079 for (JournalStructure structure : structures) {
1080 exportStructure(context, structuresEl, structure);
1081 }
1082
1083 Element templatesEl = root.addElement("templates");
1084
1085 List<JournalTemplate> templates = JournalTemplateUtil.findByGroupId(
1086 context.getGroupId());
1087
1088 for (JournalTemplate template : templates) {
1089 exportTemplate(context, templatesEl, template);
1090 }
1091
1092 Element feedsEl = root.addElement("feeds");
1093
1094 List<JournalFeed> feeds = JournalFeedUtil.findByGroupId(
1095 context.getGroupId());
1096
1097 for (JournalFeed feed : feeds) {
1098 if (context.isWithinDateRange(feed.getModifiedDate())) {
1099 exportFeed(context, feedsEl, feed);
1100 }
1101 }
1102
1103 Element articlesEl = root.addElement("articles");
1104 Element igFoldersEl = root.addElement("ig-folders");
1105 Element igImagesEl = root.addElement("ig-images");
1106 Element dlFoldersEl = root.addElement("dl-folders");
1107 Element dlFilesEl = root.addElement("dl-file-entries");
1108 Element dlFileRanksEl = root.addElement("dl-file-ranks");
1109
1110 if (context.getBooleanParameter(_NAMESPACE, "articles")) {
1111 List<JournalArticle> articles =
1112 JournalArticleUtil.findByGroupId(context.getGroupId());
1113
1114 for (JournalArticle article : articles) {
1115 if (context.isWithinDateRange(article.getModifiedDate())) {
1116 exportArticle(
1117 context, articlesEl, igFoldersEl, igImagesEl,
1118 dlFoldersEl, dlFilesEl, dlFileRanksEl, article);
1119 }
1120 }
1121 }
1122
1123 return XMLFormatter.toString(doc);
1124 }
1125 catch (Exception e) {
1126 throw new PortletDataException(e);
1127 }
1128 }
1129
1130 public PortletDataHandlerControl[] getExportControls() {
1131 return new PortletDataHandlerControl[] {
1132 _articles, _structuresTemplatesAndFeeds, _embeddedAssets, _images,
1133 _comments, _ratings, _tags
1134 };
1135 }
1136
1137 public PortletDataHandlerControl[] getImportControls() {
1138 return new PortletDataHandlerControl[] {
1139 _articles, _structuresTemplatesAndFeeds, _images, _comments,
1140 _ratings, _tags
1141 };
1142 }
1143
1144 public PortletPreferences importData(
1145 PortletDataContext context, String portletId,
1146 PortletPreferences prefs, String data)
1147 throws PortletDataException {
1148
1149 try {
1150 Document doc = DocumentUtil.readDocumentFromXML(data);
1151
1152 Element root = doc.getRootElement();
1153
1154 List<Element> structureEls = root.element("structures").elements(
1155 "structure");
1156
1157 Map<String, String> structureIds = context.getNewPrimaryKeysMap(
1158 JournalStructure.class);
1159
1160 for (Element structureEl : structureEls) {
1161 importStructure(context, structureIds, structureEl);
1162 }
1163
1164 List<Element> templateEls = root.element("templates").elements(
1165 "template");
1166
1167 Map<String, String> templateIds = context.getNewPrimaryKeysMap(
1168 JournalTemplate.class);
1169
1170 for (Element templateEl : templateEls) {
1171 importTemplate(context, structureIds, templateIds, templateEl);
1172 }
1173
1174 List<Element> feedEls = root.element("feeds").elements("feed");
1175
1176 Map<String, String> feedIds = context.getNewPrimaryKeysMap(
1177 JournalFeed.class);
1178
1179 for (Element feedEl : feedEls) {
1180 importFeed(context, structureIds, templateIds, feedIds, feedEl);
1181 }
1182
1183 if (context.getBooleanParameter(_NAMESPACE, "articles")) {
1184 List<Element> articleEls = root.element("articles").elements(
1185 "article");
1186
1187 Map<String, String> articleIds = context.getNewPrimaryKeysMap(
1188 JournalArticle.class);
1189
1190 for (Element articleEl : articleEls) {
1191 importArticle(
1192 context, structureIds, templateIds, articleIds,
1193 articleEl);
1194 }
1195 }
1196
1197 List<Element> dlFolderEls = root.element("dl-folders").elements(
1198 "folder");
1199
1200 Map<Long, Long> dlFolderPKs = context.getNewPrimaryKeysMap(
1201 DLFolder.class);
1202
1203 for (Element folderEl : dlFolderEls) {
1204 String path = folderEl.attributeValue("path");
1205
1206 if (context.isPathNotProcessed(path)) {
1207 DLFolder folder = (DLFolder)context.getZipEntryAsObject(
1208 path);
1209
1210 DLPortletDataHandlerImpl.importFolder(
1211 context, dlFolderPKs, folder);
1212 }
1213 }
1214
1215 List<Element> fileEntryEls = root.element(
1216 "dl-file-entries").elements("file-entry");
1217
1218 Map<String, String> fileEntryNames = context.getNewPrimaryKeysMap(
1219 DLFileEntry.class);
1220
1221 for (Element fileEntryEl : fileEntryEls) {
1222 String path = fileEntryEl.attributeValue("path");
1223 String binPath = fileEntryEl.attributeValue("bin-path");
1224
1225 if (context.isPathNotProcessed(path)) {
1226 DLFileEntry fileEntry =
1227 (DLFileEntry)context.getZipEntryAsObject(path);
1228
1229 DLPortletDataHandlerImpl.importFileEntry(
1230 context, dlFolderPKs, fileEntryNames, fileEntry,
1231 binPath);
1232 }
1233 }
1234
1235 List<Element> fileRankEls = root.element("dl-file-ranks").elements(
1236 "file-rank");
1237
1238 for (Element fileRankEl : fileRankEls) {
1239 String path = fileRankEl.attributeValue("path");
1240
1241 if (context.isPathNotProcessed(path)) {
1242 DLFileRank fileRank =
1243 (DLFileRank)context.getZipEntryAsObject(path);
1244
1245 DLPortletDataHandlerImpl.importFileRank(
1246 context, dlFolderPKs, fileEntryNames, fileRank);
1247 }
1248 }
1249
1250 List<Element> igFolderEls = root.element("ig-folders").elements(
1251 "folder");
1252
1253 Map<Long, Long> igFolderPKs = context.getNewPrimaryKeysMap(
1254 IGFolder.class);
1255
1256 for (Element folderEl : igFolderEls) {
1257 String path = folderEl.attributeValue("path");
1258
1259 if (context.isPathNotProcessed(path)) {
1260 IGFolder folder = (IGFolder)context.getZipEntryAsObject(
1261 path);
1262
1263 IGPortletDataHandlerImpl.importFolder(
1264 context, igFolderPKs, folder);
1265 }
1266 }
1267
1268 List<Element> imageEls = root.element("ig-images").elements(
1269 "image");
1270
1271 for (Element imageEl : imageEls) {
1272 String path = imageEl.attributeValue("path");
1273 String binPath = imageEl.attributeValue("bin-path");
1274
1275 if (context.isPathNotProcessed(path)) {
1276 IGImage image = (IGImage)context.getZipEntryAsObject(path);
1277
1278 IGPortletDataHandlerImpl.importImage(
1279 context, igFolderPKs, image, binPath);
1280 }
1281 }
1282
1283 return prefs;
1284 }
1285 catch (Exception e) {
1286 throw new PortletDataException(e);
1287 }
1288 }
1289
1290 public boolean isPublishToLiveByDefault() {
1291 return true;
1292 }
1293
1294 protected static String getArticlePath(
1295 PortletDataContext context, JournalArticle article) {
1296
1297 StringBuilder sb = new StringBuilder();
1298
1299 sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1300 sb.append("/articles/");
1301 sb.append(article.getArticleId());
1302 sb.append(StringPool.SLASH);
1303 sb.append(article.getVersion());
1304 sb.append(StringPool.SLASH);
1305 sb.append(article.getArticleId());
1306 sb.append(".xml");
1307
1308 return sb.toString();
1309 }
1310
1311 protected static String getArticleImagePath(
1312 PortletDataContext context, JournalArticle article) {
1313
1314 StringBuilder sb = new StringBuilder();
1315
1316 sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1317 sb.append("/articles/");
1318 sb.append(article.getArticleId());
1319 sb.append(StringPool.SLASH);
1320 sb.append(article.getVersion());
1321 sb.append(StringPool.SLASH);
1322
1323 return sb.toString();
1324 }
1325
1326 protected static String getArticleImagePath(
1327 PortletDataContext context, JournalArticle article,
1328 JournalArticleImage articleImage, Image image) {
1329
1330 StringBuilder sb = new StringBuilder();
1331
1332 sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1333 sb.append("/articles/");
1334 sb.append(article.getArticleId());
1335 sb.append(StringPool.SLASH);
1336 sb.append(article.getVersion());
1337 sb.append(StringPool.SLASH);
1338 sb.append(articleImage.getElName());
1339 sb.append(articleImage.getLanguageId());
1340 sb.append(StringPool.PERIOD);
1341 sb.append(image.getType());
1342
1343 return sb.toString();
1344 }
1345
1346 protected static String getArticleSmallImagePath(
1347 PortletDataContext context, JournalArticle article)
1348 throws PortalException, SystemException {
1349
1350 StringBuilder sb = new StringBuilder();
1351
1352 sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1353 sb.append("/articles/thumbnail.");
1354 sb.append(article.getSmallImageType());
1355
1356 return sb.toString();
1357 }
1358
1359 protected static String getFeedPath(
1360 PortletDataContext context, JournalFeed feed) {
1361
1362 StringBuilder sb = new StringBuilder();
1363
1364 sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1365 sb.append("/feeds/");
1366 sb.append(feed.getFeedId());
1367 sb.append(".xml");
1368
1369 return sb.toString();
1370 }
1371
1372 protected static String getTemplatePath(
1373 PortletDataContext context, JournalTemplate template) {
1374
1375 StringBuilder sb = new StringBuilder();
1376
1377 sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1378 sb.append("/templates/");
1379 sb.append(template.getTemplateId());
1380 sb.append(".xml");
1381
1382 return sb.toString();
1383 }
1384
1385 protected static String getTemplateSmallImagePath(
1386 PortletDataContext context, JournalTemplate template)
1387 throws PortalException, SystemException {
1388
1389 StringBuilder sb = new StringBuilder();
1390
1391 sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1392 sb.append("/templates/thumbnail-");
1393 sb.append(template.getTemplateId());
1394 sb.append(template.getSmallImageType());
1395
1396 return sb.toString();
1397 }
1398
1399 protected static String getStructurePath(
1400 PortletDataContext context, JournalStructure structure) {
1401
1402 StringBuilder sb = new StringBuilder();
1403
1404 sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1405 sb.append("/structures/");
1406 sb.append(structure.getStructureId());
1407 sb.append(".xml");
1408
1409 return sb.toString();
1410 }
1411
1412 private static final String _NAMESPACE = "journal";
1413
1414 private static final PortletDataHandlerBoolean _embeddedAssets =
1415 new PortletDataHandlerBoolean(_NAMESPACE, "embedded-assets");
1416
1417 private static final PortletDataHandlerBoolean _images =
1418 new PortletDataHandlerBoolean(_NAMESPACE, "images");
1419
1420 private static final PortletDataHandlerBoolean _comments =
1421 new PortletDataHandlerBoolean(_NAMESPACE, "comments");
1422
1423 private static final PortletDataHandlerBoolean _ratings =
1424 new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
1425
1426 private static final PortletDataHandlerBoolean _tags =
1427 new PortletDataHandlerBoolean(_NAMESPACE, "tags");
1428
1429 private static final PortletDataHandlerBoolean _articles =
1430 new PortletDataHandlerBoolean(_NAMESPACE, "articles", true, false,
1431 new PortletDataHandlerControl[] {_images, _comments, _ratings, _tags});
1432
1433 private static final PortletDataHandlerBoolean
1434 _structuresTemplatesAndFeeds = new PortletDataHandlerBoolean(
1435 _NAMESPACE, "structures-templates-and-feeds", true, true);
1436
1437 private static Log _log =
1438 LogFactory.getLog(JournalPortletDataHandlerImpl.class);
1439
1440}