7e85c691a3ca3c17ef4e7e4c6b8876fb35a6ef93
[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.XMLReader;
41
42 /**
43  *
44  * <p>Title: </p>
45  * <p>Description: </p>
46  * <p>Copyright: Copyright (c) 2003</p>
47  * <p>Company: </p>
48  * @author not attributable
49  * @version 1.0
50  */
51
52 public class RSS091Reader {
53   private final static String MAPPED_CHANNEL_PROPERTIES[][]  =
54      {
55        {"link",        "rss:link"        },
56        {"title",       "rss:title"       },
57        {"description", "rss:description" },
58        {"item",        "rss:item" },
59        {"language",    "dc:language" }
60      };
61
62   private final static String MAPPED_ITEM_PROPERTIES[][]  =
63     {
64       {"link",        "rss:link"        },
65       {"title",       "rss:title"       },
66       {"description", "rss:description" },
67       {"author",      "dc:creator" },
68     };
69
70   private Map mappedChannelProperties = new HashMap();
71   private Map mappedItemProperties = new HashMap();
72
73   public RSS091Reader() {
74     int i;
75
76     for (i=0; i<MAPPED_CHANNEL_PROPERTIES.length; i++) {
77       mappedChannelProperties.put(MAPPED_CHANNEL_PROPERTIES[i][0], MAPPED_CHANNEL_PROPERTIES[i][1]);
78     }
79
80     for (i=0; i<MAPPED_ITEM_PROPERTIES.length; i++) {
81       mappedItemProperties.put(MAPPED_ITEM_PROPERTIES[i][0], MAPPED_ITEM_PROPERTIES[i][1]);
82     }
83   }
84
85   public RSSData parseInputStream(InputStream aStream) throws RSSExc, RSSFailure {
86     try {
87       XMLReader xmlReader = new XMLReader(false);
88       RSSData result = new RSSData();
89       xmlReader.parseInputStream(aStream, new RootSectionHandler(result));
90
91       return result;
92     }
93     catch (Throwable t) {
94       throw new RSSFailure(t);
95     }
96   }
97
98   public RSSData parseUrl(String anUrl) throws RSSExc, RSSFailure {
99     try {
100       InputStream inputStream = (InputStream) new URL(anUrl).getContent(new Class[] {InputStream.class});
101
102       if (inputStream==null)
103         throw new RSSExc("RSSChannel.parseUrl: Can't get url content");
104
105       return parseInputStream(inputStream);
106     }
107     catch (Throwable t) {
108       throw new RSSFailure(t);
109     }
110   }
111
112   private class RootSectionHandler extends XMLReader.AbstractSectionHandler {
113     private RSSData data;
114
115     public RootSectionHandler(RSSData aData) {
116       data = aData;
117     }
118
119     public XMLReader.SectionHandler startElement(XMLReader.XMLName aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
120       if (aTag.getLocalName().equals("rss")) {
121         return new RSS091SectionHandler(data);
122       }
123       else
124         throw new XMLReader.XMLReaderFailure(new RSSExc("'rss' tag expected"));
125     };
126
127     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
128     };
129
130     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {
131       if (aCharacters.trim().length()>0)
132         throw new XMLReader.XMLReaderExc("No character data allowed here");
133     };
134
135     public void finishSection() throws XMLReader.XMLReaderExc {
136     };
137   }
138
139   private class RSS091SectionHandler extends XMLReader.AbstractSectionHandler {
140     private RSSData data;
141
142
143     public RSS091SectionHandler(RSSData aData) {
144       data = aData;
145     }
146
147     public XMLReader.SectionHandler startElement(XMLReader.XMLName aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
148       if (aTag.getLocalName().equals("channel"))
149         return new RSS091ChannelSectionHandler(data);
150       else
151         throw new XMLReader.XMLReaderExc("channel tag expected, " + aTag.getLocalName() + " found");
152     };
153
154     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {
155       if (aCharacters.trim().length()>0)
156         throw new XMLReader.XMLReaderExc("No character data allowed here");
157     };
158
159     public void finishSection() throws XMLReader.XMLReaderExc {
160     };
161   }
162
163   private class RSS091ChannelSectionHandler extends XMLReader.AbstractSectionHandler {
164     private String currentTag;
165
166     private RSSData data;
167     private List items;
168     private RDFResource channel;
169     private Map attributes;
170
171     public RSS091ChannelSectionHandler(RSSData aData) {
172       data = aData;
173       items = new Vector();
174       channel = new RDFResource("rss:channel");
175       attributes = new HashMap();
176     }
177
178     public XMLReader.SectionHandler startElement(XMLReader.XMLName aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
179       String tag = aTag.getLocalName();
180
181       if (tag.equals("item"))
182         return new RSS091ItemSectionHandler();
183       else if (mappedChannelProperties.containsKey(tag)) {
184         currentTag=(String) mappedChannelProperties.get(tag);
185         return new PCDATASectionHandler();
186       }
187       else
188         return new DiscardingSectionHandler();
189     };
190
191     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
192       if (aHandler instanceof PCDATASectionHandler) {
193         attributes.put(currentTag, (((PCDATASectionHandler) aHandler).getData()));
194       }
195       else if (aHandler instanceof RSS091ItemSectionHandler) {
196         items.add((((RSS091ItemSectionHandler) aHandler).getItem()));
197       }
198     };
199
200     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {
201       if (aCharacters.trim().length()>0)
202         throw new XMLReader.XMLReaderExc("No character data allowed here");
203     };
204
205     public void finishSection() throws XMLReader.XMLReaderExc {
206       Iterator i = items.iterator();
207
208       while (i.hasNext()) {
209         data.addResource((RDFResource) i.next());
210       }
211     };
212   }
213
214   private class RSS091ItemSectionHandler extends XMLReader.AbstractSectionHandler {
215     private String currentTag;
216
217     private RDFResource item;
218     private Map attributes;
219
220     public RSS091ItemSectionHandler() {
221       attributes = new HashMap();
222     }
223
224     public XMLReader.SectionHandler startElement(XMLReader.XMLName aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
225       String tag = aTag.getLocalName();
226       System.out.println(tag);
227
228       if (mappedItemProperties.containsKey(tag)) {
229         currentTag=(String) mappedItemProperties.get(tag);
230         return new PCDATASectionHandler();
231       }
232       else
233         return new DiscardingSectionHandler();
234     };
235
236     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
237       if (aHandler instanceof PCDATASectionHandler) {
238         attributes.put(currentTag, (((PCDATASectionHandler) aHandler).getData()));
239       }
240     };
241
242     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {
243       if (aCharacters.trim().length()>0)
244         throw new XMLReader.XMLReaderExc("No character data allowed here");
245     };
246
247     public void finishSection() throws XMLReader.XMLReaderExc {
248       item = new RDFResource("rss:item", (String) attributes.get("rss:link"));
249
250       Iterator i = attributes.entrySet().iterator();
251       while (i.hasNext()) {
252         Map.Entry entry = (Map.Entry) i.next();
253
254         item.set((String) entry.getKey(), entry.getValue());
255       }
256     };
257
258     public RDFResource getItem() {
259       return item;
260     }
261   }
262
263
264   private class PCDATASectionHandler extends XMLReader.AbstractSectionHandler {
265     private StringBuffer data;
266
267     public PCDATASectionHandler() {
268       data = new StringBuffer();
269     }
270
271     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
272       throw new XMLReader.XMLReaderFailure(new RSSExc("No subtags allowed here"));
273     };
274
275     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
276     };
277
278     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {
279       data.append(aCharacters);
280     };
281
282     public void finishSection() throws XMLReader.XMLReaderExc {
283     };
284
285     public String getData() {
286       return data.toString();
287     }
288   }
289
290
291   private class RDFSequenceSectionHandler extends XMLReader.AbstractSectionHandler {
292     private List items;
293
294     public RDFSequenceSectionHandler() {
295       items = new Vector();
296     }
297
298     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
299       if (aTag.equals("rdf:li")) {
300         String item = (String) anAttributes.get("rdf:resource");
301
302         if (item!=null)
303           items.add(item);
304       }
305
306       return new DiscardingSectionHandler();
307     };
308
309     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
310     };
311
312     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {
313     };
314
315     public void finishSection() throws XMLReader.XMLReaderExc {
316     };
317
318     public List getItems() {
319       return items;
320     }
321   }
322
323   private class DiscardingSectionHandler extends XMLReader.AbstractSectionHandler {
324     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
325       return this;
326     };
327
328     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
329     };
330
331     public void characters(String aCharacters) throws XMLReader.XMLReaderExc {
332     };
333
334     public void finishSection() throws XMLReader.XMLReaderExc {
335     };
336   }
337 }