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