1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.jelly.tags.fmt;
17
18 import org.apache.commons.jelly.JellyContext;
19 import org.apache.commons.jelly.JellyTagException;
20 import org.apache.commons.jelly.XMLOutput;
21 import org.apache.commons.jelly.TagSupport;
22 import org.apache.commons.jelly.expression.Expression;
23 import java.util.Enumeration;
24 import java.util.Locale;
25 import java.util.ResourceBundle;
26 import java.util.MissingResourceException;
27
28 /***
29 * Support for tag handlers for <bundle>, the resource bundle loading
30 * tag in JSTL.
31 *
32 * @author <a href="mailto:willievu@yahoo.com">Willie Vu</a>
33 * @version 1.1
34 *
35 * @todo decide how to implement setResponseLocale
36 */
37 public class BundleTag extends TagSupport {
38
39
40 //**********************************************************************
41 // Private constants
42
43 private static final Locale EMPTY_LOCALE = new Locale("", "");
44
45
46 //*********************************************************************
47 // Protected state
48
49 private Expression basename; // 'basename' attribute
50 private Expression prefix; // 'prefix' attribute
51 /** evaluated basename */
52 private String ebasename;
53 /*** evaluated prefix */
54 private String eprefix;
55
56
57 //**********************************************************************
58 // Private state
59
60 private LocalizationContext locCtxt;
61
62
63 //*********************************************************************
64 // Constructor and initialization
65
66 public BundleTag() {
67 }
68
69 //*********************************************************************
70 // Collaboration with subtags
71
72 public LocalizationContext getLocalizationContext() {
73 return locCtxt;
74 }
75
76 public String getPrefixAsString() {
77 return eprefix;
78 }
79
80
81 //*********************************************************************
82 // Tag logic
83
84 /**
85 * Evaluates this tag after all the tags properties have been initialized.
86 *
87 */
88 public void doTag(XMLOutput output) throws JellyTagException {
89 Object basenameInput = null;
90 if (this.basename != null) {
91 basenameInput = this.basename.evaluate(context);
92 }
93 if (basenameInput != null) {
94 ebasename = basenameInput.toString();
95 }
96
97 Object prefixInput = null;
98 if (this.prefix != null) {
99 prefixInput = this.prefix.evaluate(context);
100 }
101 if (prefixInput != null) {
102 eprefix = prefixInput.toString();
103 }
104
105 this.locCtxt = this.getLocalizationContext(context, ebasename);
106 invokeBody(output);
107 }
108
109
110 //**********************************************************************
111 // Public utility methods
112
113 /**
114 * Gets the default I18N localization context.
115 *
116 * @param jc Page in which to look up the default I18N localization context
117 */
118 public static LocalizationContext getLocalizationContext(JellyContext jc) {
119 LocalizationContext locCtxt = null;
120
121 Object obj = jc.getVariable(Config.FMT_LOCALIZATION_CONTEXT);
122 if (obj == null) {
123 return null;
124 }
125
126 if (obj instanceof LocalizationContext) {
127 locCtxt = (LocalizationContext) obj;
128 } else {
129
130 locCtxt = getLocalizationContext(jc, (String) obj);
131 }
132
133 return locCtxt;
134 }
135
136 /***
137 * Gets the resource bundle with the given base name, whose locale is
138 * determined as follows:
139 *
140 * Check if a match exists between the ordered set of preferred
141 * locales and the available locales, for the given base name.
142 * The set of preferred locales consists of a single locale
143 * (if the <tt>org.apache.commons.jelly.tags.fmt.locale</tt> configuration
144 * setting is present).
145 *
146 * <p> If no match was found in the previous step, check if a match
147 * exists between the fallback locale (given by the
148 * <tt>org.apache.commons.jelly.tags.fmt.fallbackLocale</tt> configuration
149 * setting) and the available locales, for the given base name.
150 *
151 * @param pageContext Page in which the resource bundle with the
152 * given base name is requested
153 * @param basename Resource bundle base name
154 *
155 * @return Localization context containing the resource bundle with the
156 * given base name and the locale that led to the resource bundle match,
157 * or the empty localization context if no resource bundle match was found
158 */
159 public static LocalizationContext getLocalizationContext(JellyContext jc,
160 String basename) {
161 LocalizationContext locCtxt = null;
162 ResourceBundle bundle = null;
163
164 if ((basename == null) || basename.equals("")) {
165 return new LocalizationContext();
166 }
167
168
169
170 Locale pref = null; {
171 Object tmp = jc.getVariable(Config.FMT_LOCALE);
172 if (tmp != null && tmp instanceof Locale) {
173 pref = (Locale) tmp;
174 }
175 }
176 if (pref != null) {
177
178 bundle = findMatch(basename, pref, jc.getClassLoader());
179 if (bundle != null) {
180 locCtxt = new LocalizationContext(bundle, pref);
181 }
182 }
183
184 if (locCtxt == null) {
185
186 {
187 Object tmp = jc.getVariable(Config.FMT_FALLBACK_LOCALE);
188 if (tmp != null && tmp instanceof Locale) {
189 pref = (Locale) tmp;
190 }
191 }
192 if (pref != null) {
193 bundle = findMatch(basename, pref, jc.getClassLoader());
194 if (bundle != null) {
195 locCtxt = new LocalizationContext(bundle, pref);
196 }
197 }
198 }
199
200 if (locCtxt == null) {
201
202 try {
203 bundle = ResourceBundle.getBundle(basename, EMPTY_LOCALE,
204 jc.getClassLoader());
205 if (bundle != null) {
206 locCtxt = new LocalizationContext(bundle, null);
207 }
208 } catch (MissingResourceException mre) {
209
210 }
211 }
212
213 if (locCtxt != null) {
214
215 if (locCtxt.getLocale() != null) {
216
217
218 }
219 } else {
220
221 locCtxt = new LocalizationContext();
222 }
223
224 return locCtxt;
225 }
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245 private static ResourceBundle findMatch(String basename, Locale pref, ClassLoader cl) {
246 ResourceBundle match = null;
247
248 try {
249 ResourceBundle bundle =
250 ResourceBundle.getBundle(basename, pref, cl);
251 Locale avail = bundle.getLocale();
252 if (pref.equals(avail)) {
253
254 match = bundle;
255 } else {
256 if (pref.getLanguage().equals(avail.getLanguage())
257 && ("".equals(avail.getCountry()))) {
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273 match = bundle;
274 }
275 }
276 } catch (MissingResourceException mre) {
277 }
278
279 return match;
280 }
281
282 /*** Setter for property basename.
283 * @param basename New value of property basename.
284 *
285 */
286 public void setBasename(Expression basename) {
287 this.basename = basename;
288 }
289
290 /*** Setter for property prefix.
291 * @param prefix New value of property prefix.
292 *
293 */
294 public void setPrefix(Expression prefix) {
295 this.prefix = prefix;
296 }
297
298 }