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