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