001: /*
002: * $Id: Resources.java 476419 2006-11-18 02:28:07Z niallp $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts.validator;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.apache.commons.validator.Arg;
026: import org.apache.commons.validator.Field;
027: import org.apache.commons.validator.Msg;
028: import org.apache.commons.validator.Validator;
029: import org.apache.commons.validator.ValidatorAction;
030: import org.apache.commons.validator.ValidatorResources;
031: import org.apache.commons.validator.Var;
032: import org.apache.struts.Globals;
033: import org.apache.struts.action.ActionMessage;
034: import org.apache.struts.action.ActionMessages;
035: import org.apache.struts.config.ModuleConfig;
036: import org.apache.struts.util.MessageResources;
037: import org.apache.struts.util.ModuleUtils;
038: import org.apache.struts.util.RequestUtils;
039:
040: import javax.servlet.ServletContext;
041: import javax.servlet.http.HttpServletRequest;
042:
043: import java.util.Locale;
044:
045: /**
046: * This class helps provides some useful methods for retrieving objects from
047: * different scopes of the application.
048: *
049: * @version $Rev: 476419 $ $Date: 2005-09-16 23:34:41 -0400 (Fri, 16 Sep 2005)
050: * $
051: * @since Struts 1.1
052: */
053: public class Resources {
054: /**
055: * The message resources for this package.
056: */
057: private static MessageResources sysmsgs = MessageResources
058: .getMessageResources("org.apache.struts.validator.LocalStrings");
059:
060: /**
061: * <p>Commons Logging instance.</p>
062: */
063: private static Log log = LogFactory.getLog(Resources.class);
064:
065: /**
066: * Resources key the <code>ServletContext</code> is stored under.
067: */
068: private static String SERVLET_CONTEXT_PARAM = "javax.servlet.ServletContext";
069:
070: /**
071: * Resources key the <code>HttpServletRequest</code> is stored under.
072: */
073: private static String HTTP_SERVLET_REQUEST_PARAM = "javax.servlet.http.HttpServletRequest";
074:
075: /**
076: * Resources key the <code>ActionMessages</code> is stored under.
077: */
078: private static String ACTION_MESSAGES_PARAM = "org.apache.struts.action.ActionMessages";
079:
080: /**
081: * Retrieve <code>ValidatorResources</code> for the current module.
082: *
083: * @param application Application Context
084: * @param request The ServletRequest
085: */
086: public static ValidatorResources getValidatorResources(
087: ServletContext application, HttpServletRequest request) {
088: String prefix = ModuleUtils.getInstance().getModuleConfig(
089: request, application).getPrefix();
090:
091: return (ValidatorResources) application
092: .getAttribute(ValidatorPlugIn.VALIDATOR_KEY + prefix);
093: }
094:
095: /**
096: * Retrieve <code>MessageResources</code> for the module.
097: *
098: * @param request the servlet request
099: */
100: public static MessageResources getMessageResources(
101: HttpServletRequest request) {
102: return (MessageResources) request
103: .getAttribute(Globals.MESSAGES_KEY);
104: }
105:
106: /**
107: * Retrieve <code>MessageResources</code> for the module and bundle.
108: *
109: * @param application the servlet context
110: * @param request the servlet request
111: * @param bundle the bundle key
112: */
113: public static MessageResources getMessageResources(
114: ServletContext application, HttpServletRequest request,
115: String bundle) {
116: if (bundle == null) {
117: bundle = Globals.MESSAGES_KEY;
118: }
119:
120: MessageResources resources = (MessageResources) request
121: .getAttribute(bundle);
122:
123: if (resources == null) {
124: ModuleConfig moduleConfig = ModuleUtils.getInstance()
125: .getModuleConfig(request, application);
126:
127: resources = (MessageResources) application
128: .getAttribute(bundle + moduleConfig.getPrefix());
129: }
130:
131: if (resources == null) {
132: resources = (MessageResources) application
133: .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,
156: boolean required) {
157: Var var = field.getVar(varName);
158:
159: if (var == null) {
160: String msg = sysmsgs
161: .getMessage("variable.missing", varName);
162:
163: if (required) {
164: throw new IllegalArgumentException(msg);
165: }
166:
167: if (log.isDebugEnabled()) {
168: log.debug(field.getProperty() + ": " + msg);
169: }
170:
171: return null;
172: }
173:
174: ServletContext application = (ServletContext) validator
175: .getParameterValue(SERVLET_CONTEXT_PARAM);
176:
177: return getVarValue(var, application, request, required);
178: }
179:
180: /**
181: * Get the value of a variable.
182: *
183: * @param var the validator variable
184: * @param application The ServletContext
185: * @param request the servlet request
186: * @param required Whether the variable is mandatory
187: * @return The variables values
188: */
189: public static String getVarValue(Var var,
190: ServletContext application, HttpServletRequest request,
191: boolean required) {
192: String varName = var.getName();
193: String varValue = var.getValue();
194:
195: // Non-resource variable
196: if (!var.isResource()) {
197: return varValue;
198: }
199:
200: // Get the message resources
201: String bundle = var.getBundle();
202: MessageResources messages = getMessageResources(application,
203: request, bundle);
204:
205: // Retrieve variable's value from message resources
206: Locale locale = RequestUtils.getUserLocale(request, null);
207: String value = messages.getMessage(locale, varValue, null);
208:
209: // Not found in message resources
210: if ((value == null) && required) {
211: throw new IllegalArgumentException(sysmsgs.getMessage(
212: "variable.resource.notfound", varName, varValue,
213: bundle));
214: }
215:
216: if (log.isDebugEnabled()) {
217: log.debug("Var=[" + varName + "], " + "bundle=[" + bundle
218: + "], " + "key=[" + varValue + "], " + "value=["
219: + value + "]");
220: }
221:
222: return value;
223: }
224:
225: /**
226: * Gets the <code>Locale</code> sensitive value based on the key passed
227: * in.
228: *
229: * @param messages The Message resources
230: * @param locale The locale.
231: * @param key Key used to lookup the message
232: */
233: public static String getMessage(MessageResources messages,
234: Locale locale, String key) {
235: String message = null;
236:
237: if (messages != null) {
238: message = messages.getMessage(locale, key);
239: }
240:
241: return (message == null) ? "" : message;
242: }
243:
244: /**
245: * Gets the <code>Locale</code> sensitive value based on the key passed
246: * in.
247: *
248: * @param request servlet request
249: * @param key the request key
250: */
251: public static String getMessage(HttpServletRequest request,
252: String key) {
253: MessageResources messages = getMessageResources(request);
254:
255: return getMessage(messages, RequestUtils.getUserLocale(request,
256: null), key);
257: }
258:
259: /**
260: * Gets the locale sensitive message based on the <code>ValidatorAction</code>
261: * message and the <code>Field</code>'s arg objects.
262: *
263: * @param messages The Message resources
264: * @param locale The locale
265: * @param va The Validator Action
266: * @param field The Validator Field
267: */
268: public static String getMessage(MessageResources messages,
269: Locale locale, ValidatorAction va, Field field) {
270: String[] args = getArgs(va.getName(), messages, locale, field);
271: String msg = (field.getMsg(va.getName()) != null) ? field
272: .getMsg(va.getName()) : va.getMsg();
273:
274: return messages.getMessage(locale, msg, args);
275: }
276:
277: /**
278: * Gets the <code>Locale</code> sensitive value based on the key passed
279: * in.
280: *
281: * @param application the servlet context
282: * @param request the servlet request
283: * @param defaultMessages The default Message resources
284: * @param locale The locale
285: * @param va The Validator Action
286: * @param field The Validator Field
287: */
288: public static String getMessage(ServletContext application,
289: HttpServletRequest request,
290: MessageResources defaultMessages, Locale locale,
291: ValidatorAction va, Field field) {
292: Msg msg = field.getMessage(va.getName());
293:
294: if ((msg != null) && !msg.isResource()) {
295: return msg.getKey();
296: }
297:
298: String msgKey = null;
299: String msgBundle = null;
300: MessageResources messages = defaultMessages;
301:
302: if (msg == null) {
303: msgKey = va.getMsg();
304: } else {
305: msgKey = msg.getKey();
306: msgBundle = msg.getBundle();
307:
308: if (msg.getBundle() != null) {
309: messages = getMessageResources(application, request,
310: msg.getBundle());
311: }
312: }
313:
314: if ((msgKey == null) || (msgKey.length() == 0)) {
315: return "??? " + va.getName() + "." + field.getProperty()
316: + " ???";
317: }
318:
319: // Get the arguments
320: Arg[] args = field.getArgs(va.getName());
321: String[] argValues = getArgValues(application, request,
322: messages, locale, args);
323:
324: // Return the message
325: return messages.getMessage(locale, msgKey, argValues);
326: }
327:
328: /**
329: * Gets the <code>ActionMessage</code> based on the
330: * <code>ValidatorAction</code> message and the <code>Field</code>'s arg
331: * objects.
332: * <p>
333: * <strong>Note:</strong> this method does not respect bundle information
334: * stored with the field's <msg> or <arg> elements, and localization
335: * will not work for alternative resource bundles. This method is
336: * deprecated for this reason, and you should use
337: * {@link #getActionMessage(Validator,HttpServletRequest,ValidatorAction,Field)}
338: * instead.
339: *
340: * @param request the servlet request
341: * @param va Validator action
342: * @param field the validator Field
343: * @deprecated Use getActionMessage(Validator, HttpServletRequest,
344: * ValidatorAction, Field) method instead
345: */
346: public static ActionMessage getActionMessage(
347: HttpServletRequest request, ValidatorAction va, Field field) {
348: String[] args = getArgs(va.getName(),
349: getMessageResources(request), RequestUtils
350: .getUserLocale(request, null), field);
351:
352: String msg = (field.getMsg(va.getName()) != null) ? field
353: .getMsg(va.getName()) : va.getMsg();
354:
355: return new ActionMessage(msg, args);
356: }
357:
358: /**
359: * Gets the <code>ActionMessage</code> based on the
360: * <code>ValidatorAction</code> message and the <code>Field</code>'s arg
361: * objects.
362: *
363: * @param validator the Validator
364: * @param request the servlet request
365: * @param va Validator action
366: * @param field the validator Field
367: */
368: public static ActionMessage getActionMessage(Validator validator,
369: HttpServletRequest request, ValidatorAction va, Field field) {
370: Msg msg = field.getMessage(va.getName());
371:
372: if ((msg != null) && !msg.isResource()) {
373: return new ActionMessage(msg.getKey(), false);
374: }
375:
376: String msgKey = null;
377: String msgBundle = null;
378:
379: if (msg == null) {
380: msgKey = va.getMsg();
381: } else {
382: msgKey = msg.getKey();
383: msgBundle = msg.getBundle();
384: }
385:
386: if ((msgKey == null) || (msgKey.length() == 0)) {
387: return new ActionMessage("??? " + va.getName() + "."
388: + field.getProperty() + " ???", false);
389: }
390:
391: ServletContext application = (ServletContext) validator
392: .getParameterValue(SERVLET_CONTEXT_PARAM);
393: MessageResources messages = getMessageResources(application,
394: request, msgBundle);
395: Locale locale = RequestUtils.getUserLocale(request, null);
396:
397: Arg[] args = field.getArgs(va.getName());
398: String[] argValues = getArgValues(application, request,
399: messages, locale, args);
400:
401: ActionMessage actionMessage = null;
402:
403: if (msgBundle == null) {
404: actionMessage = new ActionMessage(msgKey, argValues);
405: } else {
406: String message = messages.getMessage(locale, msgKey,
407: argValues);
408:
409: actionMessage = new ActionMessage(message, false);
410: }
411:
412: return actionMessage;
413: }
414:
415: /**
416: * Gets the message arguments based on the current <code>ValidatorAction</code>
417: * and <code>Field</code>.
418: *
419: * @param actionName action name
420: * @param messages message resources
421: * @param locale the locale
422: * @param field the validator field
423: */
424: public static String[] getArgs(String actionName,
425: MessageResources messages, Locale locale, Field field) {
426: String[] argMessages = new String[4];
427:
428: Arg[] args = new Arg[] { field.getArg(actionName, 0),
429: field.getArg(actionName, 1),
430: field.getArg(actionName, 2),
431: field.getArg(actionName, 3) };
432:
433: for (int i = 0; i < args.length; i++) {
434: if (args[i] == null) {
435: continue;
436: }
437:
438: if (args[i].isResource()) {
439: argMessages[i] = getMessage(messages, locale, args[i]
440: .getKey());
441: } else {
442: argMessages[i] = args[i].getKey();
443: }
444: }
445:
446: return argMessages;
447: }
448:
449: /**
450: * Gets the message arguments based on the current <code>ValidatorAction</code>
451: * and <code>Field</code>.
452: *
453: * @param application the servlet context
454: * @param request the servlet request
455: * @param defaultMessages Default message resources
456: * @param locale the locale
457: * @param args The arguments for the message
458: */
459: private static String[] getArgValues(ServletContext application,
460: HttpServletRequest request,
461: MessageResources defaultMessages, Locale locale, Arg[] args) {
462: if ((args == null) || (args.length == 0)) {
463: return null;
464: }
465:
466: String[] values = new String[args.length];
467:
468: for (int i = 0; i < args.length; i++) {
469: if (args[i] != null) {
470: if (args[i].isResource()) {
471: MessageResources messages = defaultMessages;
472:
473: if (args[i].getBundle() != null) {
474: messages = getMessageResources(application,
475: request, args[i].getBundle());
476: }
477:
478: values[i] = messages.getMessage(locale, args[i]
479: .getKey());
480: } else {
481: values[i] = args[i].getKey();
482: }
483: }
484: }
485:
486: return values;
487: }
488:
489: /**
490: * Initialize the <code>Validator</code> to perform validation.
491: *
492: * @param key The key that the validation rules are under (the
493: * form elements name attribute).
494: * @param bean The bean validation is being performed on.
495: * @param application servlet context
496: * @param request The current request object.
497: * @param errors The object any errors will be stored in.
498: * @param page This in conjunction with the page property of a
499: * <code>Field<code> can control the processing of
500: * fields. If the field's page is less than or equal
501: * to this page value, it will be processed.
502: */
503: public static Validator initValidator(String key, Object bean,
504: ServletContext application, HttpServletRequest request,
505: ActionMessages errors, int page) {
506: ValidatorResources resources = Resources.getValidatorResources(
507: application, request);
508:
509: Locale locale = RequestUtils.getUserLocale(request, null);
510:
511: Validator validator = new Validator(resources, key);
512:
513: validator.setUseContextClassLoader(true);
514:
515: validator.setPage(page);
516:
517: validator.setParameter(SERVLET_CONTEXT_PARAM, application);
518: validator.setParameter(HTTP_SERVLET_REQUEST_PARAM, request);
519: validator.setParameter(Validator.LOCALE_PARAM, locale);
520: validator.setParameter(ACTION_MESSAGES_PARAM, errors);
521: validator.setParameter(Validator.BEAN_PARAM, bean);
522:
523: return validator;
524: }
525: }
|