001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.journal.lar;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.json.JSONFactoryUtil;
020    import com.liferay.portal.kernel.json.JSONObject;
021    import com.liferay.portal.kernel.lar.BaseStagedModelDataHandler;
022    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
023    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
024    import com.liferay.portal.kernel.lar.PortletDataContext;
025    import com.liferay.portal.kernel.lar.PortletDataException;
026    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
027    import com.liferay.portal.kernel.lar.StagedModelModifiedDateComparator;
028    import com.liferay.portal.kernel.trash.TrashHandler;
029    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
030    import com.liferay.portal.kernel.util.FileUtil;
031    import com.liferay.portal.kernel.util.GetterUtil;
032    import com.liferay.portal.kernel.util.ListUtil;
033    import com.liferay.portal.kernel.util.MapUtil;
034    import com.liferay.portal.kernel.util.StringBundler;
035    import com.liferay.portal.kernel.util.StringPool;
036    import com.liferay.portal.kernel.util.Validator;
037    import com.liferay.portal.kernel.workflow.WorkflowConstants;
038    import com.liferay.portal.kernel.xml.Element;
039    import com.liferay.portal.model.Group;
040    import com.liferay.portal.model.Image;
041    import com.liferay.portal.model.Layout;
042    import com.liferay.portal.model.User;
043    import com.liferay.portal.service.ImageLocalServiceUtil;
044    import com.liferay.portal.service.ServiceContext;
045    import com.liferay.portal.service.UserLocalServiceUtil;
046    import com.liferay.portal.util.PortalUtil;
047    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
048    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
049    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
050    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
051    import com.liferay.portlet.journal.model.JournalArticle;
052    import com.liferay.portlet.journal.model.JournalArticleConstants;
053    import com.liferay.portlet.journal.model.JournalArticleImage;
054    import com.liferay.portlet.journal.model.JournalArticleResource;
055    import com.liferay.portlet.journal.model.JournalFolder;
056    import com.liferay.portlet.journal.model.JournalFolderConstants;
057    import com.liferay.portlet.journal.service.JournalArticleImageLocalServiceUtil;
058    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
059    import com.liferay.portlet.journal.service.JournalArticleResourceLocalServiceUtil;
060    
061    import java.io.File;
062    
063    import java.util.Calendar;
064    import java.util.Date;
065    import java.util.HashMap;
066    import java.util.List;
067    import java.util.Map;
068    
069    /**
070     * @author Daniel Kocsis
071     * @author Mate Thurzo
072     */
073    public class JournalArticleStagedModelDataHandler
074            extends BaseStagedModelDataHandler<JournalArticle> {
075    
076            public static final String[] CLASS_NAMES = {JournalArticle.class.getName()};
077    
078            @Override
079            public void deleteStagedModel(
080                            String uuid, long groupId, String className, String extraData)
081                    throws PortalException {
082    
083                    JournalArticleResource articleResource =
084                            JournalArticleResourceLocalServiceUtil.
085                                    fetchJournalArticleResourceByUuidAndGroupId(uuid, groupId);
086    
087                    if (articleResource == null) {
088                            return;
089                    }
090    
091                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject(
092                            extraData);
093    
094                    if (Validator.isNotNull(extraData) && extraDataJSONObject.has("uuid")) {
095                            String articleUuid = extraDataJSONObject.getString("uuid");
096    
097                            JournalArticle article = fetchStagedModelByUuidAndGroupId(
098                                    articleUuid, groupId);
099    
100                            JournalArticleLocalServiceUtil.deleteArticle(article);
101                    }
102                    else {
103                            JournalArticleLocalServiceUtil.deleteArticle(
104                                    groupId, articleResource.getArticleId(), null);
105                    }
106            }
107    
108            @Override
109            public JournalArticle fetchStagedModelByUuidAndCompanyId(
110                    String uuid, long companyId) {
111    
112                    List<JournalArticle> articles =
113                            JournalArticleLocalServiceUtil.getJournalArticlesByUuidAndCompanyId(
114                                    uuid, companyId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
115                                    new StagedModelModifiedDateComparator<JournalArticle>());
116    
117                    if (ListUtil.isEmpty(articles)) {
118                            return null;
119                    }
120    
121                    return articles.get(0);
122            }
123    
124            @Override
125            public JournalArticle fetchStagedModelByUuidAndGroupId(
126                    String uuid, long groupId) {
127    
128                    return JournalArticleLocalServiceUtil.
129                            fetchJournalArticleByUuidAndGroupId(uuid, groupId);
130            }
131    
132            @Override
133            public String[] getClassNames() {
134                    return CLASS_NAMES;
135            }
136    
137            @Override
138            public String getDisplayName(JournalArticle article) {
139                    return article.getTitleCurrentValue();
140            }
141    
142            @Override
143            public int[] getExportableStatuses() {
144                    return new int[] {
145                            WorkflowConstants.STATUS_APPROVED, WorkflowConstants.STATUS_EXPIRED,
146                            WorkflowConstants.STATUS_SCHEDULED
147                    };
148            }
149    
150            @Override
151            public Map<String, String> getReferenceAttributes(
152                    PortletDataContext portletDataContext, JournalArticle article) {
153    
154                    Map<String, String> referenceAttributes = new HashMap<String, String>();
155    
156                    String articleResourceUuid = null;
157    
158                    try {
159                            articleResourceUuid = article.getArticleResourceUuid();
160                    }
161                    catch (Exception e) {
162                            throw new IllegalStateException(
163                                    "Unable to find article resource for article " +
164                                            article.getArticleId());
165                    }
166    
167                    referenceAttributes.put("article-resource-uuid", articleResourceUuid);
168    
169                    referenceAttributes.put("article-id", article.getArticleId());
170    
171                    long defaultUserId = 0;
172    
173                    try {
174                            defaultUserId = UserLocalServiceUtil.getDefaultUserId(
175                                    article.getCompanyId());
176                    }
177                    catch (Exception e) {
178                            return referenceAttributes;
179                    }
180    
181                    boolean preloaded = false;
182    
183                    if (defaultUserId == article.getUserId()) {
184                            preloaded = true;
185                    }
186    
187                    referenceAttributes.put("preloaded", String.valueOf(preloaded));
188    
189                    return referenceAttributes;
190            }
191    
192            @Override
193            public void importMissingReference(
194                            PortletDataContext portletDataContext, Element referenceElement)
195                    throws PortletDataException {
196    
197                    importMissingGroupReference(portletDataContext, referenceElement);
198    
199                    String uuid = referenceElement.attributeValue("uuid");
200                    String articleResourceUuid = referenceElement.attributeValue(
201                            "article-resource-uuid");
202    
203                    Map<Long, Long> groupIds =
204                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
205                                    Group.class);
206    
207                    long liveGroupId = GetterUtil.getLong(
208                            referenceElement.attributeValue("live-group-id"));
209    
210                    liveGroupId = MapUtil.getLong(groupIds, liveGroupId);
211    
212                    String articleArticleId = referenceElement.attributeValue("article-id");
213                    boolean preloaded = GetterUtil.getBoolean(
214                            referenceElement.attributeValue("preloaded"));
215    
216                    JournalArticle existingArticle = null;
217    
218                    existingArticle = fetchExistingArticle(
219                            uuid, articleResourceUuid, liveGroupId, articleArticleId, null, 0.0,
220                            preloaded);
221    
222                    Map<String, String> articleArticleIds =
223                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
224                                    JournalArticle.class + ".articleId");
225    
226                    articleArticleIds.put(articleArticleId, existingArticle.getArticleId());
227    
228                    Map<Long, Long> articleIds =
229                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
230                                    JournalArticle.class);
231    
232                    long articleId = GetterUtil.getLong(
233                            referenceElement.attributeValue("class-pk"));
234    
235                    articleIds.put(articleId, existingArticle.getId());
236            }
237    
238            @Override
239            public boolean validateReference(
240                    PortletDataContext portletDataContext, Element referenceElement) {
241    
242                    validateMissingGroupReference(portletDataContext, referenceElement);
243    
244                    String uuid = referenceElement.attributeValue("uuid");
245                    String articleResourceUuid = referenceElement.attributeValue(
246                            "article-resource-uuid");
247    
248                    Map<Long, Long> groupIds =
249                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
250                                    Group.class);
251    
252                    long liveGroupId = GetterUtil.getLong(
253                            referenceElement.attributeValue("live-group-id"));
254    
255                    liveGroupId = MapUtil.getLong(groupIds, liveGroupId);
256    
257                    String articleArticleId = referenceElement.attributeValue("article-id");
258                    boolean preloaded = GetterUtil.getBoolean(
259                            referenceElement.attributeValue("preloaded"));
260    
261                    JournalArticle existingArticle = fetchExistingArticle(
262                            uuid, articleResourceUuid, liveGroupId, articleArticleId, null, 0.0,
263                            preloaded);
264    
265                    if (existingArticle == null) {
266                            return false;
267                    }
268    
269                    return true;
270            }
271    
272            @Override
273            protected boolean countStagedModel(
274                    PortletDataContext portletDataContext, JournalArticle article) {
275    
276                    return !portletDataContext.isModelCounted(
277                            JournalArticleResource.class.getName(),
278                            article.getResourcePrimKey());
279            }
280    
281            @Override
282            protected void doExportStagedModel(
283                            PortletDataContext portletDataContext, JournalArticle article)
284                    throws Exception {
285    
286                    Element articleElement = portletDataContext.getExportDataElement(
287                            article);
288    
289                    articleElement.addAttribute(
290                            "article-resource-uuid", article.getArticleResourceUuid());
291    
292                    if (article.getFolderId() !=
293                                    JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
294    
295                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
296                                    portletDataContext, article, article.getFolder(),
297                                    PortletDataContext.REFERENCE_TYPE_PARENT);
298                    }
299    
300                    DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(
301                            article.getGroupId(),
302                            PortalUtil.getClassNameId(JournalArticle.class),
303                            article.getStructureId(), true);
304    
305                    StagedModelDataHandlerUtil.exportReferenceStagedModel(
306                            portletDataContext, article, ddmStructure,
307                            PortletDataContext.REFERENCE_TYPE_STRONG);
308    
309                    DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
310                            article.getGroupId(), PortalUtil.getClassNameId(DDMStructure.class),
311                            article.getTemplateId(), true);
312    
313                    StagedModelDataHandlerUtil.exportReferenceStagedModel(
314                            portletDataContext, article, ddmTemplate,
315                            PortletDataContext.REFERENCE_TYPE_STRONG);
316    
317                    Layout layout = article.getLayout();
318    
319                    if (layout != null) {
320                            portletDataContext.addReferenceElement(
321                                    article, articleElement, layout,
322                                    PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
323                    }
324    
325                    if (article.isSmallImage()) {
326                            Image smallImage = ImageLocalServiceUtil.fetchImage(
327                                    article.getSmallImageId());
328    
329                            if (Validator.isNotNull(article.getSmallImageURL())) {
330                                    String smallImageURL =
331                                            ExportImportHelperUtil.replaceExportContentReferences(
332                                                    portletDataContext, article,
333                                                    article.getSmallImageURL() + StringPool.SPACE, true);
334    
335                                    article.setSmallImageURL(smallImageURL);
336                            }
337                            else if (smallImage != null) {
338                                    String smallImagePath = ExportImportPathUtil.getModelPath(
339                                            article,
340                                            smallImage.getImageId() + StringPool.PERIOD +
341                                                    smallImage.getType());
342    
343                                    articleElement.addAttribute("small-image-path", smallImagePath);
344    
345                                    article.setSmallImageType(smallImage.getType());
346    
347                                    portletDataContext.addZipEntry(
348                                            smallImagePath, smallImage.getTextObj());
349                            }
350                    }
351    
352                    List<JournalArticleImage> articleImages =
353                            JournalArticleImageLocalServiceUtil.getArticleImages(
354                                    article.getGroupId(), article.getArticleId(),
355                                    article.getVersion());
356    
357                    for (JournalArticleImage articleImage : articleImages) {
358                            exportArticleImage(
359                                    portletDataContext, articleImage, article, articleElement);
360                    }
361    
362                    article.setStatusByUserUuid(article.getStatusByUserUuid());
363    
364                    String content = ExportImportHelperUtil.replaceExportContentReferences(
365                            portletDataContext, article, article.getContent(),
366                            portletDataContext.getBooleanParameter(
367                                    JournalPortletDataHandler.NAMESPACE, "referenced-content"));
368    
369                    article.setContent(content);
370    
371                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
372                            article.getCompanyId());
373    
374                    if (defaultUserId == article.getUserId()) {
375                            articleElement.addAttribute("preloaded", "true");
376                    }
377    
378                    portletDataContext.addClassedModel(
379                            articleElement, ExportImportPathUtil.getModelPath(article),
380                            article);
381            }
382    
383            @Override
384            protected void doImportStagedModel(
385                            PortletDataContext portletDataContext, JournalArticle article)
386                    throws Exception {
387    
388                    long userId = portletDataContext.getUserId(article.getUserUuid());
389    
390                    JournalCreationStrategy creationStrategy =
391                            JournalCreationStrategyFactory.getInstance();
392    
393                    long authorId = creationStrategy.getAuthorUserId(
394                            portletDataContext, article);
395    
396                    if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
397                            userId = authorId;
398                    }
399    
400                    User user = UserLocalServiceUtil.getUser(userId);
401    
402                    Map<Long, Long> folderIds =
403                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
404                                    JournalFolder.class);
405    
406                    long folderId = MapUtil.getLong(
407                            folderIds, article.getFolderId(), article.getFolderId());
408    
409                    String articleId = article.getArticleId();
410    
411                    boolean autoArticleId = false;
412    
413                    if (Validator.isNumber(articleId) ||
414                            (JournalArticleLocalServiceUtil.fetchArticle(
415                                    portletDataContext.getScopeGroupId(), articleId,
416                                    JournalArticleConstants.VERSION_DEFAULT) != null)) {
417    
418                            autoArticleId = true;
419                    }
420    
421                    Map<String, String> articleIds =
422                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
423                                    JournalArticle.class + ".articleId");
424    
425                    String newArticleId = articleIds.get(articleId);
426    
427                    if (Validator.isNotNull(newArticleId)) {
428    
429                            // A sibling of a different version was already assigned a new
430                            // article id
431    
432                            articleId = newArticleId;
433                            autoArticleId = false;
434                    }
435    
436                    String content = article.getContent();
437    
438                    content = ExportImportHelperUtil.replaceImportContentReferences(
439                            portletDataContext, article, content);
440    
441                    article.setContent(content);
442    
443                    String newContent = creationStrategy.getTransformedContent(
444                            portletDataContext, article);
445    
446                    if (newContent != JournalCreationStrategy.ARTICLE_CONTENT_UNCHANGED) {
447                            article.setContent(newContent);
448                    }
449    
450                    Date displayDate = article.getDisplayDate();
451    
452                    int displayDateMonth = 0;
453                    int displayDateDay = 0;
454                    int displayDateYear = 0;
455                    int displayDateHour = 0;
456                    int displayDateMinute = 0;
457    
458                    if (displayDate != null) {
459                            Calendar displayCal = CalendarFactoryUtil.getCalendar(
460                                    user.getTimeZone());
461    
462                            displayCal.setTime(displayDate);
463    
464                            displayDateMonth = displayCal.get(Calendar.MONTH);
465                            displayDateDay = displayCal.get(Calendar.DATE);
466                            displayDateYear = displayCal.get(Calendar.YEAR);
467                            displayDateHour = displayCal.get(Calendar.HOUR);
468                            displayDateMinute = displayCal.get(Calendar.MINUTE);
469    
470                            if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
471                                    displayDateHour += 12;
472                            }
473                    }
474    
475                    Date expirationDate = article.getExpirationDate();
476    
477                    int expirationDateMonth = 0;
478                    int expirationDateDay = 0;
479                    int expirationDateYear = 0;
480                    int expirationDateHour = 0;
481                    int expirationDateMinute = 0;
482                    boolean neverExpire = true;
483    
484                    if (expirationDate != null) {
485                            Calendar expirationCal = CalendarFactoryUtil.getCalendar(
486                                    user.getTimeZone());
487    
488                            expirationCal.setTime(expirationDate);
489    
490                            expirationDateMonth = expirationCal.get(Calendar.MONTH);
491                            expirationDateDay = expirationCal.get(Calendar.DATE);
492                            expirationDateYear = expirationCal.get(Calendar.YEAR);
493                            expirationDateHour = expirationCal.get(Calendar.HOUR);
494                            expirationDateMinute = expirationCal.get(Calendar.MINUTE);
495                            neverExpire = false;
496    
497                            if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
498                                    expirationDateHour += 12;
499                            }
500                    }
501    
502                    Date reviewDate = article.getReviewDate();
503    
504                    int reviewDateMonth = 0;
505                    int reviewDateDay = 0;
506                    int reviewDateYear = 0;
507                    int reviewDateHour = 0;
508                    int reviewDateMinute = 0;
509                    boolean neverReview = true;
510    
511                    if (reviewDate != null) {
512                            Calendar reviewCal = CalendarFactoryUtil.getCalendar(
513                                    user.getTimeZone());
514    
515                            reviewCal.setTime(reviewDate);
516    
517                            reviewDateMonth = reviewCal.get(Calendar.MONTH);
518                            reviewDateDay = reviewCal.get(Calendar.DATE);
519                            reviewDateYear = reviewCal.get(Calendar.YEAR);
520                            reviewDateHour = reviewCal.get(Calendar.HOUR);
521                            reviewDateMinute = reviewCal.get(Calendar.MINUTE);
522                            neverReview = false;
523    
524                            if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
525                                    reviewDateHour += 12;
526                            }
527                    }
528    
529                    Map<String, String> ddmStructureKeys =
530                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
531                                    DDMStructure.class + ".ddmStructureKey");
532    
533                    String parentDDMStructureKey = MapUtil.getString(
534                            ddmStructureKeys, article.getStructureId(),
535                            article.getStructureId());
536    
537                    Map<String, Long> ddmStructureIds =
538                            (Map<String, Long>)portletDataContext.getNewPrimaryKeysMap(
539                                    DDMStructure.class);
540    
541                    long ddmStructureId = 0;
542    
543                    if (article.getClassNameId() != 0) {
544                            ddmStructureId = ddmStructureIds.get(article.getClassPK());
545                    }
546    
547                    Map<String, String> ddmTemplateKeys =
548                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
549                                    DDMTemplate.class + ".ddmTemplateKey");
550    
551                    String parentDDMTemplateKey = MapUtil.getString(
552                            ddmTemplateKeys, article.getTemplateId(), article.getTemplateId());
553    
554                    File smallFile = null;
555    
556                    try {
557                            Element articleElement =
558                                    portletDataContext.getImportDataStagedModelElement(article);
559    
560                            if (article.isSmallImage()) {
561                                    String smallImagePath = articleElement.attributeValue(
562                                            "small-image-path");
563    
564                                    if (Validator.isNotNull(article.getSmallImageURL())) {
565                                            String smallImageURL =
566                                                    ExportImportHelperUtil.replaceImportContentReferences(
567                                                            portletDataContext, article,
568                                                            article.getSmallImageURL());
569    
570                                            article.setSmallImageURL(smallImageURL);
571                                    }
572                                    else if (Validator.isNotNull(smallImagePath)) {
573                                            byte[] bytes = portletDataContext.getZipEntryAsByteArray(
574                                                    smallImagePath);
575    
576                                            if (bytes != null) {
577                                                    smallFile = FileUtil.createTempFile(
578                                                            article.getSmallImageType());
579    
580                                                    FileUtil.write(smallFile, bytes);
581                                            }
582                                    }
583                            }
584    
585                            Map<String, byte[]> images = new HashMap<String, byte[]>();
586    
587                            List<Element> imagesElements =
588                                    portletDataContext.getReferenceDataElements(
589                                            article, Image.class);
590    
591                            for (Element imageElement : imagesElements) {
592                                    String imagePath = imageElement.attributeValue("path");
593    
594                                    String fileName = imageElement.attributeValue("file-name");
595    
596                                    images.put(
597                                            fileName,
598                                            portletDataContext.getZipEntryAsByteArray(imagePath));
599                            }
600    
601                            String articleURL = null;
602    
603                            boolean addGroupPermissions = creationStrategy.addGroupPermissions(
604                                    portletDataContext, article);
605                            boolean addGuestPermissions = creationStrategy.addGuestPermissions(
606                                    portletDataContext, article);
607    
608                            ServiceContext serviceContext =
609                                    portletDataContext.createServiceContext(article);
610    
611                            serviceContext.setAddGroupPermissions(addGroupPermissions);
612                            serviceContext.setAddGuestPermissions(addGuestPermissions);
613    
614                            if ((article.getStatus() != WorkflowConstants.STATUS_APPROVED) &&
615                                    (article.getStatus() != WorkflowConstants.STATUS_SCHEDULED)) {
616    
617                                    serviceContext.setWorkflowAction(
618                                            WorkflowConstants.ACTION_SAVE_DRAFT);
619                            }
620    
621                            JournalArticle importedArticle = null;
622    
623                            String articleResourceUuid = articleElement.attributeValue(
624                                    "article-resource-uuid");
625    
626                            if (portletDataContext.isDataStrategyMirror()) {
627                                    serviceContext.setUuid(article.getUuid());
628                                    serviceContext.setAttribute(
629                                            "articleResourceUuid", articleResourceUuid);
630                                    serviceContext.setAttribute("urlTitle", article.getUrlTitle());
631    
632                                    boolean preloaded = GetterUtil.getBoolean(
633                                            articleElement.attributeValue("preloaded"));
634    
635                                    JournalArticle existingArticle = fetchExistingArticle(
636                                            article.getUuid(), articleResourceUuid,
637                                            portletDataContext.getScopeGroupId(), articleId,
638                                            newArticleId, article.getVersion(), preloaded);
639    
640                                    if (existingArticle == null) {
641                                            importedArticle =
642                                                    JournalArticleLocalServiceUtil.addArticle(
643                                                            userId, portletDataContext.getScopeGroupId(),
644                                                            folderId, article.getClassNameId(), ddmStructureId,
645                                                            articleId, autoArticleId, article.getVersion(),
646                                                            article.getTitleMap(), article.getDescriptionMap(),
647                                                            article.getContent(), article.getType(),
648                                                            parentDDMStructureKey, parentDDMTemplateKey,
649                                                            article.getLayoutUuid(), displayDateMonth,
650                                                            displayDateDay, displayDateYear, displayDateHour,
651                                                            displayDateMinute, expirationDateMonth,
652                                                            expirationDateDay, expirationDateYear,
653                                                            expirationDateHour, expirationDateMinute,
654                                                            neverExpire, reviewDateMonth, reviewDateDay,
655                                                            reviewDateYear, reviewDateHour, reviewDateMinute,
656                                                            neverReview, article.isIndexable(),
657                                                            article.isSmallImage(), article.getSmallImageURL(),
658                                                            smallFile, images, articleURL, serviceContext);
659                                    }
660                                    else {
661                                            importedArticle =
662                                                    JournalArticleLocalServiceUtil.updateArticle(
663                                                            userId, existingArticle.getGroupId(), folderId,
664                                                            existingArticle.getArticleId(),
665                                                            article.getVersion(), article.getTitleMap(),
666                                                            article.getDescriptionMap(), article.getContent(),
667                                                            article.getType(), parentDDMStructureKey,
668                                                            parentDDMTemplateKey, article.getLayoutUuid(),
669                                                            displayDateMonth, displayDateDay, displayDateYear,
670                                                            displayDateHour, displayDateMinute,
671                                                            expirationDateMonth, expirationDateDay,
672                                                            expirationDateYear, expirationDateHour,
673                                                            expirationDateMinute, neverExpire, reviewDateMonth,
674                                                            reviewDateDay, reviewDateYear, reviewDateHour,
675                                                            reviewDateMinute, neverReview,
676                                                            article.isIndexable(), article.isSmallImage(),
677                                                            article.getSmallImageURL(), smallFile, images,
678                                                            articleURL, serviceContext);
679    
680                                            String existingArticleUuid = existingArticle.getUuid();
681                                            String importedArticleUuid = importedArticle.getUuid();
682    
683                                            if (!existingArticleUuid.equals(importedArticleUuid)) {
684                                                    importedArticle.setUuid(existingArticleUuid);
685    
686                                                    JournalArticleLocalServiceUtil.updateJournalArticle(
687                                                            importedArticle);
688                                            }
689                                    }
690                            }
691                            else {
692                                    importedArticle = JournalArticleLocalServiceUtil.addArticle(
693                                            userId, portletDataContext.getScopeGroupId(), folderId,
694                                            article.getClassNameId(), ddmStructureId, articleId,
695                                            autoArticleId, article.getVersion(), article.getTitleMap(),
696                                            article.getDescriptionMap(), article.getContent(),
697                                            article.getType(), parentDDMStructureKey,
698                                            parentDDMTemplateKey, article.getLayoutUuid(),
699                                            displayDateMonth, displayDateDay, displayDateYear,
700                                            displayDateHour, displayDateMinute, expirationDateMonth,
701                                            expirationDateDay, expirationDateYear, expirationDateHour,
702                                            expirationDateMinute, neverExpire, reviewDateMonth,
703                                            reviewDateDay, reviewDateYear, reviewDateHour,
704                                            reviewDateMinute, neverReview, article.isIndexable(),
705                                            article.isSmallImage(), article.getSmallImageURL(),
706                                            smallFile, images, articleURL, serviceContext);
707                            }
708    
709                            portletDataContext.importClassedModel(article, importedArticle);
710    
711                            if (Validator.isNull(newArticleId)) {
712                                    articleIds.put(
713                                            article.getArticleId(), importedArticle.getArticleId());
714                            }
715                    }
716                    finally {
717                            if (smallFile != null) {
718                                    smallFile.delete();
719                            }
720                    }
721            }
722    
723            @Override
724            protected void doRestoreStagedModel(
725                            PortletDataContext portletDataContext, JournalArticle article)
726                    throws Exception {
727    
728                    long userId = portletDataContext.getUserId(article.getUserUuid());
729    
730                    Element articleElement =
731                            portletDataContext.getImportDataStagedModelElement(article);
732    
733                    String articleResourceUuid = articleElement.attributeValue(
734                            "article-resource-uuid");
735    
736                    boolean preloaded = GetterUtil.getBoolean(
737                            articleElement.attributeValue("preloaded"));
738    
739                    JournalArticle existingArticle = fetchExistingArticle(
740                            article.getUuid(), articleResourceUuid,
741                            portletDataContext.getScopeGroupId(), article.getArticleId(),
742                            article.getArticleId(), article.getVersion(), preloaded);
743    
744                    if ((existingArticle == null) || !existingArticle.isInTrash()) {
745                            return;
746                    }
747    
748                    TrashHandler trashHandler = existingArticle.getTrashHandler();
749    
750                    if (trashHandler.isRestorable(existingArticle.getResourcePrimKey())) {
751                            trashHandler.restoreTrashEntry(
752                                    userId, existingArticle.getResourcePrimKey());
753                    }
754            }
755    
756            protected void exportArticleImage(
757                    PortletDataContext portletDataContext, JournalArticleImage articleImage,
758                    JournalArticle article, Element articleElement) {
759    
760                    Image image = ImageLocalServiceUtil.fetchImage(
761                            articleImage.getArticleImageId());
762    
763                    if ((image == null) || (image.getTextObj() == null)) {
764                            return;
765                    }
766    
767                    StringBundler sb = new StringBundler(4);
768    
769                    sb.append(articleImage.getElInstanceId());
770                    sb.append(StringPool.UNDERLINE);
771                    sb.append(articleImage.getElName());
772    
773                    if (Validator.isNotNull(articleImage.getLanguageId())) {
774                            sb.append(articleImage.getLanguageId());
775                    }
776    
777                    String fileName = sb.toString();
778    
779                    String articleImagePath = ExportImportPathUtil.getModelPath(
780                            article, fileName);
781    
782                    if (!portletDataContext.isPathNotProcessed(articleImagePath)) {
783                            return;
784                    }
785    
786                    Element imageElement = portletDataContext.getExportDataElement(image);
787    
788                    imageElement.addAttribute("file-name", fileName);
789                    imageElement.addAttribute("path", articleImagePath);
790    
791                    portletDataContext.addZipEntry(articleImagePath, image.getTextObj());
792    
793                    portletDataContext.addReferenceElement(
794                            article, articleElement, image, articleImagePath,
795                            PortletDataContext.REFERENCE_TYPE_DEPENDENCY, false);
796            }
797    
798            protected JournalArticle fetchExistingArticle(
799                    String articleUuid, String articleResourceUuid, long groupId,
800                    String articleId, String newArticleId, double version,
801                    boolean preloaded) {
802    
803                    JournalArticle existingArticle = null;
804    
805                    if (!preloaded) {
806                            existingArticle = fetchStagedModelByUuidAndGroupId(
807                                    articleUuid, groupId);
808    
809                            if (existingArticle != null) {
810                                    return existingArticle;
811                            }
812    
813                            // Backwards compatibility
814    
815                            JournalArticleResource journalArticleResource =
816                                    JournalArticleResourceLocalServiceUtil.
817                                            fetchJournalArticleResourceByUuidAndGroupId(
818                                                    articleResourceUuid, groupId);
819    
820                            if (journalArticleResource == null) {
821                                    return null;
822                            }
823    
824                            return JournalArticleLocalServiceUtil.fetchArticle(
825                                    groupId, journalArticleResource.getArticleId(), version);
826                    }
827    
828                    if (Validator.isNotNull(newArticleId) && (version > 0.0)) {
829                            existingArticle = JournalArticleLocalServiceUtil.fetchArticle(
830                                    groupId, newArticleId, version);
831                    }
832    
833                    if ((existingArticle == null) && Validator.isNull(newArticleId)) {
834                            existingArticle = JournalArticleLocalServiceUtil.fetchArticle(
835                                    groupId, articleId, version);
836                    }
837    
838                    return existingArticle;
839            }
840    
841    }