View Javadoc

1   /*
2    * $Id: ResourceBundleResources.java 358692 2005-12-23 03:37:26Z niallp $
3    * $Revision: 358692 $
4    * $Date: 2005-12-23 03:37:26 +0000 (Fri, 23 Dec 2005) $
5    *
6    * ====================================================================
7    *
8    *  Copyright 2003-2005 The Apache Software Foundation
9    *
10   *  Licensed under the Apache License, Version 2.0 (the "License");
11   *  you may not use this file except in compliance with the License.
12   *  You may obtain a copy of the License at
13   *
14   *      http://www.apache.org/licenses/LICENSE-2.0
15   *
16   *  Unless required by applicable law or agreed to in writing, software
17   *  distributed under the License is distributed on an "AS IS" BASIS,
18   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   *  See the License for the specific language governing permissions and
20   *  limitations under the License.
21   *
22   */
23  
24  package org.apache.commons.resources.impl;
25  
26  import java.util.Collections;
27  import java.util.Iterator;
28  import java.util.Locale;
29  import java.util.MissingResourceException;
30  import java.util.ResourceBundle;
31  
32  import org.apache.commons.logging.Log;
33  import org.apache.commons.logging.LogFactory;
34  import org.apache.commons.resources.ResourcesException;
35  import org.apache.commons.resources.ResourcesKeyException;
36  import org.apache.commons.resources.util.IteratorEnumeration;
37  
38  /**
39   * <p>Concrete implementation of 
40   * {@link org.apache.commons.resources.Resources} that wraps a set
41   * (one per Locale) of <code>java.util.ResourceBundle</code> instances
42   * that share a common base name.</p>
43   */
44  public class ResourceBundleResources extends ResourcesBase {
45  
46      /**
47       * <p>The logging instance for this class.</p>
48       */
49      private transient Log log =
50          LogFactory.getLog(ResourceBundleResources.class);
51  
52      // ----------------------------------------------------------- Constructors
53  
54  
55      /**
56       * <p>Create a new {@link org.apache.commons.resources.Resources} 
57       * instance with the specified
58       * logical name and bundle base name.</p>
59       *
60       * @param name Logical name of the new instance
61       * @param base Fully qualified base name of the <code>ResourceBundle</code>
62       *  instances to be wrapped
63       */
64      public ResourceBundleResources(String name, String base) {
65  
66          super(name);
67          this.base = base;
68  
69      }
70  
71  
72      // ----------------------------------------------------- Instance Variables
73  
74  
75      /**
76       * <p>The fully qualified base name of the <code>ResourceBundle</code>
77       * instances to be wrapped.</p>
78       */
79      private String base = null;
80  
81  
82      // ------------------------------------------------------------- Properties
83  
84  
85      /**
86       * <p>Return the fully qualified base name of the
87       * <code>ResourceBundle</code> instances we are wrapping.</p>
88       * @return The base name of this resources instance.
89       */
90      public String getBase() {
91  
92          return (this.base);
93  
94      }
95  
96      /**
97       * <p>Return an <code>Iterator</code> over the defined keys in this
98       * {@link org.apache.commons.resources.Resources} instance.</p>
99       *
100      * @return The keys contained in this resources instance.
101      */
102     public Iterator getKeys() {
103 
104         try {
105             ResourceBundle bundle = getBundle(null);
106             return new IteratorEnumeration(bundle.getKeys());
107             
108         } catch (MissingResourceException e) {
109             return Collections.EMPTY_LIST.iterator();
110         }
111 
112     }
113 
114 
115     // ---------------------------------------------- Content Retrieval Methods
116 
117 
118     /**
119      * <p>Return the content for the specified <code>key</code> as an
120      * Object, localized based on the specified <code>locale</code>.
121      * </p>
122      *
123      * @param key Identifier for the requested content
124      * @param locale Locale with which to localize retrieval,
125      *  or <code>null</code> for the default Locale
126      * @return content for a specified key.
127      *
128      * @exception ResourcesException if an error occurs retrieving or
129      *  returning the requested content
130      * @exception ResourcesKeyException if the no value for the specified
131      *  key was found, and <code>isReturnNull()</code> returns
132      *  <code>false</code>
133      */
134     public Object getObject(String key, Locale locale) {
135 
136         if (getLog().isTraceEnabled()) {
137             getLog().trace("Retrieving message for key '" + key + "' and locale '"
138                       + locale + "'");
139         }
140 
141         try {
142             ResourceBundle bundle = getBundle(locale);
143             Object object = bundle.getObject(key);
144             if (getLog().isTraceEnabled()) {
145                 getLog().trace("Retrieved object for key '" + key + 
146                                "' and locale '" + locale +
147                                "' is '" + object + "'");
148             }
149             return object;
150             
151         } catch (MissingResourceException e) {
152             if (getLog().isTraceEnabled()) {
153                 getLog().trace("No resource found for key '" + key + 
154                                "' and locale '" + locale + "'");
155             }
156             if (isReturnNull()) {
157                 return (null);
158             } else {
159                 throw new ResourcesKeyException(key);
160             }
161         }
162 
163     }
164 
165 
166     // ------------------------------------------------------ Protected Methods
167 
168 
169     /**
170      * <p>Return the appropriate <code>ResourceBundle</code> instance
171      * that corresponds to the specified <code>locale</code> parameter.
172      * The first time a particular bundle is requested, cache it so
173      * that subsequent requests will operate more quickly.</p>
174      *
175      * @param locale Locale with which to localize retrieval,
176      *  or <code>null</code> for the default Locale
177      * @return The Resource Bundle corresponding to the locale and time zone.
178      *
179      * @exception MissingResourceException if the requested Resourcebundle
180      *  cannot be acquired
181      */
182     protected ResourceBundle getBundle(Locale locale)
183         throws MissingResourceException {
184 
185         if (locale == null) {
186             locale = Locale.getDefault();
187         }
188 
189         // Locate the appropriate ClassLoader
190         ClassLoader loader = getClassLoader();
191 
192         // Locate the requested ResourceBundle instance
193         ResourceBundle bundle = ResourceBundle.getBundle(base, locale, loader);
194 
195         return (bundle);
196 
197     }
198 
199 
200     /**
201      * <p>Return the <code>ClassLoader</code> for which we are mapping
202      * <code>ResourceBundle</code> instances.</p>
203      * @return The Class Loader for the resource bundle.
204      */
205     protected ClassLoader getClassLoader() {
206 
207         ClassLoader loader = Thread.currentThread().getContextClassLoader();
208         
209         if (loader == null) {
210             loader = this.getClass().getClassLoader();
211         }
212         
213         return (loader);
214 
215     }
216 
217     /**
218      * Accessor method for Log instance.
219      *
220      * The Log instance variable is transient and
221      * accessing it through this method ensures it
222      * is re-initialized when this instance is
223      * de-serialized.
224      *
225      * @return The Log instance.
226      */
227     private Log getLog() {
228         if (log == null) {
229             log =  LogFactory.getLog(ResourceBundleResources.class);
230         }
231         return log;
232     }
233 
234 }