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                            // Export DDM structure default values
192    
193                            ActionableDynamicQuery
194                                    ddmStructureDefaultValueActionableDynamicQuery =
195                                            getDDMStructureDefaultValuesActionableDynamicQuery(
196                                                    portletDataContext);
197    
198                            ddmStructureDefaultValueActionableDynamicQuery.performActions();
199                    }
200    
201                    if (portletDataContext.getBooleanParameter(NAMESPACE, "templates")) {
202                            ActionableDynamicQuery ddmTemplateActionableDynamicQuery =
203                                    getDDMTemplateActionableDynamicQuery(portletDataContext, true);
204    
205                            ddmTemplateActionableDynamicQuery.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                            // Importing DDM structure default values
271    
272                            for (Element articleElement : articleElements) {
273                                    String className = articleElement.attributeValue("class-name");
274    
275                                    if (Validator.isNotNull(className) &&
276                                            className.equals(DDMStructure.class.getName())) {
277    
278                                            StagedModelDataHandlerUtil.importStagedModel(
279                                                    portletDataContext, articleElement);
280                                    }
281                            }
282                    }
283    
284                    if (portletDataContext.getBooleanParameter(NAMESPACE, "templates")) {
285                            Element ddmTemplatesElement =
286                                    portletDataContext.getImportDataGroupElement(DDMTemplate.class);
287    
288                            List<Element> ddmTemplateElements = ddmTemplatesElement.elements();
289    
290                            for (Element ddmTemplateElement : ddmTemplateElements) {
291                                    StagedModelDataHandlerUtil.importStagedModel(
292                                            portletDataContext, ddmTemplateElement);
293                            }
294                    }
295    
296                    if (portletDataContext.getBooleanParameter(NAMESPACE, "web-content")) {
297                            for (Element articleElement : articleElements) {
298                                    StagedModelDataHandlerUtil.importStagedModel(
299                                            portletDataContext, articleElement);
300                            }
301                    }
302    
303                    return portletPreferences;
304            }
305    
306            @Override
307            protected void doPrepareManifestSummary(
308                            PortletDataContext portletDataContext,
309                            PortletPreferences portletPreferences)
310                    throws Exception {
311    
312                    ActionableDynamicQuery articleActionableDynamicQuery =
313                            getArticleActionableDynamicQuery(portletDataContext);
314    
315                    articleActionableDynamicQuery.performCount();
316    
317                    ActionableDynamicQuery ddmStructureActionableDynamicQuery =
318                            getDDMStructureActionableDynamicQuery(portletDataContext, false);
319    
320                    ddmStructureActionableDynamicQuery.performActions();
321    
322                    ddmStructureActionableDynamicQuery.performCount();
323    
324                    ActionableDynamicQuery ddmTemplateActionableDynamicQuery =
325                            getDDMTemplateActionableDynamicQuery(portletDataContext, false);
326    
327                    ddmTemplateActionableDynamicQuery.performActions();
328    
329                    ddmTemplateActionableDynamicQuery.performCount();
330    
331                    ActionableDynamicQuery feedActionableDynamicQuery =
332                            new JournalFeedExportActionableDynamicQuery(portletDataContext);
333    
334                    feedActionableDynamicQuery.performCount();
335    
336                    ActionableDynamicQuery folderActionableDynamicQuery =
337                            new JournalFolderExportActionableDynamicQuery(portletDataContext);
338    
339                    folderActionableDynamicQuery.performCount();
340            }
341    
342            protected ActionableDynamicQuery getArticleActionableDynamicQuery(
343                            final PortletDataContext portletDataContext)
344                    throws SystemException {
345    
346                    return new JournalArticleExportActionableDynamicQuery(
347                            portletDataContext) {
348    
349                                    @Override
350                                    protected void addOrderCriteria(DynamicQuery dynamicQuery) {
351                                            if (portletDataContext.getBooleanParameter(
352                                                            NAMESPACE, "version-history")) {
353    
354                                                    dynamicQuery.addOrder(OrderFactoryUtil.asc("id"));
355                                            }
356                                    }
357    
358                                    @Override
359                                    public void addCriteria(DynamicQuery dynamicQuery) {
360                                            super.addCriteria(dynamicQuery);
361    
362                                            if (portletDataContext.getBooleanParameter(
363                                                            NAMESPACE, "version-history")) {
364    
365                                                    return;
366                                            }
367    
368                                            DynamicQuery articleVersionDynamicQuery =
369                                                    DynamicQueryFactoryUtil.forClass(
370                                                            JournalArticle.class, "articleVersion",
371                                                            PortalClassLoaderUtil.getClassLoader());
372    
373                                            articleVersionDynamicQuery.setProjection(
374                                                    ProjectionFactoryUtil.alias(
375                                                            ProjectionFactoryUtil.max("articleVersion.version"),
376                                                            "articleVersion.version"));
377    
378                                            // We need to use the "this" default alias to make sure the
379                                            // database engine handles this subquery as a correlated
380                                            // subquery
381    
382                                            articleVersionDynamicQuery.add(
383                                                    RestrictionsFactoryUtil.eqProperty(
384                                                            "this.resourcePrimKey",
385                                                            "articleVersion.resourcePrimKey"));
386    
387                                            Property versionProperty = PropertyFactoryUtil.forName(
388                                                    "version");
389    
390                                            dynamicQuery.add(
391                                                    versionProperty.eq(articleVersionDynamicQuery));
392                                    }
393    
394                    };
395            }
396    
397            protected ActionableDynamicQuery getDDMStructureActionableDynamicQuery(
398                            final PortletDataContext portletDataContext, final boolean export)
399                    throws SystemException {
400    
401                    return new DDMStructureExportActionableDynamicQuery(
402                            portletDataContext) {
403    
404                            @Override
405                            protected void addCriteria(DynamicQuery dynamicQuery) {
406                                    super.addCriteria(dynamicQuery);
407    
408                                    Property classNameIdProperty = PropertyFactoryUtil.forName(
409                                            "classNameId");
410    
411                                    long classNameId = PortalUtil.getClassNameId(
412                                            JournalArticle.class);
413    
414                                    dynamicQuery.add(classNameIdProperty.eq(classNameId));
415                            }
416    
417                            @Override
418                            protected StagedModelType getStagedModelType() {
419                                    return new StagedModelType(
420                                            DDMStructure.class.getName(),
421                                            JournalArticle.class.getName());
422                            }
423    
424                            @Override
425                            protected void performAction(Object object) throws PortalException {
426                                    DDMStructure ddmStructure = (DDMStructure)object;
427    
428                                    if (export) {
429                                            StagedModelDataHandlerUtil.exportStagedModel(
430                                                    portletDataContext, ddmStructure);
431                                    }
432                            }
433    
434                    };
435            }
436    
437            protected ActionableDynamicQuery
438                    getDDMStructureDefaultValuesActionableDynamicQuery(
439                                    final PortletDataContext portletDataContext)
440                            throws SystemException {
441    
442                    return new JournalArticleExportActionableDynamicQuery(
443                            portletDataContext) {
444    
445                            @Override
446                            protected StagedModelType getStagedModelType() {
447                                    return new StagedModelType(
448                                            JournalArticle.class.getName(),
449                                            DDMStructure.class.getName());
450                            }
451    
452                    };
453            }
454    
455            /**
456             * @deprecated As of 7.0.0, replaced by {@link
457             * #getDDMTemplateActionableDynamicQuery(PortletDataContext,
458             * List, boolean)}
459             */
460            protected ActionableDynamicQuery getDDMTemplateActionableDynamicQuery(
461                            final PortletDataContext portletDataContext)
462                    throws SystemException {
463    
464                    return getDDMTemplateActionableDynamicQuery(portletDataContext, false);
465            }
466    
467            protected ActionableDynamicQuery getDDMTemplateActionableDynamicQuery(
468                            final PortletDataContext portletDataContext, final boolean export)
469                    throws SystemException {
470    
471                    return new DDMTemplateExportActionableDynamicQuery(
472                            portletDataContext) {
473    
474                            @Override
475                            protected void addCriteria(DynamicQuery dynamicQuery) {
476                                    super.addCriteria(dynamicQuery);
477    
478                                    Property classNameIdProperty = PropertyFactoryUtil.forName(
479                                            "classNameId");
480    
481                                    long classNameId = PortalUtil.getClassNameId(
482                                            DDMStructure.class);
483    
484                                    dynamicQuery.add(classNameIdProperty.eq(classNameId));
485                            }
486    
487                            @Override
488                            protected StagedModelType getStagedModelType() {
489                                    return new StagedModelType(
490                                            DDMTemplate.class.getName(), DDMStructure.class.getName());
491                            }
492    
493                            @Override
494                            public void performAction(Object object) throws PortalException {
495                                    DDMTemplate ddmTemplate = (DDMTemplate)object;
496    
497                                    if (ddmTemplate.getClassPK() != 0) {
498                                            try {
499                                                    DDMStructure ddmStructure =
500                                                            DDMStructureLocalServiceUtil.fetchDDMStructure(
501                                                                    ddmTemplate.getClassPK());
502    
503                                                    long classNameId = PortalUtil.getClassNameId(
504                                                            JournalArticle.class);
505    
506                                                    if ((ddmStructure != null) &&
507                                                            (ddmStructure.getClassNameId() != classNameId)) {
508    
509                                                            return;
510                                                    }
511                                            }
512                                            catch (SystemException e) {
513                                            }
514                                    }
515    
516                                    if (export) {
517                                            StagedModelDataHandlerUtil.exportStagedModel(
518                                                    portletDataContext, ddmTemplate);
519                                    }
520                            }
521    
522                    };
523            }
524    
525    }