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