From: Aron Roberts Date: Tue, 23 Jun 2009 16:09:49 +0000 (+0000) Subject: NOJIRA Added maximum length checks for numeric IDs, validation of numeric IDs. X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=f1ec169baa07ec69be58bde0e4d968488044745b;p=tmp%2Fjakarta-migration.git NOJIRA Added maximum length checks for numeric IDs, validation of numeric IDs. --- diff --git a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java index ff52b9c6d..46dc4fd5c 100644 --- a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java +++ b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java @@ -56,6 +56,9 @@ package org.collectionspace.services.id; import java.util.Collections; import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class AlphabeticIDGenerator implements IDGenerator { private static final char NULL_CHAR = '\u0000'; @@ -224,8 +227,24 @@ public class AlphabeticIDGenerator implements IDGenerator { } public synchronized boolean isValidID(String value) throws IllegalArgumentException { - // Currently stubbed-out - return true; + + if ( value == null || value == "") { + throw new IllegalArgumentException("ID to validate must not be null or empty"); + } + + Pattern pattern = Pattern.compile(getRegex()); + Matcher matcher = pattern.matcher(value); + if (matcher.matches()) { + return true; + } else { + return false; + } + } - + + public synchronized String getRegex() { + // @TODO: This method is stubbed out; it needs to be implemented. + String regex = "(" + "\\*" + ")"; + return regex; + } } diff --git a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDGenerator.java b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDGenerator.java index 1e5c35694..03b3f9bf2 100644 --- a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDGenerator.java +++ b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDGenerator.java @@ -16,6 +16,10 @@ * $Date: 2009-06-19 19:03:38 -0700 (Fri, 19 Jun 2009) $ */ +// @TODO: Consider making this class, or a class that implements +// this interface, abstract, in part because we're duplicating code +// in isValidID() in multiple Generator subclasses. + package org.collectionspace.services.id; public interface IDGenerator { @@ -30,6 +34,6 @@ public interface IDGenerator { public boolean isValidID(String value); - // public String getRegex(); + public String getRegex(); } diff --git a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/NumericIDGenerator.java b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/NumericIDGenerator.java index d1fece529..b8cad8bbe 100644 --- a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/NumericIDGenerator.java +++ b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/NumericIDGenerator.java @@ -23,12 +23,24 @@ package org.collectionspace.services.id; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class NumericIDGenerator implements IDGenerator { - + + final static private int DEFAULT_MAX_LENGTH = 6; + private int maxLength = DEFAULT_MAX_LENGTH; + private long initialValue = 0; private long currentValue = 0; public NumericIDGenerator(String initialValue) throws IllegalArgumentException { + this(initialValue, Integer.toString(DEFAULT_MAX_LENGTH)); + } + + public NumericIDGenerator(String initialValue, String maxLength) + throws IllegalArgumentException { + try { long l = Long.parseLong(initialValue.trim()); if ( l < 0 ) { @@ -41,6 +53,13 @@ public class NumericIDGenerator implements IDGenerator { } catch (NumberFormatException e) { throw new IllegalArgumentException("Initial ID value must be parseable as a number"); } + + try { + this.maxLength = Integer.parseInt(maxLength); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Maximum ID length must be parseable as a number"); + } + } public synchronized void reset() { @@ -55,14 +74,34 @@ public class NumericIDGenerator implements IDGenerator { return Long.toString(this.currentValue); } - public synchronized String getNextID() { + public synchronized String getNextID() throws IllegalStateException { this.currentValue++; - return Long.toString(this.currentValue); + String nextID = Long.toString(this.currentValue); + if (nextID.length() > this.maxLength) { + throw new IllegalStateException("Next ID cannot exceed maximum length"); + } + return nextID; + } + + public synchronized boolean isValidID(String value) { + + if ( value == null || value == "") { + return false; + } + + Pattern pattern = Pattern.compile(getRegex()); + Matcher matcher = pattern.matcher(value); + if (matcher.matches()) { + return true; + } else { + return false; + } + } - public synchronized boolean isValidID(String value) throws IllegalArgumentException { - // Currently stubbed-out - return true; + public synchronized String getRegex() { + String regex = "(" + "\\d" + "{1," + Integer.toString(this.maxLength) + "}" + ")"; + return regex; } } diff --git a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/NumericIDPart.java b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/NumericIDPart.java index 5d68030fc..0ec10d5e9 100644 --- a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/NumericIDPart.java +++ b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/NumericIDPart.java @@ -24,13 +24,13 @@ package org.collectionspace.services.id; public class NumericIDPart extends IDPart { - public NumericIDPart(String baseVal) { + public NumericIDPart(String baseVal) throws IllegalArgumentException { // Store the appropriate Numeric ID generator and the base value for this part. - - // @TODO: Determine how to handle the NumberFormatException that will be thrown - // from parseLong "if the string does not contain a parsable long." We may - // need a shim to perform this conversion prior to setting up the generator. super(new NumericIDGenerator(baseVal)); }; + public NumericIDPart(String baseVal, String maxLength) throws IllegalArgumentException { + super(new NumericIDGenerator(baseVal, maxLength)); + }; + } diff --git a/sandbox/aron/id/src/test/java/org/collectionspace/services/id/NumericIDPartTest.java b/sandbox/aron/id/src/test/java/org/collectionspace/services/id/NumericIDPartTest.java index 51a5ba61f..1f3d0cc12 100644 --- a/sandbox/aron/id/src/test/java/org/collectionspace/services/id/NumericIDPartTest.java +++ b/sandbox/aron/id/src/test/java/org/collectionspace/services/id/NumericIDPartTest.java @@ -39,6 +39,31 @@ public class NumericIDPartTest extends TestCase { } + public void testNextIDOverflow() { + + try { + part = new NumericIDPart("997", "3"); + assertEquals("998", part.getNextID()); + assertEquals("999", part.getNextID()); + assertEquals("1000", part.getNextID()); + fail("Should have thrown IllegalStateException here"); + } catch (IllegalStateException expected) { + // This Exception should be thrown, and thus the test should pass. + } + + // Tests default MAX_LENGTH value of 6 decimal places + try { + part = new NumericIDPart("999997"); + assertEquals("999998", part.getNextID()); + assertEquals("999999", part.getNextID()); + assertEquals("1000000", part.getNextID()); + fail("Should have thrown IllegalStateException here"); + } catch (IllegalStateException expected) { + // This Exception should be thrown, and thus the test should pass. + } + + } + public void testReset() { part = new NumericIDPart("25"); @@ -95,6 +120,45 @@ public class NumericIDPartTest extends TestCase { } } + + public void testNonLongParseableMaxLength() { + + try { + part = new NumericIDPart("1", "not an int parseable value"); + fail("Should have thrown IllegalArgumentException here"); + } catch (IllegalArgumentException expected) { + // This Exception should be thrown, and thus the test should pass. + } + + } + + public void testIsValidID() { + + part = new NumericIDPart("1"); + assertTrue(part.isValidID("1")); + + part = new NumericIDPart("1"); + assertTrue(part.isValidID("123")); + + part = new NumericIDPart("1"); + assertTrue(part.isValidID("123456")); + + part = new NumericIDPart("1"); + assertFalse(part.isValidID("1234567")); + + part = new NumericIDPart("1", "3"); + assertTrue(part.isValidID("123")); + + part = new NumericIDPart("1", "3"); + assertFalse(part.isValidID("1234")); + + part = new NumericIDPart("1"); + assertFalse(part.isValidID("not a parseable long")); + + part = new NumericIDPart("1", "3"); + assertFalse(part.isValidID("not a parseable long")); + + } // @TODO: Add more tests of boundary conditions, exceptions ...