package org.g4studio.core.mvc.xstruts.validator;
import java.util.Locale;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.Arg;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.Msg;
import org.apache.commons.validator.Validator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.ValidatorResources;
import org.apache.commons.validator.Var;
import org.g4studio.core.mvc.xstruts.Globals;
import org.g4studio.core.mvc.xstruts.action.ActionMessage;
import org.g4studio.core.mvc.xstruts.action.ActionMessages;
import org.g4studio.core.mvc.xstruts.config.ModuleConfig;
import org.g4studio.core.mvc.xstruts.util.MessageResources;
import org.g4studio.core.mvc.xstruts.util.ModuleUtils;
import org.g4studio.core.mvc.xstruts.util.RequestUtils;
/**
* This class helps provides some useful methods for retrieving objects from
* different scopes of the application.
*
* @version $Rev: 421119 $ $Date: 2005-09-16 23:34:41 -0400 (Fri, 16 Sep 2005) $
* @since Struts 1.1
*/
public class Resources {
/**
* The message resources for this package.
*/
private static MessageResources sysmsgs = MessageResources
.getMessageResources("org.g4studio.core.mvc.xstruts.validator.LocalStrings");
/**
* <p>
* Commons Logging instance.
* </p>
*/
private static Log log = LogFactory.getLog(Resources.class);
/**
* Resources key the <code>ServletContext</code> is stored under.
*/
private static String SERVLET_CONTEXT_PARAM = "javax.servlet.ServletContext";
/**
* Resources key the <code>HttpServletRequest</code> is stored under.
*/
private static String HTTP_SERVLET_REQUEST_PARAM = "javax.servlet.http.HttpServletRequest";
/**
* Resources key the <code>ActionMessages</code> is stored under.
*/
private static String ACTION_MESSAGES_PARAM = "org.g4studio.core.mvc.xstruts.action.ActionMessages";
/**
* Retrieve <code>ValidatorResources</code> for the current module.
*
* @param application
* Application Context
* @param request
* The ServletRequest
*/
public static ValidatorResources getValidatorResources(ServletContext application, HttpServletRequest request) {
String prefix = ModuleUtils.getInstance().getModuleConfig(request, application).getPrefix();
return (ValidatorResources) application.getAttribute(ValidatorPlugIn.VALIDATOR_KEY + prefix);
}
/**
* Retrieve <code>MessageResources</code> for the module.
*
* @param request
* the servlet request
*/
public static MessageResources getMessageResources(HttpServletRequest request) {
return (MessageResources) request.getAttribute(Globals.MESSAGES_KEY);
}
/**
* Retrieve <code>MessageResources</code> for the module and bundle.
*
* @param application
* the servlet context
* @param request
* the servlet request
* @param bundle
* the bundle key
*/
public static MessageResources getMessageResources(ServletContext application, HttpServletRequest request,
String bundle) {
if (bundle == null) {
bundle = Globals.MESSAGES_KEY;
}
MessageResources resources = (MessageResources) request.getAttribute(bundle);
if (resources == null) {
ModuleConfig moduleConfig = ModuleUtils.getInstance().getModuleConfig(request, application);
resources = (MessageResources) application.getAttribute(bundle + moduleConfig.getPrefix());
}
if (resources == null) {
resources = (MessageResources) application.getAttribute(bundle);
}
if (resources == null) {
throw new NullPointerException("No message resources found for bundle: " + bundle);
}
return resources;
}
/**
* Get the value of a variable.
*
* @param varName
* The variable name
* @param field
* the validator Field
* @param validator
* The Validator
* @param request
* the servlet request
* @param required
* Whether the variable is mandatory
* @return The variable's value
*/
public static String getVarValue(String varName, Field field, Validator validator, HttpServletRequest request,
boolean required) {
Var var = field.getVar(varName);
if (var == null) {
String msg = sysmsgs.getMessage("variable.missing", varName);
if (required) {
throw new IllegalArgumentException(msg);
}
if (log.isDebugEnabled()) {
log.debug(field.getProperty() + ": " + msg);
}
return null;
}
ServletContext application = (ServletContext) validator.getParameterValue(SERVLET_CONTEXT_PARAM);
return getVarValue(var, application, request, required);
}
/**
* Get the value of a variable.
*
* @param var
* the validator variable
* @param application
* The ServletContext
* @param request
* the servlet request
* @param required
* Whether the variable is mandatory
* @return The variables values
*/
public static String getVarValue(Var var, ServletContext application, HttpServletRequest request, boolean required) {
String varName = var.getName();
String varValue = var.getValue();
// Non-resource variable
if (!var.isResource()) {
return varValue;
}
// Get the message resources
String bundle = var.getBundle();
MessageResources messages = getMessageResources(application, request, bundle);
// Retrieve variable's value from message resources
Locale locale = RequestUtils.getUserLocale(request, null);
String value = messages.getMessage(locale, varValue, null);
// Not found in message resources
if ((value == null) && required) {
throw new IllegalArgumentException(sysmsgs.getMessage("variable.resource.notfound", varName, varValue,
bundle));
}
if (log.isDebugEnabled()) {
log.debug("Var=[" + varName + "], " + "bundle=[" + bundle + "], " + "key=[" + varValue + "], " + "value=["
+ value + "]");
}
return value;
}
/**
* Gets the <code>Locale</code> sensitive value based on the key passed in.
*
* @param messages
* The Message resources
* @param locale
* The locale.
* @param key
* Key used to lookup the message
*/
public static String getMessage(MessageResources messages, Locale locale, String key) {
String message = null;
if (messages != null) {
message = messages.getMessage(locale, key);
}
return (message == null) ? "" : message;
}
/**
* Gets the <code>Locale</code> sensitive value based on the key passed in.
*
* @param request
* servlet request
* @param key
* the request key
*/
public static String getMessage(HttpServletRequest request, String key) {
MessageResources messages = getMessageResources(request);
return getMessage(messages, RequestUtils.getUserLocale(request, null), key);
}
/**
* Gets the locale sensitive message based on the
* <code>ValidatorAction</code> message and the <code>Field</code>'s arg
* objects.
*
* @param messages
* The Message resources
* @param locale
* The locale
* @param va
* The Validator Action
* @param field
* The Validator Field
*/
public static String getMessage(MessageResources messages, Locale locale, ValidatorAction va, Field field) {
String[] args = getArgs(va.getName(), messages, locale, field);
String msg = (field.getMsg(va.getName()) != null) ? field.getMsg(va.getName()) : va.getMsg();
return messages.getMessage(locale, msg, args);
}
/**
* Gets the <code>Locale</code> sensitive value based on the key passed in.
*
* @param application
* the servlet context
* @param request
* the servlet request
* @param defaultMessages
* The default Message resources
* @param locale
* The locale
* @param va
* The Validator Action
* @param field
* The Validator Field
*/
public static String getMessage(ServletContext application, HttpServletRequest request,
MessageResources defaultMessages, Locale locale, ValidatorAction va, Field field) {
Msg msg = field.getMessage(va.getName());
if ((msg != null) && !msg.isResource()) {
return msg.getKey();
}
String msgKey = null;
String msgBundle = null;
MessageResources messages = defaultMessages;
if (msg == null) {
msgKey = va.getMsg();
} else {
msgKey = msg.getKey();
msgBundle = msg.getBundle();
if (msg.getBundle() != null) {
messages = getMessageResources(application, request, msg.getBundle());
}
}
if ((msgKey == null) || (msgKey.length() == 0)) {
return "??? " + va.getName() + "." + field.getProperty() + " ???";
}
// Get the arguments
Arg[] args = field.getArgs(va.getName());
String[] argValues = getArgValues(application, request, messages, locale, args);
// Return the message
return messages.getMessage(locale, msgKey, argValues);
}
/**
* Gets the <code>ActionMessage</code> based on the
* <code>ValidatorAction</code> message and the <code>Field</code>'s arg
* objects.
*
* @param request
* the servlet request
* @param va
* Validator action
* @param field
* the validator Field
*/
public static ActionMessage getActionMessage(HttpServletRequest request, ValidatorAction va, Field field) {
String[] args = getArgs(va.getName(), getMessageResources(request), RequestUtils.getUserLocale(request, null),
field);
String msg = (field.getMsg(va.getName()) != null) ? field.getMsg(va.getName()) : va.getMsg();
return new ActionMessage(msg, args);
}
/**
* Gets the <code>ActionMessage</code> based on the
* <code>ValidatorAction</code> message and the <code>Field</code>'s arg
* objects.
*
* @param validator
* the Validator
* @param request
* the servlet request
* @param va
* Validator action
* @param field
* the validator Field
*/
public static ActionMessage getActionMessage(Validator validator, HttpServletRequest request, ValidatorAction va,
Field field) {
Msg msg = field.getMessage(va.getName());
if ((msg != null) && !msg.isResource()) {
return new ActionMessage(msg.getKey(), false);
}
String msgKey = null;
String msgBundle = null;
if (msg == null) {
msgKey = va.getMsg();
} else {
msgKey = msg.getKey();
msgBundle = msg.getBundle();
}
if ((msgKey == null) || (msgKey.length() == 0)) {
return new ActionMessage("??? " + va.getName() + "." + field.getProperty() + " ???", false);
}
ServletContext application = (ServletContext) validator.getParameterValue(SERVLET_CONTEXT_PARAM);
MessageResources messages = getMessageResources(application, request, msgBundle);
Locale locale = RequestUtils.getUserLocale(request, null);
Arg[] args = field.getArgs(va.getName());
String[] argValues = getArgValues(application, request, messages, locale, args);
ActionMessage actionMessage = null;
if (msgBundle == null) {
actionMessage = new ActionMessage(msgKey, argValues);
} else {
String message = messages.getMessage(locale, msgKey, argValues);
actionMessage = new ActionMessage(message, false);
}
return actionMessage;
}
/**
* Gets the message arguments based on the current
* <code>ValidatorAction</code> and <code>Field</code>.
*
* @param actionName
* action name
* @param messages
* message resources
* @param locale
* the locale
* @param field
* the validator field
*/
public static String[] getArgs(String actionName, MessageResources messages, Locale locale, Field field) {
String[] argMessages = new String[4];
Arg[] args = new Arg[] { field.getArg(actionName, 0), field.getArg(actionName, 1), field.getArg(actionName, 2),
field.getArg(actionName, 3) };
for (int i = 0; i < args.length; i++) {
if (args[i] == null) {
continue;
}
if (args[i].isResource()) {
argMessages[i] = getMessage(messages, locale, args[i].getKey());
} else {
argMessages[i] = args[i].getKey();
}
}
return argMessages;
}
/**
* Gets the message arguments based on the current
* <code>ValidatorAction</code> and <code>Field</code>.
*
* @param application
* the servlet context
* @param request
* the servlet request
* @param defaultMessages
* Default message resources
* @param locale
* the locale
* @param args
* The arguments for the message
*/
private static String[] getArgValues(ServletContext application, HttpServletRequest request,
MessageResources defaultMessages, Locale locale, Arg[] args) {
if ((args == null) || (args.length == 0)) {
return null;
}
String[] values = new String[args.length];
for (int i = 0; i < args.length; i++) {
if (args[i] != null) {
if (args[i].isResource()) {
MessageResources messages = defaultMessages;
if (args[i].getBundle() != null) {
messages = getMessageResources(application, request, args[i].getBundle());
}
values[i] = messages.getMessage(locale, args[i].getKey());
} else {
values[i] = args[i].getKey();
}
}
}
return values;
}
/**
* Initialize the <code>Validator</code> to perform validation.
*
* @param key
* The key that the validation rules are under (the form elements
* name attribute).
* @param bean
* The bean validation is being performed on.
* @param application
* servlet context
* @param request
* The current request object.
* @param errors
* The object any errors will be stored in.
* @param page
* This in conjunction with the page property of a
* <code>Field<code> can control the processing of
* fields. If the field's page is less than or equal
* to this page value, it will be processed.
*/
public static Validator initValidator(String key, Object bean, ServletContext application,
HttpServletRequest request, ActionMessages errors, int page) {
ValidatorResources resources = Resources.getValidatorResources(application, request);
Locale locale = RequestUtils.getUserLocale(request, null);
Validator validator = new Validator(resources, key);
validator.setUseContextClassLoader(true);
validator.setPage(page);
validator.setParameter(SERVLET_CONTEXT_PARAM, application);
validator.setParameter(HTTP_SERVLET_REQUEST_PARAM, request);
validator.setParameter(Validator.LOCALE_PARAM, locale);
validator.setParameter(ACTION_MESSAGES_PARAM, errors);
validator.setParameter(Validator.BEAN_PARAM, bean);
return validator;
}
}