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.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.systemevent.SystemEvent;
022    import com.liferay.portal.kernel.util.CharPool;
023    import com.liferay.portal.kernel.util.HtmlUtil;
024    import com.liferay.portal.kernel.util.OrderByComparator;
025    import com.liferay.portal.kernel.util.StringBundler;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.kernel.xml.Document;
029    import com.liferay.portal.kernel.xml.Node;
030    import com.liferay.portal.kernel.xml.SAXReaderUtil;
031    import com.liferay.portal.kernel.xml.XPath;
032    import com.liferay.portal.model.ResourceConstants;
033    import com.liferay.portal.model.SystemEventConstants;
034    import com.liferay.portal.model.User;
035    import com.liferay.portal.service.ServiceContext;
036    import com.liferay.portal.util.PortalUtil;
037    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
038    import com.liferay.portlet.journal.DuplicateFeedIdException;
039    import com.liferay.portlet.journal.FeedContentFieldException;
040    import com.liferay.portlet.journal.FeedIdException;
041    import com.liferay.portlet.journal.FeedNameException;
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.model.JournalFeedConstants;
046    import com.liferay.portlet.journal.service.base.JournalFeedLocalServiceBaseImpl;
047    import com.liferay.util.RSSUtil;
048    
049    import java.util.Date;
050    import java.util.List;
051    
052    /**
053     * @author Raymond Aug??
054     */
055    public class JournalFeedLocalServiceImpl
056            extends JournalFeedLocalServiceBaseImpl {
057    
058            @Override
059            public JournalFeed addFeed(
060                            long userId, long groupId, String feedId, boolean autoFeedId,
061                            String name, String description, String type, String structureId,
062                            String templateId, String rendererTemplateId, int delta,
063                            String orderByCol, String orderByType,
064                            String targetLayoutFriendlyUrl, String targetPortletId,
065                            String contentField, String feedFormat, double feedVersion,
066                            ServiceContext serviceContext)
067                    throws PortalException, SystemException {
068    
069                    // Feed
070    
071                    User user = userPersistence.findByPrimaryKey(userId);
072                    feedId = StringUtil.toUpperCase(feedId.trim());
073                    Date now = new Date();
074    
075                    validate(
076                            user.getCompanyId(), groupId, feedId, autoFeedId, name, structureId,
077                            targetLayoutFriendlyUrl, contentField);
078    
079                    if (autoFeedId) {
080                            feedId = String.valueOf(counterLocalService.increment());
081                    }
082    
083                    long id = counterLocalService.increment();
084    
085                    JournalFeed feed = journalFeedPersistence.create(id);
086    
087                    feed.setUuid(serviceContext.getUuid());
088                    feed.setGroupId(groupId);
089                    feed.setCompanyId(user.getCompanyId());
090                    feed.setUserId(user.getUserId());
091                    feed.setUserName(user.getFullName());
092                    feed.setCreateDate(serviceContext.getCreateDate(now));
093                    feed.setModifiedDate(serviceContext.getModifiedDate(now));
094                    feed.setFeedId(feedId);
095                    feed.setName(name);
096                    feed.setDescription(description);
097                    feed.setType(type);
098                    feed.setStructureId(structureId);
099                    feed.setTemplateId(templateId);
100                    feed.setRendererTemplateId(rendererTemplateId);
101                    feed.setDelta(delta);
102                    feed.setOrderByCol(orderByCol);
103                    feed.setOrderByType(orderByType);
104                    feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
105                    feed.setTargetPortletId(targetPortletId);
106                    feed.setContentField(contentField);
107    
108                    if (Validator.isNull(feedFormat)) {
109                            feed.setFeedFormat(RSSUtil.FORMAT_DEFAULT);
110                            feed.setFeedVersion(RSSUtil.VERSION_DEFAULT);
111                    }
112                    else {
113                            feed.setFeedFormat(feedFormat);
114                            feed.setFeedVersion(feedVersion);
115                    }
116    
117                    feed.setExpandoBridgeAttributes(serviceContext);
118    
119                    journalFeedPersistence.update(feed);
120    
121                    // Resources
122    
123                    if (serviceContext.isAddGroupPermissions() ||
124                            serviceContext.isAddGuestPermissions()) {
125    
126                            addFeedResources(
127                                    feed, serviceContext.isAddGroupPermissions(),
128                                    serviceContext.isAddGuestPermissions());
129                    }
130                    else {
131                            addFeedResources(
132                                    feed, serviceContext.getGroupPermissions(),
133                                    serviceContext.getGuestPermissions());
134                    }
135    
136                    return feed;
137            }
138    
139            @Override
140            public void addFeedResources(
141                            JournalFeed feed, boolean addGroupPermissions,
142                            boolean addGuestPermissions)
143                    throws PortalException, SystemException {
144    
145                    resourceLocalService.addResources(
146                            feed.getCompanyId(), feed.getGroupId(), feed.getUserId(),
147                            JournalFeed.class.getName(), feed.getId(), false,
148                            addGroupPermissions, addGuestPermissions);
149            }
150    
151            @Override
152            public void addFeedResources(
153                            JournalFeed feed, String[] groupPermissions,
154                            String[] guestPermissions)
155                    throws PortalException, SystemException {
156    
157                    resourceLocalService.addModelResources(
158                            feed.getCompanyId(), feed.getGroupId(), feed.getUserId(),
159                            JournalFeed.class.getName(), feed.getId(), groupPermissions,
160                            guestPermissions);
161            }
162    
163            @Override
164            public void addFeedResources(
165                            long feedId, boolean addGroupPermissions,
166                            boolean addGuestPermissions)
167                    throws PortalException, SystemException {
168    
169                    JournalFeed feed = journalFeedPersistence.findByPrimaryKey(feedId);
170    
171                    addFeedResources(feed, addGroupPermissions, addGuestPermissions);
172            }
173    
174            @Override
175            public void addFeedResources(
176                            long feedId, String[] groupPermissions, String[] guestPermissions)
177                    throws PortalException, SystemException {
178    
179                    JournalFeed feed = journalFeedPersistence.findByPrimaryKey(feedId);
180    
181                    addFeedResources(feed, groupPermissions, guestPermissions);
182            }
183    
184            @Override
185            @SystemEvent(type = SystemEventConstants.TYPE_DELETE)
186            public void deleteFeed(JournalFeed feed)
187                    throws PortalException, SystemException {
188    
189                    // Feed
190    
191                    journalFeedPersistence.remove(feed);
192    
193                    // Resources
194    
195                    resourceLocalService.deleteResource(
196                            feed.getCompanyId(), JournalFeed.class.getName(),
197                            ResourceConstants.SCOPE_INDIVIDUAL, feed.getId());
198    
199                    // Expando
200    
201                    expandoValueLocalService.deleteValues(
202                            JournalFeed.class.getName(), feed.getId());
203            }
204    
205            @Override
206            public void deleteFeed(long feedId)
207                    throws PortalException, SystemException {
208    
209                    JournalFeed feed = journalFeedPersistence.findByPrimaryKey(feedId);
210    
211                    journalFeedLocalService.deleteFeed(feed);
212            }
213    
214            @Override
215            public void deleteFeed(long groupId, String feedId)
216                    throws PortalException, SystemException {
217    
218                    JournalFeed feed = journalFeedPersistence.findByG_F(groupId, feedId);
219    
220                    journalFeedLocalService.deleteFeed(feed);
221            }
222    
223            @Override
224            public JournalFeed fetchFeed(long groupId, String feedId)
225                    throws SystemException {
226    
227                    return journalFeedPersistence.fetchByG_F(groupId, feedId);
228            }
229    
230            @Override
231            public JournalFeed getFeed(long feedId)
232                    throws PortalException, SystemException {
233    
234                    return journalFeedPersistence.findByPrimaryKey(feedId);
235            }
236    
237            @Override
238            public JournalFeed getFeed(long groupId, String feedId)
239                    throws PortalException, SystemException {
240    
241                    return journalFeedPersistence.findByG_F(groupId, feedId);
242            }
243    
244            @Override
245            public List<JournalFeed> getFeeds() throws SystemException {
246                    return journalFeedPersistence.findAll();
247            }
248    
249            @Override
250            public List<JournalFeed> getFeeds(long groupId) throws SystemException {
251                    return journalFeedPersistence.findByGroupId(groupId);
252            }
253    
254            @Override
255            public List<JournalFeed> getFeeds(long groupId, int start, int end)
256                    throws SystemException {
257    
258                    return journalFeedPersistence.findByGroupId(groupId, start, end);
259            }
260    
261            @Override
262            public int getFeedsCount(long groupId) throws SystemException {
263                    return journalFeedPersistence.countByGroupId(groupId);
264            }
265    
266            @Override
267            public List<JournalFeed> search(
268                            long companyId, long groupId, String keywords, int start, int end,
269                            OrderByComparator obc)
270                    throws SystemException {
271    
272                    return journalFeedFinder.findByKeywords(
273                            companyId, groupId, keywords, start, end, obc);
274            }
275    
276            @Override
277            public List<JournalFeed> search(
278                            long companyId, long groupId, String feedId, String name,
279                            String description, boolean andOperator, int start, int end,
280                            OrderByComparator obc)
281                    throws SystemException {
282    
283                    return journalFeedFinder.findByC_G_F_N_D(
284                            companyId, groupId, feedId, name, description, andOperator, start,
285                            end, obc);
286            }
287    
288            @Override
289            public int searchCount(long companyId, long groupId, String keywords)
290                    throws SystemException {
291    
292                    return journalFeedFinder.countByKeywords(companyId, groupId, keywords);
293            }
294    
295            @Override
296            public int searchCount(
297                            long companyId, long groupId, String feedId, String name,
298                            String description, boolean andOperator)
299                    throws SystemException {
300    
301                    return journalFeedFinder.countByC_G_F_N_D(
302                            companyId, groupId, feedId, name, description, andOperator);
303            }
304    
305            @Override
306            public JournalFeed updateFeed(
307                            long groupId, String feedId, String name, String description,
308                            String type, String structureId, String templateId,
309                            String rendererTemplateId, int delta, String orderByCol,
310                            String orderByType, String targetLayoutFriendlyUrl,
311                            String targetPortletId, String contentField, String feedFormat,
312                            double feedVersion, ServiceContext serviceContext)
313                    throws PortalException, SystemException {
314    
315                    // Feed
316    
317                    JournalFeed feed = journalFeedPersistence.findByG_F(groupId, feedId);
318    
319                    validate(
320                            feed.getCompanyId(), groupId, name, structureId,
321                            targetLayoutFriendlyUrl, contentField);
322    
323                    feed.setModifiedDate(serviceContext.getModifiedDate(null));
324                    feed.setName(name);
325                    feed.setDescription(description);
326                    feed.setType(type);
327                    feed.setStructureId(structureId);
328                    feed.setTemplateId(templateId);
329                    feed.setRendererTemplateId(rendererTemplateId);
330                    feed.setDelta(delta);
331                    feed.setOrderByCol(orderByCol);
332                    feed.setOrderByType(orderByType);
333                    feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
334                    feed.setTargetPortletId(targetPortletId);
335                    feed.setContentField(contentField);
336    
337                    if (Validator.isNull(feedFormat)) {
338                            feed.setFeedFormat(RSSUtil.FORMAT_DEFAULT);
339                            feed.setFeedVersion(RSSUtil.VERSION_DEFAULT);
340                    }
341                    else {
342                            feed.setFeedFormat(feedFormat);
343                            feed.setFeedVersion(feedVersion);
344                    }
345    
346                    feed.setExpandoBridgeAttributes(serviceContext);
347    
348                    journalFeedPersistence.update(feed);
349    
350                    return feed;
351            }
352    
353            protected boolean isValidStructureField(
354                    long groupId, String structureId, String contentField) {
355    
356                    if (contentField.equals(JournalFeedConstants.WEB_CONTENT_DESCRIPTION) ||
357                            contentField.equals(JournalFeedConstants.RENDERED_WEB_CONTENT)) {
358    
359                            return true;
360                    }
361    
362                    try {
363                            DDMStructure ddmStructure =
364                                    ddmStructureLocalService.getStructure(
365                                            groupId, PortalUtil.getClassNameId(JournalArticle.class),
366                                            structureId);
367    
368                            Document document = SAXReaderUtil.read(ddmStructure.getXsd());
369    
370                            contentField = HtmlUtil.escapeXPathAttribute(contentField);
371    
372                            XPath xPathSelector = SAXReaderUtil.createXPath(
373                                    "//dynamic-element[@name="+ contentField + "]");
374    
375                            Node node = xPathSelector.selectSingleNode(document);
376    
377                            if (node != null) {
378                                    return true;
379                            }
380                    }
381                    catch (Exception e) {
382                            _log.error(e, e);
383                    }
384    
385                    return false;
386            }
387    
388            protected void validate(
389                            long companyId, long groupId, String feedId, boolean autoFeedId,
390                            String name, String structureId, String targetLayoutFriendlyUrl,
391                            String contentField)
392                    throws PortalException, SystemException {
393    
394                    if (!autoFeedId) {
395                            if (Validator.isNull(feedId) || Validator.isNumber(feedId) ||
396                                    (feedId.indexOf(CharPool.COMMA) != -1) ||
397                                    (feedId.indexOf(CharPool.SPACE) != -1)) {
398    
399                                    throw new FeedIdException();
400                            }
401    
402                            JournalFeed feed = journalFeedPersistence.fetchByG_F(
403                                    groupId, feedId);
404    
405                            if (feed != null) {
406                                    StringBundler sb = new StringBundler(5);
407    
408                                    sb.append("{groupId=");
409                                    sb.append(groupId);
410                                    sb.append(", feedId=");
411                                    sb.append(feedId);
412                                    sb.append("}");
413    
414                                    throw new DuplicateFeedIdException(sb.toString());
415                            }
416                    }
417    
418                    validate(
419                            companyId, groupId, name, structureId, targetLayoutFriendlyUrl,
420                            contentField);
421            }
422    
423            protected void validate(
424                            long companyId, long groupId, String name, String structureId,
425                            String targetLayoutFriendlyUrl, String contentField)
426                    throws PortalException {
427    
428                    if (Validator.isNull(name)) {
429                            throw new FeedNameException();
430                    }
431    
432                    long plid = PortalUtil.getPlidFromFriendlyURL(
433                            companyId, targetLayoutFriendlyUrl);
434    
435                    if (plid <= 0) {
436                            throw new FeedTargetLayoutFriendlyUrlException();
437                    }
438    
439                    if (!isValidStructureField(groupId, structureId, contentField)) {
440                            throw new FeedContentFieldException();
441                    }
442            }
443    
444            private static Log _log = LogFactoryUtil.getLog(
445                    JournalFeedLocalServiceImpl.class);
446    
447    }