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