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.OrderFactoryUtil;
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.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.util.Validator;
035    import com.liferay.portal.kernel.xml.Element;
036    import com.liferay.portal.util.PortalUtil;
037    import com.liferay.portal.util.PropsValues;
038    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
039    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
040    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
041    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
042    import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMStructureExportActionableDynamicQuery;
043    import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMTemplateExportActionableDynamicQuery;
044    import com.liferay.portlet.journal.model.JournalArticle;
045    import com.liferay.portlet.journal.model.JournalFeed;
046    import com.liferay.portlet.journal.model.JournalFolder;
047    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
048    import com.liferay.portlet.journal.service.JournalFolderLocalServiceUtil;
049    import com.liferay.portlet.journal.service.permission.JournalPermission;
050    import com.liferay.portlet.journal.service.persistence.JournalArticleExportActionableDynamicQuery;
051    import com.liferay.portlet.journal.service.persistence.JournalFeedExportActionableDynamicQuery;
052    import com.liferay.portlet.journal.service.persistence.JournalFolderExportActionableDynamicQuery;
053    
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(JournalArticle.class, DDMStructure.class),
100                            new StagedModelType(JournalFeed.class),
101                            new StagedModelType(JournalFolder.class));
102                    setExportControls(
103                            new PortletDataHandlerBoolean(
104                                    NAMESPACE, "web-content", true, false,
105                                    new PortletDataHandlerControl[] {
106                                            new PortletDataHandlerBoolean(
107                                                    NAMESPACE, "referenced-content"),
108                                            new PortletDataHandlerBoolean(
109                                                    NAMESPACE, "version-history",
110                                                    PropsValues.JOURNAL_PUBLISH_VERSION_HISTORY_BY_DEFAULT)
111                                    },
112                                    JournalArticle.class.getName()),
113                            new PortletDataHandlerBoolean(
114                                    NAMESPACE, "structures", true, false, null,
115                                    DDMStructure.class.getName(), JournalArticle.class.getName()),
116                            new PortletDataHandlerBoolean(
117                                    NAMESPACE, "templates", true, false, null,
118                                    DDMTemplate.class.getName(), DDMStructure.class.getName()),
119                            new PortletDataHandlerBoolean(
120                                    NAMESPACE, "feeds", true, false, null,
121                                    JournalFeed.class.getName()),
122                            new PortletDataHandlerBoolean(
123                                    NAMESPACE, "folders", true, false, null,
124                                    JournalFolder.class.getName()));
125                    setPublishToLiveByDefault(
126                            PropsValues.JOURNAL_PUBLISH_TO_LIVE_BY_DEFAULT);
127            }
128    
129            @Override
130            protected PortletPreferences doDeleteData(
131                            PortletDataContext portletDataContext, String portletId,
132                            PortletPreferences portletPreferences)
133                    throws Exception {
134    
135                    if (portletDataContext.addPrimaryKey(
136                                    JournalPortletDataHandler.class, "deleteData")) {
137    
138                            return portletPreferences;
139                    }
140    
141                    JournalArticleLocalServiceUtil.deleteArticles(
142                            portletDataContext.getScopeGroupId());
143    
144                    JournalFolderLocalServiceUtil.deleteFolders(
145                            portletDataContext.getGroupId());
146    
147                    DDMTemplateLocalServiceUtil.deleteTemplates(
148                            portletDataContext.getScopeGroupId());
149    
150                    DDMStructureLocalServiceUtil.deleteStructures(
151                            portletDataContext.getScopeGroupId());
152    
153                    return portletPreferences;
154            }
155    
156            @Override
157            protected String doExportData(
158                            final PortletDataContext portletDataContext, String portletId,
159                            PortletPreferences portletPreferences)
160                    throws Exception {
161    
162                    portletDataContext.addPortletPermissions(
163                            JournalPermission.RESOURCE_NAME);
164    
165                    Element rootElement = addExportDataRootElement(portletDataContext);
166    
167                    rootElement.addAttribute(
168                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
169    
170                    if (portletDataContext.getBooleanParameter(NAMESPACE, "feeds")) {
171                            ActionableDynamicQuery feedActionableDynamicQuery =
172                                    new JournalFeedExportActionableDynamicQuery(portletDataContext);
173    
174                            feedActionableDynamicQuery.performActions();
175                    }
176    
177                    if (portletDataContext.getBooleanParameter(NAMESPACE, "folders")) {
178                            ActionableDynamicQuery folderActionableDynamicQuery =
179                                    new JournalFolderExportActionableDynamicQuery(
180                                            portletDataContext);
181    
182                            folderActionableDynamicQuery.performActions();
183                    }
184    
185                    if (portletDataContext.getBooleanParameter(NAMESPACE, "structures")) {
186                            ActionableDynamicQuery ddmStructureActionableDynamicQuery =
187                                    getDDMStructureActionableDynamicQuery(portletDataContext, true);
188    
189                            ddmStructureActionableDynamicQuery.performActions();
190                    }
191    
192                    if (portletDataContext.getBooleanParameter(NAMESPACE, "templates")) {
193                            ActionableDynamicQuery ddmTemplateActionableDynamicQuery =
194                                    getDDMTemplateActionableDynamicQuery(portletDataContext, true);
195    
196                            ddmTemplateActionableDynamicQuery.performActions();
197    
198                            // Export DDM structure default values
199    
200                            ActionableDynamicQuery
201                                    ddmStructureDefaultValuesActionableDynamicQuery =
202                                            getDDMStructureDefaultValuesActionableDynamicQuery(
203                                                    portletDataContext);
204    
205                            ddmStructureDefaultValuesActionableDynamicQuery.performActions();
206                    }
207    
208                    if (portletDataContext.getBooleanParameter(NAMESPACE, "web-content")) {
209                            ActionableDynamicQuery articleActionableDynamicQuery =
210                                    getArticleActionableDynamicQuery(portletDataContext);
211    
212                            articleActionableDynamicQuery.performActions();
213                    }
214    
215                    return getExportDataRootElementString(rootElement);
216            }
217    
218            @Override
219            protected PortletPreferences doImportData(
220                            PortletDataContext portletDataContext, String portletId,
221                            PortletPreferences portletPreferences, String data)
222                    throws Exception {
223    
224                    portletDataContext.importPortletPermissions(
225                            JournalPermission.RESOURCE_NAME);
226    
227                    if (portletDataContext.getBooleanParameter(NAMESPACE, "feeds")) {
228                            Element feedsElement = portletDataContext.getImportDataGroupElement(
229                                    JournalFeed.class);
230    
231                            List<Element> feedElements = feedsElement.elements();
232    
233                            for (Element feedElement : feedElements) {
234                                    StagedModelDataHandlerUtil.importStagedModel(
235                                            portletDataContext, feedElement);
236                            }
237                    }
238    
239                    if (portletDataContext.getBooleanParameter(NAMESPACE, "folders")) {
240                            Element foldersElement =
241                                    portletDataContext.getImportDataGroupElement(
242                                            JournalFolder.class);
243    
244                            List<Element> folderElements = foldersElement.elements();
245    
246                            for (Element folderElement : folderElements) {
247                                    StagedModelDataHandlerUtil.importStagedModel(
248                                            portletDataContext, folderElement);
249                            }
250                    }
251    
252                    Element articlesElement = portletDataContext.getImportDataGroupElement(
253                            JournalArticle.class);
254    
255                    List<Element> articleElements = articlesElement.elements();
256    
257                    if (portletDataContext.getBooleanParameter(NAMESPACE, "structures")) {
258                            Element ddmStructuresElement =
259                                    portletDataContext.getImportDataGroupElement(
260                                            DDMStructure.class);
261    
262                            List<Element> ddmStructureElements =
263                                    ddmStructuresElement.elements();
264    
265                            for (Element ddmStructureElement : ddmStructureElements) {
266                                    StagedModelDataHandlerUtil.importStagedModel(
267                                            portletDataContext, ddmStructureElement);
268                            }
269                    }
270    
271                    if (portletDataContext.getBooleanParameter(NAMESPACE, "templates")) {
272    
273                            // Import DDM templates that belong to DDM structures
274    
275                            Element ddmTemplatesElement =
276                                    portletDataContext.getImportDataGroupElement(DDMTemplate.class);
277    
278                            List<Element> ddmTemplateElements = ddmTemplatesElement.elements();
279    
280                            for (Element ddmTemplateElement : ddmTemplateElements) {
281                                    StagedModelDataHandlerUtil.importStagedModel(
282                                            portletDataContext, ddmTemplateElement);
283                            }
284    
285                            // Importing DDM structure default values
286    
287                            for (Element articleElement : articleElements) {
288                                    String className = articleElement.attributeValue("class-name");
289    
290                                    if (Validator.isNotNull(className) &&
291                                            className.equals(DDMStructure.class.getName())) {
292    
293                                            StagedModelDataHandlerUtil.importStagedModel(
294                                                    portletDataContext, articleElement);
295                                    }
296                            }
297                    }
298    
299                    if (portletDataContext.getBooleanParameter(NAMESPACE, "web-content")) {
300                            for (Element articleElement : articleElements) {
301                                    StagedModelDataHandlerUtil.importStagedModel(
302                                            portletDataContext, articleElement);
303                            }
304                    }
305    
306                    return portletPreferences;
307            }
308    
309            @Override
310            protected void doPrepareManifestSummary(
311                            PortletDataContext portletDataContext,
312                            PortletPreferences portletPreferences)
313                    throws Exception {
314    
315                    ActionableDynamicQuery articleActionableDynamicQuery =
316                            getArticleActionableDynamicQuery(portletDataContext);
317    
318                    articleActionableDynamicQuery.performCount();
319    
320                    ActionableDynamicQuery ddmStructureActionableDynamicQuery =
321                            getDDMStructureActionableDynamicQuery(portletDataContext, false);
322    
323                    ddmStructureActionableDynamicQuery.performActions();
324    
325                    ddmStructureActionableDynamicQuery.performCount();
326    
327                    ActionableDynamicQuery ddmTemplateActionableDynamicQuery =
328                            getDDMTemplateActionableDynamicQuery(portletDataContext, false);
329    
330                    ddmTemplateActionableDynamicQuery.performActions();
331    
332                    ddmTemplateActionableDynamicQuery.performCount();
333    
334                    ActionableDynamicQuery feedActionableDynamicQuery =
335                            new JournalFeedExportActionableDynamicQuery(portletDataContext);
336    
337                    feedActionableDynamicQuery.performCount();
338    
339                    ActionableDynamicQuery folderActionableDynamicQuery =
340                            new JournalFolderExportActionableDynamicQuery(portletDataContext);
341    
342                    folderActionableDynamicQuery.performCount();
343            }
344    
345            protected ActionableDynamicQuery getArticleActionableDynamicQuery(
346                            final PortletDataContext portletDataContext)
347                    throws SystemException {
348    
349                    return new JournalArticleExportActionableDynamicQuery(
350                            portletDataContext) {
351    
352                                    @Override
353                                    protected void addOrderCriteria(DynamicQuery dynamicQuery) {
354                                            if (portletDataContext.getBooleanParameter(
355                                                            NAMESPACE, "version-history")) {
356    
357                                                    dynamicQuery.addOrder(OrderFactoryUtil.asc("id"));
358                                            }
359                                    }
360    
361                                    @Override
362                                    public void addCriteria(DynamicQuery dynamicQuery) {
363                                            super.addCriteria(dynamicQuery);
364    
365                                            if (portletDataContext.getBooleanParameter(
366                                                            NAMESPACE, "version-history")) {
367    
368                                                    return;
369                                            }
370    
371                                            DynamicQuery articleVersionDynamicQuery =
372                                                    DynamicQueryFactoryUtil.forClass(
373                                                            JournalArticle.class, "articleVersion",
374                                                            PortalClassLoaderUtil.getClassLoader());
375    
376                                            articleVersionDynamicQuery.setProjection(
377                                                    ProjectionFactoryUtil.alias(
378                                                            ProjectionFactoryUtil.max("articleVersion.version"),
379                                                            "articleVersion.version"));
380    
381                                            // We need to use the "this" default alias to make sure the
382                                            // database engine handles this subquery as a correlated
383                                            // subquery
384    
385                                            articleVersionDynamicQuery.add(
386                                                    RestrictionsFactoryUtil.eqProperty(
387                                                            "this.resourcePrimKey",
388                                                            "articleVersion.resourcePrimKey"));
389    
390                                            Property versionProperty = PropertyFactoryUtil.forName(
391                                                    "version");
392    
393                                            dynamicQuery.add(
394                                                    versionProperty.eq(articleVersionDynamicQuery));
395                                    }
396    
397                    };
398            }
399    
400            protected ActionableDynamicQuery getDDMStructureActionableDynamicQuery(
401                            final PortletDataContext portletDataContext, final boolean export)
402                    throws SystemException {
403    
404                    return new DDMStructureExportActionableDynamicQuery(
405                            portletDataContext) {
406    
407                            @Override
408                            protected void addCriteria(DynamicQuery dynamicQuery) {
409                                    super.addCriteria(dynamicQuery);
410    
411                                    Property classNameIdProperty = PropertyFactoryUtil.forName(
412                                            "classNameId");
413    
414                                    long classNameId = PortalUtil.getClassNameId(
415                                            JournalArticle.class);
416    
417                                    dynamicQuery.add(classNameIdProperty.eq(classNameId));
418                            }
419    
420                            @Override
421                            protected StagedModelType getStagedModelType() {
422                                    return new StagedModelType(
423                                            DDMStructure.class.getName(),
424                                            JournalArticle.class.getName());
425                            }
426    
427                            @Override
428                            protected void performAction(Object object) throws PortalException {
429                                    DDMStructure ddmStructure = (DDMStructure)object;
430    
431                                    if (export) {
432                                            StagedModelDataHandlerUtil.exportStagedModel(
433                                                    portletDataContext, ddmStructure);
434                                    }
435                            }
436    
437                    };
438            }
439    
440            protected ActionableDynamicQuery
441                    getDDMStructureDefaultValuesActionableDynamicQuery(
442                                    final PortletDataContext portletDataContext)
443                            throws SystemException {
444    
445                    return new JournalArticleExportActionableDynamicQuery(
446                            portletDataContext) {
447    
448                            @Override
449                            protected StagedModelType getStagedModelType() {
450                                    return new StagedModelType(
451                                            JournalArticle.class.getName(),
452                                            DDMStructure.class.getName());
453                            }
454    
455                    };
456            }
457    
458            /**
459             * @deprecated As of 7.0.0, replaced by {@link
460             * #getDDMTemplateActionableDynamicQuery(PortletDataContext,
461             * List, boolean)}
462             */
463            protected ActionableDynamicQuery getDDMTemplateActionableDynamicQuery(
464                            final PortletDataContext portletDataContext)
465                    throws SystemException {
466    
467                    return getDDMTemplateActionableDynamicQuery(portletDataContext, false);
468            }
469    
470            protected ActionableDynamicQuery getDDMTemplateActionableDynamicQuery(
471                            final PortletDataContext portletDataContext, final boolean export)
472                    throws SystemException {
473    
474                    return new DDMTemplateExportActionableDynamicQuery(
475                            portletDataContext) {
476    
477                            @Override
478                            protected void addCriteria(DynamicQuery dynamicQuery) {
479                                    super.addCriteria(dynamicQuery);
480    
481                                    Property classNameIdProperty = PropertyFactoryUtil.forName(
482                                            "classNameId");
483    
484                                    long classNameId = PortalUtil.getClassNameId(
485                                            DDMStructure.class);
486    
487                                    dynamicQuery.add(classNameIdProperty.eq(classNameId));
488                            }
489    
490                            @Override
491                            protected StagedModelType getStagedModelType() {
492                                    return new StagedModelType(
493                                            DDMTemplate.class.getName(), DDMStructure.class.getName());
494                            }
495    
496                            @Override
497                            public void performAction(Object object) throws PortalException {
498                                    DDMTemplate ddmTemplate = (DDMTemplate)object;
499    
500                                    if (ddmTemplate.getClassPK() != 0) {
501                                            try {
502                                                    DDMStructure ddmStructure =
503                                                            DDMStructureLocalServiceUtil.fetchDDMStructure(
504                                                                    ddmTemplate.getClassPK());
505    
506                                                    long classNameId = PortalUtil.getClassNameId(
507                                                            JournalArticle.class);
508    
509                                                    if ((ddmStructure != null) &&
510                                                            (ddmStructure.getClassNameId() != classNameId)) {
511    
512                                                            return;
513                                                    }
514                                            }
515                                            catch (SystemException e) {
516                                            }
517                                    }
518    
519                                    if (export) {
520                                            StagedModelDataHandlerUtil.exportStagedModel(
521                                                    portletDataContext, ddmTemplate);
522                                    }
523                            }
524    
525                    };
526            }
527    
528    }