001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.journal.lar;
016    
017    import com.liferay.portal.NoSuchImageException;
018    import com.liferay.portal.kernel.dao.orm.QueryUtil;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.lar.BasePortletDataHandler;
021    import com.liferay.portal.kernel.lar.PortletDataContext;
022    import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
023    import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.repository.model.FileEntry;
027    import com.liferay.portal.kernel.util.ArrayUtil;
028    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
029    import com.liferay.portal.kernel.util.CharPool;
030    import com.liferay.portal.kernel.util.FileUtil;
031    import com.liferay.portal.kernel.util.GetterUtil;
032    import com.liferay.portal.kernel.util.HtmlUtil;
033    import com.liferay.portal.kernel.util.HttpUtil;
034    import com.liferay.portal.kernel.util.MapUtil;
035    import com.liferay.portal.kernel.util.StringBundler;
036    import com.liferay.portal.kernel.util.StringPool;
037    import com.liferay.portal.kernel.util.StringUtil;
038    import com.liferay.portal.kernel.util.Validator;
039    import com.liferay.portal.kernel.workflow.WorkflowConstants;
040    import com.liferay.portal.kernel.xml.Document;
041    import com.liferay.portal.kernel.xml.Element;
042    import com.liferay.portal.kernel.xml.SAXReaderUtil;
043    import com.liferay.portal.model.Group;
044    import com.liferay.portal.model.Image;
045    import com.liferay.portal.model.Layout;
046    import com.liferay.portal.model.User;
047    import com.liferay.portal.service.GroupLocalServiceUtil;
048    import com.liferay.portal.service.LayoutLocalServiceUtil;
049    import com.liferay.portal.service.ServiceContext;
050    import com.liferay.portal.service.UserLocalServiceUtil;
051    import com.liferay.portal.service.persistence.ImageUtil;
052    import com.liferay.portal.service.persistence.LayoutUtil;
053    import com.liferay.portal.util.PortletKeys;
054    import com.liferay.portal.util.PropsValues;
055    import com.liferay.portlet.documentlibrary.lar.DLPortletDataHandlerImpl;
056    import com.liferay.portlet.documentlibrary.lar.FileEntryUtil;
057    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
058    import com.liferay.portlet.journal.FeedTargetLayoutFriendlyUrlException;
059    import com.liferay.portlet.journal.NoSuchArticleException;
060    import com.liferay.portlet.journal.NoSuchStructureException;
061    import com.liferay.portlet.journal.NoSuchTemplateException;
062    import com.liferay.portlet.journal.model.JournalArticle;
063    import com.liferay.portlet.journal.model.JournalArticleConstants;
064    import com.liferay.portlet.journal.model.JournalArticleImage;
065    import com.liferay.portlet.journal.model.JournalArticleResource;
066    import com.liferay.portlet.journal.model.JournalFeed;
067    import com.liferay.portlet.journal.model.JournalStructure;
068    import com.liferay.portlet.journal.model.JournalTemplate;
069    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
070    import com.liferay.portlet.journal.service.JournalFeedLocalServiceUtil;
071    import com.liferay.portlet.journal.service.JournalStructureLocalServiceUtil;
072    import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
073    import com.liferay.portlet.journal.service.persistence.JournalArticleImageUtil;
074    import com.liferay.portlet.journal.service.persistence.JournalArticleResourceUtil;
075    import com.liferay.portlet.journal.service.persistence.JournalArticleUtil;
076    import com.liferay.portlet.journal.service.persistence.JournalFeedUtil;
077    import com.liferay.portlet.journal.service.persistence.JournalStructureUtil;
078    import com.liferay.portlet.journal.service.persistence.JournalTemplateUtil;
079    import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
080    import com.liferay.portlet.journal.util.comparator.StructurePKComparator;
081    
082    import java.io.File;
083    
084    import java.util.ArrayList;
085    import java.util.Calendar;
086    import java.util.Collections;
087    import java.util.Date;
088    import java.util.HashMap;
089    import java.util.List;
090    import java.util.Map;
091    import java.util.regex.Matcher;
092    import java.util.regex.Pattern;
093    
094    import javax.portlet.PortletPreferences;
095    
096    /**
097     * <p>
098     * Provides the Journal portlet export and import functionality, which is to
099     * clone all articles, structures, and templates associated with the layout's
100     * group. Upon import, new instances of the corresponding articles, structures,
101     * and templates are created or updated according to the DATA_MIRROW strategy
102     * The author of the newly created objects are determined by the
103     * JournalCreationStrategy class defined in <i>portal.properties</i>. That
104     * strategy also allows the text of the journal article to be modified prior to
105     * import.
106     * </p>
107     *
108     * <p>
109     * This <code>PortletDataHandler</code> differs from
110     * <code>JournalContentPortletDataHandlerImpl</code> in that it exports all
111     * articles owned by the group whether or not they are actually displayed in a
112     * portlet in the layout set.
113     * </p>
114     *
115     * @author Raymond Augé
116     * @author Joel Kozikowski
117     * @author Brian Wing Shun Chan
118     * @author Bruno Farache
119     * @author Karthik Sudarshan
120     * @author Wesley Gong
121     * @author Hugo Huijser
122     * @see    com.liferay.portal.kernel.lar.PortletDataHandler
123     * @see    com.liferay.portlet.journal.lar.JournalContentPortletDataHandlerImpl
124     * @see    com.liferay.portlet.journal.lar.JournalCreationStrategy
125     */
126    public class JournalPortletDataHandlerImpl extends BasePortletDataHandler {
127    
128            public static void exportArticle(
129                            PortletDataContext portletDataContext, Element articlesElement,
130                            Element structuresElement, Element templatesElement,
131                            Element dlFileEntryTypesElement, Element dlFoldersElement,
132                            Element dlFileEntriesElement, Element dlFileRanksElement,
133                            Element igFoldersElement, Element igImagesElement,
134                            JournalArticle article, boolean checkDateRange)
135                    throws Exception {
136    
137                    if (checkDateRange &&
138                            !portletDataContext.isWithinDateRange(article.getModifiedDate())) {
139    
140                            return;
141                    }
142    
143                    if ((article.getStatus() != WorkflowConstants.STATUS_APPROVED) &&
144                            (article.getStatus() != WorkflowConstants.STATUS_EXPIRED)) {
145    
146                            return;
147                    }
148    
149                    String path = getArticlePath(portletDataContext, article);
150    
151                    if (!portletDataContext.isPathNotProcessed(path)) {
152                            return;
153                    }
154    
155                    // Clone this article to make sure changes to its content are never
156                    // persisted
157    
158                    article = (JournalArticle)article.clone();
159    
160                    Element articleElement = (Element)articlesElement.selectSingleNode(
161                            "//article[@path='".concat(path).concat("']"));
162    
163                    if (articleElement == null) {
164                            articleElement = articlesElement.addElement("article");
165                    }
166    
167                    articleElement.addAttribute(
168                            "article-resource-uuid", article.getArticleResourceUuid());
169    
170                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
171                            article.getCompanyId());
172    
173                    if (Validator.isNotNull(article.getStructureId())) {
174                            JournalStructure structure = null;
175    
176                            try {
177                                    structure = JournalStructureLocalServiceUtil.getStructure(
178                                            article.getGroupId(), article.getStructureId());
179                            }
180                            catch (NoSuchStructureException nsse) {
181                                    structure = JournalStructureLocalServiceUtil.getStructure(
182                                            companyGroup.getGroupId(), article.getStructureId());
183                            }
184    
185                            articleElement.addAttribute("structure-uuid", structure.getUuid());
186    
187                            exportStructure(portletDataContext, structuresElement, structure);
188                    }
189    
190                    if (Validator.isNotNull(article.getTemplateId())) {
191                            JournalTemplate template = null;
192    
193                            try {
194                                    template = JournalTemplateLocalServiceUtil.getTemplate(
195                                            article.getGroupId(), article.getTemplateId());
196                            }
197                            catch (NoSuchTemplateException nste) {
198                                    template = JournalTemplateLocalServiceUtil.getTemplate(
199                                            companyGroup.getGroupId(), article.getTemplateId());
200                            }
201    
202                            articleElement.addAttribute("template-uuid", template.getUuid());
203    
204                            exportTemplate(
205                                    portletDataContext, templatesElement, dlFileEntryTypesElement,
206                                    dlFoldersElement, dlFileEntriesElement, dlFileRanksElement,
207                                    igFoldersElement, igImagesElement, template, checkDateRange);
208                    }
209    
210                    Image smallImage = ImageUtil.fetchByPrimaryKey(
211                            article.getSmallImageId());
212    
213                    if (article.isSmallImage() && (smallImage != null)) {
214                            String smallImagePath = getArticleSmallImagePath(
215                                    portletDataContext, article);
216    
217                            articleElement.addAttribute("small-image-path", smallImagePath);
218    
219                            article.setSmallImageType(smallImage.getType());
220    
221                            portletDataContext.addZipEntry(
222                                    smallImagePath, smallImage.getTextObj());
223                    }
224    
225                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "images")) {
226                            String imagePath = getArticleImagePath(portletDataContext, article);
227    
228                            articleElement.addAttribute("image-path", imagePath);
229    
230                            List<JournalArticleImage> articleImages =
231                                    JournalArticleImageUtil.findByG_A_V(
232                                            article.getGroupId(), article.getArticleId(),
233                                            article.getVersion());
234    
235                            for (JournalArticleImage articleImage : articleImages) {
236                                    Image image = null;
237    
238                                    try {
239                                            image = ImageUtil.findByPrimaryKey(
240                                                    articleImage.getArticleImageId());
241                                    }
242                                    catch (NoSuchImageException nsie) {
243                                            continue;
244                                    }
245    
246                                    String articleImagePath = getArticleImagePath(
247                                            portletDataContext, article, articleImage, image);
248    
249                                    if (!portletDataContext.isPathNotProcessed(articleImagePath)) {
250                                            continue;
251                                    }
252    
253                                    portletDataContext.addZipEntry(
254                                            articleImagePath, image.getTextObj());
255                            }
256                    }
257    
258                    article.setStatusByUserUuid(article.getStatusByUserUuid());
259    
260                    if (portletDataContext.getBooleanParameter(
261                                    _NAMESPACE, "embedded-assets")) {
262    
263                            String content = exportReferencedContent(
264                                    portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
265                                    dlFileEntriesElement, dlFileRanksElement, igFoldersElement,
266                                    igImagesElement, articleElement, article.getContent(),
267                                    checkDateRange);
268    
269                            article.setContent(content);
270                    }
271    
272                    portletDataContext.addClassedModel(
273                            articleElement, path, article, _NAMESPACE);
274            }
275    
276            public static String exportReferencedContent(
277                            PortletDataContext portletDataContext,
278                            Element dlFileEntryTypesElement, Element dlFoldersElement,
279                            Element dlFileEntriesElement, Element dlFileRanksElement,
280                            Element igFoldersElement, Element igImagesElement,
281                            Element entityElement, String content, boolean checkDateRange)
282                    throws Exception {
283    
284                    content = exportDLFileEntries(
285                            portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
286                            dlFileEntriesElement, dlFileRanksElement, entityElement, content,
287                            false);
288                    content = exportLayoutFriendlyURLs(portletDataContext, content);
289                    content = exportLinksToLayout(portletDataContext, content);
290    
291                    String entityElementName = entityElement.getName();
292    
293                    if (!entityElementName.equals("article")) {
294                            content = StringUtil.replace(
295                                    content, StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
296                    }
297    
298                    return content;
299            }
300    
301            public static String getArticlePath(
302                            PortletDataContext portletDataContext, JournalArticle article)
303                    throws Exception {
304    
305                    StringBundler sb = new StringBundler(8);
306    
307                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
308                    sb.append("/articles/");
309                    sb.append(article.getArticleResourceUuid());
310                    sb.append(StringPool.SLASH);
311                    sb.append(article.getVersion());
312                    sb.append(StringPool.SLASH);
313                    sb.append("article.xml");
314    
315                    return sb.toString();
316            }
317    
318            public static void importArticle(
319                            PortletDataContext portletDataContext, Element articleElement)
320                    throws Exception {
321    
322                    String path = articleElement.attributeValue("path");
323    
324                    if (!portletDataContext.isPathNotProcessed(path)) {
325                            return;
326                    }
327    
328                    JournalArticle article =
329                            (JournalArticle)portletDataContext.getZipEntryAsObject(path);
330    
331                    long userId = portletDataContext.getUserId(article.getUserUuid());
332    
333                    JournalCreationStrategy creationStrategy =
334                            JournalCreationStrategyFactory.getInstance();
335    
336                    long authorId = creationStrategy.getAuthorUserId(
337                            portletDataContext, article);
338    
339                    if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
340                            userId = authorId;
341                    }
342    
343                    User user = UserLocalServiceUtil.getUser(userId);
344    
345                    String articleId = article.getArticleId();
346                    boolean autoArticleId = false;
347    
348                    if ((Validator.isNumber(articleId)) ||
349                            (JournalArticleUtil.fetchByG_A_V(
350                                    portletDataContext.getScopeGroupId(), articleId,
351                                            JournalArticleConstants.VERSION_DEFAULT) != null)) {
352    
353                            autoArticleId = true;
354                    }
355    
356                    Map<String, String> articleIds =
357                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
358                                    JournalArticle.class + ".articleId");
359    
360                    String newArticleId = articleIds.get(articleId);
361    
362                    if (Validator.isNotNull(newArticleId)) {
363    
364                            // A sibling of a different version was already assigned a new
365                            // article id
366    
367                            articleId = newArticleId;
368                            autoArticleId = false;
369                    }
370    
371                    String content = article.getContent();
372    
373                    content = importDLFileEntries(
374                            portletDataContext, articleElement, content);
375    
376                    Group group = GroupLocalServiceUtil.getGroup(
377                            portletDataContext.getScopeGroupId());
378    
379                    content = StringUtil.replace(
380                            content, "@data_handler_group_friendly_url@",
381                            group.getFriendlyURL());
382    
383                    content = importLinksToLayout(portletDataContext, content);
384    
385                    article.setContent(content);
386    
387                    String newContent = creationStrategy.getTransformedContent(
388                            portletDataContext, article);
389    
390                    if (newContent != JournalCreationStrategy.ARTICLE_CONTENT_UNCHANGED) {
391                            article.setContent(newContent);
392                    }
393    
394                    Map<String, String> structureIds =
395                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
396                                    JournalStructure.class);
397    
398                    String parentStructureId = MapUtil.getString(
399                            structureIds, article.getStructureId(), article.getStructureId());
400    
401                    Map<String, String> templateIds =
402                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
403                                    JournalTemplate.class);
404    
405                    String parentTemplateId = MapUtil.getString(
406                            templateIds, article.getTemplateId(), article.getTemplateId());
407    
408                    Date displayDate = article.getDisplayDate();
409    
410                    int displayDateMonth = 0;
411                    int displayDateDay = 0;
412                    int displayDateYear = 0;
413                    int displayDateHour = 0;
414                    int displayDateMinute = 0;
415    
416                    if (displayDate != null) {
417                            Calendar displayCal = CalendarFactoryUtil.getCalendar(
418                                    user.getTimeZone());
419    
420                            displayCal.setTime(displayDate);
421    
422                            displayDateMonth = displayCal.get(Calendar.MONTH);
423                            displayDateDay = displayCal.get(Calendar.DATE);
424                            displayDateYear = displayCal.get(Calendar.YEAR);
425                            displayDateHour = displayCal.get(Calendar.HOUR);
426                            displayDateMinute = displayCal.get(Calendar.MINUTE);
427    
428                            if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
429                                    displayDateHour += 12;
430                            }
431                    }
432    
433                    Date expirationDate = article.getExpirationDate();
434    
435                    int expirationDateMonth = 0;
436                    int expirationDateDay = 0;
437                    int expirationDateYear = 0;
438                    int expirationDateHour = 0;
439                    int expirationDateMinute = 0;
440                    boolean neverExpire = true;
441    
442                    if (expirationDate != null) {
443                            Calendar expirationCal = CalendarFactoryUtil.getCalendar(
444                                    user.getTimeZone());
445    
446                            expirationCal.setTime(expirationDate);
447    
448                            expirationDateMonth = expirationCal.get(Calendar.MONTH);
449                            expirationDateDay = expirationCal.get(Calendar.DATE);
450                            expirationDateYear = expirationCal.get(Calendar.YEAR);
451                            expirationDateHour = expirationCal.get(Calendar.HOUR);
452                            expirationDateMinute = expirationCal.get(Calendar.MINUTE);
453                            neverExpire = false;
454    
455                            if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
456                                    expirationDateHour += 12;
457                            }
458                    }
459    
460                    Date reviewDate = article.getReviewDate();
461    
462                    int reviewDateMonth = 0;
463                    int reviewDateDay = 0;
464                    int reviewDateYear = 0;
465                    int reviewDateHour = 0;
466                    int reviewDateMinute = 0;
467                    boolean neverReview = true;
468    
469                    if (reviewDate != null) {
470                            Calendar reviewCal = CalendarFactoryUtil.getCalendar(
471                                    user.getTimeZone());
472    
473                            reviewCal.setTime(reviewDate);
474    
475                            reviewDateMonth = reviewCal.get(Calendar.MONTH);
476                            reviewDateDay = reviewCal.get(Calendar.DATE);
477                            reviewDateYear = reviewCal.get(Calendar.YEAR);
478                            reviewDateHour = reviewCal.get(Calendar.HOUR);
479                            reviewDateMinute = reviewCal.get(Calendar.MINUTE);
480                            neverReview = false;
481    
482                            if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
483                                    reviewDateHour += 12;
484                            }
485                    }
486    
487                    long structurePrimaryKey = 0;
488    
489                    if (Validator.isNotNull(article.getStructureId())) {
490                            String structureUuid = articleElement.attributeValue(
491                                    "structure-uuid");
492    
493                            JournalStructure existingStructure =
494                                    JournalStructureUtil.fetchByUUID_G(
495                                            structureUuid, portletDataContext.getScopeGroupId());
496    
497                            if (existingStructure == null) {
498                                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
499                                            portletDataContext.getCompanyId());
500    
501                                    long companyGroupId = companyGroup.getGroupId();
502    
503                                    existingStructure = JournalStructureUtil.fetchByUUID_G(
504                                            structureUuid, companyGroupId);
505                            }
506    
507                            if (existingStructure == null) {
508                                    String newStructureId = structureIds.get(
509                                            article.getStructureId());
510    
511                                    if (Validator.isNotNull(newStructureId)) {
512                                            existingStructure = JournalStructureUtil.fetchByG_S(
513                                                    portletDataContext.getScopeGroupId(),
514                                                    String.valueOf(newStructureId));
515                                    }
516    
517                                    if (existingStructure == null) {
518                                            if (_log.isWarnEnabled()) {
519                                                    StringBundler sb = new StringBundler();
520    
521                                                    sb.append("Structure ");
522                                                    sb.append(article.getStructureId());
523                                                    sb.append(" is missing for article ");
524                                                    sb.append(article.getArticleId());
525                                                    sb.append(", skipping this article.");
526    
527                                                    _log.warn(sb.toString());
528                                            }
529    
530                                            return;
531                                    }
532                            }
533    
534                            structurePrimaryKey = existingStructure.getPrimaryKey();
535    
536                            parentStructureId = existingStructure.getStructureId();
537                    }
538    
539                    if (Validator.isNotNull(article.getTemplateId())) {
540                            String templateUuid = articleElement.attributeValue(
541                                    "template-uuid");
542    
543                            JournalTemplate existingTemplate =
544                                    JournalTemplateUtil.fetchByUUID_G(
545                                            templateUuid, portletDataContext.getScopeGroupId());
546    
547                            if (existingTemplate == null) {
548                                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
549                                            portletDataContext.getCompanyId());
550    
551                                    long companyGroupId = companyGroup.getGroupId();
552    
553                                    existingTemplate = JournalTemplateUtil.fetchByUUID_G(
554                                            templateUuid, companyGroupId);
555                            }
556    
557                            if (existingTemplate == null) {
558                                    String newTemplateId = templateIds.get(article.getTemplateId());
559    
560                                    if (Validator.isNotNull(newTemplateId)) {
561                                            existingTemplate = JournalTemplateUtil.fetchByG_T(
562                                                    portletDataContext.getScopeGroupId(), newTemplateId);
563                                    }
564    
565                                    if (existingTemplate == null) {
566                                            if (_log.isWarnEnabled()) {
567                                                    StringBundler sb = new StringBundler();
568    
569                                                    sb.append("Template ");
570                                                    sb.append(article.getTemplateId());
571                                                    sb.append(" is missing for article ");
572                                                    sb.append(article.getArticleId());
573                                                    sb.append(", skipping this article.");
574    
575                                                    _log.warn(sb.toString());
576                                            }
577    
578                                            return;
579                                    }
580                            }
581    
582                            parentTemplateId = existingTemplate.getTemplateId();
583                    }
584    
585                    File smallFile = null;
586    
587                    String smallImagePath = articleElement.attributeValue(
588                            "small-image-path");
589    
590                    if (article.isSmallImage() && Validator.isNotNull(smallImagePath)) {
591                            byte[] bytes = portletDataContext.getZipEntryAsByteArray(
592                                    smallImagePath);
593    
594                            smallFile = File.createTempFile(
595                                    String.valueOf(article.getSmallImageId()),
596                                    StringPool.PERIOD + article.getSmallImageType());
597    
598                            FileUtil.write(smallFile, bytes);
599                    }
600    
601                    Map<String, byte[]> images = new HashMap<String, byte[]>();
602    
603                    String imagePath = articleElement.attributeValue("image-path");
604    
605                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "images") &&
606                            Validator.isNotNull(imagePath)) {
607    
608                            List<String> imageFiles = portletDataContext.getZipFolderEntries(
609                                    imagePath);
610    
611                            for (String imageFile : imageFiles) {
612                                    String fileName = imageFile;
613    
614                                    if (fileName.contains(StringPool.SLASH)) {
615                                            fileName = fileName.substring(
616                                                    fileName.lastIndexOf(CharPool.SLASH) + 1);
617                                    }
618    
619                                    if (fileName.endsWith(".xml")) {
620                                            continue;
621                                    }
622    
623                                    int pos = fileName.lastIndexOf(CharPool.PERIOD);
624    
625                                    if (pos != -1) {
626                                            fileName = fileName.substring(0, pos);
627                                    }
628    
629                                    images.put(fileName, portletDataContext.getZipEntryAsByteArray(
630                                            imageFile));
631                            }
632                    }
633    
634                    String articleURL = null;
635    
636                    boolean addGroupPermissions = creationStrategy.addGroupPermissions(
637                            portletDataContext, article);
638                    boolean addGuestPermissions = creationStrategy.addGuestPermissions(
639                            portletDataContext, article);
640    
641                    ServiceContext serviceContext = portletDataContext.createServiceContext(
642                            articleElement, article, _NAMESPACE);
643    
644                    serviceContext.setAddGroupPermissions(addGroupPermissions);
645                    serviceContext.setAddGuestPermissions(addGuestPermissions);
646                    serviceContext.setAttribute("imported", Boolean.TRUE.toString());
647    
648                    if (article.getStatus() != WorkflowConstants.STATUS_APPROVED) {
649                            serviceContext.setWorkflowAction(
650                                    WorkflowConstants.ACTION_SAVE_DRAFT);
651                    }
652    
653                    JournalArticle importedArticle = null;
654    
655                    String articleResourceUuid = articleElement.attributeValue(
656                            "article-resource-uuid");
657    
658                    if (portletDataContext.isDataStrategyMirror()) {
659                            JournalArticleResource articleResource =
660                                    JournalArticleResourceUtil.fetchByUUID_G(
661                                            articleResourceUuid, portletDataContext.getScopeGroupId());
662    
663                            if (articleResource == null) {
664                                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
665                                            portletDataContext.getCompanyId());
666    
667                                    long companyGroupId = companyGroup.getGroupId();
668    
669                                    articleResource = JournalArticleResourceUtil.fetchByUUID_G(
670                                            articleResourceUuid, companyGroupId);
671                            }
672    
673                            serviceContext.setUuid(articleResourceUuid);
674    
675                            JournalArticle existingArticle = null;
676    
677                            if (articleResource != null) {
678                                    try {
679                                            existingArticle =
680                                                    JournalArticleLocalServiceUtil.getLatestArticle(
681                                                            articleResource.getResourcePrimKey(),
682                                                            WorkflowConstants.STATUS_ANY, false);
683                                    }
684                                    catch (NoSuchArticleException nsae) {
685                                    }
686                            }
687    
688                            if (existingArticle == null) {
689                                    existingArticle = JournalArticleUtil.fetchByG_A_V(
690                                            portletDataContext.getScopeGroupId(), newArticleId,
691                                            article.getVersion());
692                            }
693    
694                            if (existingArticle == null) {
695                                    importedArticle = JournalArticleLocalServiceUtil.addArticle(
696                                            userId, portletDataContext.getScopeGroupId(),
697                                            article.getClassNameId(), structurePrimaryKey, articleId,
698                                            autoArticleId, article.getVersion(), article.getTitleMap(),
699                                            article.getDescriptionMap(), article.getContent(),
700                                            article.getType(), parentStructureId, parentTemplateId,
701                                            article.getLayoutUuid(), displayDateMonth, displayDateDay,
702                                            displayDateYear, displayDateHour, displayDateMinute,
703                                            expirationDateMonth, expirationDateDay, expirationDateYear,
704                                            expirationDateHour, expirationDateMinute, neverExpire,
705                                            reviewDateMonth, reviewDateDay, reviewDateYear,
706                                            reviewDateHour, reviewDateMinute, neverReview,
707                                            article.isIndexable(), article.isSmallImage(),
708                                            article.getSmallImageURL(), smallFile, images, articleURL,
709                                            serviceContext);
710                            }
711                            else {
712                                    importedArticle = JournalArticleLocalServiceUtil.updateArticle(
713                                            userId, existingArticle.getGroupId(),
714                                            existingArticle.getArticleId(),
715                                            existingArticle.getVersion(), article.getTitleMap(),
716                                            article.getDescriptionMap(), article.getContent(),
717                                            article.getType(), parentStructureId, parentTemplateId,
718                                            existingArticle.getLayoutUuid(), displayDateMonth,
719                                            displayDateDay, displayDateYear, displayDateHour,
720                                            displayDateMinute, expirationDateMonth, expirationDateDay,
721                                            expirationDateYear, expirationDateHour,
722                                            expirationDateMinute, neverExpire, reviewDateMonth,
723                                            reviewDateDay, reviewDateYear, reviewDateHour,
724                                            reviewDateMinute, neverReview, article.isIndexable(),
725                                            article.isSmallImage(), article.getSmallImageURL(),
726                                            smallFile, images, articleURL, serviceContext);
727                            }
728                    }
729                    else {
730                            importedArticle = JournalArticleLocalServiceUtil.addArticle(
731                                    userId, portletDataContext.getScopeGroupId(),
732                                    article.getClassNameId(), structurePrimaryKey, articleId,
733                                    autoArticleId, article.getVersion(), article.getTitleMap(),
734                                    article.getDescriptionMap(), article.getContent(),
735                                    article.getType(), parentStructureId, parentTemplateId,
736                                    article.getLayoutUuid(), displayDateMonth, displayDateDay,
737                                    displayDateYear, displayDateHour, displayDateMinute,
738                                    expirationDateMonth, expirationDateDay, expirationDateYear,
739                                    expirationDateHour, expirationDateMinute, neverExpire,
740                                    reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
741                                    reviewDateMinute, neverReview, article.isIndexable(),
742                                    article.isSmallImage(), article.getSmallImageURL(), smallFile,
743                                    images, articleURL, serviceContext);
744                    }
745    
746                    if (smallFile != null) {
747                            smallFile.delete();
748                    }
749    
750                    portletDataContext.importClassedModel(
751                            article, importedArticle, _NAMESPACE);
752    
753                    if (Validator.isNull(newArticleId)) {
754                            articleIds.put(
755                                    article.getArticleId(), importedArticle.getArticleId());
756                    }
757    
758                    articleElement.addAttribute(
759                            "imported-article-group-id",
760                            String.valueOf(importedArticle.getGroupId()));
761    
762                    if (!articleId.equals(importedArticle.getArticleId())) {
763                            if (_log.isWarnEnabled()) {
764                                    _log.warn(
765                                            "An article with the ID " + articleId + " already " +
766                                                    "exists. The new generated ID is " +
767                                                            importedArticle.getArticleId());
768                            }
769                    }
770            }
771    
772            public static void importFeed(
773                            PortletDataContext portletDataContext, Element feedElement)
774                    throws Exception {
775    
776                    String path = feedElement.attributeValue("path");
777    
778                    if (!portletDataContext.isPathNotProcessed(path)) {
779                            return;
780                    }
781    
782                    JournalFeed feed = (JournalFeed)portletDataContext.getZipEntryAsObject(
783                            path);
784    
785                    long userId = portletDataContext.getUserId(feed.getUserUuid());
786    
787                    JournalCreationStrategy creationStrategy =
788                            JournalCreationStrategyFactory.getInstance();
789    
790                    long authorId = creationStrategy.getAuthorUserId(
791                            portletDataContext, feed);
792    
793                    if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
794                            userId = authorId;
795                    }
796    
797                    Group group = GroupLocalServiceUtil.getGroup(
798                            portletDataContext.getScopeGroupId());
799    
800                    String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
801    
802                    String[] friendlyUrlParts = StringUtil.split(
803                            feed.getTargetLayoutFriendlyUrl(), '/');
804    
805                    String oldGroupFriendlyURL = friendlyUrlParts[2];
806    
807                    if (oldGroupFriendlyURL.equals("@data_handler_group_friendly_url@")) {
808                            feed.setTargetLayoutFriendlyUrl(
809                                    StringUtil.replace(
810                                            feed.getTargetLayoutFriendlyUrl(),
811                                            "@data_handler_group_friendly_url@",
812                                            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            protected static String exportDLFileEntries(
1300                            PortletDataContext portletDataContext,
1301                            Element dlFileEntryTypesElement, Element dlFoldersElement,
1302                            Element dlFileEntriesElement, Element dlFileRanksElement,
1303                            Element entityElement, String content, boolean checkDateRange)
1304                    throws Exception {
1305    
1306                    Group group = GroupLocalServiceUtil.getGroup(
1307                            portletDataContext.getGroupId());
1308    
1309                    if (group.isStagingGroup()) {
1310                            group = group.getLiveGroup();
1311                    }
1312    
1313                    if (group.isStaged() && !group.isStagedRemotely() &&
1314                            !group.isStagedPortlet(PortletKeys.DOCUMENT_LIBRARY)) {
1315    
1316                            return content;
1317                    }
1318    
1319                    StringBuilder sb = new StringBuilder(content);
1320    
1321                    int beginPos = content.length();
1322                    int currentLocation = -1;
1323    
1324                    while (true) {
1325                            currentLocation = content.lastIndexOf(
1326                                    "/c/document_library/get_file?", beginPos);
1327    
1328                            if (currentLocation == -1) {
1329                                    currentLocation = content.lastIndexOf("/documents/", beginPos);
1330                            }
1331    
1332                            if (currentLocation == -1) {
1333                                    return sb.toString();
1334                            }
1335    
1336                            beginPos = currentLocation;
1337    
1338                            int endPos1 = content.indexOf(CharPool.APOSTROPHE, beginPos);
1339                            int endPos2 = content.indexOf(CharPool.CLOSE_BRACKET, beginPos);
1340                            int endPos3 = content.indexOf(CharPool.CLOSE_PARENTHESIS, beginPos);
1341                            int endPos4 = content.indexOf(CharPool.LESS_THAN, beginPos);
1342                            int endPos5 = content.indexOf(CharPool.QUOTE, beginPos);
1343                            int endPos6 = content.indexOf(CharPool.SPACE, beginPos);
1344    
1345                            int endPos = endPos1;
1346    
1347                            if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
1348                                    endPos = endPos2;
1349                            }
1350    
1351                            if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
1352                                    endPos = endPos3;
1353                            }
1354    
1355                            if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
1356                                    endPos = endPos4;
1357                            }
1358    
1359                            if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
1360                                    endPos = endPos5;
1361                            }
1362    
1363                            if ((endPos == -1) || ((endPos6 != -1) && (endPos6 < endPos))) {
1364                                    endPos = endPos6;
1365                            }
1366    
1367                            if ((beginPos == -1) || (endPos == -1)) {
1368                                    break;
1369                            }
1370    
1371                            try {
1372                                    String oldParameters = content.substring(beginPos, endPos);
1373    
1374                                    while (oldParameters.contains(StringPool.AMPERSAND_ENCODED)) {
1375                                            oldParameters = oldParameters.replace(
1376                                                    StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
1377                                    }
1378    
1379                                    Map<String, String[]> map = new HashMap<String, String[]>();
1380    
1381                                    if (oldParameters.startsWith("/documents/")) {
1382                                            String[] pathArray = oldParameters.split(StringPool.SLASH);
1383    
1384                                            map.put("groupId", new String[] {pathArray[2]});
1385    
1386                                            if (pathArray.length == 4) {
1387                                                    map.put("uuid", new String[] {pathArray[3]});
1388                                            }
1389                                            else if (pathArray.length > 4) {
1390                                                    map.put("folderId", new String[] {pathArray[3]});
1391    
1392                                                    String name = HttpUtil.decodeURL(pathArray[4]);
1393    
1394                                                    int pos = name.indexOf(StringPool.QUESTION);
1395    
1396                                                    if (pos != -1) {
1397                                                            name = name.substring(0, pos);
1398                                                    }
1399    
1400                                                    map.put("name", new String[] {name});
1401                                            }
1402                                    }
1403                                    else {
1404                                            oldParameters = oldParameters.substring(
1405                                                    oldParameters.indexOf(CharPool.QUESTION) + 1);
1406    
1407                                            map = HttpUtil.parameterMapFromString(oldParameters);
1408                                    }
1409    
1410                                    FileEntry fileEntry = null;
1411    
1412                                    String uuid = MapUtil.getString(map, "uuid");
1413    
1414                                    if (Validator.isNotNull(uuid)) {
1415                                            String groupIdString = MapUtil.getString(map, "groupId");
1416    
1417                                            long groupId = GetterUtil.getLong(groupIdString);
1418    
1419                                            if (groupIdString.equals("@group_id@")) {
1420                                                    groupId = portletDataContext.getScopeGroupId();
1421                                            }
1422    
1423                                            fileEntry =
1424                                                    DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1425                                                            uuid, groupId);
1426                                    }
1427                                    else {
1428                                            String folderIdString = MapUtil.getString(map, "folderId");
1429    
1430                                            if (Validator.isNotNull(folderIdString)) {
1431                                                    long folderId = GetterUtil.getLong(folderIdString);
1432                                                    String name = MapUtil.getString(map, "name");
1433    
1434                                                    String groupIdString = MapUtil.getString(
1435                                                            map, "groupId");
1436    
1437                                                    long groupId = GetterUtil.getLong(groupIdString);
1438    
1439                                                    if (groupIdString.equals("@group_id@")) {
1440                                                            groupId = portletDataContext.getScopeGroupId();
1441                                                    }
1442    
1443                                                    fileEntry = DLAppLocalServiceUtil.getFileEntry(
1444                                                            groupId, folderId, name);
1445                                            }
1446                                    }
1447    
1448                                    if (fileEntry == null) {
1449                                            beginPos--;
1450    
1451                                            continue;
1452                                    }
1453    
1454                                    String path = DLPortletDataHandlerImpl.getFileEntryPath(
1455                                            portletDataContext, fileEntry);
1456    
1457                                    Element dlReferenceElement = entityElement.addElement(
1458                                            "dl-reference");
1459    
1460                                    dlReferenceElement.addAttribute("path", path);
1461    
1462                                    DLPortletDataHandlerImpl.exportFileEntry(
1463                                            portletDataContext, dlFileEntryTypesElement,
1464                                            dlFoldersElement, dlFileEntriesElement, dlFileRanksElement,
1465                                            fileEntry, checkDateRange);
1466    
1467                                    String dlReference = "[$dl-reference=" + path + "$]";
1468    
1469                                    sb.replace(beginPos, endPos, dlReference);
1470                            }
1471                            catch (Exception e) {
1472                                    if (_log.isWarnEnabled()) {
1473                                            _log.warn(e);
1474                                    }
1475                            }
1476    
1477                            beginPos--;
1478                    }
1479    
1480                    return sb.toString();
1481            }
1482    
1483            protected static void exportFeed(
1484                            PortletDataContext portletDataContext, Element feedsElement,
1485                            JournalFeed feed)
1486                    throws Exception {
1487    
1488                    if (!portletDataContext.isWithinDateRange(feed.getModifiedDate())) {
1489                            return;
1490                    }
1491    
1492                    String path = getFeedPath(portletDataContext, feed);
1493    
1494                    if (!portletDataContext.isPathNotProcessed(path)) {
1495                            return;
1496                    }
1497    
1498                    feed = (JournalFeed)feed.clone();
1499    
1500                    Element feedElement = feedsElement.addElement("feed");
1501    
1502                    Group group = GroupLocalServiceUtil.getGroup(
1503                            portletDataContext.getScopeGroupId());
1504    
1505                    String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
1506    
1507                    String[] friendlyUrlParts = StringUtil.split(
1508                            feed.getTargetLayoutFriendlyUrl(), '/');
1509    
1510                    String oldGroupFriendlyURL = friendlyUrlParts[2];
1511    
1512                    if (newGroupFriendlyURL.equals(oldGroupFriendlyURL)) {
1513                            String targetLayoutFriendlyUrl = StringUtil.replaceFirst(
1514                                    feed.getTargetLayoutFriendlyUrl(),
1515                                    StringPool.SLASH + newGroupFriendlyURL + StringPool.SLASH,
1516                                    "/@data_handler_group_friendly_url@/");
1517    
1518                            feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
1519                    }
1520    
1521                    portletDataContext.addClassedModel(feedElement, path, feed, _NAMESPACE);
1522            }
1523    
1524            protected static String exportLayoutFriendlyURLs(
1525                    PortletDataContext portletDataContext, String content) {
1526    
1527                    Group group = null;
1528    
1529                    try {
1530                            group = GroupLocalServiceUtil.getGroup(
1531                                    portletDataContext.getScopeGroupId());
1532                    }
1533                    catch (Exception e) {
1534                            if (_log.isWarnEnabled()) {
1535                                    _log.warn(e);
1536                            }
1537    
1538                            return content;
1539                    }
1540    
1541                    StringBuilder sb = new StringBuilder(content);
1542    
1543                    String friendlyURLPrivateGroupPath =
1544                            PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
1545                    String friendlyURLPrivateUserPath =
1546                            PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
1547                    String friendlyURLPublicPath =
1548                            PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
1549    
1550                    String href = "href=";
1551    
1552                    int beginPos = content.length();
1553    
1554                    while (true) {
1555                            int hrefLength = href.length();
1556    
1557                            beginPos = content.lastIndexOf(href, beginPos);
1558    
1559                            if (beginPos == -1) {
1560                                    break;
1561                            }
1562    
1563                            char c = content.charAt(beginPos + hrefLength);
1564    
1565                            if ((c == CharPool.APOSTROPHE) || (c == CharPool.QUOTE)) {
1566                                    hrefLength++;
1567                            }
1568    
1569                            int endPos1 = content.indexOf(
1570                                    CharPool.APOSTROPHE, beginPos + hrefLength);
1571                            int endPos2 = content.indexOf(
1572                                    CharPool.CLOSE_BRACKET, beginPos + hrefLength);
1573                            int endPos3 = content.indexOf(
1574                                    CharPool.CLOSE_PARENTHESIS, beginPos + hrefLength);
1575                            int endPos4 = content.indexOf(
1576                                    CharPool.LESS_THAN, beginPos + hrefLength);
1577                            int endPos5 = content.indexOf(
1578                                    CharPool.QUOTE, beginPos + hrefLength);
1579                            int endPos6 = content.indexOf(
1580                                    CharPool.SPACE, beginPos + hrefLength);
1581    
1582                            int endPos = endPos1;
1583    
1584                            if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
1585                                    endPos = endPos2;
1586                            }
1587    
1588                            if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
1589                                    endPos = endPos3;
1590                            }
1591    
1592                            if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
1593                                    endPos = endPos4;
1594                            }
1595    
1596                            if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
1597                                    endPos = endPos5;
1598                            }
1599    
1600                            if ((endPos == -1) || ((endPos6 != -1) && (endPos6 < endPos))) {
1601                                    endPos = endPos6;
1602                            }
1603    
1604                            if (endPos == -1) {
1605                                    beginPos--;
1606    
1607                                    continue;
1608                            }
1609    
1610                            String url = content.substring(beginPos + hrefLength, endPos);
1611    
1612                            if (!url.startsWith(friendlyURLPrivateGroupPath) &&
1613                                    !url.startsWith(friendlyURLPrivateUserPath) &&
1614                                    !url.startsWith(friendlyURLPublicPath)) {
1615    
1616                                    beginPos--;
1617    
1618                                    continue;
1619                            }
1620    
1621                            int beginGroupPos = content.indexOf(
1622                                    CharPool.SLASH, beginPos + hrefLength + 1);
1623    
1624                            if (beginGroupPos == -1) {
1625                                    beginPos--;
1626    
1627                                    continue;
1628                            }
1629    
1630                            int endGroupPos = content.indexOf(
1631                                    CharPool.SLASH, beginGroupPos + 1);
1632    
1633                            if (endGroupPos == -1) {
1634                                    beginPos--;
1635    
1636                                    continue;
1637                            }
1638    
1639                            String groupFriendlyURL = content.substring(
1640                                    beginGroupPos, endGroupPos);
1641    
1642                            if (groupFriendlyURL.equals(group.getFriendlyURL())) {
1643                                    sb.replace(
1644                                            beginGroupPos, endGroupPos,
1645                                            "@data_handler_group_friendly_url@");
1646                            }
1647    
1648                            beginPos--;
1649                    }
1650    
1651                    return sb.toString();
1652            }
1653    
1654            protected static String exportLinksToLayout(
1655                            PortletDataContext portletDataContext, String content)
1656                    throws Exception {
1657    
1658                    List<String> oldLinksToLayout = new ArrayList<String>();
1659                    List<String> newLinksToLayout = new ArrayList<String>();
1660    
1661                    Matcher matcher = _exportLinksToLayoutPattern.matcher(content);
1662    
1663                    while (matcher.find()) {
1664                            long layoutId = GetterUtil.getLong(matcher.group(1));
1665    
1666                            String type = matcher.group(2);
1667    
1668                            boolean privateLayout = type.startsWith("private");
1669    
1670                            try {
1671                                    Layout layout = LayoutLocalServiceUtil.getLayout(
1672                                            portletDataContext.getScopeGroupId(), privateLayout,
1673                                            layoutId);
1674    
1675                                    String oldLinkToLayout = matcher.group(0);
1676    
1677                                    StringBundler sb = new StringBundler(5);
1678    
1679                                    sb.append(type);
1680                                    sb.append(StringPool.AT);
1681                                    sb.append(layout.getUuid());
1682                                    sb.append(StringPool.AT);
1683                                    sb.append(layout.getFriendlyURL());
1684    
1685                                    String newLinkToLayout = StringUtil.replace(
1686                                            oldLinkToLayout, type, sb.toString());
1687    
1688                                    oldLinksToLayout.add(oldLinkToLayout);
1689                                    newLinksToLayout.add(newLinkToLayout);
1690                            }
1691                            catch (Exception e) {
1692                                    if (_log.isWarnEnabled()) {
1693                                            _log.warn(
1694                                                    "Unable to get layout with id " + layoutId +
1695                                                            " in group " + portletDataContext.getScopeGroupId(),
1696                                                    e);
1697                                    }
1698                            }
1699                    }
1700    
1701                    content = StringUtil.replace(
1702                            content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
1703                            ArrayUtil.toStringArray(newLinksToLayout.toArray()));
1704    
1705                    return content;
1706            }
1707    
1708            protected static void exportStructure(
1709                            PortletDataContext portletDataContext, Element structuresElement,
1710                            JournalStructure structure)
1711                    throws Exception {
1712    
1713                    String path = getStructurePath(portletDataContext, structure);
1714    
1715                    if (!portletDataContext.isPathNotProcessed(path)) {
1716                            return;
1717                    }
1718    
1719                    Element structureElement = structuresElement.addElement("structure");
1720    
1721                    String parentStructureId = structure.getParentStructureId();
1722    
1723                    if (Validator.isNotNull(parentStructureId)) {
1724                            try {
1725                                    JournalStructure parentStructure =
1726                                            JournalStructureLocalServiceUtil.getStructure(
1727                                                    structure.getGroupId(), parentStructureId);
1728    
1729                                    structureElement.addAttribute(
1730                                            "parent-structure-uuid", parentStructure.getUuid());
1731    
1732                                    exportStructure(
1733                                            portletDataContext, structuresElement, parentStructure);
1734                            }
1735                            catch (NoSuchStructureException nsse) {
1736                            }
1737                    }
1738    
1739                    portletDataContext.addClassedModel(
1740                            structureElement, path, structure, _NAMESPACE);
1741            }
1742    
1743            protected static void exportTemplate(
1744                            PortletDataContext portletDataContext, Element templatesElement,
1745                            Element dlFileEntryTypesElement, Element dlFoldersElement,
1746                            Element dlFileEntriesElement, Element dlFileRanksElement,
1747                            Element igFoldersElement, Element igImagesElement,
1748                            JournalTemplate template, boolean checkDateRange)
1749                    throws Exception {
1750    
1751                    String path = getTemplatePath(portletDataContext, template);
1752    
1753                    if (!portletDataContext.isPathNotProcessed(path)) {
1754                            return;
1755                    }
1756    
1757                    // Clone this template to make sure changes to its content are never
1758                    // persisted
1759    
1760                    template = (JournalTemplate)template.clone();
1761    
1762                    Element templateElement = templatesElement.addElement("template");
1763    
1764                    if (template.isSmallImage()) {
1765                            String smallImagePath = getTemplateSmallImagePath(
1766                                    portletDataContext, template);
1767    
1768                            templateElement.addAttribute("small-image-path", smallImagePath);
1769    
1770                            Image smallImage = ImageUtil.fetchByPrimaryKey(
1771                                    template.getSmallImageId());
1772    
1773                            template.setSmallImageType(smallImage.getType());
1774    
1775                            portletDataContext.addZipEntry(
1776                                    smallImagePath, smallImage.getTextObj());
1777                    }
1778    
1779                    if (portletDataContext.getBooleanParameter(
1780                                    _NAMESPACE, "embedded-assets")) {
1781    
1782                            String content = exportReferencedContent(
1783                                    portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
1784                                    dlFileEntriesElement, dlFileRanksElement, igFoldersElement,
1785                                    igImagesElement, templateElement, template.getXsl(),
1786                                    checkDateRange);
1787    
1788                            template.setXsl(content);
1789                    }
1790    
1791                    portletDataContext.addClassedModel(
1792                            templateElement, path, template, _NAMESPACE);
1793            }
1794    
1795            protected static String getArticleImagePath(
1796                            PortletDataContext portletDataContext, JournalArticle article)
1797                    throws Exception {
1798    
1799                    StringBundler sb = new StringBundler(6);
1800    
1801                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1802                    sb.append("/articles/");
1803                    sb.append(article.getArticleResourceUuid());
1804                    sb.append(StringPool.SLASH);
1805                    sb.append(article.getVersion());
1806                    sb.append(StringPool.SLASH);
1807    
1808                    return sb.toString();
1809            }
1810    
1811            protected static String getArticleImagePath(
1812                            PortletDataContext portletDataContext, JournalArticle article,
1813                            JournalArticleImage articleImage, Image image)
1814                    throws Exception {
1815    
1816                    StringBundler sb = new StringBundler(13);
1817    
1818                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1819                    sb.append("/articles/");
1820                    sb.append(article.getArticleResourceUuid());
1821                    sb.append(StringPool.SLASH);
1822                    sb.append(article.getVersion());
1823                    sb.append(StringPool.SLASH);
1824                    sb.append(articleImage.getElInstanceId());
1825                    sb.append(StringPool.UNDERLINE);
1826                    sb.append(articleImage.getElName());
1827    
1828                    if (Validator.isNotNull(articleImage.getLanguageId())) {
1829                            sb.append(StringPool.UNDERLINE);
1830                            sb.append(articleImage.getLanguageId());
1831                    }
1832    
1833                    sb.append(StringPool.PERIOD);
1834                    sb.append(image.getType());
1835    
1836                    return sb.toString();
1837            }
1838    
1839            protected static String getArticleSmallImagePath(
1840                            PortletDataContext portletDataContext, JournalArticle article)
1841                    throws Exception {
1842    
1843                    StringBundler sb = new StringBundler(6);
1844    
1845                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1846                    sb.append("/articles/");
1847                    sb.append(article.getArticleResourceUuid());
1848                    sb.append("/thumbnail");
1849                    sb.append(StringPool.PERIOD);
1850                    sb.append(article.getSmallImageType());
1851    
1852                    return sb.toString();
1853            }
1854    
1855            protected static String getFeedPath(
1856                    PortletDataContext portletDataContext, JournalFeed feed) {
1857    
1858                    StringBundler sb = new StringBundler(4);
1859    
1860                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1861                    sb.append("/feeds/");
1862                    sb.append(feed.getUuid());
1863                    sb.append(".xml");
1864    
1865                    return sb.toString();
1866            }
1867    
1868            protected static String getStructurePath(
1869                    PortletDataContext portletDataContext, JournalStructure structure) {
1870    
1871                    StringBundler sb = new StringBundler(4);
1872    
1873                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1874                    sb.append("/structures/");
1875                    sb.append(structure.getUuid());
1876                    sb.append(".xml");
1877    
1878                    return sb.toString();
1879            }
1880    
1881            protected static String getTemplatePath(
1882                    PortletDataContext portletDataContext, JournalTemplate template) {
1883    
1884                    StringBundler sb = new StringBundler(4);
1885    
1886                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1887                    sb.append("/templates/");
1888                    sb.append(template.getUuid());
1889                    sb.append(".xml");
1890    
1891                    return sb.toString();
1892            }
1893    
1894            protected static String getTemplateSmallImagePath(
1895                            PortletDataContext portletDataContext, JournalTemplate template)
1896                    throws Exception {
1897    
1898                    StringBundler sb = new StringBundler(5);
1899    
1900                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1901                    sb.append("/templates/thumbnail-");
1902                    sb.append(template.getUuid());
1903                    sb.append(StringPool.PERIOD);
1904                    sb.append(template.getSmallImageType());
1905    
1906                    return sb.toString();
1907            }
1908    
1909            protected static String importDLFileEntries(
1910                            PortletDataContext portletDataContext, Element parentElement,
1911                            String content)
1912                    throws Exception {
1913    
1914                    List<Element> dlReferenceElements = parentElement.elements(
1915                            "dl-reference");
1916    
1917                    for (Element dlReferenceElement : dlReferenceElements) {
1918                            String dlReferencePath = dlReferenceElement.attributeValue("path");
1919    
1920                            FileEntry fileEntry = null;
1921    
1922                            try {
1923                                    fileEntry = (FileEntry)portletDataContext.getZipEntryAsObject(
1924                                            dlReferencePath);
1925                            }
1926                            catch (Exception e) {
1927                                    if (_log.isWarnEnabled()) {
1928                                            _log.warn(e);
1929                                    }
1930                            }
1931    
1932                            if (fileEntry == null) {
1933                                    continue;
1934                            }
1935    
1936                            fileEntry = FileEntryUtil.fetchByUUID_R(
1937                                    fileEntry.getUuid(), portletDataContext.getGroupId());
1938    
1939                            if (fileEntry == null) {
1940                                    continue;
1941                            }
1942    
1943                            String dlReference = "[$dl-reference=" + dlReferencePath + "$]";
1944    
1945                            StringBundler sb = new StringBundler(6);
1946    
1947                            sb.append("/documents/");
1948                            sb.append(portletDataContext.getScopeGroupId());
1949                            sb.append(StringPool.SLASH);
1950                            sb.append(fileEntry.getFolderId());
1951                            sb.append(StringPool.SLASH);
1952                            sb.append(
1953                                    HttpUtil.encodeURL(
1954                                            HtmlUtil.unescape(fileEntry.getTitle()), true));
1955    
1956                            content = StringUtil.replace(content, dlReference, sb.toString());
1957                    }
1958    
1959                    return content;
1960            }
1961    
1962            protected static String importLinksToLayout(
1963                            PortletDataContext portletDataContext, String content)
1964                    throws Exception {
1965    
1966                    List<String> oldLinksToLayout = new ArrayList<String>();
1967                    List<String> newLinksToLayout = new ArrayList<String>();
1968    
1969                    Matcher matcher = _importLinksToLayoutPattern.matcher(content);
1970    
1971                    while (matcher.find()) {
1972                            long oldLayoutId = GetterUtil.getLong(matcher.group(1));
1973    
1974                            long newLayoutId = oldLayoutId;
1975    
1976                            String type = matcher.group(2);
1977    
1978                            boolean privateLayout = type.startsWith("private");
1979    
1980                            String layoutUuid = matcher.group(3);
1981    
1982                            String friendlyURL = matcher.group(4);
1983    
1984                            try {
1985                                    Layout layout = LayoutUtil.fetchByUUID_G(
1986                                            layoutUuid, portletDataContext.getScopeGroupId());
1987    
1988                                    if (layout == null) {
1989                                            layout = LayoutUtil.fetchByG_P_F(
1990                                                    portletDataContext.getScopeGroupId(), privateLayout,
1991                                                    friendlyURL);
1992                                    }
1993    
1994                                    if (layout == null) {
1995                                            layout = LayoutUtil.fetchByG_P_L(
1996                                                    portletDataContext.getScopeGroupId(), privateLayout,
1997                                                    oldLayoutId);
1998                                    }
1999    
2000                                    if (layout == null) {
2001                                            if (_log.isWarnEnabled()) {
2002                                                    StringBundler sb = new StringBundler(9);
2003    
2004                                                    sb.append("Unable to get layout with UUID ");
2005                                                    sb.append(layoutUuid);
2006                                                    sb.append(", friendly URL ");
2007                                                    sb.append(friendlyURL);
2008                                                    sb.append(", or ");
2009                                                    sb.append("layoutId ");
2010                                                    sb.append(oldLayoutId);
2011                                                    sb.append(" in group ");
2012                                                    sb.append(portletDataContext.getScopeGroupId());
2013    
2014                                                    _log.warn(sb.toString());
2015                                            }
2016                                    }
2017                                    else {
2018                                            newLayoutId = layout.getLayoutId();
2019                                    }
2020                            }
2021                            catch (SystemException e) {
2022                                    if (_log.isWarnEnabled()) {
2023                                            _log.warn(
2024                                                    "Unable to get layout in group " +
2025                                                            portletDataContext.getScopeGroupId(), e);
2026                                    }
2027                            }
2028    
2029                            String oldLinkToLayout = matcher.group(0);
2030    
2031                            StringBundler sb = new StringBundler(4);
2032    
2033                            sb.append(StringPool.AT);
2034                            sb.append(layoutUuid);
2035                            sb.append(StringPool.AT);
2036                            sb.append(friendlyURL);
2037    
2038                            String newLinkToLayout = StringUtil.replace(
2039                                    oldLinkToLayout,
2040                                    new String[] {sb.toString(), String.valueOf(oldLayoutId)},
2041                                    new String[] {StringPool.BLANK, String.valueOf(newLayoutId)});
2042    
2043                            oldLinksToLayout.add(oldLinkToLayout);
2044                            newLinksToLayout.add(newLinkToLayout);
2045                    }
2046    
2047                    content = StringUtil.replace(
2048                            content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
2049                            ArrayUtil.toStringArray(newLinksToLayout.toArray()));
2050    
2051                    return content;
2052            }
2053    
2054            @Override
2055            public PortletDataHandlerControl[] getExportControls() {
2056                    return new PortletDataHandlerControl[] {
2057                            _articles, _structuresTemplatesAndFeeds, _embeddedAssets, _images,
2058                            _categories, _comments, _ratings, _tags
2059                    };
2060            }
2061    
2062            @Override
2063            public PortletDataHandlerControl[] getImportControls() {
2064                    return new PortletDataHandlerControl[] {
2065                            _articles, _structuresTemplatesAndFeeds, _images, _categories,
2066                            _comments, _ratings, _tags
2067                    };
2068            }
2069    
2070            @Override
2071            public boolean isAlwaysExportable() {
2072                    return _ALWAYS_EXPORTABLE;
2073            }
2074    
2075            @Override
2076            public boolean isPublishToLiveByDefault() {
2077                    return PropsValues.JOURNAL_PUBLISH_TO_LIVE_BY_DEFAULT;
2078            }
2079    
2080            @Override
2081            protected PortletPreferences doDeleteData(
2082                            PortletDataContext portletDataContext, String portletId,
2083                            PortletPreferences portletPreferences)
2084                    throws Exception {
2085    
2086                    if (!portletDataContext.addPrimaryKey(
2087                                    JournalPortletDataHandlerImpl.class, "deleteData")) {
2088    
2089                            JournalArticleLocalServiceUtil.deleteArticles(
2090                                    portletDataContext.getScopeGroupId());
2091    
2092                            JournalTemplateLocalServiceUtil.deleteTemplates(
2093                                    portletDataContext.getScopeGroupId());
2094    
2095                            JournalStructureLocalServiceUtil.deleteStructures(
2096                                    portletDataContext.getScopeGroupId());
2097                    }
2098    
2099                    return portletPreferences;
2100            }
2101    
2102            @Override
2103            protected String doExportData(
2104                            PortletDataContext portletDataContext, String portletId,
2105                            PortletPreferences portletPreferences)
2106                    throws Exception {
2107    
2108                    portletDataContext.addPermissions(
2109                            "com.liferay.portlet.journal",
2110                            portletDataContext.getScopeGroupId());
2111    
2112                    Document document = SAXReaderUtil.createDocument();
2113    
2114                    Element rootElement = document.addElement("journal-data");
2115    
2116                    rootElement.addAttribute(
2117                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
2118    
2119                    Element structuresElement = rootElement.addElement("structures");
2120    
2121                    List<JournalStructure> structures = JournalStructureUtil.findByGroupId(
2122                            portletDataContext.getScopeGroupId(), QueryUtil.ALL_POS,
2123                            QueryUtil.ALL_POS, new StructurePKComparator(true));
2124    
2125                    for (JournalStructure structure : structures) {
2126                            if (portletDataContext.isWithinDateRange(
2127                                            structure.getModifiedDate())) {
2128    
2129                                    exportStructure(
2130                                            portletDataContext, structuresElement, structure);
2131                            }
2132                    }
2133    
2134                    Element templatesElement = rootElement.addElement("templates");
2135                    Element dlFileEntryTypesElement = rootElement.addElement(
2136                            "dl-file-entry-types");
2137                    Element dlFoldersElement = rootElement.addElement("dl-folders");
2138                    Element dlFilesElement = rootElement.addElement("dl-file-entries");
2139                    Element dlFileRanksElement = rootElement.addElement("dl-file-ranks");
2140                    Element igFoldersElement = rootElement.addElement("ig-folders");
2141                    Element igImagesElement = rootElement.addElement("ig-images");
2142    
2143                    List<JournalTemplate> templates = JournalTemplateUtil.findByGroupId(
2144                            portletDataContext.getScopeGroupId());
2145    
2146                    for (JournalTemplate template : templates) {
2147                            if (portletDataContext.isWithinDateRange(
2148                                            template.getModifiedDate())) {
2149    
2150                                    exportTemplate(
2151                                            portletDataContext, templatesElement,
2152                                            dlFileEntryTypesElement, dlFoldersElement, dlFilesElement,
2153                                            dlFileRanksElement, igFoldersElement, igImagesElement,
2154                                            template, true);
2155                            }
2156                    }
2157    
2158                    Element feedsElement = rootElement.addElement("feeds");
2159    
2160                    List<JournalFeed> feeds = JournalFeedUtil.findByGroupId(
2161                            portletDataContext.getScopeGroupId());
2162    
2163                    for (JournalFeed feed : feeds) {
2164                            if (portletDataContext.isWithinDateRange(feed.getModifiedDate())) {
2165                                    exportFeed(portletDataContext, feedsElement, feed);
2166                            }
2167                    }
2168    
2169                    Element articlesElement = rootElement.addElement("articles");
2170    
2171                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "articles")) {
2172                            List<JournalArticle> articles = JournalArticleUtil.findByGroupId(
2173                                    portletDataContext.getScopeGroupId(), QueryUtil.ALL_POS,
2174                                    QueryUtil.ALL_POS, new ArticleIDComparator(true));
2175    
2176                            for (JournalArticle article : articles) {
2177                                    exportArticle(
2178                                            portletDataContext, articlesElement, structuresElement,
2179                                            templatesElement, dlFileEntryTypesElement, dlFoldersElement,
2180                                            dlFilesElement, dlFileRanksElement, igFoldersElement,
2181                                            igImagesElement, article, true);
2182                            }
2183                    }
2184    
2185                    return document.formattedString();
2186            }
2187    
2188            @Override
2189            protected PortletPreferences doImportData(
2190                            PortletDataContext portletDataContext, String portletId,
2191                            PortletPreferences portletPreferences, String data)
2192                    throws Exception {
2193    
2194                    portletDataContext.importPermissions(
2195                            "com.liferay.portlet.journal",
2196                            portletDataContext.getSourceGroupId(),
2197                            portletDataContext.getScopeGroupId());
2198    
2199                    Document document = SAXReaderUtil.read(data);
2200    
2201                    Element rootElement = document.getRootElement();
2202    
2203                    importReferencedData(portletDataContext, rootElement);
2204    
2205                    Element structuresElement = rootElement.element("structures");
2206    
2207                    List<Element> structureElements = structuresElement.elements(
2208                            "structure");
2209    
2210                    for (Element structureElement : structureElements) {
2211                            importStructure(portletDataContext, structureElement);
2212                    }
2213    
2214                    Element templatesElement = rootElement.element("templates");
2215    
2216                    List<Element> templateElements = templatesElement.elements("template");
2217    
2218                    for (Element templateElement : templateElements) {
2219                            importTemplate(portletDataContext, templateElement);
2220                    }
2221    
2222                    Element feedsElement = rootElement.element("feeds");
2223    
2224                    List<Element> feedElements = feedsElement.elements("feed");
2225    
2226                    for (Element feedElement : feedElements) {
2227                            importFeed(portletDataContext, feedElement);
2228                    }
2229    
2230                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "articles")) {
2231                            Element articlesElement = rootElement.element("articles");
2232    
2233                            List<Element> articleElements = articlesElement.elements("article");
2234    
2235                            for (Element articleElement : articleElements) {
2236                                    importArticle(portletDataContext, articleElement);
2237                            }
2238                    }
2239    
2240                    return portletPreferences;
2241            }
2242    
2243            private static final boolean _ALWAYS_EXPORTABLE = true;
2244    
2245            private static final String _NAMESPACE = "journal";
2246    
2247            private static Log _log = LogFactoryUtil.getLog(
2248                    JournalPortletDataHandlerImpl.class);
2249    
2250            private static PortletDataHandlerBoolean _categories =
2251                    new PortletDataHandlerBoolean(_NAMESPACE, "categories");
2252    
2253            private static PortletDataHandlerBoolean _comments =
2254                    new PortletDataHandlerBoolean(_NAMESPACE, "comments");
2255    
2256            private static PortletDataHandlerBoolean _embeddedAssets =
2257                    new PortletDataHandlerBoolean(_NAMESPACE, "embedded-assets");
2258    
2259            private static PortletDataHandlerBoolean _images =
2260                    new PortletDataHandlerBoolean(_NAMESPACE, "images");
2261    
2262            private static PortletDataHandlerBoolean _ratings =
2263                    new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
2264    
2265            private static PortletDataHandlerBoolean
2266                    _structuresTemplatesAndFeeds = new PortletDataHandlerBoolean(
2267                            _NAMESPACE, "structures-templates-and-feeds", true, true);
2268    
2269            private static PortletDataHandlerBoolean _tags =
2270                    new PortletDataHandlerBoolean(_NAMESPACE, "tags");
2271    
2272            private static PortletDataHandlerBoolean _articles =
2273                    new PortletDataHandlerBoolean(_NAMESPACE, "articles", true, false,
2274                    new PortletDataHandlerControl[] {_images, _comments, _ratings, _tags});
2275    
2276            private static Pattern _exportLinksToLayoutPattern = Pattern.compile(
2277                    "\\[([0-9]+)@(public|private\\-[a-z]*)\\]");
2278            private static Pattern _importLinksToLayoutPattern = Pattern.compile(
2279                    "\\[([0-9]+)@(public|private\\-[a-z]*)@(\\p{XDigit}{8}\\-" +
2280                    "(?:\\p{XDigit}{4}\\-){3}\\p{XDigit}{12})@([^\\]]*)\\]");
2281    
2282    }