WW-4578 Converts URL validator to support collections
Project: http://git-wip-us.apache.org/repos/asf/struts/repo Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/6f272e48 Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/6f272e48 Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/6f272e48 Branch: refs/heads/master Commit: 6f272e4873bdba03c1b3fe3ac8c0670b680d2c6c Parents: 16e8f10 Author: Lukasz Lenart <lukaszlen...@apache.org> Authored: Fri Apr 14 11:16:59 2017 +0200 Committer: Lukasz Lenart <lukaszlen...@apache.org> Committed: Fri Apr 14 11:16:59 2017 +0200 ---------------------------------------------------------------------- .../validator/validators/URLValidator.java | 43 ++- .../xwork2/validator/URLValidatorTest.java | 347 +++++++++++-------- 2 files changed, 242 insertions(+), 148 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/struts/blob/6f272e48/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java index f12c286..d579e34 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java @@ -20,6 +20,8 @@ import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.Collection; +import java.util.Objects; import java.util.regex.Pattern; /** @@ -65,19 +67,48 @@ public class URLValidator extends FieldValidatorSupport { private Pattern urlPattern = Pattern.compile(DEFAULT_URL_REGEX, Pattern.CASE_INSENSITIVE); public void validate(Object object) throws ValidationException { - String fieldName = getFieldName(); - Object value = this.getFieldValue(fieldName, object); + Object value = getFieldValue(fieldName, object); // if there is no value - don't do comparison // if a value is required, a required validator should be added to the field - if (value == null || value.toString().length() == 0) { + String stringValue = Objects.toString(value, "").trim(); + if (stringValue.length() == 0) { + LOG.debug("Value for field {} is empty, won't ba validated, please use required validator", fieldName); return; } - String stringValue = String.valueOf(value).trim(); + if (value.getClass().isArray()) { + Object[] values = (Object[]) value; + for (Object objValue : values) { + LOG.debug("Validating element of array: {}", objValue); + validateValue(object, objValue); + } + } else if (Collection.class.isAssignableFrom(value.getClass())) { + Collection values = (Collection) value; + for (Object objValue : values) { + LOG.debug("Validating element of collection: {}", objValue); + validateValue(object, objValue); + } + } else { + LOG.debug("Validating field: {}", value); + validateValue(object, value); + } + } - if (!(value.getClass().equals(String.class)) || !getUrlPattern().matcher(stringValue).matches()) { - addFieldError(fieldName, object); + protected void validateValue(Object object, Object value) { + String stringValue = Objects.toString(value, "").trim(); + if (stringValue.length() == 0) { + LOG.debug("Value for field {} is empty, won't ba validated, please use required validator", fieldName); + return; + } + + try { + setCurrentValue(value); + if (!(value.getClass().equals(String.class)) || !getUrlPattern().matcher(stringValue).matches()) { + addFieldError(fieldName, object); + } + } finally { + setCurrentValue(null); } } http://git-wip-us.apache.org/repos/asf/struts/blob/6f272e48/core/src/test/java/com/opensymphony/xwork2/validator/URLValidatorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/URLValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/URLValidatorTest.java index b961d78..5c83dd1 100644 --- a/core/src/test/java/com/opensymphony/xwork2/validator/URLValidatorTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/validator/URLValidatorTest.java @@ -22,96 +22,98 @@ import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.validator.validators.URLValidator; import org.apache.commons.validator.routines.UrlValidator; +import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; /** * Test case for URLValidator - * + * * @author tm_jee * @version $Date$ $Id$ */ public class URLValidatorTest extends XWorkTestCase { - - ValueStack stack; - ActionContext actionContext; - private TextProviderFactory tpf; - public void testAcceptNullValueForMutualExclusionOfValidators() throws Exception { - - URLValidator validator = new URLValidator(); - validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); - validator.setFieldName("testingUrl1"); + ValueStack stack; + ActionContext actionContext; + private TextProviderFactory tpf; + + public void testAcceptNullValueForMutualExclusionOfValidators() throws Exception { + + URLValidator validator = new URLValidator(); + validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); + validator.setFieldName("testingUrl1"); validator.setValueStack(ActionContext.getContext().getValueStack()); validator.validate(new MyObject()); - - assertFalse(validator.getValidatorContext().hasErrors()); - assertFalse(validator.getValidatorContext().hasActionErrors()); - assertFalse(validator.getValidatorContext().hasActionMessages()); - assertFalse(validator.getValidatorContext().hasFieldErrors()); - } - - public void testInvalidEmptyValue() throws Exception { - - URLValidator validator = new URLValidator(); - validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); - validator.setFieldName("testingUrl2"); + + assertFalse(validator.getValidatorContext().hasErrors()); + assertFalse(validator.getValidatorContext().hasActionErrors()); + assertFalse(validator.getValidatorContext().hasActionMessages()); + assertFalse(validator.getValidatorContext().hasFieldErrors()); + } + + public void testInvalidEmptyValue() throws Exception { + + URLValidator validator = new URLValidator(); + validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); + validator.setFieldName("testingUrl2"); validator.setValueStack(ActionContext.getContext().getValueStack()); validator.validate(new MyObject()); - - assertFalse(validator.getValidatorContext().hasErrors()); - assertFalse(validator.getValidatorContext().hasActionErrors()); - assertFalse(validator.getValidatorContext().hasActionMessages()); - assertFalse(validator.getValidatorContext().hasFieldErrors()); - } - - public void testInvalidValue() throws Exception { - - URLValidator validator = new URLValidator(); - validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); - validator.setFieldName("testingUrl3"); + + assertFalse(validator.getValidatorContext().hasErrors()); + assertFalse(validator.getValidatorContext().hasActionErrors()); + assertFalse(validator.getValidatorContext().hasActionMessages()); + assertFalse(validator.getValidatorContext().hasFieldErrors()); + } + + public void testInvalidValue() throws Exception { + + URLValidator validator = new URLValidator(); + validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); + validator.setFieldName("testingUrl3"); validator.setValueStack(ActionContext.getContext().getValueStack()); validator.validate(new MyObject()); - - assertTrue(validator.getValidatorContext().hasErrors()); - assertFalse(validator.getValidatorContext().hasActionErrors()); - assertFalse(validator.getValidatorContext().hasActionMessages()); - assertTrue(validator.getValidatorContext().hasFieldErrors()); - } - - - public void testValidUrl1() throws Exception { - - URLValidator validator = new URLValidator(); - validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); - validator.setFieldName("testingUrl4"); + + assertTrue(validator.getValidatorContext().hasErrors()); + assertFalse(validator.getValidatorContext().hasActionErrors()); + assertFalse(validator.getValidatorContext().hasActionMessages()); + assertTrue(validator.getValidatorContext().hasFieldErrors()); + } + + + public void testValidUrl1() throws Exception { + + URLValidator validator = new URLValidator(); + validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); + validator.setFieldName("testingUrl4"); validator.setValueStack(ActionContext.getContext().getValueStack()); validator.validate(new MyObject()); - - assertFalse(validator.getValidatorContext().hasErrors()); - assertFalse(validator.getValidatorContext().hasActionErrors()); - assertFalse(validator.getValidatorContext().hasActionMessages()); - assertFalse(validator.getValidatorContext().hasFieldErrors()); - } - - public void testValidUrl2() throws Exception { - - URLValidator validator = new URLValidator(); - validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); - validator.setFieldName("testingUrl5"); + + assertFalse(validator.getValidatorContext().hasErrors()); + assertFalse(validator.getValidatorContext().hasActionErrors()); + assertFalse(validator.getValidatorContext().hasActionMessages()); + assertFalse(validator.getValidatorContext().hasFieldErrors()); + } + + public void testValidUrl2() throws Exception { + + URLValidator validator = new URLValidator(); + validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); + validator.setFieldName("testingUrl5"); validator.setValueStack(ActionContext.getContext().getValueStack()); validator.validate(new MyObject()); - - assertFalse(validator.getValidatorContext().hasErrors()); - assertFalse(validator.getValidatorContext().hasActionErrors()); - assertFalse(validator.getValidatorContext().hasActionMessages()); - assertFalse(validator.getValidatorContext().hasFieldErrors()); - } - - public void testValidUrlWithRegex() throws Exception { - URLValidator validator = new URLValidator(); + + assertFalse(validator.getValidatorContext().hasErrors()); + assertFalse(validator.getValidatorContext().hasActionErrors()); + assertFalse(validator.getValidatorContext().hasActionMessages()); + assertFalse(validator.getValidatorContext().hasFieldErrors()); + } + + public void testValidUrlWithRegex() throws Exception { + URLValidator validator = new URLValidator(); validator.setUrlRegex("^myapp:\\/\\/[a-z]*\\.com$"); @@ -119,10 +121,10 @@ public class URLValidatorTest extends XWorkTestCase { assertTrue(pattern.matcher("myapp://test.com").matches()); assertFalse(pattern.matcher("myap://test.com").matches()); - } + } - public void testValidUrlWithRegexExpression() throws Exception { - URLValidator validator = new URLValidator(); + public void testValidUrlWithRegexExpression() throws Exception { + URLValidator validator = new URLValidator(); ActionContext.getContext().getValueStack().push(new MyAction()); validator.setValueStack(ActionContext.getContext().getValueStack()); validator.setUrlRegexExpression("${urlRegex}"); @@ -131,10 +133,10 @@ public class URLValidatorTest extends XWorkTestCase { assertTrue(pattern.matcher("myapp://test.com").matches()); assertFalse(pattern.matcher("myap://test.com").matches()); - } + } - public void testValidUrlWithDefaultRegex() throws Exception { - URLValidator validator = new URLValidator(); + public void testValidUrlWithDefaultRegex() throws Exception { + URLValidator validator = new URLValidator(); Pattern pattern = Pattern.compile(validator.getUrlRegex(), Pattern.CASE_INSENSITIVE); @@ -143,7 +145,7 @@ public class URLValidatorTest extends XWorkTestCase { assertFalse(pattern.matcher("").matches()); assertFalse(pattern.matcher(" ").matches()); assertFalse(pattern.matcher("no url").matches()); - assertFalse(pattern.matcher("http://example.com////////////////////////////////////////////////////////////////////////////////////??").matches()); + assertFalse(pattern.matcher("http://example.com////////////////////////////////////////////////////////////////////////////////////??").matches()); assertTrue(pattern.matcher("http://www.opensymphony.com").matches()); assertTrue(pattern.matcher("https://www.opensymphony.com").matches()); @@ -153,91 +155,152 @@ public class URLValidatorTest extends XWorkTestCase { assertTrue(pattern.matcher("http://www.legalspace.com/__media__/js/netsoltrademark.php?d=www.a-vos-travaux.fr%2Facheter-un-aspirateur-sans-sac-pas-cher%2F").matches()); assertTrue(UrlValidator.getInstance().isValid("http://www.legalspace.com/__media__/js/netsoltrademark.php?d=www.a-vos-travaux.fr%2Facheter-un-aspirateur-sans-sac-pas-cher%2F")); - assertTrue(pattern.matcher("http://www.duadmin.isaev.Infoduadmin.Isaev.info/?a%5B%5D=%3Ca%20href%3Dhttp%3A%2F%2Fwww.aspert.fr%2Fun-seche-cheveux-lisseur-est-il-vraiment-utile%2F%3Eseche%20cheveux%20dyson%20test%3C%2Fa").matches()); - assertTrue(UrlValidator.getInstance().isValid("http://www.duadmin.isaev.Infoduadmin.Isaev.info/?a%5B%5D=%3Ca%20href%3Dhttp%3A%2F%2Fwww.aspert.fr%2Fun-seche-cheveux-lisseur-est-il-vraiment-utile%2F%3Eseche%20cheveux%20dyson%20test%3C%2Fa")); + assertTrue(pattern.matcher("http://www.duadmin.isaev.Infoduadmin.Isaev.info/?a%5B%5D=%3Ca%20href%3Dhttp%3A%2F%2Fwww.aspert.fr%2Fun-seche-cheveux-lisseur-est-il-vraiment-utile%2F%3Eseche%20cheveux%20dyson%20test%3C%2Fa").matches()); + assertTrue(UrlValidator.getInstance().isValid("http://www.duadmin.isaev.Infoduadmin.Isaev.info/?a%5B%5D=%3Ca%20href%3Dhttp%3A%2F%2Fwww.aspert.fr%2Fun-seche-cheveux-lisseur-est-il-vraiment-utile%2F%3Eseche%20cheveux%20dyson%20test%3C%2Fa")); - assertTrue(pattern.matcher("http://netsol-underconstruction-page-monitor-1.com/__media__/js/netsoltrademark.php?d=www.le-soutien-scolaire.fr%2Favis-et-test-comparatifs-des-robots-multifonctions%2F").matches()); - assertTrue(UrlValidator.getInstance().isValid("http://netsol-underconstruction-page-monitor-1.com/__media__/js/netsoltrademark.php?d=www.le-soutien-scolaire.fr%2Favis-et-test-comparatifs-des-robots-multifonctions%2F")); - } + assertTrue(pattern.matcher("http://netsol-underconstruction-page-monitor-1.com/__media__/js/netsoltrademark.php?d=www.le-soutien-scolaire.fr%2Favis-et-test-comparatifs-des-robots-multifonctions%2F").matches()); + assertTrue(UrlValidator.getInstance().isValid("http://netsol-underconstruction-page-monitor-1.com/__media__/js/netsoltrademark.php?d=www.le-soutien-scolaire.fr%2Favis-et-test-comparatifs-des-robots-multifonctions%2F")); + } - public void testValidUrlCaseInsensitive() throws Exception { - // given - final Map<String, Object> fieldErrors = new HashMap<>(); + public void testValidUrlCaseInsensitive() throws Exception { + // given + final Map<String, Object> fieldErrors = new HashMap<>(); - URLValidator validator = new URLValidator() { - @Override - public String getFieldName() { - return "url"; - } + URLValidator validator = new URLValidator() { + @Override + public String getFieldName() { + return "url"; + } - @Override - protected Object getFieldValue(String name, Object object) throws ValidationException { - return object; - } + @Override + protected Object getFieldValue(String name, Object object) throws ValidationException { + return object; + } - @Override - protected void addFieldError(String propertyName, Object object) { - fieldErrors.put(propertyName, object); - } - }; + @Override + protected void addFieldError(String propertyName, Object object) { + fieldErrors.put(propertyName, object); + } + }; - // when + // when validator.validate("http://localhost:8080/myapp"); - // then - assertTrue(fieldErrors.isEmpty()); + // then + assertTrue(fieldErrors.isEmpty()); - // when + // when validator.validate("http://LOCALHOST:8080/MYAPP"); - // then - assertTrue(fieldErrors.isEmpty()); + // then + assertTrue(fieldErrors.isEmpty()); - // when + // when validator.validate("http://www.appache.org/TEST"); - // then - assertTrue(fieldErrors.isEmpty()); + // then + assertTrue(fieldErrors.isEmpty()); + } + + public void testArrayOfUrls() throws Exception { + URLValidator validator = new URLValidator(); + validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); + validator.setFieldName("urls"); + validator.setValueStack(ActionContext.getContext().getValueStack()); + validator.validate(new MyObject()); + + assertTrue(validator.getValidatorContext().hasErrors()); + assertFalse(validator.getValidatorContext().hasActionErrors()); + assertFalse(validator.getValidatorContext().hasActionMessages()); + assertTrue(validator.getValidatorContext().hasFieldErrors()); + assertEquals(1, validator.getValidatorContext().getFieldErrors().get("urls").size()); } - @Override + public void testCollectionOfUrls() throws Exception { + URLValidator validator = new URLValidator(); + validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); + validator.setFieldName("urlCollection"); + validator.setValueStack(ActionContext.getContext().getValueStack()); + validator.setDefaultMessage("Wrong URL provided: ${currentValue}"); + validator.validate(new MyObject()); + + assertTrue(validator.getValidatorContext().hasErrors()); + assertFalse(validator.getValidatorContext().hasActionErrors()); + assertFalse(validator.getValidatorContext().hasActionMessages()); + assertTrue(validator.getValidatorContext().hasFieldErrors()); + assertEquals(1, validator.getValidatorContext().getFieldErrors().get("urlCollection").size()); + assertEquals("Wrong URL provided: htps://wrong.side.com", validator.getValidatorContext().getFieldErrors().get("urlCollection").get(0)); + } + + public void testCollectionOfUrlsSafness() throws Exception { + URLValidator validator = new URLValidator(); + validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf)); + validator.setFieldName("urlSafeness"); + validator.setValueStack(ActionContext.getContext().getValueStack()); + validator.setDefaultMessage("Wrong URL provided: ${currentValue}"); + validator.validate(new MyObject()); + + assertTrue(validator.getValidatorContext().hasErrors()); + assertFalse(validator.getValidatorContext().hasActionErrors()); + assertFalse(validator.getValidatorContext().hasActionMessages()); + assertTrue(validator.getValidatorContext().hasFieldErrors()); + assertEquals(2, validator.getValidatorContext().getFieldErrors().get("urlSafeness").size()); + assertEquals("Wrong URL provided: ${1+2}", validator.getValidatorContext().getFieldErrors().get("urlSafeness").get(0)); + assertEquals("Wrong URL provided: %{2+3}", validator.getValidatorContext().getFieldErrors().get("urlSafeness").get(1)); + } + + @Override protected void setUp() throws Exception { - super.setUp(); - stack = ActionContext.getContext().getValueStack(); - actionContext = ActionContext.getContext(); - tpf = container.getInstance(TextProviderFactory.class); - } - - @Override + super.setUp(); + stack = ActionContext.getContext().getValueStack(); + actionContext = ActionContext.getContext(); + tpf = container.getInstance(TextProviderFactory.class); + } + + @Override protected void tearDown() throws Exception { - super.tearDown(); - stack = null; - actionContext = null; - } - - - class MyObject { - public String getTestingUrl1() { - return null; - } - - public String getTestingUrl2() { - return ""; - } - - public String getTestingUrl3() { - return "sasdasd@asddd"; - } - - public String getTestingUrl4() { - //return "http://yahoo.com/"; - return "http://www.jroller.com1?qwe=qwe"; - } - - public String getTestingUrl5() { - return "http://yahoo.com/articles?id=123\n"; - } - } + super.tearDown(); + stack = null; + actionContext = null; + } + + + class MyObject { + public String getTestingUrl1() { + return null; + } + + public String getTestingUrl2() { + return ""; + } + + public String getTestingUrl3() { + return "sasdasd@asddd"; + } + + public String getTestingUrl4() { + //return "http://yahoo.com/"; + return "http://www.jroller.com1?qwe=qwe"; + } + + public String getTestingUrl5() { + return "http://yahoo.com/articles?id=123\n"; + } + + public String[] getUrls() { + return new String[]{ + "https://struts.apache.org", + "htps://wrong.side.com" + }; + } + + public Collection<String> getUrlCollection() { + return Arrays.asList("https://struts.apache.org","htps://wrong.side.com"); + } + public Collection<String> getUrlSafeness() { + return Arrays.asList("https://struts.apache.org","${1+2}", "%{2+3}"); + } + } class MyAction {