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