1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   * 
13   */
14  
15  package com.liferay.portlet.journal.lar;
16  
17  import com.liferay.portal.NoSuchImageException;
18  import com.liferay.portal.PortalException;
19  import com.liferay.portal.SystemException;
20  import com.liferay.portal.kernel.dao.orm.QueryUtil;
21  import com.liferay.portal.kernel.log.Log;
22  import com.liferay.portal.kernel.log.LogFactoryUtil;
23  import com.liferay.portal.kernel.util.CalendarFactoryUtil;
24  import com.liferay.portal.kernel.util.FileUtil;
25  import com.liferay.portal.kernel.util.GetterUtil;
26  import com.liferay.portal.kernel.util.MapUtil;
27  import com.liferay.portal.kernel.util.StringBundler;
28  import com.liferay.portal.kernel.util.StringPool;
29  import com.liferay.portal.kernel.util.StringUtil;
30  import com.liferay.portal.kernel.util.Validator;
31  import com.liferay.portal.kernel.xml.Document;
32  import com.liferay.portal.kernel.xml.Element;
33  import com.liferay.portal.kernel.xml.SAXReaderUtil;
34  import com.liferay.portal.lar.PortletDataContext;
35  import com.liferay.portal.lar.PortletDataException;
36  import com.liferay.portal.lar.PortletDataHandler;
37  import com.liferay.portal.lar.PortletDataHandlerBoolean;
38  import com.liferay.portal.lar.PortletDataHandlerControl;
39  import com.liferay.portal.lar.PortletDataHandlerKeys;
40  import com.liferay.portal.model.Image;
41  import com.liferay.portal.model.User;
42  import com.liferay.portal.service.UserLocalServiceUtil;
43  import com.liferay.portal.service.persistence.ImageUtil;
44  import com.liferay.portal.util.PortletKeys;
45  import com.liferay.portal.util.PropsValues;
46  import com.liferay.portlet.documentlibrary.lar.DLPortletDataHandlerImpl;
47  import com.liferay.portlet.documentlibrary.model.DLFileEntry;
48  import com.liferay.portlet.documentlibrary.model.DLFileRank;
49  import com.liferay.portlet.documentlibrary.model.DLFolder;
50  import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
51  import com.liferay.portlet.imagegallery.lar.IGPortletDataHandlerImpl;
52  import com.liferay.portlet.imagegallery.model.IGFolder;
53  import com.liferay.portlet.imagegallery.model.IGImage;
54  import com.liferay.portlet.imagegallery.service.IGImageLocalServiceUtil;
55  import com.liferay.portlet.journal.model.JournalArticle;
56  import com.liferay.portlet.journal.model.JournalArticleImage;
57  import com.liferay.portlet.journal.model.JournalFeed;
58  import com.liferay.portlet.journal.model.JournalStructure;
59  import com.liferay.portlet.journal.model.JournalTemplate;
60  import com.liferay.portlet.journal.model.impl.JournalArticleImpl;
61  import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
62  import com.liferay.portlet.journal.service.JournalFeedLocalServiceUtil;
63  import com.liferay.portlet.journal.service.JournalStructureLocalServiceUtil;
64  import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
65  import com.liferay.portlet.journal.service.persistence.JournalArticleImageUtil;
66  import com.liferay.portlet.journal.service.persistence.JournalArticleUtil;
67  import com.liferay.portlet.journal.service.persistence.JournalFeedUtil;
68  import com.liferay.portlet.journal.service.persistence.JournalStructureUtil;
69  import com.liferay.portlet.journal.service.persistence.JournalTemplateUtil;
70  import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
71  
72  import java.io.File;
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  
80  import javax.portlet.PortletPreferences;
81  
82  /**
83   * <a href="JournalPortletDataHandlerImpl.java.html"><b><i>View Source</i></b>
84   * </a>
85   *
86   * <p>
87   * Provides the Journal portlet export and import functionality, which is to
88   * clone all articles, structures, and templates associated with the layout's
89   * group. Upon import, new instances of the corresponding articles, structures,
90   * and templates are created or updated according to the DATA_MIRROW strategy
91   * The author of the newly created objects are determined by the
92   * JournalCreationStrategy class defined in <i>portal.properties</i>. That
93   * strategy also allows the text of the journal article to be modified prior to
94   * import.
95   * </p>
96   *
97   * <p>
98   * This <code>PortletDataHandler</code> differs from
99   * <code>JournalContentPortletDataHandlerImpl</code> in that it exports all
100  * articles owned by the group whether or not they are actually displayed in a
101  * portlet in the layout set.
102  * </p>
103  *
104  * @author Raymond Augé
105  * @author Joel Kozikowski
106  * @author Brian Wing Shun Chan
107  * @author Bruno Farache
108  * @author Karthik Sudarshan
109  * @see    com.liferay.portal.lar.PortletDataHandler
110  * @see    com.liferay.portlet.journal.lar.JournalContentPortletDataHandlerImpl
111  * @see    com.liferay.portlet.journal.lar.JournalCreationStrategy
112  */
113 public class JournalPortletDataHandlerImpl implements PortletDataHandler {
114 
115     public static void exportArticle(
116             PortletDataContext context, Element articlesEl, Element dlFoldersEl,
117             Element dlFileEntriesEl, Element dlFileRanks, Element igFoldersEl,
118             Element igImagesEl, JournalArticle article)
119         throws PortalException, SystemException {
120 
121         if (!context.isWithinDateRange(article.getModifiedDate())) {
122             return;
123         }
124 
125         String path = getArticlePath(context, article);
126 
127         if (!context.isPathNotProcessed(path)) {
128             return;
129         }
130 
131         // Clone this article to make sure changes to its content are never
132         // persisted
133 
134         article = (JournalArticle)article.clone();
135 
136         Element articleEl = articlesEl.addElement("article");
137 
138         articleEl.addAttribute("path", path);
139 
140         Image smallImage = ImageUtil.fetchByPrimaryKey(
141             article.getSmallImageId());
142 
143         if (article.isSmallImage() && (smallImage != null)) {
144             String smallImagePath = getArticleSmallImagePath(context, article);
145 
146             articleEl.addAttribute("small-image-path", smallImagePath);
147 
148             article.setSmallImageType(smallImage.getType());
149 
150             context.addZipEntry(smallImagePath, smallImage.getTextObj());
151         }
152 
153         if (context.getBooleanParameter(_NAMESPACE, "images")) {
154             String imagePath = getArticleImagePath(context, article);
155 
156             articleEl.addAttribute("image-path", imagePath);
157 
158             List<JournalArticleImage> articleImages =
159                 JournalArticleImageUtil.findByG_A_V(
160                     article.getGroupId(), article.getArticleId(),
161                     article.getVersion());
162 
163             for (JournalArticleImage articleImage : articleImages) {
164                 try {
165                     Image image = ImageUtil.findByPrimaryKey(
166                         articleImage.getArticleImageId());
167 
168                     String articleImagePath = getArticleImagePath(
169                         context, article, articleImage, image);
170 
171                     if (!context.isPathNotProcessed(articleImagePath)) {
172                         continue;
173                     }
174 
175                     context.addZipEntry(articleImagePath, image.getTextObj());
176                 }
177                 catch (NoSuchImageException nsie) {
178                 }
179             }
180         }
181 
182         if (context.getBooleanParameter(_NAMESPACE, "comments")) {
183             context.addComments(
184                 JournalArticle.class, article.getResourcePrimKey());
185         }
186 
187         if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
188             context.addRatingsEntries(
189                 JournalArticle.class, article.getResourcePrimKey());
190         }
191 
192         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
193             context.addTagsEntries(
194                 JournalArticle.class, article.getResourcePrimKey());
195         }
196 
197         if (context.getBooleanParameter(_NAMESPACE, "embedded-assets")) {
198             String content = article.getContent();
199 
200             content = exportDLFileEntries(
201                 context, dlFoldersEl, dlFileEntriesEl, dlFileRanks,
202                 article.getGroupId(), content);
203             content = exportIGImages(context, igFoldersEl, igImagesEl,
204                 article.getGroupId(), content);
205 
206             article.setContent(content);
207         }
208 
209         article.setUserUuid(article.getUserUuid());
210         article.setApprovedByUserUuid(article.getApprovedByUserUuid());
211 
212         context.addZipEntry(path, article);
213     }
214 
215     public static void exportFeed(
216             PortletDataContext context, Element feedsEl, JournalFeed feed)
217         throws SystemException {
218 
219         if (!context.isWithinDateRange(feed.getModifiedDate())) {
220             return;
221         }
222 
223         String path = getFeedPath(context, feed);
224 
225         if (!context.isPathNotProcessed(path)) {
226             return;
227         }
228 
229         Element feedEl = feedsEl.addElement("feed");
230 
231         feedEl.addAttribute("path", path);
232 
233         feed.setUserUuid(feed.getUserUuid());
234 
235         context.addZipEntry(path, feed);
236     }
237 
238     public static String exportDLFileEntries(
239         PortletDataContext context, Element foldersEl, Element fileEntriesEl,
240         Element fileRanks, long entityGroupId, String content) {
241 
242         StringBuilder sb = new StringBuilder(content);
243 
244         int beginPos = content.length();
245 
246         while (true) {
247             beginPos = content.lastIndexOf("/get_file?", beginPos);
248 
249             if (beginPos == -1) {
250                 return sb.toString();
251             }
252 
253             int endPos1 = content.indexOf(StringPool.APOSTROPHE, beginPos);
254             int endPos2 = content.indexOf(StringPool.CLOSE_BRACKET, beginPos);
255             int endPos3 = content.indexOf(
256                 StringPool.CLOSE_PARENTHESIS, beginPos);
257             int endPos4 = content.indexOf(StringPool.LESS_THAN, beginPos);
258             int endPos5 = content.indexOf(StringPool.QUOTE, beginPos);
259             int endPos6 = content.indexOf(StringPool.SPACE, beginPos);
260 
261             int endPos = endPos1;
262 
263             if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
264                 endPos = endPos2;
265             }
266 
267             if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
268                 endPos = endPos3;
269             }
270 
271             if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
272                 endPos = endPos4;
273             }
274 
275             if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
276                 endPos = endPos5;
277             }
278 
279             if ((endPos == -1) || ((endPos6 != -1) && (endPos6 < endPos))) {
280                 endPos = endPos6;
281             }
282 
283             if ((beginPos == -1) || (endPos == -1)) {
284                 break;
285             }
286 
287             try {
288                 String oldParameters = content.substring(beginPos, endPos);
289 
290                 oldParameters = oldParameters.substring(
291                     oldParameters.indexOf(StringPool.QUESTION) + 1);
292 
293                 boolean hasEncodedAmpersands = false;
294 
295                 while (oldParameters.contains(StringPool.AMPERSAND_ENCODED)) {
296                     hasEncodedAmpersands = true;
297 
298                     oldParameters = oldParameters.replace(
299                         StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
300                 }
301 
302                 Map<String, String> map = MapUtil.toLinkedHashMap(
303                     oldParameters.split(StringPool.AMPERSAND),
304                     StringPool.EQUAL);
305 
306                 DLFileEntry fileEntry = null;
307 
308                 if (map.containsKey("uuid")) {
309                     String uuid = map.get("uuid");
310 
311                     String groupIdString = map.get("groupId");
312 
313                     long groupId = GetterUtil.getLong(groupIdString);
314 
315                     if (groupIdString.equals("@group_id@")) {
316                         groupId = entityGroupId;
317                     }
318 
319                     fileEntry = DLFileEntryLocalServiceUtil.
320                         getFileEntryByUuidAndGroupId(uuid, groupId);
321                 }
322                 else if (map.containsKey("folderId")) {
323                     long folderId = GetterUtil.getLong(map.get("folderId"));
324                     String name = map.get("name");
325 
326                     fileEntry = DLFileEntryLocalServiceUtil.getFileEntry(
327                         folderId, name);
328                 }
329 
330                 if (fileEntry == null) {
331                     beginPos--;
332 
333                     continue;
334                 }
335 
336                 DLPortletDataHandlerImpl.exportFileEntry(
337                     context, foldersEl, fileEntriesEl, fileRanks, fileEntry);
338 
339                 String newParameters =
340                     "/get_file?uuid=" + fileEntry.getUuid() +
341                         "&groupId=@data_handler_group_id@";
342 
343                 if (hasEncodedAmpersands) {
344                     newParameters = newParameters.replace(
345                         StringPool.AMPERSAND, StringPool.AMPERSAND_ENCODED);
346                 }
347 
348                 sb.replace(beginPos, endPos, newParameters);
349             }
350             catch (Exception e) {
351                 if (_log.isWarnEnabled()) {
352                     _log.warn(e);
353                 }
354             }
355 
356             beginPos--;
357         }
358 
359         return sb.toString();
360     }
361 
362     public static String exportIGImages(
363         PortletDataContext context, Element foldersEl, Element imagesEl,
364         long entityGroupId, String content) {
365 
366         StringBuilder sb = new StringBuilder(content);
367 
368         int beginPos = content.length();
369 
370         while (true) {
371             beginPos = content.lastIndexOf("/image_gallery?", beginPos);
372 
373             if (beginPos == -1) {
374                 return sb.toString();
375             }
376 
377             int endPos1 = content.indexOf(StringPool.APOSTROPHE, beginPos);
378             int endPos2 = content.indexOf(StringPool.CLOSE_BRACKET, beginPos);
379             int endPos3 = content.indexOf(
380                 StringPool.CLOSE_PARENTHESIS, beginPos);
381             int endPos4 = content.indexOf(StringPool.LESS_THAN, beginPos);
382             int endPos5 = content.indexOf(StringPool.QUOTE, beginPos);
383             int endPos6 = content.indexOf(StringPool.SPACE, beginPos);
384 
385             int endPos = endPos1;
386 
387             if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
388                 endPos = endPos2;
389             }
390 
391             if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
392                 endPos = endPos3;
393             }
394 
395             if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
396                 endPos = endPos4;
397             }
398 
399             if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
400                 endPos = endPos5;
401             }
402 
403             if ((endPos == -1) || ((endPos6 != -1) && (endPos6 < endPos))) {
404                 endPos = endPos6;
405             }
406 
407             if ((beginPos == -1) || (endPos == -1)) {
408                 break;
409             }
410 
411             try {
412                 String oldParameters = content.substring(beginPos, endPos);
413 
414                 oldParameters = oldParameters.substring(
415                     oldParameters.indexOf(StringPool.QUESTION) + 1);
416 
417                 boolean hasEncodedAmpersands = false;
418 
419                 while (oldParameters.contains(StringPool.AMPERSAND_ENCODED)) {
420                     hasEncodedAmpersands = true;
421 
422                     oldParameters = oldParameters.replace(
423                         StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
424                 }
425 
426                 Map<String, String> map = MapUtil.toLinkedHashMap(
427                     oldParameters.split(StringPool.AMPERSAND),
428                     StringPool.EQUAL);
429 
430                 IGImage image = null;
431 
432                 if (map.containsKey("uuid")) {
433                     String uuid = map.get("uuid");
434 
435                     String groupIdString = map.get("groupId");
436 
437                     long groupId = GetterUtil.getLong(groupIdString);
438 
439                     if (groupIdString.equals("@group_id@")) {
440                         groupId = entityGroupId;
441                     }
442 
443                     image = IGImageLocalServiceUtil.getImageByUuidAndGroupId(
444                         uuid, groupId);
445                 }
446                 else if (map.containsKey("image_id") ||
447                          map.containsKey("img_id") ||
448                          map.containsKey("i_id")) {
449 
450                     long imageId = GetterUtil.getLong(map.get("image_id"));
451 
452                     if (imageId <= 0) {
453                         imageId = GetterUtil.getLong(map.get("img_id"));
454 
455                         if (imageId <= 0) {
456                             imageId = GetterUtil.getLong(map.get("i_id"));
457                         }
458                     }
459 
460                     try {
461                         image = IGImageLocalServiceUtil.getImageByLargeImageId(
462                             imageId);
463                     }
464                     catch (Exception e) {
465                         image = IGImageLocalServiceUtil.getImageBySmallImageId(
466                             imageId);
467                     }
468                 }
469 
470                 if (image == null) {
471                     beginPos--;
472 
473                     continue;
474                 }
475 
476                 IGPortletDataHandlerImpl.exportImage(
477                     context, foldersEl, imagesEl, image);
478 
479                 String timestamp = map.get("t");
480 
481                 if (timestamp == null) {
482                     timestamp = String.valueOf(System.currentTimeMillis());
483                 }
484 
485                 String newParameters =
486                     "/image_gallery?uuid=" + image.getUuid() +
487                         "&groupId=@data_handler_group_id@&t=" + timestamp;
488 
489                 if (hasEncodedAmpersands) {
490                     newParameters = newParameters.replace(
491                         StringPool.AMPERSAND, StringPool.AMPERSAND_ENCODED);
492                 }
493 
494                 sb.replace(beginPos, endPos, newParameters);
495             }
496             catch (Exception e) {
497                 if (_log.isWarnEnabled()) {
498                     _log.warn(e);
499                 }
500             }
501 
502             beginPos--;
503         }
504 
505         return sb.toString();
506     }
507 
508     public static void exportStructure(
509             PortletDataContext context, Element structuresEl,
510             JournalStructure structure)
511         throws SystemException {
512 
513         if (!context.isWithinDateRange(structure.getModifiedDate())) {
514             return;
515         }
516 
517         String path = getStructurePath(context, structure);
518 
519         if (!context.isPathNotProcessed(path)) {
520             return;
521         }
522 
523         Element structureEl = structuresEl.addElement("structure");
524 
525         structureEl.addAttribute("path", path);
526 
527         structure.setUserUuid(structure.getUserUuid());
528 
529         context.addZipEntry(path, structure);
530     }
531 
532     public static void exportTemplate(
533             PortletDataContext context, Element templatesEl,
534             Element dlFoldersEl, Element dlFileEntriesEl, Element dlFileRanks,
535             Element igFoldersEl, Element igImagesEl, JournalTemplate template)
536         throws PortalException, SystemException {
537 
538         if (!context.isWithinDateRange(template.getModifiedDate())) {
539             return;
540         }
541 
542         String path = getTemplatePath(context, template);
543 
544         if (!context.isPathNotProcessed(path)) {
545             return;
546         }
547 
548         // Clone this template to make sure changes to its content are never
549         // persisted
550 
551         template = (JournalTemplate)template.clone();
552 
553         Element templateEl = templatesEl.addElement("template");
554 
555         templateEl.addAttribute("path", path);
556 
557         if (template.isSmallImage()) {
558             String smallImagePath = getTemplateSmallImagePath(
559                 context, template);
560 
561             templateEl.addAttribute("small-image-path", smallImagePath);
562 
563             Image smallImage = ImageUtil.fetchByPrimaryKey(
564                 template.getSmallImageId());
565 
566             template.setSmallImageType(smallImage.getType());
567 
568             context.addZipEntry(smallImagePath, smallImage.getTextObj());
569         }
570 
571         if (context.getBooleanParameter(_NAMESPACE, "embedded-assets")) {
572             String content = template.getXsl();
573 
574             content = exportDLFileEntries(
575                 context, dlFoldersEl, dlFileEntriesEl, dlFileRanks,
576                 template.getGroupId(), content);
577             content = exportIGImages(
578                 context, igFoldersEl, igImagesEl, template.getGroupId(),
579                 content);
580 
581             content = StringUtil.replace(
582                 content, StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
583 
584             template.setXsl(content);
585         }
586 
587         template.setUserUuid(template.getUserUuid());
588 
589         context.addZipEntry(path, template);
590     }
591 
592     public static void importArticle(
593             PortletDataContext context, Map<String, String> structureIds,
594             Map<String, String> templateIds, Map<String, String> articleIds,
595             Element articleEl)
596         throws Exception {
597 
598         String path = articleEl.attributeValue("path");
599 
600         if (!context.isPathNotProcessed(path)) {
601             return;
602         }
603 
604         JournalArticle article = (JournalArticle)context.getZipEntryAsObject(
605             path);
606 
607         long userId = context.getUserId(article.getUserUuid());
608 
609         User user = UserLocalServiceUtil.getUser(userId);
610 
611         long groupId = context.getGroupId();
612         long plid = context.getPlid();
613 
614         String articleId = article.getArticleId();
615         boolean autoArticleId = false;
616 
617         if ((Validator.isNumber(articleId)) ||
618             (JournalArticleUtil.fetchByG_A_V(
619                 context.getGroupId(), articleId,
620                     JournalArticleImpl.DEFAULT_VERSION) != null)) {
621 
622             autoArticleId = true;
623         }
624 
625         String newArticleId = articleIds.get(articleId);
626 
627         if (Validator.isNotNull(newArticleId)) {
628 
629             // A sibling of a different version was already assigned a new
630             // article id
631 
632             articleId = newArticleId;
633             autoArticleId = false;
634         }
635 
636         boolean incrementVersion = false;
637 
638         String content = article.getContent();
639 
640         article.setContent(
641             StringUtil.replace(
642                 content, "@data_handler_group_id@", String.valueOf(groupId)));
643 
644         String parentStructureId = MapUtil.getString(
645             structureIds, article.getStructureId(), article.getStructureId());
646         String parentTemplateId = MapUtil.getString(
647             templateIds, article.getTemplateId(), article.getTemplateId());
648 
649         Date displayDate = article.getDisplayDate();
650 
651         int displayDateMonth = 0;
652         int displayDateDay = 0;
653         int displayDateYear = 0;
654         int displayDateHour = 0;
655         int displayDateMinute = 0;
656 
657         if (displayDate != null) {
658             Calendar displayCal = CalendarFactoryUtil.getCalendar(
659                 user.getTimeZone());
660 
661             displayCal.setTime(displayDate);
662 
663             displayDateMonth = displayCal.get(Calendar.MONTH);
664             displayDateDay = displayCal.get(Calendar.DATE);
665             displayDateYear = displayCal.get(Calendar.YEAR);
666             displayDateHour = displayCal.get(Calendar.HOUR);
667             displayDateMinute = displayCal.get(Calendar.MINUTE);
668 
669             if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
670                 displayDateHour += 12;
671             }
672         }
673 
674         Date expirationDate = article.getExpirationDate();
675 
676         int expirationDateMonth = 0;
677         int expirationDateDay = 0;
678         int expirationDateYear = 0;
679         int expirationDateHour = 0;
680         int expirationDateMinute = 0;
681         boolean neverExpire = true;
682 
683         if (expirationDate != null) {
684             Calendar expirationCal = CalendarFactoryUtil.getCalendar(
685                 user.getTimeZone());
686 
687             expirationCal.setTime(expirationDate);
688 
689             expirationDateMonth = expirationCal.get(Calendar.MONTH);
690             expirationDateDay = expirationCal.get(Calendar.DATE);
691             expirationDateYear = expirationCal.get(Calendar.YEAR);
692             expirationDateHour = expirationCal.get(Calendar.HOUR);
693             expirationDateMinute = expirationCal.get(Calendar.MINUTE);
694             neverExpire = false;
695 
696             if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
697                 expirationDateHour += 12;
698             }
699         }
700 
701         Date reviewDate = article.getReviewDate();
702 
703         int reviewDateMonth = 0;
704         int reviewDateDay = 0;
705         int reviewDateYear = 0;
706         int reviewDateHour = 0;
707         int reviewDateMinute = 0;
708         boolean neverReview = true;
709 
710         if (reviewDate != null) {
711             Calendar reviewCal = CalendarFactoryUtil.getCalendar(
712                 user.getTimeZone());
713 
714             reviewCal.setTime(reviewDate);
715 
716             reviewDateMonth = reviewCal.get(Calendar.MONTH);
717             reviewDateDay = reviewCal.get(Calendar.DATE);
718             reviewDateYear = reviewCal.get(Calendar.YEAR);
719             reviewDateHour = reviewCal.get(Calendar.HOUR);
720             reviewDateMinute = reviewCal.get(Calendar.MINUTE);
721             neverReview = false;
722 
723             if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
724                 reviewDateHour += 12;
725             }
726         }
727 
728         File smallFile = null;
729 
730         String smallImagePath = articleEl.attributeValue("small-image-path");
731 
732         if (article.isSmallImage() && Validator.isNotNull(smallImagePath)) {
733             byte[] bytes = context.getZipEntryAsByteArray(smallImagePath);
734 
735             smallFile = File.createTempFile(
736                 String.valueOf(article.getSmallImageId()),
737                 StringPool.PERIOD + article.getSmallImageType());
738 
739             FileUtil.write(smallFile, bytes);
740         }
741 
742         Map<String, byte[]> images = new HashMap<String, byte[]>();
743 
744         if (context.getBooleanParameter(_NAMESPACE, "images")) {
745             String imagePath = articleEl.attributeValue("image-path");
746 
747             List<String> imageFiles = context.getZipFolderEntries(imagePath);
748 
749             for (String imageFile : imageFiles) {
750                 String fileName = imageFile;
751 
752                 if (fileName.contains(StringPool.SLASH)) {
753                     fileName = fileName.substring(
754                         fileName.lastIndexOf(StringPool.SLASH) + 1);
755                 }
756 
757                 if (fileName.endsWith(".xml")) {
758                     continue;
759                 }
760 
761                 int pos = fileName.lastIndexOf(StringPool.PERIOD);
762 
763                 if (pos != -1) {
764                     fileName = fileName.substring(0, pos);
765                 }
766 
767                 images.put(fileName, context.getZipEntryAsByteArray(imageFile));
768             }
769         }
770 
771         String articleURL = null;
772 
773         PortletPreferences prefs = null;
774 
775         String[] tagsEntries = null;
776 
777         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
778             tagsEntries = context.getTagsEntries(
779                 JournalArticle.class, article.getResourcePrimKey());
780         }
781 
782         JournalCreationStrategy creationStrategy =
783             JournalCreationStrategyFactory.getInstance();
784 
785         long authorId = creationStrategy.getAuthorUserId(context, article);
786 
787         if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
788             userId = authorId;
789         }
790 
791         String newContent = creationStrategy.getTransformedContent(
792             context, article);
793 
794         if (newContent != JournalCreationStrategy.ARTICLE_CONTENT_UNCHANGED) {
795             article.setContent(newContent);
796         }
797 
798         boolean addCommunityPermissions =
799             creationStrategy.addCommunityPermissions(context, article);
800         boolean addGuestPermissions = creationStrategy.addGuestPermissions(
801             context, article);
802 
803         JournalArticle existingArticle = null;
804 
805         if (Validator.isNotNull(article.getStructureId())) {
806             JournalStructure structure = JournalStructureUtil.fetchByG_S(
807                 context.getGroupId(), article.getStructureId());
808 
809             if (structure == null) {
810                 String structurePath = getImportStructurePath(
811                     context, article.getStructureId());
812 
813                 importStructure(context, structureIds, structurePath);
814             }
815         }
816 
817         if (Validator.isNotNull(article.getTemplateId())) {
818             JournalTemplate template = JournalTemplateUtil.fetchByG_T(
819                 context.getGroupId(), article.getTemplateId());
820 
821             if (template == null) {
822                 String templatePath = getImportTemplatePath(
823                     context, article.getTemplateId());
824 
825                 String templateSmallImagePath = getImportTemplateSmallImagePath(
826                     context, article.getTemplateId());
827 
828                 importTemplate(
829                     context, structureIds, templateIds, templateSmallImagePath,
830                     templatePath);
831             }
832         }
833 
834         if (context.getDataStrategy().equals(
835                 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
836 
837             existingArticle = JournalArticleUtil.fetchByUUID_G(
838                 article.getUuid(), context.getGroupId());
839 
840             if (existingArticle == null) {
841                 existingArticle = JournalArticleLocalServiceUtil.addArticle(
842                     article.getUuid(), userId, articleId, autoArticleId,
843                     plid, article.getVersion(), article.getTitle(),
844                     article.getDescription(), article.getContent(),
845                     article.getType(), parentStructureId, parentTemplateId,
846                     displayDateMonth, displayDateDay, displayDateYear,
847                     displayDateHour, displayDateMinute, expirationDateMonth,
848                     expirationDateDay, expirationDateYear, expirationDateHour,
849                     expirationDateMinute, neverExpire, reviewDateMonth,
850                     reviewDateDay, reviewDateYear, reviewDateHour,
851                     reviewDateMinute, neverReview, article.isIndexable(),
852                     article.isSmallImage(), article.getSmallImageURL(),
853                     smallFile, images, articleURL, prefs, tagsEntries,
854                     addCommunityPermissions, addGuestPermissions);
855             }
856             else {
857                 existingArticle = JournalArticleLocalServiceUtil.updateArticle(
858                     userId, existingArticle.getGroupId(),
859                     existingArticle.getArticleId(),
860                     existingArticle.getVersion(), incrementVersion,
861                     article.getTitle(), article.getDescription(),
862                     article.getContent(), article.getType(), parentStructureId,
863                     parentTemplateId, displayDateMonth, displayDateDay,
864                     displayDateYear, displayDateHour, displayDateMinute,
865                     expirationDateMonth, expirationDateDay, expirationDateYear,
866                     expirationDateHour, expirationDateMinute, neverExpire,
867                     reviewDateMonth, reviewDateDay, reviewDateYear,
868                     reviewDateHour, reviewDateMinute, neverReview,
869                     article.isIndexable(), article.isSmallImage(),
870                     article.getSmallImageURL(), smallFile, images, articleURL,
871                     prefs, tagsEntries);
872             }
873         }
874         else {
875             existingArticle = JournalArticleLocalServiceUtil.addArticle(
876                 userId, articleId, autoArticleId, plid, article.getVersion(),
877                 article.getTitle(), article.getDescription(),
878                 article.getContent(), article.getType(), parentStructureId,
879                 parentTemplateId, displayDateMonth, displayDateDay,
880                 displayDateYear, displayDateHour, displayDateMinute,
881                 expirationDateMonth, expirationDateDay, expirationDateYear,
882                 expirationDateHour, expirationDateMinute, neverExpire,
883                 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
884                 reviewDateMinute, neverReview, article.isIndexable(),
885                 article.isSmallImage(), article.getSmallImageURL(), smallFile,
886                 images, articleURL, prefs, tagsEntries, addCommunityPermissions,
887                 addGuestPermissions);
888         }
889 
890         long strategyApprovalUserId = creationStrategy.getApprovalUserId(
891             context, article);
892 
893         if ((strategyApprovalUserId !=
894                 JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) ||
895             (article.isApproved() && !existingArticle.isApproved())) {
896 
897             long approvedByUserId = strategyApprovalUserId;
898 
899             if (approvedByUserId == 0) {
900                 approvedByUserId = context.getUserId(
901                     article.getApprovedByUserUuid());
902             }
903 
904             JournalArticleLocalServiceUtil.approveArticle(
905                 approvedByUserId, context.getGroupId(),
906                 existingArticle.getArticleId(), existingArticle.getVersion(),
907                 articleURL, prefs);
908         }
909 
910         if (context.getBooleanParameter(_NAMESPACE, "comments")) {
911             context.importComments(
912                 JournalArticle.class, article.getResourcePrimKey(),
913                 existingArticle.getResourcePrimKey(), context.getGroupId());
914         }
915 
916         if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
917             context.importRatingsEntries(
918                 JournalArticle.class, article.getResourcePrimKey(),
919                 existingArticle.getResourcePrimKey());
920         }
921 
922         articleIds.put(articleId, existingArticle.getArticleId());
923 
924         if (!articleId.equals(existingArticle.getArticleId())) {
925             if (_log.isWarnEnabled()) {
926                 _log.warn(
927                     "An article with the ID " + articleId + " already " +
928                         "exists. The new generated ID is " +
929                             existingArticle.getArticleId());
930             }
931         }
932     }
933 
934     public static void importFeed(
935             PortletDataContext context, Map<String, String> structureIds,
936             Map<String, String> templateIds, Map<String, String> feedIds,
937             Element feedEl)
938         throws Exception {
939 
940         String path = feedEl.attributeValue("path");
941 
942         if (!context.isPathNotProcessed(path)) {
943             return;
944         }
945 
946         JournalFeed feed = (JournalFeed)context.getZipEntryAsObject(path);
947 
948         long userId = context.getUserId(feed.getUserUuid());
949         long plid = context.getPlid();
950 
951         String feedId = feed.getFeedId();
952         boolean autoFeedId = false;
953 
954         if ((Validator.isNumber(feedId)) ||
955             (JournalFeedUtil.fetchByG_F(
956                 context.getGroupId(), feedId) != null)) {
957 
958             autoFeedId = true;
959         }
960 
961         String parentStructureId = MapUtil.getString(
962             structureIds, feed.getStructureId(), feed.getStructureId());
963         String parentTemplateId = MapUtil.getString(
964             templateIds, feed.getTemplateId(), feed.getTemplateId());
965         String parentRenderTemplateId = MapUtil.getString(
966             templateIds, feed.getRendererTemplateId(),
967             feed.getRendererTemplateId());
968 
969         JournalCreationStrategy creationStrategy =
970             JournalCreationStrategyFactory.getInstance();
971 
972         long authorId = creationStrategy.getAuthorUserId(context, feed);
973 
974         if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
975             userId = authorId;
976         }
977 
978         boolean addCommunityPermissions =
979             creationStrategy.addCommunityPermissions(context, feed);
980         boolean addGuestPermissions = creationStrategy.addGuestPermissions(
981             context, feed);
982 
983         JournalFeed existingFeed = null;
984 
985         if (context.getDataStrategy().equals(
986                 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
987 
988             existingFeed = JournalFeedUtil.fetchByUUID_G(
989                 feed.getUuid(), context.getGroupId());
990 
991             if (existingFeed == null) {
992                 existingFeed = JournalFeedLocalServiceUtil.addFeed(
993                     feed.getUuid(), userId, plid, feedId, autoFeedId,
994                     feed.getName(), feed.getDescription(), feed.getType(),
995                     parentStructureId, parentTemplateId, parentRenderTemplateId,
996                     feed.getDelta(), feed.getOrderByCol(),
997                     feed.getOrderByType(), feed.getTargetLayoutFriendlyUrl(),
998                     feed.getTargetPortletId(), feed.getContentField(),
999                     feed.getFeedType(), feed.getFeedVersion(),
1000                    addCommunityPermissions, addGuestPermissions);
1001            }
1002            else {
1003                existingFeed = JournalFeedLocalServiceUtil.updateFeed(
1004                    existingFeed.getGroupId(), existingFeed.getFeedId(),
1005                    feed.getName(), feed.getDescription(), feed.getType(),
1006                    parentStructureId, parentTemplateId, parentRenderTemplateId,
1007                    feed.getDelta(), feed.getOrderByCol(),
1008                    feed.getOrderByType(), feed.getTargetLayoutFriendlyUrl(),
1009                    feed.getTargetPortletId(), feed.getContentField(),
1010                    feed.getFeedType(), feed.getFeedVersion());
1011            }
1012        }
1013        else {
1014            existingFeed = JournalFeedLocalServiceUtil.addFeed(
1015                userId, plid, feedId, autoFeedId, feed.getName(),
1016                feed.getDescription(), feed.getType(), parentStructureId,
1017                parentTemplateId, parentRenderTemplateId, feed.getDelta(),
1018                feed.getOrderByCol(), feed.getOrderByType(),
1019                feed.getTargetLayoutFriendlyUrl(), feed.getTargetPortletId(),
1020                feed.getContentField(), feed.getFeedType(),
1021                feed.getFeedVersion(), addCommunityPermissions,
1022                addGuestPermissions);
1023        }
1024
1025        feedIds.put(feedId, existingFeed.getFeedId());
1026
1027        if (!feedId.equals(existingFeed.getStructureId())) {
1028            if (_log.isWarnEnabled()) {
1029                _log.warn(
1030                    "A feed with the ID " + feedId + " already " +
1031                        "exists. The new generated ID is " +
1032                            existingFeed.getFeedId());
1033            }
1034        }
1035    }
1036
1037    public static void importStructure(
1038            PortletDataContext context, Map<String, String> structureIds,
1039            Element structureEl)
1040        throws Exception {
1041
1042        String path = structureEl.attributeValue("path");
1043
1044        importStructure(context, structureIds, path);
1045    }
1046
1047    protected static void importStructure(
1048            PortletDataContext context, Map<String, String> structureIds,
1049            String path)
1050        throws Exception {
1051
1052        if (!context.isPathNotProcessed(path)) {
1053            return;
1054        }
1055
1056        JournalStructure structure =
1057            (JournalStructure)context.getZipEntryAsObject(path);
1058
1059        long userId = context.getUserId(structure.getUserUuid());
1060        long plid = context.getPlid();
1061
1062        String structureId = structure.getStructureId();
1063        boolean autoStructureId = false;
1064
1065        if ((Validator.isNumber(structureId)) ||
1066            (JournalStructureUtil.fetchByG_S(
1067                context.getGroupId(), structureId) != null)) {
1068
1069            autoStructureId = true;
1070        }
1071
1072        JournalCreationStrategy creationStrategy =
1073            JournalCreationStrategyFactory.getInstance();
1074
1075        long authorId = creationStrategy.getAuthorUserId(context, structure);
1076
1077        if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
1078            userId = authorId;
1079        }
1080
1081        boolean addCommunityPermissions =
1082            creationStrategy.addCommunityPermissions(context, structure);
1083        boolean addGuestPermissions = creationStrategy.addGuestPermissions(
1084            context, structure);
1085
1086        JournalStructure existingStructure = null;
1087
1088        if (context.getDataStrategy().equals(
1089                PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
1090
1091            existingStructure = JournalStructureUtil.fetchByUUID_G(
1092                structure.getUuid(), context.getGroupId());
1093
1094            if (existingStructure == null) {
1095                existingStructure =
1096                    JournalStructureLocalServiceUtil.addStructure(
1097                        structure.getUuid(), userId, structureId,
1098                        autoStructureId, plid, structure.getName(),
1099                        structure.getDescription(), structure.getXsd(),
1100                        addCommunityPermissions, addGuestPermissions);
1101            }
1102            else {
1103                existingStructure =
1104                    JournalStructureLocalServiceUtil.updateStructure(
1105                        existingStructure.getGroupId(),
1106                        existingStructure.getStructureId(), structure.getName(),
1107                        structure.getDescription(), structure.getXsd());
1108            }
1109        }
1110        else {
1111            existingStructure = JournalStructureLocalServiceUtil.addStructure(
1112                userId, structureId, autoStructureId, plid, structure.getName(),
1113                structure.getDescription(), structure.getXsd(),
1114                addCommunityPermissions, addGuestPermissions);
1115        }
1116
1117        structureIds.put(structureId, existingStructure.getStructureId());
1118
1119        if (!structureId.equals(existingStructure.getStructureId())) {
1120            if (_log.isWarnEnabled()) {
1121                _log.warn(
1122                    "A structure with the ID " + structureId + " already " +
1123                        "exists. The new generated ID is " +
1124                            existingStructure.getStructureId());
1125            }
1126        }
1127    }
1128
1129    public static void importTemplate(
1130            PortletDataContext context, Map<String, String> structureIds,
1131            Map<String, String> templateIds, Element templateEl)
1132        throws Exception {
1133
1134        String path = templateEl.attributeValue("path");
1135
1136        importTemplate(
1137            context, structureIds, templateIds,
1138            templateEl.attributeValue("small-image-path"), path);
1139    }
1140
1141    protected static void importTemplate(
1142            PortletDataContext context, Map<String, String> structureIds,
1143            Map<String, String> templateIds, String smallImagePath, String path)
1144        throws Exception {
1145
1146        if (!context.isPathNotProcessed(path)) {
1147            return;
1148        }
1149
1150        JournalTemplate template = (JournalTemplate)context.getZipEntryAsObject(
1151            path);
1152
1153        long userId = context.getUserId(template.getUserUuid());
1154        long plid = context.getPlid();
1155
1156        String templateId = template.getTemplateId();
1157        boolean autoTemplateId = false;
1158
1159        if ((Validator.isNumber(templateId)) ||
1160            (JournalTemplateUtil.fetchByG_T(
1161                context.getGroupId(), templateId) != null)) {
1162
1163            autoTemplateId = true;
1164        }
1165
1166        String parentStructureId = MapUtil.getString(
1167            structureIds, template.getStructureId(), template.getStructureId());
1168
1169        boolean formatXsl = false;
1170
1171        JournalCreationStrategy creationStrategy =
1172            JournalCreationStrategyFactory.getInstance();
1173
1174        long authorId = creationStrategy.getAuthorUserId(context, template);
1175
1176        if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
1177            userId = authorId;
1178        }
1179
1180        boolean addCommunityPermissions =
1181            creationStrategy.addCommunityPermissions(context, template);
1182        boolean addGuestPermissions = creationStrategy.addGuestPermissions(
1183            context, template);
1184
1185        File smallFile = null;
1186
1187        if (template.isSmallImage() && Validator.isNotNull(smallImagePath)) {
1188            if (smallImagePath.endsWith(StringPool.PERIOD)) {
1189                smallImagePath += template.getSmallImageType();
1190            }
1191
1192            byte[] bytes = context.getZipEntryAsByteArray(smallImagePath);
1193
1194            if (bytes != null) {
1195                smallFile = File.createTempFile(
1196                    String.valueOf(template.getSmallImageId()),
1197                    StringPool.PERIOD + template.getSmallImageType());
1198
1199                FileUtil.write(smallFile, bytes);
1200            }
1201        }
1202
1203        JournalTemplate existingTemplate = null;
1204
1205        if (context.getDataStrategy().equals(
1206                PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
1207
1208            existingTemplate = JournalTemplateUtil.fetchByUUID_G(
1209                template.getUuid(), context.getGroupId());
1210
1211            if (existingTemplate == null) {
1212                existingTemplate = JournalTemplateLocalServiceUtil.addTemplate(
1213                    template.getUuid(), userId, templateId, autoTemplateId,
1214                    plid, parentStructureId, template.getName(),
1215                    template.getDescription(), template.getXsl(), formatXsl,
1216                    template.getLangType(), template.getCacheable(),
1217                    template.isSmallImage(), template.getSmallImageURL(),
1218                    smallFile, addCommunityPermissions, addGuestPermissions);
1219            }
1220            else {
1221                existingTemplate =
1222                    JournalTemplateLocalServiceUtil.updateTemplate(
1223                        existingTemplate.getGroupId(),
1224                        existingTemplate.getTemplateId(),
1225                        existingTemplate.getStructureId(), template.getName(),
1226                        template.getDescription(), template.getXsl(), formatXsl,
1227                        template.getLangType(), template.getCacheable(),
1228                        template.isSmallImage(), template.getSmallImageURL(),
1229                        smallFile);
1230            }
1231        }
1232        else {
1233            existingTemplate = JournalTemplateLocalServiceUtil.addTemplate(
1234                userId, templateId, autoTemplateId, plid, parentStructureId,
1235                template.getName(), template.getDescription(),
1236                template.getXsl(), formatXsl, template.getLangType(),
1237                template.getCacheable(), template.isSmallImage(),
1238                template.getSmallImageURL(), smallFile, addCommunityPermissions,
1239                addGuestPermissions);
1240        }
1241
1242        templateIds.put(templateId, existingTemplate.getTemplateId());
1243
1244        if (!templateId.equals(existingTemplate.getTemplateId())) {
1245            if (_log.isWarnEnabled()) {
1246                _log.warn(
1247                    "A template with the ID " + templateId + " already " +
1248                        "exists. The new generated ID is " +
1249                            existingTemplate.getTemplateId());
1250            }
1251        }
1252    }
1253
1254    public PortletPreferences deleteData(
1255            PortletDataContext context, String portletId,
1256            PortletPreferences prefs)
1257        throws PortletDataException {
1258
1259        try {
1260            if (!context.addPrimaryKey(
1261                    JournalPortletDataHandlerImpl.class, "deleteData")) {
1262
1263                JournalArticleLocalServiceUtil.deleteArticles(
1264                    context.getGroupId());
1265
1266                JournalTemplateLocalServiceUtil.deleteTemplates(
1267                    context.getGroupId());
1268
1269                JournalStructureLocalServiceUtil.deleteStructures(
1270                    context.getGroupId());
1271            }
1272
1273            return prefs;
1274        }
1275        catch (Exception e) {
1276            throw new PortletDataException(e);
1277        }
1278    }
1279
1280    public String exportData(
1281            PortletDataContext context, String portletId,
1282            PortletPreferences prefs)
1283        throws PortletDataException {
1284
1285        try {
1286            Document doc = SAXReaderUtil.createDocument();
1287
1288            Element root = doc.addElement("journal-data");
1289
1290            root.addAttribute("group-id", String.valueOf(context.getGroupId()));
1291
1292            Element structuresEl = root.addElement("structures");
1293
1294            List<JournalStructure> structures =
1295                JournalStructureUtil.findByGroupId(context.getGroupId());
1296
1297            for (JournalStructure structure : structures) {
1298                exportStructure(context, structuresEl, structure);
1299            }
1300
1301            Element templatesEl = root.addElement("templates");
1302            Element dlFoldersEl = root.addElement("dl-folders");
1303            Element dlFilesEl = root.addElement("dl-file-entries");
1304            Element dlFileRanksEl = root.addElement("dl-file-ranks");
1305            Element igFoldersEl = root.addElement("ig-folders");
1306            Element igImagesEl = root.addElement("ig-images");
1307
1308            List<JournalTemplate> templates = JournalTemplateUtil.findByGroupId(
1309                context.getGroupId());
1310
1311            for (JournalTemplate template : templates) {
1312                exportTemplate(
1313                    context, templatesEl, dlFoldersEl, dlFilesEl, dlFileRanksEl,
1314                    igFoldersEl, igImagesEl, template);
1315            }
1316
1317            Element feedsEl = root.addElement("feeds");
1318
1319            List<JournalFeed> feeds = JournalFeedUtil.findByGroupId(
1320                context.getGroupId());
1321
1322            for (JournalFeed feed : feeds) {
1323                if (context.isWithinDateRange(feed.getModifiedDate())) {
1324                    exportFeed(context, feedsEl, feed);
1325                }
1326            }
1327
1328            Element articlesEl = root.addElement("articles");
1329
1330            if (context.getBooleanParameter(_NAMESPACE, "articles")) {
1331                List<JournalArticle> articles =
1332                    JournalArticleUtil.findByGroupId(
1333                        context.getGroupId(), QueryUtil.ALL_POS,
1334                        QueryUtil.ALL_POS, new ArticleIDComparator(true));
1335
1336                for (JournalArticle article : articles) {
1337                    exportArticle(
1338                        context, articlesEl, dlFoldersEl, dlFilesEl,
1339                        dlFileRanksEl, igFoldersEl, igImagesEl, article);
1340                }
1341            }
1342
1343            return doc.formattedString();
1344        }
1345        catch (Exception e) {
1346            throw new PortletDataException(e);
1347        }
1348    }
1349
1350    public PortletDataHandlerControl[] getExportControls() {
1351        return new PortletDataHandlerControl[] {
1352            _articles, _structuresTemplatesAndFeeds, _embeddedAssets, _images,
1353            _comments, _ratings, _tags
1354        };
1355    }
1356
1357    public PortletDataHandlerControl[] getImportControls() {
1358        return new PortletDataHandlerControl[] {
1359            _articles, _structuresTemplatesAndFeeds, _images, _comments,
1360            _ratings, _tags
1361        };
1362    }
1363
1364    public PortletPreferences importData(
1365            PortletDataContext context, String portletId,
1366            PortletPreferences prefs, String data)
1367        throws PortletDataException {
1368
1369        try {
1370            Document doc = SAXReaderUtil.read(data);
1371
1372            Element root = doc.getRootElement();
1373
1374            List<Element> structureEls = root.element("structures").elements(
1375                "structure");
1376
1377            Map<String, String> structureIds =
1378                (Map<String, String>)context.getNewPrimaryKeysMap(
1379                    JournalStructure.class);
1380
1381            for (Element structureEl : structureEls) {
1382                importStructure(context, structureIds, structureEl);
1383            }
1384
1385            List<Element> templateEls = root.element("templates").elements(
1386                "template");
1387
1388            Map<String, String> templateIds =
1389                (Map<String, String>)context.getNewPrimaryKeysMap(
1390                    JournalTemplate.class);
1391
1392            for (Element templateEl : templateEls) {
1393                importTemplate(context, structureIds, templateIds, templateEl);
1394            }
1395
1396            List<Element> feedEls = root.element("feeds").elements("feed");
1397
1398            Map<String, String> feedIds =
1399                (Map<String, String>)context.getNewPrimaryKeysMap(
1400                    JournalFeed.class);
1401
1402            for (Element feedEl : feedEls) {
1403                importFeed(context, structureIds, templateIds, feedIds, feedEl);
1404            }
1405
1406            if (context.getBooleanParameter(_NAMESPACE, "articles")) {
1407                List<Element> articleEls = root.element("articles").elements(
1408                    "article");
1409
1410                Map<String, String> articleIds =
1411                    (Map<String, String>)context.getNewPrimaryKeysMap(
1412                        JournalArticle.class);
1413
1414                for (Element articleEl : articleEls) {
1415                    importArticle(
1416                        context, structureIds, templateIds, articleIds,
1417                        articleEl);
1418                }
1419            }
1420
1421            List<Element> dlFolderEls = root.element("dl-folders").elements(
1422                "folder");
1423
1424            Map<Long, Long> dlFolderPKs =
1425                (Map<Long, Long>)context.getNewPrimaryKeysMap(DLFolder.class);
1426
1427            for (Element folderEl : dlFolderEls) {
1428                String path = folderEl.attributeValue("path");
1429
1430                if (!context.isPathNotProcessed(path)) {
1431                    continue;
1432                }
1433
1434                DLFolder folder = (DLFolder)context.getZipEntryAsObject(path);
1435
1436                DLPortletDataHandlerImpl.importFolder(
1437                    context, dlFolderPKs, folder);
1438            }
1439
1440            List<Element> fileEntryEls = root.element(
1441                "dl-file-entries").elements("file-entry");
1442
1443            Map<String, String> fileEntryNames =
1444                (Map<String, String>)context.getNewPrimaryKeysMap(
1445                    DLFileEntry.class);
1446
1447            for (Element fileEntryEl : fileEntryEls) {
1448                String path = fileEntryEl.attributeValue("path");
1449
1450                if (!context.isPathNotProcessed(path)) {
1451                    continue;
1452                }
1453
1454                DLFileEntry fileEntry = null;
1455
1456                try {
1457                    fileEntry = (DLFileEntry)context.getZipEntryAsObject(path);
1458                }
1459                catch (Exception e) {
1460                    if (_log.isWarnEnabled()) {
1461                        _log.warn("No file entry found for path " + path);
1462                    }
1463
1464                    continue;
1465                }
1466
1467                String binPath = fileEntryEl.attributeValue("bin-path");
1468
1469                DLPortletDataHandlerImpl.importFileEntry(
1470                    context, dlFolderPKs, fileEntryNames, fileEntry, binPath);
1471            }
1472
1473            List<Element> fileRankEls = root.element("dl-file-ranks").elements(
1474                "file-rank");
1475
1476            for (Element fileRankEl : fileRankEls) {
1477                String path = fileRankEl.attributeValue("path");
1478
1479                if (!context.isPathNotProcessed(path)) {
1480                    continue;
1481                }
1482
1483                DLFileRank fileRank = (DLFileRank)context.getZipEntryAsObject(
1484                    path);
1485
1486                DLPortletDataHandlerImpl.importFileRank(
1487                    context, dlFolderPKs, fileEntryNames, fileRank);
1488            }
1489
1490            List<Element> igFolderEls = root.element("ig-folders").elements(
1491                "folder");
1492
1493            Map<Long, Long> igFolderPKs =
1494                (Map<Long, Long>)context.getNewPrimaryKeysMap(IGFolder.class);
1495
1496            for (Element folderEl : igFolderEls) {
1497                String path = folderEl.attributeValue("path");
1498
1499                if (!context.isPathNotProcessed(path)) {
1500                    continue;
1501                }
1502
1503                IGFolder folder = (IGFolder)context.getZipEntryAsObject(path);
1504
1505                IGPortletDataHandlerImpl.importFolder(
1506                    context, igFolderPKs, folder);
1507            }
1508
1509            List<Element> imageEls = root.element("ig-images").elements(
1510                "image");
1511
1512            for (Element imageEl : imageEls) {
1513                String path = imageEl.attributeValue("path");
1514
1515                if (!context.isPathNotProcessed(path)) {
1516                    continue;
1517                }
1518
1519                IGImage image = (IGImage)context.getZipEntryAsObject(path);
1520
1521                String binPath = imageEl.attributeValue("bin-path");
1522
1523                IGPortletDataHandlerImpl.importImage(
1524                    context, igFolderPKs, image, binPath);
1525            }
1526
1527            return prefs;
1528        }
1529        catch (Exception e) {
1530            throw new PortletDataException(e);
1531        }
1532    }
1533
1534    public boolean isPublishToLiveByDefault() {
1535        return PropsValues.JOURNAL_PUBLISH_TO_LIVE_BY_DEFAULT;
1536    }
1537
1538    protected static String getArticlePath(
1539        PortletDataContext context, JournalArticle article) {
1540
1541        StringBundler sb = new StringBundler(8);
1542
1543        sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1544        sb.append("/articles/");
1545        sb.append(article.getArticleId());
1546        sb.append(StringPool.SLASH);
1547        sb.append(article.getVersion());
1548        sb.append(StringPool.SLASH);
1549        sb.append(article.getArticleId());
1550        sb.append(".xml");
1551
1552        return sb.toString();
1553    }
1554
1555    protected static String getArticleImagePath(
1556        PortletDataContext context, JournalArticle article) {
1557
1558        StringBundler sb = new StringBundler(6);
1559
1560        sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1561        sb.append("/articles/");
1562        sb.append(article.getArticleId());
1563        sb.append(StringPool.SLASH);
1564        sb.append(article.getVersion());
1565        sb.append(StringPool.SLASH);
1566
1567        return sb.toString();
1568    }
1569
1570    protected static String getArticleImagePath(
1571        PortletDataContext context, JournalArticle article,
1572        JournalArticleImage articleImage, Image image) {
1573
1574        StringBundler sb = new StringBundler(13);
1575
1576        sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1577        sb.append("/articles/");
1578        sb.append(article.getArticleId());
1579        sb.append(StringPool.SLASH);
1580        sb.append(article.getVersion());
1581        sb.append(StringPool.SLASH);
1582        sb.append(articleImage.getElName());
1583
1584        if (Validator.isNotNull(articleImage.getLanguageId())) {
1585            sb.append(StringPool.UNDERLINE);
1586            sb.append(articleImage.getLanguageId());
1587        }
1588
1589        sb.append(StringPool.PERIOD);
1590        sb.append(image.getType());
1591
1592        return sb.toString();
1593    }
1594
1595    protected static String getArticleSmallImagePath(
1596            PortletDataContext context, JournalArticle article)
1597        throws PortalException, SystemException {
1598
1599        StringBundler sb = new StringBundler(6);
1600
1601        sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1602        sb.append("/articles/");
1603        sb.append(article.getArticleId());
1604        sb.append("/thumbnail");
1605        sb.append(StringPool.PERIOD);
1606        sb.append(article.getSmallImageType());
1607
1608        return sb.toString();
1609    }
1610
1611    protected static String getFeedPath(
1612        PortletDataContext context, JournalFeed feed) {
1613
1614        StringBundler sb = new StringBundler(4);
1615
1616        sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1617        sb.append("/feeds/");
1618        sb.append(feed.getFeedId());
1619        sb.append(".xml");
1620
1621        return sb.toString();
1622    }
1623
1624    protected static String getImportStructurePath(
1625        PortletDataContext context, String structureId) {
1626
1627        StringBundler sb = new StringBundler(4);
1628
1629        sb.append(context.getImportPortletPath(PortletKeys.JOURNAL));
1630        sb.append("/structures/");
1631        sb.append(structureId);
1632        sb.append(".xml");
1633
1634        return sb.toString();
1635    }
1636
1637    protected static String getImportTemplatePath(
1638        PortletDataContext context, String templateId) {
1639
1640        StringBundler sb = new StringBundler(4);
1641
1642        sb.append(context.getImportPortletPath(PortletKeys.JOURNAL));
1643        sb.append("/templates/");
1644        sb.append(templateId);
1645        sb.append(".xml");
1646
1647        return sb.toString();
1648    }
1649
1650    protected static String getImportTemplateSmallImagePath(
1651        PortletDataContext context, String templateId) {
1652
1653        StringBundler sb = new StringBundler(4);
1654
1655        sb.append(context.getImportPortletPath(PortletKeys.JOURNAL));
1656        sb.append("/templates/thumbnail-");
1657        sb.append(templateId);
1658        sb.append(StringPool.PERIOD);
1659
1660        return sb.toString();
1661    }
1662
1663    protected static String getTemplatePath(
1664        PortletDataContext context, JournalTemplate template) {
1665
1666        StringBundler sb = new StringBundler(4);
1667
1668        sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1669        sb.append("/templates/");
1670        sb.append(template.getTemplateId());
1671        sb.append(".xml");
1672
1673        return sb.toString();
1674    }
1675
1676    protected static String getTemplateSmallImagePath(
1677            PortletDataContext context, JournalTemplate template)
1678        throws PortalException, SystemException {
1679
1680        StringBundler sb = new StringBundler(5);
1681
1682        sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1683        sb.append("/templates/thumbnail-");
1684        sb.append(template.getTemplateId());
1685        sb.append(StringPool.PERIOD);
1686        sb.append(template.getSmallImageType());
1687
1688        return sb.toString();
1689    }
1690
1691    protected static String getStructurePath(
1692        PortletDataContext context, JournalStructure structure) {
1693
1694        StringBundler sb = new StringBundler(4);
1695
1696        sb.append(context.getPortletPath(PortletKeys.JOURNAL));
1697        sb.append("/structures/");
1698        sb.append(structure.getStructureId());
1699        sb.append(".xml");
1700
1701        return sb.toString();
1702    }
1703
1704    private static final String _NAMESPACE = "journal";
1705
1706    private static final PortletDataHandlerBoolean _embeddedAssets =
1707        new PortletDataHandlerBoolean(_NAMESPACE, "embedded-assets");
1708
1709    private static final PortletDataHandlerBoolean _images =
1710        new PortletDataHandlerBoolean(_NAMESPACE, "images");
1711
1712    private static final PortletDataHandlerBoolean _comments =
1713        new PortletDataHandlerBoolean(_NAMESPACE, "comments");
1714
1715    private static final PortletDataHandlerBoolean _ratings =
1716        new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
1717
1718    private static final PortletDataHandlerBoolean _tags =
1719        new PortletDataHandlerBoolean(_NAMESPACE, "tags");
1720
1721    private static final PortletDataHandlerBoolean _articles =
1722        new PortletDataHandlerBoolean(_NAMESPACE, "articles", true, false,
1723        new PortletDataHandlerControl[] {_images, _comments, _ratings, _tags});
1724
1725    private static final PortletDataHandlerBoolean
1726        _structuresTemplatesAndFeeds = new PortletDataHandlerBoolean(
1727            _NAMESPACE, "structures-templates-and-feeds", true, true);
1728
1729    private static Log _log = LogFactoryUtil.getLog(
1730        JournalPortletDataHandlerImpl.class);
1731
1732}