/** * Copyright (c) 2009--2012 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.redhat.rhn.frontend.struts; import com.redhat.rhn.common.validator.Validator; import com.redhat.rhn.common.validator.ValidatorError; import com.redhat.rhn.common.validator.ValidatorException; import com.redhat.rhn.common.validator.ValidatorResult; import com.redhat.rhn.common.validator.ValidatorService; import com.redhat.rhn.common.validator.ValidatorWarning; import org.apache.struts.action.Action; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import org.apache.struts.action.DynaActionForm; import java.net.URL; import java.util.List; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.servlet.http.HttpServletRequest; /** * RhnValidationHelper contains helpful to be used by Struts actions to interact * with the ValidationService * * @version $Rev$ */ public class RhnValidationHelper { private static final String FAILED_KEY = "rhn_validation_failed"; /** utility class */ private RhnValidationHelper() { } /** * Converts an array of Strings into a set of ActionError messages * * @param errors Array of ValidatorErrors you want to convert * @return ActionErrors object with set of messages */ public static ActionErrors validatorErrorToActionErrors( ValidatorError... errors) { ActionErrors messages = new ActionErrors(); for (int i = 0; i < errors.length; i++) { messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( errors[i].getKey(), errors[i].getValues())); } return messages; } /** * Converts an array of ValidatorWarnings into a set of ActionMessages. * * @param warnings Array of ValidatorWarnings you want to convert * @return ActionMessages object with set of messages */ public static ActionMessages validatorWarningToActionMessages( ValidatorWarning... warnings) { ActionMessages messages = new ActionMessages(); for (int i = 0; i < warnings.length; i++) { messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( warnings[i].getKey(), warnings[i].getValues())); } return messages; } /** * Validate a DynaActionForm from an Action and get back the set of * ActionErrors This method expects there to be an XSD file to use to * validate the Form with located in the same package as the Action under a * subdir named: validation/ * * For example, com.redhat.rhn.frontend.action.LoginAction has an associated * loginForm in Struts, so you would need a: * * com/redhat/rhn/frontend/action/validation/loginForm.xsd * * @param action The action associated with the form * @param form The form to validate * @return ActionErrors if there were validation errors, otherwise its null */ public static ActionErrors validateDynaActionForm(Action action, DynaActionForm form) { return validateDynaActionForm(action.getClass(), form, null); } /** * Validate a DynaActionForm from an Action and get back the set of * ActionErrors This method expects there to be an XSD file to use to * validate the Form with located in the same package as the Action under a * subdir named: validation/ * * For example, com.redhat.rhn.frontend.action.LoginAction has an associated * loginForm in Struts, so you would need a: * * com/redhat/rhn.frontend/action/validation/loginForm.xsd * * @param action The action associated with the form * @param form The form to validate * @param fieldNames List of form field names to validate * @return ActionErrors if there were validation errors, otherwise its null */ public static ActionErrors validateDynaActionForm(Action action, DynaActionForm form, List fieldNames) { return validateDynaActionForm(action.getClass(), form, fieldNames); } /** * Validate a DynaActionForm from an class and get back the set of * ActionErrors This method expects there to be an XSD file to use to * validate the Form with located in the same package as the class under a * subdir named: validation/ * * For example, com.redhat.rhn.frontend.action.LoginAction has an associated * loginForm in Struts, so you would need a: * * com/redhat/rhn/frontend/action/validation/loginForm.xsd * * @param base the base from which to lookup the validator * @param form The form to validate * @return ActionErrors if there were validation errors, otherwise its null */ public static ActionErrors validateDynaActionForm(Class base, DynaActionForm form) { return validateDynaActionForm(base, form, null); } /** * Validate a DynaActionForm from an class and get back the set of * ActionErrors This method expects there to be an XSD file to use to * validate the Form with located in the same package as the class under a * subdir named: validation/ * * For example, com.redhat.rhn.frontend.action.LoginAction has an associated * loginForm in Struts, so you would need a: * * com/redhat/rhn/frontend/action/validation/loginForm.xsd * * Sometimes, you want to use a given form and validation for a variety of * actions, which may not all belong in the same package hierarchy. This * code checks for a "validatorPath" attribute, and if it finds it, looks * for the validator .xsd at that path, rather than using the 'dead * reckoning"approach described above. * * @param base the base from which to lookup the validator * @param form The form to validate * @param fieldNames List of field names to validate * @return ActionErrors if there were validation errors, otherwise its null */ public static ActionErrors validateDynaActionForm(Class base, DynaActionForm form, List fieldNames) { return validateDynaActionForm(base, form, fieldNames, null); } /** * Validate a DynaActionForm from an class and get back the set of * ActionErrors This method expects there to be an XSD file to use to * validate the Form with located in the same package as the class under a * subdir named: validation/ * * For example, com.redhat.rhn.frontend.action.LoginAction has an associated * loginForm in Struts, so you would need a: * * com/redhat/rhn/frontend/action/validation/loginForm.xsd * * Sometimes, you want to use a given form and validation for a variety of * actions, which may not all belong in the same package hierarchy. This * code will use the XSD pointed at by the slash-delimited xsdName, if one * is provided (eg, "") rather than using the 'dead reckoning"approach * described above. * * @param base the base from which to lookup the validator * @param form The form to validate * @param fieldNames List of field names to validate * @param xsdName the fully-qualified pathname to the XSD that we want to * validate against, or "null" if we want to use the dead-reckoning approach * @return ActionErrors if there were validation errors, otherwise its null */ public static ActionErrors validateDynaActionForm(Class base, DynaActionForm form, List fieldNames, String xsdName) { String formName = form.getDynaClass().getName(); if (xsdName == null) { xsdName = "validation/" + formName + ".xsd"; } ValidatorResult result = validate(base, form, fieldNames, xsdName); if (!result.isEmpty()) { return validatorErrorToActionErrors(result.getErrors().toArray(new ValidatorError[0])); } return new ActionErrors(); } /** * Validate a DynaActionForm from an class and get back the set of * ActionErrors This method expects there to be an XSD file to use to * validate the Form with located in the same package as the class under a * subdir named: validation/ * * For example, com.redhat.rhn.frontend.action.LoginAction has an associated * loginForm in Struts, so you would need a: * * com/redhat/rhn/frontend/action/validation/loginForm.xsd * * Sometimes, you want to use a given form and validation for a variety of * actions, which may not all belong in the same package hierarchy. This * code will use the XSD pointed at by the slash-delimited xsdName, if one * is provided (eg, "") rather than using the 'dead reckoning"approach * described above. * * @param base the base from which to lookup the validator * @param toValidate The form to validate * @param fieldNames List of field names to validate * @param xsdName the fully-qualified pathname to the XSD that we want to * validate against. * @return ValidatorResult , look at the result to determine errors.. */ public static ValidatorResult validate(Class base, Object toValidate, List fieldNames, String xsdName) { Validator validator; try { URL xsd = base.getResource(xsdName); if (xsd == null) { throw new IllegalArgumentException( "Could not find validator for " + xsdName + " and " + base.getName()); } validator = Validator.getInstance(xsd); } catch (java.io.IOException ioe) { throw new ValidatorException("Failed to instantiate Validator"); } return ValidatorService.getInstance().validateObject(toValidate, validator, fieldNames); } /** * Validate a DynaActionForm from an class and get back the set of * ActionErrors This method expects there to be an XSD file to use to * validate the Form with located in the same package as the class under a * subdir named: validation/ * * For example, com.redhat.rhn.frontend.action.LoginAction has an associated * loginForm in Struts, so you would need a: * * com/redhat/rhn/frontend/action/validation/loginForm.xsd * * Sometimes, you want to use a given form and validation for a variety of * actions, which may not all belong in the same package hierarchy. This * code will use the XSD pointed at by the slash-delimited xsdName, if one * is provided (eg, "") rather than using the 'dead reckoning"approach * described above. * * @param toValidate The form to validate * @param xsdPath the fully-qualified pathname to the XSD that we want to * validate against. * @return ValidatorResult , look at the result to determine errors.. */ public static ValidatorResult validate(Object toValidate, String xsdPath) { return validate(RhnValidationHelper.class, toValidate, null, xsdPath); } /** * Place a flag in the request to indicate that the form failed its * validation This can be used by SetupActions to determine if they should * fill out the form with default values or not. * @param request Set the attribute on this request */ public static void setFailedValidation(HttpServletRequest request) { request.setAttribute(FAILED_KEY, "true"); } /** * Check the request to see if an Action indicated that a form failed its * validation process. * @param request to check to see if validation failed * @return boolean if the validation failed or not */ public static boolean getFailedValidation(HttpServletRequest request) { String failed = (String) request.getAttribute(FAILED_KEY); return (failed != null && failed.equals("true")); } /** * Return <code>true</code> if <code>email</code> is a valid email * address * @param email the email to validate * @return <code>true</code> if <code>email</code> is a valid email * address * @see InternetAddress#validate */ public static boolean isValidEmailAddress(String email) { try { new InternetAddress(email).validate(); return true; } catch (AddressException e) { return false; } } /** * Converts an single instance of a ValidatorError to an ActionErrors class * for use in Struts. * * @param ve Single instance of a ValidatorError * @return ActionErrors object with set of messages * public static ActionErrors validatorErrorToActionErrors(ValidatorError ve) { ValidatorError[] varray = new ValidatorError[1]; varray[0] = ve; return validatorErrorToActionErrors(varray); }*/ }