2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.util;
19
20 import java.beans.Beans;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Enumeration;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Locale;
29 import java.util.Map;
30 import java.util.MissingResourceException;
31 import java.util.ResourceBundle;
32 import java.util.Set;
33 import javax.faces.component.UIViewRoot;
34
35 import javax.faces.context.FacesContext;
36
37 /***
38 * <p>Utility class emulating the behavior of the standard JSF Core Library
39 * tag <code><f:loadBundle></code>. This class is designed to be used
40 * as a managed bean, and exposes a <code>map</code> property containing the
41 * messages in the resoruce bundle specified by the <code>basename</code>
42 * property, localized for the <code>Locale</code> specified on the current
43 * request.</p>
44 *
45 * <p>A typical use of this class would be to declare a managed bean like this:</p>
46 * <pre>
47 * <managed-bean>
48 * <managed-bean-name>bundle</managed-bean-name>
49 * <managed-bean-class>
50 * org.apache.shale.util.LoadBundle
51 * </managed-bean-class>
52 * <managed-bean-scope>request</managed-bean-scope>
53 * <managed-property>
54 * <property-name>basename</property-name>
55 * <value>com.mycompany.mypackage.Bundle</value>
56 * </managed-property>
57 * </managed-bean>
58 * </pre>
59 *
60 * <p>This will result in creation of a request scope object whose <code>map</code>
61 * property will return a <code>Map</code> representing the localized messages for
62 * the <code>com.mycompany.mypackage.Bundle</code> resource bundle. You can look
63 * up localized messages in this <code>Map</code> by evaluating a value binding
64 * expression like this:</p>
65 * <blockquote>
66 * <code>#{messages.['message.key']}</code>
67 * </blockquote>
68 * <p>where <code>message.key</code> is the key for which to retrieve a
69 * localized message.</p>
70 *
71 * <p>(Since 1.0.1) <strong>IMPLEMENTATION NOTE</strong> - For backwards
72 * compatibility in applications that utilized the 1.0.0 version of this
73 * class, the following sort of expression resolves to the same value:</p>
74 * <blockquote>
75 * <code>#{messages.map['message.key']}</code>
76 * </blockquote>
77 */
78 public class LoadBundle {
79
80
81
82
83 /*** Creates a new instance of LoadBundle. */
84 public LoadBundle() {
85 this(null);
86 }
87
88
89 /*** <p>Creates a new instance of LoadBundle for the specified bundle.</p>
90 *
91 * @param basename Base resource bundle name for this <code>LoadBundle</code>
92 */
93 public LoadBundle(String basename) {
94 this.basename = basename;
95 }
96
97
98
99
100
101 /***
102 * <p>The default <code>Locale</code> for this application.</p>
103 */
104 private static final Locale defaultLocale = Locale.getDefault();
105
106
107
108
109
110 /***
111 * <p>The base resource bundle name for this <code>LoadBundle</code> instance.</p>
112 */
113 private String basename = null;
114
115
116 /***
117 * <p>Return the base resource bundle name for this <code>LoadBundle</code>
118 * instance.</p>
119 */
120 public String getBasename() {
121 return this.basename;
122 }
123
124
125 /***
126 * <p>Set the base resource bundle name for this <code>LoadBundle</code>
127 * instance.</p>
128 *
129 * @param basename The new base resource bundle name
130 */
131 public void setBasename(String basename) {
132 this.basename = basename;
133 }
134
135
136
137
138
139 /***
140 * <p>Return a <code>Map</code> whose keys and values represent the content
141 * of the application resource bundle specified by the <code>basename</code>
142 * property, localized for the <code>Locale</code> stored in the
143 * <code>UIViewRoot</code> for the current request.</p>
144 *
145 * @exception IllegalStateException if we are not inside a Faces request,
146 * or if there is not a current view root with a valid locale
147 */
148 public Map getMap() throws IllegalStateException {
149
150
151 if (basename == null) {
152 if (Beans.isDesignTime()) {
153 return Collections.EMPTY_MAP;
154 }
155 throw new IllegalStateException("The 'basename' property cannot be null");
156 }
157 FacesContext context = FacesContext.getCurrentInstance();
158 UIViewRoot root = null;
159 Locale locale = null;
160 if (context != null) {
161 root = context.getViewRoot();
162 }
163 if (root != null) {
164 locale = root.getLocale();
165 }
166 if (locale == null) {
167 throw new IllegalStateException("Cannot retrieve locale-specific map if there " +
168 "is not a current Faces request, containing a valid view root, with" +
169 "a Locale instance inside.");
170 }
171
172
173 final ResourceBundle bundle = getBundle(basename, locale);
174 if (bundle == null) {
175 throw new IllegalArgumentException
176 ("No resource bundle found for base name '" + basename + "' and locale '" + locale + "'");
177 }
178
179
180 Map map = new Map() {
181
182 public void clear() {
183 throw new UnsupportedOperationException();
184 }
185
186 public boolean containsKey(Object key) {
187 boolean result = false;
188 if (key != null) {
189 result = bundle.getObject(key.toString()) != null;
190 }
191 return result;
192 }
193
194 public boolean containsValue(Object value) {
195 Enumeration keys = bundle.getKeys();
196 while (keys.hasMoreElements()) {
197 Object val = bundle.getObject(keys.nextElement().toString());
198 if ((val != null) && val.equals(value)) {
199 return true;
200 }
201 }
202 return false;
203 }
204
205
206 public Set entrySet() {
207 Map map = new HashMap();
208 Enumeration keys = bundle.getKeys();
209 while (keys.hasMoreElements()) {
210 String key = keys.nextElement().toString();
211 Object value = bundle.getObject(key);
212 map.put(key, value);
213 }
214 return map.entrySet();
215 }
216
217 public boolean equals(Object o) {
218 if ((o == null) || !(o instanceof Map)) {
219 return false;
220 }
221 return entrySet().equals(((Map) o).entrySet());
222 }
223
224 public Object get(Object key) {
225 if (key == null) {
226 return null;
227 }
228 try {
229 return bundle.getObject(key.toString());
230 } catch (MissingResourceException e) {
231 return "???" + key.toString() + "???";
232 }
233 }
234
235 public int hashCode() {
236 return bundle.hashCode();
237 }
238
239 public boolean isEmpty() {
240 Enumeration keys = bundle.getKeys();
241 while (keys.hasMoreElements()) {
242 return false;
243 }
244 return true;
245 }
246
247 public Set keySet() {
248 Set set = new HashSet();
249 Enumeration keys = bundle.getKeys();
250 while (keys.hasMoreElements()) {
251 set.add(keys.nextElement());
252 }
253 return set;
254 }
255
256 public Object put(Object key, Object value) {
257 throw new UnsupportedOperationException();
258 }
259
260 public void putAll(Map map) {
261 throw new UnsupportedOperationException();
262 }
263
264 public Object remove(Object key) {
265 throw new UnsupportedOperationException();
266 }
267
268 public int size() {
269 int size = 0;
270 Enumeration keys = bundle.getKeys();
271 while (keys.hasMoreElements()) {
272 keys.nextElement();
273 size++;
274 }
275 return size;
276 }
277
278 public Collection values() {
279 List list = new ArrayList();
280 Enumeration keys = bundle.getKeys();
281 while (keys.hasMoreElements()) {
282 String key = keys.nextElement().toString();
283 list.add(bundle.getObject(key));
284 }
285 return list;
286 }
287
288 };
289 return map;
290
291 }
292
293
294
295
296
297 /***
298 * <p>Return the localized <code>ResourceBundle</code> for the specified
299 * <code>Locale</code>.</p>
300 *
301 * @param basename Base name of the resource bundle to return
302 * @param locale Locale used to select the appropriate resource bundle
303 */
304 private ResourceBundle getBundle(String basename, Locale locale) {
305
306 assert basename != null;
307 assert locale != null;
308 ClassLoader rbcl = Thread.currentThread().getContextClassLoader();
309 if (rbcl == null) {
310 rbcl = this.getClass().getClassLoader();
311 }
312 try {
313 return ResourceBundle.getBundle(basename, locale, rbcl);
314 } catch (MissingResourceException e) {
315 return ResourceBundle.getBundle(basename, defaultLocale, rbcl);
316 }
317
318 }
319
320
321 }