View Javadoc

1   /*
2    * Copyright 2004 Sun Microsystems, Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  package com.sun.syndication.io;
18  
19  import com.sun.syndication.feed.WireFeed;
20  import com.sun.syndication.io.impl.FeedParsers;
21  import org.jdom.Document;
22  import org.jdom.input.DOMBuilder;
23  import org.jdom.input.JDOMParseException;
24  import org.jdom.input.SAXBuilder;
25  import org.xml.sax.InputSource;
26  import org.xml.sax.EntityResolver;
27  
28  import java.io.*;
29  import java.util.List;
30  
31  /***
32   * Parses an XML document (File, InputStream, Reader, W3C SAX InputSource, W3C DOM Document or JDom DOcument)
33   * into an WireFeed (RSS/Atom).
34   * <p>
35   * It accepts all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0) and
36   * Atom 0.3 feeds. Parsers are plugable (they must implement the WireFeedParser interface).
37   * <p>
38   * The WireFeedInput useds liberal parsers.
39   * <p>
40   * @author Alejandro Abdelnur
41   *
42   */
43  public class WireFeedInput {
44      private static FeedParsers FEED_PARSERS = new FeedParsers();
45      private static final InputSource EMPTY_INPUTSOURCE = new InputSource(new ByteArrayInputStream(new byte[0]));
46      private static final EntityResolver RESOLVER = new EmptyEntityResolver();
47  
48      private static class EmptyEntityResolver implements EntityResolver {
49          public InputSource resolveEntity(String publicId, String systemId) {
50              if(systemId != null && systemId.endsWith(".dtd")) return EMPTY_INPUTSOURCE;
51              return null;
52          }
53      }
54      private boolean _validate;
55  
56      /***
57       * Returns the list of supported input feed types.
58       * <p>
59       * @see WireFeed for details on the format of these strings.
60       * <p>
61       * @return a list of String elements with the supported input feed types.
62       *
63       */
64      public static List getSupportedFeedTypes() {
65          return FEED_PARSERS.getSupportedFeedTypes();
66      }
67  
68      /***
69       * Creates a WireFeedInput instance with input validation turned off.
70       * <p>
71       *
72       */
73      public WireFeedInput() {
74          this (false);
75      }
76  
77      /***
78       * Creates a WireFeedInput instance.
79       * <p>
80       * @param validate indicates if the input should be validated. NOT IMPLEMENTED YET (validation does not happen)
81       *
82       */
83      public WireFeedInput(boolean validate) {
84          _validate = false; // TODO FIX THIS THINGY
85      }
86  
87      /***
88       * Builds an WireFeed (RSS or Atom) from a file.
89       * <p>
90       * NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom.Document)'.
91       * <p>
92       * @param file file to read to create the WireFeed.
93       * @return the WireFeed read from the file.
94       * @throws FileNotFoundException thrown if the file could not be found.
95       * @throws IOException thrown if there is problem reading the file.
96       * @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers.
97       * @throws FeedException if the feed could not be parsed
98       *
99       */
100     public WireFeed build(File file) throws FileNotFoundException,IOException,IllegalArgumentException,FeedException {
101         WireFeed feed;
102         Reader reader = new FileReader(file);
103         feed = build(reader);
104         reader.close();
105         return feed;
106     }
107 
108     /***
109      * Builds an WireFeed (RSS or Atom) from an Reader.
110      * <p>
111      * NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom.Document)'.
112      * <p>
113      * @param reader Reader to read to create the WireFeed.
114      * @return the WireFeed read from the Reader.
115      * @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers.
116      * @throws FeedException if the feed could not be parsed
117      *
118      */
119     public WireFeed build(Reader reader) throws IllegalArgumentException,FeedException {
120         SAXBuilder saxBuilder = new SAXBuilder(_validate);
121         saxBuilder.setEntityResolver(RESOLVER);
122         try {            
123             Document document = saxBuilder.build(reader);            
124             return build(document);
125         }
126         catch (JDOMParseException ex) {
127             throw new ParsingFeedException("Invalid XML: " + ex.getMessage(), ex);
128         }
129         catch (Exception ex) {  
130             throw new ParsingFeedException("Invalid XML",ex);
131         }
132     }
133 
134     /***
135      * Builds an WireFeed (RSS or Atom) from an W3C SAX InputSource.
136      * <p>
137      * NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom.Document)'.
138      * <p>
139      * @param is W3C SAX InputSource to read to create the WireFeed.
140      * @return the WireFeed read from the W3C SAX InputSource.
141      * @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers.
142      * @throws FeedException if the feed could not be parsed
143      *
144      */
145     public WireFeed build(InputSource is) throws IllegalArgumentException,FeedException {
146         SAXBuilder saxBuilder = new SAXBuilder(_validate);
147         saxBuilder.setEntityResolver(RESOLVER);
148         try {
149             Document document = saxBuilder.build(is);
150             return build(document);
151         }
152         catch (JDOMParseException ex) {
153             throw new ParsingFeedException("Invalid XML: " + ex.getMessage(), ex);
154         }
155         catch (Exception ex) {  
156             throw new ParsingFeedException("Invalid XML",ex);
157         }
158     }
159 
160     /***
161      * Builds an WireFeed (RSS or Atom) from an W3C DOM document.
162      * <p>
163      * NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom.Document)'.
164      * <p>
165      * @param document W3C DOM document to read to create the WireFeed.
166      * @return the WireFeed read from the W3C DOM document.
167      * @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers.
168      * @throws FeedException if the feed could not be parsed
169      *
170      */
171     public WireFeed build(org.w3c.dom.Document document) throws IllegalArgumentException,FeedException {
172         DOMBuilder domBuilder = new DOMBuilder();
173         try {
174             Document jdomDoc = domBuilder.build(document);
175             return build(jdomDoc);
176         }
177         catch (Exception ex) {
178             throw new ParsingFeedException("Invalid XML",ex);
179         }
180     }
181 
182     /***
183      * Builds an WireFeed (RSS or Atom) from an JDOM document.
184      * <p>
185      * NOTE: All other build methods delegate to this method.
186      * <p>
187      * @param document JDOM document to read to create the WireFeed.
188      * @return the WireFeed read from the JDOM document.
189      * @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers.
190      * @throws FeedException if the feed could not be parsed
191      *
192      */
193     public WireFeed build(Document document) throws IllegalArgumentException,FeedException {
194         WireFeedParser parser = FEED_PARSERS.getParserFor(document);
195         if (parser==null) {
196             throw new IllegalArgumentException("Invalid document");
197         }
198         return parser.parse(document, _validate);
199     }
200 }