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