1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts.validator;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.apache.commons.validator.Arg;
23 import org.apache.commons.validator.Field;
24 import org.apache.commons.validator.Msg;
25 import org.apache.commons.validator.Validator;
26 import org.apache.commons.validator.ValidatorAction;
27 import org.apache.commons.validator.ValidatorResources;
28 import org.apache.commons.validator.Var;
29 import org.apache.struts.Globals;
30 import org.apache.struts.action.ActionMessage;
31 import org.apache.struts.action.ActionMessages;
32 import org.apache.struts.config.ModuleConfig;
33 import org.apache.struts.util.MessageResources;
34 import org.apache.struts.util.ModuleUtils;
35 import org.apache.struts.util.RequestUtils;
36
37 import javax.servlet.ServletContext;
38 import javax.servlet.http.HttpServletRequest;
39
40 import java.util.Locale;
41
42 /***
43 * This class helps provides some useful methods for retrieving objects from
44 * different scopes of the application.
45 *
46 * @version $Rev: 421119 $ $Date: 2005-09-16 23:34:41 -0400 (Fri, 16 Sep 2005)
47 * $
48 * @since Struts 1.1
49 */
50 public class Resources {
51 /***
52 * The message resources for this package.
53 */
54 private static MessageResources sysmsgs =
55 MessageResources.getMessageResources(
56 "org.apache.struts.validator.LocalStrings");
57
58 /***
59 * <p>Commons Logging instance.</p>
60 */
61 private static Log log = LogFactory.getLog(Resources.class);
62
63 /***
64 * Resources key the <code>ServletContext</code> is stored under.
65 */
66 private static String SERVLET_CONTEXT_PARAM =
67 "javax.servlet.ServletContext";
68
69 /***
70 * Resources key the <code>HttpServletRequest</code> is stored under.
71 */
72 private static String HTTP_SERVLET_REQUEST_PARAM =
73 "javax.servlet.http.HttpServletRequest";
74
75 /***
76 * Resources key the <code>ActionMessages</code> is stored under.
77 */
78 private static String ACTION_MESSAGES_PARAM =
79 "org.apache.struts.action.ActionMessages";
80
81 /***
82 * Retrieve <code>ValidatorResources</code> for the current module.
83 *
84 * @param application Application Context
85 * @param request The ServletRequest
86 */
87 public static ValidatorResources getValidatorResources(
88 ServletContext application, HttpServletRequest request) {
89 String prefix =
90 ModuleUtils.getInstance().getModuleConfig(request, application)
91 .getPrefix();
92
93 return (ValidatorResources) application.getAttribute(ValidatorPlugIn.VALIDATOR_KEY
94 + prefix);
95 }
96
97 /***
98 * Retrieve <code>MessageResources</code> for the module.
99 *
100 * @param request the servlet request
101 */
102 public static MessageResources getMessageResources(
103 HttpServletRequest request) {
104 return (MessageResources) request.getAttribute(Globals.MESSAGES_KEY);
105 }
106
107 /***
108 * Retrieve <code>MessageResources</code> for the module and bundle.
109 *
110 * @param application the servlet context
111 * @param request the servlet request
112 * @param bundle the bundle key
113 */
114 public static MessageResources getMessageResources(
115 ServletContext application, HttpServletRequest request, String bundle) {
116 if (bundle == null) {
117 bundle = Globals.MESSAGES_KEY;
118 }
119
120 MessageResources resources =
121 (MessageResources) request.getAttribute(bundle);
122
123 if (resources == null) {
124 ModuleConfig moduleConfig =
125 ModuleUtils.getInstance().getModuleConfig(request, application);
126
127 resources =
128 (MessageResources) application.getAttribute(bundle
129 + moduleConfig.getPrefix());
130 }
131
132 if (resources == null) {
133 resources = (MessageResources) application.getAttribute(bundle);
134 }
135
136 if (resources == null) {
137 throw new NullPointerException(
138 "No message resources found for bundle: " + bundle);
139 }
140
141 return resources;
142 }
143
144 /***
145 * Get the value of a variable.
146 *
147 * @param varName The variable name
148 * @param field the validator Field
149 * @param validator The Validator
150 * @param request the servlet request
151 * @param required Whether the variable is mandatory
152 * @return The variable's value
153 */
154 public static String getVarValue(String varName, Field field,
155 Validator validator, HttpServletRequest request, boolean required) {
156 Var var = field.getVar(varName);
157
158 if (var == null) {
159 String msg = sysmsgs.getMessage("variable.missing", varName);
160
161 if (required) {
162 throw new IllegalArgumentException(msg);
163 }
164
165 if (log.isDebugEnabled()) {
166 log.debug(field.getProperty() + ": " + msg);
167 }
168
169 return null;
170 }
171
172 ServletContext application =
173 (ServletContext) validator.getParameterValue(SERVLET_CONTEXT_PARAM);
174
175 return getVarValue(var, application, request, required);
176 }
177
178 /***
179 * Get the value of a variable.
180 *
181 * @param var the validator variable
182 * @param application The ServletContext
183 * @param request the servlet request
184 * @param required Whether the variable is mandatory
185 * @return The variables values
186 */
187 public static String getVarValue(Var var, ServletContext application,
188 HttpServletRequest request, boolean required) {
189 String varName = var.getName();
190 String varValue = var.getValue();
191
192
193 if (!var.isResource()) {
194 return varValue;
195 }
196
197
198 String bundle = var.getBundle();
199 MessageResources messages =
200 getMessageResources(application, request, bundle);
201
202
203 Locale locale = RequestUtils.getUserLocale(request, null);
204 String value = messages.getMessage(locale, varValue, null);
205
206
207 if ((value == null) && required) {
208 throw new IllegalArgumentException(sysmsgs.getMessage(
209 "variable.resource.notfound", varName, varValue, bundle));
210 }
211
212 if (log.isDebugEnabled()) {
213 log.debug("Var=[" + varName + "], " + "bundle=[" + bundle + "], "
214 + "key=[" + varValue + "], " + "value=[" + value + "]");
215 }
216
217 return value;
218 }
219
220 /***
221 * Gets the <code>Locale</code> sensitive value based on the key passed
222 * in.
223 *
224 * @param messages The Message resources
225 * @param locale The locale.
226 * @param key Key used to lookup the message
227 */
228 public static String getMessage(MessageResources messages, Locale locale,
229 String key) {
230 String message = null;
231
232 if (messages != null) {
233 message = messages.getMessage(locale, key);
234 }
235
236 return (message == null) ? "" : message;
237 }
238
239 /***
240 * Gets the <code>Locale</code> sensitive value based on the key passed
241 * in.
242 *
243 * @param request servlet request
244 * @param key the request key
245 */
246 public static String getMessage(HttpServletRequest request, String key) {
247 MessageResources messages = getMessageResources(request);
248
249 return getMessage(messages, RequestUtils.getUserLocale(request, null),
250 key);
251 }
252
253 /***
254 * Gets the locale sensitive message based on the <code>ValidatorAction</code>
255 * message and the <code>Field</code>'s arg objects.
256 *
257 * @param messages The Message resources
258 * @param locale The locale
259 * @param va The Validator Action
260 * @param field The Validator Field
261 */
262 public static String getMessage(MessageResources messages, Locale locale,
263 ValidatorAction va, Field field) {
264 String[] args = getArgs(va.getName(), messages, locale, field);
265 String msg =
266 (field.getMsg(va.getName()) != null) ? field.getMsg(va.getName())
267 : va.getMsg();
268
269 return messages.getMessage(locale, msg, args);
270 }
271
272 /***
273 * Gets the <code>Locale</code> sensitive value based on the key passed
274 * in.
275 *
276 * @param application the servlet context
277 * @param request the servlet request
278 * @param defaultMessages The default Message resources
279 * @param locale The locale
280 * @param va The Validator Action
281 * @param field The Validator Field
282 */
283 public static String getMessage(ServletContext application,
284 HttpServletRequest request, MessageResources defaultMessages,
285 Locale locale, ValidatorAction va, Field field) {
286 Msg msg = field.getMessage(va.getName());
287
288 if ((msg != null) && !msg.isResource()) {
289 return msg.getKey();
290 }
291
292 String msgKey = null;
293 String msgBundle = null;
294 MessageResources messages = defaultMessages;
295
296 if (msg == null) {
297 msgKey = va.getMsg();
298 } else {
299 msgKey = msg.getKey();
300 msgBundle = msg.getBundle();
301
302 if (msg.getBundle() != null) {
303 messages =
304 getMessageResources(application, request, msg.getBundle());
305 }
306 }
307
308 if ((msgKey == null) || (msgKey.length() == 0)) {
309 return "??? " + va.getName() + "." + field.getProperty() + " ???";
310 }
311
312
313 Arg[] args = field.getArgs(va.getName());
314 String[] argValues =
315 getArgValues(application, request, messages, locale, args);
316
317
318 return messages.getMessage(locale, msgKey, argValues);
319 }
320
321 /***
322 * Gets the <code>ActionMessage</code> based on the
323 * <code>ValidatorAction</code> message and the <code>Field</code>'s arg
324 * objects.
325 *
326 * @param request the servlet request
327 * @param va Validator action
328 * @param field the validator Field
329 */
330 public static ActionMessage getActionMessage(HttpServletRequest request,
331 ValidatorAction va, Field field) {
332 String[] args =
333 getArgs(va.getName(), getMessageResources(request),
334 RequestUtils.getUserLocale(request, null), field);
335
336 String msg =
337 (field.getMsg(va.getName()) != null) ? field.getMsg(va.getName())
338 : va.getMsg();
339
340 return new ActionMessage(msg, args);
341 }
342
343 /***
344 * Gets the <code>ActionMessage</code> based on the
345 * <code>ValidatorAction</code> message and the <code>Field</code>'s arg
346 * objects.
347 *
348 * @param validator the Validator
349 * @param request the servlet request
350 * @param va Validator action
351 * @param field the validator Field
352 */
353 public static ActionMessage getActionMessage(Validator validator,
354 HttpServletRequest request, ValidatorAction va, Field field) {
355 Msg msg = field.getMessage(va.getName());
356
357 if ((msg != null) && !msg.isResource()) {
358 return new ActionMessage(msg.getKey(), false);
359 }
360
361 String msgKey = null;
362 String msgBundle = null;
363
364 if (msg == null) {
365 msgKey = va.getMsg();
366 } else {
367 msgKey = msg.getKey();
368 msgBundle = msg.getBundle();
369 }
370
371 if ((msgKey == null) || (msgKey.length() == 0)) {
372 return new ActionMessage("??? " + va.getName() + "."
373 + field.getProperty() + " ???", false);
374 }
375
376 ServletContext application =
377 (ServletContext) validator.getParameterValue(SERVLET_CONTEXT_PARAM);
378 MessageResources messages =
379 getMessageResources(application, request, msgBundle);
380 Locale locale = RequestUtils.getUserLocale(request, null);
381
382 Arg[] args = field.getArgs(va.getName());
383 String[] argValues =
384 getArgValues(application, request, messages, locale, args);
385
386 ActionMessage actionMessage = null;
387
388 if (msgBundle == null) {
389 actionMessage = new ActionMessage(msgKey, argValues);
390 } else {
391 String message = messages.getMessage(locale, msgKey, argValues);
392
393 actionMessage = new ActionMessage(message, false);
394 }
395
396 return actionMessage;
397 }
398
399 /***
400 * Gets the message arguments based on the current <code>ValidatorAction</code>
401 * and <code>Field</code>.
402 *
403 * @param actionName action name
404 * @param messages message resources
405 * @param locale the locale
406 * @param field the validator field
407 */
408 public static String[] getArgs(String actionName,
409 MessageResources messages, Locale locale, Field field) {
410 String[] argMessages = new String[4];
411
412 Arg[] args =
413 new Arg[] {
414 field.getArg(actionName, 0), field.getArg(actionName, 1),
415 field.getArg(actionName, 2), field.getArg(actionName, 3)
416 };
417
418 for (int i = 0; i < args.length; i++) {
419 if (args[i] == null) {
420 continue;
421 }
422
423 if (args[i].isResource()) {
424 argMessages[i] = getMessage(messages, locale, args[i].getKey());
425 } else {
426 argMessages[i] = args[i].getKey();
427 }
428 }
429
430 return argMessages;
431 }
432
433 /***
434 * Gets the message arguments based on the current <code>ValidatorAction</code>
435 * and <code>Field</code>.
436 *
437 * @param application the servlet context
438 * @param request the servlet request
439 * @param defaultMessages Default message resources
440 * @param locale the locale
441 * @param args The arguments for the message
442 */
443 private static String[] getArgValues(ServletContext application,
444 HttpServletRequest request, MessageResources defaultMessages,
445 Locale locale, Arg[] args) {
446 if ((args == null) || (args.length == 0)) {
447 return null;
448 }
449
450 String[] values = new String[args.length];
451
452 for (int i = 0; i < args.length; i++) {
453 if (args[i] != null) {
454 if (args[i].isResource()) {
455 MessageResources messages = defaultMessages;
456
457 if (args[i].getBundle() != null) {
458 messages =
459 getMessageResources(application, request,
460 args[i].getBundle());
461 }
462
463 values[i] = messages.getMessage(locale, args[i].getKey());
464 } else {
465 values[i] = args[i].getKey();
466 }
467 }
468 }
469
470 return values;
471 }
472
473 /***
474 * Initialize the <code>Validator</code> to perform validation.
475 *
476 * @param key The key that the validation rules are under (the
477 * form elements name attribute).
478 * @param bean The bean validation is being performed on.
479 * @param application servlet context
480 * @param request The current request object.
481 * @param errors The object any errors will be stored in.
482 * @param page This in conjunction with the page property of a
483 * <code>Field<code> can control the processing of
484 * fields. If the field's page is less than or equal
485 * to this page value, it will be processed.
486 */
487 public static Validator initValidator(String key, Object bean,
488 ServletContext application, HttpServletRequest request,
489 ActionMessages errors, int page) {
490 ValidatorResources resources =
491 Resources.getValidatorResources(application, request);
492
493 Locale locale = RequestUtils.getUserLocale(request, null);
494
495 Validator validator = new Validator(resources, key);
496
497 validator.setUseContextClassLoader(true);
498
499 validator.setPage(page);
500
501 validator.setParameter(SERVLET_CONTEXT_PARAM, application);
502 validator.setParameter(HTTP_SERVLET_REQUEST_PARAM, request);
503 validator.setParameter(Validator.LOCALE_PARAM, locale);
504 validator.setParameter(ACTION_MESSAGES_PARAM, errors);
505 validator.setParameter(Validator.BEAN_PARAM, bean);
506
507 return validator;
508 }
509 }