root/trunk/src/java/org/jcoderz/commons/config/ConfigurationCacheByPropertiesImpl.java

Revision 1011, 7.4 kB (checked in by amandel, 4 years ago)

Aligned svn keyword settings.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 *
4 * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 *    * Redistributions of source code must retain the above copyright
11 *      notice, this list of conditions and the following disclaimer.
12 *    * Redistributions in binary form must reproduce the above
13 *      copyright notice, this list of conditions and the following
14 *      disclaimer in the documentation and/or other materials
15 *      provided with the distribution.
16 *    * Neither the name of the jCoderZ.org Project nor the names of
17 *      its contributors may be used to endorse or promote products
18 *      derived from this software without specific prior written
19 *      permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33package org.jcoderz.commons.config;
34
35import java.util.Enumeration;
36import java.util.HashSet;
37import java.util.Iterator;
38import java.util.MissingResourceException;
39import java.util.ResourceBundle;
40import java.util.Set;
41import java.util.logging.Level;
42import java.util.logging.Logger;
43
44/**
45 * This ConfigurationCache implementation is based on a property file.
46 *
47 */
48public final class ConfigurationCacheByPropertiesImpl
49      implements ConfigurationCacheInterface
50{
51   // the property file's bundle name for the configuration
52   private static final String BUNDLE_NAME
53         = "org.jcoderz.commons.config.configuration";
54
55   /**
56    * Name of this class
57    */
58   private static final String CLASSNAME
59           = ConfigurationCacheByPropertiesImpl.class.getName();
60
61   /**
62    * Logger for this class
63    */
64   private static final Logger logger = Logger.getLogger(CLASSNAME);
65
66   /**
67    * The resource bundle where the config data is cached.
68    * It contains the cached Configuration values.
69    * The key is a ConfigurationKey object and the value
70    * a String representing the value.
71    */
72   private ResourceBundle mResourceBundle = null;
73
74   /**
75    * cache the configuration keys also, to prevent set creation for every
76    * getKeys() call
77    */
78   private Set mConfigurationKeys = null;
79
80   /**
81    * This Set contains the Services that have been registered to receive
82    * notifications when the cache has been changed.
83    * The Set contains objects that implement the ConfigurationListener
84    * interface.
85    */
86   private final Set mRegisteredServices = new HashSet();
87
88   private boolean mIsInitialized;
89   private Exception mInitException;
90
91   /**
92    * Singleton has no public constructor
93    *
94    * @see ConfigurationCacheByPropertiesImpl#current
95    */
96   private ConfigurationCacheByPropertiesImpl ()
97   {
98      try
99      {
100         init();
101         mIsInitialized = true;
102         mInitException = null;
103      }
104      catch (Exception x)
105      {
106         mIsInitialized = false;
107         mInitException = x;
108         final ConfigurationInitializationFailedException sysEvt
109               = new ConfigurationInitializationFailedException(x);
110         sysEvt.log();
111      }
112   }
113
114
115   /**
116    * Returns a reference to the one and only object instance of this
117    * class. Use this method to access the object's methods.
118    *
119    * @return a reference to the one and only object instance of this class.
120    */
121   public static ConfigurationCacheByPropertiesImpl current ()
122   {
123      final ConfigurationCacheByPropertiesImpl result
124            = ConfigurationCacheHolder.INSTANCE;
125      if (! result.mIsInitialized)
126      {
127         throw new ConfigurationInitializationFailedException(
128               result.mInitException);
129      }
130      return result;
131   }
132
133
134   /**
135    * Setup configuration cache as MBean and initialize cache.
136    */
137   private void init ()
138   {
139      final String method = "init";
140
141      if (logger.isLoggable(Level.FINER))
142      {
143         logger.entering(CLASSNAME, method);
144      }
145
146      reloadCache();
147
148      if (logger.isLoggable(Level.FINER))
149      {
150         logger.exiting(CLASSNAME, method);
151      }
152   }
153
154   /**
155    * @see ConfigurationCacheInterface#getString
156    * Returns the String value set for the given configuration key.
157    * @param key the key to look up.
158    * @return the value as string.
159    * @throws ConfigurationValueNotFoundException if the key is not set or
160    *       the resource was not found.
161    */
162   public String getString (String key)
163         throws ConfigurationValueNotFoundException
164   {
165      final String result;
166      try
167      {
168         result = mResourceBundle.getString(key);
169         CfgLogMessage.ConfigurationValueRead.log(key, result);
170      }
171      catch (MissingResourceException e)
172      {
173         throw new ConfigurationValueNotFoundException(key, e);
174      }
175      return result;
176   }
177
178   /** {@inheritDoc} */
179   public Set getKeys ()
180   {
181      return mConfigurationKeys;
182   }
183
184
185   /** {@inheritDoc} */
186   public void addConfigurationListener (ConfigurationListener newListener)
187   {
188      mRegisteredServices.add(newListener);
189   }
190
191
192   /**
193    * Reloads the internal configuration cache from resource bundle.
194    * If an exception occurs during, the old cached properties are
195    * returned.
196    */
197   public void reloadCache ()
198   {
199      final String method = "reloadCache";
200      if (logger.isLoggable(Level.FINER))
201      {
202         logger.entering(CLASSNAME, method);
203      }
204
205      try
206      {
207         mResourceBundle = ResourceBundle.getBundle(BUNDLE_NAME);
208         final Enumeration keys = mResourceBundle.getKeys();
209         mConfigurationKeys = new HashSet(java.util.Collections.list(keys));
210      }
211      catch (Exception e)
212      {
213         final ConfigurationInitializationFailedException cife
214               = new ConfigurationInitializationFailedException(e);
215         // CHECKME: create special config cache reload exception?
216         cife.addParameter("DETAIL",
217               "Exception while updating ConfigurationCache.");
218         throw cife;
219      }
220
221      if (logger.isLoggable(Level.FINER))
222      {
223         logger.exiting(CLASSNAME, method);
224      }
225      notifyServices();
226   }
227
228   /**
229    * Notifies all registered services about the cache update.
230    */
231   private void notifyServices ()
232   {
233      final Iterator it = mRegisteredServices.iterator();
234      final ConfigUpdateEvent event = new ConfigUpdateEvent(this,
235         ConfigUpdateEvent.CACHE_UPDATED);
236      while (it.hasNext())
237      {
238         ((ConfigurationListener) it.next()).updateConfiguration(event);
239      }
240   }
241
242
243   /**
244    * Local helper class holding a member initialized by calling
245    * the private constructor of the singleton.
246    */
247   private static final class ConfigurationCacheHolder
248   {
249      private static final ConfigurationCacheByPropertiesImpl INSTANCE
250         = new ConfigurationCacheByPropertiesImpl();
251   }
252}
Note: See TracBrowser for help on using the browser.