001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.journal.lar;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.lar.BaseStagedModelDataHandler;
020    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
021    import com.liferay.portal.kernel.lar.PortletDataContext;
022    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
023    import com.liferay.portal.kernel.log.Log;
024    import com.liferay.portal.kernel.log.LogFactoryUtil;
025    import com.liferay.portal.kernel.util.GetterUtil;
026    import com.liferay.portal.kernel.util.MapUtil;
027    import com.liferay.portal.kernel.util.StringBundler;
028    import com.liferay.portal.kernel.util.StringPool;
029    import com.liferay.portal.kernel.util.StringUtil;
030    import com.liferay.portal.kernel.util.Validator;
031    import com.liferay.portal.kernel.xml.Element;
032    import com.liferay.portal.model.Group;
033    import com.liferay.portal.service.GroupLocalServiceUtil;
034    import com.liferay.portal.service.ServiceContext;
035    import com.liferay.portal.util.PortalUtil;
036    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
037    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
038    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
039    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
040    import com.liferay.portlet.journal.FeedTargetLayoutFriendlyUrlException;
041    import com.liferay.portlet.journal.model.JournalArticle;
042    import com.liferay.portlet.journal.model.JournalFeed;
043    import com.liferay.portlet.journal.service.JournalFeedLocalServiceUtil;
044    
045    import java.util.List;
046    import java.util.Map;
047    
048    /**
049     * @author Daniel Kocsis
050     */
051    public class JournalFeedStagedModelDataHandler
052            extends BaseStagedModelDataHandler<JournalFeed> {
053    
054            public static final String[] CLASS_NAMES = {JournalFeed.class.getName()};
055    
056            @Override
057            public void deleteStagedModel(
058                            String uuid, long groupId, String className, String extraData)
059                    throws PortalException, SystemException {
060    
061                    JournalFeed feed =
062                            JournalFeedLocalServiceUtil.fetchJournalFeedByUuidAndGroupId(
063                                    uuid, groupId);
064    
065                    if (feed != null) {
066                            JournalFeedLocalServiceUtil.deleteFeed(feed);
067                    }
068            }
069    
070            @Override
071            public String[] getClassNames() {
072                    return CLASS_NAMES;
073            }
074    
075            @Override
076            protected void doExportStagedModel(
077                            PortletDataContext portletDataContext, JournalFeed feed)
078                    throws Exception {
079    
080                    Element feedElement = portletDataContext.getExportDataElement(feed);
081    
082                    DDMStructure ddmStructure = DDMStructureLocalServiceUtil.fetchStructure(
083                            feed.getGroupId(), PortalUtil.getClassNameId(JournalArticle.class),
084                            feed.getStructureId(), true);
085    
086                    if (ddmStructure != null) {
087                            StagedModelDataHandlerUtil.exportStagedModel(
088                                    portletDataContext, ddmStructure);
089    
090                            portletDataContext.addReferenceElement(
091                                    feed, feedElement, ddmStructure,
092                                    PortletDataContext.REFERENCE_TYPE_STRONG, false);
093                    }
094                    else {
095                            if (_log.isWarnEnabled()) {
096                                    _log.warn(
097                                            "Unable to find DDM structure with key " +
098                                                    feed.getStructureId());
099                            }
100                    }
101    
102                    DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.fetchTemplate(
103                            feed.getGroupId(), PortalUtil.getClassNameId(DDMStructure.class),
104                            feed.getTemplateId());
105    
106                    if (ddmTemplate != null) {
107                            StagedModelDataHandlerUtil.exportStagedModel(
108                                    portletDataContext, ddmTemplate);
109    
110                            portletDataContext.addReferenceElement(
111                                    feed, feedElement, ddmTemplate,
112                                    PortletDataContext.REFERENCE_TYPE_STRONG, false);
113                    }
114                    else {
115                            if (_log.isWarnEnabled()) {
116                                    _log.warn(
117                                            "Unable to find DDM template with key " +
118                                                    feed.getTemplateId());
119                            }
120                    }
121    
122                    DDMTemplate rendererDDMTemplate =
123                            DDMTemplateLocalServiceUtil.fetchTemplate(
124                                    feed.getGroupId(),
125                                    PortalUtil.getClassNameId(DDMStructure.class),
126                                    feed.getRendererTemplateId());
127    
128                    if (rendererDDMTemplate != null) {
129                            StagedModelDataHandlerUtil.exportStagedModel(
130                                    portletDataContext, rendererDDMTemplate);
131    
132                            Element rendererDDMTemplateElement =
133                                    portletDataContext.addReferenceElement(
134                                            feed, feedElement, rendererDDMTemplate,
135                                            PortletDataContext.REFERENCE_TYPE_STRONG, false);
136    
137                            rendererDDMTemplateElement.addAttribute(
138                                    "rendererDDMTemplate", "true");
139                    }
140                    else {
141                            if (_log.isWarnEnabled()) {
142                                    _log.warn(
143                                            "Unable to find DDM template with key " +
144                                                    feed.getRendererTemplateId());
145                            }
146                    }
147    
148                    Group group = GroupLocalServiceUtil.getGroup(
149                            portletDataContext.getScopeGroupId());
150    
151                    String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
152    
153                    String[] friendlyURLParts = StringUtil.split(
154                            feed.getTargetLayoutFriendlyUrl(), '/');
155    
156                    String oldGroupFriendlyURL = friendlyURLParts[2];
157    
158                    if (newGroupFriendlyURL.equals(oldGroupFriendlyURL)) {
159                            String targetLayoutFriendlyUrl = StringUtil.replaceFirst(
160                                    feed.getTargetLayoutFriendlyUrl(),
161                                    StringPool.SLASH + newGroupFriendlyURL + StringPool.SLASH,
162                                    "/@data_handler_group_friendly_url@/");
163    
164                            feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
165                    }
166    
167                    portletDataContext.addClassedModel(
168                            feedElement, ExportImportPathUtil.getModelPath(feed), feed,
169                            JournalPortletDataHandler.NAMESPACE);
170            }
171    
172            @Override
173            protected void doImportStagedModel(
174                            PortletDataContext portletDataContext, JournalFeed feed)
175                    throws Exception {
176    
177                    long userId = portletDataContext.getUserId(feed.getUserUuid());
178    
179                    JournalCreationStrategy creationStrategy =
180                            JournalCreationStrategyFactory.getInstance();
181    
182                    long authorId = creationStrategy.getAuthorUserId(
183                            portletDataContext, feed);
184    
185                    if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
186                            userId = authorId;
187                    }
188    
189                    Group group = GroupLocalServiceUtil.getGroup(
190                            portletDataContext.getScopeGroupId());
191    
192                    String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
193    
194                    String[] friendlyURLParts = StringUtil.split(
195                            feed.getTargetLayoutFriendlyUrl(), '/');
196    
197                    String oldGroupFriendlyURL = friendlyURLParts[2];
198    
199                    if (oldGroupFriendlyURL.equals("@data_handler_group_friendly_url@")) {
200                            feed.setTargetLayoutFriendlyUrl(
201                                    StringUtil.replace(
202                                            feed.getTargetLayoutFriendlyUrl(),
203                                            "@data_handler_group_friendly_url@", newGroupFriendlyURL));
204                    }
205    
206                    String feedId = feed.getFeedId();
207    
208                    boolean autoFeedId = false;
209    
210                    if (Validator.isNumber(feedId) ||
211                            (JournalFeedLocalServiceUtil.fetchFeed(
212                                    portletDataContext.getScopeGroupId(), feedId) != null)) {
213    
214                            autoFeedId = true;
215                    }
216    
217                    List<Element> ddmStructureElements =
218                            portletDataContext.getReferenceDataElements(
219                                    feed, DDMStructure.class);
220    
221                    String parentDDMStructureKey = StringPool.BLANK;
222    
223                    if (!ddmStructureElements.isEmpty()) {
224                            Element ddmStructureElement = ddmStructureElements.get(0);
225    
226                            String ddmStructurePath = ddmStructureElement.attributeValue(
227                                    "path");
228    
229                            DDMStructure ddmStructure =
230                                    (DDMStructure)portletDataContext.getZipEntryAsObject(
231                                            ddmStructurePath);
232    
233                            StagedModelDataHandlerUtil.importStagedModel(
234                                    portletDataContext, ddmStructure);
235    
236                            Map<String, String> ddmStructureKeys =
237                                    (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
238                                            DDMStructure.class + ".ddmStructureKey");
239    
240                            parentDDMStructureKey = MapUtil.getString(
241                                    ddmStructureKeys, ddmStructure.getStructureKey(),
242                                    ddmStructure.getStructureKey());
243                    }
244    
245                    List<Element> ddmTemplateElements =
246                            portletDataContext.getReferenceDataElements(
247                                    feed, DDMTemplate.class);
248    
249                    String parentDDMTemplateKey = StringPool.BLANK;
250                    String parentRendererDDMTemplateKey = StringPool.BLANK;
251    
252                    for (Element ddmTemplateElement : ddmTemplateElements) {
253                            String ddmTemplatePath = ddmTemplateElement.attributeValue("path");
254    
255                            DDMTemplate ddmTemplate =
256                                    (DDMTemplate)portletDataContext.getZipEntryAsObject(
257                                            ddmTemplatePath);
258    
259                            StagedModelDataHandlerUtil.importStagedModel(
260                                    portletDataContext, ddmTemplate);
261    
262                            Map<String, String> ddmTemplateKeys =
263                                    (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
264                                            DDMTemplate.class + ".ddmTemplateKey");
265    
266                            boolean rendererDDMTemplate = GetterUtil.getBoolean(
267                                    ddmTemplateElement.attributeValue("rendererDDMTemplate"));
268    
269                            String ddmTemplateKey = MapUtil.getString(
270                                    ddmTemplateKeys, ddmTemplate.getTemplateKey(),
271                                    ddmTemplate.getTemplateKey());
272    
273                            if (rendererDDMTemplate) {
274                                    parentDDMTemplateKey = ddmTemplateKey;
275                            }
276                            else {
277                                    parentRendererDDMTemplateKey = ddmTemplateKey;
278                            }
279                    }
280    
281                    ServiceContext serviceContext = portletDataContext.createServiceContext(
282                            feed, JournalPortletDataHandler.NAMESPACE);
283    
284                    boolean addGroupPermissions = creationStrategy.addGroupPermissions(
285                            portletDataContext, feed);
286    
287                    serviceContext.setAddGroupPermissions(addGroupPermissions);
288    
289                    boolean addGuestPermissions = creationStrategy.addGuestPermissions(
290                            portletDataContext, feed);
291    
292                    serviceContext.setAddGuestPermissions(addGuestPermissions);
293    
294                    JournalFeed importedFeed = null;
295    
296                    try {
297                            if (portletDataContext.isDataStrategyMirror()) {
298                                    JournalFeed existingFeed =
299                                            JournalFeedLocalServiceUtil.
300                                                    fetchJournalFeedByUuidAndGroupId(
301                                                            feed.getUuid(),
302                                                            portletDataContext.getScopeGroupId());
303    
304                                    if (existingFeed == null) {
305                                            serviceContext.setUuid(feed.getUuid());
306    
307                                            importedFeed = JournalFeedLocalServiceUtil.addFeed(
308                                                    userId, portletDataContext.getScopeGroupId(), feedId,
309                                                    autoFeedId, feed.getName(), feed.getDescription(),
310                                                    feed.getType(), parentDDMStructureKey,
311                                                    parentDDMTemplateKey, parentRendererDDMTemplateKey,
312                                                    feed.getDelta(), feed.getOrderByCol(),
313                                                    feed.getOrderByType(),
314                                                    feed.getTargetLayoutFriendlyUrl(),
315                                                    feed.getTargetPortletId(), feed.getContentField(),
316                                                    feed.getFeedFormat(), feed.getFeedVersion(),
317                                                    serviceContext);
318                                    }
319                                    else {
320                                            importedFeed = JournalFeedLocalServiceUtil.updateFeed(
321                                                    existingFeed.getGroupId(), existingFeed.getFeedId(),
322                                                    feed.getName(), feed.getDescription(), feed.getType(),
323                                                    parentDDMStructureKey, parentDDMTemplateKey,
324                                                    parentRendererDDMTemplateKey, feed.getDelta(),
325                                                    feed.getOrderByCol(), feed.getOrderByType(),
326                                                    feed.getTargetLayoutFriendlyUrl(),
327                                                    feed.getTargetPortletId(), feed.getContentField(),
328                                                    feed.getFeedFormat(), feed.getFeedVersion(),
329                                                    serviceContext);
330                                    }
331                            }
332                            else {
333                                    importedFeed = JournalFeedLocalServiceUtil.addFeed(
334                                            userId, portletDataContext.getScopeGroupId(), feedId,
335                                            autoFeedId, feed.getName(), feed.getDescription(),
336                                            feed.getType(), parentDDMStructureKey, parentDDMTemplateKey,
337                                            parentRendererDDMTemplateKey, feed.getDelta(),
338                                            feed.getOrderByCol(), feed.getOrderByType(),
339                                            feed.getTargetLayoutFriendlyUrl(),
340                                            feed.getTargetPortletId(), feed.getContentField(),
341                                            feed.getFeedFormat(), feed.getFeedVersion(),
342                                            serviceContext);
343                            }
344    
345                            portletDataContext.importClassedModel(
346                                    feed, importedFeed, JournalPortletDataHandler.NAMESPACE);
347    
348                            if (!feedId.equals(importedFeed.getFeedId())) {
349                                    if (_log.isWarnEnabled()) {
350                                            StringBundler sb = new StringBundler(5);
351    
352                                            sb.append("A feed with the ID ");
353                                            sb.append(feedId);
354                                            sb.append(" already exists. The new generated ID is ");
355                                            sb.append(importedFeed.getFeedId());
356                                            sb.append(".");
357    
358                                            _log.warn(sb.toString());
359                                    }
360                            }
361                    }
362                    catch (FeedTargetLayoutFriendlyUrlException ftlfurle) {
363                            if (_log.isWarnEnabled()) {
364                                    StringBundler sb = new StringBundler(6);
365    
366                                    sb.append("A feed with the ID ");
367                                    sb.append(feedId);
368                                    sb.append(" cannot be imported because layout with friendly ");
369                                    sb.append("URL ");
370                                    sb.append(feed.getTargetLayoutFriendlyUrl());
371                                    sb.append(" does not exist");
372    
373                                    _log.warn(sb.toString());
374                            }
375                    }
376            }
377    
378            private static Log _log = LogFactoryUtil.getLog(
379                    JournalFeedStagedModelDataHandler.class);
380    
381    }