001    /**
002     * Copyright (c) 2000-present 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.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.lar.BaseStagedModelDataHandler;
020    import com.liferay.portal.kernel.lar.ExportImportHelper;
021    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
022    import com.liferay.portal.kernel.lar.PortletDataContext;
023    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
024    import com.liferay.portal.kernel.lar.StagedModelModifiedDateComparator;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.util.ListUtil;
028    import com.liferay.portal.kernel.util.MapUtil;
029    import com.liferay.portal.kernel.util.StringBundler;
030    import com.liferay.portal.kernel.util.StringPool;
031    import com.liferay.portal.kernel.util.StringUtil;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.kernel.xml.Element;
034    import com.liferay.portal.model.Group;
035    import com.liferay.portal.service.GroupLocalServiceUtil;
036    import com.liferay.portal.service.ServiceContext;
037    import com.liferay.portal.util.PortalUtil;
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.journal.FeedTargetLayoutFriendlyUrlException;
043    import com.liferay.portlet.journal.model.JournalArticle;
044    import com.liferay.portlet.journal.model.JournalFeed;
045    import com.liferay.portlet.journal.service.JournalFeedLocalServiceUtil;
046    
047    import java.util.List;
048    import java.util.Map;
049    
050    /**
051     * @author Daniel Kocsis
052     */
053    public class JournalFeedStagedModelDataHandler
054            extends BaseStagedModelDataHandler<JournalFeed> {
055    
056            public static final String[] CLASS_NAMES = {JournalFeed.class.getName()};
057    
058            @Override
059            public void deleteStagedModel(
060                            String uuid, long groupId, String className, String extraData)
061                    throws PortalException {
062    
063                    JournalFeed feed = fetchStagedModelByUuidAndGroupId(uuid, groupId);
064    
065                    if (feed != null) {
066                            JournalFeedLocalServiceUtil.deleteFeed(feed);
067                    }
068            }
069    
070            @Override
071            public JournalFeed fetchStagedModelByUuidAndCompanyId(
072                    String uuid, long companyId) {
073    
074                    List<JournalFeed> feeds =
075                            JournalFeedLocalServiceUtil.getJournalFeedsByUuidAndCompanyId(
076                                    uuid, companyId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
077                                    new StagedModelModifiedDateComparator<JournalFeed>());
078    
079                    if (ListUtil.isEmpty(feeds)) {
080                            return null;
081                    }
082    
083                    return feeds.get(0);
084            }
085    
086            @Override
087            public JournalFeed fetchStagedModelByUuidAndGroupId(
088                    String uuid, long groupId) {
089    
090                    return JournalFeedLocalServiceUtil.fetchJournalFeedByUuidAndGroupId(
091                            uuid, groupId);
092            }
093    
094            @Override
095            public String[] getClassNames() {
096                    return CLASS_NAMES;
097            }
098    
099            @Override
100            protected void doExportStagedModel(
101                            PortletDataContext portletDataContext, JournalFeed feed)
102                    throws Exception {
103    
104                    Element feedElement = portletDataContext.getExportDataElement(feed);
105    
106                    DDMStructure ddmStructure = DDMStructureLocalServiceUtil.fetchStructure(
107                            feed.getGroupId(), PortalUtil.getClassNameId(JournalArticle.class),
108                            feed.getDDMStructureKey(), true);
109    
110                    if (ddmStructure != null) {
111                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
112                                    portletDataContext, feed, ddmStructure,
113                                    PortletDataContext.REFERENCE_TYPE_STRONG);
114                    }
115                    else {
116                            if (_log.isWarnEnabled()) {
117                                    _log.warn(
118                                            "Unable to find DDM structure with key " +
119                                                    feed.getDDMStructureKey());
120                            }
121                    }
122    
123                    DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.fetchTemplate(
124                            feed.getGroupId(), PortalUtil.getClassNameId(DDMStructure.class),
125                            feed.getDDMTemplateKey());
126    
127                    if (ddmTemplate != null) {
128                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
129                                    portletDataContext, feed, ddmTemplate,
130                                    PortletDataContext.REFERENCE_TYPE_STRONG);
131                    }
132                    else {
133                            if (_log.isWarnEnabled()) {
134                                    _log.warn(
135                                            "Unable to find DDM template with key " +
136                                                    feed.getDDMTemplateKey());
137                            }
138                    }
139    
140                    DDMTemplate rendererDDMTemplate =
141                            DDMTemplateLocalServiceUtil.fetchTemplate(
142                                    feed.getGroupId(),
143                                    PortalUtil.getClassNameId(DDMStructure.class),
144                                    feed.getDDMRendererTemplateKey());
145    
146                    if (rendererDDMTemplate != null) {
147                            Element rendererDDMTemplateElement =
148                                    StagedModelDataHandlerUtil.exportReferenceStagedModel(
149                                            portletDataContext, feed, rendererDDMTemplate,
150                                            PortletDataContext.REFERENCE_TYPE_STRONG);
151    
152                            rendererDDMTemplateElement.addAttribute(
153                                    "rendererDDMTemplate", "true");
154                    }
155                    else {
156                            if (_log.isWarnEnabled()) {
157                                    _log.warn(
158                                            "Unable to find DDM template with key " +
159                                                    feed.getDDMRendererTemplateKey());
160                            }
161                    }
162    
163                    Group group = GroupLocalServiceUtil.getGroup(
164                            portletDataContext.getScopeGroupId());
165    
166                    String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
167    
168                    String[] friendlyURLParts = StringUtil.split(
169                            feed.getTargetLayoutFriendlyUrl(), '/');
170    
171                    String oldGroupFriendlyURL = friendlyURLParts[2];
172    
173                    if (newGroupFriendlyURL.equals(oldGroupFriendlyURL)) {
174                            String targetLayoutFriendlyUrl = StringUtil.replaceFirst(
175                                    feed.getTargetLayoutFriendlyUrl(),
176                                    StringPool.SLASH + newGroupFriendlyURL + StringPool.SLASH,
177                                    StringPool.SLASH +
178                                            ExportImportHelper.DATA_HANDLER_GROUP_FRIENDLY_URL +
179                                                    StringPool.SLASH);
180    
181                            feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
182                    }
183    
184                    portletDataContext.addClassedModel(
185                            feedElement, ExportImportPathUtil.getModelPath(feed), feed);
186            }
187    
188            @Override
189            protected void doImportStagedModel(
190                            PortletDataContext portletDataContext, JournalFeed feed)
191                    throws Exception {
192    
193                    long userId = portletDataContext.getUserId(feed.getUserUuid());
194    
195                    JournalCreationStrategy creationStrategy =
196                            JournalCreationStrategyFactory.getInstance();
197    
198                    long authorId = creationStrategy.getAuthorUserId(
199                            portletDataContext, feed);
200    
201                    if (authorId != JournalCreationStrategy.USE_DEFAULT_USER_ID_STRATEGY) {
202                            userId = authorId;
203                    }
204    
205                    Group group = GroupLocalServiceUtil.getGroup(
206                            portletDataContext.getScopeGroupId());
207    
208                    String newGroupFriendlyURL = group.getFriendlyURL().substring(1);
209    
210                    String[] friendlyURLParts = StringUtil.split(
211                            feed.getTargetLayoutFriendlyUrl(), '/');
212    
213                    String oldGroupFriendlyURL = friendlyURLParts[2];
214    
215                    if (oldGroupFriendlyURL.equals(
216                                    ExportImportHelper.DATA_HANDLER_GROUP_FRIENDLY_URL)) {
217    
218                            feed.setTargetLayoutFriendlyUrl(
219                                    StringUtil.replace(
220                                            feed.getTargetLayoutFriendlyUrl(),
221                                            ExportImportHelper.DATA_HANDLER_GROUP_FRIENDLY_URL,
222                                            newGroupFriendlyURL));
223                    }
224    
225                    String feedId = feed.getFeedId();
226    
227                    boolean autoFeedId = false;
228    
229                    if (Validator.isNumber(feedId) ||
230                            (JournalFeedLocalServiceUtil.fetchFeed(
231                                    portletDataContext.getScopeGroupId(), feedId) != null)) {
232    
233                            autoFeedId = true;
234                    }
235    
236                    Map<String, String> ddmStructureKeys =
237                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
238                                    DDMStructure.class + ".ddmStructureKey");
239    
240                    String parentDDMStructureKey = MapUtil.getString(
241                            ddmStructureKeys, feed.getDDMStructureKey(),
242                            feed.getDDMStructureKey());
243    
244                    Map<String, String> ddmTemplateKeys =
245                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
246                                    DDMTemplate.class + ".ddmTemplateKey");
247    
248                    String parentDDMTemplateKey = MapUtil.getString(
249                            ddmTemplateKeys, feed.getDDMTemplateKey(),
250                            feed.getDDMTemplateKey());
251                    String parentRendererDDMTemplateKey = MapUtil.getString(
252                            ddmTemplateKeys, feed.getDDMRendererTemplateKey(),
253                            feed.getDDMRendererTemplateKey());
254    
255                    ServiceContext serviceContext = portletDataContext.createServiceContext(
256                            feed);
257    
258                    boolean addGroupPermissions = creationStrategy.addGroupPermissions(
259                            portletDataContext, feed);
260    
261                    serviceContext.setAddGroupPermissions(addGroupPermissions);
262    
263                    boolean addGuestPermissions = creationStrategy.addGuestPermissions(
264                            portletDataContext, feed);
265    
266                    serviceContext.setAddGuestPermissions(addGuestPermissions);
267    
268                    JournalFeed importedFeed = null;
269    
270                    try {
271                            if (portletDataContext.isDataStrategyMirror()) {
272                                    JournalFeed existingFeed = fetchStagedModelByUuidAndGroupId(
273                                            feed.getUuid(), portletDataContext.getScopeGroupId());
274    
275                                    if (existingFeed == null) {
276                                            serviceContext.setUuid(feed.getUuid());
277    
278                                            importedFeed = JournalFeedLocalServiceUtil.addFeed(
279                                                    userId, portletDataContext.getScopeGroupId(), feedId,
280                                                    autoFeedId, feed.getName(), feed.getDescription(),
281                                                    parentDDMStructureKey, parentDDMTemplateKey,
282                                                    parentRendererDDMTemplateKey, feed.getDelta(),
283                                                    feed.getOrderByCol(), feed.getOrderByType(),
284                                                    feed.getTargetLayoutFriendlyUrl(),
285                                                    feed.getTargetPortletId(), feed.getContentField(),
286                                                    feed.getFeedFormat(), feed.getFeedVersion(),
287                                                    serviceContext);
288                                    }
289                                    else {
290                                            importedFeed = JournalFeedLocalServiceUtil.updateFeed(
291                                                    existingFeed.getGroupId(), existingFeed.getFeedId(),
292                                                    feed.getName(), feed.getDescription(),
293                                                    parentDDMStructureKey, parentDDMTemplateKey,
294                                                    parentRendererDDMTemplateKey, feed.getDelta(),
295                                                    feed.getOrderByCol(), feed.getOrderByType(),
296                                                    feed.getTargetLayoutFriendlyUrl(),
297                                                    feed.getTargetPortletId(), feed.getContentField(),
298                                                    feed.getFeedFormat(), feed.getFeedVersion(),
299                                                    serviceContext);
300                                    }
301                            }
302                            else {
303                                    importedFeed = JournalFeedLocalServiceUtil.addFeed(
304                                            userId, portletDataContext.getScopeGroupId(), feedId,
305                                            autoFeedId, feed.getName(), feed.getDescription(),
306                                            parentDDMStructureKey, parentDDMTemplateKey,
307                                            parentRendererDDMTemplateKey, feed.getDelta(),
308                                            feed.getOrderByCol(), feed.getOrderByType(),
309                                            feed.getTargetLayoutFriendlyUrl(),
310                                            feed.getTargetPortletId(), feed.getContentField(),
311                                            feed.getFeedFormat(), feed.getFeedVersion(),
312                                            serviceContext);
313                            }
314    
315                            portletDataContext.importClassedModel(feed, importedFeed);
316    
317                            if (!feedId.equals(importedFeed.getFeedId())) {
318                                    if (_log.isWarnEnabled()) {
319                                            StringBundler sb = new StringBundler(5);
320    
321                                            sb.append("A feed with the ID ");
322                                            sb.append(feedId);
323                                            sb.append(" already exists. The new generated ID is ");
324                                            sb.append(importedFeed.getFeedId());
325                                            sb.append(".");
326    
327                                            _log.warn(sb.toString());
328                                    }
329                            }
330                    }
331                    catch (FeedTargetLayoutFriendlyUrlException ftlfurle) {
332                            if (_log.isWarnEnabled()) {
333                                    StringBundler sb = new StringBundler(6);
334    
335                                    sb.append("A feed with the ID ");
336                                    sb.append(feedId);
337                                    sb.append(" cannot be imported because layout with friendly ");
338                                    sb.append("URL ");
339                                    sb.append(feed.getTargetLayoutFriendlyUrl());
340                                    sb.append(" does not exist");
341    
342                                    _log.warn(sb.toString());
343                            }
344                    }
345            }
346    
347            private static final Log _log = LogFactoryUtil.getLog(
348                    JournalFeedStagedModelDataHandler.class);
349    
350    }