001    /**
002     * Copyright (c) 2000-2012 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.NoSuchImageException;
018    import com.liferay.portal.kernel.dao.orm.QueryUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.lar.BasePortletDataHandler;
022    import com.liferay.portal.kernel.lar.PortletDataContext;
023    import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
024    import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.repository.model.FileEntry;
028    import com.liferay.portal.kernel.util.ArrayUtil;
029    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
030    import com.liferay.portal.kernel.util.CharPool;
031    import com.liferay.portal.kernel.util.FileUtil;
032    import com.liferay.portal.kernel.util.GetterUtil;
033    import com.liferay.portal.kernel.util.HttpUtil;
034    import com.liferay.portal.kernel.util.LocaleUtil;
035    import com.liferay.portal.kernel.util.LocalizationUtil;
036    import com.liferay.portal.kernel.util.MapUtil;
037    import com.liferay.portal.kernel.util.StringBundler;
038    import com.liferay.portal.kernel.util.StringPool;
039    import com.liferay.portal.kernel.util.StringUtil;
040    import com.liferay.portal.kernel.util.Validator;
041    import com.liferay.portal.kernel.workflow.WorkflowConstants;
042    import com.liferay.portal.kernel.xml.Document;
043    import com.liferay.portal.kernel.xml.Element;
044    import com.liferay.portal.kernel.xml.SAXReaderUtil;
045    import com.liferay.portal.model.Group;
046    import com.liferay.portal.model.Image;
047    import com.liferay.portal.model.Layout;
048    import com.liferay.portal.model.RepositoryEntry;
049    import com.liferay.portal.model.User;
050    import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
051    import com.liferay.portal.service.GroupLocalServiceUtil;
052    import com.liferay.portal.service.LayoutLocalServiceUtil;
053    import com.liferay.portal.service.ServiceContext;
054    import com.liferay.portal.service.UserLocalServiceUtil;
055    import com.liferay.portal.service.persistence.ImageUtil;
056    import com.liferay.portal.service.persistence.LayoutUtil;
057    import com.liferay.portal.util.PortletKeys;
058    import com.liferay.portal.util.PropsValues;
059    import com.liferay.portlet.documentlibrary.lar.DLPortletDataHandlerImpl;
060    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
061    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
062    import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
063    import com.liferay.portlet.documentlibrary.util.DLUtil;
064    import com.liferay.portlet.journal.ArticleContentException;
065    import com.liferay.portlet.journal.FeedTargetLayoutFriendlyUrlException;
066    import com.liferay.portlet.journal.NoSuchArticleException;
067    import com.liferay.portlet.journal.NoSuchStructureException;
068    import com.liferay.portlet.journal.model.JournalArticle;
069    import com.liferay.portlet.journal.model.JournalArticleConstants;
070    import com.liferay.portlet.journal.model.JournalArticleImage;
071    import com.liferay.portlet.journal.model.JournalArticleResource;
072    import com.liferay.portlet.journal.model.JournalFeed;
073    import com.liferay.portlet.journal.model.JournalFolder;
074    import com.liferay.portlet.journal.model.JournalFolderConstants;
075    import com.liferay.portlet.journal.model.JournalStructure;
076    import com.liferay.portlet.journal.model.JournalTemplate;
077    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
078    import com.liferay.portlet.journal.service.JournalFeedLocalServiceUtil;
079    import com.liferay.portlet.journal.service.JournalFolderLocalServiceUtil;
080    import com.liferay.portlet.journal.service.JournalStructureLocalServiceUtil;
081    import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
082    import com.liferay.portlet.journal.service.persistence.JournalArticleImageUtil;
083    import com.liferay.portlet.journal.service.persistence.JournalArticleResourceUtil;
084    import com.liferay.portlet.journal.service.persistence.JournalArticleUtil;
085    import com.liferay.portlet.journal.service.persistence.JournalFeedUtil;
086    import com.liferay.portlet.journal.service.persistence.JournalFolderUtil;
087    import com.liferay.portlet.journal.service.persistence.JournalStructureUtil;
088    import com.liferay.portlet.journal.service.persistence.JournalTemplateUtil;
089    import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
090    import com.liferay.portlet.journal.util.comparator.StructurePKComparator;
091    
092    import java.io.File;
093    
094    import java.util.ArrayList;
095    import java.util.Calendar;
096    import java.util.Collections;
097    import java.util.Date;
098    import java.util.HashMap;
099    import java.util.List;
100    import java.util.Locale;
101    import java.util.Map;
102    import java.util.regex.Matcher;
103    import java.util.regex.Pattern;
104    
105    import javax.portlet.PortletPreferences;
106    
107    /**
108     * <p>
109     * Provides the Journal portlet export and import functionality, which is to
110     * clone all articles, structures, and templates associated with the layout's
111     * group. Upon import, new instances of the corresponding articles, structures,
112     * and templates are created or updated according to the DATA_MIRROW strategy
113     * The author of the newly created objects are determined by the
114     * JournalCreationStrategy class defined in <i>portal.properties</i>. That
115     * strategy also allows the text of the journal article to be modified prior to
116     * import.
117     * </p>
118     *
119     * <p>
120     * This <code>PortletDataHandler</code> differs from
121     * <code>JournalContentPortletDataHandlerImpl</code> in that it exports all
122     * articles owned by the group whether or not they are actually displayed in a
123     * portlet in the layout set.
124     * </p>
125     *
126     * @author Raymond Augé
127     * @author Joel Kozikowski
128     * @author Brian Wing Shun Chan
129     * @author Bruno Farache
130     * @author Karthik Sudarshan
131     * @author Wesley Gong
132     * @author Hugo Huijser
133     * @see    com.liferay.portal.kernel.lar.PortletDataHandler
134     * @see    com.liferay.portlet.journal.lar.JournalContentPortletDataHandlerImpl
135     * @see    com.liferay.portlet.journal.lar.JournalCreationStrategy
136     */
137    public class JournalPortletDataHandlerImpl extends BasePortletDataHandler {
138    
139            public static void exportArticle(
140                            PortletDataContext portletDataContext, Element articlesElement,
141                            Element structuresElement, Element templatesElement,
142                            Element dlFileEntryTypesElement, Element dlFoldersElement,
143                            Element dlFileEntriesElement, Element dlFileRanksElement,
144                            Element dlRepositoriesElement, Element dlRepositoryEntriesElement,
145                            JournalArticle article, boolean checkDateRange)
146                    throws Exception {
147    
148                    if (checkDateRange &&
149                            !portletDataContext.isWithinDateRange(article.getModifiedDate())) {
150    
151                            return;
152                    }
153    
154                    if ((article.getStatus() != WorkflowConstants.STATUS_APPROVED) &&
155                            (article.getStatus() != WorkflowConstants.STATUS_EXPIRED)) {
156    
157                            return;
158                    }
159    
160                    String path = getArticlePath(portletDataContext, article);
161    
162                    if (!portletDataContext.isPathNotProcessed(path)) {
163                            return;
164                    }
165    
166                    // Clone this article to make sure changes to its content are never
167                    // persisted
168    
169                    article = (JournalArticle)article.clone();
170    
171                    Element articleElement = (Element)articlesElement.selectSingleNode(
172                            "//article[@path='".concat(path).concat("']"));
173    
174                    if (articleElement == null) {
175                            articleElement = articlesElement.addElement("article");
176                    }
177    
178                    articleElement.addAttribute(
179                            "article-resource-uuid", article.getArticleResourceUuid());
180    
181                    if (Validator.isNotNull(article.getStructureId())) {
182                            JournalStructure structure =
183                                    JournalStructureLocalServiceUtil.getStructure(
184                                            article.getGroupId(), article.getStructureId(), true);
185    
186                            articleElement.addAttribute("structure-uuid", structure.getUuid());
187    
188                            exportStructure(portletDataContext, structuresElement, structure);
189                    }
190    
191                    String templateId = article.getTemplateId();
192    
193                    if (Validator.isNotNull(templateId)) {
194                            JournalTemplate template =
195                                    JournalTemplateLocalServiceUtil.getTemplate(
196                                            article.getGroupId(), templateId, true);
197    
198                            articleElement.addAttribute("template-uuid", template.getUuid());
199    
200                            exportTemplate(
201                                    portletDataContext, templatesElement, dlFileEntryTypesElement,
202                                    dlFoldersElement, dlFileEntriesElement, dlFileRanksElement,
203                                    dlRepositoriesElement, dlRepositoryEntriesElement, template);
204                    }
205    
206                    Image smallImage = ImageUtil.fetchByPrimaryKey(
207                            article.getSmallImageId());
208    
209                    if (article.isSmallImage() && (smallImage != null)) {
210                            String smallImagePath = getArticleSmallImagePath(
211                                    portletDataContext, article);
212    
213                            articleElement.addAttribute("small-image-path", smallImagePath);
214    
215                            article.setSmallImageType(smallImage.getType());
216    
217                            portletDataContext.addZipEntry(
218                                    smallImagePath, smallImage.getTextObj());
219                    }
220    
221                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "images")) {
222                            String imagePath = getArticleImagePath(portletDataContext, article);
223    
224                            articleElement.addAttribute("image-path", imagePath);
225    
226                            List<JournalArticleImage> articleImages =
227                                    JournalArticleImageUtil.findByG_A_V(
228                                            article.getGroupId(), article.getArticleId(),
229                                            article.getVersion());
230    
231                            for (JournalArticleImage articleImage : articleImages) {
232                                    Image image = null;
233    
234                                    try {
235                                            image = ImageUtil.findByPrimaryKey(
236                                                    articleImage.getArticleImageId());
237                                    }
238                                    catch (NoSuchImageException nsie) {
239                                            continue;
240                                    }
241    
242                                    if (image.getTextObj() == null) {
243                                            continue;
244                                    }
245    
246                                    String articleImagePath = getArticleImagePath(
247                                            portletDataContext, article, articleImage, image);
248    
249                                    if (!portletDataContext.isPathNotProcessed(articleImagePath)) {
250                                            continue;
251                                    }
252    
253                                    portletDataContext.addZipEntry(
254                                            articleImagePath, image.getTextObj());
255                            }
256                    }
257    
258                    article.setStatusByUserUuid(article.getStatusByUserUuid());
259    
260                    if (portletDataContext.getBooleanParameter(
261                                    _NAMESPACE, "embedded-assets")) {
262    
263                            String content = exportReferencedContent(
264                                    portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
265                                    dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
266                                    dlRepositoryEntriesElement, articleElement,
267                                    article.getContent());
268    
269                            article.setContent(content);
270                    }
271    
272                    portletDataContext.addClassedModel(
273                            articleElement, path, article, _NAMESPACE);
274            }
275    
276            public static String exportReferencedContent(
277                            PortletDataContext portletDataContext,
278                            Element dlFileEntryTypesElement, Element dlFoldersElement,
279                            Element dlFileEntriesElement, Element dlFileRanksElement,
280                            Element dlRepositoriesElement, Element dlRepositoryEntriesElement,
281                            Element entityElement, String content)
282                    throws Exception {
283    
284                    content = exportDLFileEntries(
285                            portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
286                            dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
287                            dlRepositoryEntriesElement, entityElement, content, false);
288                    content = exportLayoutFriendlyURLs(portletDataContext, content);
289                    content = exportLinksToLayout(portletDataContext, content);
290    
291                    String entityElementName = entityElement.getName();
292    
293                    if (!entityElementName.equals("article")) {
294                            content = StringUtil.replace(
295                                    content, StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
296                    }
297    
298                    return content;
299            }
300    
301            public static String getArticlePath(
302                            PortletDataContext portletDataContext, JournalArticle article)
303                    throws Exception {
304    
305                    StringBundler sb = new StringBundler(8);
306    
307                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
308                    sb.append("/articles/");
309                    sb.append(article.getArticleResourceUuid());
310                    sb.append(StringPool.SLASH);
311                    sb.append(article.getVersion());
312                    sb.append(StringPool.SLASH);
313                    sb.append("article.xml");
314    
315                    return sb.toString();
316            }
317    
318            public static PortletDataHandlerControl[] getMetadataControls() {
319                    return _metadataControls;
320            }
321    
322            public static void importArticle(
323                            PortletDataContext portletDataContext, Element articleElement)
324                    throws Exception {
325    
326                    String path = articleElement.attributeValue("path");
327    
328                    if (!portletDataContext.isPathNotProcessed(path)) {
329                            return;
330                    }
331    
332                    JournalArticle article =
333                            (JournalArticle)portletDataContext.getZipEntryAsObject(
334                                    articleElement, path);
335    
336                    prepareLanguagesForImport(article);
337    
338                    long userId = portletDataContext.getUserId(article.getUserUuid());
339    
340                    JournalCreationStrategy creationStrategy =
341                            JournalCreationStrategyFactory.getInstance();
342    
343                    long authorId = creationStrategy.getAuthorUserId(
344                            portletDataContext, article);
345    
346                    if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
347                            userId = authorId;
348                    }
349    
350                    User user = UserLocalServiceUtil.getUser(userId);
351    
352                    Map<Long, Long> folderIds =
353                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
354                                    JournalFolder.class);
355    
356                    long folderId = MapUtil.getLong(
357                            folderIds, article.getFolderId(), article.getFolderId());
358    
359                    if ((folderId != JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
360                            (folderId == article.getFolderId())) {
361    
362                            String folderPath = getImportFolderPath(
363                                    portletDataContext, folderId);
364    
365                            JournalFolder folder =
366                                    (JournalFolder)portletDataContext.getZipEntryAsObject(
367                                            folderPath);
368    
369                            importFolder(portletDataContext, folderPath, folder);
370    
371                            folderId = MapUtil.getLong(
372                                    folderIds, article.getFolderId(), article.getFolderId());
373                    }
374    
375                    String articleId = article.getArticleId();
376                    boolean autoArticleId = false;
377    
378                    if (Validator.isNumber(articleId) ||
379                            (JournalArticleUtil.fetchByG_A_V(
380                                    portletDataContext.getScopeGroupId(), articleId,
381                                    JournalArticleConstants.VERSION_DEFAULT) != null)) {
382    
383                            autoArticleId = true;
384                    }
385    
386                    Map<String, String> articleIds =
387                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
388                                    JournalArticle.class + ".articleId");
389    
390                    String newArticleId = articleIds.get(articleId);
391    
392                    if (Validator.isNotNull(newArticleId)) {
393    
394                            // A sibling of a different version was already assigned a new
395                            // article id
396    
397                            articleId = newArticleId;
398                            autoArticleId = false;
399                    }
400    
401                    String content = article.getContent();
402    
403                    content = importDLFileEntries(
404                            portletDataContext, articleElement, content);
405    
406                    Group group = GroupLocalServiceUtil.getGroup(
407                            portletDataContext.getScopeGroupId());
408    
409                    content = StringUtil.replace(
410                            content, "@data_handler_group_friendly_url@",
411                            group.getFriendlyURL());
412    
413                    content = importLinksToLayout(portletDataContext, content);
414    
415                    article.setContent(content);
416    
417                    String newContent = creationStrategy.getTransformedContent(
418                            portletDataContext, article);
419    
420                    if (newContent != JournalCreationStrategy.ARTICLE_CONTENT_UNCHANGED) {
421                            article.setContent(newContent);
422                    }
423    
424                    Map<String, String> structureIds =
425                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
426                                    JournalStructure.class);
427    
428                    String parentStructureId = MapUtil.getString(
429                            structureIds, article.getStructureId(), article.getStructureId());
430    
431                    Map<String, String> templateIds =
432                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
433                                    JournalTemplate.class);
434    
435                    String parentTemplateId = MapUtil.getString(
436                            templateIds, article.getTemplateId(), article.getTemplateId());
437    
438                    Date displayDate = article.getDisplayDate();
439    
440                    int displayDateMonth = 0;
441                    int displayDateDay = 0;
442                    int displayDateYear = 0;
443                    int displayDateHour = 0;
444                    int displayDateMinute = 0;
445    
446                    if (displayDate != null) {
447                            Calendar displayCal = CalendarFactoryUtil.getCalendar(
448                                    user.getTimeZone());
449    
450                            displayCal.setTime(displayDate);
451    
452                            displayDateMonth = displayCal.get(Calendar.MONTH);
453                            displayDateDay = displayCal.get(Calendar.DATE);
454                            displayDateYear = displayCal.get(Calendar.YEAR);
455                            displayDateHour = displayCal.get(Calendar.HOUR);
456                            displayDateMinute = displayCal.get(Calendar.MINUTE);
457    
458                            if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
459                                    displayDateHour += 12;
460                            }
461                    }
462    
463                    Date expirationDate = article.getExpirationDate();
464    
465                    int expirationDateMonth = 0;
466                    int expirationDateDay = 0;
467                    int expirationDateYear = 0;
468                    int expirationDateHour = 0;
469                    int expirationDateMinute = 0;
470                    boolean neverExpire = true;
471    
472                    if (expirationDate != null) {
473                            Calendar expirationCal = CalendarFactoryUtil.getCalendar(
474                                    user.getTimeZone());
475    
476                            expirationCal.setTime(expirationDate);
477    
478                            expirationDateMonth = expirationCal.get(Calendar.MONTH);
479                            expirationDateDay = expirationCal.get(Calendar.DATE);
480                            expirationDateYear = expirationCal.get(Calendar.YEAR);
481                            expirationDateHour = expirationCal.get(Calendar.HOUR);
482                            expirationDateMinute = expirationCal.get(Calendar.MINUTE);
483                            neverExpire = false;
484    
485                            if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
486                                    expirationDateHour += 12;
487                            }
488                    }
489    
490                    Date reviewDate = article.getReviewDate();
491    
492                    int reviewDateMonth = 0;
493                    int reviewDateDay = 0;
494                    int reviewDateYear = 0;
495                    int reviewDateHour = 0;
496                    int reviewDateMinute = 0;
497                    boolean neverReview = true;
498    
499                    if (reviewDate != null) {
500                            Calendar reviewCal = CalendarFactoryUtil.getCalendar(
501                                    user.getTimeZone());
502    
503                            reviewCal.setTime(reviewDate);
504    
505                            reviewDateMonth = reviewCal.get(Calendar.MONTH);
506                            reviewDateDay = reviewCal.get(Calendar.DATE);
507                            reviewDateYear = reviewCal.get(Calendar.YEAR);
508                            reviewDateHour = reviewCal.get(Calendar.HOUR);
509                            reviewDateMinute = reviewCal.get(Calendar.MINUTE);
510                            neverReview = false;
511    
512                            if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
513                                    reviewDateHour += 12;
514                            }
515                    }
516    
517                    long structurePrimaryKey = 0;
518    
519                    if (Validator.isNotNull(article.getStructureId())) {
520                            String structureUuid = articleElement.attributeValue(
521                                    "structure-uuid");
522    
523                            JournalStructure existingStructure =
524                                    JournalStructureUtil.fetchByUUID_G(
525                                            structureUuid, portletDataContext.getScopeGroupId());
526    
527                            if (existingStructure == null) {
528                                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
529                                            portletDataContext.getCompanyId());
530    
531                                    long companyGroupId = companyGroup.getGroupId();
532    
533                                    existingStructure = JournalStructureUtil.fetchByUUID_G(
534                                            structureUuid, companyGroupId);
535                            }
536    
537                            if (existingStructure == null) {
538                                    String newStructureId = structureIds.get(
539                                            article.getStructureId());
540    
541                                    if (Validator.isNotNull(newStructureId)) {
542                                            existingStructure = JournalStructureUtil.fetchByG_S(
543                                                    portletDataContext.getScopeGroupId(),
544                                                    String.valueOf(newStructureId));
545                                    }
546    
547                                    if (existingStructure == null) {
548                                            if (_log.isWarnEnabled()) {
549                                                    StringBundler sb = new StringBundler();
550    
551                                                    sb.append("Structure ");
552                                                    sb.append(article.getStructureId());
553                                                    sb.append(" is missing for article ");
554                                                    sb.append(article.getArticleId());
555                                                    sb.append(", skipping this article.");
556    
557                                                    _log.warn(sb.toString());
558                                            }
559    
560                                            return;
561                                    }
562                            }
563    
564                            structurePrimaryKey = existingStructure.getPrimaryKey();
565    
566                            parentStructureId = existingStructure.getStructureId();
567                    }
568    
569                    if (Validator.isNotNull(article.getTemplateId())) {
570                            String templateUuid = articleElement.attributeValue(
571                                    "template-uuid");
572    
573                            JournalTemplate existingTemplate =
574                                    JournalTemplateUtil.fetchByUUID_G(
575                                            templateUuid, portletDataContext.getScopeGroupId());
576    
577                            if (existingTemplate == null) {
578                                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
579                                            portletDataContext.getCompanyId());
580    
581                                    long companyGroupId = companyGroup.getGroupId();
582    
583                                    existingTemplate = JournalTemplateUtil.fetchByUUID_G(
584                                            templateUuid, companyGroupId);
585                            }
586    
587                            if (existingTemplate == null) {
588                                    String newTemplateId = templateIds.get(article.getTemplateId());
589    
590                                    if (Validator.isNotNull(newTemplateId)) {
591                                            existingTemplate = JournalTemplateUtil.fetchByG_T(
592                                                    portletDataContext.getScopeGroupId(), newTemplateId);
593                                    }
594    
595                                    if (existingTemplate == null) {
596                                            if (_log.isWarnEnabled()) {
597                                                    StringBundler sb = new StringBundler();
598    
599                                                    sb.append("Template ");
600                                                    sb.append(article.getTemplateId());
601                                                    sb.append(" is missing for article ");
602                                                    sb.append(article.getArticleId());
603                                                    sb.append(", skipping this article.");
604    
605                                                    _log.warn(sb.toString());
606                                            }
607    
608                                            return;
609                                    }
610                            }
611    
612                            parentTemplateId = existingTemplate.getTemplateId();
613                    }
614    
615                    File smallFile = null;
616    
617                    String smallImagePath = articleElement.attributeValue(
618                            "small-image-path");
619    
620                    if (article.isSmallImage() && Validator.isNotNull(smallImagePath)) {
621                            byte[] bytes = portletDataContext.getZipEntryAsByteArray(
622                                    smallImagePath);
623    
624                            smallFile = FileUtil.createTempFile(article.getSmallImageType());
625    
626                            FileUtil.write(smallFile, bytes);
627                    }
628    
629                    Map<String, byte[]> images = new HashMap<String, byte[]>();
630    
631                    String imagePath = articleElement.attributeValue("image-path");
632    
633                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "images") &&
634                            Validator.isNotNull(imagePath)) {
635    
636                            List<String> imageFiles = portletDataContext.getZipFolderEntries(
637                                    imagePath);
638    
639                            for (String imageFile : imageFiles) {
640                                    String fileName = imageFile;
641    
642                                    if (fileName.contains(StringPool.SLASH)) {
643                                            fileName = fileName.substring(
644                                                    fileName.lastIndexOf(CharPool.SLASH) + 1);
645                                    }
646    
647                                    if (fileName.endsWith(".xml")) {
648                                            continue;
649                                    }
650    
651                                    int pos = fileName.lastIndexOf(CharPool.PERIOD);
652    
653                                    if (pos != -1) {
654                                            fileName = fileName.substring(0, pos);
655                                    }
656    
657                                    images.put(
658                                            fileName,
659                                            portletDataContext.getZipEntryAsByteArray(imageFile));
660                            }
661                    }
662    
663                    String articleURL = null;
664    
665                    boolean addGroupPermissions = creationStrategy.addGroupPermissions(
666                            portletDataContext, article);
667                    boolean addGuestPermissions = creationStrategy.addGuestPermissions(
668                            portletDataContext, article);
669    
670                    ServiceContext serviceContext = portletDataContext.createServiceContext(
671                            articleElement, article, _NAMESPACE);
672    
673                    serviceContext.setAddGroupPermissions(addGroupPermissions);
674                    serviceContext.setAddGuestPermissions(addGuestPermissions);
675                    serviceContext.setAttribute("imported", Boolean.TRUE.toString());
676    
677                    if (article.getStatus() != WorkflowConstants.STATUS_APPROVED) {
678                            serviceContext.setWorkflowAction(
679                                    WorkflowConstants.ACTION_SAVE_DRAFT);
680                    }
681    
682                    JournalArticle importedArticle = null;
683    
684                    String articleResourceUuid = articleElement.attributeValue(
685                            "article-resource-uuid");
686    
687                    if (portletDataContext.isDataStrategyMirror()) {
688                            JournalArticleResource articleResource =
689                                    JournalArticleResourceUtil.fetchByUUID_G(
690                                            articleResourceUuid, portletDataContext.getScopeGroupId());
691    
692                            if (articleResource == null) {
693                                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
694                                            portletDataContext.getCompanyId());
695    
696                                    long companyGroupId = companyGroup.getGroupId();
697    
698                                    articleResource = JournalArticleResourceUtil.fetchByUUID_G(
699                                            articleResourceUuid, companyGroupId);
700                            }
701    
702                            serviceContext.setUuid(articleResourceUuid);
703                            serviceContext.setAttribute("urlTitle", article.getUrlTitle());
704    
705                            JournalArticle existingArticle = null;
706    
707                            if (articleResource != null) {
708                                    try {
709                                            existingArticle =
710                                                    JournalArticleLocalServiceUtil.getLatestArticle(
711                                                            articleResource.getResourcePrimKey(),
712                                                            WorkflowConstants.STATUS_ANY, false);
713                                    }
714                                    catch (NoSuchArticleException nsae) {
715                                    }
716                            }
717    
718                            if (existingArticle == null) {
719                                    existingArticle = JournalArticleUtil.fetchByG_A_V(
720                                            portletDataContext.getScopeGroupId(), newArticleId,
721                                            article.getVersion());
722                            }
723    
724                            if (existingArticle == null) {
725                                    importedArticle = JournalArticleLocalServiceUtil.addArticle(
726                                            userId, portletDataContext.getScopeGroupId(), folderId,
727                                            article.getClassNameId(), structurePrimaryKey, articleId,
728                                            autoArticleId, article.getVersion(), article.getTitleMap(),
729                                            article.getDescriptionMap(), article.getContent(),
730                                            article.getType(), parentStructureId, parentTemplateId,
731                                            article.getLayoutUuid(), displayDateMonth, displayDateDay,
732                                            displayDateYear, displayDateHour, displayDateMinute,
733                                            expirationDateMonth, expirationDateDay, expirationDateYear,
734                                            expirationDateHour, expirationDateMinute, neverExpire,
735                                            reviewDateMonth, reviewDateDay, reviewDateYear,
736                                            reviewDateHour, reviewDateMinute, neverReview,
737                                            article.isIndexable(), article.isSmallImage(),
738                                            article.getSmallImageURL(), smallFile, images, articleURL,
739                                            serviceContext);
740                            }
741                            else {
742                                    importedArticle = JournalArticleLocalServiceUtil.updateArticle(
743                                            userId, existingArticle.getGroupId(), folderId,
744                                            existingArticle.getArticleId(), article.getVersion(),
745                                            article.getTitleMap(), article.getDescriptionMap(),
746                                            article.getContent(), article.getType(), parentStructureId,
747                                            parentTemplateId, article.getLayoutUuid(), displayDateMonth,
748                                            displayDateDay, displayDateYear, displayDateHour,
749                                            displayDateMinute, expirationDateMonth, expirationDateDay,
750                                            expirationDateYear, expirationDateHour,
751                                            expirationDateMinute, neverExpire, reviewDateMonth,
752                                            reviewDateDay, reviewDateYear, reviewDateHour,
753                                            reviewDateMinute, neverReview, article.isIndexable(),
754                                            article.isSmallImage(), article.getSmallImageURL(),
755                                            smallFile, images, articleURL, serviceContext);
756                            }
757                    }
758                    else {
759                            importedArticle = JournalArticleLocalServiceUtil.addArticle(
760                                    userId, portletDataContext.getScopeGroupId(), folderId,
761                                    article.getClassNameId(), structurePrimaryKey, articleId,
762                                    autoArticleId, article.getVersion(), article.getTitleMap(),
763                                    article.getDescriptionMap(), article.getContent(),
764                                    article.getType(), parentStructureId, parentTemplateId,
765                                    article.getLayoutUuid(), displayDateMonth, displayDateDay,
766                                    displayDateYear, displayDateHour, displayDateMinute,
767                                    expirationDateMonth, expirationDateDay, expirationDateYear,
768                                    expirationDateHour, expirationDateMinute, neverExpire,
769                                    reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
770                                    reviewDateMinute, neverReview, article.isIndexable(),
771                                    article.isSmallImage(), article.getSmallImageURL(), smallFile,
772                                    images, articleURL, serviceContext);
773                    }
774    
775                    if (smallFile != null) {
776                            smallFile.delete();
777                    }
778    
779                    portletDataContext.importClassedModel(
780                            article, importedArticle, _NAMESPACE);
781    
782                    if (Validator.isNull(newArticleId)) {
783                            articleIds.put(
784                                    article.getArticleId(), importedArticle.getArticleId());
785                    }
786    
787                    if (!articleId.equals(importedArticle.getArticleId())) {
788                            if (_log.isWarnEnabled()) {
789                                    _log.warn(
790                                            "An article with the ID " + articleId + " already " +
791                                                    "exists. The new generated ID is " +
792                                                            importedArticle.getArticleId());
793                            }
794                    }
795            }
796    
797            public static void importFeed(
798                            PortletDataContext portletDataContext, Element feedElement)
799                    throws Exception {
800    
801                    String path = feedElement.attributeValue("path");
802    
803                    if (!portletDataContext.isPathNotProcessed(path)) {
804                            return;
805                    }
806    
807                    JournalFeed feed = (JournalFeed)portletDataContext.getZipEntryAsObject(
808                            path);
809    
810                    long userId = portletDataContext.getUserId(feed.getUserUuid());
811    
812                    JournalCreationStrategy creationStrategy =
813                            JournalCreationStrategyFactory.getInstance();
814    
815                    long authorId = creationStrategy.getAuthorUserId(
816                            portletDataContext, feed);
817    
818                    if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
819                            userId = authorId;
820                    }
821    
822                    Group group = GroupLocalServiceUtil.getGroup(
823                            portletDataContext.getScopeGroupId());
824    
825                    String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
826    
827                    String[] friendlyUrlParts = StringUtil.split(
828                            feed.getTargetLayoutFriendlyUrl(), '/');
829    
830                    String oldGroupFriendlyURL = friendlyUrlParts[2];
831    
832                    if (oldGroupFriendlyURL.equals("@data_handler_group_friendly_url@")) {
833                            feed.setTargetLayoutFriendlyUrl(
834                                    StringUtil.replace(
835                                            feed.getTargetLayoutFriendlyUrl(),
836                                            "@data_handler_group_friendly_url@", newGroupFriendlyURL));
837                    }
838    
839                    String feedId = feed.getFeedId();
840                    boolean autoFeedId = false;
841    
842                    if (Validator.isNumber(feedId) ||
843                            (JournalFeedUtil.fetchByG_F(
844                                    portletDataContext.getScopeGroupId(), feedId) != null)) {
845    
846                            autoFeedId = true;
847                    }
848    
849                    Map<String, String> structureIds =
850                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
851                                    JournalStructure.class + ".structureId");
852    
853                    String parentStructureId = MapUtil.getString(
854                            structureIds, feed.getStructureId(), feed.getStructureId());
855    
856                    Map<String, String> templateIds =
857                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
858                                    JournalTemplate.class + ".templateId");
859    
860                    String parentTemplateId = MapUtil.getString(
861                            templateIds, feed.getTemplateId(), feed.getTemplateId());
862                    String parentRenderTemplateId = MapUtil.getString(
863                            templateIds, feed.getRendererTemplateId(),
864                            feed.getRendererTemplateId());
865    
866                    boolean addGroupPermissions = creationStrategy.addGroupPermissions(
867                            portletDataContext, feed);
868                    boolean addGuestPermissions = creationStrategy.addGuestPermissions(
869                            portletDataContext, feed);
870    
871                    ServiceContext serviceContext = portletDataContext.createServiceContext(
872                            feedElement, feed, _NAMESPACE);
873    
874                    serviceContext.setAddGroupPermissions(addGroupPermissions);
875                    serviceContext.setAddGuestPermissions(addGuestPermissions);
876    
877                    JournalFeed importedFeed = null;
878    
879                    try {
880                            if (portletDataContext.isDataStrategyMirror()) {
881                                    JournalFeed existingFeed = JournalFeedUtil.fetchByUUID_G(
882                                            feed.getUuid(), portletDataContext.getScopeGroupId());
883    
884                                    if (existingFeed == null) {
885                                            serviceContext.setUuid(feed.getUuid());
886    
887                                            importedFeed = JournalFeedLocalServiceUtil.addFeed(
888                                                    userId, portletDataContext.getScopeGroupId(), feedId,
889                                                    autoFeedId, feed.getName(), feed.getDescription(),
890                                                    feed.getType(), parentStructureId, parentTemplateId,
891                                                    parentRenderTemplateId, feed.getDelta(),
892                                                    feed.getOrderByCol(), feed.getOrderByType(),
893                                                    feed.getTargetLayoutFriendlyUrl(),
894                                                    feed.getTargetPortletId(), feed.getContentField(),
895                                                    feed.getFeedType(), feed.getFeedVersion(),
896                                                    serviceContext);
897                                    }
898                                    else {
899                                            importedFeed = JournalFeedLocalServiceUtil.updateFeed(
900                                                    existingFeed.getGroupId(), existingFeed.getFeedId(),
901                                                    feed.getName(), feed.getDescription(), feed.getType(),
902                                                    parentStructureId, parentTemplateId,
903                                                    parentRenderTemplateId, feed.getDelta(),
904                                                    feed.getOrderByCol(), feed.getOrderByType(),
905                                                    feed.getTargetLayoutFriendlyUrl(),
906                                                    feed.getTargetPortletId(), feed.getContentField(),
907                                                    feed.getFeedType(), feed.getFeedVersion(),
908                                                    serviceContext);
909                                    }
910                            }
911                            else {
912                                    importedFeed = JournalFeedLocalServiceUtil.addFeed(
913                                            userId, portletDataContext.getScopeGroupId(), feedId,
914                                            autoFeedId, feed.getName(), feed.getDescription(),
915                                            feed.getType(), parentStructureId, parentTemplateId,
916                                            parentRenderTemplateId, feed.getDelta(),
917                                            feed.getOrderByCol(), feed.getOrderByType(),
918                                            feed.getTargetLayoutFriendlyUrl(),
919                                            feed.getTargetPortletId(), feed.getContentField(),
920                                            feed.getFeedType(), feed.getFeedVersion(), serviceContext);
921                            }
922    
923                            portletDataContext.importClassedModel(
924                                    feed, importedFeed, _NAMESPACE);
925    
926                            if (!feedId.equals(importedFeed.getFeedId())) {
927                                    if (_log.isWarnEnabled()) {
928                                            StringBundler sb = new StringBundler(5);
929    
930                                            sb.append("A feed with the ID ");
931                                            sb.append(feedId);
932                                            sb.append(" already exists. The new generated ID is ");
933                                            sb.append(importedFeed.getFeedId());
934                                            sb.append(".");
935    
936                                            _log.warn(sb.toString());
937                                    }
938                            }
939                    }
940                    catch (FeedTargetLayoutFriendlyUrlException ftlfurle) {
941                            if (_log.isWarnEnabled()) {
942                                    StringBundler sb = new StringBundler(6);
943    
944                                    sb.append("A feed with the ID ");
945                                    sb.append(feedId);
946                                    sb.append(" cannot be imported because layout with friendly ");
947                                    sb.append("URL ");
948                                    sb.append(feed.getTargetLayoutFriendlyUrl());
949                                    sb.append(" does not exist");
950    
951                                    _log.warn(sb.toString());
952                            }
953                    }
954            }
955    
956            public static String importReferencedContent(
957                            PortletDataContext portletDataContext, Element parentElement,
958                            String content)
959                    throws Exception {
960    
961                    content = importDLFileEntries(
962                            portletDataContext, parentElement, content);
963    
964                    Group group = GroupLocalServiceUtil.getGroup(
965                            portletDataContext.getScopeGroupId());
966    
967                    content = StringUtil.replace(
968                            content, "@data_handler_group_friendly_url@",
969                            group.getFriendlyURL());
970    
971                    content = importLinksToLayout(portletDataContext, content);
972    
973                    return content;
974            }
975    
976            public static void importReferencedData(
977                            PortletDataContext portletDataContext, Element entityElement)
978                    throws Exception {
979    
980                    Element dlRepositoriesElement = entityElement.element(
981                            "dl-repositories");
982    
983                    List<Element> dlRepositoryElements = Collections.emptyList();
984    
985                    if (dlRepositoriesElement != null) {
986                            dlRepositoryElements = dlRepositoriesElement.elements("repository");
987                    }
988    
989                    for (Element repositoryElement : dlRepositoryElements) {
990                            DLPortletDataHandlerImpl.importRepository(
991                                    portletDataContext, repositoryElement);
992                    }
993    
994                    Element dlRepositoryEntriesElement = entityElement.element(
995                            "dl-repository-entries");
996    
997                    List<Element> dlRepositoryEntryElements = Collections.emptyList();
998    
999                    if (dlRepositoryEntriesElement != null) {
1000                            dlRepositoryEntryElements = dlRepositoryEntriesElement.elements(
1001                                    "repository-entry");
1002                    }
1003    
1004                    for (Element repositoryEntryElement : dlRepositoryEntryElements) {
1005                            DLPortletDataHandlerImpl.importRepositoryEntry(
1006                                    portletDataContext, repositoryEntryElement);
1007                    }
1008    
1009                    Element dlFoldersElement = entityElement.element("dl-folders");
1010    
1011                    List<Element> dlFolderElements = Collections.emptyList();
1012    
1013                    if (dlFoldersElement != null) {
1014                            dlFolderElements = dlFoldersElement.elements("folder");
1015                    }
1016    
1017                    for (Element folderElement : dlFolderElements) {
1018                            DLPortletDataHandlerImpl.importFolder(
1019                                    portletDataContext, folderElement);
1020                    }
1021    
1022                    Element dlFileEntriesElement = entityElement.element("dl-file-entries");
1023    
1024                    List<Element> dlFileEntryElements = Collections.emptyList();
1025    
1026                    if (dlFileEntriesElement != null) {
1027                            dlFileEntryElements = dlFileEntriesElement.elements("file-entry");
1028                    }
1029    
1030                    for (Element fileEntryElement : dlFileEntryElements) {
1031                            DLPortletDataHandlerImpl.importFileEntry(
1032                                    portletDataContext, fileEntryElement);
1033                    }
1034    
1035                    Element dlFileRanksElement = entityElement.element("dl-file-ranks");
1036    
1037                    List<Element> dlFileRankElements = Collections.emptyList();
1038    
1039                    if (dlFileRanksElement != null) {
1040                            dlFileRankElements = dlFileRanksElement.elements("file-rank");
1041                    }
1042    
1043                    for (Element fileRankElement : dlFileRankElements) {
1044                            DLPortletDataHandlerImpl.importFileRank(
1045                                    portletDataContext, fileRankElement);
1046                    }
1047            }
1048    
1049            public static void importStructure(
1050                            PortletDataContext portletDataContext, Element structureElement)
1051                    throws Exception {
1052    
1053                    String path = structureElement.attributeValue("path");
1054    
1055                    if (!portletDataContext.isPathNotProcessed(path)) {
1056                            return;
1057                    }
1058    
1059                    JournalStructure structure =
1060                            (JournalStructure)portletDataContext.getZipEntryAsObject(path);
1061    
1062                    long userId = portletDataContext.getUserId(structure.getUserUuid());
1063    
1064                    JournalCreationStrategy creationStrategy =
1065                            JournalCreationStrategyFactory.getInstance();
1066    
1067                    long authorId = creationStrategy.getAuthorUserId(
1068                            portletDataContext, structure);
1069    
1070                    if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
1071                            userId = authorId;
1072                    }
1073    
1074                    String structureId = structure.getStructureId();
1075                    boolean autoStructureId = false;
1076    
1077                    if (Validator.isNumber(structureId) ||
1078                            (JournalStructureUtil.fetchByG_S(
1079                                    portletDataContext.getScopeGroupId(), structureId) != null)) {
1080    
1081                            autoStructureId = true;
1082                    }
1083    
1084                    Map<String, String> structureIds =
1085                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
1086                                    JournalStructure.class + ".structureId");
1087    
1088                    String parentStructureId = MapUtil.getString(
1089                            structureIds, structure.getParentStructureId(),
1090                            structure.getParentStructureId());
1091    
1092                    Document document = structureElement.getDocument();
1093    
1094                    Element rootElement = document.getRootElement();
1095    
1096                    String parentStructureUuid = GetterUtil.getString(
1097                            structureElement.attributeValue("parent-structure-uuid"));
1098    
1099                    String parentPath = getStructurePath(
1100                            portletDataContext, parentStructureUuid);
1101    
1102                    Element parentStructureElement = (Element)rootElement.selectSingleNode(
1103                            "//structure[@path='".concat(parentPath).concat("']"));
1104    
1105                    if ((parentStructureElement != null) &&
1106                            Validator.isNotNull(parentStructureId)) {
1107    
1108                            importStructure(portletDataContext, parentStructureElement);
1109    
1110                            parentStructureId = structureIds.get(parentStructureId);
1111                    }
1112    
1113                    boolean addGroupPermissions = creationStrategy.addGroupPermissions(
1114                            portletDataContext, structure);
1115                    boolean addGuestPermissions = creationStrategy.addGuestPermissions(
1116                            portletDataContext, structure);
1117    
1118                    ServiceContext serviceContext = portletDataContext.createServiceContext(
1119                            structureElement, structure, _NAMESPACE);
1120    
1121                    serviceContext.setAddGroupPermissions(addGroupPermissions);
1122                    serviceContext.setAddGuestPermissions(addGuestPermissions);
1123    
1124                    JournalStructure importedStructure = null;
1125    
1126                    if (portletDataContext.isDataStrategyMirror()) {
1127                            JournalStructure existingStructure =
1128                                    JournalStructureUtil.fetchByUUID_G(
1129                                            structure.getUuid(), portletDataContext.getScopeGroupId());
1130    
1131                            if (existingStructure == null) {
1132                                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
1133                                            portletDataContext.getCompanyId());
1134    
1135                                    long companyGroupId = companyGroup.getGroupId();
1136    
1137                                    existingStructure = JournalStructureUtil.fetchByUUID_G(
1138                                            structure.getUuid(), companyGroupId);
1139                            }
1140    
1141                            if (existingStructure == null) {
1142                                    serviceContext.setUuid(structure.getUuid());
1143    
1144                                    importedStructure =
1145                                            JournalStructureLocalServiceUtil.addStructure(
1146                                                    userId, portletDataContext.getScopeGroupId(),
1147                                                    structureId, autoStructureId, parentStructureId,
1148                                                    structure.getNameMap(), structure.getDescriptionMap(),
1149                                                    structure.getXsd(), serviceContext);
1150                            }
1151                            else {
1152                                    importedStructure =
1153                                            JournalStructureLocalServiceUtil.updateStructure(
1154                                                    existingStructure.getGroupId(),
1155                                                    existingStructure.getStructureId(), parentStructureId,
1156                                                    structure.getNameMap(), structure.getDescriptionMap(),
1157                                                    structure.getXsd(), serviceContext);
1158                            }
1159                    }
1160                    else {
1161                            importedStructure = JournalStructureLocalServiceUtil.addStructure(
1162                                    userId, portletDataContext.getScopeGroupId(), structureId,
1163                                    autoStructureId, parentStructureId, structure.getNameMap(),
1164                                    structure.getDescriptionMap(), structure.getXsd(),
1165                                    serviceContext);
1166                    }
1167    
1168                    portletDataContext.importClassedModel(
1169                            structure, importedStructure, _NAMESPACE);
1170    
1171                    structureIds.put(structureId, importedStructure.getStructureId());
1172    
1173                    if (!structureId.equals(importedStructure.getStructureId())) {
1174                            if (_log.isWarnEnabled()) {
1175                                    _log.warn(
1176                                            "A structure with the ID " + structureId + " already " +
1177                                                    "exists. The new generated ID is " +
1178                                                            importedStructure.getStructureId());
1179                            }
1180                    }
1181            }
1182    
1183            public static void importTemplate(
1184                            PortletDataContext portletDataContext, Element templateElement)
1185                    throws Exception {
1186    
1187                    String path = templateElement.attributeValue("path");
1188    
1189                    if (!portletDataContext.isPathNotProcessed(path)) {
1190                            return;
1191                    }
1192    
1193                    JournalTemplate template =
1194                            (JournalTemplate)portletDataContext.getZipEntryAsObject(path);
1195    
1196                    long userId = portletDataContext.getUserId(template.getUserUuid());
1197    
1198                    JournalCreationStrategy creationStrategy =
1199                            JournalCreationStrategyFactory.getInstance();
1200    
1201                    long authorId = creationStrategy.getAuthorUserId(
1202                            portletDataContext, template);
1203    
1204                    if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
1205                            userId = authorId;
1206                    }
1207    
1208                    String templateId = template.getTemplateId();
1209                    boolean autoTemplateId = false;
1210    
1211                    if (Validator.isNumber(templateId) ||
1212                            (JournalTemplateUtil.fetchByG_T(
1213                                    portletDataContext.getScopeGroupId(), templateId) != null)) {
1214    
1215                            autoTemplateId = true;
1216                    }
1217    
1218                    Map<String, String> structureIds =
1219                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
1220                                    JournalStructure.class + ".structureId");
1221    
1222                    String parentStructureId = MapUtil.getString(
1223                            structureIds, template.getStructureId(), template.getStructureId());
1224    
1225                    String xsl = template.getXsl();
1226    
1227                    xsl = importDLFileEntries(portletDataContext, templateElement, xsl);
1228    
1229                    Group group = GroupLocalServiceUtil.getGroup(
1230                            portletDataContext.getScopeGroupId());
1231    
1232                    xsl = StringUtil.replace(
1233                            xsl, "@data_handler_group_friendly_url@", group.getFriendlyURL());
1234    
1235                    template.setXsl(xsl);
1236    
1237                    boolean formatXsl = false;
1238    
1239                    boolean addGroupPermissions = creationStrategy.addGroupPermissions(
1240                            portletDataContext, template);
1241                    boolean addGuestPermissions = creationStrategy.addGuestPermissions(
1242                            portletDataContext, template);
1243    
1244                    ServiceContext serviceContext = portletDataContext.createServiceContext(
1245                            templateElement, template, _NAMESPACE);
1246    
1247                    serviceContext.setAddGroupPermissions(addGroupPermissions);
1248                    serviceContext.setAddGuestPermissions(addGuestPermissions);
1249    
1250                    File smallFile = null;
1251    
1252                    String smallImagePath = templateElement.attributeValue(
1253                            "small-image-path");
1254    
1255                    if (template.isSmallImage() && Validator.isNotNull(smallImagePath)) {
1256                            if (smallImagePath.endsWith(StringPool.PERIOD)) {
1257                                    smallImagePath += template.getSmallImageType();
1258                            }
1259    
1260                            byte[] bytes = portletDataContext.getZipEntryAsByteArray(
1261                                    smallImagePath);
1262    
1263                            if (bytes != null) {
1264                                    smallFile = FileUtil.createTempFile(
1265                                            template.getSmallImageType());
1266    
1267                                    FileUtil.write(smallFile, bytes);
1268                            }
1269                    }
1270    
1271                    JournalTemplate importedTemplate = null;
1272    
1273                    if (portletDataContext.isDataStrategyMirror()) {
1274                            JournalTemplate existingTemplate =
1275                                    JournalTemplateUtil.fetchByUUID_G(
1276                                            template.getUuid(), portletDataContext.getScopeGroupId());
1277    
1278                            if (existingTemplate == null) {
1279                                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
1280                                            portletDataContext.getCompanyId());
1281    
1282                                    long companyGroupId = companyGroup.getGroupId();
1283    
1284                                    existingTemplate = JournalTemplateUtil.fetchByUUID_G(
1285                                            template.getUuid(), companyGroupId);
1286                            }
1287    
1288                            if (existingTemplate == null) {
1289                                    serviceContext.setUuid(template.getUuid());
1290    
1291                                    importedTemplate = JournalTemplateLocalServiceUtil.addTemplate(
1292                                            userId, portletDataContext.getScopeGroupId(), templateId,
1293                                            autoTemplateId, parentStructureId, template.getNameMap(),
1294                                            template.getDescriptionMap(), template.getXsl(), formatXsl,
1295                                            template.getLangType(), template.getCacheable(),
1296                                            template.isSmallImage(), template.getSmallImageURL(),
1297                                            smallFile, serviceContext);
1298                            }
1299                            else {
1300                                    String structureId = existingTemplate.getStructureId();
1301    
1302                                    if (Validator.isNull(structureId) &&
1303                                            Validator.isNotNull(template.getStructureId())) {
1304    
1305                                            JournalStructure structure =
1306                                                    JournalStructureUtil.fetchByG_S(
1307                                                            template.getGroupId(), template.getStructureId());
1308    
1309                                            if (structure == null) {
1310                                                    structureId = template.getStructureId();
1311                                            }
1312                                            else {
1313                                                    JournalStructure existingStructure =
1314                                                            JournalStructureUtil.findByUUID_G(
1315                                                                    structure.getUuid(),
1316                                                                    portletDataContext.getScopeGroupId());
1317    
1318                                                    structureId = existingStructure.getStructureId();
1319                                            }
1320                                    }
1321    
1322                                    importedTemplate =
1323                                            JournalTemplateLocalServiceUtil.updateTemplate(
1324                                                    existingTemplate.getGroupId(),
1325                                                    existingTemplate.getTemplateId(), structureId,
1326                                                    template.getNameMap(), template.getDescriptionMap(),
1327                                                    template.getXsl(), formatXsl, template.getLangType(),
1328                                                    template.getCacheable(), template.isSmallImage(),
1329                                                    template.getSmallImageURL(), smallFile, serviceContext);
1330                            }
1331                    }
1332                    else {
1333                            importedTemplate = JournalTemplateLocalServiceUtil.addTemplate(
1334                                    userId, portletDataContext.getScopeGroupId(), templateId,
1335                                    autoTemplateId, parentStructureId, template.getNameMap(),
1336                                    template.getDescriptionMap(), template.getXsl(), formatXsl,
1337                                    template.getLangType(), template.getCacheable(),
1338                                    template.isSmallImage(), template.getSmallImageURL(), smallFile,
1339                                    serviceContext);
1340                    }
1341    
1342                    if (smallFile != null) {
1343                            smallFile.delete();
1344                    }
1345    
1346                    portletDataContext.importClassedModel(
1347                            template, importedTemplate, _NAMESPACE);
1348    
1349                    Map<String, String> templateIds =
1350                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
1351                                    JournalTemplate.class + ".templateId");
1352    
1353                    templateIds.put(
1354                            template.getTemplateId(), importedTemplate.getTemplateId());
1355    
1356                    if (!templateId.equals(importedTemplate.getTemplateId())) {
1357                            if (_log.isWarnEnabled()) {
1358                                    _log.warn(
1359                                            "A template with the ID " + templateId + " already " +
1360                                                    "exists. The new generated ID is " +
1361                                                            importedTemplate.getTemplateId());
1362                            }
1363                    }
1364            }
1365    
1366            @Override
1367            public PortletDataHandlerControl[] getExportControls() {
1368                    return new PortletDataHandlerControl[] {
1369                            _articles, _structuresTemplatesAndFeeds, _embeddedAssets,
1370                            _versionHistory
1371                    };
1372            }
1373    
1374            @Override
1375            public PortletDataHandlerControl[] getExportMetadataControls() {
1376                    return new PortletDataHandlerControl[] {
1377                            new PortletDataHandlerBoolean(
1378                                    _NAMESPACE, "web-content", true, _metadataControls)
1379                    };
1380            }
1381    
1382            @Override
1383            public PortletDataHandlerControl[] getImportControls() {
1384                    return new PortletDataHandlerControl[] {
1385                            _articles, _structuresTemplatesAndFeeds
1386                    };
1387            }
1388    
1389            @Override
1390            public PortletDataHandlerControl[] getImportMetadataControls() {
1391                    return new PortletDataHandlerControl[] {
1392                            new PortletDataHandlerBoolean(
1393                                    _NAMESPACE, "web-content", true, _metadataControls)
1394                    };
1395            }
1396    
1397            @Override
1398            public boolean isAlwaysExportable() {
1399                    return _ALWAYS_EXPORTABLE;
1400            }
1401    
1402            @Override
1403            public boolean isDataLocalized() {
1404                    return _DATA_LOCALIZED;
1405            }
1406    
1407            @Override
1408            public boolean isPublishToLiveByDefault() {
1409                    return PropsValues.JOURNAL_PUBLISH_TO_LIVE_BY_DEFAULT;
1410            }
1411    
1412            protected static String exportDLFileEntries(
1413                            PortletDataContext portletDataContext,
1414                            Element dlFileEntryTypesElement, Element dlFoldersElement,
1415                            Element dlFileEntriesElement, Element dlFileRanksElement,
1416                            Element dlRepositoriesElement, Element dlRepositoryEntriesElement,
1417                            Element entityElement, String content, boolean checkDateRange)
1418                    throws Exception {
1419    
1420                    Group group = GroupLocalServiceUtil.getGroup(
1421                            portletDataContext.getGroupId());
1422    
1423                    if (group.isStagingGroup()) {
1424                            group = group.getLiveGroup();
1425                    }
1426    
1427                    if (group.isStaged() && !group.isStagedRemotely() &&
1428                            !group.isStagedPortlet(PortletKeys.DOCUMENT_LIBRARY)) {
1429    
1430                            return content;
1431                    }
1432    
1433                    StringBuilder sb = new StringBuilder(content);
1434    
1435                    int beginPos = content.length();
1436                    int currentLocation = -1;
1437    
1438                    boolean legacyURL = true;
1439    
1440                    while (true) {
1441                            currentLocation = content.lastIndexOf(
1442                                    "/c/document_library/get_file?", beginPos);
1443    
1444                            if (currentLocation == -1) {
1445                                    currentLocation = content.lastIndexOf(
1446                                            "/image/image_gallery?", beginPos);
1447                            }
1448    
1449                            if (currentLocation == -1) {
1450                                    currentLocation = content.lastIndexOf("/documents/", beginPos);
1451    
1452                                    legacyURL = false;
1453                            }
1454    
1455                            if (currentLocation == -1) {
1456                                    return sb.toString();
1457                            }
1458    
1459                            beginPos = currentLocation;
1460    
1461                            int endPos1 = content.indexOf(CharPool.APOSTROPHE, beginPos);
1462                            int endPos2 = content.indexOf(CharPool.CLOSE_BRACKET, beginPos);
1463                            int endPos3 = content.indexOf(CharPool.CLOSE_CURLY_BRACE, beginPos);
1464                            int endPos4 = content.indexOf(CharPool.CLOSE_PARENTHESIS, beginPos);
1465                            int endPos5 = content.indexOf(CharPool.LESS_THAN, beginPos);
1466                            int endPos6 = content.indexOf(CharPool.QUESTION, beginPos);
1467                            int endPos7 = content.indexOf(CharPool.QUOTE, beginPos);
1468                            int endPos8 = content.indexOf(CharPool.SPACE, beginPos);
1469    
1470                            int endPos = endPos1;
1471    
1472                            if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
1473                                    endPos = endPos2;
1474                            }
1475    
1476                            if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
1477                                    endPos = endPos3;
1478                            }
1479    
1480                            if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
1481                                    endPos = endPos4;
1482                            }
1483    
1484                            if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
1485                                    endPos = endPos5;
1486                            }
1487    
1488                            if ((endPos == -1) ||
1489                                    ((endPos6 != -1) && (endPos6 < endPos) && !legacyURL)) {
1490    
1491                                    endPos = endPos6;
1492                            }
1493    
1494                            if ((endPos == -1) || ((endPos7 != -1) && (endPos7 < endPos))) {
1495                                    endPos = endPos7;
1496                            }
1497    
1498                            if ((endPos == -1) || ((endPos8 != -1) && (endPos8 < endPos))) {
1499                                    endPos = endPos8;
1500                            }
1501    
1502                            if ((beginPos == -1) || (endPos == -1)) {
1503                                    break;
1504                            }
1505    
1506                            try {
1507                                    String oldParameters = content.substring(beginPos, endPos);
1508    
1509                                    while (oldParameters.contains(StringPool.AMPERSAND_ENCODED)) {
1510                                            oldParameters = oldParameters.replace(
1511                                                    StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
1512                                    }
1513    
1514                                    Map<String, String[]> map = new HashMap<String, String[]>();
1515    
1516                                    if (oldParameters.startsWith("/documents/")) {
1517                                            String[] pathArray = oldParameters.split(StringPool.SLASH);
1518    
1519                                            map.put("groupId", new String[] {pathArray[2]});
1520    
1521                                            if (pathArray.length == 4) {
1522                                                    map.put("uuid", new String[] {pathArray[3]});
1523                                            }
1524                                            else if (pathArray.length == 5) {
1525                                                    map.put("folderId", new String[] {pathArray[3]});
1526    
1527                                                    String title = HttpUtil.decodeURL(pathArray[4]);
1528    
1529                                                    int pos = title.indexOf(StringPool.QUESTION);
1530    
1531                                                    if (pos != -1) {
1532                                                            title = title.substring(0, pos);
1533                                                    }
1534    
1535                                                    map.put("title", new String[] {title});
1536                                            }
1537                                            else if (pathArray.length > 5) {
1538                                                    String uuid = pathArray[5];
1539    
1540                                                    int pos = uuid.indexOf(StringPool.QUESTION);
1541    
1542                                                    if (pos != -1) {
1543                                                            uuid = uuid.substring(0, pos);
1544                                                    }
1545    
1546                                                    map.put("uuid", new String[] {uuid});
1547                                            }
1548                                    }
1549                                    else {
1550                                            oldParameters = oldParameters.substring(
1551                                                    oldParameters.indexOf(CharPool.QUESTION) + 1);
1552    
1553                                            map = HttpUtil.parameterMapFromString(oldParameters);
1554                                    }
1555    
1556                                    FileEntry fileEntry = null;
1557    
1558                                    String uuid = MapUtil.getString(map, "uuid");
1559    
1560                                    if (Validator.isNotNull(uuid)) {
1561                                            String groupIdString = MapUtil.getString(map, "groupId");
1562    
1563                                            long groupId = GetterUtil.getLong(groupIdString);
1564    
1565                                            if (groupIdString.equals("@group_id@")) {
1566                                                    groupId = portletDataContext.getScopeGroupId();
1567                                            }
1568    
1569                                            fileEntry =
1570                                                    DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1571                                                            uuid, groupId);
1572                                    }
1573                                    else {
1574                                            String folderIdString = MapUtil.getString(map, "folderId");
1575    
1576                                            if (Validator.isNotNull(folderIdString)) {
1577                                                    long folderId = GetterUtil.getLong(folderIdString);
1578                                                    String name = MapUtil.getString(map, "name");
1579                                                    String title = MapUtil.getString(map, "title");
1580    
1581                                                    String groupIdString = MapUtil.getString(
1582                                                            map, "groupId");
1583    
1584                                                    long groupId = GetterUtil.getLong(groupIdString);
1585    
1586                                                    if (groupIdString.equals("@group_id@")) {
1587                                                            groupId = portletDataContext.getScopeGroupId();
1588                                                    }
1589    
1590                                                    if (Validator.isNotNull(title)) {
1591                                                            fileEntry = DLAppLocalServiceUtil.getFileEntry(
1592                                                                    groupId, folderId, title);
1593                                                    }
1594                                                    else {
1595                                                            DLFileEntry dlFileEntry =
1596                                                                    DLFileEntryLocalServiceUtil.getFileEntryByName(
1597                                                                            groupId, folderId, name);
1598    
1599                                                            fileEntry = new LiferayFileEntry(dlFileEntry);
1600                                                    }
1601                                            }
1602                                            else if (map.containsKey("image_id") ||
1603                                                             map.containsKey("img_id") ||
1604                                                             map.containsKey("i_id")) {
1605    
1606                                                    long imageId = MapUtil.getLong(map, "image_id");
1607    
1608                                                    if (imageId <= 0) {
1609                                                            imageId = MapUtil.getLong(map, "img_id");
1610    
1611                                                            if (imageId <= 0) {
1612                                                                    imageId = MapUtil.getLong(map, "i_id");
1613                                                            }
1614                                                    }
1615    
1616                                                    DLFileEntry dlFileEntry =
1617                                                            DLFileEntryLocalServiceUtil.
1618                                                                    fetchFileEntryByAnyImageId(imageId);
1619    
1620                                                    if (dlFileEntry != null) {
1621                                                            fileEntry = new LiferayFileEntry(dlFileEntry);
1622                                                    }
1623                                            }
1624                                    }
1625    
1626                                    if (fileEntry == null) {
1627                                            beginPos--;
1628    
1629                                            continue;
1630                                    }
1631    
1632                                    DLPortletDataHandlerImpl.exportFileEntry(
1633                                            portletDataContext, dlFileEntryTypesElement,
1634                                            dlFoldersElement, dlFileEntriesElement, dlFileRanksElement,
1635                                            dlRepositoriesElement, dlRepositoryEntriesElement,
1636                                            fileEntry, checkDateRange);
1637    
1638                                    Element dlReferenceElement = entityElement.addElement(
1639                                            "dl-reference");
1640    
1641                                    dlReferenceElement.addAttribute(
1642                                            "default-repository",
1643                                            String.valueOf(fileEntry.isDefaultRepository()));
1644    
1645                                    String path = null;
1646    
1647                                    if (fileEntry.isDefaultRepository()) {
1648                                            path = DLPortletDataHandlerImpl.getFileEntryPath(
1649                                                    portletDataContext, fileEntry);
1650    
1651                                    }
1652                                    else {
1653                                            path = DLPortletDataHandlerImpl.getRepositoryEntryPath(
1654                                                    portletDataContext, fileEntry.getFileEntryId());
1655                                    }
1656    
1657                                    dlReferenceElement.addAttribute("path", path);
1658    
1659                                    String dlReference = "[$dl-reference=" + path + "$]";
1660    
1661                                    sb.replace(beginPos, endPos, dlReference);
1662                            }
1663                            catch (Exception e) {
1664                                    if (_log.isDebugEnabled()) {
1665                                            _log.debug(e, e);
1666                                    }
1667                                    else if (_log.isWarnEnabled()) {
1668                                            _log.warn(e.getMessage());
1669                                    }
1670                            }
1671    
1672                            beginPos--;
1673                    }
1674    
1675                    return sb.toString();
1676            }
1677    
1678            protected static void exportFeed(
1679                            PortletDataContext portletDataContext, Element feedsElement,
1680                            JournalFeed feed)
1681                    throws Exception {
1682    
1683                    if (!portletDataContext.isWithinDateRange(feed.getModifiedDate())) {
1684                            return;
1685                    }
1686    
1687                    String path = getFeedPath(portletDataContext, feed);
1688    
1689                    if (!portletDataContext.isPathNotProcessed(path)) {
1690                            return;
1691                    }
1692    
1693                    feed = (JournalFeed)feed.clone();
1694    
1695                    Element feedElement = feedsElement.addElement("feed");
1696    
1697                    Group group = GroupLocalServiceUtil.getGroup(
1698                            portletDataContext.getScopeGroupId());
1699    
1700                    String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
1701    
1702                    String[] friendlyUrlParts = StringUtil.split(
1703                            feed.getTargetLayoutFriendlyUrl(), '/');
1704    
1705                    String oldGroupFriendlyURL = friendlyUrlParts[2];
1706    
1707                    if (newGroupFriendlyURL.equals(oldGroupFriendlyURL)) {
1708                            String targetLayoutFriendlyUrl = StringUtil.replaceFirst(
1709                                    feed.getTargetLayoutFriendlyUrl(),
1710                                    StringPool.SLASH + newGroupFriendlyURL + StringPool.SLASH,
1711                                    "/@data_handler_group_friendly_url@/");
1712    
1713                            feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
1714                    }
1715    
1716                    portletDataContext.addClassedModel(feedElement, path, feed, _NAMESPACE);
1717            }
1718    
1719            protected static void exportFolder(
1720                            PortletDataContext portletDataContext, Element foldersElement,
1721                            Element articlesElement, Element structuresElement,
1722                            Element templatesElement, Element dlFileEntryTypesElement,
1723                            Element dlFoldersElement, Element dlFileEntriesElement,
1724                            Element dlFileRanksElement, Element dlRepositoriesElement,
1725                            Element dlRepositoryEntriesElement, JournalFolder folder,
1726                            boolean checkDateRange)
1727                    throws Exception {
1728    
1729                    if (checkDateRange &&
1730                            !portletDataContext.isWithinDateRange(folder.getModifiedDate())) {
1731    
1732                            return;
1733                    }
1734    
1735                    exportParentFolder(
1736                            portletDataContext, foldersElement, folder.getParentFolderId());
1737    
1738                    String path = getFolderPath(portletDataContext, folder);
1739    
1740                    if (portletDataContext.isPathNotProcessed(path)) {
1741                            Element folderElement = foldersElement.addElement("folder");
1742    
1743                            portletDataContext.addClassedModel(
1744                                    folderElement, path, folder, _NAMESPACE);
1745                    }
1746    
1747                    List<JournalArticle> articles = JournalArticleUtil.findByG_F(
1748                            folder.getGroupId(), folder.getFolderId());
1749    
1750                    for (JournalArticle article : articles) {
1751                            exportArticle(
1752                                    portletDataContext, articlesElement, structuresElement,
1753                                    templatesElement, dlFileEntryTypesElement, dlFoldersElement,
1754                                    dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
1755                                    dlRepositoryEntriesElement, article, true);
1756                    }
1757            }
1758    
1759            protected static String exportLayoutFriendlyURLs(
1760                    PortletDataContext portletDataContext, String content) {
1761    
1762                    Group group = null;
1763    
1764                    try {
1765                            group = GroupLocalServiceUtil.getGroup(
1766                                    portletDataContext.getScopeGroupId());
1767                    }
1768                    catch (Exception e) {
1769                            if (_log.isWarnEnabled()) {
1770                                    _log.warn(e);
1771                            }
1772    
1773                            return content;
1774                    }
1775    
1776                    StringBuilder sb = new StringBuilder(content);
1777    
1778                    String friendlyURLPrivateGroupPath =
1779                            PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
1780                    String friendlyURLPrivateUserPath =
1781                            PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
1782                    String friendlyURLPublicPath =
1783                            PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
1784    
1785                    String href = "href=";
1786    
1787                    int beginPos = content.length();
1788    
1789                    while (true) {
1790                            int hrefLength = href.length();
1791    
1792                            beginPos = content.lastIndexOf(href, beginPos);
1793    
1794                            if (beginPos == -1) {
1795                                    break;
1796                            }
1797    
1798                            char c = content.charAt(beginPos + hrefLength);
1799    
1800                            if ((c == CharPool.APOSTROPHE) || (c == CharPool.QUOTE)) {
1801                                    hrefLength++;
1802                            }
1803    
1804                            int endPos1 = content.indexOf(
1805                                    CharPool.APOSTROPHE, beginPos + hrefLength);
1806                            int endPos2 = content.indexOf(
1807                                    CharPool.CLOSE_BRACKET, beginPos + hrefLength);
1808                            int endPos3 = content.indexOf(
1809                                    CharPool.CLOSE_CURLY_BRACE, beginPos + hrefLength);
1810                            int endPos4 = content.indexOf(
1811                                    CharPool.CLOSE_PARENTHESIS, beginPos + hrefLength);
1812                            int endPos5 = content.indexOf(
1813                                    CharPool.LESS_THAN, beginPos + hrefLength);
1814                            int endPos6 = content.indexOf(
1815                                    CharPool.QUESTION, beginPos + hrefLength);
1816                            int endPos7 = content.indexOf(
1817                                    CharPool.QUOTE, beginPos + hrefLength);
1818                            int endPos8 = content.indexOf(
1819                                    CharPool.SPACE, beginPos + hrefLength);
1820    
1821                            int endPos = endPos1;
1822    
1823                            if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
1824                                    endPos = endPos2;
1825                            }
1826    
1827                            if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
1828                                    endPos = endPos3;
1829                            }
1830    
1831                            if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
1832                                    endPos = endPos4;
1833                            }
1834    
1835                            if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
1836                                    endPos = endPos5;
1837                            }
1838    
1839                            if ((endPos == -1) || ((endPos6 != -1) && (endPos6 < endPos))) {
1840                                    endPos = endPos6;
1841                            }
1842    
1843                            if ((endPos == -1) || ((endPos7 != -1) && (endPos7 < endPos))) {
1844                                    endPos = endPos7;
1845                            }
1846    
1847                            if ((endPos == -1) || ((endPos8 != -1) && (endPos8 < endPos))) {
1848                                    endPos = endPos8;
1849                            }
1850    
1851                            if (endPos == -1) {
1852                                    beginPos--;
1853    
1854                                    continue;
1855                            }
1856    
1857                            String url = content.substring(beginPos + hrefLength, endPos);
1858    
1859                            if (!url.startsWith(friendlyURLPrivateGroupPath) &&
1860                                    !url.startsWith(friendlyURLPrivateUserPath) &&
1861                                    !url.startsWith(friendlyURLPublicPath)) {
1862    
1863                                    beginPos--;
1864    
1865                                    continue;
1866                            }
1867    
1868                            int beginGroupPos = content.indexOf(
1869                                    CharPool.SLASH, beginPos + hrefLength + 1);
1870    
1871                            if (beginGroupPos == -1) {
1872                                    beginPos--;
1873    
1874                                    continue;
1875                            }
1876    
1877                            int endGroupPos = content.indexOf(
1878                                    CharPool.SLASH, beginGroupPos + 1);
1879    
1880                            if (endGroupPos == -1) {
1881                                    beginPos--;
1882    
1883                                    continue;
1884                            }
1885    
1886                            String groupFriendlyURL = content.substring(
1887                                    beginGroupPos, endGroupPos);
1888    
1889                            if (groupFriendlyURL.equals(group.getFriendlyURL())) {
1890                                    sb.replace(
1891                                            beginGroupPos, endGroupPos,
1892                                            "@data_handler_group_friendly_url@");
1893                            }
1894    
1895                            beginPos--;
1896                    }
1897    
1898                    return sb.toString();
1899            }
1900    
1901            protected static String exportLinksToLayout(
1902                            PortletDataContext portletDataContext, String content)
1903                    throws Exception {
1904    
1905                    List<String> oldLinksToLayout = new ArrayList<String>();
1906                    List<String> newLinksToLayout = new ArrayList<String>();
1907    
1908                    Matcher matcher = _exportLinksToLayoutPattern.matcher(content);
1909    
1910                    while (matcher.find()) {
1911                            long layoutId = GetterUtil.getLong(matcher.group(1));
1912    
1913                            String type = matcher.group(2);
1914    
1915                            boolean privateLayout = type.startsWith("private");
1916    
1917                            try {
1918                                    Layout layout = LayoutLocalServiceUtil.getLayout(
1919                                            portletDataContext.getScopeGroupId(), privateLayout,
1920                                            layoutId);
1921    
1922                                    String oldLinkToLayout = matcher.group(0);
1923    
1924                                    StringBundler sb = new StringBundler(5);
1925    
1926                                    sb.append(type);
1927                                    sb.append(StringPool.AT);
1928                                    sb.append(layout.getUuid());
1929                                    sb.append(StringPool.AT);
1930                                    sb.append(layout.getFriendlyURL());
1931    
1932                                    String newLinkToLayout = StringUtil.replace(
1933                                            oldLinkToLayout, type, sb.toString());
1934    
1935                                    oldLinksToLayout.add(oldLinkToLayout);
1936                                    newLinksToLayout.add(newLinkToLayout);
1937                            }
1938                            catch (Exception e) {
1939                                    if (_log.isDebugEnabled() || _log.isWarnEnabled()) {
1940                                            String message =
1941                                                    "Unable to get layout with ID " + layoutId +
1942                                                            " in group " + portletDataContext.getScopeGroupId();
1943    
1944                                            if (_log.isWarnEnabled()) {
1945                                                    _log.warn(message);
1946                                            }
1947                                            else {
1948                                                    _log.debug(message, e);
1949                                            }
1950                                    }
1951                            }
1952                    }
1953    
1954                    content = StringUtil.replace(
1955                            content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
1956                            ArrayUtil.toStringArray(newLinksToLayout.toArray()));
1957    
1958                    return content;
1959            }
1960    
1961            protected static void exportParentFolder(
1962                            PortletDataContext portletDataContext, Element foldersElement,
1963                            long folderId)
1964                    throws Exception {
1965    
1966                    if (folderId == JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1967                            return;
1968                    }
1969    
1970                    JournalFolder folder = JournalFolderUtil.findByPrimaryKey(folderId);
1971    
1972                    exportParentFolder(
1973                            portletDataContext, foldersElement, folder.getParentFolderId());
1974    
1975                    String path = getFolderPath(portletDataContext, folder);
1976    
1977                    if (portletDataContext.isPathNotProcessed(path)) {
1978                            Element folderElement = foldersElement.addElement("folder");
1979    
1980                            portletDataContext.addClassedModel(
1981                                    folderElement, path, folder, _NAMESPACE);
1982                    }
1983            }
1984    
1985            protected static void exportStructure(
1986                            PortletDataContext portletDataContext, Element structuresElement,
1987                            JournalStructure structure)
1988                    throws Exception {
1989    
1990                    String path = getStructurePath(portletDataContext, structure.getUuid());
1991    
1992                    if (!portletDataContext.isPathNotProcessed(path)) {
1993                            return;
1994                    }
1995    
1996                    JournalStructure parentStructure = null;
1997    
1998                    String parentStructureId = structure.getParentStructureId();
1999    
2000                    if (Validator.isNotNull(parentStructureId)) {
2001                            try {
2002                                    parentStructure =
2003                                            JournalStructureLocalServiceUtil.getStructure(
2004                                                    structure.getGroupId(), parentStructureId, true);
2005    
2006                                    exportStructure(
2007                                            portletDataContext, structuresElement, parentStructure);
2008                            }
2009                            catch (NoSuchStructureException nsse) {
2010                            }
2011                    }
2012    
2013                    Element structureElement = structuresElement.addElement("structure");
2014    
2015                    if (parentStructure != null) {
2016                            structureElement.addAttribute(
2017                                    "parent-structure-uuid", parentStructure.getUuid());
2018                    }
2019    
2020                    portletDataContext.addClassedModel(
2021                            structureElement, path, structure, _NAMESPACE);
2022            }
2023    
2024            protected static void exportTemplate(
2025                            PortletDataContext portletDataContext, Element templatesElement,
2026                            Element dlFileEntryTypesElement, Element dlFoldersElement,
2027                            Element dlFileEntriesElement, Element dlFileRanksElement,
2028                            Element dlRepositoriesElement, Element dlRepositoryEntriesElement,
2029                            JournalTemplate template)
2030                    throws Exception {
2031    
2032                    String path = getTemplatePath(portletDataContext, template);
2033    
2034                    if (!portletDataContext.isPathNotProcessed(path)) {
2035                            return;
2036                    }
2037    
2038                    // Clone this template to make sure changes to its content are never
2039                    // persisted
2040    
2041                    template = (JournalTemplate)template.clone();
2042    
2043                    Element templateElement = templatesElement.addElement("template");
2044    
2045                    if (template.isSmallImage()) {
2046                            String smallImagePath = getTemplateSmallImagePath(
2047                                    portletDataContext, template);
2048    
2049                            templateElement.addAttribute("small-image-path", smallImagePath);
2050    
2051                            Image smallImage = ImageUtil.fetchByPrimaryKey(
2052                                    template.getSmallImageId());
2053    
2054                            template.setSmallImageType(smallImage.getType());
2055    
2056                            portletDataContext.addZipEntry(
2057                                    smallImagePath, smallImage.getTextObj());
2058                    }
2059    
2060                    if (portletDataContext.getBooleanParameter(
2061                                    _NAMESPACE, "embedded-assets")) {
2062    
2063                            String content = exportReferencedContent(
2064                                    portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
2065                                    dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
2066                                    dlRepositoryEntriesElement, templateElement, template.getXsl());
2067    
2068                            template.setXsl(content);
2069                    }
2070    
2071                    portletDataContext.addClassedModel(
2072                            templateElement, path, template, _NAMESPACE);
2073            }
2074    
2075            protected static String getArticleImagePath(
2076                            PortletDataContext portletDataContext, JournalArticle article)
2077                    throws Exception {
2078    
2079                    StringBundler sb = new StringBundler(6);
2080    
2081                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2082                    sb.append("/articles/");
2083                    sb.append(article.getArticleResourceUuid());
2084                    sb.append(StringPool.SLASH);
2085                    sb.append(article.getVersion());
2086                    sb.append(StringPool.SLASH);
2087    
2088                    return sb.toString();
2089            }
2090    
2091            protected static String getArticleImagePath(
2092                            PortletDataContext portletDataContext, JournalArticle article,
2093                            JournalArticleImage articleImage, Image image)
2094                    throws Exception {
2095    
2096                    StringBundler sb = new StringBundler(12);
2097    
2098                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2099                    sb.append("/articles/");
2100                    sb.append(article.getArticleResourceUuid());
2101                    sb.append(StringPool.SLASH);
2102                    sb.append(article.getVersion());
2103                    sb.append(StringPool.SLASH);
2104                    sb.append(articleImage.getElInstanceId());
2105                    sb.append(StringPool.UNDERLINE);
2106                    sb.append(articleImage.getElName());
2107    
2108                    if (Validator.isNotNull(articleImage.getLanguageId())) {
2109                            sb.append(articleImage.getLanguageId());
2110                    }
2111    
2112                    sb.append(StringPool.PERIOD);
2113                    sb.append(image.getType());
2114    
2115                    return sb.toString();
2116            }
2117    
2118            protected static String getArticleSmallImagePath(
2119                            PortletDataContext portletDataContext, JournalArticle article)
2120                    throws Exception {
2121    
2122                    StringBundler sb = new StringBundler(6);
2123    
2124                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2125                    sb.append("/articles/");
2126                    sb.append(article.getArticleResourceUuid());
2127                    sb.append("/thumbnail");
2128                    sb.append(StringPool.PERIOD);
2129                    sb.append(article.getSmallImageType());
2130    
2131                    return sb.toString();
2132            }
2133    
2134            protected static String getFeedPath(
2135                    PortletDataContext portletDataContext, JournalFeed feed) {
2136    
2137                    StringBundler sb = new StringBundler(4);
2138    
2139                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2140                    sb.append("/feeds/");
2141                    sb.append(feed.getUuid());
2142                    sb.append(".xml");
2143    
2144                    return sb.toString();
2145            }
2146    
2147            protected static String getFolderPath(
2148                    PortletDataContext portletDataContext, JournalFolder folder) {
2149    
2150                    StringBundler sb = new StringBundler(4);
2151    
2152                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2153                    sb.append("/folders/");
2154                    sb.append(folder.getFolderId());
2155                    sb.append(".xml");
2156    
2157                    return sb.toString();
2158            }
2159    
2160            protected static String getImportFolderPath(
2161                    PortletDataContext portletDataContext, long folderId) {
2162    
2163                    StringBundler sb = new StringBundler(4);
2164    
2165                    sb.append(portletDataContext.getSourcePortletPath(PortletKeys.JOURNAL));
2166                    sb.append("/folders/");
2167                    sb.append(folderId);
2168                    sb.append(".xml");
2169    
2170                    return sb.toString();
2171            }
2172    
2173            protected static String getStructurePath(
2174                    PortletDataContext portletDataContext, String uuid) {
2175    
2176                    StringBundler sb = new StringBundler(4);
2177    
2178                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2179                    sb.append("/structures/");
2180                    sb.append(uuid);
2181                    sb.append(".xml");
2182    
2183                    return sb.toString();
2184            }
2185    
2186            protected static String getTemplatePath(
2187                    PortletDataContext portletDataContext, JournalTemplate template) {
2188    
2189                    StringBundler sb = new StringBundler(4);
2190    
2191                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2192                    sb.append("/templates/");
2193                    sb.append(template.getUuid());
2194                    sb.append(".xml");
2195    
2196                    return sb.toString();
2197            }
2198    
2199            protected static String getTemplateSmallImagePath(
2200                            PortletDataContext portletDataContext, JournalTemplate template)
2201                    throws Exception {
2202    
2203                    StringBundler sb = new StringBundler(5);
2204    
2205                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
2206                    sb.append("/templates/thumbnail-");
2207                    sb.append(template.getUuid());
2208                    sb.append(StringPool.PERIOD);
2209                    sb.append(template.getSmallImageType());
2210    
2211                    return sb.toString();
2212            }
2213    
2214            protected static String importDLFileEntries(
2215                            PortletDataContext portletDataContext, Element parentElement,
2216                            String content)
2217                    throws Exception {
2218    
2219                    List<Element> dlReferenceElements = parentElement.elements(
2220                            "dl-reference");
2221    
2222                    for (Element dlReferenceElement : dlReferenceElements) {
2223                            String dlReferencePath = dlReferenceElement.attributeValue("path");
2224    
2225                            String fileEntryUUID = null;
2226    
2227                            try {
2228                                    Object zipEntryObject = portletDataContext.getZipEntryAsObject(
2229                                            dlReferencePath);
2230    
2231                                    if (zipEntryObject == null) {
2232                                            if (_log.isWarnEnabled()) {
2233                                                    _log.warn("Unable to reference " + dlReferencePath);
2234                                            }
2235    
2236                                            continue;
2237                                    }
2238    
2239                                    boolean defaultRepository = GetterUtil.getBoolean(
2240                                            dlReferenceElement.attributeValue("default-repository"));
2241    
2242                                    if (defaultRepository) {
2243                                            FileEntry fileEntry = (FileEntry)zipEntryObject;
2244    
2245                                            fileEntryUUID = fileEntry.getUuid();
2246                                    }
2247                                    else {
2248                                            RepositoryEntry repositoryEntry =
2249                                                    (RepositoryEntry)zipEntryObject;
2250    
2251                                            fileEntryUUID = repositoryEntry.getUuid();
2252                                    }
2253                            }
2254                            catch (Exception e) {
2255                                    if (_log.isDebugEnabled()) {
2256                                            _log.debug(e, e);
2257                                    }
2258                                    else if (_log.isWarnEnabled()) {
2259                                            _log.warn(e.getMessage());
2260                                    }
2261                            }
2262    
2263                            if (fileEntryUUID == null) {
2264                                    continue;
2265                            }
2266    
2267                            FileEntry fileEntry =
2268                                    DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
2269                                            fileEntryUUID, portletDataContext.getGroupId());
2270    
2271                            if (fileEntry == null) {
2272                                    continue;
2273                            }
2274    
2275                            String dlReference = "[$dl-reference=" + dlReferencePath + "$]";
2276    
2277                            String url = DLUtil.getPreviewURL(
2278                                    fileEntry, fileEntry.getFileVersion(), null, StringPool.BLANK,
2279                                    false, false);
2280    
2281                            content = StringUtil.replace(content, dlReference, url);
2282                    }
2283    
2284                    return content;
2285            }
2286    
2287            protected static void importFolder(
2288                            PortletDataContext portletDataContext, Element folderElement)
2289                    throws Exception {
2290    
2291                    String path = folderElement.attributeValue("path");
2292    
2293                    if (!portletDataContext.isPathNotProcessed(path)) {
2294                            return;
2295                    }
2296    
2297                    JournalFolder folder =
2298                            (JournalFolder)portletDataContext.getZipEntryAsObject(path);
2299    
2300                    importFolder(portletDataContext, path, folder);
2301            }
2302    
2303            protected static void importFolder(
2304                            PortletDataContext portletDataContext, String folderPath,
2305                            JournalFolder folder)
2306                    throws Exception {
2307    
2308                    long userId = portletDataContext.getUserId(folder.getUserUuid());
2309    
2310                    Map<Long, Long> folderIds =
2311                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
2312                                    JournalFolder.class);
2313    
2314                    long parentFolderId = MapUtil.getLong(
2315                            folderIds, folder.getParentFolderId(), folder.getParentFolderId());
2316    
2317                    if ((parentFolderId !=
2318                                    JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
2319                            (parentFolderId == folder.getParentFolderId())) {
2320    
2321                            String path = getImportFolderPath(
2322                                    portletDataContext, parentFolderId);
2323    
2324                            JournalFolder parentFolder =
2325                                    (JournalFolder)portletDataContext.getZipEntryAsObject(path);
2326    
2327                            importFolder(portletDataContext, path, parentFolder);
2328    
2329                            parentFolderId = MapUtil.getLong(
2330                                    folderIds, folder.getParentFolderId(),
2331                                    folder.getParentFolderId());
2332                    }
2333    
2334                    ServiceContext serviceContext = portletDataContext.createServiceContext(
2335                            folderPath, folder, _NAMESPACE);
2336    
2337                    JournalFolder importedFolder = null;
2338    
2339                    long groupId = portletDataContext.getScopeGroupId();
2340    
2341                    if (portletDataContext.isDataStrategyMirror()) {
2342                            JournalFolder existingFolder = JournalFolderUtil.fetchByUUID_G(
2343                                    folder.getUuid(), groupId);
2344    
2345                            if (existingFolder == null) {
2346                                    serviceContext.setUuid(folder.getUuid());
2347    
2348                                    importedFolder = JournalFolderLocalServiceUtil.addFolder(
2349                                            userId, groupId, parentFolderId, folder.getName(),
2350                                            folder.getDescription(), serviceContext);
2351                            }
2352                            else {
2353                                    importedFolder = JournalFolderLocalServiceUtil.updateFolder(
2354                                            existingFolder.getFolderId(), parentFolderId,
2355                                            folder.getName(), folder.getDescription(), false,
2356                                            serviceContext);
2357                            }
2358                    }
2359                    else {
2360                            importedFolder = JournalFolderLocalServiceUtil.addFolder(
2361                                    userId, groupId, parentFolderId, folder.getName(),
2362                                    folder.getDescription(), serviceContext);
2363                    }
2364    
2365                    portletDataContext.importClassedModel(
2366                            folder, importedFolder, _NAMESPACE);
2367            }
2368    
2369            protected static String importLinksToLayout(
2370                            PortletDataContext portletDataContext, String content)
2371                    throws Exception {
2372    
2373                    List<String> oldLinksToLayout = new ArrayList<String>();
2374                    List<String> newLinksToLayout = new ArrayList<String>();
2375    
2376                    Matcher matcher = _importLinksToLayoutPattern.matcher(content);
2377    
2378                    while (matcher.find()) {
2379                            long oldLayoutId = GetterUtil.getLong(matcher.group(1));
2380    
2381                            long newLayoutId = oldLayoutId;
2382    
2383                            String type = matcher.group(2);
2384    
2385                            boolean privateLayout = type.startsWith("private");
2386    
2387                            String layoutUuid = matcher.group(3);
2388    
2389                            String friendlyURL = matcher.group(4);
2390    
2391                            try {
2392                                    Layout layout = LayoutUtil.fetchByUUID_G(
2393                                            layoutUuid, portletDataContext.getScopeGroupId());
2394    
2395                                    if (layout == null) {
2396                                            layout = LayoutUtil.fetchByG_P_F(
2397                                                    portletDataContext.getScopeGroupId(), privateLayout,
2398                                                    friendlyURL);
2399                                    }
2400    
2401                                    if (layout == null) {
2402                                            layout = LayoutUtil.fetchByG_P_L(
2403                                                    portletDataContext.getScopeGroupId(), privateLayout,
2404                                                    oldLayoutId);
2405                                    }
2406    
2407                                    if (layout == null) {
2408                                            if (_log.isWarnEnabled()) {
2409                                                    StringBundler sb = new StringBundler(9);
2410    
2411                                                    sb.append("Unable to get layout with UUID ");
2412                                                    sb.append(layoutUuid);
2413                                                    sb.append(", friendly URL ");
2414                                                    sb.append(friendlyURL);
2415                                                    sb.append(", or ");
2416                                                    sb.append("layoutId ");
2417                                                    sb.append(oldLayoutId);
2418                                                    sb.append(" in group ");
2419                                                    sb.append(portletDataContext.getScopeGroupId());
2420    
2421                                                    _log.warn(sb.toString());
2422                                            }
2423                                    }
2424                                    else {
2425                                            newLayoutId = layout.getLayoutId();
2426                                    }
2427                            }
2428                            catch (SystemException se) {
2429                                    if (_log.isWarnEnabled()) {
2430                                            _log.warn(
2431                                                    "Unable to get layout in group " +
2432                                                            portletDataContext.getScopeGroupId(), se);
2433                                    }
2434                            }
2435    
2436                            String oldLinkToLayout = matcher.group(0);
2437    
2438                            StringBundler sb = new StringBundler(4);
2439    
2440                            sb.append(StringPool.AT);
2441                            sb.append(layoutUuid);
2442                            sb.append(StringPool.AT);
2443                            sb.append(friendlyURL);
2444    
2445                            String newLinkToLayout = StringUtil.replace(
2446                                    oldLinkToLayout,
2447                                    new String[] {sb.toString(), String.valueOf(oldLayoutId)},
2448                                    new String[] {StringPool.BLANK, String.valueOf(newLayoutId)});
2449    
2450                            oldLinksToLayout.add(oldLinkToLayout);
2451                            newLinksToLayout.add(newLinkToLayout);
2452                    }
2453    
2454                    content = StringUtil.replace(
2455                            content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
2456                            ArrayUtil.toStringArray(newLinksToLayout.toArray()));
2457    
2458                    return content;
2459            }
2460    
2461            protected static void prepareLanguagesForImport(JournalArticle article)
2462                    throws PortalException {
2463    
2464                    Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
2465                            article.getDefaultLocale());
2466    
2467                    Locale[] articleAvailableLocales = LocaleUtil.fromLanguageIds(
2468                            article.getAvailableLocales());
2469    
2470                    Locale defaultImportLocale = LocalizationUtil.getDefaultImportLocale(
2471                            JournalArticle.class.getName(), article.getPrimaryKey(),
2472                            articleDefaultLocale, articleAvailableLocales);
2473    
2474                    article.prepareLocalizedFieldsForImport(defaultImportLocale);
2475            }
2476    
2477            @Override
2478            protected PortletPreferences doDeleteData(
2479                            PortletDataContext portletDataContext, String portletId,
2480                            PortletPreferences portletPreferences)
2481                    throws Exception {
2482    
2483                    if (!portletDataContext.addPrimaryKey(
2484                                    JournalPortletDataHandlerImpl.class, "deleteData")) {
2485    
2486                            JournalArticleLocalServiceUtil.deleteArticles(
2487                                    portletDataContext.getScopeGroupId());
2488    
2489                            JournalTemplateLocalServiceUtil.deleteTemplates(
2490                                    portletDataContext.getScopeGroupId());
2491    
2492                            JournalStructureLocalServiceUtil.deleteStructures(
2493                                    portletDataContext.getScopeGroupId());
2494                    }
2495    
2496                    return portletPreferences;
2497            }
2498    
2499            @Override
2500            protected String doExportData(
2501                            PortletDataContext portletDataContext, String portletId,
2502                            PortletPreferences portletPreferences)
2503                    throws Exception {
2504    
2505                    portletDataContext.addPermissions(
2506                            "com.liferay.portlet.journal",
2507                            portletDataContext.getScopeGroupId());
2508    
2509                    Document document = SAXReaderUtil.createDocument();
2510    
2511                    Element rootElement = document.addElement("journal-data");
2512    
2513                    rootElement.addAttribute(
2514                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
2515    
2516                    Element structuresElement = rootElement.addElement("structures");
2517    
2518                    List<JournalStructure> structures = JournalStructureUtil.findByGroupId(
2519                            portletDataContext.getScopeGroupId(), QueryUtil.ALL_POS,
2520                            QueryUtil.ALL_POS, new StructurePKComparator(true));
2521    
2522                    for (JournalStructure structure : structures) {
2523                            if (portletDataContext.isWithinDateRange(
2524                                            structure.getModifiedDate())) {
2525    
2526                                    exportStructure(
2527                                            portletDataContext, structuresElement, structure);
2528                            }
2529                    }
2530    
2531                    Element templatesElement = rootElement.addElement("templates");
2532                    Element dlFileEntryTypesElement = rootElement.addElement(
2533                            "dl-file-entry-types");
2534                    Element dlFoldersElement = rootElement.addElement("dl-folders");
2535                    Element dlFilesElement = rootElement.addElement("dl-file-entries");
2536                    Element dlFileRanksElement = rootElement.addElement("dl-file-ranks");
2537                    Element dlRepositoriesElement = rootElement.addElement(
2538                            "dl-repositories");
2539                    Element dlRepositoryEntriesElement = rootElement.addElement(
2540                            "dl-repository-entries");
2541    
2542                    List<JournalTemplate> templates = JournalTemplateUtil.findByGroupId(
2543                            portletDataContext.getScopeGroupId());
2544    
2545                    for (JournalTemplate template : templates) {
2546                            if (portletDataContext.isWithinDateRange(
2547                                            template.getModifiedDate())) {
2548    
2549                                    exportTemplate(
2550                                            portletDataContext, templatesElement,
2551                                            dlFileEntryTypesElement, dlFoldersElement, dlFilesElement,
2552                                            dlFileRanksElement, dlRepositoriesElement,
2553                                            dlRepositoryEntriesElement, template);
2554                            }
2555                    }
2556    
2557                    Element feedsElement = rootElement.addElement("feeds");
2558    
2559                    List<JournalFeed> feeds = JournalFeedUtil.findByGroupId(
2560                            portletDataContext.getScopeGroupId());
2561    
2562                    for (JournalFeed feed : feeds) {
2563                            if (portletDataContext.isWithinDateRange(feed.getModifiedDate())) {
2564                                    exportFeed(portletDataContext, feedsElement, feed);
2565                            }
2566                    }
2567    
2568                    Element foldersElement = rootElement.addElement("folders");
2569                    Element articlesElement = rootElement.addElement("articles");
2570    
2571                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "web-content")) {
2572                            List<JournalFolder> folders = JournalFolderUtil.findByGroupId(
2573                                    portletDataContext.getScopeGroupId());
2574    
2575                            for (JournalFolder folder : folders) {
2576                                    exportFolder(
2577                                            portletDataContext, foldersElement, articlesElement,
2578                                            structuresElement, templatesElement,
2579                                            dlFileEntryTypesElement, dlFoldersElement, dlFilesElement,
2580                                            dlFileRanksElement, dlRepositoriesElement,
2581                                            dlRepositoryEntriesElement, folder, true);
2582                            }
2583    
2584                            List<JournalArticle> articles = JournalArticleUtil.findByG_F(
2585                                    portletDataContext.getScopeGroupId(),
2586                                    JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID,
2587                                    QueryUtil.ALL_POS, QueryUtil.ALL_POS,
2588                                    new ArticleIDComparator(true));
2589    
2590                            for (JournalArticle article : articles) {
2591                                    if (portletDataContext.getBooleanParameter(
2592                                                    _NAMESPACE, "version-history") ||
2593                                            JournalArticleLocalServiceUtil.isLatestVersion(
2594                                                    article.getGroupId(), article.getArticleId(),
2595                                                    article.getVersion(),
2596                                                    WorkflowConstants.STATUS_APPROVED)) {
2597    
2598                                            exportArticle(
2599                                                    portletDataContext, articlesElement, structuresElement,
2600                                                    templatesElement, dlFileEntryTypesElement,
2601                                                    dlFoldersElement, dlFilesElement, dlFileRanksElement,
2602                                                    dlRepositoriesElement, dlRepositoryEntriesElement,
2603                                                    article, true);
2604                                    }
2605                            }
2606                    }
2607    
2608                    return document.formattedString();
2609            }
2610    
2611            @Override
2612            protected PortletPreferences doImportData(
2613                            PortletDataContext portletDataContext, String portletId,
2614                            PortletPreferences portletPreferences, String data)
2615                    throws Exception {
2616    
2617                    portletDataContext.importPermissions(
2618                            "com.liferay.portlet.journal",
2619                            portletDataContext.getSourceGroupId(),
2620                            portletDataContext.getScopeGroupId());
2621    
2622                    Document document = SAXReaderUtil.read(data);
2623    
2624                    Element rootElement = document.getRootElement();
2625    
2626                    importReferencedData(portletDataContext, rootElement);
2627    
2628                    Element structuresElement = rootElement.element("structures");
2629    
2630                    List<Element> structureElements = structuresElement.elements(
2631                            "structure");
2632    
2633                    for (Element structureElement : structureElements) {
2634                            importStructure(portletDataContext, structureElement);
2635                    }
2636    
2637                    Element templatesElement = rootElement.element("templates");
2638    
2639                    List<Element> templateElements = templatesElement.elements("template");
2640    
2641                    for (Element templateElement : templateElements) {
2642                            importTemplate(portletDataContext, templateElement);
2643                    }
2644    
2645                    Element feedsElement = rootElement.element("feeds");
2646    
2647                    List<Element> feedElements = feedsElement.elements("feed");
2648    
2649                    for (Element feedElement : feedElements) {
2650                            importFeed(portletDataContext, feedElement);
2651                    }
2652    
2653                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "web-content")) {
2654                            Element foldersElement = rootElement.element("folders");
2655    
2656                            List<Element> folderElements = foldersElement.elements("folder");
2657    
2658                            for (Element folderElement : folderElements) {
2659                                    importFolder(portletDataContext, folderElement);
2660                            }
2661    
2662                            Element articlesElement = rootElement.element("articles");
2663    
2664                            List<Element> articleElements = articlesElement.elements("article");
2665    
2666                            for (Element articleElement : articleElements) {
2667                                    try {
2668                                            importArticle(portletDataContext, articleElement);
2669                                    }
2670                                    catch (ArticleContentException ace) {
2671                                            if (_log.isWarnEnabled()) {
2672                                                    String path = articleElement.attributeValue("path");
2673    
2674                                                    _log.warn(
2675                                                            "Skipping article with path " + path +
2676                                                                    " because of invalid content");
2677                                            }
2678                                    }
2679                            }
2680                    }
2681    
2682                    return portletPreferences;
2683            }
2684    
2685            private static final boolean _ALWAYS_EXPORTABLE = true;
2686    
2687            private static final boolean _DATA_LOCALIZED = true;
2688    
2689            private static final String _NAMESPACE = "journal";
2690    
2691            private static Log _log = LogFactoryUtil.getLog(
2692                    JournalPortletDataHandlerImpl.class);
2693    
2694            private static PortletDataHandlerBoolean _articles =
2695                    new PortletDataHandlerBoolean(_NAMESPACE, "web-content");
2696    
2697            private static PortletDataHandlerBoolean _embeddedAssets =
2698                    new PortletDataHandlerBoolean(_NAMESPACE, "embedded-assets");
2699    
2700            private static Pattern _exportLinksToLayoutPattern = Pattern.compile(
2701                    "\\[([0-9]+)@(public|private\\-[a-z]*)\\]");
2702    
2703            private static Pattern _importLinksToLayoutPattern = Pattern.compile(
2704                    "\\[([0-9]+)@(public|private\\-[a-z]*)@(\\p{XDigit}{8}\\-" +
2705                    "(?:\\p{XDigit}{4}\\-){3}\\p{XDigit}{12})@([^\\]]*)\\]");
2706    
2707            private static PortletDataHandlerControl[] _metadataControls =
2708                    new PortletDataHandlerControl[] {
2709                            new PortletDataHandlerBoolean(_NAMESPACE, "images"),
2710                            new PortletDataHandlerBoolean(_NAMESPACE, "categories"),
2711                            new PortletDataHandlerBoolean(_NAMESPACE, "comments"),
2712                            new PortletDataHandlerBoolean(_NAMESPACE, "ratings"),
2713                            new PortletDataHandlerBoolean(_NAMESPACE, "tags")
2714                    };
2715    
2716            private static PortletDataHandlerBoolean _structuresTemplatesAndFeeds =
2717                    new PortletDataHandlerBoolean(
2718                            _NAMESPACE, "structures-templates-and-feeds", true, true);
2719    
2720            private static PortletDataHandlerBoolean _versionHistory =
2721                    new PortletDataHandlerBoolean(
2722                            _NAMESPACE, "version-history",
2723                            PropsValues.JOURNAL_PUBLISH_VERSION_HISTORY_BY_DEFAULT);
2724    
2725    }