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.getDDMStructureKey(), 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.getDDMTemplateKey(), 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.getDDMStructureKey(),
535                            article.getDDMStructureKey());
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.getDDMTemplateKey(),
553                            article.getDDMTemplateKey());
554    
555                    File smallFile = null;
556    
557                    try {
558                            Element articleElement =
559                                    portletDataContext.getImportDataStagedModelElement(article);
560    
561                            if (article.isSmallImage()) {
562                                    String smallImagePath = articleElement.attributeValue(
563                                            "small-image-path");
564    
565                                    if (Validator.isNotNull(article.getSmallImageURL())) {
566                                            String smallImageURL =
567                                                    ExportImportHelperUtil.replaceImportContentReferences(
568                                                            portletDataContext, article,
569                                                            article.getSmallImageURL());
570    
571                                            article.setSmallImageURL(smallImageURL);
572                                    }
573                                    else if (Validator.isNotNull(smallImagePath)) {
574                                            byte[] bytes = portletDataContext.getZipEntryAsByteArray(
575                                                    smallImagePath);
576    
577                                            if (bytes != null) {
578                                                    smallFile = FileUtil.createTempFile(
579                                                            article.getSmallImageType());
580    
581                                                    FileUtil.write(smallFile, bytes);
582                                            }
583                                    }
584                            }
585    
586                            Map<String, byte[]> images = new HashMap<String, byte[]>();
587    
588                            List<Element> imagesElements =
589                                    portletDataContext.getReferenceDataElements(
590                                            article, Image.class);
591    
592                            for (Element imageElement : imagesElements) {
593                                    String imagePath = imageElement.attributeValue("path");
594    
595                                    String fileName = imageElement.attributeValue("file-name");
596    
597                                    images.put(
598                                            fileName,
599                                            portletDataContext.getZipEntryAsByteArray(imagePath));
600                            }
601    
602                            String articleURL = null;
603    
604                            boolean addGroupPermissions = creationStrategy.addGroupPermissions(
605                                    portletDataContext, article);
606                            boolean addGuestPermissions = creationStrategy.addGuestPermissions(
607                                    portletDataContext, article);
608    
609                            ServiceContext serviceContext =
610                                    portletDataContext.createServiceContext(article);
611    
612                            serviceContext.setAddGroupPermissions(addGroupPermissions);
613                            serviceContext.setAddGuestPermissions(addGuestPermissions);
614    
615                            if ((article.getStatus() != WorkflowConstants.STATUS_APPROVED) &&
616                                    (article.getStatus() != WorkflowConstants.STATUS_SCHEDULED)) {
617    
618                                    serviceContext.setWorkflowAction(
619                                            WorkflowConstants.ACTION_SAVE_DRAFT);
620                            }
621    
622                            JournalArticle importedArticle = null;
623    
624                            String articleResourceUuid = articleElement.attributeValue(
625                                    "article-resource-uuid");
626    
627                            if (portletDataContext.isDataStrategyMirror()) {
628                                    serviceContext.setUuid(article.getUuid());
629                                    serviceContext.setAttribute(
630                                            "articleResourceUuid", articleResourceUuid);
631                                    serviceContext.setAttribute("urlTitle", article.getUrlTitle());
632    
633                                    boolean preloaded = GetterUtil.getBoolean(
634                                            articleElement.attributeValue("preloaded"));
635    
636                                    JournalArticle existingArticle = fetchExistingArticle(
637                                            article.getUuid(), articleResourceUuid,
638                                            portletDataContext.getScopeGroupId(), articleId,
639                                            newArticleId, article.getVersion(), preloaded);
640    
641                                    if (existingArticle == null) {
642                                            importedArticle = JournalArticleLocalServiceUtil.addArticle(
643                                                    userId, portletDataContext.getScopeGroupId(), folderId,
644                                                    article.getClassNameId(), ddmStructureId, articleId,
645                                                    autoArticleId, article.getVersion(),
646                                                    article.getTitleMap(), article.getDescriptionMap(),
647                                                    article.getContent(), parentDDMStructureKey,
648                                                    parentDDMTemplateKey, article.getLayoutUuid(),
649                                                    displayDateMonth, displayDateDay, displayDateYear,
650                                                    displayDateHour, displayDateMinute, expirationDateMonth,
651                                                    expirationDateDay, expirationDateYear,
652                                                    expirationDateHour, expirationDateMinute, neverExpire,
653                                                    reviewDateMonth, reviewDateDay, reviewDateYear,
654                                                    reviewDateHour, reviewDateMinute, neverReview,
655                                                    article.isIndexable(), article.isSmallImage(),
656                                                    article.getSmallImageURL(), smallFile, images,
657                                                    articleURL, serviceContext);
658                                    }
659                                    else {
660                                            importedArticle =
661                                                    JournalArticleLocalServiceUtil.updateArticle(
662                                                            userId, existingArticle.getGroupId(), folderId,
663                                                            existingArticle.getArticleId(),
664                                                            article.getVersion(), article.getTitleMap(),
665                                                            article.getDescriptionMap(), article.getContent(),
666                                                            parentDDMStructureKey, parentDDMTemplateKey,
667                                                            article.getLayoutUuid(), displayDateMonth,
668                                                            displayDateDay, displayDateYear, displayDateHour,
669                                                            displayDateMinute, expirationDateMonth,
670                                                            expirationDateDay, expirationDateYear,
671                                                            expirationDateHour, expirationDateMinute,
672                                                            neverExpire, reviewDateMonth, reviewDateDay,
673                                                            reviewDateYear, reviewDateHour, reviewDateMinute,
674                                                            neverReview, article.isIndexable(),
675                                                            article.isSmallImage(), article.getSmallImageURL(),
676                                                            smallFile, images, articleURL, serviceContext);
677    
678                                            String existingArticleUuid = existingArticle.getUuid();
679                                            String importedArticleUuid = importedArticle.getUuid();
680    
681                                            if (!existingArticleUuid.equals(importedArticleUuid)) {
682                                                    importedArticle.setUuid(existingArticleUuid);
683    
684                                                    JournalArticleLocalServiceUtil.updateJournalArticle(
685                                                            importedArticle);
686                                            }
687                                    }
688                            }
689                            else {
690                                    importedArticle = JournalArticleLocalServiceUtil.addArticle(
691                                            userId, portletDataContext.getScopeGroupId(), folderId,
692                                            article.getClassNameId(), ddmStructureId, articleId,
693                                            autoArticleId, article.getVersion(), article.getTitleMap(),
694                                            article.getDescriptionMap(), article.getContent(),
695                                            parentDDMStructureKey, parentDDMTemplateKey,
696                                            article.getLayoutUuid(), displayDateMonth, displayDateDay,
697                                            displayDateYear, displayDateHour, displayDateMinute,
698                                            expirationDateMonth, expirationDateDay, expirationDateYear,
699                                            expirationDateHour, expirationDateMinute, neverExpire,
700                                            reviewDateMonth, reviewDateDay, reviewDateYear,
701                                            reviewDateHour, reviewDateMinute, neverReview,
702                                            article.isIndexable(), article.isSmallImage(),
703                                            article.getSmallImageURL(), smallFile, images, articleURL,
704                                            serviceContext);
705                            }
706    
707                            portletDataContext.importClassedModel(article, importedArticle);
708    
709                            if (Validator.isNull(newArticleId)) {
710                                    articleIds.put(
711                                            article.getArticleId(), importedArticle.getArticleId());
712                            }
713                    }
714                    finally {
715                            if (smallFile != null) {
716                                    smallFile.delete();
717                            }
718                    }
719            }
720    
721            @Override
722            protected void doRestoreStagedModel(
723                            PortletDataContext portletDataContext, JournalArticle article)
724                    throws Exception {
725    
726                    long userId = portletDataContext.getUserId(article.getUserUuid());
727    
728                    Element articleElement =
729                            portletDataContext.getImportDataStagedModelElement(article);
730    
731                    String articleResourceUuid = articleElement.attributeValue(
732                            "article-resource-uuid");
733    
734                    boolean preloaded = GetterUtil.getBoolean(
735                            articleElement.attributeValue("preloaded"));
736    
737                    JournalArticle existingArticle = fetchExistingArticle(
738                            article.getUuid(), articleResourceUuid,
739                            portletDataContext.getScopeGroupId(), article.getArticleId(),
740                            article.getArticleId(), article.getVersion(), preloaded);
741    
742                    if ((existingArticle == null) || !existingArticle.isInTrash()) {
743                            return;
744                    }
745    
746                    TrashHandler trashHandler = existingArticle.getTrashHandler();
747    
748                    if (trashHandler.isRestorable(existingArticle.getResourcePrimKey())) {
749                            trashHandler.restoreTrashEntry(
750                                    userId, existingArticle.getResourcePrimKey());
751                    }
752            }
753    
754            protected void exportArticleImage(
755                    PortletDataContext portletDataContext, JournalArticleImage articleImage,
756                    JournalArticle article, Element articleElement) {
757    
758                    Image image = ImageLocalServiceUtil.fetchImage(
759                            articleImage.getArticleImageId());
760    
761                    if ((image == null) || (image.getTextObj() == null)) {
762                            return;
763                    }
764    
765                    StringBundler sb = new StringBundler(4);
766    
767                    sb.append(articleImage.getElInstanceId());
768                    sb.append(StringPool.UNDERLINE);
769                    sb.append(articleImage.getElName());
770    
771                    if (Validator.isNotNull(articleImage.getLanguageId())) {
772                            sb.append(articleImage.getLanguageId());
773                    }
774    
775                    String fileName = sb.toString();
776    
777                    String articleImagePath = ExportImportPathUtil.getModelPath(
778                            article, fileName);
779    
780                    if (!portletDataContext.isPathNotProcessed(articleImagePath)) {
781                            return;
782                    }
783    
784                    Element imageElement = portletDataContext.getExportDataElement(image);
785    
786                    imageElement.addAttribute("file-name", fileName);
787                    imageElement.addAttribute("path", articleImagePath);
788    
789                    portletDataContext.addZipEntry(articleImagePath, image.getTextObj());
790    
791                    portletDataContext.addReferenceElement(
792                            article, articleElement, image, articleImagePath,
793                            PortletDataContext.REFERENCE_TYPE_DEPENDENCY, false);
794            }
795    
796            protected JournalArticle fetchExistingArticle(
797                    String articleUuid, String articleResourceUuid, long groupId,
798                    String articleId, String newArticleId, double version,
799                    boolean preloaded) {
800    
801                    JournalArticle existingArticle = null;
802    
803                    if (!preloaded) {
804                            existingArticle = fetchStagedModelByUuidAndGroupId(
805                                    articleUuid, groupId);
806    
807                            if (existingArticle != null) {
808                                    return existingArticle;
809                            }
810    
811                            // Backwards compatibility
812    
813                            JournalArticleResource journalArticleResource =
814                                    JournalArticleResourceLocalServiceUtil.
815                                            fetchJournalArticleResourceByUuidAndGroupId(
816                                                    articleResourceUuid, groupId);
817    
818                            if (journalArticleResource == null) {
819                                    return null;
820                            }
821    
822                            return JournalArticleLocalServiceUtil.fetchArticle(
823                                    groupId, journalArticleResource.getArticleId(), version);
824                    }
825    
826                    if (Validator.isNotNull(newArticleId) && (version > 0.0)) {
827                            existingArticle = JournalArticleLocalServiceUtil.fetchArticle(
828                                    groupId, newArticleId, version);
829                    }
830    
831                    if ((existingArticle == null) && Validator.isNull(newArticleId)) {
832                            existingArticle = JournalArticleLocalServiceUtil.fetchArticle(
833                                    groupId, articleId, version);
834                    }
835    
836                    return existingArticle;
837            }
838    
839    }