001    /**
002     * Copyright (c) 2000-2012 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.expando.model.ExpandoBridge;
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.JournalFeed;
040    import com.liferay.portlet.journal.model.JournalFeedConstants;
041    import com.liferay.portlet.journal.model.JournalStructure;
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 feedType, 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(feedType)) {
104                            feed.setFeedType(RSSUtil.TYPE_DEFAULT);
105                            feed.setFeedVersion(RSSUtil.VERSION_DEFAULT);
106                    }
107                    else {
108                            feed.setFeedType(feedType);
109                            feed.setFeedVersion(feedVersion);
110                    }
111    
112                    journalFeedPersistence.update(feed);
113    
114                    // Resources
115    
116                    if (serviceContext.isAddGroupPermissions() ||
117                            serviceContext.isAddGuestPermissions()) {
118    
119                            addFeedResources(
120                                    feed, serviceContext.isAddGroupPermissions(),
121                                    serviceContext.isAddGuestPermissions());
122                    }
123                    else {
124                            addFeedResources(
125                                    feed, serviceContext.getGroupPermissions(),
126                                    serviceContext.getGuestPermissions());
127                    }
128    
129                    // Expando
130    
131                    ExpandoBridge expandoBridge = feed.getExpandoBridge();
132    
133                    expandoBridge.setAttributes(serviceContext);
134    
135                    return feed;
136            }
137    
138            public void addFeedResources(
139                            JournalFeed feed, boolean addGroupPermissions,
140                            boolean addGuestPermissions)
141                    throws PortalException, SystemException {
142    
143                    resourceLocalService.addResources(
144                            feed.getCompanyId(), feed.getGroupId(), feed.getUserId(),
145                            JournalFeed.class.getName(), feed.getId(), false,
146                            addGroupPermissions, addGuestPermissions);
147            }
148    
149            public void addFeedResources(
150                            JournalFeed feed, String[] groupPermissions,
151                            String[] guestPermissions)
152                    throws PortalException, SystemException {
153    
154                    resourceLocalService.addModelResources(
155                            feed.getCompanyId(), feed.getGroupId(), feed.getUserId(),
156                            JournalFeed.class.getName(), feed.getId(), groupPermissions,
157                            guestPermissions);
158            }
159    
160            public void addFeedResources(
161                            long feedId, boolean addGroupPermissions,
162                            boolean addGuestPermissions)
163                    throws PortalException, SystemException {
164    
165                    JournalFeed feed = journalFeedPersistence.findByPrimaryKey(feedId);
166    
167                    addFeedResources(feed, addGroupPermissions, addGuestPermissions);
168            }
169    
170            public void addFeedResources(
171                            long feedId, String[] groupPermissions, String[] guestPermissions)
172                    throws PortalException, SystemException {
173    
174                    JournalFeed feed = journalFeedPersistence.findByPrimaryKey(feedId);
175    
176                    addFeedResources(feed, groupPermissions, guestPermissions);
177            }
178    
179            public void deleteFeed(JournalFeed feed)
180                    throws PortalException, SystemException {
181    
182                    // Expando
183    
184                    expandoValueLocalService.deleteValues(
185                            JournalFeed.class.getName(), feed.getId());
186    
187                    // Resources
188    
189                    resourceLocalService.deleteResource(
190                            feed.getCompanyId(), JournalFeed.class.getName(),
191                            ResourceConstants.SCOPE_INDIVIDUAL, feed.getId());
192    
193                    // Feed
194    
195                    journalFeedPersistence.remove(feed);
196            }
197    
198            public void deleteFeed(long feedId)
199                    throws PortalException, SystemException {
200    
201                    JournalFeed feed = journalFeedPersistence.findByPrimaryKey(feedId);
202    
203                    deleteFeed(feed);
204            }
205    
206            public void deleteFeed(long groupId, String feedId)
207                    throws PortalException, SystemException {
208    
209                    JournalFeed feed = journalFeedPersistence.findByG_F(groupId, feedId);
210    
211                    deleteFeed(feed);
212            }
213    
214            public JournalFeed getFeed(long feedId)
215                    throws PortalException, SystemException {
216    
217                    return journalFeedPersistence.findByPrimaryKey(feedId);
218            }
219    
220            public JournalFeed getFeed(long groupId, String feedId)
221                    throws PortalException, SystemException {
222    
223                    return journalFeedPersistence.findByG_F(groupId, feedId);
224            }
225    
226            public List<JournalFeed> getFeeds() throws SystemException {
227                    return journalFeedPersistence.findAll();
228            }
229    
230            public List<JournalFeed> getFeeds(long groupId) throws SystemException {
231                    return journalFeedPersistence.findByGroupId(groupId);
232            }
233    
234            public List<JournalFeed> getFeeds(long groupId, int start, int end)
235                    throws SystemException {
236    
237                    return journalFeedPersistence.findByGroupId(groupId, start, end);
238            }
239    
240            public int getFeedsCount(long groupId) throws SystemException {
241                    return journalFeedPersistence.countByGroupId(groupId);
242            }
243    
244            public List<JournalFeed> search(
245                            long companyId, long groupId, String keywords, int start, int end,
246                            OrderByComparator obc)
247                    throws SystemException {
248    
249                    return journalFeedFinder.findByKeywords(
250                            companyId, groupId, keywords, start, end, obc);
251            }
252    
253            public List<JournalFeed> search(
254                            long companyId, long groupId, String feedId, String name,
255                            String description, boolean andOperator, int start, int end,
256                            OrderByComparator obc)
257                    throws SystemException {
258    
259                    return journalFeedFinder.findByC_G_F_N_D(
260                            companyId, groupId, feedId, name, description, andOperator, start,
261                            end, obc);
262            }
263    
264            public int searchCount(long companyId, long groupId, String keywords)
265                    throws SystemException {
266    
267                    return journalFeedFinder.countByKeywords(companyId, groupId, keywords);
268            }
269    
270            public int searchCount(
271                            long companyId, long groupId, String feedId, String name,
272                            String description, boolean andOperator)
273                    throws SystemException {
274    
275                    return journalFeedFinder.countByC_G_F_N_D(
276                            companyId, groupId, feedId, name, description, andOperator);
277            }
278    
279            public JournalFeed updateFeed(
280                            long groupId, String feedId, String name, String description,
281                            String type, String structureId, String templateId,
282                            String rendererTemplateId, int delta, String orderByCol,
283                            String orderByType, String targetLayoutFriendlyUrl,
284                            String targetPortletId, String contentField, String feedType,
285                            double feedVersion, ServiceContext serviceContext)
286                    throws PortalException, SystemException {
287    
288                    // Feed
289    
290                    JournalFeed feed = journalFeedPersistence.findByG_F(groupId, feedId);
291    
292                    validate(
293                            feed.getCompanyId(), groupId, name, structureId,
294                            targetLayoutFriendlyUrl, contentField);
295    
296                    feed.setModifiedDate(serviceContext.getModifiedDate(null));
297                    feed.setName(name);
298                    feed.setDescription(description);
299                    feed.setType(type);
300                    feed.setStructureId(structureId);
301                    feed.setTemplateId(templateId);
302                    feed.setRendererTemplateId(rendererTemplateId);
303                    feed.setDelta(delta);
304                    feed.setOrderByCol(orderByCol);
305                    feed.setOrderByType(orderByType);
306                    feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
307                    feed.setTargetPortletId(targetPortletId);
308                    feed.setContentField(contentField);
309    
310                    if (Validator.isNull(feedType)) {
311                            feed.setFeedType(RSSUtil.TYPE_DEFAULT);
312                            feed.setFeedVersion(RSSUtil.VERSION_DEFAULT);
313                    }
314                    else {
315                            feed.setFeedType(feedType);
316                            feed.setFeedVersion(feedVersion);
317                    }
318    
319                    journalFeedPersistence.update(feed);
320    
321                    // Expando
322    
323                    ExpandoBridge expandoBridge = feed.getExpandoBridge();
324    
325                    expandoBridge.setAttributes(serviceContext);
326    
327                    return feed;
328            }
329    
330            protected boolean isValidStructureField(
331                    long groupId, String structureId, String contentField) {
332    
333                    if (contentField.equals(JournalFeedConstants.WEB_CONTENT_DESCRIPTION) ||
334                            contentField.equals(JournalFeedConstants.RENDERED_WEB_CONTENT)) {
335    
336                            return true;
337                    }
338                    else {
339                            try {
340                                    JournalStructure structure =
341                                            journalStructurePersistence.findByG_S(groupId, structureId);
342    
343                                    Document document = SAXReaderUtil.read(structure.getXsd());
344    
345                                    contentField = HtmlUtil.escapeXPathAttribute(contentField);
346    
347                                    XPath xPathSelector = SAXReaderUtil.createXPath(
348                                            "//dynamic-element[@name="+ contentField + "]");
349    
350                                    Node node = xPathSelector.selectSingleNode(document);
351    
352                                    if (node != null) {
353                                            return true;
354                                    }
355                            }
356                            catch (Exception e) {
357                                    _log.error(e, e);
358                            }
359                    }
360    
361                    return false;
362            }
363    
364            protected void validate(
365                            long companyId, long groupId, String feedId, boolean autoFeedId,
366                            String name, String structureId, String targetLayoutFriendlyUrl,
367                            String contentField)
368                    throws PortalException, SystemException {
369    
370                    if (!autoFeedId) {
371                            if (Validator.isNull(feedId) || Validator.isNumber(feedId) ||
372                                    (feedId.indexOf(CharPool.SPACE) != -1)) {
373    
374                                    throw new FeedIdException();
375                            }
376    
377                            JournalFeed feed = journalFeedPersistence.fetchByG_F(
378                                    groupId, feedId);
379    
380                            if (feed != null) {
381                                    throw new DuplicateFeedIdException();
382                            }
383                    }
384    
385                    validate(
386                            companyId, groupId, name, structureId, targetLayoutFriendlyUrl,
387                            contentField);
388            }
389    
390            protected void validate(
391                            long companyId, long groupId, String name, String structureId,
392                            String targetLayoutFriendlyUrl, String contentField)
393                    throws PortalException {
394    
395                    if (Validator.isNull(name)) {
396                            throw new FeedNameException();
397                    }
398    
399                    long plid = PortalUtil.getPlidFromFriendlyURL(
400                            companyId, targetLayoutFriendlyUrl);
401    
402                    if (plid <= 0) {
403                            throw new FeedTargetLayoutFriendlyUrlException();
404                    }
405    
406                    if (!isValidStructureField(groupId, structureId, contentField)) {
407                            throw new FeedContentFieldException();
408                    }
409            }
410    
411            private static Log _log = LogFactoryUtil.getLog(
412                    JournalFeedLocalServiceImpl.class);
413    
414    }