001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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(
1341                                    CharPool.CLOSE_PARENTHESIS, beginPos);
1342                            int endPos4 = content.indexOf(CharPool.LESS_THAN, beginPos);
1343                            int endPos5 = content.indexOf(CharPool.QUOTE, beginPos);
1344                            int endPos6 = content.indexOf(CharPool.SPACE, beginPos);
1345    
1346                            int endPos = endPos1;
1347    
1348                            if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
1349                                    endPos = endPos2;
1350                            }
1351    
1352                            if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
1353                                    endPos = endPos3;
1354                            }
1355    
1356                            if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
1357                                    endPos = endPos4;
1358                            }
1359    
1360                            if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
1361                                    endPos = endPos5;
1362                            }
1363    
1364                            if ((endPos == -1) || ((endPos6 != -1) && (endPos6 < endPos))) {
1365                                    endPos = endPos6;
1366                            }
1367    
1368                            if ((beginPos == -1) || (endPos == -1)) {
1369                                    break;
1370                            }
1371    
1372                            try {
1373                                    String oldParameters = content.substring(beginPos, endPos);
1374    
1375                                    while (oldParameters.contains(StringPool.AMPERSAND_ENCODED)) {
1376                                            oldParameters = oldParameters.replace(
1377                                                    StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
1378                                    }
1379    
1380                                    Map<String, String[]> map = new HashMap<String, String[]>();
1381    
1382                                    if (oldParameters.startsWith("/documents/")) {
1383                                            String[] pathArray = oldParameters.split(StringPool.SLASH);
1384    
1385                                            map.put("groupId", new String[] {pathArray[2]});
1386    
1387                                            if (pathArray.length == 4) {
1388                                                    map.put("uuid", new String[] {pathArray[3]});
1389                                            }
1390                                            else if (pathArray.length > 4) {
1391                                                    map.put("folderId", new String[] {pathArray[3]});
1392    
1393                                                    String name = HttpUtil.decodeURL(pathArray[4]);
1394    
1395                                                    map.put("name", new String[] {name});
1396                                            }
1397                                    }
1398                                    else {
1399                                            oldParameters = oldParameters.substring(
1400                                                    oldParameters.indexOf(CharPool.QUESTION) + 1);
1401    
1402                                            map = HttpUtil.parameterMapFromString(oldParameters);
1403                                    }
1404    
1405                                    FileEntry fileEntry = null;
1406    
1407                                    String uuid = MapUtil.getString(map, "uuid");
1408    
1409                                    if (Validator.isNotNull(uuid)) {
1410                                            String groupIdString = MapUtil.getString(map, "groupId");
1411    
1412                                            long groupId = GetterUtil.getLong(groupIdString);
1413    
1414                                            if (groupIdString.equals("@group_id@")) {
1415                                                    groupId = portletDataContext.getScopeGroupId();
1416                                            }
1417    
1418                                            fileEntry =
1419                                                    DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1420                                                            uuid, groupId);
1421                                    }
1422                                    else {
1423                                            String folderIdString = MapUtil.getString(map, "folderId");
1424    
1425                                            if (Validator.isNotNull(folderIdString)) {
1426                                                    long folderId = GetterUtil.getLong(folderIdString);
1427                                                    String name = MapUtil.getString(map, "name");
1428    
1429                                                    String groupIdString = MapUtil.getString(
1430                                                            map, "groupId");
1431    
1432                                                    long groupId = GetterUtil.getLong(groupIdString);
1433    
1434                                                    if (groupIdString.equals("@group_id@")) {
1435                                                            groupId = portletDataContext.getScopeGroupId();
1436                                                    }
1437    
1438                                                    fileEntry = DLAppLocalServiceUtil.getFileEntry(
1439                                                            groupId, folderId, name);
1440                                            }
1441                                    }
1442    
1443                                    if (fileEntry == null) {
1444                                            beginPos--;
1445    
1446                                            continue;
1447                                    }
1448    
1449                                    String path = DLPortletDataHandlerImpl.getFileEntryPath(
1450                                            portletDataContext, fileEntry);
1451    
1452                                    Element dlReferenceElement = entityElement.addElement(
1453                                            "dl-reference");
1454    
1455                                    dlReferenceElement.addAttribute("path", path);
1456    
1457                                    DLPortletDataHandlerImpl.exportFileEntry(
1458                                            portletDataContext, dlFileEntryTypesElement,
1459                                            dlFoldersElement, dlFileEntriesElement, dlFileRanksElement,
1460                                            fileEntry, checkDateRange);
1461    
1462                                    String dlReference = "[$dl-reference=" + path + "$]";
1463    
1464                                    sb.replace(beginPos, endPos, dlReference);
1465                            }
1466                            catch (Exception e) {
1467                                    if (_log.isWarnEnabled()) {
1468                                            _log.warn(e);
1469                                    }
1470                            }
1471    
1472                            beginPos--;
1473                    }
1474    
1475                    return sb.toString();
1476            }
1477    
1478            protected static void exportFeed(
1479                            PortletDataContext portletDataContext, Element feedsElement,
1480                            JournalFeed feed)
1481                    throws Exception {
1482    
1483                    if (!portletDataContext.isWithinDateRange(feed.getModifiedDate())) {
1484                            return;
1485                    }
1486    
1487                    String path = getFeedPath(portletDataContext, feed);
1488    
1489                    if (!portletDataContext.isPathNotProcessed(path)) {
1490                            return;
1491                    }
1492    
1493                    feed = (JournalFeed)feed.clone();
1494    
1495                    Element feedElement = feedsElement.addElement("feed");
1496    
1497                    Group group = GroupLocalServiceUtil.getGroup(
1498                            portletDataContext.getScopeGroupId());
1499    
1500                    String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
1501    
1502                    String[] friendlyUrlParts = StringUtil.split(
1503                            feed.getTargetLayoutFriendlyUrl(), '/');
1504    
1505                    String oldGroupFriendlyURL = friendlyUrlParts[2];
1506    
1507                    if (newGroupFriendlyURL.equals(oldGroupFriendlyURL)) {
1508                            String targetLayoutFriendlyUrl = StringUtil.replaceFirst(
1509                                    feed.getTargetLayoutFriendlyUrl(),
1510                                    StringPool.SLASH + newGroupFriendlyURL + StringPool.SLASH,
1511                                    "/@data_handler_group_friendly_url@/");
1512    
1513                            feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
1514                    }
1515    
1516                    portletDataContext.addClassedModel(feedElement, path, feed, _NAMESPACE);
1517            }
1518    
1519            protected static String exportLayoutFriendlyURLs(
1520                    PortletDataContext portletDataContext, String content) {
1521    
1522                    Group group = null;
1523    
1524                    try {
1525                            group = GroupLocalServiceUtil.getGroup(
1526                                    portletDataContext.getScopeGroupId());
1527                    }
1528                    catch (Exception e) {
1529                            if (_log.isWarnEnabled()) {
1530                                    _log.warn(e);
1531                            }
1532    
1533                            return content;
1534                    }
1535    
1536                    StringBuilder sb = new StringBuilder(content);
1537    
1538                    String friendlyURLPrivateGroupPath =
1539                            PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
1540                    String friendlyURLPrivateUserPath =
1541                            PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
1542                    String friendlyURLPublicPath =
1543                            PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
1544    
1545                    String href = "href=";
1546    
1547                    int beginPos = content.length();
1548    
1549                    while (true) {
1550                            int hrefLength = href.length();
1551    
1552                            beginPos = content.lastIndexOf(href, beginPos);
1553    
1554                            if (beginPos == -1) {
1555                                    break;
1556                            }
1557    
1558                            char c = content.charAt(beginPos + hrefLength);
1559    
1560                            if ((c == CharPool.APOSTROPHE) || (c == CharPool.QUOTE)) {
1561                                    hrefLength++;
1562                            }
1563    
1564                            int endPos1 = content.indexOf(
1565                                    CharPool.APOSTROPHE, beginPos + hrefLength);
1566                            int endPos2 = content.indexOf(
1567                                    CharPool.CLOSE_BRACKET, beginPos + hrefLength);
1568                            int endPos3 = content.indexOf(
1569                                    CharPool.CLOSE_PARENTHESIS, beginPos + hrefLength);
1570                            int endPos4 = content.indexOf(
1571                                    CharPool.LESS_THAN, beginPos + hrefLength);
1572                            int endPos5 = content.indexOf(
1573                                    CharPool.QUOTE, beginPos + hrefLength);
1574                            int endPos6 = content.indexOf(
1575                                    CharPool.SPACE, beginPos + hrefLength);
1576    
1577                            int endPos = endPos1;
1578    
1579                            if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
1580                                    endPos = endPos2;
1581                            }
1582    
1583                            if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
1584                                    endPos = endPos3;
1585                            }
1586    
1587                            if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
1588                                    endPos = endPos4;
1589                            }
1590    
1591                            if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
1592                                    endPos = endPos5;
1593                            }
1594    
1595                            if ((endPos == -1) || ((endPos6 != -1) && (endPos6 < endPos))) {
1596                                    endPos = endPos6;
1597                            }
1598    
1599                            if (endPos == -1) {
1600                                    beginPos--;
1601    
1602                                    continue;
1603                            }
1604    
1605                            String url = content.substring(beginPos + hrefLength, endPos);
1606    
1607                            if (!url.startsWith(friendlyURLPrivateGroupPath) &&
1608                                    !url.startsWith(friendlyURLPrivateUserPath) &&
1609                                    !url.startsWith(friendlyURLPublicPath)) {
1610    
1611                                    beginPos--;
1612    
1613                                    continue;
1614                            }
1615    
1616                            int beginGroupPos = content.indexOf(
1617                                    CharPool.SLASH, beginPos + hrefLength + 1);
1618    
1619                            if (beginGroupPos == -1) {
1620                                    beginPos--;
1621    
1622                                    continue;
1623                            }
1624    
1625                            int endGroupPos = content.indexOf(
1626                                    CharPool.SLASH, beginGroupPos + 1);
1627    
1628                            if (endGroupPos == -1) {
1629                                    beginPos--;
1630    
1631                                    continue;
1632                            }
1633    
1634                            String groupFriendlyURL = content.substring(
1635                                    beginGroupPos, endGroupPos);
1636    
1637                            if (groupFriendlyURL.equals(group.getFriendlyURL())) {
1638                                    sb.replace(
1639                                            beginGroupPos, endGroupPos,
1640                                            "@data_handler_group_friendly_url@");
1641                            }
1642    
1643                            beginPos--;
1644                    }
1645    
1646                    return sb.toString();
1647            }
1648    
1649            protected static String exportLinksToLayout(
1650                            PortletDataContext portletDataContext, String content)
1651                    throws Exception {
1652    
1653                    List<String> oldLinksToLayout = new ArrayList<String>();
1654                    List<String> newLinksToLayout = new ArrayList<String>();
1655    
1656                    Matcher matcher = _exportLinksToLayoutPattern.matcher(content);
1657    
1658                    while (matcher.find()) {
1659                            long layoutId = GetterUtil.getLong(matcher.group(1));
1660    
1661                            String type = matcher.group(2);
1662    
1663                            boolean privateLayout = type.startsWith("private");
1664    
1665                            try {
1666                                    Layout layout = LayoutLocalServiceUtil.getLayout(
1667                                            portletDataContext.getScopeGroupId(), privateLayout,
1668                                            layoutId);
1669    
1670                                    String oldLinkToLayout = matcher.group(0);
1671    
1672                                    StringBundler sb = new StringBundler(5);
1673    
1674                                    sb.append(type);
1675                                    sb.append(StringPool.AT);
1676                                    sb.append(layout.getUuid());
1677                                    sb.append(StringPool.AT);
1678                                    sb.append(layout.getFriendlyURL());
1679    
1680                                    String newLinkToLayout = StringUtil.replace(
1681                                            oldLinkToLayout, type, sb.toString());
1682    
1683                                    oldLinksToLayout.add(oldLinkToLayout);
1684                                    newLinksToLayout.add(newLinkToLayout);
1685                            }
1686                            catch (Exception e) {
1687                                    if (_log.isWarnEnabled()) {
1688                                            _log.warn(
1689                                                    "Unable to get layout with id " + layoutId +
1690                                                            " in group " + portletDataContext.getScopeGroupId(),
1691                                                    e);
1692                                    }
1693                            }
1694                    }
1695    
1696                    content = StringUtil.replace(
1697                            content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
1698                            ArrayUtil.toStringArray(newLinksToLayout.toArray()));
1699    
1700                    return content;
1701            }
1702    
1703            protected static void exportStructure(
1704                            PortletDataContext portletDataContext, Element structuresElement,
1705                            JournalStructure structure)
1706                    throws Exception {
1707    
1708                    String path = getStructurePath(portletDataContext, structure);
1709    
1710                    if (!portletDataContext.isPathNotProcessed(path)) {
1711                            return;
1712                    }
1713    
1714                    Element structureElement = structuresElement.addElement("structure");
1715    
1716                    String parentStructureId = structure.getParentStructureId();
1717    
1718                    if (Validator.isNotNull(parentStructureId)) {
1719                            try {
1720                                    JournalStructure parentStructure =
1721                                            JournalStructureLocalServiceUtil.getStructure(
1722                                                    structure.getGroupId(), parentStructureId);
1723    
1724                                    structureElement.addAttribute(
1725                                            "parent-structure-uuid", parentStructure.getUuid());
1726    
1727                                    exportStructure(
1728                                            portletDataContext, structuresElement, parentStructure);
1729                            }
1730                            catch (NoSuchStructureException nsse) {
1731                            }
1732                    }
1733    
1734                    portletDataContext.addClassedModel(
1735                            structureElement, path, structure, _NAMESPACE);
1736            }
1737    
1738            protected static void exportTemplate(
1739                            PortletDataContext portletDataContext, Element templatesElement,
1740                            Element dlFileEntryTypesElement, Element dlFoldersElement,
1741                            Element dlFileEntriesElement, Element dlFileRanksElement,
1742                            Element igFoldersElement, Element igImagesElement,
1743                            JournalTemplate template, boolean checkDateRange)
1744                    throws Exception {
1745    
1746                    String path = getTemplatePath(portletDataContext, template);
1747    
1748                    if (!portletDataContext.isPathNotProcessed(path)) {
1749                            return;
1750                    }
1751    
1752                    // Clone this template to make sure changes to its content are never
1753                    // persisted
1754    
1755                    template = (JournalTemplate)template.clone();
1756    
1757                    Element templateElement = templatesElement.addElement("template");
1758    
1759                    if (template.isSmallImage()) {
1760                            String smallImagePath = getTemplateSmallImagePath(
1761                                    portletDataContext, template);
1762    
1763                            templateElement.addAttribute("small-image-path", smallImagePath);
1764    
1765                            Image smallImage = ImageUtil.fetchByPrimaryKey(
1766                                    template.getSmallImageId());
1767    
1768                            template.setSmallImageType(smallImage.getType());
1769    
1770                            portletDataContext.addZipEntry(
1771                                    smallImagePath, smallImage.getTextObj());
1772                    }
1773    
1774                    if (portletDataContext.getBooleanParameter(
1775                                    _NAMESPACE, "embedded-assets")) {
1776    
1777                            String content = exportReferencedContent(
1778                                    portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
1779                                    dlFileEntriesElement, dlFileRanksElement, igFoldersElement,
1780                                    igImagesElement, templateElement, template.getXsl(),
1781                                    checkDateRange);
1782    
1783                            template.setXsl(content);
1784                    }
1785    
1786                    portletDataContext.addClassedModel(
1787                            templateElement, path, template, _NAMESPACE);
1788            }
1789    
1790            protected static String getArticleImagePath(
1791                            PortletDataContext portletDataContext, JournalArticle article)
1792                    throws Exception {
1793    
1794                    StringBundler sb = new StringBundler(6);
1795    
1796                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1797                    sb.append("/articles/");
1798                    sb.append(article.getArticleResourceUuid());
1799                    sb.append(StringPool.SLASH);
1800                    sb.append(article.getVersion());
1801                    sb.append(StringPool.SLASH);
1802    
1803                    return sb.toString();
1804            }
1805    
1806            protected static String getArticleImagePath(
1807                            PortletDataContext portletDataContext, JournalArticle article,
1808                            JournalArticleImage articleImage, Image image)
1809                    throws Exception {
1810    
1811                    StringBundler sb = new StringBundler(13);
1812    
1813                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1814                    sb.append("/articles/");
1815                    sb.append(article.getArticleResourceUuid());
1816                    sb.append(StringPool.SLASH);
1817                    sb.append(article.getVersion());
1818                    sb.append(StringPool.SLASH);
1819                    sb.append(articleImage.getElInstanceId());
1820                    sb.append(StringPool.UNDERLINE);
1821                    sb.append(articleImage.getElName());
1822    
1823                    if (Validator.isNotNull(articleImage.getLanguageId())) {
1824                            sb.append(StringPool.UNDERLINE);
1825                            sb.append(articleImage.getLanguageId());
1826                    }
1827    
1828                    sb.append(StringPool.PERIOD);
1829                    sb.append(image.getType());
1830    
1831                    return sb.toString();
1832            }
1833    
1834            protected static String getArticleSmallImagePath(
1835                            PortletDataContext portletDataContext, JournalArticle article)
1836                    throws Exception {
1837    
1838                    StringBundler sb = new StringBundler(6);
1839    
1840                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1841                    sb.append("/articles/");
1842                    sb.append(article.getArticleResourceUuid());
1843                    sb.append("/thumbnail");
1844                    sb.append(StringPool.PERIOD);
1845                    sb.append(article.getSmallImageType());
1846    
1847                    return sb.toString();
1848            }
1849    
1850            protected static String getFeedPath(
1851                    PortletDataContext portletDataContext, JournalFeed feed) {
1852    
1853                    StringBundler sb = new StringBundler(4);
1854    
1855                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1856                    sb.append("/feeds/");
1857                    sb.append(feed.getUuid());
1858                    sb.append(".xml");
1859    
1860                    return sb.toString();
1861            }
1862    
1863            protected static String getStructurePath(
1864                    PortletDataContext portletDataContext, JournalStructure structure) {
1865    
1866                    StringBundler sb = new StringBundler(4);
1867    
1868                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1869                    sb.append("/structures/");
1870                    sb.append(structure.getUuid());
1871                    sb.append(".xml");
1872    
1873                    return sb.toString();
1874            }
1875    
1876            protected static String getTemplatePath(
1877                    PortletDataContext portletDataContext, JournalTemplate template) {
1878    
1879                    StringBundler sb = new StringBundler(4);
1880    
1881                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1882                    sb.append("/templates/");
1883                    sb.append(template.getUuid());
1884                    sb.append(".xml");
1885    
1886                    return sb.toString();
1887            }
1888    
1889            protected static String getTemplateSmallImagePath(
1890                            PortletDataContext portletDataContext, JournalTemplate template)
1891                    throws Exception {
1892    
1893                    StringBundler sb = new StringBundler(5);
1894    
1895                    sb.append(portletDataContext.getPortletPath(PortletKeys.JOURNAL));
1896                    sb.append("/templates/thumbnail-");
1897                    sb.append(template.getUuid());
1898                    sb.append(StringPool.PERIOD);
1899                    sb.append(template.getSmallImageType());
1900    
1901                    return sb.toString();
1902            }
1903    
1904            protected static String importDLFileEntries(
1905                            PortletDataContext portletDataContext, Element parentElement,
1906                            String content)
1907                    throws Exception {
1908    
1909                    List<Element> dlReferenceElements = parentElement.elements(
1910                            "dl-reference");
1911    
1912                    for (Element dlReferenceElement : dlReferenceElements) {
1913                            String dlReferencePath = dlReferenceElement.attributeValue("path");
1914    
1915                            FileEntry fileEntry = null;
1916    
1917                            try {
1918                                    fileEntry = (FileEntry)portletDataContext.getZipEntryAsObject(
1919                                            dlReferencePath);
1920                            }
1921                            catch (Exception e) {
1922                                    if (_log.isWarnEnabled()) {
1923                                            _log.warn(e);
1924                                    }
1925                            }
1926    
1927                            if (fileEntry == null) {
1928                                    continue;
1929                            }
1930    
1931                            fileEntry = FileEntryUtil.fetchByUUID_R(
1932                                    fileEntry.getUuid(), portletDataContext.getGroupId());
1933    
1934                            if (fileEntry == null) {
1935                                    continue;
1936                            }
1937    
1938                            String dlReference = "[$dl-reference=" + dlReferencePath + "$]";
1939    
1940                            StringBundler sb = new StringBundler(6);
1941    
1942                            sb.append("/documents/");
1943                            sb.append(portletDataContext.getScopeGroupId());
1944                            sb.append(StringPool.SLASH);
1945                            sb.append(fileEntry.getFolderId());
1946                            sb.append(StringPool.SLASH);
1947                            sb.append(
1948                                    HttpUtil.encodeURL(HtmlUtil.unescape(fileEntry.getTitle())));
1949    
1950                            content = StringUtil.replace(content, dlReference, sb.toString());
1951                    }
1952    
1953                    return content;
1954            }
1955    
1956            protected static String importLinksToLayout(
1957                            PortletDataContext portletDataContext, String content)
1958                    throws Exception {
1959    
1960                    List<String> oldLinksToLayout = new ArrayList<String>();
1961                    List<String> newLinksToLayout = new ArrayList<String>();
1962    
1963                    Matcher matcher = _importLinksToLayoutPattern.matcher(content);
1964    
1965                    while (matcher.find()) {
1966                            long oldLayoutId = GetterUtil.getLong(matcher.group(1));
1967    
1968                            long newLayoutId = oldLayoutId;
1969    
1970                            String type = matcher.group(2);
1971    
1972                            boolean privateLayout = type.startsWith("private");
1973    
1974                            String layoutUuid = matcher.group(3);
1975    
1976                            String friendlyURL = matcher.group(4);
1977    
1978                            try {
1979                                    Layout layout = LayoutUtil.fetchByUUID_G(
1980                                            layoutUuid, portletDataContext.getScopeGroupId());
1981    
1982                                    if (layout == null) {
1983                                            layout = LayoutUtil.fetchByG_P_F(
1984                                                    portletDataContext.getScopeGroupId(), privateLayout,
1985                                                    friendlyURL);
1986                                    }
1987    
1988                                    if (layout == null) {
1989                                            layout = LayoutUtil.fetchByG_P_L(
1990                                                    portletDataContext.getScopeGroupId(), privateLayout,
1991                                                    oldLayoutId);
1992                                    }
1993    
1994                                    if (layout == null) {
1995                                            if (_log.isWarnEnabled()) {
1996                                                    StringBundler sb = new StringBundler(9);
1997    
1998                                                    sb.append("Unable to get layout with UUID ");
1999                                                    sb.append(layoutUuid);
2000                                                    sb.append(", friendly URL ");
2001                                                    sb.append(friendlyURL);
2002                                                    sb.append(", or ");
2003                                                    sb.append("layoutId ");
2004                                                    sb.append(oldLayoutId);
2005                                                    sb.append(" in group ");
2006                                                    sb.append(portletDataContext.getScopeGroupId());
2007    
2008                                                    _log.warn(sb.toString());
2009                                            }
2010                                    }
2011                                    else {
2012                                            newLayoutId = layout.getLayoutId();
2013                                    }
2014                            }
2015                            catch (SystemException e) {
2016                                    if (_log.isWarnEnabled()) {
2017                                            _log.warn(
2018                                                    "Unable to get layout in group " +
2019                                                            portletDataContext.getScopeGroupId(), e);
2020                                    }
2021                            }
2022    
2023                            String oldLinkToLayout = matcher.group(0);
2024    
2025                            StringBundler sb = new StringBundler(4);
2026    
2027                            sb.append(StringPool.AT);
2028                            sb.append(layoutUuid);
2029                            sb.append(StringPool.AT);
2030                            sb.append(friendlyURL);
2031    
2032                            String newLinkToLayout = StringUtil.replace(
2033                                    oldLinkToLayout,
2034                                    new String[] {sb.toString(), String.valueOf(oldLayoutId)},
2035                                    new String[] {StringPool.BLANK, String.valueOf(newLayoutId)});
2036    
2037                            oldLinksToLayout.add(oldLinkToLayout);
2038                            newLinksToLayout.add(newLinkToLayout);
2039                    }
2040    
2041                    content = StringUtil.replace(
2042                            content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
2043                            ArrayUtil.toStringArray(newLinksToLayout.toArray()));
2044    
2045                    return content;
2046            }
2047    
2048            @Override
2049            public PortletDataHandlerControl[] getExportControls() {
2050                    return new PortletDataHandlerControl[] {
2051                            _articles, _structuresTemplatesAndFeeds, _embeddedAssets, _images,
2052                            _categories, _comments, _ratings, _tags
2053                    };
2054            }
2055    
2056            @Override
2057            public PortletDataHandlerControl[] getImportControls() {
2058                    return new PortletDataHandlerControl[] {
2059                            _articles, _structuresTemplatesAndFeeds, _images, _categories,
2060                            _comments, _ratings, _tags
2061                    };
2062            }
2063    
2064            @Override
2065            public boolean isAlwaysExportable() {
2066                    return _ALWAYS_EXPORTABLE;
2067            }
2068    
2069            @Override
2070            public boolean isPublishToLiveByDefault() {
2071                    return PropsValues.JOURNAL_PUBLISH_TO_LIVE_BY_DEFAULT;
2072            }
2073    
2074            @Override
2075            protected PortletPreferences doDeleteData(
2076                            PortletDataContext portletDataContext, String portletId,
2077                            PortletPreferences portletPreferences)
2078                    throws Exception {
2079    
2080                    if (!portletDataContext.addPrimaryKey(
2081                                    JournalPortletDataHandlerImpl.class, "deleteData")) {
2082    
2083                            JournalArticleLocalServiceUtil.deleteArticles(
2084                                    portletDataContext.getScopeGroupId());
2085    
2086                            JournalTemplateLocalServiceUtil.deleteTemplates(
2087                                    portletDataContext.getScopeGroupId());
2088    
2089                            JournalStructureLocalServiceUtil.deleteStructures(
2090                                    portletDataContext.getScopeGroupId());
2091                    }
2092    
2093                    return portletPreferences;
2094            }
2095    
2096            @Override
2097            protected String doExportData(
2098                            PortletDataContext portletDataContext, String portletId,
2099                            PortletPreferences portletPreferences)
2100                    throws Exception {
2101    
2102                    portletDataContext.addPermissions(
2103                            "com.liferay.portlet.journal",
2104                            portletDataContext.getScopeGroupId());
2105    
2106                    Document document = SAXReaderUtil.createDocument();
2107    
2108                    Element rootElement = document.addElement("journal-data");
2109    
2110                    rootElement.addAttribute(
2111                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
2112    
2113                    Element structuresElement = rootElement.addElement("structures");
2114    
2115                    List<JournalStructure> structures = JournalStructureUtil.findByGroupId(
2116                            portletDataContext.getScopeGroupId(), QueryUtil.ALL_POS,
2117                            QueryUtil.ALL_POS, new StructurePKComparator(true));
2118    
2119                    for (JournalStructure structure : structures) {
2120                            if (portletDataContext.isWithinDateRange(
2121                                            structure.getModifiedDate())) {
2122    
2123                                    exportStructure(
2124                                            portletDataContext, structuresElement, structure);
2125                            }
2126                    }
2127    
2128                    Element templatesElement = rootElement.addElement("templates");
2129                    Element dlFileEntryTypesElement = rootElement.addElement(
2130                            "dl-file-entry-types");
2131                    Element dlFoldersElement = rootElement.addElement("dl-folders");
2132                    Element dlFilesElement = rootElement.addElement("dl-file-entries");
2133                    Element dlFileRanksElement = rootElement.addElement("dl-file-ranks");
2134                    Element igFoldersElement = rootElement.addElement("ig-folders");
2135                    Element igImagesElement = rootElement.addElement("ig-images");
2136    
2137                    List<JournalTemplate> templates = JournalTemplateUtil.findByGroupId(
2138                            portletDataContext.getScopeGroupId());
2139    
2140                    for (JournalTemplate template : templates) {
2141                            if (portletDataContext.isWithinDateRange(
2142                                            template.getModifiedDate())) {
2143    
2144                                    exportTemplate(
2145                                            portletDataContext, templatesElement,
2146                                            dlFileEntryTypesElement, dlFoldersElement, dlFilesElement,
2147                                            dlFileRanksElement, igFoldersElement, igImagesElement,
2148                                            template, true);
2149                            }
2150                    }
2151    
2152                    Element feedsElement = rootElement.addElement("feeds");
2153    
2154                    List<JournalFeed> feeds = JournalFeedUtil.findByGroupId(
2155                            portletDataContext.getScopeGroupId());
2156    
2157                    for (JournalFeed feed : feeds) {
2158                            if (portletDataContext.isWithinDateRange(feed.getModifiedDate())) {
2159                                    exportFeed(portletDataContext, feedsElement, feed);
2160                            }
2161                    }
2162    
2163                    Element articlesElement = rootElement.addElement("articles");
2164    
2165                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "articles")) {
2166                            List<JournalArticle> articles = JournalArticleUtil.findByGroupId(
2167                                    portletDataContext.getScopeGroupId(), QueryUtil.ALL_POS,
2168                                    QueryUtil.ALL_POS, new ArticleIDComparator(true));
2169    
2170                            for (JournalArticle article : articles) {
2171                                    exportArticle(
2172                                            portletDataContext, articlesElement, structuresElement,
2173                                            templatesElement, dlFileEntryTypesElement, dlFoldersElement,
2174                                            dlFilesElement, dlFileRanksElement, igFoldersElement,
2175                                            igImagesElement, article, true);
2176                            }
2177                    }
2178    
2179                    return document.formattedString();
2180            }
2181    
2182            @Override
2183            protected PortletPreferences doImportData(
2184                            PortletDataContext portletDataContext, String portletId,
2185                            PortletPreferences portletPreferences, String data)
2186                    throws Exception {
2187    
2188                    portletDataContext.importPermissions(
2189                            "com.liferay.portlet.journal",
2190                            portletDataContext.getSourceGroupId(),
2191                            portletDataContext.getScopeGroupId());
2192    
2193                    Document document = SAXReaderUtil.read(data);
2194    
2195                    Element rootElement = document.getRootElement();
2196    
2197                    importReferencedData(portletDataContext, rootElement);
2198    
2199                    Element structuresElement = rootElement.element("structures");
2200    
2201                    List<Element> structureElements = structuresElement.elements(
2202                            "structure");
2203    
2204                    for (Element structureElement : structureElements) {
2205                            importStructure(portletDataContext, structureElement);
2206                    }
2207    
2208                    Element templatesElement = rootElement.element("templates");
2209    
2210                    List<Element> templateElements = templatesElement.elements("template");
2211    
2212                    for (Element templateElement : templateElements) {
2213                            importTemplate(portletDataContext, templateElement);
2214                    }
2215    
2216                    Element feedsElement = rootElement.element("feeds");
2217    
2218                    List<Element> feedElements = feedsElement.elements("feed");
2219    
2220                    for (Element feedElement : feedElements) {
2221                            importFeed(portletDataContext, feedElement);
2222                    }
2223    
2224                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "articles")) {
2225                            Element articlesElement = rootElement.element("articles");
2226    
2227                            List<Element> articleElements = articlesElement.elements("article");
2228    
2229                            for (Element articleElement : articleElements) {
2230                                    importArticle(portletDataContext, articleElement);
2231                            }
2232                    }
2233    
2234                    return portletPreferences;
2235            }
2236    
2237            private static final boolean _ALWAYS_EXPORTABLE = true;
2238    
2239            private static final String _NAMESPACE = "journal";
2240    
2241            private static Log _log = LogFactoryUtil.getLog(
2242                    JournalPortletDataHandlerImpl.class);
2243    
2244            private static PortletDataHandlerBoolean _categories =
2245                    new PortletDataHandlerBoolean(_NAMESPACE, "categories");
2246    
2247            private static PortletDataHandlerBoolean _comments =
2248                    new PortletDataHandlerBoolean(_NAMESPACE, "comments");
2249    
2250            private static PortletDataHandlerBoolean _embeddedAssets =
2251                    new PortletDataHandlerBoolean(_NAMESPACE, "embedded-assets");
2252    
2253            private static PortletDataHandlerBoolean _images =
2254                    new PortletDataHandlerBoolean(_NAMESPACE, "images");
2255    
2256            private static PortletDataHandlerBoolean _ratings =
2257                    new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
2258    
2259            private static PortletDataHandlerBoolean
2260                    _structuresTemplatesAndFeeds = new PortletDataHandlerBoolean(
2261                            _NAMESPACE, "structures-templates-and-feeds", true, true);
2262    
2263            private static PortletDataHandlerBoolean _tags =
2264                    new PortletDataHandlerBoolean(_NAMESPACE, "tags");
2265    
2266            private static PortletDataHandlerBoolean _articles =
2267                    new PortletDataHandlerBoolean(_NAMESPACE, "articles", true, false,
2268                    new PortletDataHandlerControl[] {_images, _comments, _ratings, _tags});
2269    
2270            private static Pattern _exportLinksToLayoutPattern = Pattern.compile(
2271                    "\\[([0-9]+)@(public|private\\-[a-z]*)\\]");
2272            private static Pattern _importLinksToLayoutPattern = Pattern.compile(
2273                    "\\[([0-9]+)@(public|private\\-[a-z]*)@(\\p{XDigit}{8}\\-" +
2274                    "(?:\\p{XDigit}{4}\\-){3}\\p{XDigit}{12})@([^\\]]*)\\]");
2275    
2276    }