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