View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.configuration;
19  
20  import java.io.Reader;
21  import java.io.Writer;
22  import java.io.File;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.net.URL;
26  import java.util.Iterator;
27  
28  import org.apache.commons.configuration.event.ConfigurationEvent;
29  import org.apache.commons.configuration.event.ConfigurationListener;
30  import org.apache.commons.configuration.reloading.ReloadingStrategy;
31  
32  /***
33   * <p>Base class for implementing file based hierarchical configurations.</p>
34   * <p>This class serves an analogous purpose as the
35   * <code>{@link AbstractFileConfiguration}</code> class for non hierarchical
36   * configurations. It behaves in exactly the same way, so please refer to the
37   * documentation of <code>AbstractFileConfiguration</code> for further details.</p>
38   *
39   * @since 1.2
40   *
41   * @author Emmanuel Bourg
42   * @version $Revision: 439648 $, $Date: 2006-09-02 22:42:10 +0200 (Sa, 02 Sep 2006) $
43   */
44  public abstract class AbstractHierarchicalFileConfiguration
45  extends HierarchicalConfiguration
46  implements FileConfiguration, ConfigurationListener
47  {
48      /*** Stores the delegate used for implementing functionality related to the
49       * <code>FileConfiguration</code> interface.
50       */
51      private FileConfigurationDelegate delegate;
52  
53      protected AbstractHierarchicalFileConfiguration()
54      {
55          delegate = createDelegate();
56          initDelegate(delegate);
57      }
58  
59      /***
60       * Creates and loads the configuration from the specified file.
61       *
62       * @param fileName The name of the plist file to load.
63       * @throws ConfigurationException Error while loading the file
64       */
65      public AbstractHierarchicalFileConfiguration(String fileName) throws ConfigurationException
66      {
67          this();
68          // store the file name
69          delegate.setFileName(fileName);
70  
71          // load the file
72          load();
73      }
74  
75      /***
76       * Creates and loads the configuration from the specified file.
77       *
78       * @param file The configuration file to load.
79       * @throws ConfigurationException Error while loading the file
80       */
81      public AbstractHierarchicalFileConfiguration(File file) throws ConfigurationException
82      {
83          this();
84          // set the file and update the url, the base path and the file name
85          setFile(file);
86  
87          // load the file
88          if (file.exists())
89          {
90              load();
91          }
92      }
93  
94      /***
95       * Creates and loads the configuration from the specified URL.
96       *
97       * @param url The location of the configuration file to load.
98       * @throws ConfigurationException Error while loading the file
99       */
100     public AbstractHierarchicalFileConfiguration(URL url) throws ConfigurationException
101     {
102         this();
103         // set the URL and update the base path and the file name
104         setURL(url);
105 
106         // load the file
107         load();
108     }
109 
110     protected void addPropertyDirect(String key, Object obj)
111     {
112         super.addPropertyDirect(key, obj);
113         delegate.possiblySave();
114     }
115 
116     public void clearProperty(String key)
117     {
118         super.clearProperty(key);
119         delegate.possiblySave();
120     }
121 
122     public void clearTree(String key)
123     {
124         super.clearTree(key);
125         delegate.possiblySave();
126     }
127 
128     public void setProperty(String key, Object value)
129     {
130         super.setProperty(key, value);
131         delegate.possiblySave();
132     }
133 
134     public void load() throws ConfigurationException
135     {
136         delegate.load();
137     }
138 
139     public void load(String fileName) throws ConfigurationException
140     {
141         delegate.load(fileName);
142     }
143 
144     public void load(File file) throws ConfigurationException
145     {
146         delegate.load(file);
147     }
148 
149     public void load(URL url) throws ConfigurationException
150     {
151         delegate.load(url);
152     }
153 
154     public void load(InputStream in) throws ConfigurationException
155     {
156         delegate.load(in);
157     }
158 
159     public void load(InputStream in, String encoding) throws ConfigurationException
160     {
161         delegate.load(in, encoding);
162     }
163 
164     public void save() throws ConfigurationException
165     {
166         delegate.save();
167     }
168 
169     public void save(String fileName) throws ConfigurationException
170     {
171         delegate.save(fileName);
172     }
173 
174     public void save(File file) throws ConfigurationException
175     {
176         delegate.save(file);
177     }
178 
179     public void save(URL url) throws ConfigurationException
180     {
181         delegate.save(url);
182     }
183 
184     public void save(OutputStream out) throws ConfigurationException
185     {
186         delegate.save(out);
187     }
188 
189     public void save(OutputStream out, String encoding) throws ConfigurationException
190     {
191         delegate.save(out, encoding);
192     }
193 
194     public String getFileName()
195     {
196         return delegate.getFileName();
197     }
198 
199     public void setFileName(String fileName)
200     {
201         delegate.setFileName(fileName);
202     }
203 
204     public String getBasePath()
205     {
206         return delegate.getBasePath();
207     }
208 
209     public void setBasePath(String basePath)
210     {
211         delegate.setBasePath(basePath);
212     }
213 
214     public File getFile()
215     {
216         return delegate.getFile();
217     }
218 
219     public void setFile(File file)
220     {
221         delegate.setFile(file);
222     }
223 
224     public URL getURL()
225     {
226         return delegate.getURL();
227     }
228 
229     public void setURL(URL url)
230     {
231         delegate.setURL(url);
232     }
233 
234     public void setAutoSave(boolean autoSave)
235     {
236         delegate.setAutoSave(autoSave);
237     }
238 
239     public boolean isAutoSave()
240     {
241         return delegate.isAutoSave();
242     }
243 
244     public ReloadingStrategy getReloadingStrategy()
245     {
246         return delegate.getReloadingStrategy();
247     }
248 
249     public void setReloadingStrategy(ReloadingStrategy strategy)
250     {
251         delegate.setReloadingStrategy(strategy);
252     }
253 
254     public void reload()
255     {
256         setDetailEvents(false);
257         try
258         {
259             delegate.reload();
260         }
261         finally
262         {
263             setDetailEvents(true);
264         }
265     }
266 
267     public String getEncoding()
268     {
269         return delegate.getEncoding();
270     }
271 
272     public void setEncoding(String encoding)
273     {
274         delegate.setEncoding(encoding);
275     }
276 
277     public boolean containsKey(String key)
278     {
279         reload();
280         return super.containsKey(key);
281     }
282 
283     public Iterator getKeys(String prefix)
284     {
285         reload();
286         return super.getKeys(prefix);
287     }
288 
289     public Object getProperty(String key)
290     {
291         reload();
292         return super.getProperty(key);
293     }
294 
295     public boolean isEmpty()
296     {
297         reload();
298         return super.isEmpty();
299     }
300 
301     /***
302      * Creates the file configuration delegate, i.e. the object that implements
303      * functionality required by the <code>FileConfiguration</code> interface.
304      * This base implementation will return an instance of the
305      * <code>FileConfigurationDelegate</code> class. Derived classes may
306      * override it to create a different delegate object.
307      *
308      * @return the file configuration delegate
309      */
310     protected FileConfigurationDelegate createDelegate()
311     {
312         return new FileConfigurationDelegate();
313     }
314 
315     /***
316      * Helper method for initializing the file configuration delegate.
317      *
318      * @param del the delegate
319      */
320     private void initDelegate(FileConfigurationDelegate del)
321     {
322         del.addConfigurationListener(this);
323     }
324 
325     /***
326      * Reacts on configuration change events triggered by the delegate. These
327      * events are passed to the registered configuration listeners.
328      *
329      * @param event the triggered event
330      * @since 1.3
331      */
332     public void configurationChanged(ConfigurationEvent event)
333     {
334         // deliver reload events to registered listeners
335         setDetailEvents(true);
336         try
337         {
338             fireEvent(event.getType(), event.getPropertyName(), event
339                     .getPropertyValue(), event.isBeforeUpdate());
340         }
341         finally
342         {
343             setDetailEvents(false);
344         }
345     }
346 
347     /***
348      * Returns the file configuration delegate.
349      *
350      * @return the delegate
351      */
352     protected FileConfigurationDelegate getDelegate()
353     {
354         return delegate;
355     }
356 
357     /***
358      * Allows to set the file configuration delegate.
359      * @param delegate the new delegate
360      */
361     protected void setDelegate(FileConfigurationDelegate delegate)
362     {
363         this.delegate = delegate;
364     }
365 
366     /***
367      * A special implementation of the <code>FileConfiguration</code> interface that is
368      * used internally to implement the <code>FileConfiguration</code> methods
369      * for hierarchical configurations.
370      */
371     protected class FileConfigurationDelegate extends AbstractFileConfiguration
372     {
373         public void load(Reader in) throws ConfigurationException
374         {
375             AbstractHierarchicalFileConfiguration.this.load(in);
376         }
377 
378         public void save(Writer out) throws ConfigurationException
379         {
380             AbstractHierarchicalFileConfiguration.this.save(out);
381         }
382 
383         public void clear()
384         {
385             AbstractHierarchicalFileConfiguration.this.clear();
386         }
387     }
388 }