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