View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *  http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.geronimo.javamail.store.nntp.newsrc;
21  
22  import java.io.BufferedReader;
23  import java.io.IOException;
24  import java.io.Writer;
25  import java.util.HashMap;
26  import java.util.Iterator;
27  import java.util.Map;
28  
29  /**
30   * Base class implementation of a standard news reader news rc file. This is
31   * used to track newsgroup subscriptions and SEEN flags for articles. This is an
32   * abstract class designed for subclasses to bridge to the physical store type
33   * used for the newsgroup information.
34   */
35  public abstract class NNTPNewsrc {
36  
37      // the group information we've read from the news rc file.
38      Map groups = new HashMap();
39  
40      // flag to let us know of we need to persist the newsrc file on close.
41      boolean dirty = false;
42  
43      /**
44       * Base class constructor for NNTPNewsrc items. Subclasses provide their own
45       * domain-specific intialization.
46       */
47      protected NNTPNewsrc() {
48      }
49  
50      /**
51       * Load the data from the newsrc file and parse into an instore group
52       * database.
53       */
54      public void load() {
55          BufferedReader in = null;
56  
57          try {
58              in = getInputReader();
59  
60              String line = in.readLine();
61  
62              while (line != null) {
63                  // parse the line...this returns null if it's something
64                  // unrecognized.
65                  NNTPNewsrcGroup group = NNTPNewsrcGroup.parse(this, line);
66                  // if it parsed ok, add it to the group list, and potentially to
67                  // the subscribed list.
68                  if (group != null) {
69                      groups.put(group.getName(), group);
70                  }
71  
72                  line = in.readLine();
73              }
74  
75              in.close();
76          } catch (IOException e) {
77              // an IOException may mean that the file just doesn't exist, which
78              // is fine. We'll ignore and
79              // proceed with the information we have.
80          } finally {
81              if (in != null) {
82                  try {
83                      in.close();
84                  } catch (IOException e) {
85                      // ignore
86                  }
87              }
88          }
89      }
90  
91      /**
92       * Save the newsrc file data back to the original source file.
93       * 
94       * @exception IOException
95       */
96      public void save() throws IOException {
97          Writer out = getOutputWriter();
98  
99          Iterator i = groups.values().iterator();
100 
101         while (i.hasNext()) {
102             NNTPNewsrcGroup group = (NNTPNewsrcGroup) i.next();
103             group.save(out);
104         }
105 
106         out.close();
107     }
108 
109     /**
110      * Abstract open method intended for sub class initialization. The subclass
111      * is responsible for creating the BufferedReaded used to read the .newsrc
112      * file.
113      * 
114      * @return A BufferedReader for reading the .newsrc file.
115      * @exception IOException
116      */
117     abstract public BufferedReader getInputReader() throws IOException;
118 
119     /**
120      * Abstract open for output method intended for subclass implementation. The
121      * subclasses are reponsible for opening the output stream and creating an
122      * appropriate Writer for saving the .newsrc file.
123      * 
124      * @return A Writer target at the .newsrc file save location.
125      * @exception IOException
126      */
127     abstract public Writer getOutputWriter() throws IOException;
128 
129     /**
130      * Retrieve the newsrc group information for a named group. If the file does
131      * not currently include this group, an unsubscribed group will be added to
132      * the file.
133      * 
134      * @param name
135      *            The name of the target group.
136      * 
137      * @return The NNTPNewsrcGroup item corresponding to this name.
138      */
139     public NNTPNewsrcGroup getGroup(String name) {
140         NNTPNewsrcGroup group = (NNTPNewsrcGroup) groups.get(name);
141         // if we don't know about this, create a new one and add to the list.
142         // This
143         // will be an unsubscribed one.
144         if (group == null) {
145             group = new NNTPNewsrcGroup(this, name, null, false);
146             groups.put(name, group);
147             // we've added a group, so we need to resave
148             dirty = true;
149         }
150         return group;
151     }
152 
153     /**
154      * Mark this newsrc database as dirty.
155      */
156     public void setDirty() {
157         dirty = true;
158     }
159 
160     /**
161      * Close the newsrc file, persisting it back to disk if the file has
162      * changed.
163      */
164     public void close() {
165         if (dirty) {
166             try {
167                 save();
168             } catch (IOException e) {
169                 // ignore
170             }
171         }
172     }
173 
174     /**
175      * Retrieve the current set of loaded groups.
176      * 
177      * @return An iterator for traversing the group set.
178      */
179     public Iterator getGroups() {
180         return groups.values().iterator();
181     }
182 }