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