1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.journal.service.impl;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.util.OrderByComparator;
28  import com.liferay.portal.kernel.util.StringPool;
29  import com.liferay.portal.kernel.util.Validator;
30  import com.liferay.portal.kernel.xml.Document;
31  import com.liferay.portal.kernel.xml.Element;
32  import com.liferay.portal.kernel.xml.SAXReaderUtil;
33  import com.liferay.portal.kernel.xml.XPath;
34  import com.liferay.portal.model.ResourceConstants;
35  import com.liferay.portal.model.User;
36  import com.liferay.portal.service.ServiceContext;
37  import com.liferay.portal.util.PortalUtil;
38  import com.liferay.portlet.expando.model.ExpandoBridge;
39  import com.liferay.portlet.journal.DuplicateFeedIdException;
40  import com.liferay.portlet.journal.FeedContentFieldException;
41  import com.liferay.portlet.journal.FeedDescriptionException;
42  import com.liferay.portlet.journal.FeedIdException;
43  import com.liferay.portlet.journal.FeedNameException;
44  import com.liferay.portlet.journal.FeedTargetLayoutFriendlyUrlException;
45  import com.liferay.portlet.journal.model.JournalFeed;
46  import com.liferay.portlet.journal.model.JournalStructure;
47  import com.liferay.portlet.journal.model.impl.JournalFeedImpl;
48  import com.liferay.portlet.journal.service.base.JournalFeedLocalServiceBaseImpl;
49  import com.liferay.util.RSSUtil;
50  
51  import java.util.Date;
52  import java.util.List;
53  
54  /**
55   * <a href="JournalFeedLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
56   *
57   * @author Raymond Augé
58   *
59   */
60  public class JournalFeedLocalServiceImpl
61      extends JournalFeedLocalServiceBaseImpl {
62  
63      public JournalFeed addFeed(
64              long userId, long groupId, String feedId, boolean autoFeedId,
65              String name, String description, String type, String structureId,
66              String templateId, String rendererTemplateId, int delta,
67              String orderByCol, String orderByType,
68              String targetLayoutFriendlyUrl, String targetPortletId,
69              String contentField, String feedType, double feedVersion,
70              ServiceContext serviceContext)
71          throws PortalException, SystemException {
72  
73          return addFeed(
74              null, userId, groupId, feedId, autoFeedId, name, description, type,
75              structureId, templateId, rendererTemplateId, delta, orderByCol,
76              orderByType, targetLayoutFriendlyUrl, targetPortletId, contentField,
77              feedType, feedVersion, serviceContext);
78      }
79  
80      public JournalFeed addFeed(
81              String uuid, long userId, long groupId, String feedId,
82              boolean autoFeedId, String name, String description,
83              String type, String structureId, String templateId,
84              String rendererTemplateId, int delta, String orderByCol,
85              String orderByType, String targetLayoutFriendlyUrl,
86              String targetPortletId, String contentField, String feedType,
87              double feedVersion, ServiceContext serviceContext)
88          throws PortalException, SystemException {
89  
90          // Feed
91  
92          User user = userPersistence.findByPrimaryKey(userId);
93          feedId = feedId.trim().toUpperCase();
94          Date now = new Date();
95  
96          validate(
97              user.getCompanyId(), groupId, feedId, autoFeedId, name, description,
98              structureId, targetLayoutFriendlyUrl, contentField);
99  
100         if (autoFeedId) {
101             feedId = String.valueOf(counterLocalService.increment());
102         }
103 
104         long id = counterLocalService.increment();
105 
106         JournalFeed feed = journalFeedPersistence.create(id);
107 
108         feed.setUuid(uuid);
109         feed.setGroupId(groupId);
110         feed.setCompanyId(user.getCompanyId());
111         feed.setUserId(user.getUserId());
112         feed.setUserName(user.getFullName());
113         feed.setCreateDate(now);
114         feed.setModifiedDate(now);
115         feed.setFeedId(feedId);
116         feed.setName(name);
117         feed.setDescription(description);
118         feed.setType(type);
119         feed.setStructureId(structureId);
120         feed.setTemplateId(templateId);
121         feed.setRendererTemplateId(rendererTemplateId);
122         feed.setDelta(delta);
123         feed.setOrderByCol(orderByCol);
124         feed.setOrderByType(orderByType);
125         feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
126         feed.setTargetPortletId(targetPortletId);
127         feed.setContentField(contentField);
128 
129         if (Validator.isNull(feedType)) {
130             feed.setFeedType(RSSUtil.DEFAULT_TYPE);
131             feed.setFeedVersion(RSSUtil.DEFAULT_VERSION);
132         }
133         else {
134             feed.setFeedType(feedType);
135             feed.setFeedVersion(feedVersion);
136         }
137 
138         journalFeedPersistence.update(feed, false);
139 
140         // Resources
141 
142         if (serviceContext.getAddCommunityPermissions() ||
143             serviceContext.getAddGuestPermissions()) {
144 
145             addFeedResources(
146                 feed, serviceContext.getAddCommunityPermissions(),
147                 serviceContext.getAddGuestPermissions());
148         }
149         else {
150             addFeedResources(
151                 feed, serviceContext.getCommunityPermissions(),
152                 serviceContext.getGuestPermissions());
153         }
154 
155         // Expando
156 
157         ExpandoBridge expandoBridge = feed.getExpandoBridge();
158 
159         expandoBridge.setAttributes(serviceContext);
160 
161         return feed;
162     }
163 
164     public void addFeedResources(
165             long feedId, boolean addCommunityPermissions,
166             boolean addGuestPermissions)
167         throws PortalException, SystemException {
168 
169         JournalFeed feed = journalFeedPersistence.findByPrimaryKey(feedId);
170 
171         addFeedResources(feed, addCommunityPermissions, addGuestPermissions);
172     }
173 
174     public void addFeedResources(
175             JournalFeed feed, boolean addCommunityPermissions,
176             boolean addGuestPermissions)
177         throws PortalException, SystemException {
178 
179         resourceLocalService.addResources(
180             feed.getCompanyId(), feed.getGroupId(), feed.getUserId(),
181             JournalFeed.class.getName(), feed.getId(), false,
182             addCommunityPermissions, addGuestPermissions);
183     }
184 
185     public void addFeedResources(
186             long feedId, String[] communityPermissions,
187             String[] guestPermissions)
188         throws PortalException, SystemException {
189 
190         JournalFeed feed = journalFeedPersistence.findByPrimaryKey(feedId);
191 
192         addFeedResources(feed, communityPermissions, guestPermissions);
193     }
194 
195     public void addFeedResources(
196             JournalFeed feed, String[] communityPermissions,
197             String[] guestPermissions)
198         throws PortalException, SystemException {
199 
200         resourceLocalService.addModelResources(
201             feed.getCompanyId(), feed.getGroupId(), feed.getUserId(),
202             JournalFeed.class.getName(), feed.getId(), communityPermissions,
203             guestPermissions);
204     }
205 
206     public void deleteFeed(long feedId)
207         throws PortalException, SystemException {
208 
209         JournalFeed feed = journalFeedPersistence.findByPrimaryKey(feedId);
210 
211         deleteFeed(feed);
212     }
213 
214     public void deleteFeed(long groupId, String feedId)
215         throws PortalException, SystemException {
216 
217         JournalFeed feed = journalFeedPersistence.findByG_F(groupId, feedId);
218 
219         deleteFeed(feed);
220     }
221 
222     public void deleteFeed(JournalFeed feed)
223         throws PortalException, SystemException {
224 
225         // Expando
226 
227         expandoValueLocalService.deleteValues(
228             JournalFeed.class.getName(), feed.getId());
229 
230         // Resources
231 
232         resourceLocalService.deleteResource(
233             feed.getCompanyId(), JournalFeed.class.getName(),
234             ResourceConstants.SCOPE_INDIVIDUAL, feed.getId());
235 
236         // Feed
237 
238         journalFeedPersistence.remove(feed);
239     }
240 
241     public JournalFeed getFeed(long feedId)
242         throws PortalException, SystemException {
243 
244         return journalFeedPersistence.findByPrimaryKey(feedId);
245     }
246 
247     public JournalFeed getFeed(long groupId, String feedId)
248         throws PortalException, SystemException {
249 
250         return journalFeedPersistence.findByG_F(groupId, feedId);
251     }
252 
253     public List<JournalFeed> getFeeds() throws SystemException {
254         return journalFeedPersistence.findAll();
255     }
256 
257     public List<JournalFeed> getFeeds(long groupId) throws SystemException {
258         return journalFeedPersistence.findByGroupId(groupId);
259     }
260 
261     public List<JournalFeed> getFeeds(long groupId, int start, int end)
262         throws SystemException {
263 
264         return journalFeedPersistence.findByGroupId(groupId, start, end);
265     }
266 
267     public int getFeedsCount(long groupId) throws SystemException {
268         return journalFeedPersistence.countByGroupId(groupId);
269     }
270 
271     public List<JournalFeed> search(
272             long companyId, long groupId, String keywords, int start, int end,
273             OrderByComparator obc)
274         throws SystemException {
275 
276         return journalFeedFinder.findByKeywords(
277             companyId, groupId, keywords, start, end, obc);
278     }
279 
280     public List<JournalFeed> search(
281             long companyId, long groupId, String feedId, String name,
282             String description, boolean andOperator, int start, int end,
283             OrderByComparator obc)
284         throws SystemException {
285 
286         return journalFeedFinder.findByC_G_F_N_D(
287             companyId, groupId, feedId, name, description, andOperator, start,
288             end, obc);
289     }
290 
291     public int searchCount(long companyId, long groupId, String keywords)
292         throws SystemException {
293 
294         return journalFeedFinder.countByKeywords(
295             companyId, groupId, keywords);
296     }
297 
298     public int searchCount(
299             long companyId, long groupId, String feedId, String name,
300             String description, boolean andOperator)
301         throws SystemException {
302 
303         return journalFeedFinder.countByC_G_F_N_D(
304             companyId, groupId, feedId, name, description, andOperator);
305     }
306 
307     public JournalFeed updateFeed(
308             long groupId, String feedId, String name, String description,
309             String type, String structureId, String templateId,
310             String rendererTemplateId, int delta, String orderByCol,
311             String orderByType, String targetLayoutFriendlyUrl,
312             String targetPortletId, String contentField, String feedType,
313             double feedVersion, ServiceContext serviceContext)
314         throws PortalException, SystemException{
315 
316         // Feed
317 
318         JournalFeed feed = journalFeedPersistence.findByG_F(groupId, feedId);
319 
320         validate(
321             feed.getCompanyId(), groupId, name, description, structureId,
322             targetLayoutFriendlyUrl, contentField);
323 
324         feed.setModifiedDate(new Date());
325         feed.setName(name);
326         feed.setDescription(description);
327         feed.setType(type);
328         feed.setStructureId(structureId);
329         feed.setTemplateId(templateId);
330         feed.setRendererTemplateId(rendererTemplateId);
331         feed.setDelta(delta);
332         feed.setOrderByCol(orderByCol);
333         feed.setOrderByType(orderByType);
334         feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
335         feed.setTargetPortletId(targetPortletId);
336         feed.setContentField(contentField);
337 
338         if (Validator.isNull(feedType)) {
339             feed.setFeedType(RSSUtil.DEFAULT_TYPE);
340             feed.setFeedVersion(RSSUtil.DEFAULT_VERSION);
341         }
342         else {
343             feed.setFeedType(feedType);
344             feed.setFeedVersion(feedVersion);
345         }
346 
347         journalFeedPersistence.update(feed, false);
348 
349         // Expando
350 
351         ExpandoBridge expandoBridge = feed.getExpandoBridge();
352 
353         expandoBridge.setAttributes(serviceContext);
354 
355         return feed;
356     }
357 
358     protected boolean isValidStructureField(
359         long groupId, String structureId, String contentField) {
360 
361         if (contentField.equals(JournalFeedImpl.WEB_CONTENT_DESCRIPTION) ||
362             contentField.equals(JournalFeedImpl.RENDERED_WEB_CONTENT)) {
363 
364             return true;
365         }
366         else {
367             try {
368                 JournalStructure structure =
369                     journalStructurePersistence.findByG_S(groupId, structureId);
370 
371                 Document doc = SAXReaderUtil.read(structure.getXsd());
372 
373                 XPath xpathSelector = SAXReaderUtil.createXPath(
374                     "//dynamic-element[@name='"+ contentField + "']");
375 
376                 Element el = (Element)xpathSelector.selectSingleNode(doc);
377 
378                 if (el != null) {
379                     return true;
380                 }
381             }
382             catch (Exception e) {
383             }
384         }
385 
386         return false;
387     }
388 
389     protected void validate(
390             long companyId, long groupId, String feedId, boolean autoFeedId,
391             String name, String description, String structureId,
392             String targetLayoutFriendlyUrl, String contentField)
393         throws PortalException, SystemException {
394 
395         if (!autoFeedId) {
396             if ((Validator.isNull(feedId)) || (Validator.isNumber(feedId)) ||
397                 (feedId.indexOf(StringPool.SPACE) != -1)) {
398 
399                 throw new FeedIdException();
400             }
401 
402             JournalFeed feed = journalFeedPersistence.fetchByG_F(
403                 groupId, feedId);
404 
405             if (feed != null) {
406                 throw new DuplicateFeedIdException();
407             }
408         }
409 
410         validate(
411             companyId, groupId, name, description, structureId,
412             targetLayoutFriendlyUrl, contentField);
413     }
414 
415     protected void validate(
416             long companyId, long groupId, String name, String description,
417             String structureId, String targetLayoutFriendlyUrl,
418             String contentField)
419         throws PortalException {
420 
421         if (Validator.isNull(name)) {
422             throw new FeedNameException();
423         }
424 
425         if (Validator.isNull(description)) {
426             throw new FeedDescriptionException();
427         }
428 
429         long plid = PortalUtil.getPlidFromFriendlyURL(
430             companyId, targetLayoutFriendlyUrl);
431 
432         if (plid <= 0) {
433             throw new FeedTargetLayoutFriendlyUrlException();
434         }
435 
436         if (!isValidStructureField(groupId, structureId, contentField)) {
437             throw new FeedContentFieldException();
438         }
439     }
440 
441 }