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