Source code: com/xpn/xwiki/plugin/feed/FeedPlugin.java
1 /**
2 * ===================================================================
3 *
4 * Copyright (c) 2003,2004 Ludovic Dubost, All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details, published at
15 * http://www.gnu.org/copyleft/lesser.html or in lesser.txt in the
16 * root folder of this distribution.
17
18 * Created by
19 * User: Ludovic Dubost
20 * Date: 23 avr. 2005
21 * Time: 00:21:43
22 */
23 package com.xpn.xwiki.plugin.feed;
24
25 import com.xpn.xwiki.plugin.XWikiDefaultPlugin;
26 import com.xpn.xwiki.plugin.XWikiPluginInterface;
27 import com.xpn.xwiki.XWikiContext;
28 import com.xpn.xwiki.XWikiException;
29 import com.xpn.xwiki.api.Api;
30 import com.xpn.xwiki.cache.api.XWikiCache;
31 import com.xpn.xwiki.cache.api.XWikiCacheNeedsRefreshException;
32 import com.xpn.xwiki.cache.impl.OSCacheCache;
33 import com.sun.syndication.feed.synd.SyndFeed;
34 import com.sun.syndication.feed.synd.SyndFeedImpl;
35 import com.sun.syndication.feed.synd.SyndEntry;
36 import com.sun.syndication.io.SyndFeedInput;
37 import com.sun.syndication.io.XmlReader;
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41 import java.net.URL;
42 import java.io.IOException;
43 import java.util.*;
44
45 public class FeedPlugin extends XWikiDefaultPlugin implements XWikiPluginInterface {
46 private static Log mLogger =
47 LogFactory.getFactory().getInstance(com.xpn.xwiki.plugin.feed.FeedPlugin.class);
48
49 private XWikiCache feedCache;
50 private int refreshPeriod;
51
52 public static class SyndEntryComparator implements Comparator {
53
54 public int compare(Object element1, Object element2) {
55 SyndEntry entry1 = (SyndEntry) element1;
56 SyndEntry entry2 = (SyndEntry) element2;
57
58 if ((entry1.getPublishedDate() == null) && (entry2.getPublishedDate() == null))
59 return 0;
60 if (entry1.getPublishedDate() == null)
61 return 1;
62 if (entry2.getPublishedDate() == null)
63 return -1;
64 return (-entry1.getPublishedDate().compareTo(entry2.getPublishedDate()));
65 }
66 }
67
68
69 public FeedPlugin(String name, String className, XWikiContext context) {
70 super(name, className, context);
71 init(context);
72 }
73
74 public String getName() {
75 return "feed";
76 }
77
78 public Api getPluginApi(XWikiPluginInterface plugin, XWikiContext context) {
79 return new FeedPluginApi((FeedPlugin) plugin, context);
80 }
81
82 public void flushCache() {
83 if (feedCache!=null)
84 feedCache.flushAll();
85 }
86
87 public void init(XWikiContext context) {
88 super.init(context);
89 feedCache = new OSCacheCache();
90 refreshPeriod = (int) context.getWiki().ParamAsLong("xwiki.plugins.feed.cacherefresh", 3600);
91 }
92
93 public SyndFeed getFeeds(String sfeeds, XWikiContext context) throws IOException {
94 String[] feeds;
95 if (sfeeds.indexOf("\n") != -1)
96 feeds = sfeeds.split("\n");
97 else
98 feeds = sfeeds.split("\\|");
99 List entries = new ArrayList();
100 SyndFeed outputFeed = new SyndFeedImpl();
101 if (context.getDoc() != null)
102 {
103 outputFeed.setTitle(context.getDoc().getFullName());
104 try {
105 outputFeed.setUri(context.getWiki().getURL(context.getDoc().getFullName(), "view", context));
106 } catch (XWikiException e) {
107 e.printStackTrace();
108 }
109 outputFeed.setAuthor(context.getDoc().getAuthor());
110 }
111 else
112 {
113 outputFeed.setTitle("XWiki Feeds");
114 outputFeed.setAuthor("XWiki Team");
115 }
116 outputFeed.setEntries(entries);
117 for (int i = 0; i < feeds.length; i++)
118 {
119 SyndFeed feed = getFeed(feeds[i], context);
120 if (feed != null)
121 entries.addAll(feed.getEntries());
122 }
123 SyndEntryComparator comp = new SyndEntryComparator();
124 Collections.sort(entries, comp);
125 return outputFeed;
126 }
127
128
129 public SyndFeed getFeed(String sfeed, XWikiContext context) throws IOException {
130 return getFeed(sfeed, false, context);
131 }
132
133 public SyndFeed getFeed(String sfeed, boolean force, XWikiContext context) throws IOException {
134 SyndFeed feed = null;
135 if (!force)
136 try {
137 feed = (SyndFeed) feedCache.getFromCache(sfeed, refreshPeriod);
138
139 } catch (XWikiCacheNeedsRefreshException e) {
140 feedCache.cancelUpdate(sfeed);
141 } catch (Exception e) {
142 }
143
144 if (feed==null)
145 feed = getFeedForce(sfeed, context);
146
147 if (feed!=null)
148 feedCache.putInCache(sfeed, feed);
149
150 return feed;
151 }
152
153 public SyndFeed getFeedForce(String sfeed, XWikiContext context) throws IOException {
154 SyndFeedInput input = new SyndFeedInput();
155 SyndFeed feed = null;
156 URL feedURL = new URL(sfeed);
157 try {
158 feed = input.build(new XmlReader(feedURL));
159 }
160 catch (Exception ex) {
161 throw new java.io.IOException("Error processing " + feedURL + ": " + ex.getMessage());
162 }
163 return feed;
164 }
165 }