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.addPortletPermissions(
153                            JournalPermission.RESOURCE_NAME);
154    
155                    Element rootElement = addExportDataRootElement(portletDataContext);
156    
157                    rootElement.addAttribute(
158                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
159    
160                    if (portletDataContext.getBooleanParameter(NAMESPACE, "feeds")) {
161                            ActionableDynamicQuery feedActionableDynamicQuery =
162                                    new JournalFeedExportActionableDynamicQuery(portletDataContext);
163    
164                            feedActionableDynamicQuery.performActions();
165                    }
166    
167                    if (portletDataContext.getBooleanParameter(NAMESPACE, "structures")) {
168                            List<DDMTemplate> ddmTemplates = new ArrayList<DDMTemplate>();
169    
170                            ActionableDynamicQuery ddmStructureActionableDynamicQuery =
171                                    getDDMStructureActionableDynamicQuery(
172                                            portletDataContext, ddmTemplates, true);
173    
174                            ddmStructureActionableDynamicQuery.performActions();
175    
176                            // Export templates that belong to structures
177    
178                            for (DDMTemplate ddmTemplate : ddmTemplates) {
179                                    StagedModelDataHandlerUtil.exportStagedModel(
180                                            portletDataContext, ddmTemplate);
181                            }
182    
183                            // Export templates that do not belong to structures
184    
185                            ActionableDynamicQuery ddmTemplateActionableDynamicQuery =
186                                    getDDMTemplateActionableDynamicQuery(portletDataContext);
187    
188                            ddmTemplateActionableDynamicQuery.performActions();
189                    }
190    
191                    if (portletDataContext.getBooleanParameter(NAMESPACE, "web-content")) {
192                            ActionableDynamicQuery folderActionableDynamicQuery =
193                                    new JournalFolderExportActionableDynamicQuery(
194                                            portletDataContext);
195    
196                            folderActionableDynamicQuery.performActions();
197    
198                            ActionableDynamicQuery articleActionableDynamicQuery =
199                                    getArticleActionableDynamicQuery(portletDataContext);
200    
201                            articleActionableDynamicQuery.performActions();
202                    }
203    
204                    return getExportDataRootElementString(rootElement);
205            }
206    
207            @Override
208            protected PortletPreferences doImportData(
209                            PortletDataContext portletDataContext, String portletId,
210                            PortletPreferences portletPreferences, String data)
211                    throws Exception {
212    
213                    portletDataContext.importPortletPermissions(
214                            JournalPermission.RESOURCE_NAME);
215    
216                    if (portletDataContext.getBooleanParameter(NAMESPACE, "feeds")) {
217                            Element feedsElement = portletDataContext.getImportDataGroupElement(
218                                    JournalFeed.class);
219    
220                            List<Element> feedElements = feedsElement.elements();
221    
222                            for (Element feedElement : feedElements) {
223                                    StagedModelDataHandlerUtil.importStagedModel(
224                                            portletDataContext, feedElement);
225                            }
226                    }
227    
228                    if (portletDataContext.getBooleanParameter(NAMESPACE, "structures")) {
229                            Element ddmStructuresElement =
230                                    portletDataContext.getImportDataGroupElement(
231                                            DDMStructure.class);
232    
233                            List<Element> ddmStructureElements =
234                                    ddmStructuresElement.elements();
235    
236                            for (Element ddmStructureElement : ddmStructureElements) {
237                                    StagedModelDataHandlerUtil.importStagedModel(
238                                            portletDataContext, ddmStructureElement);
239                            }
240    
241                            Element ddmTemplatesElement =
242                                    portletDataContext.getImportDataGroupElement(DDMTemplate.class);
243    
244                            List<Element> ddmTemplateElements = ddmTemplatesElement.elements();
245    
246                            for (Element ddmTemplateElement : ddmTemplateElements) {
247                                    StagedModelDataHandlerUtil.importStagedModel(
248                                            portletDataContext, ddmTemplateElement);
249                            }
250                    }
251    
252                    if (!portletDataContext.getBooleanParameter(NAMESPACE, "web-content")) {
253                            return portletPreferences;
254                    }
255    
256                    Element foldersElement = portletDataContext.getImportDataGroupElement(
257                            JournalFolder.class);
258    
259                    List<Element> folderElements = foldersElement.elements();
260    
261                    for (Element folderElement : folderElements) {
262                            StagedModelDataHandlerUtil.importStagedModel(
263                                    portletDataContext, folderElement);
264                    }
265    
266                    Element articlesElement = portletDataContext.getImportDataGroupElement(
267                            JournalArticle.class);
268    
269                    List<Element> articleElements = articlesElement.elements();
270    
271                    for (Element articleElement : articleElements) {
272                            StagedModelDataHandlerUtil.importStagedModel(
273                                    portletDataContext, articleElement);
274                    }
275    
276                    return portletPreferences;
277            }
278    
279            @Override
280            protected void doPrepareManifestSummary(
281                            PortletDataContext portletDataContext,
282                            PortletPreferences portletPreferences)
283                    throws Exception {
284    
285                    ActionableDynamicQuery articleActionableDynamicQuery =
286                            getArticleActionableDynamicQuery(portletDataContext);
287    
288                    articleActionableDynamicQuery.performCount();
289    
290                    List<DDMTemplate> ddmTemplates = new ArrayList<DDMTemplate>();
291    
292                    ActionableDynamicQuery ddmStructureActionableDynamicQuery =
293                            getDDMStructureActionableDynamicQuery(
294                                    portletDataContext, ddmTemplates, false);
295    
296                    ddmStructureActionableDynamicQuery.performActions();
297    
298                    ddmStructureActionableDynamicQuery.performCount();
299    
300                    ManifestSummary manifestSummary =
301                            portletDataContext.getManifestSummary();
302    
303                    ActionableDynamicQuery ddmTemplateActionableDynamicQuery =
304                            getDDMTemplateActionableDynamicQuery(portletDataContext);
305    
306                    manifestSummary.addModelAdditionCount(
307                            new StagedModelType(DDMTemplate.class, DDMStructure.class),
308                            ddmTemplateActionableDynamicQuery.performCount() +
309                                    ddmTemplates.size());
310    
311                    ActionableDynamicQuery feedActionableDynamicQuery =
312                            new JournalFeedExportActionableDynamicQuery(portletDataContext);
313    
314                    feedActionableDynamicQuery.performCount();
315    
316                    ActionableDynamicQuery folderActionableDynamicQuery =
317                            new JournalFolderExportActionableDynamicQuery(portletDataContext);
318    
319                    folderActionableDynamicQuery.performCount();
320            }
321    
322            protected ActionableDynamicQuery getArticleActionableDynamicQuery(
323                            final PortletDataContext portletDataContext)
324                    throws SystemException {
325    
326                    return new JournalArticleExportActionableDynamicQuery(
327                            portletDataContext) {
328    
329                            @Override
330                            protected void performAction(Object object) throws PortalException {
331                                    JournalArticle article = (JournalArticle)object;
332    
333                                    boolean latestVersion = false;
334    
335                                    try {
336                                            latestVersion =
337                                                    JournalArticleLocalServiceUtil.isLatestVersion(
338                                                            article.getGroupId(), article.getArticleId(),
339                                                            article.getVersion(),
340                                                            WorkflowConstants.STATUS_APPROVED);
341                                    }
342                                    catch (Exception e) {
343                                    }
344    
345                                    if (portletDataContext.getBooleanParameter(
346                                                    NAMESPACE, "version-history") || latestVersion) {
347    
348                                            StagedModelDataHandlerUtil.exportStagedModel(
349                                                    portletDataContext, article);
350                                    }
351                            }
352    
353                    };
354            }
355    
356            protected ActionableDynamicQuery getDDMStructureActionableDynamicQuery(
357                            final PortletDataContext portletDataContext,
358                            final List<DDMTemplate> ddmTemplates, final boolean export)
359                    throws SystemException {
360    
361                    return new DDMStructureExportActionableDynamicQuery(
362                            portletDataContext) {
363    
364                            @Override
365                            protected void addCriteria(DynamicQuery dynamicQuery) {
366                                    super.addCriteria(dynamicQuery);
367    
368                                    Property classNameIdProperty = PropertyFactoryUtil.forName(
369                                            "classNameId");
370    
371                                    long classNameId = PortalUtil.getClassNameId(
372                                            JournalArticle.class);
373    
374                                    dynamicQuery.add(classNameIdProperty.eq(classNameId));
375                            }
376    
377                            @Override
378                            protected StagedModelType getStagedModelType() {
379                                    return new StagedModelType(
380                                            DDMStructure.class.getName(),
381                                            JournalArticle.class.getName());
382                            }
383    
384                            @Override
385                            protected void performAction(Object object) throws PortalException {
386                                    DDMStructure ddmStructure = (DDMStructure)object;
387    
388                                    if (export) {
389                                            StagedModelDataHandlerUtil.exportStagedModel(
390                                                    portletDataContext, ddmStructure);
391                                    }
392    
393                                    try {
394                                            ddmTemplates.addAll(ddmStructure.getTemplates());
395                                    }
396                                    catch (SystemException se) {
397                                    }
398                            }
399    
400                    };
401            }
402    
403            protected ActionableDynamicQuery getDDMTemplateActionableDynamicQuery(
404                            final PortletDataContext portletDataContext)
405                    throws SystemException {
406    
407                    return new DDMTemplateExportActionableDynamicQuery(
408                            portletDataContext) {
409    
410                            @Override
411                            protected void addCriteria(DynamicQuery dynamicQuery) {
412                                    super.addCriteria(dynamicQuery);
413    
414                                    Property classNameIdProperty = PropertyFactoryUtil.forName(
415                                            "classNameId");
416    
417                                    long classNameId = PortalUtil.getClassNameId(
418                                            DDMStructure.class);
419    
420                                    dynamicQuery.add(classNameIdProperty.eq(classNameId));
421    
422                                    Property classPKProperty = PropertyFactoryUtil.forName(
423                                            "classPK");
424    
425                                    dynamicQuery.add(classPKProperty.eq(-1L));
426                            }
427    
428                            @Override
429                            protected StagedModelType getStagedModelType() {
430                                    return new StagedModelType(
431                                            DDMTemplate.class.getName(), DDMStructure.class.getName());
432                            }
433    
434                    };
435            }
436    
437    }