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.FeedGenerators;
21  import org.jdom.Document;
22  import org.jdom.JDOMException;
23  import org.jdom.output.DOMOutputter;
24  import org.jdom.output.Format;
25  import org.jdom.output.XMLOutputter;
26  
27  import java.io.IOException;
28  import java.io.Writer;
29  import java.io.File;
30  import java.io.FileWriter;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.WeakHashMap;
34  
35  /***
36   * Generates an XML document (String, File, OutputStream, Writer, W3C DOM document or JDOM document)
37   * out of an WireFeed (RSS/Atom).
38   * <p>
39   * It generates all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0) and
40   * Atom 0.3 feeds. Generators are plugable (they must implement the ModuleParser interface).
41   * <p>
42   * @author Alejandro Abdelnur
43   *
44   */
45  public class WireFeedOutput {
46      private static Map clMap = new WeakHashMap();
47  
48      private static FeedGenerators getFeedGenerators() {
49          synchronized(WireFeedOutput.class) {
50              FeedGenerators generators = (FeedGenerators)
51                  clMap.get(Thread.currentThread().getContextClassLoader());
52              if (generators == null) {
53                  generators = new FeedGenerators();
54                  clMap.put(Thread.currentThread().getContextClassLoader(), generators);
55              }
56              return generators;
57          }
58      }
59  
60      /***
61       * Returns the list of supported output feed types.
62       * <p>
63       * @see WireFeed for details on the format of these strings.
64       * <p>
65       * @return a list of String elements with the supported output feed types.
66       *
67       */
68      public static List getSupportedFeedTypes() {
69          return getFeedGenerators().getSupportedFeedTypes();
70      }
71  
72      /***
73       * Creates a FeedOuput instance.
74       * <p>
75       *
76       */
77      public WireFeedOutput() {
78      }
79  
80      /***
81       * Creates a String with the XML representation for the given WireFeed.
82       * <p>
83       * If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility
84       * of the developer to ensure that if the String is written to a character stream the stream charset is the same as
85       * the feed encoding property.
86       * <p>
87       * NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'.
88       * <p>
89       * @param feed Abstract feed to create XML representation from. The type of the WireFeed must match
90       *        the type given to the FeedOuptut constructor.
91       * @return a String with the XML representation for the given WireFeed.
92       * @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match.
93       * @throws FeedException thrown if the XML representation for the feed could not be created.
94       *
95       */
96      public String outputString(WireFeed feed) throws IllegalArgumentException,FeedException {
97          Document doc = outputJDom(feed);
98          String encoding = feed.getEncoding();
99          Format format = Format.getPrettyFormat();
100         if (encoding!=null) {
101             format.setEncoding(encoding);
102         }
103         XMLOutputter outputter = new XMLOutputter(format);
104         return outputter.outputString(doc);
105     }
106 
107     /***
108      * Creates a File containing with the XML representation for the given WireFeed.
109      * <p>
110      * If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. The platform
111      * default charset encoding is used to write the feed to the file. It is the responsibility
112      * of the developer to ensure the feed encoding is set to the platform charset encoding.
113      * <p>
114      * NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'.
115      * <p>
116      * @param feed Abstract feed to create XML representation from. The type of the WireFeed must match
117      *        the type given to the FeedOuptut constructor.
118      * @param file the file where to write the XML representation for the given WireFeed.
119      * @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match.
120      * @throws IOException thrown if there was some problem writing to the File.
121      * @throws FeedException thrown if the XML representation for the feed could not be created.
122      *
123      */
124     public void output(WireFeed feed,File file) throws IllegalArgumentException,IOException,FeedException {
125         Writer writer = new FileWriter(file);
126         output(feed,writer);
127         writer.close();
128     }
129 
130     /***
131      * Writes to an Writer the XML representation for the given WireFeed.
132      * <p>
133      * If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility
134      * of the developer to ensure the Writer instance is using the same charset encoding.
135      * <p>
136      * NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'.
137      * <p>
138      * @param feed Abstract feed to create XML representation from. The type of the WireFeed must match
139      *        the type given to the FeedOuptut constructor.
140      * @param writer Writer to write the XML representation for the given WireFeed.
141      * @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match.
142      * @throws IOException thrown if there was some problem writing to the Writer.
143      * @throws FeedException thrown if the XML representation for the feed could not be created.
144      *
145      */
146     public void output(WireFeed feed,Writer writer) throws IllegalArgumentException,IOException, FeedException {
147         Document doc = outputJDom(feed);
148         String encoding = feed.getEncoding();
149         Format format = Format.getPrettyFormat();
150         if (encoding!=null) {
151             format.setEncoding(encoding);
152         }
153         XMLOutputter outputter = new XMLOutputter(format);
154         outputter.output(doc,writer);
155     }
156 
157     /***
158      * Creates a W3C DOM document for the given WireFeed.
159      * <p>
160      * This method does not use the feed encoding property.
161      * <p>
162      * NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'.
163      * <p>
164      * @param feed Abstract feed to create W3C DOM document from. The type of the WireFeed must match
165      *        the type given to the FeedOuptut constructor.
166      * @return the W3C DOM document for the given WireFeed.
167      * @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match.
168      * @throws FeedException thrown if the W3C DOM document for the feed could not be created.
169      *
170      */
171     public org.w3c.dom.Document outputW3CDom(WireFeed feed) throws IllegalArgumentException,FeedException {
172         Document doc = outputJDom(feed);
173         DOMOutputter outputter = new DOMOutputter();
174         try {
175             return outputter.output(doc);
176         }
177         catch (JDOMException jdomEx) {
178             throw new FeedException("Could not create DOM",jdomEx);
179         }
180     }
181 
182     /***
183      * Creates a JDOM document for the given WireFeed.
184      * <p>
185      * This method does not use the feed encoding property.
186      * <p>
187      * NOTE: All other output methods delegate to this method.
188      * <p>
189      * @param feed Abstract feed to create JDOM document from. The type of the WireFeed must match
190      *        the type given to the FeedOuptut constructor.
191      * @return the JDOM document for the given WireFeed.
192      * @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match.
193      * @throws FeedException thrown if the JDOM document for the feed could not be created.
194      *
195      */
196     public Document outputJDom(WireFeed feed) throws IllegalArgumentException,FeedException {
197         String type = feed.getFeedType();
198         WireFeedGenerator generator = getFeedGenerators().getGenerator(type);
199         if (generator==null) {
200             throw new IllegalArgumentException("Invalid feed type ["+type+"]");
201         }
202 
203         if (!generator.getType().equals(type)) {
204             throw new IllegalArgumentException("WireFeedOutput type["+type+"] and WireFeed type ["+
205                                                type+"] don't match");
206         }
207         return generator.generate(feed);
208     }
209 
210 }