001    /**
002     * Copyright (c) 2000-2012 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.journal.NoSuchArticleException;
035    import com.liferay.portlet.journal.model.JournalArticle;
036    import com.liferay.portlet.journal.model.JournalTemplate;
037    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
038    import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
039    import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
040    
041    import java.util.List;
042    import java.util.Map;
043    
044    import javax.portlet.PortletPreferences;
045    
046    /**
047     * <p>
048     * Provides the Journal Content portlet export and import functionality, which
049     * is to clone the article, structure, and template referenced in the Journal
050     * Content portlet if the article is associated with the layout's group. Upon
051     * import, a new instance of the corresponding article, structure, and template
052     * will be created or updated. The author of the newly created objects are
053     * determined by the JournalCreationStrategy class defined in
054     * <i>portal.properties</i>.
055     * </p>
056     *
057     * <p>
058     * This <code>PortletDataHandler</code> differs from from
059     * <code>JournalPortletDataHandlerImpl</code> in that it only exports articles
060     * referenced in Journal Content portlets. Articles not displayed in Journal
061     * Content portlets will not be exported unless
062     * <code>JournalPortletDataHandlerImpl</code> is activated.
063     * </p>
064     *
065     * @author Joel Kozikowski
066     * @author Raymond Augé
067     * @author Bruno Farache
068     * @see    com.liferay.portal.kernel.lar.PortletDataHandler
069     * @see    com.liferay.portlet.journal.lar.JournalCreationStrategy
070     * @see    com.liferay.portlet.journal.lar.JournalPortletDataHandlerImpl
071     */
072    public class JournalContentPortletDataHandlerImpl
073            extends BasePortletDataHandler {
074    
075            @Override
076            public String[] getDataPortletPreferences() {
077                    return new String[] {"groupId", "articleId", "templateId"};
078            }
079    
080            @Override
081            public PortletDataHandlerControl[] getExportControls() {
082                    return new PortletDataHandlerControl[] {
083                            _selectedArticles, _embeddedAssets
084                    };
085            }
086    
087            @Override
088            public PortletDataHandlerControl[] getExportMetadataControls() {
089                    return new PortletDataHandlerControl[] {
090                            new PortletDataHandlerBoolean(
091                                    _NAMESPACE, "web-content", true,
092                                    JournalPortletDataHandlerImpl.getMetadataControls()),
093                            new PortletDataHandlerBoolean(
094                                    _NAMESPACE, "folders-and-documents", true,
095                                    DLPortletDataHandlerImpl.getMetadataControls()
096                            )
097                    };
098            }
099    
100            @Override
101            public PortletDataHandlerControl[] getImportControls() {
102                    return new PortletDataHandlerControl[] {
103                            _selectedArticles
104                    };
105            }
106    
107            @Override
108            public PortletDataHandlerControl[] getImportMetadataControls() {
109                    return new PortletDataHandlerControl[] {
110                            new PortletDataHandlerBoolean(
111                                    _NAMESPACE, "web-content", true,
112                                    JournalPortletDataHandlerImpl.getMetadataControls()),
113                            new PortletDataHandlerBoolean(
114                                    _NAMESPACE, "folders-and-documents", true,
115                                    DLPortletDataHandlerImpl.getMetadataControls()
116                            )
117                    };
118            }
119    
120            @Override
121            public boolean isAlwaysExportable() {
122                    return _ALWAYS_EXPORTABLE;
123            }
124    
125            @Override
126            public boolean isAlwaysStaged() {
127                    return _ALWAYS_STAGED;
128            }
129    
130            @Override
131            public boolean isDataLocalized() {
132                    return _DATA_LOCALIZED;
133            }
134    
135            @Override
136            public boolean isPublishToLiveByDefault() {
137                    return _PUBLISH_TO_LIVE_BY_DEFAULT;
138            }
139    
140            @Override
141            protected PortletPreferences doDeleteData(
142                            PortletDataContext portletDataContext, String portletId,
143                            PortletPreferences portletPreferences)
144                    throws Exception {
145    
146                    if (portletPreferences == null) {
147                            return portletPreferences;
148                    }
149    
150                    portletPreferences.setValue("groupId", StringPool.BLANK);
151                    portletPreferences.setValue("articleId", StringPool.BLANK);
152    
153                    return portletPreferences;
154            }
155    
156            @Override
157            protected String doExportData(
158                            PortletDataContext portletDataContext, String portletId,
159                            PortletPreferences portletPreferences)
160                    throws Exception {
161    
162                    portletDataContext.addPermissions(
163                            "com.liferay.portlet.journal",
164                            portletDataContext.getScopeGroupId());
165    
166                    String articleId = portletPreferences.getValue("articleId", null);
167    
168                    if (articleId == null) {
169                            if (_log.isDebugEnabled()) {
170                                    _log.debug(
171                                            "No article id found in preferences of portlet " +
172                                                    portletId);
173                            }
174    
175                            return StringPool.BLANK;
176                    }
177    
178                    long articleGroupId = GetterUtil.getLong(
179                            portletPreferences.getValue("groupId", StringPool.BLANK));
180    
181                    if (articleGroupId <= 0) {
182                            if (_log.isWarnEnabled()) {
183                                    _log.warn(
184                                            "No group id found in preferences of portlet " + portletId);
185                            }
186    
187                            return StringPool.BLANK;
188                    }
189    
190                    long previousScopeGroupId = portletDataContext.getScopeGroupId();
191    
192                    if (articleGroupId != portletDataContext.getScopeGroupId()) {
193                            portletDataContext.setScopeGroupId(articleGroupId);
194                    }
195    
196                    JournalArticle article = null;
197    
198                    try {
199                            article = JournalArticleLocalServiceUtil.getLatestArticle(
200                                    articleGroupId, articleId, WorkflowConstants.STATUS_APPROVED);
201                    }
202                    catch (NoSuchArticleException nsae) {
203                    }
204    
205                    if (article == null) {
206                            try {
207                                    article = JournalArticleLocalServiceUtil.getLatestArticle(
208                                            articleGroupId, articleId,
209                                            WorkflowConstants.STATUS_EXPIRED);
210                            }
211                            catch (NoSuchArticleException nsae) {
212                            }
213                    }
214    
215                    Document document = SAXReaderUtil.createDocument();
216    
217                    Element rootElement = document.addElement("journal-content-data");
218    
219                    if (article == null) {
220                            portletDataContext.setScopeGroupId(previousScopeGroupId);
221    
222                            return document.formattedString();
223                    }
224    
225                    String path = JournalPortletDataHandlerImpl.getArticlePath(
226                            portletDataContext, article);
227    
228                    Element articleElement = rootElement.addElement("article");
229    
230                    articleElement.addAttribute("path", path);
231    
232                    Element dlFileEntryTypesElement = rootElement.addElement(
233                            "dl-file-entry-types");
234                    Element dlFoldersElement = rootElement.addElement("dl-folders");
235                    Element dlFilesElement = rootElement.addElement("dl-file-entries");
236                    Element dlFileRanksElement = rootElement.addElement("dl-file-ranks");
237                    Element dlRepositoriesElement = rootElement.addElement(
238                            "dl-repositories");
239                    Element dlRepositoryEntriesElement = rootElement.addElement(
240                            "dl-repository-entries");
241    
242                    JournalPortletDataHandlerImpl.exportArticle(
243                            portletDataContext, rootElement, rootElement, rootElement,
244                            dlFileEntryTypesElement, dlFoldersElement, dlFilesElement,
245                            dlFileRanksElement, dlRepositoriesElement,
246                            dlRepositoryEntriesElement, article, false);
247    
248                    String defaultTemplateId = article.getTemplateId();
249                    String preferenceTemplateId = portletPreferences.getValue(
250                            "templateId", null);
251    
252                    if (Validator.isNotNull(defaultTemplateId) &&
253                            Validator.isNotNull(preferenceTemplateId) &&
254                            !defaultTemplateId.equals(preferenceTemplateId)) {
255    
256                            JournalTemplate template =
257                                    JournalTemplateLocalServiceUtil.getTemplate(
258                                            article.getGroupId(), preferenceTemplateId, true);
259    
260                            JournalPortletDataHandlerImpl.exportTemplate(
261                                    portletDataContext, rootElement, dlFileEntryTypesElement,
262                                    dlFoldersElement, dlFilesElement, dlFileRanksElement,
263                                    dlRepositoriesElement, dlRepositoryEntriesElement, template);
264                    }
265    
266                    portletDataContext.setScopeGroupId(previousScopeGroupId);
267    
268                    return document.formattedString();
269            }
270    
271            @Override
272            protected PortletPreferences doImportData(
273                            PortletDataContext portletDataContext, String portletId,
274                            PortletPreferences portletPreferences, String data)
275                    throws Exception {
276    
277                    portletDataContext.importPermissions(
278                            "com.liferay.portlet.journal",
279                            portletDataContext.getSourceGroupId(),
280                            portletDataContext.getScopeGroupId());
281    
282                    if (Validator.isNull(data)) {
283                            return null;
284                    }
285    
286                    long previousScopeGroupId = portletDataContext.getScopeGroupId();
287    
288                    long importGroupId = GetterUtil.getLong(
289                            portletPreferences.getValue("groupId", null));
290    
291                    if (importGroupId == portletDataContext.getSourceGroupId()) {
292                            portletDataContext.setScopeGroupId(portletDataContext.getGroupId());
293                    }
294    
295                    Document document = SAXReaderUtil.read(data);
296    
297                    Element rootElement = document.getRootElement();
298    
299                    JournalPortletDataHandlerImpl.importReferencedData(
300                            portletDataContext, rootElement);
301    
302                    Element structureElement = rootElement.element("structure");
303    
304                    if (structureElement != null) {
305                            JournalPortletDataHandlerImpl.importStructure(
306                                    portletDataContext, structureElement);
307                    }
308    
309                    List<Element> templateElements = rootElement.elements("template");
310    
311                    if (templateElements != null) {
312                            for (Element templateElement : templateElements) {
313                                    JournalPortletDataHandlerImpl.importTemplate(
314                                            portletDataContext, templateElement);
315                            }
316                    }
317    
318                    Element articleElement = rootElement.element("article");
319    
320                    if (articleElement != null) {
321                            JournalPortletDataHandlerImpl.importArticle(
322                                    portletDataContext, articleElement);
323                    }
324    
325                    String articleId = portletPreferences.getValue("articleId", null);
326    
327                    if (Validator.isNotNull(articleId) && (articleElement != null)) {
328                            Map<String, String> articleIds =
329                                    (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
330                                            JournalArticle.class + ".articleId");
331    
332                            articleId = MapUtil.getString(articleIds, articleId, articleId);
333    
334                            portletPreferences.setValue("articleId", articleId);
335    
336                            String importedArticleGroupId = String.valueOf(
337                                    portletDataContext.getScopeGroupId());
338    
339                            portletPreferences.setValue("groupId", importedArticleGroupId);
340    
341                            Layout layout = LayoutLocalServiceUtil.getLayout(
342                                    portletDataContext.getPlid());
343    
344                            JournalContentSearchLocalServiceUtil.updateContentSearch(
345                                    portletDataContext.getScopeGroupId(), layout.isPrivateLayout(),
346                                    layout.getLayoutId(), portletId, articleId, true);
347                    }
348                    else {
349                            portletPreferences.setValue("groupId", StringPool.BLANK);
350                            portletPreferences.setValue("articleId", StringPool.BLANK);
351                    }
352    
353                    String templateId = portletPreferences.getValue("templateId", null);
354    
355                    if (Validator.isNotNull(templateId)) {
356                            Map<String, String> templateIds =
357                                    (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
358                                            JournalTemplate.class + ".templateId");
359    
360                            templateId = MapUtil.getString(templateIds, templateId, templateId);
361    
362                            portletPreferences.setValue("templateId", templateId);
363                    }
364                    else {
365                            portletPreferences.setValue("templateId", StringPool.BLANK);
366                    }
367    
368                    portletDataContext.setScopeGroupId(previousScopeGroupId);
369    
370                    return portletPreferences;
371            }
372    
373            private static final boolean _ALWAYS_EXPORTABLE = true;
374    
375            private static final boolean _ALWAYS_STAGED = true;
376    
377            private static final boolean _DATA_LOCALIZED = true;
378    
379            private static final String _NAMESPACE = "journal";
380    
381            private static final boolean _PUBLISH_TO_LIVE_BY_DEFAULT = true;
382    
383            private static Log _log = LogFactoryUtil.getLog(
384                    JournalContentPortletDataHandlerImpl.class);
385    
386            private static PortletDataHandlerBoolean _embeddedAssets =
387                    new PortletDataHandlerBoolean(_NAMESPACE, "embedded-assets");
388    
389            private static PortletDataHandlerBoolean _selectedArticles =
390                    new PortletDataHandlerBoolean(
391                            _NAMESPACE, "selected-web-content", true, true);
392    
393    }