1.1 restoration
[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.net.URL;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Vector;
39
40 import mir.util.HTTPClientHelper;
41 import mir.util.xml.*;
42 import mir.util.xml.XMLParserEngine;
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       else
159         throw new XMLParserFailure(new RSSExc("'rss' tag expected"));
160     };
161
162     public void endElement(mir.util.xml.SectionHandler aHandler) throws XMLParserExc {
163     };
164
165     public void characters(String aCharacters) throws XMLParserExc {
166       if (aCharacters.trim().length()>0)
167         throw new XMLParserExc("No character data allowed here");
168     };
169
170     public void finishSection() throws XMLParserExc {
171     };
172   }
173
174   private class RSS091SectionHandler extends mir.util.xml.AbstractSectionHandler {
175     private RSSData data;
176
177
178     public RSS091SectionHandler(RSSData aData) {
179       data = aData;
180     }
181
182     public mir.util.xml.SectionHandler startElement(mir.util.xml.XMLName aTag, Map anAttributes) throws XMLParserExc {
183       if (aTag.getLocalName().equals("channel"))
184         return new RSS091ChannelSectionHandler(data);
185       else
186         throw new XMLParserExc("channel tag expected, " + aTag.getLocalName() + " found");
187     };
188
189     public void characters(String aCharacters) throws XMLParserExc {
190       if (aCharacters.trim().length()>0)
191         throw new XMLParserExc("No character data allowed here");
192     };
193
194     public void finishSection() throws XMLParserExc {
195     };
196   }
197
198   private class RSS091ChannelSectionHandler extends mir.util.xml.AbstractSectionHandler {
199     private String currentTag;
200
201     private RSSData data;
202     private List items;
203     private RDFResource channel;
204     private Map attributes;
205
206     public RSS091ChannelSectionHandler(RSSData aData) {
207       data = aData;
208       items = new Vector();
209       channel = new RDFResource("rss:channel");
210       attributes = new HashMap();
211     }
212
213     public mir.util.xml.SectionHandler startElement(mir.util.xml.XMLName aTag, Map anAttributes) throws XMLParserExc {
214       String tag = aTag.getLocalName();
215
216       if (tag.equals("item"))
217         return new RSS091ItemSectionHandler();
218       else if (mappedChannelProperties.containsKey(tag)) {
219         currentTag=(String) mappedChannelProperties.get(tag);
220         return new PCDATASectionHandler();
221       }
222       else
223         return new DiscardingSectionHandler();
224     };
225
226     public void endElement(mir.util.xml.SectionHandler aHandler) throws XMLParserExc {
227       if (aHandler instanceof PCDATASectionHandler) {
228         attributes.put(currentTag, (((PCDATASectionHandler) aHandler).getData()));
229       }
230       else if (aHandler instanceof RSS091ItemSectionHandler) {
231         items.add((((RSS091ItemSectionHandler) aHandler).getItem()));
232       }
233     };
234
235     public void characters(String aCharacters) throws XMLParserExc {
236       if (aCharacters.trim().length()>0)
237         throw new XMLParserExc("No character data allowed here");
238     };
239
240     public void finishSection() throws XMLParserExc {
241       Iterator i = items.iterator();
242
243       while (i.hasNext()) {
244         data.addResource((RDFResource) i.next());
245       }
246     };
247   }
248
249   private class RSS091ItemSectionHandler extends mir.util.xml.AbstractSectionHandler {
250     private String currentTag;
251
252     private RDFResource item;
253     private Map attributes;
254
255     public RSS091ItemSectionHandler() {
256       attributes = new HashMap();
257     }
258
259     public mir.util.xml.SectionHandler startElement(mir.util.xml.XMLName aTag, Map anAttributes) throws XMLParserExc {
260       String tag = aTag.getLocalName();
261
262       if (mappedItemProperties.containsKey(tag)) {
263         currentTag=(String) mappedItemProperties.get(tag);
264         return new PCDATASectionHandler();
265       }
266       else
267         return new DiscardingSectionHandler();
268     };
269
270     public void endElement(mir.util.xml.SectionHandler aHandler) throws XMLParserExc {
271       if (aHandler instanceof PCDATASectionHandler) {
272         attributes.put(currentTag, (((PCDATASectionHandler) aHandler).getData()));
273       }
274     };
275
276     public void characters(String aCharacters) throws XMLParserExc {
277       if (aCharacters.trim().length()>0)
278         throw new XMLParserExc("No character data allowed here");
279     };
280
281     public void finishSection() throws XMLParserExc {
282       item = new RDFResource("rss:item", (String) attributes.get("rss:link"));
283
284       Iterator i = attributes.entrySet().iterator();
285       while (i.hasNext()) {
286         Map.Entry entry = (Map.Entry) i.next();
287
288         item.set((String) entry.getKey(), entry.getValue());
289       }
290     };
291
292     public RDFResource getItem() {
293       return item;
294     }
295   }
296
297
298   private class PCDATASectionHandler extends mir.util.xml.AbstractSectionHandler {
299     private StringBuffer data;
300
301     public PCDATASectionHandler() {
302       data = new StringBuffer();
303     }
304
305     public mir.util.xml.SectionHandler startElement(String aTag, Map anAttributes) throws XMLParserExc {
306       throw new XMLParserFailure(new RSSExc("No subtags allowed here"));
307     };
308
309     public void endElement(mir.util.xml.SectionHandler aHandler) throws XMLParserExc {
310     };
311
312     public void characters(String aCharacters) throws XMLParserExc {
313       data.append(aCharacters);
314     };
315
316     public void finishSection() throws XMLParserExc {
317     };
318
319     public String getData() {
320       return data.toString();
321     }
322   }
323
324
325   private class RDFSequenceSectionHandler extends mir.util.xml.AbstractSectionHandler {
326     private List items;
327
328     public RDFSequenceSectionHandler() {
329       items = new Vector();
330     }
331
332     public mir.util.xml.SectionHandler startElement(String aTag, Map anAttributes) throws XMLParserExc {
333       if (aTag.equals("rdf:li")) {
334         String item = (String) anAttributes.get("rdf:resource");
335
336         if (item!=null)
337           items.add(item);
338       }
339
340       return new DiscardingSectionHandler();
341     };
342
343     public void endElement(mir.util.xml.SectionHandler aHandler) throws XMLParserExc {
344     };
345
346     public void characters(String aCharacters) throws XMLParserExc {
347     };
348
349     public void finishSection() throws XMLParserExc {
350     };
351
352     public List getItems() {
353       return items;
354     }
355   }
356
357   private class DiscardingSectionHandler extends mir.util.xml.AbstractSectionHandler {
358     public mir.util.xml.SectionHandler startElement(String aTag, Map anAttributes) throws XMLParserExc {
359       return this;
360     };
361
362     public void endElement(mir.util.xml.SectionHandler aHandler) throws XMLParserExc {
363     };
364
365     public void characters(String aCharacters) throws XMLParserExc {
366     };
367
368     public void finishSection() throws XMLParserExc {
369     };
370   }
371 }