This is an automated email from the ASF dual-hosted git repository.

sebb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-validator.git


The following commit(s) were added to refs/heads/master by this push:
     new 44522d2  VALIDATOR-473 User specified DomainValidator
44522d2 is described below

commit 44522d25d578e74175e0908dc6e75e387a631a38
Author: Sebb <s...@apache.org>
AuthorDate: Tue Jul 28 21:07:58 2020 +0100

    VALIDATOR-473 User specified DomainValidator
---
 src/changes/changes.xml                            |  3 ++
 .../commons/validator/routines/EmailValidator.java | 34 +++++++++++++-----
 .../commons/validator/routines/UrlValidator.java   | 40 ++++++++++++++++++++--
 .../validator/routines/EmailValidatorTest.java     | 27 +++++++++++++++
 .../validator/routines/UrlValidatorTest.java       | 20 +++++++++++
 5 files changed, 114 insertions(+), 10 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 4b413bb..7458a04 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -99,6 +99,9 @@ Apache Commons Validator.
 For the current list of dependencies, please see
 http://commons.apache.org/validator/dependencies.html
   ">
+    <action issue="VALIDATOR-473" type="add" dev="sebb">
+    Allow Email- and UrlValidator to use specified DomainValidator
+    </action>
     <action issue="VALIDATOR-403" type="fix" dev="sebb" due-to="Tanya">
     Accept Discover cards of 17 digits long that start with 6011
     </action>
