45fbe4f343c52fd60e45f8d6cc1c2bc06fed93e6
[mir.git] / source / mir / rss / RSSReader.java
1 /*\r
2  * Copyright (C) 2001, 2002  The Mir-coders group\r
3  *\r
4  * This file is part of Mir.\r
5  *\r
6  * Mir is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 2 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Mir is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with Mir; if not, write to the Free Software\r
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19  *\r
20  * In addition, as a special exception, The Mir-coders gives permission to link\r
21  * the code of this program with the com.oreilly.servlet library, any library\r
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced\r
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of\r
24  * the above that use the same license as the above), and distribute linked\r
25  * combinations including the two.  You must obey the GNU General Public\r
26  * License in all respects for all of the code used other than the above\r
27  * mentioned libraries.  If you modify this file, you may extend this exception\r
28  * to your version of the file, but you are not obligated to do so.  If you do\r
29  * not wish to do so, delete this exception statement from your version.\r
30  */\r
31 \r
32 package mir.rss;\r
33 \r
34 import java.io.InputStream;\r
35 import java.net.URL;\r
36 import java.util.List;\r
37 import java.util.Map;\r
38 import java.util.Vector;\r
39 \r
40 import mir.util.XMLReader;\r
41 import mir.util.XMLReaderTool;\r
42 \r
43 /**\r
44  *\r
45  * <p>Title: </p>\r
46  * <p>Description: </p>\r
47  * <p>Copyright: Copyright (c) 2003</p>\r
48  * <p>Company: </p>\r
49  * @author not attributable\r
50  * @version 1.0\r
51  */\r
52 \r
53 public class RSSReader {\r
54   public RSSReader() {\r
55   }\r
56 \r
57   public RSSData parseInputStream(InputStream aStream) throws RSSExc, RSSFailure {\r
58     try {\r
59       XMLReader xmlReader = new XMLReader();\r
60       RSSData result = new RSSData();\r
61       xmlReader.parseInputStream(aStream, new RootSectionHandler(result));\r
62 \r
63       return result;\r
64     }\r
65     catch (Throwable t) {\r
66       throw new RSSFailure(t);\r
67     }\r
68   }\r
69 \r
70   public RSSData parseUrl(String anUrl) throws RSSExc, RSSFailure {\r
71     try {\r
72       InputStream inputStream = (InputStream) new URL(anUrl).getContent(new Class[] {InputStream.class});\r
73 \r
74       if (inputStream==null)\r
75         throw new RSSExc("RSSChannel.parseUrl: Can't get url content");\r
76 \r
77       return parseInputStream(inputStream);\r
78     }\r
79     catch (Throwable t) {\r
80       throw new RSSFailure(t);\r
81     }\r
82   }\r
83 \r
84   private static class RootSectionHandler extends XMLReader.AbstractSectionHandler {\r
85     private RSSData data;\r
86 \r
87     public RootSectionHandler(RSSData aData) {\r
88       data = aData;\r
89     }\r
90 \r
91     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {\r
92       if (XMLReaderTool.getLocalNameFromQualifiedName(aTag).equals("RDF")) {\r
93         return new RDFSectionHandler(data);\r
94       }\r
95       else\r
96         throw new XMLReader.XMLReaderFailure(new RSSExc("'RDF' tag expected"));\r
97     };\r
98 \r
99     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {\r
100     };\r
101 \r
102     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {\r
103       if (aCharacters.trim().length()>0)\r
104         throw new XMLReader.XMLReaderExc("No character data allowed here");\r
105     };\r
106 \r
107     public void finishSection() throws XMLReader.XMLReaderExc {\r
108     };\r
109   }\r
110 \r
111   private static class RDFSectionHandler extends XMLReader.AbstractSectionHandler {\r
112     private RSSData data;\r
113 \r
114     public RDFSectionHandler(RSSData aData) {\r
115       data = aData;\r
116     }\r
117 \r
118     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {\r
119       String identifier = (String) anAttributes.get("rdf:about");\r
120 \r
121       if (aTag.equals("channel")) {\r
122         if (identifier==null)\r
123           throw new XMLReader.XMLReaderFailure(new RSSExc("Missing rdf:about"));\r
124         else\r
125           return new ChannelSectionHandler(identifier);\r
126       }\r
127       else if (aTag.equals("item")) {\r
128         if (identifier==null)\r
129           throw new XMLReader.XMLReaderFailure(new RSSExc("Missing rdf:about"));\r
130         else\r
131           return new ItemSectionHandler(identifier);\r
132       }\r
133       else\r
134         return new DiscardingSectionHandler();\r
135     };\r
136 \r
137     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {\r
138       if (aHandler instanceof ItemSectionHandler) {\r
139         data.addItem(((ItemSectionHandler) aHandler).getItem());\r
140       }\r
141       else if (aHandler instanceof ChannelSectionHandler) {\r
142         data.setChannel(((ChannelSectionHandler) aHandler).getChannel());\r
143       }\r
144     };\r
145 \r
146     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {\r
147       if (aCharacters.trim().length()>0)\r
148         throw new XMLReader.XMLReaderExc("No character data allowed here");\r
149     };\r
150 \r
151     public void finishSection() throws XMLReader.XMLReaderExc {\r
152     };\r
153   }\r
154 \r
155   private static class ChannelSectionHandler extends XMLReader.AbstractSectionHandler {\r
156     private String image;\r
157     private String currentTag;\r
158     private RSSChannel channel;\r
159 \r
160     public ChannelSectionHandler(String anIdentifier) {\r
161       channel = new RSSChannel(anIdentifier);\r
162     }\r
163 \r
164     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {\r
165       currentTag = aTag;\r
166       if (currentTag.equals("items")) {\r
167         return new ChannelItemsSectionHandler();\r
168       }\r
169       else if (currentTag.equals("description") ||\r
170                currentTag.equals("link") ||\r
171                currentTag.equals("title")) {\r
172         return new PCDATASectionHandler();\r
173       }\r
174 \r
175       return new DiscardingSectionHandler();\r
176     };\r
177 \r
178     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {\r
179       if (currentTag.equals("items")) {\r
180         channel.setItems(((ChannelItemsSectionHandler) aHandler).getItems());\r
181       }\r
182       if (currentTag.equals("description")) {\r
183         channel.setDescription(((PCDATASectionHandler) aHandler).getData());\r
184       }\r
185       else if (currentTag.equals("title")) {\r
186         channel.setTitle(((PCDATASectionHandler) aHandler).getData());\r
187       }\r
188       else if (currentTag.equals("link")) {\r
189         channel.setLink(((PCDATASectionHandler) aHandler).getData());\r
190       }\r
191     };\r
192 \r
193     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {\r
194       if (aCharacters.trim().length()>0)\r
195         throw new XMLReader.XMLReaderExc("No character data allowed here");\r
196     };\r
197 \r
198     public void finishSection() throws XMLReader.XMLReaderExc {\r
199     };\r
200 \r
201     public RSSChannel getChannel () {\r
202       return channel;\r
203     }\r
204   }\r
205 \r
206   private static class ChannelItemsSectionHandler extends XMLReader.AbstractSectionHandler {\r
207     private List items;\r
208 \r
209     public ChannelItemsSectionHandler() {\r
210       items = new Vector();\r
211     }\r
212 \r
213     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {\r
214       if (aTag.equals("rdf:Seq"))\r
215         return new RDFSequenceSectionHandler();\r
216       else\r
217         return new DiscardingSectionHandler();\r
218     };\r
219 \r
220     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {\r
221       if (aHandler instanceof RDFSequenceSectionHandler) {\r
222         items.addAll(((RDFSequenceSectionHandler) aHandler).getItems());\r
223       }\r
224     };\r
225 \r
226     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {\r
227       if (aCharacters.trim().length()>0)\r
228         throw new XMLReader.XMLReaderExc("No character data allowed here");\r
229     };\r
230 \r
231     public void finishSection() throws XMLReader.XMLReaderExc {\r
232     };\r
233 \r
234     public List getItems() {\r
235       return items;\r
236     }\r
237   }\r
238 \r
239   private static class ItemSectionHandler extends XMLReader.AbstractSectionHandler {\r
240     private String currentTag;\r
241     private RSSItem item;\r
242 \r
243     public ItemSectionHandler(String anIdentifier) {\r
244       item = new RSSItem(anIdentifier);\r
245     }\r
246 \r
247     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {\r
248       currentTag = aTag;\r
249 \r
250       if (currentTag.equals("description") ||\r
251                currentTag.equals("link") ||\r
252                currentTag.equals("title")) {\r
253         return new PCDATASectionHandler();\r
254       }\r
255 \r
256       return new DiscardingSectionHandler();\r
257     };\r
258 \r
259     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {\r
260       if (currentTag.equals("description")) {\r
261         item.setDescription(((PCDATASectionHandler) aHandler).getData());\r
262       }\r
263       else if (currentTag.equals("title")) {\r
264         item.setTitle(((PCDATASectionHandler) aHandler).getData());\r
265       }\r
266       else if (currentTag.equals("link")) {\r
267         item.setLink(((PCDATASectionHandler) aHandler).getData());\r
268       }\r
269     };\r
270 \r
271     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {\r
272       if (aCharacters.trim().length()>0)\r
273         throw new XMLReader.XMLReaderExc("No character data allowed here");\r
274     };\r
275 \r
276     public void finishSection() throws XMLReader.XMLReaderExc {\r
277     };\r
278 \r
279     public RSSItem getItem() {\r
280       return item;\r
281     };\r
282   }\r
283 \r
284   private static class PCDATASectionHandler extends XMLReader.AbstractSectionHandler {\r
285     private StringBuffer data;\r
286 \r
287     public PCDATASectionHandler() {\r
288       data = new StringBuffer();\r
289     }\r
290 \r
291     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {\r
292       throw new XMLReader.XMLReaderFailure(new RSSExc("No subtags allowed here"));\r
293     };\r
294 \r
295     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {\r
296     };\r
297 \r
298     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {\r
299       data.append(aCharacters);\r
300     };\r
301 \r
302     public void finishSection() throws XMLReader.XMLReaderExc {\r
303     };\r
304 \r
305     public String getData() {\r
306       return data.toString();\r
307     }\r
308   }\r
309 \r
310 \r
311   private static class RDFSequenceSectionHandler extends XMLReader.AbstractSectionHandler {\r
312     private List items;\r
313 \r
314     public RDFSequenceSectionHandler() {\r
315       items = new Vector();\r
316     }\r
317 \r
318     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {\r
319       if (aTag.equals("rdf:li")) {\r
320         String item = (String) anAttributes.get("rdf:resource");\r
321 \r
322         if (item!=null)\r
323           items.add(item);\r
324       }\r
325 \r
326       return new DiscardingSectionHandler();\r
327     };\r
328 \r
329     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {\r
330     };\r
331 \r
332     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {\r
333     };\r
334 \r
335     public void finishSection() throws XMLReader.XMLReaderExc {\r
336     };\r
337 \r
338     public List getItems() {\r
339       return items;\r
340     }\r
341   }\r
342 \r
343   private static class RDFLiteralSectionHandler extends XMLReader.AbstractSectionHandler {\r
344     private StringBuffer data;\r
345     private String tag;\r
346 \r
347     public RDFLiteralSectionHandler() {\r
348       data = new StringBuffer();\r
349     }\r
350 \r
351     protected StringBuffer getData() {\r
352       return data;\r
353     }\r
354 \r
355     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {\r
356       tag=aTag;\r
357       data.append("<"+tag+">");\r
358 \r
359       return new RDFLiteralSectionHandler();\r
360     };\r
361 \r
362     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {\r
363       data.append(((RDFLiteralSectionHandler) aHandler).getData());\r
364       data.append("</"+tag+">");\r
365     };\r
366 \r
367     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {\r
368       data.append(aCharacters);\r
369     };\r
370 \r
371     public void finishSection() throws XMLReader.XMLReaderExc {\r
372     };\r
373   }\r
374 \r
375   private static class DiscardingSectionHandler extends XMLReader.AbstractSectionHandler {\r
376     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {\r
377       return this;\r
378     };\r
379 \r
380     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {\r
381     };\r
382 \r
383     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {\r
384     };\r
385 \r
386     public void finishSection() throws XMLReader.XMLReaderExc {\r
387     };\r
388   }\r
389 }\r