You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2011/12/02 17:33:45 UTC
svn commit: r1209569 [32/50] - in /struts/struts2/branches/STRUTS_3_X:
apps/blank/src/main/java/example/ apps/blank/src/test/java/example/
apps/jboss-blank/src/main/java/example/
apps/jboss-blank/src/test/java/example/ apps/mailreader/src/main/java/mai...
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/DefaultValidatorFileParser.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/DefaultValidatorFileParser.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/DefaultValidatorFileParser.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/DefaultValidatorFileParser.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.validator;
+
+import org.apache.struts2.xwork2.ObjectFactory;
+import org.apache.struts2.xwork2.config.ConfigurationException;
+import org.apache.struts2.xwork2.config.providers.XmlHelper;
+import org.apache.struts2.xwork2.inject.Inject;
+import org.apache.struts2.xwork2.util.DomHelper;
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerFactory;
+import org.w3c.dom.*;
+import org.xml.sax.InputSource;
+
+import java.io.InputStream;
+import java.util.*;
+
+
+/**
+ * Parse the validation file. (eg. MyAction-validation.xml, MyAction-actionAlias-validation.xml)
+ * to return a List of ValidatorConfig encapsulating the validator information.
+ *
+ * @author Jason Carreira
+ * @author James House
+ * @author tm_jee ( tm_jee (at) yahoo.co.uk )
+ * @author Rob Harrop
+ * @author Rene Gielen
+ * @author Martin Gilday
+ *
+ * @see ValidatorConfig
+ */
+public class DefaultValidatorFileParser implements ValidatorFileParser {
+
+ private static Logger LOG = LoggerFactory.getLogger(DefaultValidatorFileParser.class);
+
+ static final String DEFAULT_MULTI_TEXTVALUE_SEPARATOR = " ";
+ static final String MULTI_TEXTVALUE_SEPARATOR_CONFIG_KEY = "xwork.validatorfileparser.multi_textvalue_separator";
+
+ private ObjectFactory objectFactory;
+ private String multiTextvalueSeparator=DEFAULT_MULTI_TEXTVALUE_SEPARATOR;
+
+ @Inject(value=MULTI_TEXTVALUE_SEPARATOR_CONFIG_KEY, required = false)
+ public void setMultiTextvalueSeparator(String type) {
+ multiTextvalueSeparator = type;
+ }
+
+ public String getMultiTextvalueSeparator() {
+ return multiTextvalueSeparator;
+ }
+
+ @Inject
+ public void setObjectFactory(ObjectFactory fac) {
+ this.objectFactory = fac;
+ }
+
+ public List<ValidatorConfig> parseActionValidatorConfigs(ValidatorFactory validatorFactory, InputStream is, final String resourceName) {
+ List<ValidatorConfig> validatorCfgs = new ArrayList<ValidatorConfig>();
+
+ InputSource in = new InputSource(is);
+ in.setSystemId(resourceName);
+
+ Map<String, String> dtdMappings = new HashMap<String, String>();
+ dtdMappings.put("-//Apache Struts//XWork Validator 1.0//EN", "xwork-validator-1.0.dtd");
+ dtdMappings.put("-//Apache Struts//XWork Validator 1.0.2//EN", "xwork-validator-1.0.2.dtd");
+ dtdMappings.put("-//Apache Struts//XWork Validator 1.0.3//EN", "xwork-validator-1.0.3.dtd");
+ dtdMappings.put("-//Apache Struts//XWork Validator Config 1.0//EN", "xwork-validator-config-1.0.dtd");
+
+ Document doc = DomHelper.parse(in, dtdMappings);
+
+ if (doc != null) {
+ NodeList fieldNodes = doc.getElementsByTagName("field");
+
+ // BUG: xw-305: Let validator be parsed first and hence added to
+ // the beginning of list and therefore evaluated first, so short-circuting
+ // it will not cause field-level validator to be kicked off.
+ {
+ NodeList validatorNodes = doc.getElementsByTagName("validator");
+ addValidatorConfigs(validatorFactory, validatorNodes, new HashMap<String, String>(), validatorCfgs);
+ }
+
+ for (int i = 0; i < fieldNodes.getLength(); i++) {
+ Element fieldElement = (Element) fieldNodes.item(i);
+ String fieldName = fieldElement.getAttribute("name");
+ Map<String, String> extraParams = new HashMap<String, String>();
+ extraParams.put("fieldName", fieldName);
+
+ NodeList validatorNodes = fieldElement.getElementsByTagName("field-validator");
+ addValidatorConfigs(validatorFactory, validatorNodes, extraParams, validatorCfgs);
+ }
+ }
+
+ return validatorCfgs;
+ }
+
+
+ public void parseValidatorDefinitions(Map<String, String> validators, InputStream is, String resourceName) {
+
+ InputSource in = new InputSource(is);
+ in.setSystemId(resourceName);
+
+ Map<String, String> dtdMappings = new HashMap<String, String>();
+ dtdMappings.put("-//Apache Struts//XWork Validator Config 1.0//EN", "xwork-validator-config-1.0.dtd");
+
+ Document doc = DomHelper.parse(in, dtdMappings);
+
+ if (doc != null) {
+ NodeList nodes = doc.getElementsByTagName("validator");
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Element validatorElement = (Element) nodes.item(i);
+ String name = validatorElement.getAttribute("name");
+ String className = validatorElement.getAttribute("class");
+
+ try {
+ // catch any problems here
+ objectFactory.buildValidator(className, new HashMap<String, String>(), null);
+ validators.put(name, className);
+ } catch (Exception e) {
+ throw new ConfigurationException("Unable to load validator class " + className, e, validatorElement);
+ }
+ }
+ }
+ }
+
+ /**
+ * Extract trimmed text value from the given DOM element, ignoring XML comments. Appends all CharacterData nodes
+ * and EntityReference nodes into a single String value, excluding Comment nodes.
+ * This method is based on a method originally found in DomUtils class of Springframework.
+ *
+ * @see org.w3c.dom.CharacterData
+ * @see org.w3c.dom.EntityReference
+ * @see org.w3c.dom.Comment
+ */
+ public String getTextValue(Element valueEle) {
+ StringBuilder value = new StringBuilder();
+ NodeList nl = valueEle.getChildNodes();
+ boolean firstCDataFound = false;
+ for (int i = 0; i < nl.getLength(); i++) {
+ Node item = nl.item(i);
+ if ((item instanceof CharacterData && !(item instanceof Comment)) || item instanceof EntityReference) {
+ final String nodeValue = item.getNodeValue();
+ if (nodeValue != null) {
+ if (firstCDataFound) {
+ value.append(getMultiTextvalueSeparator());
+ } else {
+ firstCDataFound = true;
+ }
+ value.append(nodeValue.trim());
+ }
+ }
+ }
+ return value.toString().trim();
+ }
+
+ private void addValidatorConfigs(ValidatorFactory factory, NodeList validatorNodes, Map<String, String> extraParams, List<ValidatorConfig> validatorCfgs) {
+ for (int j = 0; j < validatorNodes.getLength(); j++) {
+ Element validatorElement = (Element) validatorNodes.item(j);
+ String validatorType = validatorElement.getAttribute("type");
+ Map<String, String> params = new HashMap<String, String>(extraParams);
+
+ params.putAll(XmlHelper.getParams(validatorElement));
+
+ // ensure that the type is valid...
+ try {
+ factory.lookupRegisteredValidatorType(validatorType);
+ } catch (IllegalArgumentException ex) {
+ throw new ConfigurationException("Invalid validation type: " + validatorType, validatorElement);
+ }
+
+ ValidatorConfig.Builder vCfg = new ValidatorConfig.Builder(validatorType)
+ .addParams(params)
+ .location(DomHelper.getLocationObject(validatorElement))
+ .shortCircuit(Boolean.valueOf(validatorElement.getAttribute("short-circuit")).booleanValue());
+
+ NodeList messageNodes = validatorElement.getElementsByTagName("message");
+ Element messageElement = (Element) messageNodes.item(0);
+
+ final Node defaultMessageNode = messageElement.getFirstChild();
+ String defaultMessage = (defaultMessageNode == null) ? "" : defaultMessageNode.getNodeValue();
+ vCfg.defaultMessage(defaultMessage);
+
+ Map<String, String> messageParams = XmlHelper.getParams(messageElement);
+ String key = messageElement.getAttribute("key");
+
+
+ if ((key != null) && (key.trim().length() > 0)) {
+ vCfg.messageKey(key);
+
+ // Get the default message when pattern 2 is used. We are only interested in the
+ // i18n message parameters when an i18n message key is specified.
+ // pattern 1:
+ // <message key="someKey">Default message</message>
+ // pattern 2:
+ // <message key="someKey">
+ // <param name="1">'param1'</param>
+ // <param name="2">'param2'</param>
+ // <param name="defaultMessage>The Default Message</param>
+ // </message>
+
+ if (messageParams.containsKey("defaultMessage")) {
+ vCfg.defaultMessage(messageParams.get("defaultMessage").toString());
+ }
+
+ // Sort the message param. those with keys as '1', '2', '3' etc. (numeric values)
+ // are i18n message parameter, others are excluded.
+ TreeMap<Integer, String> sortedMessageParameters = new TreeMap<Integer, String>();
+ for (Map.Entry<String, String> messageParamEntry : messageParams.entrySet()) {
+
+ try {
+ int _order = Integer.parseInt(messageParamEntry.getKey());
+ sortedMessageParameters.put(Integer.valueOf(_order), messageParamEntry.getValue().toString());
+ }
+ catch (NumberFormatException e) {
+ // ignore if its not numeric.
+ }
+ }
+ vCfg.messageParams(sortedMessageParameters.values().toArray(new String[sortedMessageParameters.values().size()]));
+ } else {
+ if (messageParams != null && (messageParams.size() > 0)) {
+ // we are i18n message parameters defined but no i18n message,
+ // let's warn the user.
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("validator of type ["+validatorType+"] have i18n message parameters defined but no i18n message key, it's parameters will be ignored");
+ }
+ }
+ }
+
+ validatorCfgs.add(vCfg.build());
+ }
+ }
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/DelegatingValidatorContext.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/DelegatingValidatorContext.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/DelegatingValidatorContext.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/DelegatingValidatorContext.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,316 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.validator;
+
+import org.apache.struts2.xwork2.util.ValueStack;
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerFactory;
+import org.apache.struts2.xwork2.ActionContext;
+import org.apache.struts2.xwork2.CompositeTextProvider;
+import org.apache.struts2.xwork2.LocaleProvider;
+import org.apache.struts2.xwork2.TextProvider;
+import org.apache.struts2.xwork2.TextProviderFactory;
+import org.apache.struts2.xwork2.TextProviderSupport;
+import org.apache.struts2.xwork2.ValidationAware;
+
+import java.util.*;
+
+
+/**
+ * A default implementation of the {@link ValidatorContext} interface.
+ *
+ * @author Jason Carreira
+ * @author Rainer Hermanns
+ */
+public class DelegatingValidatorContext implements ValidatorContext {
+
+ private LocaleProvider localeProvider;
+ private TextProvider textProvider;
+ private ValidationAware validationAware;
+
+ /**
+ * Creates a new validation context given a ValidationAware object, and a text and locale provider. These objects
+ * are used internally to set errors and get and set error text.
+ */
+ public DelegatingValidatorContext(ValidationAware validationAware, TextProvider textProvider,
+ LocaleProvider localeProvider) {
+ this.textProvider = textProvider;
+ this.validationAware = validationAware;
+ this.localeProvider = localeProvider;
+ }
+
+ /**
+ * Creates a new validation context given an object - usually an Action. The internal objects
+ * (validation aware instance and a locale and text provider) are created based on the given action.
+ *
+ * @param object the object to use for validation (usually an Action).
+ */
+ public DelegatingValidatorContext(Object object) {
+ this.localeProvider = makeLocaleProvider(object);
+ this.validationAware = makeValidationAware(object);
+ this.textProvider = makeTextProvider(object, localeProvider);
+ }
+
+ /**
+ * Create a new validation context given a Class definition. The locale provider, text provider and
+ * the validation context are created based on the class.
+ *
+ * @param clazz the class to initialize the context with.
+ */
+ public DelegatingValidatorContext(Class clazz) {
+ localeProvider = new ActionContextLocaleProvider();
+ textProvider = new TextProviderFactory().createInstance(clazz, localeProvider);
+ validationAware = new LoggingValidationAware(clazz);
+ }
+
+ public void setActionErrors(Collection<String> errorMessages) {
+ validationAware.setActionErrors(errorMessages);
+ }
+
+ public Collection<String> getActionErrors() {
+ return validationAware.getActionErrors();
+ }
+
+ public void setActionMessages(Collection<String> messages) {
+ validationAware.setActionMessages(messages);
+ }
+
+ public Collection<String> getActionMessages() {
+ return validationAware.getActionMessages();
+ }
+
+ public void setFieldErrors(Map<String, List<String>> errorMap) {
+ validationAware.setFieldErrors(errorMap);
+ }
+
+ public Map<String, List<String>> getFieldErrors() {
+ return validationAware.getFieldErrors();
+ }
+
+ public String getFullFieldName(String fieldName) {
+ return fieldName;
+ }
+
+ public Locale getLocale() {
+ return localeProvider.getLocale();
+ }
+
+ public boolean hasKey(String key) {
+ return textProvider.hasKey(key);
+ }
+
+ public String getText(String aTextName) {
+ return textProvider.getText(aTextName);
+ }
+
+ public String getText(String aTextName, String defaultValue) {
+ return textProvider.getText(aTextName, defaultValue);
+ }
+
+ public String getText(String aTextName, String defaultValue, String obj) {
+ return textProvider.getText(aTextName, defaultValue, obj);
+ }
+
+ public String getText(String aTextName, List<?> args) {
+ return textProvider.getText(aTextName, args);
+ }
+
+ public String getText(String key, String[] args) {
+ return textProvider.getText(key, args);
+ }
+
+ public String getText(String aTextName, String defaultValue, List<?> args) {
+ return textProvider.getText(aTextName, defaultValue, args);
+ }
+
+ public String getText(String key, String defaultValue, String[] args) {
+ return textProvider.getText(key, defaultValue, args);
+ }
+
+ public ResourceBundle getTexts(String aBundleName) {
+ return textProvider.getTexts(aBundleName);
+ }
+
+ public String getText(String key, String defaultValue, List<?> args, ValueStack stack) {
+ return textProvider.getText(key, defaultValue, args, stack);
+ }
+
+ public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
+ return textProvider.getText(key, defaultValue, args, stack);
+ }
+
+ public ResourceBundle getTexts() {
+ return textProvider.getTexts();
+ }
+
+ public void addActionError(String anErrorMessage) {
+ validationAware.addActionError(anErrorMessage);
+ }
+
+ public void addActionMessage(String aMessage) {
+ validationAware.addActionMessage(aMessage);
+ }
+
+ public void addFieldError(String fieldName, String errorMessage) {
+ validationAware.addFieldError(fieldName, errorMessage);
+ }
+
+ public boolean hasActionErrors() {
+ return validationAware.hasActionErrors();
+ }
+
+ public boolean hasActionMessages() {
+ return validationAware.hasActionMessages();
+ }
+
+ public boolean hasErrors() {
+ return validationAware.hasErrors();
+ }
+
+ public boolean hasFieldErrors() {
+ return validationAware.hasFieldErrors();
+ }
+
+ public static TextProvider makeTextProvider(Object object, LocaleProvider localeProvider) {
+ // the object argument passed through here will most probably be an ActionSupport decendant which does
+ // implements TextProvider.
+ if ((object != null) && (object instanceof TextProvider)) {
+ return new CompositeTextProvider(new TextProvider[]{
+ ((TextProvider) object),
+ new TextProviderSupport(object.getClass(), localeProvider)
+ });
+ } else {
+ return new TextProviderFactory().createInstance(object.getClass(), localeProvider);
+ }
+ }
+
+ protected static LocaleProvider makeLocaleProvider(Object object) {
+ if (object instanceof LocaleProvider) {
+ return (LocaleProvider) object;
+ } else {
+ return new ActionContextLocaleProvider();
+ }
+ }
+
+ protected static ValidationAware makeValidationAware(Object object) {
+ if (object instanceof ValidationAware) {
+ return (ValidationAware) object;
+ } else {
+ return new LoggingValidationAware(object);
+ }
+ }
+
+ protected void setTextProvider(TextProvider textProvider) {
+ this.textProvider = textProvider;
+ }
+
+ protected TextProvider getTextProvider() {
+ return textProvider;
+ }
+
+ protected void setValidationAware(ValidationAware validationAware) {
+ this.validationAware = validationAware;
+ }
+
+ protected ValidationAware getValidationAware() {
+ return validationAware;
+ }
+
+ /**
+ * An implementation of LocaleProvider which gets the locale from the action context.
+ */
+ private static class ActionContextLocaleProvider implements LocaleProvider {
+ public Locale getLocale() {
+ return ActionContext.getContext().getLocale();
+ }
+ }
+
+ /**
+ * An implementation of ValidationAware which logs errors and messages.
+ */
+ private static class LoggingValidationAware implements ValidationAware {
+
+ private Logger log;
+
+ public LoggingValidationAware(Class clazz) {
+ log = LoggerFactory.getLogger(clazz);
+ }
+
+ public LoggingValidationAware(Object obj) {
+ log = LoggerFactory.getLogger(obj.getClass());
+ }
+
+ public void setActionErrors(Collection<String> errorMessages) {
+ for (Object errorMessage : errorMessages) {
+ String s = (String) errorMessage;
+ addActionError(s);
+ }
+ }
+
+ public Collection<String> getActionErrors() {
+ return null;
+ }
+
+ public void setActionMessages(Collection<String> messages) {
+ for (Object message : messages) {
+ String s = (String) message;
+ addActionMessage(s);
+ }
+ }
+
+ public Collection<String> getActionMessages() {
+ return null;
+ }
+
+ public void setFieldErrors(Map<String, List<String>> errorMap) {
+ for (Map.Entry<String, List<String>> entry : errorMap.entrySet()) {
+ addFieldError(entry.getKey(), entry.getValue().toString());
+ }
+ }
+
+ public Map<String, List<String>> getFieldErrors() {
+ return null;
+ }
+
+ public void addActionError(String anErrorMessage) {
+ log.error("Validation error: " + anErrorMessage);
+ }
+
+ public void addActionMessage(String aMessage) {
+ log.info("Validation Message: " + aMessage);
+ }
+
+ public void addFieldError(String fieldName, String errorMessage) {
+ log.error("Validation error for " + fieldName + ":" + errorMessage);
+ }
+
+ public boolean hasActionErrors() {
+ return false;
+ }
+
+ public boolean hasActionMessages() {
+ return false;
+ }
+
+ public boolean hasErrors() {
+ return false;
+ }
+
+ public boolean hasFieldErrors() {
+ return false;
+ }
+ }
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/FieldValidator.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/FieldValidator.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/FieldValidator.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/FieldValidator.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2002-2007,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.validator;
+
+/**
+ * The FieldValidator interface defines the methods to be implemented by FieldValidators.
+ * Which are used by the XWork validation framework to validate Action properties before
+ * executing the Action.
+ */
+public interface FieldValidator extends Validator {
+
+ /**
+ * Sets the field name to validate with this FieldValidator
+ *
+ * @param fieldName the field name
+ */
+ void setFieldName(String fieldName);
+
+ /**
+ * Gets the field name to be validated
+ *
+ * @return the field name
+ */
+ String getFieldName();
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ShortCircuitableValidator.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ShortCircuitableValidator.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ShortCircuitableValidator.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ShortCircuitableValidator.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2002-2007,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.validator;
+
+
+/**
+ * This interface should be implemented by validators that can short-circuit the validator queue
+ * that it is in.
+ *
+ * @author Mark Woon
+ */
+public interface ShortCircuitableValidator {
+
+ /**
+ * Sets whether this field validator should short circuit the validator queue
+ * it's in if validation fails.
+ *
+ * @param shortcircuit <tt>true</tt> if this field validator should short circuit on
+ * failure, <tt>false</tt> otherwise
+ */
+ public void setShortCircuit(boolean shortcircuit);
+
+ /**
+ * Gets whether this field validator should short circuit the validator queue
+ * it's in if validation fails.
+ *
+ * @return <tt>true</tt> if this field validator should short circuit on failure,
+ * <tt>false</tt> otherwise
+ */
+ public boolean isShortCircuit();
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidationException.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidationException.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidationException.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidationException.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.validator;
+
+
+/**
+ * ValidationException.
+ *
+ * @author Jason Carreira
+ */
+public class ValidationException extends Exception {
+
+ /**
+ * Constructs an <code>Exception</code> with no specified detail message.
+ */
+ public ValidationException() {
+ }
+
+ /**
+ * Constructs an <code>Exception</code> with the specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public ValidationException(String s) {
+ super(s);
+ }
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidationInterceptor.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidationInterceptor.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidationInterceptor.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidationInterceptor.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2002-2007,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.validator;
+
+import org.apache.struts2.xwork2.ActionInvocation;
+import org.apache.struts2.xwork2.ActionProxy;
+import org.apache.struts2.xwork2.Validateable;
+import org.apache.struts2.xwork2.inject.Inject;
+import org.apache.struts2.xwork2.interceptor.MethodFilterInterceptor;
+import org.apache.struts2.xwork2.interceptor.PrefixMethodInvocationUtil;
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerFactory;
+
+/**
+ * <!-- START SNIPPET: description -->
+ *
+ * This interceptor runs the action through the standard validation framework, which in turn checks the action against
+ * any validation rules (found in files such as <i>ActionClass-validation.xml</i>) and adds field-level and action-level
+ * error messages (provided that the action implements {@link org.apache.struts2.xwork2.ValidationAware}). This interceptor
+ * is often one of the last (or second to last) interceptors applied in a stack, as it assumes that all values have
+ * already been set on the action.
+ *
+ * <p/>This interceptor does nothing if the name of the method being invoked is specified in the <b>excludeMethods</b>
+ * parameter. <b>excludeMethods</b> accepts a comma-delimited list of method names. For example, requests to
+ * <b>foo!input.action</b> and <b>foo!back.action</b> will be skipped by this interceptor if you set the
+ * <b>excludeMethods</b> parameter to "input, back".
+ *
+ * </ol>
+ *
+ * <p/> The workflow of the action request does not change due to this interceptor. Rather,
+ * this interceptor is often used in conjuction with the <b>workflow</b> interceptor.
+ *
+ * <p/>
+ *
+ * <b>NOTE:</b> As this method extends off MethodFilterInterceptor, it is capable of
+ * deciding if it is applicable only to selective methods in the action class. See
+ * <code>MethodFilterInterceptor</code> for more info.
+ *
+ * <!-- END SNIPPET: description -->
+ *
+ * <p/> <u>Interceptor parameters:</u>
+ *
+ * <!-- START SNIPPET: parameters -->
+ *
+ * <ul>
+ *
+ * <li>alwaysInvokeValidate - Defaults to true. If true validate() method will always
+ * be invoked, otherwise it will not.</li>
+ *
+ * <li>programmatic - Defaults to true. If true and the action is Validateable call validate(),
+ * and any method that starts with "validate".
+ * </li>
+ *
+ * <li>declarative - Defaults to true. Perform validation based on xml or annotations.</li>
+ *
+ * </ul>
+ *
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <p/> <u>Extending the interceptor:</u>
+ *
+ * <p/>
+ *
+ * <!-- START SNIPPET: extending -->
+ *
+ * There are no known extension points for this interceptor.
+ *
+ * <!-- END SNIPPET: extending -->
+ *
+ * <p/> <u>Example code:</u>
+ *
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ *
+ * <action name="someAction" class="com.examples.SomeAction">
+ * <interceptor-ref name="params"/>
+ * <interceptor-ref name="validation"/>
+ * <interceptor-ref name="workflow"/>
+ * <result name="success">good_result.ftl</result>
+ * </action>
+ *
+ * <-- in the following case myMethod of the action class will not
+ * get validated -->
+ * <action name="someAction" class="com.examples.SomeAction">
+ * <interceptor-ref name="params"/>
+ * <interceptor-ref name="validation">
+ * <param name="excludeMethods">myMethod</param>
+ * </interceptor-ref>
+ * <interceptor-ref name="workflow"/>
+ * <result name="success">good_result.ftl</result>
+ * </action>
+ *
+ * <-- in the following case only annotated methods of the action class will
+ * be validated -->
+ * <action name="someAction" class="com.examples.SomeAction">
+ * <interceptor-ref name="params"/>
+ * <interceptor-ref name="validation">
+ * <param name="validateAnnotatedMethodOnly">true</param>
+ * </interceptor-ref>
+ * <interceptor-ref name="workflow"/>
+ * <result name="success">good_result.ftl</result>
+ * </action>
+ *
+ *
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * @author Jason Carreira
+ * @author Rainer Hermanns
+ * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
+ * @see ActionValidatorManager
+ * @see org.apache.struts2.xwork2.interceptor.DefaultWorkflowInterceptor
+ */
+public class ValidationInterceptor extends MethodFilterInterceptor {
+
+ private boolean validateAnnotatedMethodOnly;
+
+ private ActionValidatorManager actionValidatorManager;
+
+ private static final Logger LOG = LoggerFactory.getLogger(ValidationInterceptor.class);
+
+ private final static String VALIDATE_PREFIX = "validate";
+ private final static String ALT_VALIDATE_PREFIX = "validateDo";
+
+ private boolean alwaysInvokeValidate = true;
+ private boolean programmatic = true;
+ private boolean declarative = true;
+
+ @Inject
+ public void setActionValidatorManager(ActionValidatorManager mgr) {
+ this.actionValidatorManager = mgr;
+ }
+
+ /**
+ * Determines if {@link org.apache.struts2.xwork2.Validateable}'s <code>validate()</code> should be called,
+ * as well as methods whose name that start with "validate". Defaults to "true".
+ *
+ * @param programmatic <tt>true</tt> then <code>validate()</code> is invoked.
+ */
+ public void setProgrammatic(boolean programmatic) {
+ this.programmatic = programmatic;
+ }
+
+ /**
+ * Determines if validation based on annotations or xml should be performed. Defaults
+ * to "true".
+ *
+ * @param declarative <tt>true</tt> then perform validation based on annotations or xml.
+ */
+ public void setDeclarative(boolean declarative) {
+ this.declarative = declarative;
+ }
+
+ /**
+ * Determines if {@link org.apache.struts2.xwork2.Validateable}'s <code>validate()</code> should always
+ * be invoked. Default to "true".
+ *
+ * @param alwaysInvokeValidate <tt>true</tt> then <code>validate()</code> is always invoked.
+ */
+ public void setAlwaysInvokeValidate(String alwaysInvokeValidate) {
+ this.alwaysInvokeValidate = Boolean.parseBoolean(alwaysInvokeValidate);
+ }
+
+ /**
+ * Gets if <code>validate()</code> should always be called or only per annotated method.
+ *
+ * @return <tt>true</tt> to only validate per annotated method, otherwise <tt>false</tt> to always validate.
+ */
+ public boolean isValidateAnnotatedMethodOnly() {
+ return validateAnnotatedMethodOnly;
+ }
+
+ /**
+ * Determine if <code>validate()</code> should always be called or only per annotated method.
+ * Default to <tt>false</tt>.
+ *
+ * @param validateAnnotatedMethodOnly <tt>true</tt> to only validate per annotated method, otherwise <tt>false</tt> to always validate.
+ */
+ public void setValidateAnnotatedMethodOnly(boolean validateAnnotatedMethodOnly) {
+ this.validateAnnotatedMethodOnly = validateAnnotatedMethodOnly;
+ }
+
+ /**
+ * Gets the current action and its context and delegates to {@link ActionValidatorManager} proper validate method.
+ *
+ * @param invocation the execution state of the Action.
+ * @throws Exception if an error occurs validating the action.
+ */
+ protected void doBeforeInvocation(ActionInvocation invocation) throws Exception {
+ Object action = invocation.getAction();
+ ActionProxy proxy = invocation.getProxy();
+
+ //the action name has to be from the url, otherwise validators that use aliases, like
+ //MyActio-someaction-validator.xml will not be found, see WW-3194
+ String context = proxy.getActionName();
+ String method = proxy.getMethod();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Validating "
+ + invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName() + " with method "+ method +".");
+ }
+
+
+ if (declarative) {
+ if (validateAnnotatedMethodOnly) {
+ actionValidatorManager.validate(action, context, method);
+ } else {
+ actionValidatorManager.validate(action, context);
+ }
+ }
+
+ if (action instanceof Validateable && programmatic) {
+ // keep exception that might occured in validateXXX or validateDoXXX
+ Exception exception = null;
+
+ Validateable validateable = (Validateable) action;
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Invoking validate() on action "+validateable);
+ }
+
+ try {
+ PrefixMethodInvocationUtil.invokePrefixMethod(
+ invocation,
+ new String[] { VALIDATE_PREFIX, ALT_VALIDATE_PREFIX });
+ }
+ catch(Exception e) {
+ // If any exception occurred while doing reflection, we want
+ // validate() to be executed
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("an exception occured while executing the prefix method", e);
+ }
+ exception = e;
+ }
+
+
+ if (alwaysInvokeValidate) {
+ validateable.validate();
+ }
+
+ if (exception != null) {
+ // rethrow if something is wrong while doing validateXXX / validateDoXXX
+ throw exception;
+ }
+ }
+ }
+
+ @Override
+ protected String doIntercept(ActionInvocation invocation) throws Exception {
+ doBeforeInvocation(invocation);
+
+ return invocation.invoke();
+ }
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/Validator.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/Validator.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/Validator.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/Validator.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,490 @@
+/*
+ * Copyright 2002-2007,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.validator;
+
+import org.apache.struts2.xwork2.util.ValueStack;
+
+
+/**
+ * <!-- START SNIPPET: validatorFlavours -->
+ * <p>The validators supplied by the XWork distribution (and any validators you
+ * might write yourself) come in two different flavors:</p>
+ * <p/>
+ * <ol>
+ * <li> Plain Validators / Non-Field validators </li>
+ * <li> FieldValidators </li>
+ * </ol>
+ * <p/>
+ * <p>Plain Validators (such as the ExpressionValidator) perform validation checks
+ * that are not inherently tied to a single specified field. When you declare a
+ * plain Validator in your -validation.xml file you do not associate a fieldname
+ * attribute with it. (You should avoid using plain Validators within the
+ * <field-validator> syntax described below.)</p>
+ * <p/>
+ * <p>FieldValidators (such as the EmailValidator) are designed to perform
+ * validation checks on a single field. They require that you specify a fieldname
+ * attribute in your -validation.xml file. There are two different (but equivalent)
+ * XML syntaxes you can use to declare FieldValidators (see "<validator> vs.
+ * <field-Validator> syntax" below).</p>
+ * <p/>
+ * <p>There are two places where the differences between the two validator flavors
+ * are important to keep in mind:</p>
+ * <p/>
+ * <ol>
+ * <li> when choosing the xml syntax used for declaring a validator
+ * (either <validator> or <field-validator>)</li>
+ * <li> when using the short-circuit capability</li>
+ * </ol>
+ * <p/>
+ * <p><b>NOTE:</b>Note that you do not declare what "flavor" of validator you are
+ * using in your -validation.xml file, you just declare the name of the validator
+ * to use and Struts will know whether it's a "plain Validator" or a "FieldValidator"
+ * by looking at the validation class that the validator's programmer chose
+ * to implement.</p>
+ * <!-- END SNIPPET: validatorFlavours -->
+ * <p/>
+ * <p/>
+ * <p/>
+ * <p/>
+ * <!-- START SNIPPET: validationRules -->
+ * <p>To define validation rules for an Action, create a file named ActionName-validation.xml
+ * in the same package as the Action. You may also create alias-specific validation rules which
+ * add to the default validation rules defined in ActionName-validation.xml by creating
+ * another file in the same directory named ActionName-aliasName-validation.xml. In both
+ * cases, ActionName is the name of the Action class, and aliasName is the name of the
+ * Action alias defined in the xwork.xml configuration for the Action.</p>
+ * <p/>
+ * <p>The framework will also search up the inheritance tree of the Action to
+ * find validation rules for directly implemented interfaces and parent classes of the Action.
+ * This is particularly powerful when combined with ModelDriven Actions and the VisitorFieldValidator.
+ * Here's an example of how validation rules are discovered. Given the following class structure:</p>
+ * <p/>
+ * <ul>
+ * <li>interface Animal;</li>
+ * <li>interface Quadraped extends Animal;</li>
+ * <li>class AnimalImpl implements Animal;</li>
+ * <li>class QuadrapedImpl extends AnimalImpl implements Quadraped;</li>
+ * <li>class Dog extends QuadrapedImpl;</li>
+ * </ul>
+ * <p/>
+ * <p>The framework method will look for the following config files if Dog is to be validated:</p>
+ * <p/>
+ * <ul>
+ * <li>Animal</li>
+ * <li>Animal-aliasname</li>
+ * <li>AnimalImpl</li>
+ * <li>AnimalImpl-aliasname</li>
+ * <li>Quadraped</li>
+ * <li>Quadraped-aliasname</li>
+ * <li>QuadrapedImpl</li>
+ * <li>QuadrapedImpl-aliasname</li>
+ * <li>Dog</li>
+ * <li>Dog-aliasname</li>
+ * </ul>
+ * <p/>
+ * <p>While this process is similar to what the XW:Localization framework does
+ * when finding messages, there are some subtle differences. The most important
+ * difference is that validation rules are discovered from the parent downwards.
+ * </p>
+ * <p/>
+ * <p><b>NOTE:</b>Child's *-validation.xml will add on to parent's *-validation.xml
+ * according to the class hierarchy defined above. With this feature, one could have
+ * more generic validation rule at the parent and more specific validation rule at
+ * the child.</p>
+ * <p/>
+ * <!-- END SNIPPET: validationRules -->
+ * <p/>
+ * <p/>
+ * <!-- START SNIPPET: validatorVsFieldValidators1 -->
+ * <p>There are two ways you can define validators in your -validation.xml file:</p>
+ * <ol>
+ * <li> <validator> </li>
+ * <li> <field-validator> </li>
+ * </ol>
+ * <p>Keep the following in mind when using either syntax:</p>
+ * <p/>
+ * <p><b>Non-Field-Validator</b>
+ * The <validator> element allows you to declare both types of validators
+ * (either a plain Validator a field-specific FieldValidator).</p>
+ * <!-- END SNIPPET: validatorVsFieldValidators1 -->
+ * <p/>
+ * <pre>
+ * <!-- START SNIPPET: nonFieldValidatorUsingValidatorSyntax -->
+ * <!-- Declaring a plain Validator using the <validator> syntax: -->
+ * <p/>
+ * <validator type="expression>
+ * <param name="expression">foo gt bar</param>
+ * <message>foo must be great than bar.</message>
+ * </validator>
+ * <!-- END SNIPPET: nonFieldValidatorUsingValidatorSyntax -->
+ * </pre>
+ * <p/>
+ * <pre>
+ * <!-- START SNIPPET: fieldValidatorUsingValidatorSyntax -->
+ * <!-- Declaring a field validator using the <validator> syntax; -->
+ * <p/>
+ * <validator type="required">
+ * <param name="fieldName">bar</param>
+ * <message>You must enter a value for bar.</message>
+ * </validator>
+ * <!-- END SNIPPET: fieldValidatorUsingValidatorSyntax -->
+ * </pre>
+ * <p/>
+ * <p/>
+ * <!-- START SNIPPET: validatorVsFieldValidators2 -->
+ * <p><b>field-validator</b>
+ * The <field-validator> elements are basically the same as the <validator> elements
+ * except that they inherit the fieldName attribute from the enclosing <field> element.
+ * FieldValidators defined within a <field-validator> element will have their fieldName
+ * automatically filled with the value of the parent <field> element's fieldName
+ * attribute. The reason for this structure is to conveniently group the validators
+ * for a particular field under one element, otherwise the fieldName attribute
+ * would have to be repeated, over and over, for each individual <validator>.</p>
+ * <p/>
+ * <p><b>HINT:</b>
+ * It is always better to defined field-validator inside a <field> tag instead of
+ * using a <validator> tag and supplying fieldName as its param as the xml code itself
+ * is clearer (grouping of field is clearer)</p>
+ * <p/>
+ * <p><b>NOTE:</b>
+ * Note that you should only use FieldValidators (not plain Validators) within a
+ * <field-validator> block. A plain Validator inside a <field> will not be
+ * allowed and would generate error when parsing the xml, as it is not allowed in
+ * the defined dtd (xwork-validator-1.0.2.dtd)</p>
+ * <!-- END SNIPPET: validatorVsFieldValidators2 -->
+ * <p/>
+ * <pre>
+ * <!-- START SNIPPET: fieldValidatorUsingFieldValidatorSyntax -->
+ * Declaring a FieldValidator using the <field-validator> syntax:
+ * <p/>
+ * <field name="email_address">
+ * <field-validator type="required">
+ * <message>You cannot leave the email address field empty.</message>
+ * </field-validator>
+ * <field-validator type="email">
+ * <message>The email address you entered is not valid.</message>
+ * </field-validator>
+ * </field>
+ * <!-- END SNIPPET: fieldValidatorUsingFieldValidatorSyntax -->
+ * </pre>
+ * <p/>
+ * <p/>
+ * <!-- START SNIPPET: validatorVsFieldValidators3 -->
+ * <p>The choice is yours. It's perfectly legal to only use <validator> elements
+ * without the <field> elements and set the fieldName attribute for each of them.
+ * The following are effectively equal:</P>
+ * <!-- END SNIPPET: validatorVsFieldValidators3 -->
+ * <p/>
+ * <pre>
+ * <!-- START SNIPPET: similarVaidatorDeclaredInDiffSyntax -->
+ * <field name="email_address">
+ * <field-validator type="required">
+ * <message>You cannot leave the email address field empty.</message>
+ * </field-validator>
+ * <field-validator type="email">
+ * <message>The email address you entered is not valid.</message>
+ * </field-validator>
+ * </field>
+ * <p/>
+ * <p/>
+ * <validator type="required">
+ * <param name="fieldName">email_address</param>
+ * <message>You cannot leave the email address field empty.</message>
+ * </validator>
+ * <validator type="email">
+ * <param name="fieldName">email_address</param>
+ * <message>The email address you entered is not valid.</message>
+ * </validator>
+ * <!-- END SNIPPET: similarVaidatorDeclaredInDiffSyntax -->
+ * </pre>
+ * <p/>
+ * <p/>
+ * <!-- START SNIPPET: shortCircuitingValidators1 -->
+ * <p>It is possible to short-circuit a stack of validators.
+ * Here is another sample config file containing validation rules from the
+ * Xwork test cases: Notice that some of the <field-validator> and
+ * <validator> elements have the short-circuit attribute set to true.</p>
+ * <!-- END SNIPPET : shortCircuitingValidators1 -->
+ * <p/>
+ * <pre>
+ * <!-- START SNIPPET: exShortCircuitingValidators -->
+ * <!DOCTYPE validators PUBLIC
+ * "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ * "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+ * <validators>
+ * <!-- Field Validators for email field -->
+ * <field name="email">
+ * <field-validator type="required" short-circuit="true">
+ * <message>You must enter a value for email.</message>
+ * </field-validator>
+ * <field-validator type="email" short-circuit="true">
+ * <message>Not a valid e-mail.</message>
+ * </field-validator>
+ * </field>
+ * <!-- Field Validators for email2 field -->
+ * <field name="email2">
+ * <field-validator type="required">
+ * <message>You must enter a value for email2.</message>
+ * </field-validator>
+ * <field-validator type="email">
+ * <message>Not a valid e-mail2.</message>
+ * </field-validator>
+ * </field>
+ * <!-- Plain Validator 1 -->
+ * <validator type="expression">
+ * <param name="expression">email.equals(email2)</param>
+ * <message>Email not the same as email2</message>
+ * </validator>
+ * <!-- Plain Validator 2 -->
+ * <validator type="expression" short-circuit="true">
+ * <param name="expression">email.startsWith('mark')</param>
+ * <message>Email does not start with mark</message>
+ * </validator>
+ * </validators>
+ * <!-- END SNIPPET: exShortCircuitingValidators -->
+ * </pre>
+ * <p/>
+ * <!-- START SNIPPET:shortCircuitingValidators2 -->
+ * <p><b>short-circuiting and Validator flavors</b></p>
+ * <p>Plain validator takes precedence over field-validator. They get validated
+ * first in the order they are defined and then the field-validator in the order
+ * they are defined. Failure of a particular validator marked as short-circuit
+ * will prevent the evaluation of subsequent validators and an error (action
+ * error or field error depending on the type of validator) will be added to
+ * the ValidationContext of the object being validated.</p>
+ * <p/>
+ * <p>In the example above, the actual execution of validator would be as follows:</p>
+ * <p/>
+ * <ol>
+ * <li> Plain Validator 1</li>
+ * <li> Plain Validator 2</li>
+ * <li> Field Validators for email field</li>
+ * <li> Field Validators for email2 field</li>
+ * </ol>
+ * <p/>
+ * <p>Since Plain Validator 2 is short-circuited, if its validation failed,
+ * it will causes Field validators for email field and Field validators for email2
+ * field to not be validated as well.</p>
+ * <p/>
+ * <p><b>Usefull Information:</b>
+ * More complicated validation should probably be done in the validate()
+ * method on the action itself (assuming the action implements Validatable
+ * interface which ActionSupport already does).</p>
+ * <p/>
+ * <p>
+ * A plain Validator (non FieldValidator) that gets short-circuited will
+ * completely break out of the validation stack. No other validators will be
+ * evaluated and plain validators takes precedence over field validators meaning
+ * that they get evaluated in the order they are defined before field validators
+ * get a chance to be evaluated.
+ * </p>
+ * <!-- END SNIPPET: shortCircuitingValidators2 -->
+ * <p/>
+ * <p/>
+ * <!-- START SNIPPET: scAndValidatorFlavours1 -->
+ * <p><b>Short cuircuiting and validator flavours</b></p>
+ * <p>A FieldValidator that gets short-circuited will only prevent other
+ * FieldValidators for the same field from being evaluated. Note that this
+ * "same field" behavior applies regardless of whether the <validator> or
+ * <field-validator> syntax was used to declare the validation rule.
+ * By way of example, given this -validation.xml file:</p>
+ * <!-- END SNIPPET: scAndValidatorFlavours1 -->
+ * <p/>
+ * <pre>
+ * <!-- START SNIPPET: exScAndValidatorFlavours -->
+ * <validator type="required" short-circuit="true">
+ * <param name="fieldName">bar</param>
+ * <message>You must enter a value for bar.</message>
+ * </validator>
+ * <p/>
+ * <validator type="expression">
+ * <param name="expression">foo gt bar</param>
+ * <message>foo must be great than bar.</message>
+ * </validator>
+ * <!-- END SNIPPET: exScAndValidatorFlavours -->
+ * </pre>
+ * <p/>
+ * <!-- START SNIPPET: scAndValidatorFlavours2 -->
+ * <p>both validators will be run, even if the "required" validator short-circuits.
+ * "required" validators are FieldValidator's and will not short-circuit the plain
+ * ExpressionValidator because FieldValidators only short-circuit other checks on
+ * that same field. Since the plain Validator is not field specific, it is
+ * not short-circuited.</p>
+ * <!-- END SNIPPET: scAndValidatorFlavours2 -->
+ * <p/>
+ * <p/>
+ * <!-- START SNIPPET: howXworkFindsValidatorForAction -->
+ * <p>As mentioned above, the framework will also search up the inheritance tree
+ * of the action to find default validations for interfaces and parent classes of
+ * the Action. If you are using the short-circuit attribute and relying on
+ * default validators higher up in the inheritance tree, make sure you don't
+ * accidentally short-circuit things higher in the tree that you really want!</p>
+ * <p>
+ * The effect of having common validators on both
+ * </p>
+ * <ul>
+ * <li><actionClass>-validation.xml</li>
+ * <li><actionClass>-<actionAlias>-validation.xml</li>
+ * </ul>
+ * <p>
+ * It should be noted that the nett effect will be validation on both the validators available
+ * in both validation configuration file. For example if we have 'requiredstring' validators defined
+ * in both validation xml file for field named 'address', we will see 2 validation error indicating that
+ * the the address cannot be empty (assuming validation failed). This is due to WebWork
+ * will merge validators found in both validation configuration files.
+ * </p>
+ * <p>
+ * The logic behind this design decision is such that we could have common validators in
+ * <actionClass>-validation.xml and more context specific validators to be located
+ * in <actionClass>-<actionAlias>-validation.xml
+ * </p>
+ * <!-- END SNIPPET: howXworkFindsValidatorForAction -->
+ *
+ * <p/>
+ * <!-- START SNIPPET: i18n -->
+ * Validator's validation messages could be internatinalized. For example,
+ * <pre>
+ * <field-validator type="required">
+ * <message key="required.field" />
+ * </field-validator>
+ * </pre>
+ * or
+ * <pre>
+ * <validator type="expression">
+ * <param name="expression">email.startsWith('Mark')</param>
+ * <message key="email.invalid" />
+ * </validator>
+ * </pre>
+ * In the first case, WebWork would look for i18n with key 'required.field' as the validation error message if
+ * validation fails, and 'email.invalid' in the second case.
+ * <p/>
+ * We could also provide a default message such that if validation failed and the i18n key for the message
+ * cannot be found, WebWork would fall back and use the default message. An example would be as follows :-
+ * <pre>
+ * <field-validator type="required">
+ * <message key="required.field">This field is required.</message>
+ * </field-validator>
+ * </pre>
+ * or
+ * <pre>
+ * <validator type="expression">
+ * <param name="expression">email.startsWith('Mark')</param>
+ * <message key="email.invalid">Email needs with starts with Mark</message>
+ * </validator>
+ * </pre>
+ *
+ *
+ * <!-- END SNIPPET: i18n -->
+ * @author Jason Carreira
+ */
+public interface Validator<T> {
+
+ /**
+ * Sets the default message to use for validation failure
+ *
+ * @param message the default message
+ */
+ void setDefaultMessage(String message);
+
+ /**
+ * Gets the default message used for validation failures
+ *
+ * @return the default message
+ */
+ String getDefaultMessage();
+
+ /**
+ * Gets the validation failure message for the given object
+ *
+ * @param object object being validated (eg. a domain model object)
+ * @return the validation failure message
+ */
+ String getMessage(Object object);
+
+ /**
+ * Sets a resource bundle key to be used for lookup of validation failure message
+ *
+ * @param key the resource bundle key
+ */
+ void setMessageKey(String key);
+
+ /**
+ * Gets the resource bundle key used for lookup of validation failure message
+ *
+ * @return the resource bundle key
+ */
+ String getMessageKey();
+
+ /**
+ * Sets the messsage parameters to be used when parsing i18n messages
+ *
+ * @param messageParameters the messsage parameters
+ */
+ void setMessageParameters(String[] messageParameters);
+
+ /**
+ * Gets the messsage parameters to be used when parsing i18n messages
+ *
+ * @return the messsage parameters
+ */
+ String[] getMessageParameters();
+
+ /**
+ * This method will be called before validate with a non-null ValidatorContext.
+ *
+ * @param validatorContext the validation context to use.
+ */
+ void setValidatorContext(ValidatorContext validatorContext);
+
+ /**
+ * Gets the validation context used
+ *
+ * @return the validation context
+ */
+ ValidatorContext getValidatorContext();
+
+ /**
+ * The validation implementation must guarantee that setValidatorContext will
+ * be called with a non-null ValidatorContext before validate is called.
+ *
+ * @param object the object to be validated.
+ * @throws ValidationException is thrown if there is validation error(s).
+ */
+ void validate(Object object) throws ValidationException;
+
+ /**
+ * Sets the validator type to use (see class javadoc).
+ *
+ * @param type the type to use.
+ */
+ void setValidatorType(String type);
+
+ /**
+ * Gets the vaildator type used (see class javadoc).
+ *
+ * @return the type used
+ */
+ String getValidatorType();
+
+ /**
+ * Sets the value stack to use to resolve values and parameters
+ *
+ * @param stack The value stack for the request
+ * @since 2.1.1
+ */
+ void setValueStack(ValueStack stack);
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorConfig.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorConfig.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorConfig.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorConfig.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.validator;
+
+import org.apache.struts2.xwork2.util.location.Located;
+import org.apache.struts2.xwork2.util.location.Location;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Holds the necessary information for configuring an instance of a Validator.
+ *
+ *
+ * @author James House
+ * @author Rainer Hermanns
+ * @author tm_jee
+ * @author Martin Gilday
+ */
+public class ValidatorConfig extends Located {
+
+ private String type;
+ private Map<String,String> params;
+ private String defaultMessage;
+ private String messageKey;
+ private boolean shortCircuit;
+ private String[] messageParams;
+
+ /**
+ * @param validatorType
+ */
+ protected ValidatorConfig(String validatorType) {
+ this.type = validatorType;
+ params = new LinkedHashMap<String, String>();
+ }
+
+ protected ValidatorConfig(ValidatorConfig orig) {
+ this.type = orig.type;
+ this.params = new LinkedHashMap<String,String>(orig.params);
+ this.defaultMessage = orig.defaultMessage;
+ this.messageKey = orig.messageKey;
+ this.shortCircuit = orig.shortCircuit;
+ this.messageParams = orig.messageParams;
+ }
+
+ /**
+ * @return Returns the defaultMessage for the validator.
+ */
+ public String getDefaultMessage() {
+ return defaultMessage;
+ }
+
+ /**
+ * @return Returns the messageKey for the validator.
+ */
+ public String getMessageKey() {
+ return messageKey;
+ }
+
+ /**
+ * @return Returns wether the shortCircuit flag should be set on the
+ * validator.
+ */
+ public boolean isShortCircuit() {
+ return shortCircuit;
+ }
+
+ /**
+ * @return Returns the configured params to set on the validator.
+ */
+ public Map<String, String> getParams() {
+ return params;
+ }
+
+ /**
+ * @return Returns the type of validator to configure.
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * @return The i18n message parameters/arguments to be used.
+ */
+ public String[] getMessageParams() {
+ return messageParams;
+ }
+
+ /**
+ * Builds a ValidatorConfig
+ */
+ public static final class Builder {
+ private ValidatorConfig target;
+
+ public Builder(String validatorType) {
+ target = new ValidatorConfig(validatorType);
+ }
+
+ public Builder(ValidatorConfig config) {
+ target = new ValidatorConfig(config);
+ }
+
+ public Builder shortCircuit(boolean shortCircuit) {
+ target.shortCircuit = shortCircuit;
+ return this;
+ }
+
+ public Builder defaultMessage(String msg) {
+ if ((msg != null) && (msg.trim().length() > 0)) {
+ target.defaultMessage = msg;
+ }
+ return this;
+ }
+
+ public Builder messageParams(String[] msgParams) {
+ target.messageParams = msgParams;
+ return this;
+ }
+
+ public Builder messageKey(String key) {
+ if ((key != null) && (key.trim().length() > 0)) {
+ target.messageKey = key;
+ }
+ return this;
+ }
+
+ public Builder addParam(String name, String value) {
+ if (value != null && name != null) {
+ target.params.put(name, value);
+ }
+ return this;
+ }
+
+ public Builder addParams(Map<String,String> params) {
+ target.params.putAll(params);
+ return this;
+ }
+
+ public Builder location(Location loc) {
+ target.location = loc;
+ return this;
+ }
+
+ public ValidatorConfig build() {
+ target.params = Collections.unmodifiableMap(target.params);
+ ValidatorConfig result = target;
+ target = new ValidatorConfig(target);
+ return result;
+ }
+
+ public Builder removeParam(String key) {
+ target.params.remove(key);
+ return this;
+ }
+ }
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorContext.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorContext.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorContext.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorContext.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.validator;
+
+import org.apache.struts2.xwork2.LocaleProvider;
+import org.apache.struts2.xwork2.TextProvider;
+import org.apache.struts2.xwork2.ValidationAware;
+
+
+/**
+ * The context for validation. This interface extends others to provide methods for reporting
+ * errors and messages as well as looking up error messages in a resource bundle using a specific locale.
+ *
+ * @author Jason Carreira
+ */
+public interface ValidatorContext extends ValidationAware, TextProvider, LocaleProvider {
+
+ /**
+ * Translates a simple field name into a full field name in OGNL syntax.
+ *
+ * @param fieldName the field name to lookup.
+ * @return the full field name in OGNL syntax.
+ */
+ String getFullFieldName(String fieldName);
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorFactory.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorFactory.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorFactory.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorFactory.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,239 @@
+package org.apache.struts2.xwork2.validator;
+
+/**
+ * ValidatorFactory
+ *
+ * <p>
+ * <!-- START SNIPPET: javadoc -->
+ * Validation rules are handled by validators, which must be registered with
+ * the ValidatorFactory (using the registerValidator method). The simplest way to do so is to add a file name
+ * validators.xml in the root of the classpath (/WEB-INF/classes) that declares
+ * all the validators you intend to use.
+ * <!-- END SNIPPET: javadoc -->
+ * </p>
+ *
+ *
+ * <p>
+ * <b>INFORMATION</b>
+ * <!-- START SNIPPET: information -->
+ * validators.xml if being defined should be available in the classpath. However
+ * this is not necessary, if no custom validator is needed. Predefined sets of validators
+ * will automatically be picked up when defined in
+ * org/apache/struts2/xwork2/validator/validators/default.xml packaged in
+ * in the xwork jar file. See ValidatorFactory static block for details.
+ * <!-- END SNIPPET: information -->
+ * </p>
+ *
+ * <p>
+ * <b>WARNING</b>
+ * <!-- START SNIPPET: warning -->
+ * If custom validator is being defined and a validators.xml is created and
+ * place in the classpath, do remember to copy all the other pre-defined validators
+ * that is needed into the validators.xml as if not they will not be registered.
+ * Once a validators.xml is detected in the classpath, the default one
+ * (org/apache/struts2/xwork2/validator/validators/default.xml) will not be loaded.
+ * It is only loaded when a custom validators.xml cannot be found in the classpath.
+ * Be careful.
+ * <!-- END SNIPPET: warning -->
+ * </p>
+ *
+ * <p><b>Note:</b>
+ * <!-- START SNIPPET: turningOnValidators -->
+ * The default validationWorkflowStack already includes this.<br/>
+ * All that is required to enable validation for an Action is to put the
+ * ValidationInterceptor in the interceptor refs of the action (see xwork.xml) like so:
+ * <!-- END SNIPPET: turningOnValidators -->
+ * </p>
+ *
+ * <pre>
+ * <!-- START SNIPPET: exTurnOnValidators -->
+ * <interceptor name="validator" class="org.apache.struts2.xwork2.validator.ValidationInterceptor"/>
+ * <!-- END SNIPPET: exTurnOnValidators -->
+ * </pre>
+ *
+ * <p><b>Field Validators</b>
+ * <!-- START SNIPPET: fieldValidators -->
+ * Field validators, as the name indicate, act on single fields accessible through an action.
+ * A validator, in contrast, is more generic and can do validations in the full action context,
+ * involving more than one field (or even no field at all) in validation rule.
+ * Most validations can be defined on per field basis. This should be preferred over
+ * non-field validation wherever possible, as field validator messages are bound to the
+ * related field and will be presented next to the corresponding input element in the
+ * respecting view.
+ * <!-- END SNIPPET: fieldValidators -->
+ * </p>
+ *
+ * <p><b>Non Field Validators</b>
+ * <!-- START SNIPPET: nonFieldValidators -->
+ * Non-field validators only add action level messages. Non-field validators
+ * are mostly domain specific and therefore offer custom implementations.
+ * The most important standard non-field validator provided by XWork
+ * is ExpressionValidator.
+ * <!-- END SNIPPET: nonFieldValidators -->
+ * </p>
+ *
+ * <p><b>NOTE:</b>
+ * <!-- START SNIPPET: validatorsNote -->
+ * Non-field validators takes precedence over field validators
+ * regardless of the order they are defined in *-validation.xml. If a non-field
+ * validator is short-circuited, it will causes its non-field validator to not
+ * being executed. See validation framework documentation for more info.
+ * <!-- END SNIPPET: validatorsNote -->
+ * </p>
+ *
+ * <p><b>VALIDATION RULES:</b>
+ * <!-- START SNIPPET: validationRules1 -->
+ * Validation rules can be specified:
+ * <ol>
+ * <li> Per Action class: in a file named ActionName-validation.xml</li>
+ * <li> Per Action alias: in a file named ActionName-alias-validation.xml</li>
+ * <li> Inheritance hierarchy and interfaces implemented by Action class:
+ * XWork searches up the inheritance tree of the action to find default
+ * validations for parent classes of the Action and interfaces implemented</li>
+ * </ol>
+ * Here is an example for SimpleAction-validation.xml:
+ * <!-- END SNIPPET: validationRules1 -->
+ * <p>
+ *
+ * <pre>
+ * <!-- START SNIPPET: exValidationRules1 -->
+ * <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ * "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+ * <validators>
+ * <field name="bar">
+ * <field-validator type="required">
+ * <message>You must enter a value for bar.</message>
+ * </field-validator>
+ * <field-validator type="int">
+ * <param name="min">6</param>
+ * <param name="max">10</param>
+ * <message>bar must be between ${min} and ${max}, current value is ${bar}.</message>
+ * </field-validator>
+ * </field>
+ * <field name="bar2">
+ * <field-validator type="regex">
+ * <param name="expression">[0-9],[0-9]</param>
+ * <message>The value of bar2 must be in the format "x, y", where x and y are between 0 and 9</message>
+ * </field-validator>
+ * </field>
+ * <field name="date">
+ * <field-validator type="date">
+ * <param name="min">12/22/2002</param>
+ * <param name="max">12/25/2002</param>
+ * <message>The date must be between 12-22-2002 and 12-25-2002.</message>
+ * </field-validator>
+ * </field>
+ * <field name="foo">
+ * <field-validator type="int">
+ * <param name="min">0</param>
+ * <param name="max">100</param>
+ * <message key="foo.range">Could not find foo.range!</message>
+ * </field-validator>
+ * </field>
+ * <validator type="expression">
+ * <param name="expression">foo lt bar </param>
+ * <message>Foo must be greater than Bar. Foo = ${foo}, Bar = ${bar}.</message>
+ * </validator>
+ * </validators>
+ * <!-- END SNIPPET: exValidationRules1 -->
+ * </pre>
+ *
+ *
+ * <p>
+ * <!-- START SNIPPET: validationRules2 -->
+ * Here we can see the configuration of validators for the SimpleAction class.
+ * Validators (and field-validators) must have a type attribute, which refers
+ * to a name of an Validator registered with the ValidatorFactory as above.
+ * Validator elements may also have <param> elements with name and value attributes
+ * to set arbitrary parameters into the Validator instance. See below for discussion
+ * of the message element.
+ * <!-- END SNIPPET: validationRules2 -->
+ * </p>
+ *
+ *
+ *
+ * <!-- START SNIPPET: validationRules3 -->
+ * <p>Each Validator or Field-Validator element must define one message element inside
+ * the validator element body. The message element has 1 attributes, key which is not
+ * required. The body of the message tag is taken as the default message which should
+ * be added to the Action if the validator fails. Key gives a message key to look up
+ * in the Action's ResourceBundles using getText() from LocaleAware if the Action
+ * implements that interface (as ActionSupport does). This provides for Localized
+ * messages based on the Locale of the user making the request (or whatever Locale
+ * you've set into the LocaleAware Action). After either retrieving the message from
+ * the ResourceBundle using the Key value, or using the Default message, the current
+ * Validator is pushed onto the ValueStack, then the message is parsed for \$\{...\}
+ * sections which are replaced with the evaluated value of the string between the
+ * \$\{ and \}. This allows you to parameterize your messages with values from the
+ * Validator, the Action, or both.</p>
+ *
+ *
+ * <p>If the validator fails, the validator is pushed onto the ValueStack and the
+ * message - either the default or the locale-specific one if the key attribute is
+ * defined (and such a message exists) - is parsed for ${...} sections which are
+ * replaced with the evaluated value of the string between the ${ and }. This
+ * allows you to parameterize your messages with values from the validator, the
+ * Action, or both. </p>
+ *
+ * <p><b>NOTE:</b> Since validation rules are in an XML file, you must make sure
+ * you escape special characters. For example, notice that in the expression
+ * validator rule above we use "&gt;" instead of ">". Consult a resource on XML
+ * for the full list of characters that must be escaped. The most commonly used
+ * characters that must be escaped are: & (use &amp;), > (user &gt;), and < (use &lt;).</p>
+ *
+ * <p>Here is an example of a parameterized message:</p>
+ * <p>This will pull the min and max parameters from the IntRangeFieldValidator and
+ * the value of bar from the Action.</p>
+ * <!-- END SNIPPET: validationRules3 -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: exValidationRules3 -->
+ * bar must be between ${min} and ${max}, current value is ${bar}.
+ * <!-- END SNIPPET: exValidationRules3 -->
+ * </pre>
+ *
+ * <!-- START SNIPPET: validationRules4 -->
+ * <p>Another notable fact is that the provided message value is capable of containing OGNL expressions.
+ * Keeping this in mind, it is possible to construct quite sophisticated messages.</p>
+ * <p>See the following example to get an impression:</p>
+ *
+ * <!-- END SNIPPET: validationRules4 -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: exValidationRules4 -->
+ * <message>${getText("validation.failednotice")}! ${getText("reason")}: ${getText("validation.inputrequired")}</message>
+ * <!-- END SNIPPET: exValidationRules4 -->
+ * </pre>
+ *
+ * @version $Date: 2011-12-02 12:24:48 +0100 (Fri, 02 Dec 2011) $ $Id: ValidatorFactory.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+ * @author Jason Carreira
+ * @author James House
+ */
+public interface ValidatorFactory {
+
+ /**
+ * Get a Validator that matches the given configuration.
+ *
+ * @param cfg the configurator.
+ * @return the validator.
+ */
+ Validator getValidator(ValidatorConfig cfg);
+
+ /**
+ * Registers the given validator to the existing map of validators.
+ * This will <b>add</b> to the existing list.
+ *
+ * @param name name of validator to add.
+ * @param className the FQ classname of the validator.
+ */
+ void registerValidator(String name, String className);
+
+ /**
+ * Lookup to get the FQ classname of the given validator name.
+ *
+ * @param name name of validator to lookup.
+ * @return the found FQ classname
+ * @throws IllegalArgumentException is thrown if the name is not found.
+ */
+ String lookupRegisteredValidatorType(String name);
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorFileParser.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorFileParser.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorFileParser.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/validator/ValidatorFileParser.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,46 @@
+package org.apache.struts2.xwork2.validator;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class serves 2 purpose :
+ * <ul>
+ * <li>
+ * Parse the validation config file. (eg. MyAction-validation.xml, MyAction-actionAlias-validation.xml)
+ * to return a List of ValidatorConfig encapsulating the validator information.
+ * </li>
+ * <li>
+ * Parse the validator definition file, (eg. validators.xml) that defines the {@link Validator}s
+ * registered with XWork.
+ * </li>
+ * </ul>
+ *
+ * @author Jason Carreira
+ * @author James House
+ * @author tm_jee ( tm_jee (at) yahoo.co.uk )
+ * @author Rob Harrop
+ * @author Rene Gielen
+ *
+ * @see ValidatorConfig
+ */
+public interface ValidatorFileParser {
+ /**
+ * Parse resource for a list of ValidatorConfig objects (configuring which validator(s) are
+ * being applied to a particular field etc.)
+ *
+ * @param is input stream to the resource
+ * @param resourceName file name of the resource
+ * @return List list of ValidatorConfig
+ */
+ List<ValidatorConfig> parseActionValidatorConfigs(ValidatorFactory validatorFactory, InputStream is, String resourceName);
+
+ /**
+ * Parses validator definitions (register various validators with XWork).
+ *
+ * @param is The input stream
+ * @param resourceName The location of the input stream
+ */
+ void parseValidatorDefinitions(Map<String,String> validators, InputStream is, String resourceName);
+}