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