001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.journal.lar;
016    
017    import com.liferay.portal.kernel.lar.BasePortletDataHandler;
018    import com.liferay.portal.kernel.lar.PortletDataContext;
019    import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
020    import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.MapUtil;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.kernel.workflow.WorkflowConstants;
028    import com.liferay.portal.kernel.xml.Document;
029    import com.liferay.portal.kernel.xml.Element;
030    import com.liferay.portal.kernel.xml.SAXReaderUtil;
031    import com.liferay.portal.model.Layout;
032    import com.liferay.portal.service.LayoutLocalServiceUtil;
033    import com.liferay.portlet.documentlibrary.lar.DLPortletDataHandlerImpl;
034    import com.liferay.portlet.imagegallery.lar.IGPortletDataHandlerImpl;
035    import com.liferay.portlet.journal.NoSuchArticleException;
036    import com.liferay.portlet.journal.model.JournalArticle;
037    import com.liferay.portlet.journal.model.JournalStructure;
038    import com.liferay.portlet.journal.model.JournalTemplate;
039    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
040    import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
041    import com.liferay.portlet.journal.service.persistence.JournalStructureUtil;
042    import com.liferay.portlet.journal.service.persistence.JournalTemplateUtil;
043    
044    import java.util.Collections;
045    import java.util.List;
046    import java.util.Map;
047    
048    import javax.portlet.PortletPreferences;
049    
050    /**
051     * <p>
052     * Provides the Journal Content portlet export and import functionality, which
053     * is to clone the article, structure, and template referenced in the Journal
054     * Content portlet if the article is associated with the layout's group. Upon
055     * import, a new instance of the corresponding article, structure, and template
056     * will be created or updated. The author of the newly created objects are
057     * determined by the JournalCreationStrategy class defined in
058     * <i>portal.properties</i>.
059     * </p>
060     *
061     * <p>
062     * This <code>PortletDataHandler</code> differs from from
063     * <code>JournalPortletDataHandlerImpl</code> in that it only exports articles
064     * referenced in Journal Content portlets. Articles not displayed in Journal
065     * Content portlets will not be exported unless
066     * <code>JournalPortletDataHandlerImpl</code> is activated.
067     * </p>
068     *
069     * @author Joel Kozikowski
070     * @author Raymond Augé
071     * @author Bruno Farache
072     * @see    com.liferay.portal.kernel.lar.PortletDataHandler
073     * @see    com.liferay.portlet.journal.lar.JournalCreationStrategy
074     * @see    com.liferay.portlet.journal.lar.JournalPortletDataHandlerImpl
075     */
076    public class JournalContentPortletDataHandlerImpl
077            extends BasePortletDataHandler {
078    
079            public PortletDataHandlerControl[] getExportControls() {
080                    return new PortletDataHandlerControl[] {
081                            _selectedArticles, _embeddedAssets, _images, _comments, _ratings,
082                            _tags
083                    };
084            }
085    
086            public PortletDataHandlerControl[] getImportControls() {
087                    return new PortletDataHandlerControl[] {
088                            _selectedArticles, _images, _comments, _ratings, _tags
089                    };
090            }
091    
092            public boolean isPublishToLiveByDefault() {
093                    return     _PUBLISH_TO_LIVE_BY_DEFAULT;
094            }
095    
096            protected PortletPreferences doDeleteData(
097                            PortletDataContext context, String portletId,
098                            PortletPreferences preferences)
099                    throws Exception {
100    
101                    preferences.setValue("group-id", StringPool.BLANK);
102                    preferences.setValue("article-id", StringPool.BLANK);
103    
104                    return preferences;
105            }
106    
107            protected String doExportData(
108                            PortletDataContext context, String portletId,
109                            PortletPreferences preferences)
110                    throws Exception {
111    
112                    context.addPermissions(
113                            "com.liferay.portlet.journal", context.getScopeGroupId());
114    
115                    String articleId = preferences.getValue("article-id", null);
116    
117                    if (articleId == null) {
118                            if (_log.isWarnEnabled()) {
119                                    _log.warn(
120                                            "No article id found in preferences of portlet " +
121                                                    portletId);
122                            }
123    
124                            return StringPool.BLANK;
125                    }
126    
127                    long articleGroupId = GetterUtil.getLong(
128                            preferences.getValue("group-id", StringPool.BLANK));
129    
130                    if (articleGroupId <= 0) {
131                            if (_log.isWarnEnabled()) {
132                                    _log.warn(
133                                            "No group id found in preferences of portlet " + portletId);
134                            }
135    
136                            return StringPool.BLANK;
137                    }
138    
139                    JournalArticle article = null;
140    
141                    try {
142                            article = JournalArticleLocalServiceUtil.getLatestArticle(
143                                    articleGroupId, articleId, WorkflowConstants.STATUS_APPROVED);
144                    }
145                    catch (NoSuchArticleException nsae) {
146                            if (_log.isWarnEnabled()) {
147                                    _log.warn(
148                                            "No approved article found with group id " +
149                                                    articleGroupId + " and article id " + articleId);
150                            }
151                    }
152    
153                    if (article == null) {
154                            return StringPool.BLANK;
155                    }
156    
157                    Document document = SAXReaderUtil.createDocument();
158    
159                    Element rootElement = document.addElement("journal-content-data");
160    
161                    Element dlFoldersElement = rootElement.addElement("dl-folders");
162                    Element dlFilesElement = rootElement.addElement("dl-file-entries");
163                    Element dlFileRanksElement = rootElement.addElement("dl-file-ranks");
164                    Element igFoldersElement = rootElement.addElement("ig-folders");
165                    Element igImagesElement = rootElement.addElement("ig-images");
166    
167                    JournalPortletDataHandlerImpl.exportArticle(
168                            context, rootElement, dlFoldersElement, dlFilesElement,
169                            dlFileRanksElement, igFoldersElement, igImagesElement, article);
170    
171                    String structureId = article.getStructureId();
172    
173                    if (Validator.isNotNull(structureId)) {
174                            JournalStructure structure = JournalStructureUtil.findByG_S(
175                                    article.getGroupId(), structureId);
176    
177                            JournalPortletDataHandlerImpl.exportStructure(
178                                    context, rootElement, structure);
179                    }
180    
181                    String templateId = article.getTemplateId();
182    
183                    if (Validator.isNotNull(templateId)) {
184                            JournalTemplate template = JournalTemplateUtil.findByG_T(
185                                    article.getGroupId(), templateId);
186    
187                            JournalPortletDataHandlerImpl.exportTemplate(
188                                    context, rootElement, dlFoldersElement, dlFilesElement,
189                                    dlFileRanksElement, igFoldersElement, igImagesElement,
190                                    template);
191                    }
192    
193                    return document.formattedString();
194            }
195    
196            protected PortletPreferences doImportData(
197                            PortletDataContext context, String portletId,
198                            PortletPreferences preferences, String data)
199                    throws Exception {
200    
201                    context.importPermissions(
202                            "com.liferay.portlet.journal", context.getSourceGroupId(),
203                            context.getScopeGroupId());
204    
205                    if (Validator.isNull(data)) {
206                            return null;
207                    }
208    
209                    Document document = SAXReaderUtil.read(data);
210    
211                    Element rootElement = document.getRootElement();
212    
213                    Element dlFoldersElement = rootElement.element("dl-folders");
214    
215                    List<Element> dlFolderElements = Collections.EMPTY_LIST;
216    
217                    if (dlFoldersElement != null) {
218                            dlFolderElements = dlFoldersElement.elements("folder");
219                    }
220    
221                    for (Element folderElement : dlFolderElements) {
222                            DLPortletDataHandlerImpl.importFolder(context, folderElement);
223                    }
224    
225                    Element dlFileEntriesElement = rootElement.element("dl-file-entries");
226    
227                    List<Element> dlFileEntryElements = Collections.EMPTY_LIST;
228    
229                    if (dlFileEntriesElement != null) {
230                            dlFileEntryElements = dlFileEntriesElement.elements("file-entry");
231                    }
232    
233                    for (Element fileEntryElement : dlFileEntryElements) {
234                            DLPortletDataHandlerImpl.importFileEntry(context, fileEntryElement);
235                    }
236    
237                    Element dlFileRanksElement = rootElement.element("dl-file-ranks");
238    
239                    List<Element> dlFileRankElements = Collections.EMPTY_LIST;
240    
241                    if (dlFileRanksElement != null) {
242                            dlFileRankElements = dlFileRanksElement.elements("file-rank");
243                    }
244    
245                    for (Element fileRankElement : dlFileRankElements) {
246                            DLPortletDataHandlerImpl.importFileRank(context, fileRankElement);
247                    }
248    
249                    Element igFoldersElement = rootElement.element("ig-folders");
250    
251                    List<Element> igFolderElements = Collections.EMPTY_LIST;
252    
253                    if (igFoldersElement != null) {
254                            igFolderElements = igFoldersElement.elements("folder");
255                    }
256    
257                    for (Element folderElement : igFolderElements) {
258                            IGPortletDataHandlerImpl.importFolder(context, folderElement);
259                    }
260    
261                    Element igImagesElement = rootElement.element("ig-images");
262    
263                    List<Element> igImageElements = Collections.EMPTY_LIST;
264    
265                    if (igImagesElement != null) {
266                            igImageElements = igImagesElement.elements("image");
267                    }
268    
269                    for (Element imageElement : igImageElements) {
270                            IGPortletDataHandlerImpl.importImage(context, imageElement);
271                    }
272    
273                    Element structureElement = rootElement.element("structure");
274    
275                    if (structureElement != null) {
276                            JournalPortletDataHandlerImpl.importStructure(
277                                    context, structureElement);
278                    }
279    
280                    Element templateElement = rootElement.element("template");
281    
282                    if (templateElement != null) {
283                            JournalPortletDataHandlerImpl.importTemplate(
284                                    context, templateElement);
285                    }
286    
287                    Element articleElement = rootElement.element("article");
288    
289                    if (articleElement != null) {
290                            JournalPortletDataHandlerImpl.importArticle(
291                                    context, articleElement);
292                    }
293    
294                    String articleId = preferences.getValue("article-id", StringPool.BLANK);
295    
296                    if (Validator.isNotNull(articleId)) {
297                            Map<String, String> articleIds =
298                                    (Map<String, String>)context.getNewPrimaryKeysMap(
299                                            JournalArticle.class);
300    
301                            articleId = MapUtil.getString(articleIds, articleId, articleId);
302    
303                            preferences.setValue(
304                                    "group-id", String.valueOf(context.getScopeGroupId()));
305                            preferences.setValue("article-id", articleId);
306    
307                            Layout layout = LayoutLocalServiceUtil.getLayout(
308                                    context.getPlid());
309    
310                            JournalContentSearchLocalServiceUtil.updateContentSearch(
311                                    context.getScopeGroupId(), layout.isPrivateLayout(),
312                                    layout.getLayoutId(), portletId, articleId, true);
313                    }
314    
315                    return preferences;
316            }
317    
318            private static final String _NAMESPACE = "journal";
319    
320            private static final boolean _PUBLISH_TO_LIVE_BY_DEFAULT = true;
321    
322            private static PortletDataHandlerBoolean _comments =
323                    new PortletDataHandlerBoolean(_NAMESPACE, "comments");
324    
325            private static PortletDataHandlerBoolean _embeddedAssets =
326                    new PortletDataHandlerBoolean(_NAMESPACE, "embedded-assets");
327    
328            private static PortletDataHandlerBoolean _images =
329                    new PortletDataHandlerBoolean(_NAMESPACE, "images");
330    
331            private static Log _log = LogFactoryUtil.getLog(
332                    JournalContentPortletDataHandlerImpl.class);
333    
334            private static PortletDataHandlerBoolean _ratings =
335                    new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
336    
337            private static PortletDataHandlerBoolean _selectedArticles =
338                    new PortletDataHandlerBoolean(
339                            _NAMESPACE, "selected-web-content", true, true);
340    
341            private static PortletDataHandlerBoolean _tags =
342                    new PortletDataHandlerBoolean(_NAMESPACE, "tags");
343    
344    }