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 }