garydgregory commented on code in PR #216:
URL: https://github.com/apache/commons-validator/pull/216#discussion_r1590324152


##########
src/main/java/org/apache/commons/validator/routines/checkdigit/CASNumberCheckDigit.java:
##########
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.apache.commons.validator.routines.CodeValidator;
+
+/**
+ * Modulus 10 <b>CAS Registry Number</b> (or <b>Chemical Abstracts Service</b> 
(CAS RN)) Check Digit
+ * calculation/validation.
+ *
+ * <p>
+ * CAS Numbers are unique identification numbers used
+ * to identify chemical substance described in the open scientific literature.
+ * </p>
+ *
+ * <p>
+ * Check digit calculation is based on <i>modulus 10</i> with digits being 
weighted
+ * based on their position (from right to left).
+ * </p>
+ *
+ * <p>
+ * The check digit is found by taking the last digit times 1, the preceding 
digit times 2,
+ * the preceding digit times 3 etc., adding all these up and computing the sum 
modulo 10.
+ * For example, the CAS number of water is <code>7732-18-5</code>:
+ * the checksum 5 is calculated as (8×1 + 1×2 + 2×3 + 3×4 + 7×5 + 7×6) = 105; 
105 mod 10 = 5.
+ * </p>
+ *
+ * <p>
+ * For further information see
+ *  <a href="https://en.wikipedia.org/wiki/CAS_Registry_Number";>Wikipedia - 
CAS Registry Number</a>.
+ * </p>
+ *
+ * @since 1.9.0
+ */
+public final class CASNumberCheckDigit extends ModulusCheckDigit {
+
+    private static final long serialVersionUID = -5387334603220786657L;
+
+    /** Singleton Check Digit instance */
+    private static final CheckDigit INSTANCE = new CASNumberCheckDigit();
+
+    /**
+     * Gets the singleton instance of this validator.
+     * @return A singleton instance of the CAS Number validator.
+     */
+    public static CheckDigit getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * CAS number consists of 3 groups of numbers separated dashes (-).
+     * First group up to 7 digits.
+     * Example: water is 7732-18-5
+     */
+    private static final String GROUP1 = "(\\d{1,7})";
+    private static final String DASH = "(?:\\-)";
+    static final String CAS_REGEX = "^(?:" + GROUP1 + DASH + "(\\d{2})" + DASH 
+ "(\\d))$";
+
+    private static final int CAS_MIN_LEN = 4; // 9-99-9 LEN without SEP
+    /** maximum capacity of 1,000,000,000 == 9999999-99-9*/
+    private static final int CAS_MAX_LEN = 10;
+    static final CodeValidator REGEX_VALIDATOR = new CodeValidator(CAS_REGEX, 
CAS_MIN_LEN, CAS_MAX_LEN, null);
+
+    /** Weighting given to digits depending on their right position */
+    private static final int[] POSITION_WEIGHT = { 0,1,2,3,4,5,6,7,8,9 };
+
+    /**
+     * Constructs a modulus 10 Check Digit routine for CAS Numbers.
+     */
+    private CASNumberCheckDigit() {
+    }
+
+    /**
+     * Calculates the <i>weighted</i> value of a character in the code at a 
specified position.
+     * <p>
+     * CAS numbers are weighted in the following manner:
+     * <pre><code>
+     *    right position: 1  2  3  4  5  6  7  8  9 10
+     *            weight: 1  2  3  4  5  6  7  8  9  0
+     * </code></pre>
+     *
+     * @param charValue The numeric value of the character.
+     * @param leftPos The position of the character in the code, counting from 
left to right
+     * @param rightPos The positionof the character in the code, counting from 
right to left
+     * @return The weighted value of the character.
+     */
+    @Override
+    protected int weightedValue(final int charValue, final int leftPos, final 
int rightPos) {
+        final int weight = POSITION_WEIGHT[(rightPos - 1) % MODULUS_10];
+        return charValue * weight;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String calculate(final String code) throws CheckDigitException {
+        if (code == null || code.isEmpty()) {
+            throw new CheckDigitException("Code is missing");
+        }
+        int modulusResult = calculateModulus(code, false);

Review Comment:
   Inline single-use instance variable.



##########
src/test/java/org/apache/commons/validator/routines/checkdigit/CASNumberCheckDigitTest.java:
##########
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.junit.jupiter.api.BeforeEach;
+
+/**
+ * CAS Number Check Digit Tests.
+ */
+public class CASNumberCheckDigitTest extends AbstractCheckDigitTest {
+
+    private static final String WATER = "7732-18-5";
+    private static final String ETHANOL = "64-17-5";
+    private static final String ASPIRIN = "50-78-2";
+    private static final String COFFEIN = "58-08-2";
+    private static final String FORMALDEHYDE = "50-00-0";
+    private static final String DEXAMETHASONE = "50-02-2";
+    private static final String ARSENIC = "7440-38-2";
+    private static final String ASBESTOS = "1332-21-4";
+    
+    /**
+     * Sets up routine & valid codes.
+     */
+    @BeforeEach
+    protected void setUp() {
+        routine = CASNumberCheckDigit.getInstance();
+        valid = new String[] {WATER, ETHANOL, ASPIRIN, COFFEIN, FORMALDEHYDE, 
DEXAMETHASONE, ARSENIC, ASBESTOS };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String removeCheckDigit(final String code) {
+       String cde = (String)CASNumberCheckDigit.REGEX_VALIDATOR.validate(code);

Review Comment:
   Whitespace after type cast.



##########
src/test/java/org/apache/commons/validator/routines/checkdigit/CASNumberCheckDigitTest.java:
##########
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.junit.jupiter.api.BeforeEach;
+
+/**
+ * CAS Number Check Digit Tests.
+ */
+public class CASNumberCheckDigitTest extends AbstractCheckDigitTest {
+
+    private static final String WATER = "7732-18-5";
+    private static final String ETHANOL = "64-17-5";
+    private static final String ASPIRIN = "50-78-2";
+    private static final String COFFEIN = "58-08-2";
+    private static final String FORMALDEHYDE = "50-00-0";
+    private static final String DEXAMETHASONE = "50-02-2";
+    private static final String ARSENIC = "7440-38-2";
+    private static final String ASBESTOS = "1332-21-4";
+    
+    /**
+     * Sets up routine & valid codes.
+     */
+    @BeforeEach
+    protected void setUp() {
+        routine = CASNumberCheckDigit.getInstance();
+        valid = new String[] {WATER, ETHANOL, ASPIRIN, COFFEIN, FORMALDEHYDE, 
DEXAMETHASONE, ARSENIC, ASBESTOS };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String removeCheckDigit(final String code) {
+       String cde = (String)CASNumberCheckDigit.REGEX_VALIDATOR.validate(code);
+       if(cde == null || cde.length() <= checkDigitLth) return null;

Review Comment:
   Always use a block:
   ```
   if (...) {
   ...
   }
   ```



##########
src/main/java/org/apache/commons/validator/routines/checkdigit/CASNumberCheckDigit.java:
##########
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.apache.commons.validator.routines.CodeValidator;
+
+/**
+ * Modulus 10 <b>CAS Registry Number</b> (or <b>Chemical Abstracts Service</b> 
(CAS RN)) Check Digit
+ * calculation/validation.
+ *
+ * <p>
+ * CAS Numbers are unique identification numbers used
+ * to identify chemical substance described in the open scientific literature.
+ * </p>
+ *
+ * <p>
+ * Check digit calculation is based on <i>modulus 10</i> with digits being 
weighted
+ * based on their position (from right to left).
+ * </p>
+ *
+ * <p>
+ * The check digit is found by taking the last digit times 1, the preceding 
digit times 2,
+ * the preceding digit times 3 etc., adding all these up and computing the sum 
modulo 10.
+ * For example, the CAS number of water is <code>7732-18-5</code>:
+ * the checksum 5 is calculated as (8×1 + 1×2 + 2×3 + 3×4 + 7×5 + 7×6) = 105; 
105 mod 10 = 5.
+ * </p>
+ *
+ * <p>
+ * For further information see
+ *  <a href="https://en.wikipedia.org/wiki/CAS_Registry_Number";>Wikipedia - 
CAS Registry Number</a>.
+ * </p>
+ *
+ * @since 1.9.0
+ */
+public final class CASNumberCheckDigit extends ModulusCheckDigit {
+
+    private static final long serialVersionUID = -5387334603220786657L;
+
+    /** Singleton Check Digit instance */
+    private static final CheckDigit INSTANCE = new CASNumberCheckDigit();
+
+    /**
+     * Gets the singleton instance of this validator.
+     * @return A singleton instance of the CAS Number validator.
+     */
+    public static CheckDigit getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * CAS number consists of 3 groups of numbers separated dashes (-).
+     * First group up to 7 digits.
+     * Example: water is 7732-18-5
+     */
+    private static final String GROUP1 = "(\\d{1,7})";
+    private static final String DASH = "(?:\\-)";
+    static final String CAS_REGEX = "^(?:" + GROUP1 + DASH + "(\\d{2})" + DASH 
+ "(\\d))$";
+
+    private static final int CAS_MIN_LEN = 4; // 9-99-9 LEN without SEP
+    /** maximum capacity of 1,000,000,000 == 9999999-99-9*/
+    private static final int CAS_MAX_LEN = 10;
+    static final CodeValidator REGEX_VALIDATOR = new CodeValidator(CAS_REGEX, 
CAS_MIN_LEN, CAS_MAX_LEN, null);
+
+    /** Weighting given to digits depending on their right position */
+    private static final int[] POSITION_WEIGHT = { 0,1,2,3,4,5,6,7,8,9 };
+
+    /**
+     * Constructs a modulus 10 Check Digit routine for CAS Numbers.
+     */
+    private CASNumberCheckDigit() {
+    }
+
+    /**
+     * Calculates the <i>weighted</i> value of a character in the code at a 
specified position.
+     * <p>
+     * CAS numbers are weighted in the following manner:
+     * <pre><code>
+     *    right position: 1  2  3  4  5  6  7  8  9 10
+     *            weight: 1  2  3  4  5  6  7  8  9  0
+     * </code></pre>
+     *
+     * @param charValue The numeric value of the character.
+     * @param leftPos The position of the character in the code, counting from 
left to right
+     * @param rightPos The positionof the character in the code, counting from 
right to left
+     * @return The weighted value of the character.
+     */
+    @Override
+    protected int weightedValue(final int charValue, final int leftPos, final 
int rightPos) {
+        final int weight = POSITION_WEIGHT[(rightPos - 1) % MODULUS_10];
+        return charValue * weight;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String calculate(final String code) throws CheckDigitException {
+        if (code == null || code.isEmpty()) {
+            throw new CheckDigitException("Code is missing");
+        }
+        int modulusResult = calculateModulus(code, false);
+        return toCheckDigit(modulusResult);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isValid(final String code) {
+        if (code == null || code.isEmpty()) {
+            return false;
+        }
+        Object cde = REGEX_VALIDATOR.validate(code);
+        if (cde instanceof String) {
+            try {
+                final int modulusResult = calculateModulus((String)cde, true);

Review Comment:
   `(String)cde` -> `(String) cde`
   Rebasing on git master (and running `mvn`) would have picked up this 
Checkstyle issue.



##########
src/main/java/org/apache/commons/validator/routines/checkdigit/CASNumberCheckDigit.java:
##########
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.apache.commons.validator.routines.CodeValidator;
+
+/**
+ * Modulus 10 <b>CAS Registry Number</b> (or <b>Chemical Abstracts Service</b> 
(CAS RN)) Check Digit
+ * calculation/validation.
+ *
+ * <p>
+ * CAS Numbers are unique identification numbers used
+ * to identify chemical substance described in the open scientific literature.
+ * </p>
+ *
+ * <p>
+ * Check digit calculation is based on <i>modulus 10</i> with digits being 
weighted
+ * based on their position (from right to left).
+ * </p>
+ *
+ * <p>
+ * The check digit is found by taking the last digit times 1, the preceding 
digit times 2,
+ * the preceding digit times 3 etc., adding all these up and computing the sum 
modulo 10.
+ * For example, the CAS number of water is <code>7732-18-5</code>:
+ * the checksum 5 is calculated as (8×1 + 1×2 + 2×3 + 3×4 + 7×5 + 7×6) = 105; 
105 mod 10 = 5.
+ * </p>
+ *
+ * <p>
+ * For further information see
+ *  <a href="https://en.wikipedia.org/wiki/CAS_Registry_Number";>Wikipedia - 
CAS Registry Number</a>.
+ * </p>
+ *
+ * @since 1.9.0
+ */
+public final class CASNumberCheckDigit extends ModulusCheckDigit {
+
+    private static final long serialVersionUID = -5387334603220786657L;
+
+    /** Singleton Check Digit instance */
+    private static final CheckDigit INSTANCE = new CASNumberCheckDigit();
+
+    /**
+     * Gets the singleton instance of this validator.
+     * @return A singleton instance of the CAS Number validator.
+     */
+    public static CheckDigit getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * CAS number consists of 3 groups of numbers separated dashes (-).
+     * First group up to 7 digits.
+     * Example: water is 7732-18-5
+     */
+    private static final String GROUP1 = "(\\d{1,7})";
+    private static final String DASH = "(?:\\-)";
+    static final String CAS_REGEX = "^(?:" + GROUP1 + DASH + "(\\d{2})" + DASH 
+ "(\\d))$";
+
+    private static final int CAS_MIN_LEN = 4; // 9-99-9 LEN without SEP
+    /** maximum capacity of 1,000,000,000 == 9999999-99-9*/
+    private static final int CAS_MAX_LEN = 10;
+    static final CodeValidator REGEX_VALIDATOR = new CodeValidator(CAS_REGEX, 
CAS_MIN_LEN, CAS_MAX_LEN, null);
+
+    /** Weighting given to digits depending on their right position */
+    private static final int[] POSITION_WEIGHT = { 0,1,2,3,4,5,6,7,8,9 };
+
+    /**
+     * Constructs a modulus 10 Check Digit routine for CAS Numbers.
+     */
+    private CASNumberCheckDigit() {
+    }
+
+    /**
+     * Calculates the <i>weighted</i> value of a character in the code at a 
specified position.
+     * <p>
+     * CAS numbers are weighted in the following manner:
+     * <pre><code>
+     *    right position: 1  2  3  4  5  6  7  8  9 10
+     *            weight: 1  2  3  4  5  6  7  8  9  0
+     * </code></pre>
+     *
+     * @param charValue The numeric value of the character.
+     * @param leftPos The position of the character in the code, counting from 
left to right
+     * @param rightPos The positionof the character in the code, counting from 
right to left
+     * @return The weighted value of the character.
+     */
+    @Override
+    protected int weightedValue(final int charValue, final int leftPos, final 
int rightPos) {
+        final int weight = POSITION_WEIGHT[(rightPos - 1) % MODULUS_10];
+        return charValue * weight;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String calculate(final String code) throws CheckDigitException {
+        if (code == null || code.isEmpty()) {

Review Comment:
   This patterns is duplicated in many places in this package. Please rebase on 
git master, and reuse `isEmpty(String)`.



##########
src/main/java/org/apache/commons/validator/routines/checkdigit/ECNumberCheckDigit.java:
##########
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.apache.commons.validator.routines.CodeValidator;
+
+/**
+ * Modulus 11 <b>EC number</b> Check Digit calculation/validation.
+ *
+ * <p>
+ * The European Community number (EC number) is a unique seven-digit identifier
+ * that is assigned to chemical substances.
+ * For example, the EC number of arsenic is 231-148-6:
+ * </p>
+ *
+ * <p>
+ * Check digit calculation is based on <i>modulus 11</i> with digits being 
weighted
+ * based on their position (from left to right).
+ * </p>
+ *
+ * <p>
+ * For further information see
+ *  <a 
href="https://en.wikipedia.org/wiki/European_Community_number";>Wikipedia - EC 
number</a>.
+ * </p>
+ *
+ * @since 1.9.0
+ */
+public final class ECNumberCheckDigit extends ModulusCheckDigit {
+
+    private static final long serialVersionUID = 7265356024784308367L;
+
+    /** Singleton Check Digit instance */
+    private static final CheckDigit INSTANCE = new ECNumberCheckDigit();
+
+    /**
+     * Gets the singleton instance of this validator.
+     * @return A singleton instance of the EC Number validator.
+     */
+    public static CheckDigit getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * EC number consists of 3 groups of numbers separated dashes (-).
+     * Example: dexamethasone is 200-003-9
+     */
+    private static final String GROUP = "(\\d{3})";
+    private static final String DASH = "(?:\\-)";
+    static final String EC_REGEX = "^(?:" + GROUP + DASH + GROUP + DASH + 
"(\\d))$";
+
+    private static final int EC_LEN = 7;
+    static final CodeValidator REGEX_VALIDATOR = new CodeValidator(EC_REGEX, 
EC_LEN, null);
+
+    /**
+     * Constructs a modulus 11 Check Digit routine.
+     */
+    private ECNumberCheckDigit() {
+        super(MODULUS_11);
+    }
+
+    /**
+     * Calculates the <i>weighted</i> value of a character in the
+     * code at a specified position.
+     *
+     * <p>For EC number digits are weighted by their position from left to 
right.</p>
+     *
+     * @param charValue The numeric value of the character.
+     * @param leftPos The position of the character in the code, counting from 
left to right
+     * @param rightPos The positionof the character in the code, counting from 
right to left
+     * @return The weighted value of the character.
+     */
+    @Override
+    protected int weightedValue(final int charValue, final int leftPos, final 
int rightPos) {
+        return leftPos >= EC_LEN ? 0 : charValue * leftPos;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String calculate(final String code) throws CheckDigitException {
+        if (code == null || code.isEmpty()) {

Review Comment:
   Reuse the new `isEmpty(String)`



##########
src/main/java/org/apache/commons/validator/routines/checkdigit/ECNumberCheckDigit.java:
##########
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.apache.commons.validator.routines.CodeValidator;
+
+/**
+ * Modulus 11 <b>EC number</b> Check Digit calculation/validation.
+ *
+ * <p>
+ * The European Community number (EC number) is a unique seven-digit identifier
+ * that is assigned to chemical substances.
+ * For example, the EC number of arsenic is 231-148-6:
+ * </p>
+ *
+ * <p>
+ * Check digit calculation is based on <i>modulus 11</i> with digits being 
weighted
+ * based on their position (from left to right).
+ * </p>
+ *
+ * <p>
+ * For further information see
+ *  <a 
href="https://en.wikipedia.org/wiki/European_Community_number";>Wikipedia - EC 
number</a>.
+ * </p>
+ *
+ * @since 1.9.0
+ */
+public final class ECNumberCheckDigit extends ModulusCheckDigit {
+
+    private static final long serialVersionUID = 7265356024784308367L;
+
+    /** Singleton Check Digit instance */
+    private static final CheckDigit INSTANCE = new ECNumberCheckDigit();
+
+    /**
+     * Gets the singleton instance of this validator.
+     * @return A singleton instance of the EC Number validator.
+     */
+    public static CheckDigit getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * EC number consists of 3 groups of numbers separated dashes (-).
+     * Example: dexamethasone is 200-003-9
+     */
+    private static final String GROUP = "(\\d{3})";
+    private static final String DASH = "(?:\\-)";
+    static final String EC_REGEX = "^(?:" + GROUP + DASH + GROUP + DASH + 
"(\\d))$";
+
+    private static final int EC_LEN = 7;
+    static final CodeValidator REGEX_VALIDATOR = new CodeValidator(EC_REGEX, 
EC_LEN, null);
+
+    /**
+     * Constructs a modulus 11 Check Digit routine.
+     */
+    private ECNumberCheckDigit() {
+        super(MODULUS_11);
+    }
+
+    /**
+     * Calculates the <i>weighted</i> value of a character in the
+     * code at a specified position.
+     *
+     * <p>For EC number digits are weighted by their position from left to 
right.</p>
+     *
+     * @param charValue The numeric value of the character.
+     * @param leftPos The position of the character in the code, counting from 
left to right
+     * @param rightPos The positionof the character in the code, counting from 
right to left
+     * @return The weighted value of the character.
+     */
+    @Override
+    protected int weightedValue(final int charValue, final int leftPos, final 
int rightPos) {
+        return leftPos >= EC_LEN ? 0 : charValue * leftPos;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String calculate(final String code) throws CheckDigitException {
+        if (code == null || code.isEmpty()) {
+            throw new CheckDigitException("Code is missing");
+        }
+        int modulusResult = calculateModulus(code, false);
+        return toCheckDigit(modulusResult);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isValid(final String code) {
+        if (code == null || code.isEmpty()) {
+            return false;
+        }
+        Object cde = REGEX_VALIDATOR.validate(code);
+        if (cde instanceof String) {
+            try {
+                final int modulusResult = calculateModulus((String)cde, true);

Review Comment:
   Whitespace after type cast.



##########
src/test/java/org/apache/commons/validator/routines/checkdigit/CASNumberCheckDigitTest.java:
##########
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.junit.jupiter.api.BeforeEach;
+
+/**
+ * CAS Number Check Digit Tests.
+ */
+public class CASNumberCheckDigitTest extends AbstractCheckDigitTest {
+
+    private static final String WATER = "7732-18-5";
+    private static final String ETHANOL = "64-17-5";
+    private static final String ASPIRIN = "50-78-2";
+    private static final String COFFEIN = "58-08-2";
+    private static final String FORMALDEHYDE = "50-00-0";
+    private static final String DEXAMETHASONE = "50-02-2";
+    private static final String ARSENIC = "7440-38-2";
+    private static final String ASBESTOS = "1332-21-4";
+    
+    /**
+     * Sets up routine & valid codes.
+     */
+    @BeforeEach
+    protected void setUp() {
+        routine = CASNumberCheckDigit.getInstance();
+        valid = new String[] {WATER, ETHANOL, ASPIRIN, COFFEIN, FORMALDEHYDE, 
DEXAMETHASONE, ARSENIC, ASBESTOS };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String removeCheckDigit(final String code) {
+       String cde = (String)CASNumberCheckDigit.REGEX_VALIDATOR.validate(code);
+       if(cde == null || cde.length() <= checkDigitLth) return null;

Review Comment:
   Whitespace after if: `if(` -> `if (`



##########
src/main/java/org/apache/commons/validator/routines/checkdigit/ECNumberCheckDigit.java:
##########
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.apache.commons.validator.routines.CodeValidator;
+
+/**
+ * Modulus 11 <b>EC number</b> Check Digit calculation/validation.
+ *
+ * <p>
+ * The European Community number (EC number) is a unique seven-digit identifier
+ * that is assigned to chemical substances.
+ * For example, the EC number of arsenic is 231-148-6:
+ * </p>
+ *
+ * <p>
+ * Check digit calculation is based on <i>modulus 11</i> with digits being 
weighted
+ * based on their position (from left to right).
+ * </p>
+ *
+ * <p>
+ * For further information see
+ *  <a 
href="https://en.wikipedia.org/wiki/European_Community_number";>Wikipedia - EC 
number</a>.
+ * </p>
+ *
+ * @since 1.9.0
+ */
+public final class ECNumberCheckDigit extends ModulusCheckDigit {
+
+    private static final long serialVersionUID = 7265356024784308367L;
+
+    /** Singleton Check Digit instance */
+    private static final CheckDigit INSTANCE = new ECNumberCheckDigit();
+
+    /**
+     * Gets the singleton instance of this validator.
+     * @return A singleton instance of the EC Number validator.
+     */
+    public static CheckDigit getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * EC number consists of 3 groups of numbers separated dashes (-).
+     * Example: dexamethasone is 200-003-9
+     */
+    private static final String GROUP = "(\\d{3})";
+    private static final String DASH = "(?:\\-)";
+    static final String EC_REGEX = "^(?:" + GROUP + DASH + GROUP + DASH + 
"(\\d))$";
+
+    private static final int EC_LEN = 7;
+    static final CodeValidator REGEX_VALIDATOR = new CodeValidator(EC_REGEX, 
EC_LEN, null);
+
+    /**
+     * Constructs a modulus 11 Check Digit routine.
+     */
+    private ECNumberCheckDigit() {
+        super(MODULUS_11);
+    }
+
+    /**
+     * Calculates the <i>weighted</i> value of a character in the
+     * code at a specified position.
+     *
+     * <p>For EC number digits are weighted by their position from left to 
right.</p>
+     *
+     * @param charValue The numeric value of the character.
+     * @param leftPos The position of the character in the code, counting from 
left to right
+     * @param rightPos The positionof the character in the code, counting from 
right to left
+     * @return The weighted value of the character.
+     */
+    @Override
+    protected int weightedValue(final int charValue, final int leftPos, final 
int rightPos) {
+        return leftPos >= EC_LEN ? 0 : charValue * leftPos;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String calculate(final String code) throws CheckDigitException {
+        if (code == null || code.isEmpty()) {
+            throw new CheckDigitException("Code is missing");
+        }
+        int modulusResult = calculateModulus(code, false);
+        return toCheckDigit(modulusResult);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isValid(final String code) {
+        if (code == null || code.isEmpty()) {

Review Comment:
   Reuse the new `isEmpty(String)`



##########
src/main/java/org/apache/commons/validator/routines/checkdigit/CASNumberCheckDigit.java:
##########
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.apache.commons.validator.routines.CodeValidator;
+
+/**
+ * Modulus 10 <b>CAS Registry Number</b> (or <b>Chemical Abstracts Service</b> 
(CAS RN)) Check Digit
+ * calculation/validation.
+ *
+ * <p>
+ * CAS Numbers are unique identification numbers used
+ * to identify chemical substance described in the open scientific literature.
+ * </p>
+ *
+ * <p>
+ * Check digit calculation is based on <i>modulus 10</i> with digits being 
weighted
+ * based on their position (from right to left).
+ * </p>
+ *
+ * <p>
+ * The check digit is found by taking the last digit times 1, the preceding 
digit times 2,
+ * the preceding digit times 3 etc., adding all these up and computing the sum 
modulo 10.
+ * For example, the CAS number of water is <code>7732-18-5</code>:
+ * the checksum 5 is calculated as (8×1 + 1×2 + 2×3 + 3×4 + 7×5 + 7×6) = 105; 
105 mod 10 = 5.
+ * </p>
+ *
+ * <p>
+ * For further information see
+ *  <a href="https://en.wikipedia.org/wiki/CAS_Registry_Number";>Wikipedia - 
CAS Registry Number</a>.
+ * </p>
+ *
+ * @since 1.9.0
+ */
+public final class CASNumberCheckDigit extends ModulusCheckDigit {
+
+    private static final long serialVersionUID = -5387334603220786657L;
+
+    /** Singleton Check Digit instance */
+    private static final CheckDigit INSTANCE = new CASNumberCheckDigit();
+
+    /**
+     * Gets the singleton instance of this validator.
+     * @return A singleton instance of the CAS Number validator.
+     */
+    public static CheckDigit getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * CAS number consists of 3 groups of numbers separated dashes (-).
+     * First group up to 7 digits.
+     * Example: water is 7732-18-5
+     */
+    private static final String GROUP1 = "(\\d{1,7})";
+    private static final String DASH = "(?:\\-)";
+    static final String CAS_REGEX = "^(?:" + GROUP1 + DASH + "(\\d{2})" + DASH 
+ "(\\d))$";
+
+    private static final int CAS_MIN_LEN = 4; // 9-99-9 LEN without SEP
+    /** maximum capacity of 1,000,000,000 == 9999999-99-9*/
+    private static final int CAS_MAX_LEN = 10;
+    static final CodeValidator REGEX_VALIDATOR = new CodeValidator(CAS_REGEX, 
CAS_MIN_LEN, CAS_MAX_LEN, null);
+
+    /** Weighting given to digits depending on their right position */
+    private static final int[] POSITION_WEIGHT = { 0,1,2,3,4,5,6,7,8,9 };
+
+    /**
+     * Constructs a modulus 10 Check Digit routine for CAS Numbers.
+     */
+    private CASNumberCheckDigit() {
+    }
+
+    /**
+     * Calculates the <i>weighted</i> value of a character in the code at a 
specified position.
+     * <p>
+     * CAS numbers are weighted in the following manner:

Review Comment:
   The paragraph tag is not closed.



##########
src/test/java/org/apache/commons/validator/routines/checkdigit/ECNumberCheckDigitTest.java:
##########
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.junit.jupiter.api.BeforeEach;
+
+/**
+ * EC Number Check Digit Tests.
+ */
+public class ECNumberCheckDigitTest extends AbstractCheckDigitTest {
+
+    private static final String FORMALDEHYDE = "200-001-8";
+    private static final String DEXAMETHASONE = "200-003-9";
+    private static final String ARSENIC = "231-148-6";
+    private static final String ASBESTOS = "603-721-4";
+    
+    /**
+     * Sets up routine & valid codes.
+     */
+    @BeforeEach
+    protected void setUp() {
+        routine = ECNumberCheckDigit.getInstance();
+        valid = new String[] { FORMALDEHYDE, DEXAMETHASONE, ARSENIC, ASBESTOS 
};
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String removeCheckDigit(final String code) {
+       String cde = (String)ECNumberCheckDigit.REGEX_VALIDATOR.validate(code);
+       if(cde == null || cde.length() <= checkDigitLth) return null;

Review Comment:
   See above.



##########
src/main/java/org/apache/commons/validator/routines/checkdigit/CASNumberCheckDigit.java:
##########
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons.validator.routines.checkdigit;
+
+import org.apache.commons.validator.routines.CodeValidator;
+
+/**
+ * Modulus 10 <b>CAS Registry Number</b> (or <b>Chemical Abstracts Service</b> 
(CAS RN)) Check Digit
+ * calculation/validation.
+ *
+ * <p>
+ * CAS Numbers are unique identification numbers used
+ * to identify chemical substance described in the open scientific literature.
+ * </p>
+ *
+ * <p>
+ * Check digit calculation is based on <i>modulus 10</i> with digits being 
weighted
+ * based on their position (from right to left).
+ * </p>
+ *
+ * <p>
+ * The check digit is found by taking the last digit times 1, the preceding 
digit times 2,
+ * the preceding digit times 3 etc., adding all these up and computing the sum 
modulo 10.
+ * For example, the CAS number of water is <code>7732-18-5</code>:
+ * the checksum 5 is calculated as (8×1 + 1×2 + 2×3 + 3×4 + 7×5 + 7×6) = 105; 
105 mod 10 = 5.
+ * </p>
+ *
+ * <p>
+ * For further information see
+ *  <a href="https://en.wikipedia.org/wiki/CAS_Registry_Number";>Wikipedia - 
CAS Registry Number</a>.
+ * </p>
+ *
+ * @since 1.9.0
+ */
+public final class CASNumberCheckDigit extends ModulusCheckDigit {
+
+    private static final long serialVersionUID = -5387334603220786657L;
+
+    /** Singleton Check Digit instance */
+    private static final CheckDigit INSTANCE = new CASNumberCheckDigit();
+
+    /**
+     * Gets the singleton instance of this validator.
+     * @return A singleton instance of the CAS Number validator.
+     */
+    public static CheckDigit getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * CAS number consists of 3 groups of numbers separated dashes (-).
+     * First group up to 7 digits.
+     * Example: water is 7732-18-5
+     */
+    private static final String GROUP1 = "(\\d{1,7})";
+    private static final String DASH = "(?:\\-)";
+    static final String CAS_REGEX = "^(?:" + GROUP1 + DASH + "(\\d{2})" + DASH 
+ "(\\d))$";
+
+    private static final int CAS_MIN_LEN = 4; // 9-99-9 LEN without SEP
+    /** maximum capacity of 1,000,000,000 == 9999999-99-9*/
+    private static final int CAS_MAX_LEN = 10;
+    static final CodeValidator REGEX_VALIDATOR = new CodeValidator(CAS_REGEX, 
CAS_MIN_LEN, CAS_MAX_LEN, null);
+
+    /** Weighting given to digits depending on their right position */
+    private static final int[] POSITION_WEIGHT = { 0,1,2,3,4,5,6,7,8,9 };
+
+    /**
+     * Constructs a modulus 10 Check Digit routine for CAS Numbers.
+     */
+    private CASNumberCheckDigit() {
+    }
+
+    /**
+     * Calculates the <i>weighted</i> value of a character in the code at a 
specified position.
+     * <p>
+     * CAS numbers are weighted in the following manner:
+     * <pre><code>
+     *    right position: 1  2  3  4  5  6  7  8  9 10
+     *            weight: 1  2  3  4  5  6  7  8  9  0
+     * </code></pre>
+     *
+     * @param charValue The numeric value of the character.
+     * @param leftPos The position of the character in the code, counting from 
left to right
+     * @param rightPos The positionof the character in the code, counting from 
right to left
+     * @return The weighted value of the character.
+     */
+    @Override
+    protected int weightedValue(final int charValue, final int leftPos, final 
int rightPos) {
+        final int weight = POSITION_WEIGHT[(rightPos - 1) % MODULUS_10];
+        return charValue * weight;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String calculate(final String code) throws CheckDigitException {
+        if (code == null || code.isEmpty()) {
+            throw new CheckDigitException("Code is missing");
+        }
+        int modulusResult = calculateModulus(code, false);
+        return toCheckDigit(modulusResult);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isValid(final String code) {
+        if (code == null || code.isEmpty()) {

Review Comment:
   Reuse the new `isEmpty(String)`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to