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