1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.journal.lar;
24  
25  import com.liferay.portal.NoSuchImageException;
26  import com.liferay.portal.PortalException;
27  import com.liferay.portal.SystemException;
28  import com.liferay.portal.kernel.lar.PortletDataContext;
29  import com.liferay.portal.kernel.lar.PortletDataException;
30  import com.liferay.portal.kernel.lar.PortletDataHandler;
31  import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
32  import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
33  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
34  import com.liferay.portal.kernel.util.CalendarFactoryUtil;
35  import com.liferay.portal.kernel.util.ObjectValuePair;
36  import com.liferay.portal.kernel.util.StringPool;
37  import com.liferay.portal.kernel.util.Validator;
38  import com.liferay.portal.model.Image;
39  import com.liferay.portal.service.persistence.ImageUtil;
40  import com.liferay.portal.util.DocumentUtil;
41  import com.liferay.portlet.journal.model.JournalArticle;
42  import com.liferay.portlet.journal.model.JournalArticleImage;
43  import com.liferay.portlet.journal.model.JournalStructure;
44  import com.liferay.portlet.journal.model.JournalTemplate;
45  import com.liferay.portlet.journal.model.impl.JournalArticleImpl;
46  import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
47  import com.liferay.portlet.journal.service.JournalStructureLocalServiceUtil;
48  import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
49  import com.liferay.portlet.journal.service.persistence.JournalArticleImageUtil;
50  import com.liferay.portlet.journal.service.persistence.JournalArticleUtil;
51  import com.liferay.portlet.journal.service.persistence.JournalStructureUtil;
52  import com.liferay.portlet.journal.service.persistence.JournalTemplateUtil;
53  import com.liferay.util.FileUtil;
54  import com.liferay.util.MapUtil;
55  
56  import com.thoughtworks.xstream.XStream;
57  
58  import java.io.File;
59  import java.io.IOException;
60  
61  import java.util.Calendar;
62  import java.util.Date;
63  import java.util.HashMap;
64  import java.util.Iterator;
65  import java.util.List;
66  import java.util.Map;
67  
68  import javax.portlet.PortletPreferences;
69  
70  import org.apache.commons.logging.Log;
71  import org.apache.commons.logging.LogFactory;
72  
73  import org.dom4j.Document;
74  import org.dom4j.DocumentHelper;
75  import org.dom4j.Element;
76  
77  /**
78   * <a href="JournalPortletDataHandlerImpl.java.html"><b><i>View Source</i></b>
79   * </a>
80   *
81   * <p>
82   * Provides the Journal portlet export and import functionality, which is to
83   * clone all articles, structures, and templates associated with the layout's
84   * group. Upon import, new instances of the corresponding articles, structures,
85   * and templates are created or updated according to the DATA_MIRROW strategy
86   * The author of the newly created objects are determined by the
87   * JournalCreationStrategy class defined in <i>portal.properties</i>. That
88   * strategy also allows the text of the journal article to be modified prior
89   * to import.
90   * </p>
91   *
92   * <p>
93   * This <code>PortletDataHandler</code> differs from
94   * <code>JournalContentPortletDataHandlerImpl</code> in that it exports all
95   * articles owned by the group whether or not they are actually displayed in a
96   * portlet in the layout set.
97   * </p>
98   *
99   * @author Raymond Aug�
100  * @author Joel Kozikowski
101  * @author Brian Wing Shun Chan
102  * @author Bruno Farache
103  *
104  * @see com.liferay.portal.kernel.lar.PortletDataHandler
105  * @see com.liferay.portlet.journal.lar.JournalContentPortletDataHandlerImpl
106  * @see com.liferay.portlet.journal.lar.JournalCreationStrategy
107  *
108  */
109 public class JournalPortletDataHandlerImpl implements PortletDataHandler {
110 
111     public PortletPreferences deleteData(
112             PortletDataContext context, String portletId,
113             PortletPreferences prefs)
114         throws PortletDataException {
115 
116         try {
117             if (!context.addPrimaryKey(
118                     JournalPortletDataHandlerImpl.class, "deleteData")) {
119 
120                 List<JournalArticle> articles =
121                     JournalArticleUtil.findByGroupId(
122                         context.getGroupId());
123 
124                 for (JournalArticle article : articles) {
125 
126                     // Templates
127 
128                     JournalTemplateLocalServiceUtil.deleteTemplate(
129                         context.getGroupId(), article.getTemplateId());
130 
131                     // Structures
132 
133                     JournalStructureLocalServiceUtil.deleteStructure(
134                         context.getGroupId(), article.getStructureId());
135                 }
136 
137                 // Articles
138 
139                 JournalArticleLocalServiceUtil.deleteArticles(
140                     context.getGroupId());
141             }
142 
143             return null;
144         }
145         catch (Exception e) {
146             throw new PortletDataException(e);
147         }
148     }
149 
150     public String exportData(
151             PortletDataContext context, String portletId,
152             PortletPreferences prefs)
153         throws PortletDataException {
154 
155         try {
156             XStream xStream = new XStream();
157 
158             Document doc = DocumentHelper.createDocument();
159 
160             Element root = doc.addElement("journal-data");
161 
162             root.addAttribute("group-id", String.valueOf(context.getGroupId()));
163 
164             // Structures
165 
166             List<JournalStructure> structures =
167                 JournalStructureUtil.findByGroupId(
168                     context.getGroupId());
169 
170             Iterator<JournalStructure> structuresItr = structures.iterator();
171 
172             while (structuresItr.hasNext()) {
173                 JournalStructure structure = structuresItr.next();
174 
175                 if (context.addPrimaryKey(
176                         JournalStructure.class, structure.getPrimaryKeyObj())) {
177 
178                     structuresItr.remove();
179                 }
180                 else {
181                     exportStructure(structure);
182                 }
183             }
184 
185             String xml = xStream.toXML(structures);
186 
187             Document tempDoc = DocumentUtil.readDocumentFromXML(xml);
188 
189             Element el = root.addElement("journal-structures");
190 
191             el.content().add(tempDoc.getRootElement().createCopy());
192 
193             // Templates
194 
195             List<JournalTemplate> templates =
196                 JournalTemplateUtil.findByGroupId(context.getGroupId());
197 
198             Iterator<JournalTemplate> templatesItr = templates.iterator();
199 
200             while (templatesItr.hasNext()) {
201                 JournalTemplate template = templatesItr.next();
202 
203                 if (context.addPrimaryKey(
204                         JournalTemplate.class, template.getPrimaryKeyObj())) {
205 
206                     templatesItr.remove();
207                 }
208                 else {
209                     exportTemplate(context, template);
210                 }
211             }
212 
213             xml = xStream.toXML(templates);
214 
215             el = root.addElement("journal-templates");
216 
217             tempDoc = DocumentUtil.readDocumentFromXML(xml);
218 
219             el.content().add(tempDoc.getRootElement().createCopy());
220 
221             // Articles
222 
223             List<JournalArticle> articles = JournalArticleUtil.findByGroupId(
224                 context.getGroupId());
225 
226             Iterator<JournalArticle> articlesItr = articles.iterator();
227 
228             while (articlesItr.hasNext()) {
229                 JournalArticle article = articlesItr.next();
230 
231                 if (context.addPrimaryKey(
232                         JournalArticle.class, article.getPrimaryKeyObj())) {
233 
234                     articlesItr.remove();
235                 }
236                 else {
237                     exportArticle(context, article);
238                 }
239             }
240 
241             xml = xStream.toXML(articles);
242 
243             el = root.addElement("journal-articles");
244 
245             tempDoc = DocumentUtil.readDocumentFromXML(xml);
246 
247             el.content().add(tempDoc.getRootElement().createCopy());
248 
249             return doc.asXML();
250         }
251         catch (Exception e) {
252             throw new PortletDataException(e);
253         }
254     }
255 
256     public PortletDataHandlerControl[] getExportControls()
257         throws PortletDataException {
258 
259         return new PortletDataHandlerControl[] {
260             _articlesStructuresAndTemplates, _images, _comments, _ratings, _tags
261         };
262     }
263 
264     public PortletDataHandlerControl[] getImportControls()
265         throws PortletDataException {
266 
267         return new PortletDataHandlerControl[] {
268             _articlesStructuresAndTemplates, _images, _comments, _ratings, _tags
269         };
270     }
271 
272     public PortletPreferences importData(
273             PortletDataContext context, String portletId,
274             PortletPreferences prefs, String data)
275         throws PortletDataException {
276 
277         try {
278             XStream xStream = new XStream();
279 
280             Document doc = DocumentUtil.readDocumentFromXML(data);
281 
282             Element root = doc.getRootElement();
283 
284             // Structures
285 
286             Element el = root.element("journal-structures").element("list");
287 
288             Document tempDoc = DocumentHelper.createDocument();
289 
290             tempDoc.content().add(el.createCopy());
291 
292             Map<String, String> structureIds = context.getNewPrimaryKeysMap(
293                 JournalStructure.class);
294 
295             List<JournalStructure> structures =
296                 (List<JournalStructure>)xStream.fromXML(tempDoc.asXML());
297 
298             for (JournalStructure structure : structures) {
299                 importStructure(context, structureIds, structure);
300             }
301 
302             // Templates
303 
304             el = root.element("journal-templates").element("list");
305 
306             tempDoc = DocumentHelper.createDocument();
307 
308             tempDoc.content().add(el.createCopy());
309 
310             Map<String, String> templateIds = context.getNewPrimaryKeysMap(
311                 JournalTemplate.class);
312 
313             List<JournalTemplate> templates =
314                 (List<JournalTemplate>)xStream.fromXML(tempDoc.asXML());
315 
316             for (JournalTemplate template : templates) {
317                 importTemplate(context, structureIds, templateIds, template);
318             }
319 
320             // Articles
321 
322             el = root.element("journal-articles").element("list");
323 
324             tempDoc = DocumentHelper.createDocument();
325 
326             tempDoc.content().add(el.createCopy());
327 
328             Map<String, String> articleIds = context.getNewPrimaryKeysMap(
329                 JournalArticle.class);
330 
331             List<JournalArticle> articles =
332                 (List<JournalArticle>)xStream.fromXML(tempDoc.asXML());
333 
334             for (JournalArticle article : articles) {
335                 importArticle(
336                     context, structureIds, templateIds, articleIds, article);
337             }
338 
339             return null;
340         }
341         catch (Exception e) {
342             throw new PortletDataException(e);
343         }
344     }
345 
346     public boolean isPublishToLiveByDefault() {
347         return true;
348     }
349 
350     protected static void exportArticle(
351             PortletDataContext context, JournalArticle article)
352         throws IOException, PortalException, SystemException {
353 
354         article.setUserUuid(article.getUserUuid());
355         article.setApprovedByUserUuid(article.getApprovedByUserUuid());
356 
357         if (article.isSmallImage()) {
358             Image smallImage = ImageUtil.fetchByPrimaryKey(
359                 article.getSmallImageId());
360 
361             article.setSmallImageType(smallImage.getType());
362 
363             context.getZipWriter().addEntry(
364                 getSmallImageDir(article), smallImage.getTextObj());
365         }
366 
367         if (context.getBooleanParameter(_NAMESPACE, "images")) {
368             List<JournalArticleImage> articleImages =
369                 JournalArticleImageUtil.findByG_A_V(
370                     context.getGroupId(), article.getArticleId(),
371                     article.getVersion());
372 
373             for (JournalArticleImage articleImage : articleImages) {
374                 try {
375                     Image image = ImageUtil.findByPrimaryKey(
376                         articleImage.getArticleImageId());
377 
378                     String fileName =
379                         articleImage.getElName() +
380                             articleImage.getLanguageId() + "." +
381                                 image.getType();
382 
383                     context.getZipWriter().addEntry(
384                         getArticleImageDir(article) + fileName,
385                         image.getTextObj());
386                 }
387                 catch (NoSuchImageException nsie) {
388                 }
389             }
390         }
391 
392         if (context.getBooleanParameter(_NAMESPACE, "comments")) {
393             context.addComments(
394                 JournalArticle.class, new Long(article.getResourcePrimKey()));
395         }
396 
397         if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
398             context.addRatingsEntries(
399                 JournalArticle.class, new Long(article.getResourcePrimKey()));
400         }
401 
402         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
403             context.addTagsEntries(
404                 JournalArticle.class, new Long(article.getResourcePrimKey()));
405         }
406     }
407 
408     protected static void exportStructure(JournalStructure structure)
409         throws SystemException {
410 
411         structure.setUserUuid(structure.getUserUuid());
412     }
413 
414     protected static void exportTemplate(
415             PortletDataContext context, JournalTemplate template)
416         throws IOException, PortalException, SystemException {
417 
418         template.setUserUuid(template.getUserUuid());
419 
420         if (template.isSmallImage()) {
421             Image smallImage = ImageUtil.fetchByPrimaryKey(
422                 template.getSmallImageId());
423 
424             template.setSmallImageType(smallImage.getType());
425 
426             context.getZipWriter().addEntry(
427                 getSmallImageDir(template), smallImage.getTextObj());
428         }
429     }
430 
431     protected static String getArticleImageDir(JournalArticle article) {
432         return _ARTICLE_IMAGES_FOLDER + article.getArticleId() + "/" +
433             article.getVersion() + "/";
434     }
435 
436     protected static String getSmallImageDir(JournalArticle article)
437         throws PortalException, SystemException {
438 
439         return _ARTICLE_SMALL_IMAGES_FOLDER + article.getSmallImageId() + "." +
440             article.getSmallImageType();
441     }
442 
443     protected static String getSmallImageDir(JournalTemplate template)
444         throws PortalException, SystemException {
445 
446         return _TEMPLATE_SMALL_IMAGES_FOLDER + template.getSmallImageId() +
447             "." + template.getSmallImageType();
448     }
449 
450     protected static void importArticle(
451             PortletDataContext context, Map<String, String> structureIds,
452             Map<String, String> templateIds, Map<String, String> articleIds,
453             JournalArticle article)
454         throws Exception {
455 
456         long userId = context.getUserId(article.getUserUuid());
457         long plid = context.getPlid();
458 
459         String articleId = article.getArticleId();
460         boolean autoArticleId = false;
461 
462         if ((Validator.isNumber(articleId)) ||
463             (JournalArticleUtil.fetchByG_A_V(
464                 context.getGroupId(), articleId,
465                     JournalArticleImpl.DEFAULT_VERSION) != null)) {
466 
467             autoArticleId = true;
468         }
469 
470         boolean incrementVersion = false;
471 
472         String parentStructureId = MapUtil.getString(
473             structureIds, article.getStructureId(), article.getStructureId());
474         String parentTemplateId = MapUtil.getString(
475             templateIds, article.getTemplateId(), article.getTemplateId());
476 
477         Date displayDate = article.getDisplayDate();
478 
479         int displayDateMonth = 0;
480         int displayDateDay = 0;
481         int displayDateYear = 0;
482         int displayDateHour = 0;
483         int displayDateMinute = 0;
484 
485         if (displayDate != null) {
486             Calendar displayCal = CalendarFactoryUtil.getCalendar();
487 
488             displayCal.setTime(displayDate);
489 
490             displayDateMonth = displayCal.get(Calendar.MONTH);
491             displayDateDay = displayCal.get(Calendar.DATE);
492             displayDateYear = displayCal.get(Calendar.YEAR);
493             displayDateHour = displayCal.get(Calendar.HOUR);
494             displayDateMinute = displayCal.get(Calendar.MINUTE);
495 
496             if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
497                 displayDateHour += 12;
498             }
499         }
500 
501         Date expirationDate = article.getExpirationDate();
502 
503         int expirationDateMonth = 0;
504         int expirationDateDay = 0;
505         int expirationDateYear = 0;
506         int expirationDateHour = 0;
507         int expirationDateMinute = 0;
508         boolean neverExpire = true;
509 
510         if (expirationDate != null) {
511             Calendar expirationCal = CalendarFactoryUtil.getCalendar();
512 
513             expirationCal.setTime(expirationDate);
514 
515             expirationDateMonth = expirationCal.get(Calendar.MONTH);
516             expirationDateDay = expirationCal.get(Calendar.DATE);
517             expirationDateYear = expirationCal.get(Calendar.YEAR);
518             expirationDateHour = expirationCal.get(Calendar.HOUR);
519             expirationDateMinute = expirationCal.get(Calendar.MINUTE);
520             neverExpire = false;
521 
522             if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
523                 expirationDateHour += 12;
524             }
525         }
526 
527         Date reviewDate = article.getReviewDate();
528 
529         int reviewDateMonth = 0;
530         int reviewDateDay = 0;
531         int reviewDateYear = 0;
532         int reviewDateHour = 0;
533         int reviewDateMinute = 0;
534         boolean neverReview = true;
535 
536         if (reviewDate != null) {
537             Calendar reviewCal = CalendarFactoryUtil.getCalendar();
538 
539             reviewCal.setTime(reviewDate);
540 
541             reviewDateMonth = reviewCal.get(Calendar.MONTH);
542             reviewDateDay = reviewCal.get(Calendar.DATE);
543             reviewDateYear = reviewCal.get(Calendar.YEAR);
544             reviewDateHour = reviewCal.get(Calendar.HOUR);
545             reviewDateMinute = reviewCal.get(Calendar.MINUTE);
546             neverReview = false;
547 
548             if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
549                 reviewDateHour += 12;
550             }
551         }
552 
553         File smallFile = null;
554 
555         if (article.isSmallImage()) {
556             byte[] byteArray = context.getZipReader().getEntryAsByteArray(
557                 getSmallImageDir(article));
558 
559             smallFile = File.createTempFile(
560                 String.valueOf(article.getSmallImageId()),
561                 StringPool.PERIOD + article.getSmallImageType());
562 
563             FileUtil.write(smallFile, byteArray);
564         }
565 
566         Map<String, byte[]> images = new HashMap<String, byte[]>();
567 
568         if (context.getBooleanParameter(_NAMESPACE, "images")) {
569             List<ObjectValuePair<String, byte[]>> imageFiles =
570                 context.getZipReader().getFolderEntries().get(
571                     getArticleImageDir(article));
572 
573             if (imageFiles != null) {
574                 for (ObjectValuePair<String, byte[]> imageFile : imageFiles) {
575                     String fileName = imageFile.getKey();
576 
577                     int pos = fileName.lastIndexOf(".");
578 
579                     if (pos != -1) {
580                         fileName = fileName.substring(0, pos);
581                     }
582 
583                     images.put(fileName, imageFile.getValue());
584                 }
585             }
586         }
587 
588         String articleURL = null;
589 
590         PortletPreferences prefs = null;
591 
592         String[] tagsEntries = null;
593 
594         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
595             tagsEntries = context.getTagsEntries(
596                 JournalArticle.class, new Long(article.getResourcePrimKey()));
597         }
598 
599         JournalCreationStrategy creationStrategy =
600             JournalCreationStrategyFactory.getInstance();
601 
602         long authorId = creationStrategy.getAuthorUserId(context, article);
603 
604         if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
605             userId = authorId;
606         }
607 
608         String newContent = creationStrategy.getTransformedContent(
609             context, article);
610 
611         if (newContent != JournalCreationStrategy.ARTICLE_CONTENT_UNCHANGED) {
612             article.setContent(newContent);
613         }
614 
615         boolean addCommunityPermissions =
616             creationStrategy.addCommunityPermissions(context, article);
617         boolean addGuestPermissions = creationStrategy.addGuestPermissions(
618             context, article);
619 
620         JournalArticle existingArticle = null;
621 
622         if (context.getDataStrategy().equals(
623                 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
624 
625             existingArticle = JournalArticleUtil.fetchByUUID_G(
626                 article.getUuid(), context.getGroupId());
627 
628             if (existingArticle == null) {
629                 existingArticle =  JournalArticleLocalServiceUtil.addArticle(
630                     article.getUuid(), userId, articleId, autoArticleId, plid,
631                     article.getVersion(), article.getTitle(),
632                     article.getDescription(), article.getContent(),
633                     article.getType(), parentStructureId, parentTemplateId,
634                     displayDateMonth, displayDateDay, displayDateYear,
635                     displayDateHour, displayDateMinute, expirationDateMonth,
636                     expirationDateDay, expirationDateYear, expirationDateHour,
637                     expirationDateMinute, neverExpire, reviewDateMonth,
638                     reviewDateDay, reviewDateYear, reviewDateHour,
639                     reviewDateMinute, neverReview, article.getIndexable(),
640                     article.getSmallImage(), article.getSmallImageURL(),
641                     smallFile, images, articleURL, prefs, tagsEntries,
642                     addCommunityPermissions, addGuestPermissions);
643             }
644             else {
645                 existingArticle =  JournalArticleLocalServiceUtil.updateArticle(
646                     userId, existingArticle.getGroupId(),
647                     existingArticle.getArticleId(),
648                     existingArticle.getVersion(), incrementVersion,
649                     article.getTitle(), article.getDescription(),
650                     article.getContent(), article.getType(),
651                     existingArticle.getStructureId(),
652                     existingArticle.getTemplateId(), displayDateMonth,
653                     displayDateDay, displayDateYear, displayDateHour,
654                     displayDateMinute, expirationDateMonth,
655                     expirationDateDay, expirationDateYear, expirationDateHour,
656                     expirationDateMinute, neverExpire, reviewDateMonth,
657                     reviewDateDay, reviewDateYear, reviewDateHour,
658                     reviewDateMinute, neverReview, article.getIndexable(),
659                     article.getSmallImage(), article.getSmallImageURL(),
660                     smallFile, images, articleURL, prefs, tagsEntries);
661             }
662         }
663         else {
664             existingArticle = JournalArticleLocalServiceUtil.addArticle(
665                 userId, articleId, autoArticleId, plid, article.getVersion(),
666                 article.getTitle(), article.getDescription(),
667                 article.getContent(), article.getType(), parentStructureId,
668                 parentTemplateId, displayDateMonth, displayDateDay,
669                 displayDateYear, displayDateHour, displayDateMinute,
670                 expirationDateMonth, expirationDateDay, expirationDateYear,
671                 expirationDateHour, expirationDateMinute, neverExpire,
672                 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
673                 reviewDateMinute, neverReview, article.getIndexable(),
674                 article.getSmallImage(), article.getSmallImageURL(), smallFile,
675                 images, articleURL, prefs, tagsEntries, addCommunityPermissions,
676                 addGuestPermissions);
677         }
678 
679         long strategyApprovalUserId = creationStrategy.getApprovalUserId(
680             context, article);
681 
682         if ((strategyApprovalUserId !=
683                 JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) ||
684             (article.isApproved() && !existingArticle.isApproved())) {
685 
686             long approvedByUserId = strategyApprovalUserId;
687 
688             if (approvedByUserId == 0) {
689                 approvedByUserId = context.getUserId(
690                     article.getApprovedByUserUuid());
691             }
692 
693             JournalArticleLocalServiceUtil.approveArticle(
694                 approvedByUserId, context.getGroupId(),
695                 existingArticle.getArticleId(), existingArticle.getVersion(),
696                 articleURL, prefs);
697         }
698 
699         if (context.getBooleanParameter(_NAMESPACE, "comments")) {
700             context.importComments(
701                 JournalArticle.class, new Long(article.getResourcePrimKey()),
702                 new Long(existingArticle.getResourcePrimKey()),
703                 context.getGroupId());
704         }
705 
706         if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
707             context.importRatingsEntries(
708                 JournalArticle.class, new Long(article.getResourcePrimKey()),
709                 new Long(existingArticle.getResourcePrimKey()));
710         }
711 
712         articleIds.put(
713             article.getArticleId(), existingArticle.getArticleId());
714 
715         if (!articleId.equals(existingArticle.getArticleId())) {
716             if (_log.isWarnEnabled()) {
717                 _log.warn(
718                     "An article with the ID " + articleId + " already " +
719                         "exists. The new generated ID is " +
720                             existingArticle.getArticleId());
721             }
722         }
723     }
724 
725     protected static void importStructure(
726             PortletDataContext context, Map<String, String> structureIds,
727             JournalStructure structure)
728         throws Exception {
729 
730         long userId = context.getUserId(structure.getUserUuid());
731         long plid = context.getPlid();
732 
733         String structureId = structure.getStructureId();
734         boolean autoStructureId = false;
735 
736         if ((Validator.isNumber(structureId)) ||
737             (JournalStructureUtil.fetchByG_S(
738                 context.getGroupId(), structureId) != null)) {
739 
740             autoStructureId = true;
741         }
742 
743         JournalCreationStrategy creationStrategy =
744             JournalCreationStrategyFactory.getInstance();
745 
746         long authorId = creationStrategy.getAuthorUserId(context, structure);
747 
748         if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
749             userId = authorId;
750         }
751 
752         boolean addCommunityPermissions =
753             creationStrategy.addCommunityPermissions(context, structure);
754         boolean addGuestPermissions = creationStrategy.addGuestPermissions(
755             context, structure);
756 
757         JournalStructure existingStructure = null;
758 
759         if (context.getDataStrategy().equals(
760                 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
761 
762             existingStructure = JournalStructureUtil.fetchByUUID_G(
763                 structure.getUuid(), context.getGroupId());
764 
765             if (existingStructure == null) {
766                 existingStructure =
767                     JournalStructureLocalServiceUtil.addStructure(
768                         structure.getUuid(), userId, structureId,
769                         autoStructureId, plid, structure.getName(),
770                         structure.getDescription(), structure.getXsd(),
771                         addCommunityPermissions, addGuestPermissions);
772             }
773             else {
774                 existingStructure =
775                     JournalStructureLocalServiceUtil.updateStructure(
776                         existingStructure.getGroupId(),
777                         existingStructure.getStructureId(), structure.getName(),
778                         structure.getDescription(), structure.getXsd());
779             }
780         }
781         else {
782             existingStructure =
783                 JournalStructureLocalServiceUtil.addStructure(
784                     userId, structureId, autoStructureId, plid,
785                     structure.getName(), structure.getDescription(),
786                     structure.getXsd(), addCommunityPermissions,
787                     addGuestPermissions);
788         }
789 
790         structureIds.put(
791             structure.getStructureId(), existingStructure.getStructureId());
792 
793         if (!structureId.equals(existingStructure.getStructureId())) {
794             if (_log.isWarnEnabled()) {
795                 _log.warn(
796                     "A structure with the ID " + structureId + " already " +
797                         "exists. The new generated ID is " +
798                             existingStructure.getStructureId());
799             }
800         }
801     }
802 
803     protected static void importTemplate(
804             PortletDataContext context, Map<String, String> structureIds,
805             Map<String, String> templateIds, JournalTemplate template)
806         throws Exception {
807 
808         long userId = context.getUserId(template.getUserUuid());
809         long plid = context.getPlid();
810 
811         String templateId = template.getTemplateId();
812         boolean autoTemplateId = false;
813 
814         if ((Validator.isNumber(templateId)) ||
815             (JournalTemplateUtil.fetchByG_T(
816                 context.getGroupId(), templateId) != null)) {
817 
818             autoTemplateId = true;
819         }
820 
821         String parentStructureId = MapUtil.getString(
822             structureIds, template.getStructureId(), template.getStructureId());
823 
824         boolean formatXsl = false;
825 
826         JournalCreationStrategy creationStrategy =
827             JournalCreationStrategyFactory.getInstance();
828 
829         long authorId = creationStrategy.getAuthorUserId(context, template);
830 
831         if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
832             userId = authorId;
833         }
834 
835         boolean addCommunityPermissions =
836             creationStrategy.addCommunityPermissions(context, template);
837         boolean addGuestPermissions = creationStrategy.addGuestPermissions(
838             context, template);
839 
840         File smallFile = null;
841 
842         if (template.isSmallImage()) {
843             byte[] byteArray = context.getZipReader().getEntryAsByteArray(
844                 getSmallImageDir(template));
845 
846             smallFile = File.createTempFile(
847                 String.valueOf(template.getSmallImageId()),
848                 StringPool.PERIOD + template.getSmallImageType());
849 
850             FileUtil.write(smallFile, byteArray);
851         }
852 
853         JournalTemplate existingTemplate = null;
854 
855         if (context.getDataStrategy().equals(
856                 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
857 
858             existingTemplate = JournalTemplateUtil.fetchByUUID_G(
859                 template.getUuid(), context.getGroupId());
860 
861             if (existingTemplate == null) {
862                 existingTemplate =
863                     JournalTemplateLocalServiceUtil.addTemplate(
864                         template.getUuid(), userId, templateId, autoTemplateId,
865                         plid, parentStructureId, template.getName(),
866                         template.getDescription(), template.getXsl(), formatXsl,
867                         template.getLangType(), template.getCacheable(),
868                         template.isSmallImage(), template.getSmallImageURL(),
869                         smallFile, addCommunityPermissions,
870                         addGuestPermissions);
871             }
872             else {
873                 existingTemplate =
874                     JournalTemplateLocalServiceUtil.updateTemplate(
875                         existingTemplate.getGroupId(),
876                         existingTemplate.getTemplateId(),
877                         existingTemplate.getStructureId(), template.getName(),
878                         template.getDescription(), template.getXsl(), formatXsl,
879                         template.getLangType(), template.getCacheable(),
880                         template.isSmallImage(), template.getSmallImageURL(),
881                         smallFile);
882             }
883         }
884         else {
885             existingTemplate =
886                 JournalTemplateLocalServiceUtil.addTemplate(
887                     userId, templateId, autoTemplateId, plid, parentStructureId,
888                     template.getName(), template.getDescription(),
889                     template.getXsl(), formatXsl, template.getLangType(),
890                     template.getCacheable(), template.isSmallImage(),
891                     template.getSmallImageURL(), smallFile,
892                     addCommunityPermissions, addGuestPermissions);
893         }
894 
895         templateIds.put(
896             template.getTemplateId(), existingTemplate.getTemplateId());
897 
898         if (!templateId.equals(existingTemplate.getTemplateId())) {
899             if (_log.isWarnEnabled()) {
900                 _log.warn(
901                     "A template with the ID " + templateId + " already " +
902                         "exists. The new generated ID is " +
903                             existingTemplate.getTemplateId());
904             }
905         }
906     }
907 
908     private static final String _NAMESPACE = "journal";
909 
910     private static final String _ARTICLE_IMAGES_FOLDER =
911         "article-images/";
912 
913     private static final String _ARTICLE_SMALL_IMAGES_FOLDER =
914         "article-thumbnails/";
915 
916     private static final String _TEMPLATE_SMALL_IMAGES_FOLDER =
917         "template-thumbnails/";
918 
919     private static final PortletDataHandlerBoolean
920         _articlesStructuresAndTemplates = new PortletDataHandlerBoolean(
921             _NAMESPACE, "articles-structures-and-templates", true, true);
922 
923     private static final PortletDataHandlerBoolean _images =
924         new PortletDataHandlerBoolean(_NAMESPACE, "images");
925 
926     private static final PortletDataHandlerBoolean _comments =
927         new PortletDataHandlerBoolean(_NAMESPACE, "comments");
928 
929     private static final PortletDataHandlerBoolean _ratings =
930         new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
931 
932     private static final PortletDataHandlerBoolean _tags =
933         new PortletDataHandlerBoolean(_NAMESPACE, "tags");
934 
935     private static Log _log =
936         LogFactory.getLog(JournalPortletDataHandlerImpl.class);
937 
938 }