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