diff --git 
a/src/main/java/org/apache/commons/validator/routines/EmailValidator.java 
b/src/main/java/org/apache/commons/validator/routines/EmailValidator.java
index 51337d9..6279ae2 100644
--- a/src/main/java/org/apache/commons/validator/routines/EmailValidator.java
+++ b/src/main/java/org/apache/commons/validator/routines/EmailValidator.java
@@ -52,7 +52,6 @@ public class EmailValidator implements Serializable {
 
     private static final int MAX_USERNAME_LEN = 64;
 
-    private final boolean allowLocal;
     private final boolean allowTld;
 
     /**
@@ -80,6 +79,8 @@ public class EmailValidator implements Serializable {
      */
     private static final EmailValidator EMAIL_VALIDATOR_WITH_LOCAL_WITH_TLD = 
new EmailValidator(true, true);
 
+    private final DomainValidator domainValidator;
+
     /**
      * Returns the Singleton instance of this validator.
      *
@@ -125,15 +126,36 @@ public class EmailValidator implements Serializable {
     }
 
     /**
+     * constructor for creating instances with the specified domainValidator
+     *
+     * @param allowLocal Should local addresses be considered valid?
+     * @param allowTld Should TLDs be allowed?
+     * @param domainValidator allow override of the DomainValidator.
+     * The instance must have the same allowLocal setting.
+     * @since 1.7
+     */
+    public EmailValidator(boolean allowLocal, boolean allowTld, 
DomainValidator domainValidator) {
+        super();
+        this.allowTld = allowTld;
+        if (domainValidator == null) {
+            throw new IllegalArgumentException("DomainValidator cannot be 
null");
+        } else {
+            if (domainValidator.isAllowLocal() != allowLocal) {
+                throw new IllegalArgumentException("DomainValidator must agree 
with allowLocal setting");
+            }
+            this.domainValidator = domainValidator;
+        }
+    }
+
+    /**
      * Protected constructor for subclasses to use.
      *
      * @param allowLocal Should local addresses be considered valid?
      * @param allowTld Should TLDs be allowed?
      */
     protected EmailValidator(boolean allowLocal, boolean allowTld) {
-        super();
-        this.allowLocal = allowLocal;
         this.allowTld = allowTld;
+        this.domainValidator = DomainValidator.getInstance(allowLocal);
     }
 
     /**
@@ -142,9 +164,7 @@ public class EmailValidator implements Serializable {
      * @param allowLocal Should local addresses be considered valid?
      */
     protected EmailValidator(boolean allowLocal) {
-        super();
-        this.allowLocal = allowLocal;
-        this.allowTld = false;
+        this(allowLocal, false);
     }
 
     /**
@@ -196,8 +216,6 @@ public class EmailValidator implements Serializable {
             return inetAddressValidator.isValid(ipDomainMatcher.group(1));
         }
         // Domain is symbolic name
-        DomainValidator domainValidator =
-                DomainValidator.getInstance(allowLocal);
         if (allowTld) {
             return domainValidator.isValid(domain) || (!domain.startsWith(".") 
&& domainValidator.isValidTld(domain));
         } else {
diff --git 
a/src/main/java/org/apache/commons/validator/routines/UrlValidator.java 
b/src/main/java/org/apache/commons/validator/routines/UrlValidator.java
index 11e69b9..74b0d30 100644
--- a/src/main/java/org/apache/commons/validator/routines/UrlValidator.java
+++ b/src/main/java/org/apache/commons/validator/routines/UrlValidator.java
@@ -182,6 +182,8 @@ public class UrlValidator implements Serializable {
         return DEFAULT_URL_VALIDATOR;
     }
 
+    private final DomainValidator domainValidator;
+
     /**
      * Create a UrlValidator with default properties.
      */
@@ -245,7 +247,29 @@ public class UrlValidator implements Serializable {
      * enables both of those options.
      */
     public UrlValidator(String[] schemes, RegexValidator authorityValidator, 
long options) {
+        this(schemes, authorityValidator, options, 
DomainValidator.getInstance(isOn(ALLOW_LOCAL_URLS, options)));
+    }
+
+    /**
+     * Customizable constructor. Validation behavior is modifed by passing in 
options.
+     * @param schemes the set of valid schemes. Ignored if the 
ALLOW_ALL_SCHEMES option is set.
+     * @param authorityValidator Regular expression validator used to validate 
the authority part
+     * @param options Validation options. Set using the public constants of 
this class.
+     * To set multiple options, simply add them together:
+     * <p><code>ALLOW_2_SLASHES + NO_FRAGMENTS</code></p>
+     * enables both of those options.
+     * @param domainValidator the DomainValidator to use; must agree with 
ALLOW_LOCAL_URLS setting
+     * @since 1.7
+     */
+    public UrlValidator(String[] schemes, RegexValidator authorityValidator, 
long options, DomainValidator domainValidator) {
         this.options = options;
+        if (domainValidator == null) {
+            throw new IllegalArgumentException("DomainValidator must not be 
null");
+        }
+        if (domainValidator.isAllowLocal() != ((options & ALLOW_LOCAL_URLS) > 
0)){
+            throw new IllegalArgumentException("DomainValidator disagrees with 
ALLOW_LOCAL_URLS setting");
+        }
+        this.domainValidator = domainValidator;
 
         if (isOn(ALLOW_ALL_SCHEMES)) {
             allowedSchemes = Collections.emptySet();
@@ -380,8 +404,7 @@ public class UrlValidator implements Serializable {
             String hostLocation = 
authorityMatcher.group(PARSE_AUTHORITY_HOST_IP);
             // check if authority is hostname or IP address:
             // try a hostname first since that's much more likely
-            DomainValidator domainValidator = 
DomainValidator.getInstance(isOn(ALLOW_LOCAL_URLS));
-            if (!domainValidator.isValid(hostLocation)) {
+            if (!this.domainValidator.isValid(hostLocation)) {
                 // try an IPv4 address
                 InetAddressValidator inetAddressValidator = 
InetAddressValidator.getInstance();
                 if (!inetAddressValidator.isValidInet4Address(hostLocation)) {
@@ -502,6 +525,19 @@ public class UrlValidator implements Serializable {
     }
 
     /**
+     * Tests whether the given flag is on.  If the flag is not a power of 2
+     * (e.g. 3) this tests whether the combination of flags is on.
+     *
+     * @param flag Flag value to check.
+     * @param options what to check
+     *
+     * @return whether the specified flag value is on.
+     */
+    private static boolean isOn(long flag, long options) {
+        return (options & flag) > 0;
+    }
+
+    /**
      * Tests whether the given flag is off.  If the flag is not a power of 2
      * (ie. 3) this tests whether the combination of flags is off.
      *
diff --git 
a/src/test/java/org/apache/commons/validator/routines/EmailValidatorTest.java 
b/src/test/java/org/apache/commons/validator/routines/EmailValidatorTest.java
index fe9ddff..4f0d28e 100644
--- 
a/src/test/java/org/apache/commons/validator/routines/EmailValidatorTest.java
+++ 
b/src/test/java/org/apache/commons/validator/routines/EmailValidatorTest.java
@@ -565,4 +565,31 @@ public class EmailValidatorTest {
     public void testValidator374() {
         assertTrue(validator.isValid("abc@school.school"));
     }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testValidator473_1() { // reject null DomainValidator
+        new EmailValidator(false, false, null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testValidator473_2() { // reject null DomainValidator with 
mismatched allowLocal
+        List<DomainValidator.Item> items = new ArrayList<>();
+        new EmailValidator(false, false, DomainValidator.getInstance(true, 
items));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testValidator473_3() { // reject null DomainValidator with 
mismatched allowLocal
+        List<DomainValidator.Item> items = new ArrayList<>();
+        new EmailValidator(true, false, DomainValidator.getInstance(false, 
items));
+    }
+
+    @Test
+    public void testValidator473_4() { // Show that can override domain 
validation
+        assertFalse(validator.isValidDomain("test.local"));
+        List<DomainValidator.Item> items = new ArrayList<>();
+        items.add(new 
DomainValidator.Item(DomainValidator.ArrayType.GENERIC_PLUS, new 
String[]{"local"}));
+        EmailValidator val = new EmailValidator(true, false, 
DomainValidator.getInstance(true, items));
+        assertTrue(val.isValidDomain("test.local"));
+    }
+
 }
diff --git 
a/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java 
b/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java
index 3f9d4ef..a436698 100644
--- a/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java
+++ b/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java
@@ -18,6 +18,9 @@ package org.apache.commons.validator.routines;
 
 import static org.junit.Assert.*;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.commons.validator.ResultPair;
 import org.junit.Before;
 import org.junit.Test;
@@ -358,6 +361,23 @@ public class UrlValidatorTest {
       
assertTrue(urlValidator.isValid("http://[::FFFF:129.144.52.38]:80/index.html";));
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void testValidator473_1() { // reject null DomainValidator
+        new UrlValidator(new String[]{}, null, 0L, null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testValidator473_2() { // reject null DomainValidator with 
mismatched allowLocal
+        List<DomainValidator.Item> items = new ArrayList<>();
+        new UrlValidator(new String[]{}, null, 0L, 
DomainValidator.getInstance(true, items));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testValidator473_3() { // reject null DomainValidator with 
mismatched allowLocal
+        List<DomainValidator.Item> items = new ArrayList<>();
+        new UrlValidator(new String[]{}, null, UrlValidator.ALLOW_LOCAL_URLS, 
DomainValidator.getInstance(false, items));
+    }
+
     static boolean incrementTestPartsIndex(int[] testPartsIndex, Object[] 
testParts) {
       boolean carry = true;  //add 1 to lowest order part.
       boolean maxIndex = true;

Reply via email to