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