001    /**
002     * Copyright (c) 2000-2013 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.dao.orm.ActionableDynamicQuery;
018    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
019    import com.liferay.portal.kernel.dao.orm.Property;
020    import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
021    import com.liferay.portal.kernel.exception.PortalException;
022    import com.liferay.portal.kernel.exception.SystemException;
023    import com.liferay.portal.kernel.lar.BasePortletDataHandler;
024    import com.liferay.portal.kernel.lar.ManifestSummary;
025    import com.liferay.portal.kernel.lar.PortletDataContext;
026    import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
027    import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
028    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
029    import com.liferay.portal.kernel.lar.StagedModelType;
030    import com.liferay.portal.kernel.workflow.WorkflowConstants;
031    import com.liferay.portal.kernel.xml.Element;
032    import com.liferay.portal.util.PortalUtil;
033    import com.liferay.portal.util.PropsValues;
034    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
035    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
036    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
037    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
038    import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMStructureExportActionableDynamicQuery;
039    import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMTemplateExportActionableDynamicQuery;
040    import com.liferay.portlet.journal.model.JournalArticle;
041    import com.liferay.portlet.journal.model.JournalFeed;
042    import com.liferay.portlet.journal.model.JournalFolder;
043    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
044    import com.liferay.portlet.journal.service.JournalFolderLocalServiceUtil;
045    import com.liferay.portlet.journal.service.permission.JournalPermission;
046    import com.liferay.portlet.journal.service.persistence.JournalArticleExportActionableDynamicQuery;
047    import com.liferay.portlet.journal.service.persistence.JournalFeedExportActionableDynamicQuery;
048    import com.liferay.portlet.journal.service.persistence.JournalFolderExportActionableDynamicQuery;
049    
050    import java.util.ArrayList;
051    import java.util.List;
052    
053    import javax.portlet.PortletPreferences;
054    
055    /**
056     * <p>
057     * Provides the Journal portlet export and import functionality, which is to
058     * clone all articles, structures, and templates associated with the layout's
059     * group. Upon import, new instances of the corresponding articles, structures,
060     * and templates are created or updated according to the DATA_MIRROW strategy
061     * The author of the newly created objects are determined by the
062     * JournalCreationStrategy class defined in <i>portal.properties</i>. That
063     * strategy also allows the text of the journal article to be modified prior to
064     * import.
065     * </p>
066     *
067     * <p>
068     * This <code>PortletDataHandler</code> differs from
069     * <code>JournalContentPortletDataHandlerImpl</code> in that it exports all
070     * articles owned by the group whether or not they are actually displayed in a
071     * portlet in the layout set.
072     * </p>
073     *
074     * @author Raymond Aug??
075     * @author Joel Kozikowski
076     * @author Brian Wing Shun Chan
077     * @author Bruno Farache
078     * @author Karthik Sudarshan
079     * @author Wesley Gong
080     * @author Hugo Huijser
081     * @author Daniel Kocsis
082     * @see    com.liferay.portal.kernel.lar.PortletDataHandler
083     * @see    com.liferay.portlet.journal.lar.JournalContentPortletDataHandler
084     * @see    com.liferay.portlet.journal.lar.JournalCreationStrategy
085     */
086    public class JournalPortletDataHandler extends BasePortletDataHandler {
087    
088            public static final String NAMESPACE = "journal";
089    
090            public JournalPortletDataHandler() {
091                    setDataLocalized(true);
092                    setDeletionSystemEventStagedModelTypes(
093                            new StagedModelType(DDMStructure.class, JournalArticle.class),
094                            new StagedModelType(DDMTemplate.class, DDMStructure.class),
095                            new StagedModelType(JournalArticle.class),
096                            new StagedModelType(JournalFeed.class),
097                            new StagedModelType(JournalFolder.class));
098                    setExportControls(
099                            new PortletDataHandlerBoolean(
100                                    NAMESPACE, "web-content", true, false,
101                                    new PortletDataHandlerControl[] {
102                                            new PortletDataHandlerBoolean(
103                                                    NAMESPACE, "referenced-content"),
104                                            new PortletDataHandlerBoolean(
105                                                    NAMESPACE, "version-history",
106                                                    PropsValues.JOURNAL_PUBLISH_VERSION_HISTORY_BY_DEFAULT)
107                                    },
108                                    JournalArticle.class.getName()),
109                            new PortletDataHandlerBoolean(
110                                    NAMESPACE, "structures", true, false, null,
111                                    DDMStructure.class.getName(), JournalArticle.class.getName()),
112                            new PortletDataHandlerBoolean(
113                                    NAMESPACE, "feeds", true, false, null,
114                                    JournalFeed.class.getName()));
115                    setPublishToLiveByDefault(
116                            PropsValues.JOURNAL_PUBLISH_TO_LIVE_BY_DEFAULT);
117            }
118    
119            @Override
120            protected PortletPreferences doDeleteData(
121                            PortletDataContext portletDataContext, String portletId,
122                            PortletPreferences portletPreferences)
123                    throws Exception {
124    
125                    if (portletDataContext.addPrimaryKey(
126                                    JournalPortletDataHandler.class, "deleteData")) {
127    
128                            return portletPreferences;
129                    }
130    
131                    JournalArticleLocalServiceUtil.deleteArticles(
132                            portletDataContext.getScopeGroupId());
133    
134                    JournalFolderLocalServiceUtil.deleteFolders(
135                            portletDataContext.getGroupId());
136    
137                    DDMTemplateLocalServiceUtil.deleteTemplates(
138                            portletDataContext.getScopeGroupId());
139    
140                    DDMStructureLocalServiceUtil.deleteStructures(
141                            portletDataContext.getScopeGroupId());
142    
143                    return portletPreferences;
144            }
145    
146            @Override
147            protected String doExportData(
148                            final PortletDataContext portletDataContext, String portletId,
149                            PortletPreferences portletPreferences)
150                    throws Exception {
151    
152                    portletDataContext.addPermissions(
153                            JournalPermission.RESOURCE_NAME,
154                            portletDataContext.getScopeGroupId());
155    
156                    Element rootElement = addExportDataRootElement(portletDataContext);
157    
158                    rootElement.addAttribute(
159                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
160    
161                    if (portletDataContext.getBooleanParameter(NAMESPACE, "feeds")) {
162                            ActionableDynamicQuery feedActionableDynamicQuery =
163                                    new JournalFeedExportActionableDynamicQuery(portletDataContext);
164    
165                            feedActionableDynamicQuery.performActions();
166                    }
167    
168                    if (portletDataContext.getBooleanParameter(NAMESPACE, "structures")) {
169                            List<DDMTemplate> ddmTemplates = new ArrayList<DDMTemplate>();
170    
171                            ActionableDynamicQuery ddmStructureActionableDynamicQuery =
172                                    getDDMStructureActionableDynamicQuery(
173                                            portletDataContext, ddmTemplates, true);
174    
175                            ddmStructureActionableDynamicQuery.performActions();
176    
177                            // Export templates that belong to structures
178    
179                            for (DDMTemplate ddmTemplate : ddmTemplates) {
180                                    StagedModelDataHandlerUtil.exportStagedModel(
181                                            portletDataContext, ddmTemplate);
182                            }
183    
184                            // Export templates that do not belong to structures
185    
186                            ActionableDynamicQuery ddmTemplateActionableDynamicQuery =
187                                    getDDMTemplateActionableDynamicQuery(portletDataContext);
188    
189                            ddmTemplateActionableDynamicQuery.performActions();
190                    }
191    
192                    if (portletDataContext.getBooleanParameter(NAMESPACE, "web-content")) {
193                            ActionableDynamicQuery folderActionableDynamicQuery =
194                                    new JournalFolderExportActionableDynamicQuery(
195                                            portletDataContext);
196    
197                            folderActionableDynamicQuery.performActions();
198    
199                            ActionableDynamicQuery articleActionableDynamicQuery =
200                                    getArticleActionableDynamicQuery(portletDataContext);
201    
202                            articleActionableDynamicQuery.performActions();
203                    }
204    
205                    return getExportDataRootElementString(rootElement);
206            }
207    
208            @Override
209            protected PortletPreferences doImportData(
210                            PortletDataContext portletDataContext, String portletId,
211                            PortletPreferences portletPreferences, String data)
212                    throws Exception {
213    
214                    portletDataContext.importPermissions(
215                            JournalPermission.RESOURCE_NAME,
216                            portletDataContext.getSourceGroupId(),
217                            portletDataContext.getScopeGroupId());
218    
219                    if (portletDataContext.getBooleanParameter(NAMESPACE, "feeds")) {
220                            Element feedsElement = portletDataContext.getImportDataGroupElement(
221                                    JournalFeed.class);
222    
223                            List<Element> feedElements = feedsElement.elements();
224    
225                            for (Element feedElement : feedElements) {
226                                    StagedModelDataHandlerUtil.importStagedModel(
227                                            portletDataContext, feedElement);
228                            }
229                    }
230    
231                    if (portletDataContext.getBooleanParameter(NAMESPACE, "structures")) {
232                            Element ddmStructuresElement =
233                                    portletDataContext.getImportDataGroupElement(
234                                            DDMStructure.class);
235    
236                            List<Element> ddmStructureElements =
237                                    ddmStructuresElement.elements();
238    
239                            for (Element ddmStructureElement : ddmStructureElements) {
240                                    StagedModelDataHandlerUtil.importStagedModel(
241                                            portletDataContext, ddmStructureElement);
242                            }
243    
244                            Element ddmTemplatesElement =
245                                    portletDataContext.getImportDataGroupElement(DDMTemplate.class);
246    
247                            List<Element> ddmTemplateElements = ddmTemplatesElement.elements();
248    
249                            for (Element ddmTemplateElement : ddmTemplateElements) {
250                                    StagedModelDataHandlerUtil.importStagedModel(
251                                            portletDataContext, ddmTemplateElement);
252                            }
253                    }
254    
255                    if (!portletDataContext.getBooleanParameter(NAMESPACE, "web-content")) {
256                            return portletPreferences;
257                    }
258    
259                    Element foldersElement = portletDataContext.getImportDataGroupElement(
260                            JournalFolder.class);
261    
262                    List<Element> folderElements = foldersElement.elements();
263    
264                    for (Element folderElement : folderElements) {
265                            StagedModelDataHandlerUtil.importStagedModel(
266                                    portletDataContext, folderElement);
267                    }
268    
269                    Element articlesElement = portletDataContext.getImportDataGroupElement(
270                            JournalArticle.class);
271    
272                    List<Element> articleElements = articlesElement.elements();
273    
274                    for (Element articleElement : articleElements) {
275                            StagedModelDataHandlerUtil.importStagedModel(
276                                    portletDataContext, articleElement);
277                    }
278    
279                    return portletPreferences;
280            }
281    
282            @Override
283            protected void doPrepareManifestSummary(
284                            PortletDataContext portletDataContext,
285                            PortletPreferences portletPreferences)
286                    throws Exception {
287    
288                    ActionableDynamicQuery articleActionableDynamicQuery =
289                            getArticleActionableDynamicQuery(portletDataContext);
290    
291                    articleActionableDynamicQuery.performCount();
292    
293                    List<DDMTemplate> ddmTemplates = new ArrayList<DDMTemplate>();
294    
295                    ActionableDynamicQuery ddmStructureActionableDynamicQuery =
296                            getDDMStructureActionableDynamicQuery(
297                                    portletDataContext, ddmTemplates, false);
298    
299                    ddmStructureActionableDynamicQuery.performActions();
300    
301                    ddmStructureActionableDynamicQuery.performCount();
302    
303                    ManifestSummary manifestSummary =
304                            portletDataContext.getManifestSummary();
305    
306                    ActionableDynamicQuery ddmTemplateActionableDynamicQuery =
307                            getDDMTemplateActionableDynamicQuery(portletDataContext);
308    
309                    manifestSummary.addModelAdditionCount(
310                            new StagedModelType(DDMTemplate.class, DDMStructure.class),
311                            ddmTemplateActionableDynamicQuery.performCount() +
312                                    ddmTemplates.size());
313    
314                    ActionableDynamicQuery feedActionableDynamicQuery =
315                            new JournalFeedExportActionableDynamicQuery(portletDataContext);
316    
317                    feedActionableDynamicQuery.performCount();
318    
319                    ActionableDynamicQuery folderActionableDynamicQuery =
320                            new JournalFolderExportActionableDynamicQuery(portletDataContext);
321    
322                    folderActionableDynamicQuery.performCount();
323            }
324    
325            protected ActionableDynamicQuery getArticleActionableDynamicQuery(
326                            final PortletDataContext portletDataContext)
327                    throws SystemException {
328    
329                    return new JournalArticleExportActionableDynamicQuery(
330                            portletDataContext) {
331    
332                            @Override
333                            protected void performAction(Object object) throws PortalException {
334                                    JournalArticle article = (JournalArticle)object;
335    
336                                    boolean latestVersion = false;
337    
338                                    try {
339                                            latestVersion =
340                                                    JournalArticleLocalServiceUtil.isLatestVersion(
341                                                            article.getGroupId(), article.getArticleId(),
342                                                            article.getVersion(),
343                                                            WorkflowConstants.STATUS_APPROVED);
344                                    }
345                                    catch (Exception e) {
346                                    }
347    
348                                    if (portletDataContext.getBooleanParameter(
349                                                    NAMESPACE, "version-history") || latestVersion) {
350    
351                                            StagedModelDataHandlerUtil.exportStagedModel(
352                                                    portletDataContext, article);
353                                    }
354                            }
355    
356                    };
357            }
358    
359            protected ActionableDynamicQuery getDDMStructureActionableDynamicQuery(
360                            final PortletDataContext portletDataContext,
361                            final List<DDMTemplate> ddmTemplates, final boolean export)
362                    throws SystemException {
363    
364                    return new DDMStructureExportActionableDynamicQuery(
365                            portletDataContext) {
366    
367                            @Override
368                            protected void addCriteria(DynamicQuery dynamicQuery) {
369                                    super.addCriteria(dynamicQuery);
370    
371                                    Property classNameIdProperty = PropertyFactoryUtil.forName(
372                                            "classNameId");
373    
374                                    long classNameId = PortalUtil.getClassNameId(
375                                            JournalArticle.class);
376    
377                                    dynamicQuery.add(classNameIdProperty.eq(classNameId));
378                            }
379    
380                            @Override
381                            protected StagedModelType getStagedModelType() {
382                                    return new StagedModelType(
383                                            DDMStructure.class.getName(),
384                                            JournalArticle.class.getName());
385                            }
386    
387                            @Override
388                            protected void performAction(Object object) throws PortalException {
389                                    DDMStructure ddmStructure = (DDMStructure)object;
390    
391                                    if (export) {
392                                            StagedModelDataHandlerUtil.exportStagedModel(
393                                                    portletDataContext, ddmStructure);
394                                    }
395    
396                                    try {
397                                            ddmTemplates.addAll(ddmStructure.getTemplates());
398                                    }
399                                    catch (SystemException se) {
400                                    }
401                            }
402    
403                    };
404            }
405    
406            protected ActionableDynamicQuery getDDMTemplateActionableDynamicQuery(
407                            final PortletDataContext portletDataContext)
408                    throws SystemException {
409    
410                    return new DDMTemplateExportActionableDynamicQuery(
411                            portletDataContext) {
412    
413                            @Override
414                            protected void addCriteria(DynamicQuery dynamicQuery) {
415                                    super.addCriteria(dynamicQuery);
416    
417                                    Property classNameIdProperty = PropertyFactoryUtil.forName(
418                                            "classNameId");
419    
420                                    long classNameId = PortalUtil.getClassNameId(
421                                            DDMStructure.class);
422    
423                                    dynamicQuery.add(classNameIdProperty.eq(classNameId));
424    
425                                    Property classPKProperty = PropertyFactoryUtil.forName(
426                                            "classPK");
427    
428                                    dynamicQuery.add(classPKProperty.eq(-1L));
429                            }
430    
431                            @Override
432                            protected StagedModelType getStagedModelType() {
433                                    return new StagedModelType(
434                                            DDMTemplate.class.getName(), DDMStructure.class.getName());
435                            }
436    
437                    };
438            }
439    
440    }