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