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