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