1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.plugin.news;
21
22 import java.io.InputStream;
23 import java.text.DateFormat;
24 import java.text.SimpleDateFormat;
25 import java.util.Locale;
26 import java.util.StringTokenizer;
27 import java.util.Vector;
28
29 import javax.swing.Action;
30 import javax.swing.SwingUtilities;
31
32 import net.n3.nanoxml.IXMLElement;
33 import net.n3.nanoxml.IXMLParser;
34 import net.n3.nanoxml.IXMLReader;
35 import net.n3.nanoxml.StdXMLReader;
36 import net.n3.nanoxml.XMLParserFactory;
37
38 import org.apache.log4j.Logger;
39 import org.xnap.gui.XNapFrame;
40 import org.xnap.gui.action.PluginDialogAction;
41 import org.xnap.net.HttpConnection;
42 import org.xnap.plugin.AbstractPlugin;
43 import org.xnap.plugin.PluginInfo;
44 import org.xnap.plugin.PluginManager;
45 import org.xnap.util.Scheduler;
46 import org.xnap.util.VersionParser;
47 import org.xnap.util.XNapTask;
48
49 /***
50 * Provides a plugin fetching xnaps release news. */
51 public class NewsPlugin extends AbstractPlugin
52 {
53
54 public static final String XNAP_NEWS_FEED = "http://sourceforge.net/export/rss2_projnews.php?group_id=9285&rss_fulltext=1";
55
56
57
58 private static Logger logger = Logger.getLogger(NewsPlugin.class);
59 private static NewsPlugin instance;
60 private static DateFormat dateFormatter
61 = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
62 private XNapTask updateTask;
63 private NewsPanel newsPanel;
64
65
66
67 public NewsPlugin()
68 {
69 }
70
71
72
73 public static NewsPlugin getInstance()
74 {
75 return instance;
76 }
77
78 /***
79 * Starts the plugin.
80 */
81 public void start()
82 {
83 instance = this;
84 }
85
86 /***
87 * Starts the GUI of the plugin.
88 */
89 public void startGUI()
90 {
91 newsPanel = new NewsPanel();
92 XNapFrame.getInstance().getSearchPanel().setLogoPanel(newsPanel);
93
94
95 updateTask = new UpdateTask();
96 Scheduler.run(0, 12 * 60 * 60 * 1000, updateTask);
97 }
98
99
100 /***
101 * Stops the plugin. Disposes all singletons.
102 */
103 public void stop()
104 {
105 instance = null;
106 }
107
108 /***
109 * Stops the GUI of the plugin.
110 */
111 public void stopGUI()
112 {
113 updateTask.cancel();
114 updateTask = null;
115
116 XNapFrame.getInstance().getSearchPanel().setLogoPanel(null);
117 newsPanel = null;
118 }
119
120 /***
121 * Fetches the XNap news feed. */
122 private void fetchFeed()
123 {
124 try {
125 HttpConnection conn = new HttpConnection();
126 conn.connect(XNAP_NEWS_FEED);
127 InputStream in = conn.getInputStream();
128 IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
129 IXMLReader reader = new StdXMLReader(in);
130 parser.setReader(reader);
131
132 IXMLElement xml = (IXMLElement)parser.parse();
133 Vector items
134 = xml.getFirstChildNamed("channel").getChildrenNamed("item");
135
136 for (int i=0; i < items.size(); i++) {
137 IXMLElement xitem = ((IXMLElement)items.get(i));
138 String title = xitem.getFirstChildNamed("title").getContent();
139 if (isAlreadyInstalled(title)) {
140 continue;
141 }
142
143 final DefaultNewsItem item = new DefaultNewsItem();
144 if (title != null) {
145 item.setTitle(title);
146 }
147 if (xitem.getFirstChildNamed("description") != null) {
148 item.setDescription(xitem.getFirstChildNamed("description").getContent());
149 }
150 if (xitem.getFirstChildNamed("author") != null) {
151 String s = xitem.getFirstChildNamed("author").getContent();
152
153 int j = s.indexOf("@");
154 item.setAuthor((j != -1) ? s.substring(0, j) : s);
155 }
156 if (xitem.getFirstChildNamed("link") != null) {
157 item.setLink(xitem.getFirstChildNamed("link").getContent());
158 }
159 if (xitem.getFirstChildNamed("pubDate") != null) {
160 item.setDate(dateFormatter.parse(xitem.getFirstChildNamed("pubDate").getContent()));
161 }
162
163
164 item.setActions(new Action[] { new PluginDialogAction() });
165
166 Runnable runner = new Runnable()
167 {
168 public void run()
169 {
170 newsPanel.add(item);
171 }
172 };
173 SwingUtilities.invokeLater(runner);
174 }
175
176 }
177 catch (Exception e) {
178 logger.debug("Could not fetch the news feed.", e);
179 }
180 }
181
182 private boolean isAlreadyInstalled(String title)
183 {
184 if (title == null || title.indexOf("released") == -1) {
185 return false;
186 }
187
188 StringTokenizer t = new StringTokenizer(title);
189 if (t.countTokens() == 3) {
190 if (t.nextToken().equals("XNap")) {
191 if (VersionParser.compare(PluginManager.getCoreVersion(),
192 t.nextToken()) >= 0) {
193
194 if (t.nextToken().equals("released")) {
195 return true;
196 }
197 }
198 }
199 }
200 else if (t.countTokens() >= 4) {
201 String plugin = t.nextToken();
202 if (plugin.equals("XNap")) {
203 plugin = t.nextToken();
204 }
205 if (t.nextToken().toLowerCase().equals("plugin")) {
206 PluginInfo info = PluginManager.getInstance().getInfoByName(plugin);
207 String version = t.nextToken();
208 if (info != null
209 && info.isEnabled()
210 && VersionParser.compare(info.getVersion(), version) >= 0) {
211
212 if (t.hasMoreTokens() && t.nextToken().equals("released")) {
213 return true;
214 }
215 }
216 }
217 }
218
219 return false;
220 }
221
222 private class UpdateTask extends XNapTask
223 {
224 public void run()
225 {
226 NewsPlugin.this.fetchFeed();
227 }
228 }
229
230 }