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