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