Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/fm/rss/fsChannelStorage.java


1   /****************************************************************************
2    * Copyright (c) 2003 Andrew Duka | aduka@users.sourceforge.net
3    * All right reserved.
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2.1 of the License, or (at your option) any later version.
9    *
10   ****************************************************************************/
11  package com.fm.rss;
12  
13  import java.util.*;
14  import java.io.*;
15  
16  import org.w3c.dom.Element;
17  import org.w3c.dom.Node;
18  import org.w3c.dom.NodeList;
19  import org.xml.sax.SAXException;
20  
21  import javax.xml.parsers.ParserConfigurationException;
22  
23  import com.fm.rss.filter.RssItemFilter;
24  
25  /**
26   * File system channel storage.
27   *
28   * <p>Storage will save/load its state to/from the well formed XML document
29   * stored in the file specified by DESTINATION parameter. Load operation
30   * accepts remote resources if they are specified by correct URI.</p>
31   *
32   * <p>Complete format of the storage file may discovered from the FM DTD,
33   * here is the only brief schema:
34   * <code>
35   *   <?xml version="1.0">
36   *    <rss-channel-storage xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/">
37   *     <dcterms:dateCreated> Date when current storage was actually created</dcterms:dateCreated>
38   *     <dcterms:dateModified> Date when current storage was last time saved to disk</dcterms:dateModified>
39   *
40   *
41   *     //Each category is stored in separate hasPart element
42   *     <dcterms:hasPart>
43   *       Category string here
44   *     </dcterms:hasPart>
45   *
46   *     <dcterms:hasPart>
47   *       Another category string here
48   *     </dcterms:hasPart>
49   *
50   *     .....
51   *
52   *    </rss-channel-storage>
53   * </code>
54   */
55  public class fsChannelStorage implements ChannelStorage {
56  
57      private HashMap params;
58      private HashMap categories;
59      private static final String DEFAULT_SOURCE_NAME = "fm-default-storage.xml";
60  
61  
62      /**
63       * Default constructor
64       */
65      public fsChannelStorage()
66      {
67          this.params = new HashMap();
68          this.categories = new HashMap();
69      }
70  
71      /**
72       * Return list of the channel categories
73       *
74       * @return ArrayList of categories (list is empty if no categories exist)
75       */
76      public Map getCategories()
77      {
78          return this.categories;
79      }
80  
81      /**
82       * Returns plain list of the channel entries reqtreived from existing
83       * categories
84       *
85       * @return Map object containing all known channels
86       */
87      public Map getChannels()
88      {
89          return null;
90      }
91  
92      /**
93       * Set list of the existing categories to given value
94       *
95       * @param newCats
96       */
97      public void setCategories(Map newCats)
98      {
99          this.categories = new HashMap(newCats);
100     }
101 
102     /**
103      * Saves state of the storage to disk.
104      *
105      * The destination file must be specified using <code>setParamValue()</code>,
106      * with <code>ChannelStorage.DESTINATION</code> as a parameter name.</p>
107      *
108      * @throws IOException if I/O error occures during saving
109      */
110     public void save() throws IOException
111     {
112         String destination = "";
113         if ((destination = (String)this.params.get(ChannelStorage.DESTINATION)) == null)
114         {
115             throw new IOException("fsChannelStorage: destination parameter isn't set");
116         }
117 
118         try
119         {
120             //FileWriter out_stream = new FileWriter(destination);
121             OutputStreamWriter out_stream = new OutputStreamWriter(new FileOutputStream(destination),
122                                                                    "UTF-8");
123             StringBuffer header = new StringBuffer();
124             header.append("<?xml version='1.0'?>");
125             header.append("<rss-channel-storage  xmlns:dc='");
126             header.append(documentAdapter.DC_NAMESPACE_URI);
127             header.append("' xmlls:dcterms='");
128             header.append(documentAdapter.DCTERMS_NAMESPACE_URI);
129             header.append("'>");
130             header.append("<dcterms:dateCreated>");
131             header.append(rssDateHandler.dateToString(new Date(), rssDateHandler.RSS_OUTPUT_PATTERN));
132             header.append("</dcterms:dateCreated>");
133             header.append("<dcterms:dateModified>");
134             header.append((new rssDateHandler()).toString());
135             header.append("</dcterms:dateModified>");
136 
137             out_stream.write(header.toString());
138 
139             String c_s;
140             rssChannelCategory c;
141             RssItemFilter filter;
142 
143             if (params.containsKey(ChannelStorage.OUTPUT_FILTER))
144                 filter = (RssItemFilter) params.get(ChannelStorage.OUTPUT_FILTER);
145             else
146                 filter = null;
147 
148 
149             // dumpnig categories
150             for (Iterator i = categories.keySet().iterator(); i.hasNext();)
151             {
152                 c  = (rssChannelCategory) categories.get(i.next());
153 
154                 if (filter != null)
155                     c.filterItems(filter);
156 
157                 c_s = c.toString();
158                 if (c_s != null)
159                     out_stream.write(c_s);
160             }
161 
162             out_stream.write("</rss-channel-storage>");
163             out_stream.close();
164         }
165         catch (IOException e)
166         {
167             throw e;
168         }
169 
170     }
171 
172     /**
173      * Loads state of the storage from the source.
174      *
175      * <p>The source file(resource) must be specified using
176      * <code>setParamValue()</code>, with <code>ChannelStorage.SOURCE</code>
177      * as a parameter name. Note that for load operation the source may be a
178      * remote resource specified by URI as well.</p>
179      *
180      * @throws IOException if I/O error occures during saving
181      */
182     public void load() throws IOException, rssParseException
183     {
184         String source = "";
185         this.categories = new HashMap();
186 
187         if ((source = (String)this.params.get(ChannelStorage.SOURCE)) == null)
188         {
189             throw new IOException("fsChannelStorage: source isn't set");
190         }
191 
192         try
193         {
194             documentAdapter docAdapter = documentAdapter.newInstance((String)this.params.get(ChannelStorage.SOURCE),
195                                                                      true,
196                                                                      true);
197 
198             Element el = docAdapter.getDocumentElement();
199             // nothing to get our state from
200             if (el == null)
201             {
202                 throw new rssParseException("document contains no data");
203             }
204 
205             // chacking that if we've opened channel file instead of storage
206             String el_title = el.getNodeName();
207 
208             if (el_title.equalsIgnoreCase("rss") ||
209                 el_title.equalsIgnoreCase("rdf:RDF") ||
210                 el_title.equalsIgnoreCase("rss-channel"))
211             {
212                 rssChannel op_channel = new rssChannel();
213 
214                 try
215                 {
216                     op_channel.parse(el);
217 
218                     rssChannelCategory new_cat = new rssChannelCategory("Auto created",
219                                                                         "This category was created automatically," +
220                                                                         "because you selected channel file instead of storage");
221                     new_cat.setID(new_cat.generateID());
222                     new_cat.addChannel(op_channel);
223                     categories.put(new Integer(new_cat.getID()),new_cat);
224                     return;
225                 }
226                 catch (rssParseException pe)
227                 {
228                      throw new rssParseException("Storage parse error: "+ pe.toString());
229                 }
230             }
231 
232             Node curr_node;
233             NodeList nl = el.getChildNodes();
234             String node_name;
235             rssChannelCategory new_cat;
236             int child_num = nl.getLength();
237 
238             for (int i=0; i < child_num; i++)
239             {
240                 curr_node = nl.item(i);
241                 if (curr_node.getNodeType() == Node.ELEMENT_NODE)
242                 {
243                     node_name = curr_node.getNodeName();
244                     if (node_name.equalsIgnoreCase("rss-channel-category"))
245                     {
246                             new_cat = new rssChannelCategory();
247                             try
248                             {
249                                 new_cat.parse((Element)curr_node);
250                             }
251                             catch (rssParseException pe)
252                             {
253                                 throw new rssParseException("Storage parse error: "+ pe.toString());
254                             }
255 
256                             this.categories.put(new Integer(new_cat.getID()),new_cat);
257                     }
258                 }//end of ELEMENT_NODE
259             }//end of for
260 
261         }
262         catch (SAXException sax_e)
263         {
264             sax_e.printStackTrace();
265             throw new rssParseException("Storage parse error: " + sax_e.toString());
266         }
267         catch (ParserConfigurationException e)
268         {
269             e.printStackTrace();
270             throw new IOException("Storage DOM error: " + e.toString());
271         }
272 
273 
274 
275     }
276 
277     /**
278      * Set configuration param.
279      *
280      * All unrecognized params are ignored.
281      *
282      * @param param String with parameter name
283      * @param value Object with parameter value
284      */
285     public void setParamValue(String param, Object value)
286     {
287         params.put(param, value);
288     }
289 
290     /**
291      * Return value of the configuration param.
292      *
293      * The <code>null</code> will be returned if specified param
294      * doesn't exist.
295      *
296      * @return String with parameter value or <code>null</code> if parameter
297      *         doesn't exist.
298      */
299     public Object getParamValue(String param)
300     {
301         return params.get(param);
302     }
303 
304     /**
305      * Return name of the default file from which data should be loaded
306      * @return
307      */
308     public Object getDefaultSource()
309     {
310         return fsChannelStorage.DEFAULT_SOURCE_NAME;
311     }
312 
313 }