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