001 /*
002 * $Id: ResourceBundleResources.java 358692 2005-12-23 03:37:26Z niallp $
003 * $Revision: 358692 $
004 * $Date: 2005-12-23 03:37:26 +0000 (Fri, 23 Dec 2005) $
005 *
006 * ====================================================================
007 *
008 * Copyright 2003-2005 The Apache Software Foundation
009 *
010 * Licensed under the Apache License, Version 2.0 (the "License");
011 * you may not use this file except in compliance with the License.
012 * You may obtain a copy of the License at
013 *
014 * http://www.apache.org/licenses/LICENSE-2.0
015 *
016 * Unless required by applicable law or agreed to in writing, software
017 * distributed under the License is distributed on an "AS IS" BASIS,
018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019 * See the License for the specific language governing permissions and
020 * limitations under the License.
021 *
022 */
023
024 package org.apache.commons.resources.impl;
025
026 import java.util.Collections;
027 import java.util.Iterator;
028 import java.util.Locale;
029 import java.util.MissingResourceException;
030 import java.util.ResourceBundle;
031
032 import org.apache.commons.logging.Log;
033 import org.apache.commons.logging.LogFactory;
034 import org.apache.commons.resources.ResourcesException;
035 import org.apache.commons.resources.ResourcesKeyException;
036 import org.apache.commons.resources.util.IteratorEnumeration;
037
038 /**
039 * <p>Concrete implementation of
040 * {@link org.apache.commons.resources.Resources} that wraps a set
041 * (one per Locale) of <code>java.util.ResourceBundle</code> instances
042 * that share a common base name.</p>
043 */
044 public class ResourceBundleResources extends ResourcesBase {
045
046 /**
047 * <p>The logging instance for this class.</p>
048 */
049 private transient Log log =
050 LogFactory.getLog(ResourceBundleResources.class);
051
052 // ----------------------------------------------------------- Constructors
053
054
055 /**
056 * <p>Create a new {@link org.apache.commons.resources.Resources}
057 * instance with the specified
058 * logical name and bundle base name.</p>
059 *
060 * @param name Logical name of the new instance
061 * @param base Fully qualified base name of the <code>ResourceBundle</code>
062 * instances to be wrapped
063 */
064 public ResourceBundleResources(String name, String base) {
065
066 super(name);
067 this.base = base;
068
069 }
070
071
072 // ----------------------------------------------------- Instance Variables
073
074
075 /**
076 * <p>The fully qualified base name of the <code>ResourceBundle</code>
077 * instances to be wrapped.</p>
078 */
079 private String base = null;
080
081
082 // ------------------------------------------------------------- Properties
083
084
085 /**
086 * <p>Return the fully qualified base name of the
087 * <code>ResourceBundle</code> instances we are wrapping.</p>
088 * @return The base name of this resources instance.
089 */
090 public String getBase() {
091
092 return (this.base);
093
094 }
095
096 /**
097 * <p>Return an <code>Iterator</code> over the defined keys in this
098 * {@link org.apache.commons.resources.Resources} instance.</p>
099 *
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 }