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