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