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