From ac1a0c7e400cfeb7cfc90ce54dfe9d960bc9e102 Mon Sep 17 00:00:00 2001 From: Aron Roberts Date: Fri, 4 Sep 2009 19:28:13 +0000 Subject: [PATCH] CSPACE-361: Initial steps toward larger refactoring of ID Service --- services/id/client/pom.xml | 91 +++++ .../src/test/resources/log4j.properties | 23 ++ .../services/id/AlphabeticIDGenerator.java | 328 ----------------- .../id/AlphabeticIDGeneratorPart.java | 333 ++++++++++++++++++ .../services/id/AlphabeticIDPart.java | 45 --- .../{IDPattern.java => BaseIDGenerator.java} | 64 ++-- .../services/id/IDGenerator.java | 48 +-- .../services/id/IDGeneratorPart.java | 51 +++ .../services/id/IDGeneratorSerializer.java | 31 +- .../collectionspace/services/id/IDPart.java | 92 ----- .../services/id/IDResource.java | 236 ++++++------- .../services/id/IDServiceJdbcImpl.java | 72 ++-- .../services/id/NumericIDGenerator.java | 159 --------- .../services/id/NumericIDGeneratorPart.java | 177 ++++++++++ .../services/id/NumericIDPart.java | 49 --- .../services/id/StringIDGenerator.java | 110 ------ .../services/id/StringIDGeneratorPart.java | 113 ++++++ .../services/id/StringIDPart.java | 36 -- ...enerator.java => YearIDGeneratorPart.java} | 34 +- .../services/id/YearIDPart.java | 41 --- .../services/id/IDPatternTest.java | 273 -------------- .../services/id/NumericIDPartTest.java | 192 ---------- .../services/id/YearIDPartTest.java | 154 -------- .../AlphabeticIDGeneratorPartTest.java} | 74 ++-- .../id/test/IDGeneratorSerializerTest.java | 88 +++-- .../services/id/test/IDGeneratorTest.java | 271 ++++++++++++++ .../id/test/IDServiceJdbcImplTest.java | 267 +++++++------- .../id/test/NumericIDGeneratorPartTest.java | 196 +++++++++++ .../StringIDGeneratorPartTest.java} | 58 +-- .../id/test/YearIDGeneratorPartTest.java | 154 ++++++++ 30 files changed, 1880 insertions(+), 1980 deletions(-) create mode 100644 services/id/client/pom.xml create mode 100644 services/id/client/src/test/resources/log4j.properties delete mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java create mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGeneratorPart.java delete mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDPart.java rename services/id/service/src/main/java/org/collectionspace/services/id/{IDPattern.java => BaseIDGenerator.java} (81%) create mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorPart.java delete mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/IDPart.java delete mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGenerator.java create mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGeneratorPart.java delete mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/NumericIDPart.java delete mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/StringIDGenerator.java create mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/StringIDGeneratorPart.java delete mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/StringIDPart.java rename services/id/service/src/main/java/org/collectionspace/services/id/{YearIDGenerator.java => YearIDGeneratorPart.java} (90%) delete mode 100644 services/id/service/src/main/java/org/collectionspace/services/id/YearIDPart.java delete mode 100644 services/id/service/src/test/java/org/collectionspace/services/id/IDPatternTest.java delete mode 100644 services/id/service/src/test/java/org/collectionspace/services/id/NumericIDPartTest.java delete mode 100644 services/id/service/src/test/java/org/collectionspace/services/id/YearIDPartTest.java rename services/id/service/src/test/java/org/collectionspace/services/id/{AlphabeticIDPartTest.java => test/AlphabeticIDGeneratorPartTest.java} (77%) create mode 100644 services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorTest.java create mode 100644 services/id/service/src/test/java/org/collectionspace/services/id/test/NumericIDGeneratorPartTest.java rename services/id/service/src/test/java/org/collectionspace/services/id/{StringIDPartTest.java => test/StringIDGeneratorPartTest.java} (69%) create mode 100644 services/id/service/src/test/java/org/collectionspace/services/id/test/YearIDGeneratorPartTest.java diff --git a/services/id/client/pom.xml b/services/id/client/pom.xml new file mode 100644 index 000000000..66fbd1a00 --- /dev/null +++ b/services/id/client/pom.xml @@ -0,0 +1,91 @@ + + + + + org.collectionspace.services.id + org.collectionspace.services + 1.0 + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.id.client + 1.0 + services.id.client + + + + + org.slf4j + slf4j-api + test + + + org.slf4j + slf4j-log4j12 + test + + + org.collectionspace.services + org.collectionspace.services.client + 1.0 + + + + org.testng + testng + 5.6 + + + org.jboss.resteasy + resteasy-jaxrs + 1.0.2.GA + + + + tjws + webserver + + + + + org.jboss.resteasy + resteasy-jaxb-provider + 1.0.2.GA + + + org.jboss.resteasy + resteasy-multipart-provider + 1.0.2.GA + + + + + cspace-services-id-client + + + org.apache.maven.plugins + maven-surefire-plugin + + + + log4j.configuration + file:target/test-classes/log4j.properties + + + + + + maven-compiler-plugin + 2.0.2 + + 1.6 + 1.6 + + + + + + diff --git a/services/id/client/src/test/resources/log4j.properties b/services/id/client/src/test/resources/log4j.properties new file mode 100644 index 000000000..148a3e865 --- /dev/null +++ b/services/id/client/src/test/resources/log4j.properties @@ -0,0 +1,23 @@ +log4j.rootLogger=debug, stdout, R + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +# Pattern to output the caller's file name and line number. +log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n + +log4j.appender.R=org.apache.log4j.RollingFileAppender +log4j.appender.R.File=target/test-client.log + +log4j.appender.R.MaxFileSize=100KB +# Keep one backup file +log4j.appender.R.MaxBackupIndex=1 + +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n + +#packages +log4j.logger.org.collectionspace=DEBUG +log4j.logger.org.apache=INFO +log4j.logger.httpclient=INFO +log4j.logger.org.jboss.resteasy=INFO diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java b/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java deleted file mode 100644 index 4f5444d9a..000000000 --- a/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java +++ /dev/null @@ -1,328 +0,0 @@ -/* - * AlphabeticIDGenerator - * - * Generates identifiers (IDs) that consist of incrementing alphabetic - * characters, from within a sequence of characters. - * - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ - */ - -// @TODO: Add Javadoc comments - -// @TODO: When auto expanding, we'll need to allow setting of a maximum length to -// which the generated IDs can grow, likely as an additional parameter to be -// passed to a constructor, with a default value hard-coded in the class. -// If that length is exceeded, nextID() should throw an IllegalStateException. - -// @TODO: Consider handling escaped characters or sequences which represent Unicode -// code points, both in the start and end characters of the sequence, and in the initial value. -// (Example: '\u0072' for the USASCII 'r' character; see -// http://www.fileformat.info/info/unicode/char/0072/index.htm) -// -// Ideally, we should read these in free-text patterns, alongside unescaped characters, -// but in practice we may wish to require some structured form for arguments -// containing such characters. -// -// Some initial research on this: -// http://www.velocityreviews.com/forums/t367758-unescaping-unicode-code-points-in-a-java-string.html -// We might also look into the (protected) source code for java.util.Properties.load() -// which reads escaped Unicode values. -// -// Note also that, if the goal is to cycle through a sequence of alphabetic identifiers, -// such as the sequence of characters used in a particular human language, it may or may not -// be the case that any contiguous Unicode code point sequence reflects such a character sequence. - -// NOTE: This class currently hard-codes the assumption that the values in -// alphabetic identifiers are ordered in significance from left-to-right; -// that is, the most significant value appears in the left-most position. - -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'; - - private static final String DEFAULT_START_CHAR = "a"; - private static final String DEFAULT_END_CHAR = "z"; - private static final String DEFAULT_INITIAL_VALUE = "a"; - - private char startChar = NULL_CHAR; - private char endChar = NULL_CHAR; - - private Vector initialValue = new Vector(); - private Vector currentValue = new Vector(); - - // Constructor using defaults for character sequence and initial value. - // - // If no start and end characters are provided for the alphabetic character - // sequence, default to an 'a-z' sequence, representing the lowercase alphabetic - // characters in the USASCII character set (within Java's internal - // Unicode UTF-16 representation). - // - // Additionally defaults to an initial value of "a". - public AlphabeticIDGenerator() throws IllegalArgumentException { - - this(DEFAULT_START_CHAR, DEFAULT_END_CHAR, DEFAULT_INITIAL_VALUE); - - } - - // Constructor using defaults for character sequence. - // - // If no start and end characters are provided for the alphabetic character - // sequence, default to an 'a-z' sequence, representing the lowercase alphabetic - // characters in the USASCII character set (within Java's internal - // Unicode UTF-16 representation). - public AlphabeticIDGenerator(String initial) throws IllegalArgumentException { - - this(DEFAULT_START_CHAR, DEFAULT_END_CHAR, initial); - - } - - // Constructor. - public AlphabeticIDGenerator(String sequenceStart, String sequenceEnd, String initial) - throws IllegalArgumentException { - - // Validate and store the start character in the character sequence. - - if (sequenceStart == null || sequenceStart.equals("")) { - throw new IllegalArgumentException( - "Start character in the character sequence must not be null or empty"); - } - - if (sequenceStart.length() == 1) { - this.startChar = sequenceStart.charAt(0); - } else if (false) { - // Handle representations of Unicode code points here - } else { - throw new IllegalArgumentException( - "Start character must be one character in length"); - // "Start character must be one character in length or a Unicode value such as '\u0000'"); - } - - // Validate and store the end character in the character sequence. - - if (sequenceEnd == null || sequenceEnd.equals("")) { - throw new IllegalArgumentException( - "End character in the character sequence must not be null or empty"); - } - - if (sequenceEnd.length() == 1) { - this.endChar = sequenceEnd.charAt(0); - } else if (false) { - // Handle representations of Unicode code points here - } else { - throw new IllegalArgumentException( - "End character must be one character in length"); - // "End character must be one character in length or a Unicode value such as '\u0000'"); - } - - if (this.endChar <= this.startChar) { - throw new IllegalArgumentException( - "End (last) character in the character sequence must be greater than the start character"); - } - - // Validate and store the initial value of this identifier. - - if (initial == null || initial.equals("")) { - throw new IllegalArgumentException("Initial value must not be null or empty"); - } - - // @TODO: Add a check for maximum length of the initial value here. - - // Store the chars in the initial value as Characters in a Vector, - // validating each character to identify whether it falls within - // the provided sequence. - // - // (Since we're performing casts from char to Character, we can't just - // use Arrays.asList() to copy the initial array to a Vector.) - char[] chars = initial.toCharArray(); - char ch; - for (int i = 0; i < chars.length; i++) { - - // If the character falls within the provided sequence, copy it to the Vector. - ch = chars[i]; - if (ch >= this.startChar && ch <= this.endChar) { - this.initialValue.add(new Character(ch)); - // Otherwise, we've detected a character not in the sequence. - } else { - throw new IllegalArgumentException("character " + "\'" + ch + "\'" + " is not valid"); - } - - } - - // Initialize the current value from the initial value. - this.currentValue = new Vector(this.initialValue); - - } - - // Returns the initial value. - public String getInitialID() { - return getIDString(this.initialValue); - } - - // Returns the current value. - public String getCurrentID() { - return getIDString(this.currentValue); - } - - // Sets the current value. - public void setCurrentID(String value) throws IllegalArgumentException { - - // @TODO Much of this code is copied from the main constructor, - // and may be ripe for refactoring. - - if (value == null || value.equals("")) { - throw new IllegalArgumentException("Initial value must not be null or empty"); - } - - // @TODO: Add a check for maximum length of the value here. - - // Store the chars in the value as Characters in a Vector, - // validating each character to identify whether it falls within - // the provided sequence. - // - // (Since we're performing casts from char to Character, we can't just - // use Arrays.asList() to copy the initial array to a Vector.) - char[] chars = value.toCharArray(); - char ch; - Vector v = new Vector(); - for (int i = 0; i < chars.length; i++) { - - // If the character falls within the range bounded by the start and end - // characters, copy it to the Vector. - ch = chars[i]; - if (ch >= this.startChar && ch <= this.endChar) { - v.add(new Character(ch)); - // Otherwise, we've detected a character not in the sequence. - } else { - throw new IllegalArgumentException("character " + "\'" + ch + "\'" + " is not valid"); - } - - } - - // Set the current value. - this.currentValue = new Vector(v); - - } - - // Reset the current value to the initial value. - public void resetID() { - Collections.copy(this.currentValue, this.initialValue); - } - - - // Returns the next alphabetic ID in the sequence. - // - // Currently, the number of characters auto-expands as the - // value of the most significant character rolls over. - // E.g. a call to getNextID(), where the current ID is "z", - // auto-expands to "aa", and "ZZ" auto-expands to "AAA". - // - // See the TODOs at the top of this class for additional - // functionality that needs to be implemented. - public String nextID() throws IllegalStateException { - - // Get next values for each character, from right to left - // (least significant to most significant). - boolean expandIdentifier = false; - int size = this.currentValue.size(); - char ch; - for (int i = (size - 1); i >= 0; i--) { - - ch = this.currentValue.get(i).charValue(); - - // When we reach the maximum value for any character, - // 'roll over' to the minimum value in our character range. - if (ch == this.endChar) { - this.currentValue.set(i, Character.valueOf(this.startChar)); - // If this rollover occurs in the most significant value, - // set a flag to later expand the size of the identifier. - // - // @TODO: Set another flag to enable or disable this behavior, - // as well as a mechanism for setting the maximum expansion permitted. - if (i == 0) { - expandIdentifier = true; - } - // When we reach the most significant character whose value - // doesn't roll over, increment that character and exit the loop. - } else { - ch++; - this.currentValue.set(i, Character.valueOf(ch)); - i = -1; - break; - } - - } - - // If we are expanding the size of the identifier, insert a new - // value at the most significant (leftmost) character position, - // sliding other values to the right. - if (expandIdentifier) { - this.currentValue.add(0, Character.valueOf(this.startChar)); - } - - return getIDString(this.currentValue); - - } - - // Returns a String representation of the ID, by appending - // the String values of each character. - public String getIDString(Vector v) { - StringBuffer sb = new StringBuffer(); - for ( Character ch : v ) { - sb.append(ch.toString()); - } - return sb.toString(); - } - - public boolean isValidID(String value) { - - if (value == null || value.equals("")) { - return false; - } - - Pattern pattern = Pattern.compile(getRegex()); - Matcher matcher = pattern.matcher(value); - if (matcher.matches()) { - return true; - } else { - return false; - } - - } - - public String getRegex() { - // @TODO: May need to constrain the number of alphabetic characters based - // on a maximum value, TBA. Currently, this regex simply matches sequences - // of one or more characters. - String regex = - "(" + "[" + - String.valueOf(this.startChar) + "-" + String.valueOf(this.endChar) + - "]+" + ")"; - return regex; - } - -} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGeneratorPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGeneratorPart.java new file mode 100644 index 000000000..9a9b59d0c --- /dev/null +++ b/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGeneratorPart.java @@ -0,0 +1,333 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright © 2009 Regents of the University of California + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + */ + +// @TODO: Add Javadoc comments + +// @TODO: When auto expanding, we'll need to allow setting of a maximum length to +// which the generated IDs can grow, likely as an additional parameter to be +// passed to a constructor, with a default value hard-coded in the class. +// If that length is exceeded, nextID() should throw an IllegalStateException. + +// @TODO: Consider handling escaped characters or sequences which represent Unicode +// code points, both in the start and end characters of the sequence, and in the initial value. +// (Example: '\u0072' for the USASCII 'r' character; see +// http://www.fileformat.info/info/unicode/char/0072/index.htm) +// +// Ideally, we should read these in free-text patterns, alongside unescaped characters, +// but in practice we may wish to require some structured form for arguments +// containing such characters. +// +// Some initial research on this: +// http://www.velocityreviews.com/forums/t367758-unescaping-unicode-code-points-in-a-java-string.html +// We might also look into the (protected) source code for java.util.Properties.load() +// which reads escaped Unicode values. +// +// Note also that, if the goal is to cycle through a sequence of alphabetic identifiers, +// such as the sequence of characters used in a particular human language, it may or may not +// be the case that any contiguous Unicode code point sequence reflects such a character sequence. + +// NOTE: This class currently hard-codes the assumption that the values in +// alphabetic identifiers are ordered in significance from left-to-right; +// that is, the most significant value appears in the left-most position. + +package org.collectionspace.services.id; + +import java.util.Collections; +import java.util.Vector; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * AlphabeticIDGeneratorPart + * + * Generates identifiers (IDs) that consist of incrementing alphabetic + * characters, from within a sequence of characters. + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ +public class AlphabeticIDGeneratorPart implements IDGeneratorPart { + + private static final char NULL_CHAR = '\u0000'; + + private static final String DEFAULT_START_CHAR = "a"; + private static final String DEFAULT_END_CHAR = "z"; + private static final String DEFAULT_INITIAL_VALUE = "a"; + + private char startChar = NULL_CHAR; + private char endChar = NULL_CHAR; + + private Vector initialValue = new Vector(); + private Vector currentValue = new Vector(); + + // Constructor using defaults for character sequence and initial value. + // + // If no start and end characters are provided for the alphabetic character + // sequence, default to an 'a-z' sequence, representing the lowercase alphabetic + // characters in the USASCII character set (within Java's internal + // Unicode UTF-16 representation). + // + // Additionally defaults to an initial value of "a". + public AlphabeticIDGeneratorPart() throws IllegalArgumentException { + + this(DEFAULT_START_CHAR, DEFAULT_END_CHAR, DEFAULT_INITIAL_VALUE); + + } + + // Constructor using defaults for character sequence. + // + // If no start and end characters are provided for the alphabetic character + // sequence, default to an 'a-z' sequence, representing the lowercase alphabetic + // characters in the USASCII character set (within Java's internal + // Unicode UTF-16 representation). + public AlphabeticIDGeneratorPart(String initial) throws IllegalArgumentException { + + this(DEFAULT_START_CHAR, DEFAULT_END_CHAR, initial); + + } + + // Constructor. + public AlphabeticIDGeneratorPart(String sequenceStart, String sequenceEnd, String initial) + throws IllegalArgumentException { + + // Validate and store the start character in the character sequence. + + if (sequenceStart == null || sequenceStart.equals("")) { + throw new IllegalArgumentException( + "Start character in the character sequence must not be null or empty"); + } + + if (sequenceStart.length() == 1) { + this.startChar = sequenceStart.charAt(0); + } else if (false) { + // Handle representations of Unicode code points here + } else { + throw new IllegalArgumentException( + "Start character must be one character in length"); + // "Start character must be one character in length or + // a Unicode value such as '\u0000'"); + } + + // Validate and store the end character in the character sequence. + + if (sequenceEnd == null || sequenceEnd.equals("")) { + throw new IllegalArgumentException( + "End character in the character sequence must not be null or empty"); + } + + if (sequenceEnd.length() == 1) { + this.endChar = sequenceEnd.charAt(0); + } else if (false) { + // Handle representations of Unicode code points here + } else { + throw new IllegalArgumentException( + "End character must be one character in length"); + // "End character must be one character in length or + // a Unicode value such as '\u0000'"); + } + + if (this.endChar <= this.startChar) { + throw new IllegalArgumentException( + "End (last) character in the character sequence must be greater than the start character"); + } + + // Validate and store the initial value of this identifier. + + if (initial == null || initial.equals("")) { + throw new IllegalArgumentException("Initial value must not be null or empty"); + } + + // @TODO: Add a check for maximum length of the initial value here. + + // Store the chars in the initial value as Characters in a Vector, + // validating each character to identify whether it falls within + // the provided sequence. + // + // (Since we're performing casts from char to Character, we can't just + // use Arrays.asList() to copy the initial array to a Vector.) + char[] chars = initial.toCharArray(); + char ch; + for (int i = 0; i < chars.length; i++) { + + // If the character falls within the provided sequence, + // copy it to the Vector. + ch = chars[i]; + if (ch >= this.startChar && ch <= this.endChar) { + this.initialValue.add(new Character(ch)); + // Otherwise, we've detected a character not in the sequence. + } else { + throw new IllegalArgumentException( + "character " + "\'" + ch + "\'" + " is not valid"); + } + + } + + // Initialize the current value from the initial value. + this.currentValue = new Vector(this.initialValue); + + } + + // Returns the initial value. + public String getInitialID() { + return getIDString(this.initialValue); + } + + // Returns the current value. + public String getCurrentID() { + return getIDString(this.currentValue); + } + + // Sets the current value. + public void setCurrentID(String value) throws IllegalArgumentException { + + // @TODO Much of this code is copied from the main constructor, + // and may be ripe for refactoring. + + if (value == null || value.equals("")) { + throw new IllegalArgumentException("Initial value must not be null or empty"); + } + + // @TODO: Add a check for maximum length of the value here. + + // Store the chars in the value as Characters in a Vector, + // validating each character to identify whether it falls within + // the provided sequence. + // + // (Since we're performing casts from char to Character, we can't just + // use Arrays.asList() to copy the initial array to a Vector.) + char[] chars = value.toCharArray(); + char ch; + Vector v = new Vector(); + for (int i = 0; i < chars.length; i++) { + + // If the character falls within the range bounded by + // the start and end characters, copy it to the Vector. + ch = chars[i]; + if (ch >= this.startChar && ch <= this.endChar) { + v.add(new Character(ch)); + // Otherwise, we've detected a character not in the sequence. + } else { + throw new IllegalArgumentException( + "character " + "\'" + ch + "\'" + " is not valid"); + } + + } + + // Set the current value. + this.currentValue = new Vector(v); + + } + + // Reset the current value to the initial value. + public void resetID() { + Collections.copy(this.currentValue, this.initialValue); + } + + + // Returns the next alphabetic ID in the sequence. + // + // Currently, the number of characters auto-expands as the + // value of the most significant character rolls over. + // E.g. a call to getNextID(), where the current ID is "z", + // auto-expands to "aa", and "ZZ" auto-expands to "AAA". + // + // See the TODOs at the top of this class for additional + // functionality that needs to be implemented. + public String nextID() throws IllegalStateException { + + // Get next values for each character, from right to left + // (least significant to most significant). + boolean expandIdentifier = false; + int size = this.currentValue.size(); + char ch; + for (int i = (size - 1); i >= 0; i--) { + + ch = this.currentValue.get(i).charValue(); + + // When we reach the maximum value for any character, + // 'roll over' to the minimum value in our character range. + if (ch == this.endChar) { + this.currentValue.set(i, Character.valueOf(this.startChar)); + // If this rollover occurs in the most significant value, + // set a flag to later expand the size of the identifier. + // + // @TODO: Set another flag to enable or disable this behavior, + // as well as a mechanism for setting the maximum expansion permitted. + if (i == 0) { + expandIdentifier = true; + } + // When we reach the most significant character whose value + // doesn't roll over, increment that character and exit the loop. + } else { + ch++; + this.currentValue.set(i, Character.valueOf(ch)); + i = -1; + break; + } + + } + + // If we are expanding the size of the identifier, insert a new + // value at the most significant (leftmost) character position, + // sliding other values to the right. + if (expandIdentifier) { + this.currentValue.add(0, Character.valueOf(this.startChar)); + } + + return getIDString(this.currentValue); + + } + + // Returns a String representation of the ID, by appending + // the String values of each character. + public String getIDString(Vector v) { + StringBuffer sb = new StringBuffer(); + for ( Character ch : v ) { + sb.append(ch.toString()); + } + return sb.toString(); + } + + public boolean isValidID(String value) { + + if (value == null || value.equals("")) { + return false; + } + + Pattern pattern = Pattern.compile(getRegex()); + Matcher matcher = pattern.matcher(value); + if (matcher.matches()) { + return true; + } else { + return false; + } + + } + + public String getRegex() { + // @TODO: May need to constrain the number of alphabetic characters based + // on a maximum value, TBA. Currently, this regex simply matches sequences + // of one or more characters. + String regex = + "(" + "[" + + String.valueOf(this.startChar) + "-" + String.valueOf(this.endChar) + + "]+" + ")"; + return regex; + } + +} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDPart.java deleted file mode 100644 index c90d86766..000000000 --- a/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDPart.java +++ /dev/null @@ -1,45 +0,0 @@ - /* - * AlphabeticIDPart - * - * Models a part of an identifier (ID) whose values consist of incrementing - * alphabetic characters, from within a sequence of characters. - * - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ - */ - -// @TODO: Add Javadoc comments - -package org.collectionspace.services.id; - -public class AlphabeticIDPart extends IDPart { - - public AlphabeticIDPart() { - super(new AlphabeticIDGenerator()); - }; - - public AlphabeticIDPart(String baseVal) { - super(new AlphabeticIDGenerator(baseVal)); - }; - - public AlphabeticIDPart(String startVal, String endVal, String baseVal) { - super(new AlphabeticIDGenerator(startVal, endVal, baseVal)); - }; - -} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDPattern.java b/services/id/service/src/main/java/org/collectionspace/services/id/BaseIDGenerator.java similarity index 81% rename from services/id/service/src/main/java/org/collectionspace/services/id/IDPattern.java rename to services/id/service/src/main/java/org/collectionspace/services/id/BaseIDGenerator.java index f70338769..5f1339d98 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/IDPattern.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/BaseIDGenerator.java @@ -1,7 +1,7 @@ /** - * IDPattern + * BaseIDGenerator * - * Models an identifier (ID), which consists of multiple IDParts. + * Models an identifier (ID), which consists of multiple IDGeneratorParts. * * This document is a part of the source code and related artifacts * for CollectionSpace, an open source collections management system @@ -25,8 +25,8 @@ // @TODO: Add Javadoc comments -// @TODO: Catch Exceptions thrown by IDPart, then -// reflect this in the corresponding IDPatternTest class. +// @TODO: Catch Exceptions thrown by IDGeneratorPart, then +// reflect this in the corresponding BaseIDGeneratorTest class. package org.collectionspace.services.id; @@ -36,24 +36,24 @@ import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class IDPattern { +public class BaseIDGenerator implements IDGenerator { private String csid = ""; private String uri = ""; private String description = ""; - private Vector parts = new Vector(); + private Vector parts = new Vector(); final static int MAX_ID_LENGTH = 50; // Constructor - public IDPattern(String csid) { + public BaseIDGenerator(String csid) { if (csid != null && ! csid.equals("")) { this.csid = csid; } } // Constructor - public IDPattern(String csid, Vector partsList) { + public BaseIDGenerator(String csid, Vector partsList) { if (csid != null && ! csid.equals("")) { this.csid = csid; } @@ -93,7 +93,7 @@ public class IDPattern { return this.description; } - public void add(IDPart part) { + public void add(IDGeneratorPart part) { if (part != null) { this.parts.add(part); } @@ -102,7 +102,7 @@ public class IDPattern { // Returns the current value of this ID. public String getCurrentID() { StringBuffer sb = new StringBuffer(MAX_ID_LENGTH); - for (IDPart part : this.parts) { + for (IDGeneratorPart part : this.parts) { sb.append(part.getCurrentID()); } return sb.toString(); @@ -122,9 +122,9 @@ public class IDPattern { // // Examples: // * 2009.5." becomes "2009.5.1", in a case where the - // next ID component is an incrementing numeric IDPart. + // next ID component is an incrementing numeric IDGeneratorPart. // * "E55-" becomes "E55-a", where the next ID component - // is an incrementing alphabetic IDPart. + // is an incrementing alphabetic IDGeneratorPart. public String getCurrentID(String value) throws IllegalArgumentException { @@ -134,19 +134,19 @@ public class IDPattern { // by incrementally appending each part's regex, until no // (more) matches are found. // - // In so doing, build a subset of this IDPattern's regex + // In so doing, build a subset of this BaseIDGenerator's regex // that fully matches the supplied value. Pattern pattern = null; Matcher matcher = null; int matchedParts = 0; StringBuffer regexToTry = new StringBuffer(); StringBuffer regex = new StringBuffer(); - for (IDPart partToTryMatching : this.parts) { + for (IDGeneratorPart partToTryMatching : this.parts) { regexToTry.append(partToTryMatching.getRegex()); pattern = Pattern.compile(regexToTry.toString()); matcher = pattern.matcher(value); // If a stem match was found on the current regex, - // store a count of matched IDParts and the regex pattern + // store a count of matched IDGeneratorParts and the regex pattern // that has matched to this point. if (matcher.lookingAt()) { matchedParts++; @@ -175,24 +175,24 @@ public class IDPattern { // Otherwise, if the supplied ID matches the pattern, // split the ID into its components and store those - // values in each of the pattern's IDParts. - IDPart currentPart; + // values in each of the pattern's IDGeneratorParts. + IDGeneratorPart currentPart; for (int i = 1; i <= matchedParts; i++) { currentPart = this.parts.get(i - 1); currentPart.setCurrentID(matcher.group(i)); } - // Obtain the initial value of the next IDPart, and + // Obtain the initial value of the next IDGeneratorPart, and // set the current value of that part to its initial value. // // If the supplied ID fully matches the pattern, there will - // be no 'next' IDPart, and we must catch that Exception below. + // be no 'next' IDGeneratorPart, and we must catch that Exception below. int nextPartNum = matchedParts; try { String initial = this.parts.get(nextPartNum).getInitialID(); this.parts.get(nextPartNum).setCurrentID(initial); // Increment the number of matched parts to reflect the - // addition of this next IDPart. + // addition of this next IDGeneratorPart. matchedParts++; } catch (ArrayIndexOutOfBoundsException e ) { // Do nothing here; we simply won't increment @@ -200,7 +200,7 @@ public class IDPattern { } // Call the getCurrentID() method on each of the - // supplied IDParts, as well as on the added IDPart + // supplied IDGeneratorParts, as well as on the added IDGeneratorPart // whose initial value was just obtained, if any. StringBuffer sb = new StringBuffer(); for (int i = 1; i <= matchedParts; i++) { @@ -212,18 +212,18 @@ public class IDPattern { } // Returns the next value of this ID, and sets the current value to that ID. - public String nextID() throws IllegalStateException { + public String newID() throws IllegalStateException { - // Obtain the last (least significant) IDPart, + // Obtain the last (least significant) IDGeneratorPart, // and call its nextID() method, which will // concurrently set the current value of that ID // to the next ID. int lastPartNum = this.parts.size() - 1; this.parts.get(lastPartNum).nextID(); - // Then call the getCurrentID() method on all of the IDParts + // Then call the getCurrentID() method on all of the IDGeneratorParts StringBuffer sb = new StringBuffer(MAX_ID_LENGTH); - for (IDPart part : this.parts) { + for (IDGeneratorPart part : this.parts) { sb.append(part.getCurrentID()); } @@ -234,7 +234,7 @@ public class IDPattern { // Returns the next value of this ID, given a // supplied ID that entirely matches the pattern, // and sets the current value to that ID. - public String nextID(String value) + public String newID(String value) throws IllegalStateException, IllegalArgumentException { if (value == null) { @@ -252,14 +252,14 @@ public class IDPattern { // Otherwise, if the supplied ID entirely matches the pattern, // split the ID into its components and store those values in - // each of the pattern's IDParts. - IDPart currentPart; + // each of the pattern's IDGeneratorParts. + IDGeneratorPart currentPart; for (int i = 1; i <= (matcher.groupCount() - 1); i++) { currentPart = this.parts.get(i - 1); currentPart.setCurrentID(matcher.group(i)); } - // Obtain the last (least significant) IDPart, + // Obtain the last (least significant) IDGeneratorPart, // and call its nextID() method, which will // concurrently set the current value of that ID // to the next ID. @@ -269,9 +269,9 @@ public class IDPattern { int lastPartNum = this.parts.size() - 1; this.parts.get(lastPartNum).nextID(); - // Then call the getCurrentID() method on all of the IDParts + // Then call the getCurrentID() method on all of the IDGeneratorParts StringBuffer sb = new StringBuffer(); - for (IDPart part : this.parts) { + for (IDGeneratorPart part : this.parts) { sb.append(part.getCurrentID()); } @@ -300,7 +300,7 @@ public class IDPattern { // Returns a regular expression to validate this ID. public String getRegex() { StringBuffer sb = new StringBuffer(); - for (IDPart part : this.parts) { + for (IDGeneratorPart part : this.parts) { sb.append(part.getRegex()); } return sb.toString(); diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDGenerator.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDGenerator.java index f9c69b2e6..829e6a964 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/IDGenerator.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/IDGenerator.java @@ -1,8 +1,4 @@ - /* - * IDGenerator - * - * Interface for a generator class that returns IDs. - * +/** * This document is a part of the source code and related artifacts * for CollectionSpace, an open source collections management system * for museums and related institutions: @@ -23,35 +19,29 @@ * $LastChangedDate$ */ -// @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; +/** + * IDGenerator, interface for an IDGenerator, which returns identifiers (IDs). + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ public interface IDGenerator { - - // Returns the initial value of the ID. - public String getInitialID(); - // Gets the current value of an ID. - public String getCurrentID(); - - // Sets the current value of an ID. - public void setCurrentID(String value) throws IllegalArgumentException; + /** + * Returns a new identifier (ID). + */ + public String newID(); - // Resets an ID to its initial value. - public void resetID(); + /** + * Returns a new identifier (ID), based on a supplied identifier. + */ + public String newID(String id); - // Returns the next ID in the sequence, and sets - // the current value to that ID. - public String nextID() throws IllegalStateException; - - // Validates an ID against a pattern of generated IDs. - public boolean isValidID(String value); + /** + * Returns the current identifier (ID). + */ + public String getCurrentID(); - // Returns a String representation of the regular expression ("regex") - // pattern used to validate instance values of generated IDs. - public String getRegex(); - } diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorPart.java new file mode 100644 index 000000000..b76a12f97 --- /dev/null +++ b/services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorPart.java @@ -0,0 +1,51 @@ + /* + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright © 2009 Regents of the University of California + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + */ + + /* + * IDGeneratorPart, interface for a component part of an ID Generator. + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ +package org.collectionspace.services.id; + +public interface IDGeneratorPart { + + // Returns the initial value of the ID. + public String getInitialID(); + + // Gets the current value of an ID. + public String getCurrentID(); + + // Sets the current value of an ID. + public void setCurrentID(String value) throws IllegalArgumentException; + + // Resets an ID to its initial value. + public void resetID(); + + // Returns the next ID in the sequence, and sets + // the current value to that ID. + public String nextID() throws IllegalStateException; + + // Validates an ID against a pattern of generated IDs. + public boolean isValidID(String value); + + // Returns a String representation of the regular expression ("regex") + // pattern used to validate instance values of generated IDs. + public String getRegex(); + +} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorSerializer.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorSerializer.java index ada47f8bc..fcb95a352 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorSerializer.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorSerializer.java @@ -30,20 +30,13 @@ import com.thoughtworks.xstream.io.xml.DomDriver; /** * IDGeneratorSerializer * - * Serializer and deserializer for ID patterns. + * Serializer and deserializer for ID generators. * - * $LastChangedBy: aron $ * $LastChangedRevision: 414 $ * $LastChangedDate$ */ public class IDGeneratorSerializer { - // *IMPORTANT* - // @TODO: This class is in an early state of a refactoring to - // reflect a change from IDPatterns to IDGenerators at the top level - // of the ID Service. As a result, there will be some naming - // inconsistencies throughout this source file. - ////////////////////////////////////////////////////////////////////// /** * Constructor (no-argument). @@ -53,17 +46,19 @@ public class IDGeneratorSerializer { ////////////////////////////////////////////////////////////////////// /** - * Serializes an ID generator, converting it from a Java object into an XML representation. + * Serializes an ID generator, converting it from a Java object + * into an XML representation. * - * @param pattern An ID generator. + * @param generator An ID generator. * * @return A serialized representation of that ID generator. * * @throws IllegalArgumentException if the ID generator cannot be serialized. */ - public static String serialize(IDPattern pattern) throws IllegalArgumentException { + public static String serialize(BaseIDGenerator generator) + throws IllegalArgumentException { - if (pattern == null) { + if (generator == null) { throw new IllegalArgumentException("ID generator cannot be null."); } @@ -71,10 +66,10 @@ public class IDGeneratorSerializer { String serializedGenerator = ""; try { - serializedGenerator = xstream.toXML(pattern); + serializedGenerator = xstream.toXML(generator); } catch (XStreamException e) { throw new IllegalArgumentException( - "Could not convert ID pattern to XML for storage in database."); + "Could not convert ID generator to XML for storage in database."); } return serializedGenerator; @@ -92,7 +87,7 @@ public class IDGeneratorSerializer { * * @throws IllegalArgumentException if the ID generator cannot be deserialized. */ - public static IDPattern deserialize(String serializedGenerator) + public static BaseIDGenerator deserialize(String serializedGenerator) throws IllegalArgumentException { if (serializedGenerator == null || serializedGenerator.equals("")) { @@ -101,15 +96,15 @@ public class IDGeneratorSerializer { XStream xstream = new XStream(new DomDriver()); - IDPattern pattern; + BaseIDGenerator generator; try { - pattern = (IDPattern) xstream.fromXML(serializedGenerator); + generator = (BaseIDGenerator) xstream.fromXML(serializedGenerator); } catch (XStreamException e) { throw new IllegalArgumentException( "Could not understand or parse this representation of an ID generator."); } - return pattern; + return generator; } diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDPart.java deleted file mode 100644 index cde6f105a..000000000 --- a/services/id/service/src/main/java/org/collectionspace/services/id/IDPart.java +++ /dev/null @@ -1,92 +0,0 @@ - /* - * IDPart - * - *

Models a part of an identifier (ID).

- * - *

Some representative examples of data that can be - * managed within IDParts include:

- * - *
    - *
  • Incrementing numeric or alphabetic values
  • - *
  • Date values
  • - *
  • Static separators
  • - *
- * - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ - */ - -// @TODO: Add Javadoc comments - -package org.collectionspace.services.id; - -public abstract class IDPart { - - // A generator for the types of IDs that are generated by this part. - // This generator is passed in at construction time. - protected IDGenerator generator; - - // Constructor - public IDPart(IDGenerator idGenerator) throws IllegalArgumentException { - this.generator = idGenerator; - } - - // Returns the initial value of the ID associated with this IDPart. - public String getInitialID() { - return generator.getInitialID(); - } - - // Returns the current value of the ID associated with this IDPart. - public String getCurrentID() { - return generator.getCurrentID(); - } - - // Sets the current value of the ID associated with this IDPart. - public void setCurrentID(String value) throws IllegalArgumentException { - generator.setCurrentID(value); - } - - // Resets the ID associated with this IDPart to its initial value. - public void resetID() { - generator.resetID(); - } - - // Returns the next ID in the sequence, and sets the current value - // of the ID associated with this IDPart to that next ID. - public String nextID() throws IllegalStateException { - return generator.nextID(); - } - - // Validates a supplied ID against the pattern of this IDPart. - // - // Some IDParts may offer generic validation, - // while others may offer per-instance valiadation - // based on the values, series, etc. that are - // stored within those parts. - public boolean isValidID(String value) throws IllegalArgumentException { - return generator.isValidID(value); - } - - // Returns a String representation of the regular expression ("regex") - // pattern used to validate instance values of this IDPart. - public String getRegex() { - return generator.getRegex(); - } - -} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDResource.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDResource.java index 56e757dcd..0ad1b6f5b 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/IDResource.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/IDResource.java @@ -13,8 +13,6 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * Based in part on work by Richard Millet and Sanjay Dalal. */ package org.collectionspace.services.id; @@ -33,145 +31,137 @@ import javax.xml.bind.Marshaller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -// Set the base path component for URLs that access this service. -@Path("/idgenerators") - -// Identify the default MIME media types consumed and produced by this service. -@Consumes(MediaType.APPLICATION_XML) -@Produces(MediaType.APPLICATION_XML) - /** * IDResource * * Resource class to handle requests to the ID Service. * - * $LastChangedBy$ * $LastChangedRevision$ * $LastChangedDate$ */ +// Set the base path component for URLs that access this service. +@Path("/idgenerators") +// Identify the default MIME media types consumed and produced by this service. +@Consumes(MediaType.TEXT_PLAIN) +@Produces(MediaType.TEXT_PLAIN) public class IDResource { - final Logger logger = LoggerFactory.getLogger(IDResource.class); + final Logger logger = LoggerFactory.getLogger(IDResource.class); - // @TODO Determine if this is pertinent here: - // Per Richard's comment in the CollectionObject Resource class, from which - // this class was derived: "This should be a DI wired by a container like - // Spring, Seam, or EJB3." - - final static IDService service = new IDServiceJdbcImpl(); + final static IDService service = new IDServiceJdbcImpl(); - ////////////////////////////////////////////////////////////////////// - /** - * Constructor (no argument). - */ - public IDResource() { - // do nothing - } + ////////////////////////////////////////////////////////////////////// + /** + * Constructor (no argument). + */ + public IDResource() { + // do nothing + } - ////////////////////////////////////////////////////////////////////// - /** - * Placeholder for retrieving list of available ID Generators. - * Currently returns an empty entity body. - * - * Implemented to facilitate a HEAD method test in ServicesTest - * - * @return An empty entity body (for now). - */ - @GET - @Path("") - @Produces("text/plain") - public Response getIDGenerators() { - - logger.debug("> in getIDGenerators()"); - - // @TODO Replace this placeholder code. - Response response = Response.status(Response.Status.NO_CONTENT) - .entity("").type(MediaType.TEXT_PLAIN).build(); - - return response; + ////////////////////////////////////////////////////////////////////// + /** + * Placeholder for retrieving list of available ID Generators. + * Currently returns an empty entity body. + * + * Implemented to facilitate a HEAD method test in ServicesTest + * + * @return An empty entity body (for now). + */ + @GET + @Path("") + public Response getIDGenerators() { + + logger.debug("> in getIDGenerators()"); + + // @TODO Replace this placeholder code. + Response response = Response.status(Response.Status.NO_CONTENT) + .entity("").type(MediaType.TEXT_PLAIN).build(); + + return response; } - ////////////////////////////////////////////////////////////////////// - /** - * Generates and returns a new ID, from the specified ID generator. - * - * @param csid An identifier for an ID generator. - * - * @return A new ID from the specified ID generator. - */ - @POST - @Path("/{csid}/ids") - @Produces("text/plain") - public Response newID(@PathParam("csid") String csid) { - - logger.debug("> in newID(String)"); - - // @TODO The JavaDoc description reflects an as-yet-to-be-carried out - // refactoring, in which the highest object type in the ID service - // is that of an IDGenerator, some or all of which may be composed - // of IDParts. Some IDGenerators generate IDs based on patterns, - // which may be composed in part of incrementing numeric or alphabetic - // components, while others may not (e.g. UUIDs, web services-based - // responses). + ////////////////////////////////////////////////////////////////////// + /** + * Generates and returns a new ID, from the specified ID generator. + * + * @param csid An identifier for an ID generator. + * + * @return A new ID from the specified ID generator. + */ + @POST + @Path("/{csid}/ids") + public Response newID(@PathParam("csid") String csid) { - // @TODO We're currently using simple integer IDs to identify ID generators - // in this initial iteration. - // - // To uniquely identify ID generators in production, we'll need to handle - // both CollectionSpace IDs (csids) - a form of UUIDs/GUIDs - and some - // other form of identifier to be determined, such as URLs or URNs. + logger.debug("> in newID(String)"); - // @TODO We're currently returning IDs in plain text. Identify whether - // there is a requirement to return an XML representation, and/or any - // other representations. - - // Unless the 'response' variable is explicitly initialized here, - // the compiler gives the error: "variable response might not have - // been initialized." - Response response = null; - response = response.ok().build(); - String newId = ""; - - try { - - // Obtain a new ID from the specified ID generator, - // and return it in the entity body of the response. - newId = service.newID(csid); - - if (newId == null || newId.equals("")) { - response = Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity("ID Service returned null or empty ID").type(MediaType.TEXT_PLAIN).build(); + // @TODO The JavaDoc description reflects an as-yet-to-be-carried out + // refactoring, in which the highest object type in the ID service + // is that of an IDGenerator, some or all of which may be composed + // of IDParts. Some IDGenerators generate IDs based on patterns, + // which may be composed in part of incrementing numeric or alphabetic + // components, while others may not (e.g. UUIDs, web services-based + // responses). + + // @TODO We're currently using simple integer IDs to identify ID generators + // in this initial iteration. + // + // To uniquely identify ID generators in production, we'll need to handle + // both CollectionSpace IDs (csids) - a form of UUIDs/GUIDs - and some + // other form of identifier to be determined, such as URLs or URNs. + + // @TODO We're currently returning IDs in plain text. Identify whether + // there is a requirement to return an XML representation, and/or any + // other representations. + + // Unless the 'response' variable is explicitly initialized here, + // the compiler gives the error: "variable response might not have + // been initialized." + Response response = null; + response = response.ok().build(); + String newId = ""; + + try { + + // Obtain a new ID from the specified ID generator, + // and return it in the entity body of the response. + newId = service.newID(csid); + + if (newId == null || newId.equals("")) { + response = Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity("ID Service returned null or empty ID") + .type(MediaType.TEXT_PLAIN) + .build(); + return response; + } + + response = Response.status(Response.Status.OK) + .entity(newId).type(MediaType.TEXT_PLAIN).build(); + + // @TODO Return an XML-based error results format with the + // responses below. + + // @TODO An IllegalStateException often indicates an overflow + // of an IDPart. Consider whether returning a 400 Bad Request + // status code is still warranted, or whether returning some other + // status would be more appropriate. + + } catch (IllegalStateException ise) { + response = Response.status(Response.Status.BAD_REQUEST) + .entity(ise.getMessage()).type(MediaType.TEXT_PLAIN).build(); + + } catch (IllegalArgumentException iae) { + response = Response.status(Response.Status.BAD_REQUEST) + .entity(iae.getMessage()).type(MediaType.TEXT_PLAIN).build(); + + // This is guard code that should never be reached. + } catch (Exception e) { + response = Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build(); + } + return response; - } - - response = Response.status(Response.Status.OK) - .entity(newId).type(MediaType.TEXT_PLAIN).build(); - - // @TODO Return an XML-based error results format with the - // responses below. - - // @TODO An IllegalStateException often indicates an overflow - // of an IDPart. Consider whether returning a 400 Bad Request - // status code is still warranted, or whether returning some other - // status would be more appropriate. - - } catch (IllegalStateException ise) { - response = Response.status(Response.Status.BAD_REQUEST) - .entity(ise.getMessage()).type(MediaType.TEXT_PLAIN).build(); - - } catch (IllegalArgumentException iae) { - response = Response.status(Response.Status.BAD_REQUEST) - .entity(iae.getMessage()).type(MediaType.TEXT_PLAIN).build(); - - // This is guard code that should never be reached. - } catch (Exception e) { - response = Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build(); - } - - return response; - - } + + } } diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDServiceJdbcImpl.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDServiceJdbcImpl.java index 8b182af49..da5c69f94 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/IDServiceJdbcImpl.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/IDServiceJdbcImpl.java @@ -16,11 +16,6 @@ */ // *IMPORTANT* -// @TODO: This class is in an early state of a refactoring to -// reflect a change from IDPatterns to IDGenerators at the top level -// of the ID Service. As a result, there will be some naming -// inconsistencies throughout this source file. - // @TODO Revise exception handling to return custom Exceptions, // perhaps mirroring the subset of HTTP status codes returned. // @@ -50,7 +45,7 @@ // @TODO Handle concurrency. // // Right now, with each new request we're simply instantiating -// a new IDPattern and returning its next ID. As a result, +// a new BaseIDGenerator and returning its next ID. As a result, // the generated IDs may well duplicate other, previously-generated IDs. // // When we start storing ID generators and IDs in a database, @@ -299,40 +294,41 @@ public class IDServiceJdbcImpl implements IDService { // Guard code - should not be needed. if (serializedGenerator == null || serializedGenerator.equals("")) { throw new IllegalArgumentException( - "Pattern with ID " + "\'" + csid + "\'" + " could not be found."); + "ID generator " + "\'" + csid + "\'" + " could not be found."); } - IDPattern pattern; + BaseIDGenerator generator; try { - pattern = IDGeneratorSerializer.deserialize(serializedGenerator); + generator = IDGeneratorSerializer.deserialize(serializedGenerator); } catch (IllegalArgumentException e) { throw e; } try { - // Retrieve the last ID associated with this pattern from persistent storage. + // Retrieve the last ID associated with this generator + // from persistent storage. lastId = getLastID(csid); - // If there was no last generated ID associated with this pattern, + // If there was no last generated ID associated with this generator, // get the current ID generated by the ID generator as the 'new' ID. if (lastId == null || lastId.equals("")) { - newId = pattern.getCurrentID(); + newId = generator.getCurrentID(); // Otherwise, generate a new ID, potentially based on the last ID. // (This also sets the current ID of the ID generator's state // to this just-generated 'new' ID.) } else { - newId = pattern.nextID(lastId); + newId = generator.newID(lastId); } - // Store the 'new' ID as the last-generated ID for this pattern. + // Store the 'new' ID as the last-generated ID for this generator. updateLastID(csid, newId); // Store the new state of this ID generator, reflecting that // one of its parts may possibly have had its value updated as // a result of the generation of this 'new' ID. - updateIDGenerator(csid, pattern); + updateIDGenerator(csid, generator); } catch (IllegalArgumentException e ) { throw e; @@ -351,7 +347,7 @@ public class IDServiceJdbcImpl implements IDService { * * @param csid An identifier for an ID generator. * - * @param pattern An ID Pattern, including the values of its constituent parts. + * @param generator An ID generator, including the values of its constituent parts. * * @param lastId The value of the last-generated ID associated with that ID generator. * @@ -380,7 +376,7 @@ public class IDServiceJdbcImpl implements IDService { if (rowsUpdated != 1) { throw new IllegalStateException( - "Error updating last-generated ID in the database for ID Pattern '" + csid + "'"); + "Error updating last-generated ID in the database for ID generator '" + csid + "'"); } logger.debug("> successfully updated last-generated ID: " + lastId); @@ -434,7 +430,7 @@ public class IDServiceJdbcImpl implements IDService { boolean moreRows = rs.next(); if (! moreRows) { throw new IllegalArgumentException( - "Pattern with ID " + "\'" + csid + "\'" + " could not be found."); + "ID generator " + "\'" + csid + "\'" + " could not be found."); } lastId = rs.getString(1); @@ -467,25 +463,25 @@ public class IDServiceJdbcImpl implements IDService { * * @param csid An identifier for an ID generator. * - * @param pattern An ID generator, reflecting its current state, + * @param generator An ID generator, reflecting its current state, * including the values of its constituent parts. * * @throws IllegalStateException if a storage-related error occurred. */ - public void addIDGenerator(String csid, IDPattern pattern) + public void addIDGenerator(String csid, BaseIDGenerator generator) throws IllegalArgumentException, IllegalStateException { - logger.debug("> in addIDGenerator(String, IDPattern)"); + logger.debug("> in addIDGenerator(String, BaseIDGenerator)"); // @TODO: Add checks for authorization to perform this operation. - if (pattern == null) { + if (generator == null) { throw new IllegalArgumentException("New ID generator to add cannot be null."); } String serializedGenerator = ""; try { - serializedGenerator = IDGeneratorSerializer.serialize(pattern); + serializedGenerator = IDGeneratorSerializer.serialize(generator); } catch (IllegalArgumentException e) { throw e; } @@ -536,7 +532,7 @@ public class IDServiceJdbcImpl implements IDService { // Test whether this ID generator already exists in the database. // - // @TODO This check should extend further, to other aspects of the pattern, + // @TODO This check should extend further, to other aspects of the generator, // such as its URI, if any, and its structure. ResultSet rs = stmt.executeQuery( "SELECT id_generator_csid FROM id_generators WHERE id_generator_csid='" + csid + "'"); @@ -554,7 +550,7 @@ public class IDServiceJdbcImpl implements IDService { // occurred, so that this status can be reported to the client. if (idGeneratorFound) { throw new IllegalStateException( - "Conflict with existing pattern when attempting to add new ID generator with ID '" + + "Conflict with existing generator when attempting to add new ID generator with ID '" + csid + "' to the database."); @@ -583,7 +579,7 @@ public class IDServiceJdbcImpl implements IDService { } // end if (idGeneratorFound) - logger.debug("> successfully added ID Pattern: " + csid); + logger.debug("> successfully added ID generator: " + csid); } catch (SQLException e) { throw new IllegalStateException("Error adding new ID generator to the database: " + e.getMessage()); @@ -605,26 +601,26 @@ public class IDServiceJdbcImpl implements IDService { * * @param csid An identifier for an ID generator. * - * @param pattern An ID generator, reflecting its current state, + * @param generator An ID generator, reflecting its current state, * including the values of its constituent parts. * * @throws IllegalStateException if a storage-related error occurred. */ - public void updateIDGenerator(String csid, IDPattern pattern) + public void updateIDGenerator(String csid, BaseIDGenerator generator) throws IllegalArgumentException, IllegalStateException { - logger.debug("> in updateIDGenerator(String, IDPattern)"); + logger.debug("> in updateIDGenerator(String, BaseIDGenerator)"); // @TODO: Add checks for authorization to perform this operation. - if (pattern == null) { + if (generator == null) { throw new IllegalArgumentException( - "ID generator supplied in an attempt to update an existing ID generator cannot be null."); + "ID generator provided in update operation cannot be null."); } String serializedGenerator = ""; try { - serializedGenerator = IDGeneratorSerializer.serialize(pattern); + serializedGenerator = IDGeneratorSerializer.serialize(generator); } catch (IllegalArgumentException e) { throw e; } @@ -642,7 +638,7 @@ public class IDServiceJdbcImpl implements IDService { ////////////////////////////////////////////////////////////////////// /** * Updates an existing ID generator in persistent storage, - * from a serialization of the current state of that pattern. + * from a serialization of the current state of that generator. * * The serialization method recognized by this method has implementation * dependencies. Currently, this method expects serialization via XStream's @@ -650,7 +646,7 @@ public class IDServiceJdbcImpl implements IDService { * * @param csid An identifier for an ID generator. * - * @param serializedGenerator A serialized ID Pattern, reflecting its current state, + * @param serializedGenerator A serialized ID generator, reflecting its current state, * including the values of its constituent parts. * * @throws IllegalStateException if a storage-related error occurred. @@ -693,13 +689,13 @@ public class IDServiceJdbcImpl implements IDService { "last_generated_id = ? " + "WHERE id_generator_csid = ?"; - IDPattern pattern; + BaseIDGenerator generator; try { - pattern = IDGeneratorSerializer.deserialize(serializedGenerator); + generator = IDGeneratorSerializer.deserialize(serializedGenerator); } catch (IllegalArgumentException e) { throw e; } - String lastId = pattern.getCurrentID(); + String lastId = generator.getCurrentID(); PreparedStatement ps = conn.prepareStatement(SQL_STATEMENT_STRING); ps.setString(1, serializedGenerator); @@ -888,7 +884,7 @@ public class IDServiceJdbcImpl implements IDService { } } - logger.debug("> retrieved IDGenerator: " + serializedGenerator); + logger.debug("> retrieved BaseIDGenerator: " + serializedGenerator); return serializedGenerator; diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGenerator.java b/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGenerator.java deleted file mode 100644 index 2369a9b8f..000000000 --- a/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGenerator.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * NumericIDGenerator - * - * Generates identifiers (IDs) that consist of a sequence of - * numeric values, beginning from an initial value. - * - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ - */ - -// @TODO: Add Javadoc comments - -// @TODO: Need to set and enforce maximum value. - -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; - - final static private int DEFAULT_INITIAL_VALUE = 1; - private long initialValue = DEFAULT_INITIAL_VALUE; - private long currentValue = DEFAULT_INITIAL_VALUE; - - // Constructor using defaults for initial value and maximum length. - public NumericIDGenerator() throws IllegalArgumentException { - this(Integer.toString(DEFAULT_INITIAL_VALUE), Integer.toString(DEFAULT_MAX_LENGTH)); - } - - // Constructor using default maximum length. - public NumericIDGenerator(String initialValue) throws IllegalArgumentException { - this(initialValue, Integer.toString(DEFAULT_MAX_LENGTH)); - } - - // Constructor. - public NumericIDGenerator(String initialValue, String maxLength) - throws IllegalArgumentException { - - if (initialValue == null || initialValue.equals("")) { - throw new IllegalArgumentException("Initial ID value must not be null or empty"); - } - - try { - long l = Long.parseLong(initialValue.trim()); - if ( l < 0 ) { - throw new IllegalArgumentException("Initial ID value should be zero (0) or greater"); - } - this.currentValue = l; - this.initialValue = l; - } catch (NullPointerException e) { - throw new IllegalArgumentException("Initial ID value should not be null"); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Initial ID value must be parseable as a number"); - } - - if (maxLength == null || maxLength.equals("")) { - throw new IllegalArgumentException("Initial ID value must not be null or empty"); - } - - try { - this.maxLength = Integer.parseInt(maxLength); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Maximum ID length must be parseable as a number"); - } - - } - - public String getInitialID() { - return Long.toString(this.initialValue); - } - - public String getCurrentID() { - return Long.toString(this.currentValue); - } - - // Sets the current value of the ID. - public void setCurrentID(String value) throws IllegalArgumentException { - - // @TODO Much of this code is copied from the main constructor, - // and may be ripe for refactoring. - - if (value == null || value.equals("")) { - throw new IllegalArgumentException("ID value must not be null or empty"); - } - - try { - long l = Long.parseLong(value.trim()); - if ( l < 0 ) { - throw new IllegalArgumentException("ID value should be zero (0) or greater"); - } - this.currentValue = l; - this.initialValue = l; - } catch (NullPointerException e) { - throw new IllegalArgumentException("ID value should not be null"); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("ID value must be parseable as a number"); - } - - // @TODO An expedient; we may need to check the String length of the - // provided ID and calculate a maximum length here. - this.maxLength = DEFAULT_MAX_LENGTH; - } - - public void resetID() { - this.currentValue = this.initialValue; - } - - // Returns the next ID in the sequence, and sets the current value to that ID. - public String nextID() throws IllegalStateException { - 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 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 String getRegex() { - String regex = "(" + "\\d" + "{1," + Integer.toString(this.maxLength) + "}" + ")"; - return regex; - } - -} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGeneratorPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGeneratorPart.java new file mode 100644 index 000000000..6dc5ae05a --- /dev/null +++ b/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGeneratorPart.java @@ -0,0 +1,177 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright © 2009 Regents of the University of California + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * $LastChangedBy$ + * $LastChangedRevision$ + * $LastChangedDate$ + */ + +// @TODO: Add Javadoc comments + +// @TODO: Need to set and enforce maximum value. + +package org.collectionspace.services.id; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * NumericIDGeneratorPart + * + * Generates identifiers (IDs) that consist of a sequence of + * numeric values, beginning from an initial value. + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ +public class NumericIDGeneratorPart implements IDGeneratorPart { + + final static private int DEFAULT_MAX_LENGTH = 6; + private int maxLength = DEFAULT_MAX_LENGTH; + + final static private int DEFAULT_INITIAL_VALUE = 1; + private long initialValue = DEFAULT_INITIAL_VALUE; + private long currentValue = DEFAULT_INITIAL_VALUE; + + // Constructor using defaults for initial value and maximum length. + public NumericIDGeneratorPart() throws IllegalArgumentException { + this(Integer.toString(DEFAULT_INITIAL_VALUE), + Integer.toString(DEFAULT_MAX_LENGTH)); + } + + // Constructor using default maximum length. + public NumericIDGeneratorPart(String initialValue) + throws IllegalArgumentException { + this(initialValue, Integer.toString(DEFAULT_MAX_LENGTH)); + } + + // Constructor. + public NumericIDGeneratorPart(String initialValue, String maxLength) + throws IllegalArgumentException { + + if (initialValue == null || initialValue.equals("")) { + throw new IllegalArgumentException( + "Initial ID value must not be null or empty"); + } + + try { + long l = Long.parseLong(initialValue.trim()); + if ( l < 0 ) { + throw new IllegalArgumentException( + "Initial ID value should be zero (0) or greater"); + } + this.currentValue = l; + this.initialValue = l; + } catch (NullPointerException e) { + throw new IllegalArgumentException( + "Initial ID value should not be null"); + } catch (NumberFormatException e) { + throw new IllegalArgumentException( + "Initial ID value must be parseable as a number"); + } + + if (maxLength == null || maxLength.equals("")) { + throw new IllegalArgumentException( + "Initial ID value must not be null or empty"); + } + + try { + this.maxLength = Integer.parseInt(maxLength); + } catch (NumberFormatException e) { + throw new IllegalArgumentException( + "Maximum ID length must be parseable as a number"); + } + + } + + public String getInitialID() { + return Long.toString(this.initialValue); + } + + public String getCurrentID() { + return Long.toString(this.currentValue); + } + + // Sets the current value of the ID. + public void setCurrentID(String value) throws IllegalArgumentException { + + // @TODO Much of this code is copied from the main constructor, + // and may be ripe for refactoring. + + if (value == null || value.equals("")) { + throw new IllegalArgumentException( + "ID value must not be null or empty"); + } + + try { + long l = Long.parseLong(value.trim()); + if ( l < 0 ) { + throw new IllegalArgumentException( + "ID value should be zero (0) or greater"); + } + this.currentValue = l; + this.initialValue = l; + } catch (NullPointerException e) { + throw new IllegalArgumentException( + "ID value should not be null"); + } catch (NumberFormatException e) { + throw new IllegalArgumentException( + "ID value must be parseable as a number"); + } + + // @TODO An expedient; we may need to check the String length of the + // provided ID and calculate a maximum length here. + this.maxLength = DEFAULT_MAX_LENGTH; + } + + public void resetID() { + this.currentValue = this.initialValue; + } + + // Returns the next ID in the sequence, and sets the current value to that ID. + public String nextID() throws IllegalStateException { + 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 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 String getRegex() { + String regex = + "(" + "\\d" + "{1," + Integer.toString(this.maxLength) + "}" + ")"; + return regex; + } + +} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDPart.java deleted file mode 100644 index bb3e5b02e..000000000 --- a/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDPart.java +++ /dev/null @@ -1,49 +0,0 @@ - /* - * NumericIDPart - * - * Models a part of an identifier (ID) whose values consist of an - * incrementing numeric series, with those values represented as - * String objects. - * - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ - */ - -// @TODO: Add Javadoc comments - -package org.collectionspace.services.id; - -public class NumericIDPart extends IDPart { - - public NumericIDPart() throws IllegalArgumentException { - super(new NumericIDGenerator()); - }; - - // Store the appropriate Numeric ID generator and the base value for this part. - public NumericIDPart(String baseVal) throws IllegalArgumentException { - super(new NumericIDGenerator(baseVal)); - }; - - // Store the appropriate Numeric ID generator, and the base value - // and maximum length for this part. - public NumericIDPart(String baseVal, String maxLength) throws IllegalArgumentException { - super(new NumericIDGenerator(baseVal, maxLength)); - }; - -} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/StringIDGenerator.java b/services/id/service/src/main/java/org/collectionspace/services/id/StringIDGenerator.java deleted file mode 100644 index 98e9b2dde..000000000 --- a/services/id/service/src/main/java/org/collectionspace/services/id/StringIDGenerator.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * StringIDGenerator - * - * Generates identifiers (IDs) that consist of a static String value. - * - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ - */ - -// @TODO: Add Javadoc comments - -// @TODO: Need to set and enforce maximum String length. - -package org.collectionspace.services.id; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -public class StringIDGenerator implements IDGenerator { - - private String initialValue = null; - private String currentValue = null; - - public StringIDGenerator(String initialValue) throws IllegalArgumentException { - - if (initialValue == null || initialValue.equals("")) { - throw new IllegalArgumentException("Initial ID value must not be null or empty"); - } - - this.initialValue = initialValue; - this.currentValue = initialValue; - - } - - public String getInitialID() { - return this.initialValue; - } - - public String getCurrentID() { - return this.currentValue; - } - - public void setCurrentID(String value) throws IllegalArgumentException { - if (value == null || value.equals("")) { - throw new IllegalArgumentException("ID value must not be null or empty"); - } - this.currentValue = value; - } - - public void resetID() { - // Do nothing - } - - public String nextID() { - return this.currentValue; - } - - public boolean isValidID(String value) { - - if (value == null || value.equals("")) { - return false; - } - - Pattern pattern = Pattern.compile(getRegex()); - Matcher matcher = pattern.matcher(value); - if (matcher.matches()) { - return true; - } else { - return false; - } - - } - - public String getRegex() { - - String initial = this.initialValue; - - // Escape or otherwise modify various characters that have - // significance in regular expressions. - // - // @TODO Test these thoroughly, add processing of more - // special characters as needed. - - // Escape un-escaped period/full stop characters. - Pattern pattern = Pattern.compile("([^\\\\]{0,1})\\."); - Matcher matcher = pattern.matcher(initial); - String escapedInitial = matcher.replaceAll("$1\\\\."); - - String regex = "(" + escapedInitial + ")"; - return regex; - } - -} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/StringIDGeneratorPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/StringIDGeneratorPart.java new file mode 100644 index 000000000..19254a351 --- /dev/null +++ b/services/id/service/src/main/java/org/collectionspace/services/id/StringIDGeneratorPart.java @@ -0,0 +1,113 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright © 2009 Regents of the University of California + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + */ + +// @TODO: Add Javadoc comments + +// @TODO: Need to set and enforce maximum String length. + +package org.collectionspace.services.id; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +/** + * StringIDGeneratorPart + * + * Generates identifiers (IDs) that consist of a static String value. + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ +public class StringIDGeneratorPart implements IDGeneratorPart { + + private String initialValue = null; + private String currentValue = null; + + public StringIDGeneratorPart(String initialValue) + throws IllegalArgumentException { + + if (initialValue == null || initialValue.equals("")) { + throw new IllegalArgumentException( + "Initial ID value must not be null or empty"); + } + + this.initialValue = initialValue; + this.currentValue = initialValue; + + } + + public String getInitialID() { + return this.initialValue; + } + + public String getCurrentID() { + return this.currentValue; + } + + public void setCurrentID(String value) throws IllegalArgumentException { + if (value == null || value.equals("")) { + throw new IllegalArgumentException( + "ID value must not be null or empty"); + } + this.currentValue = value; + } + + public void resetID() { + // Do nothing + } + + public String nextID() { + return this.currentValue; + } + + public boolean isValidID(String value) { + + if (value == null || value.equals("")) { + return false; + } + + Pattern pattern = Pattern.compile(getRegex()); + Matcher matcher = pattern.matcher(value); + if (matcher.matches()) { + return true; + } else { + return false; + } + + } + + public String getRegex() { + + String initial = this.initialValue; + + // Escape or otherwise modify various characters that have + // significance in regular expressions. + // + // @TODO Test these thoroughly, add processing of more + // special characters as needed. + + // Escape un-escaped period/full stop characters. + Pattern pattern = Pattern.compile("([^\\\\]{0,1})\\."); + Matcher matcher = pattern.matcher(initial); + String escapedInitial = matcher.replaceAll("$1\\\\."); + + String regex = "(" + escapedInitial + ")"; + return regex; + } + +} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/StringIDPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/StringIDPart.java deleted file mode 100644 index 7fd8981c1..000000000 --- a/services/id/service/src/main/java/org/collectionspace/services/id/StringIDPart.java +++ /dev/null @@ -1,36 +0,0 @@ - /* - * StringIDPart - * - * Models a part of an identifier (ID) that stores and returns a static String value. - * - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ - */ - -// @TODO: Add Javadoc comments - -package org.collectionspace.services.id; - -public class StringIDPart extends IDPart { - - public StringIDPart(String baseVal) { - super(new StringIDGenerator(baseVal)); - }; - -} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/YearIDGenerator.java b/services/id/service/src/main/java/org/collectionspace/services/id/YearIDGeneratorPart.java similarity index 90% rename from services/id/service/src/main/java/org/collectionspace/services/id/YearIDGenerator.java rename to services/id/service/src/main/java/org/collectionspace/services/id/YearIDGeneratorPart.java index 49f42b2d2..286fa843e 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/YearIDGenerator.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/YearIDGeneratorPart.java @@ -1,9 +1,4 @@ -/* - * YearIDGenerator - * - * Generates identifiers (IDs) that store and returns the current year - * or a supplied year as a String object. - * +/** * This document is a part of the source code and related artifacts * for CollectionSpace, an open source collections management system * for museums and related institutions: @@ -18,10 +13,6 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ */ // @TODO: Add Javadoc comments @@ -51,12 +42,21 @@ import java.util.GregorianCalendar; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class YearIDGenerator implements IDGenerator { +/** + * YearIDGeneratorPart + * + * Generates identifiers (IDs) that store and returns the current year + * or a supplied year as a String object. + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ +public class YearIDGeneratorPart implements IDGeneratorPart { private String initialValue = null; private String currentValue = null; - public YearIDGenerator() throws IllegalArgumentException { + public YearIDGeneratorPart() throws IllegalArgumentException { String currentYear = getCurrentYear(); this.initialValue = currentYear; @@ -64,10 +64,12 @@ public class YearIDGenerator implements IDGenerator { } - public YearIDGenerator(String initialValue) throws IllegalArgumentException { + public YearIDGeneratorPart(String initialValue) + throws IllegalArgumentException { if (initialValue == null || initialValue.equals("")) { - throw new IllegalArgumentException("Initial ID value must not be null or empty"); + throw new IllegalArgumentException( + "Initial ID value must not be null or empty"); } // @TODO: Add regex-based validation here, by calling isValidID(). @@ -114,11 +116,11 @@ public class YearIDGenerator implements IDGenerator { // to a new instant in time. public String nextID() { return this.currentValue; - } + } public static String getCurrentYear() { Calendar cal = GregorianCalendar.getInstance(); - int y = cal.get(Calendar.YEAR); + int y = cal.get(Calendar.YEAR); return Integer.toString(y); } diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/YearIDPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/YearIDPart.java deleted file mode 100644 index d66bfd901..000000000 --- a/services/id/service/src/main/java/org/collectionspace/services/id/YearIDPart.java +++ /dev/null @@ -1,41 +0,0 @@ - /* - * YearIDGenerator - * - * Models a part of an identifier (ID) whose value is the current year - * or a supplied year. - * - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ - */ - -// @TODO: Add Javadoc comments - -package org.collectionspace.services.id; - -public class YearIDPart extends IDPart { - - public YearIDPart() { - super(new YearIDGenerator()); - }; - - public YearIDPart(String baseVal) { - super(new YearIDGenerator(baseVal)); - }; - -} diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/IDPatternTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/IDPatternTest.java deleted file mode 100644 index 27ec02f09..000000000 --- a/services/id/service/src/test/java/org/collectionspace/services/id/IDPatternTest.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * IDPatternTest - * - * Test class for IDPattern. - * - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ - */ - -package org.collectionspace.services.id; - -import static org.junit.Assert.fail; -import java.util.Vector; -import junit.framework.TestCase; - -public class IDPatternTest extends TestCase { - - IDPattern pattern; - IDPart part; - - final static String DEFAULT_CSID = "1"; - - // Note: tests may fail with IllegalArgumentException - // if any initialization of new IDParts fails - // due to invalid arguments passed to their constructors. - - public void testCurrentIDViaVector() { - - Vector parts = new Vector(); - parts.add(new YearIDPart("2009")); - parts.add(new StringIDPart(".")); - parts.add(new NumericIDPart("1")); - parts.add(new StringIDPart("-")); - parts.add(new AlphabeticIDPart("a")); - pattern = new IDPattern(DEFAULT_CSID, parts); - assertEquals("2009.1-a", pattern.getCurrentID()); - - } - - public void testCurrentIDViaAdd() { - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - pattern.add(new StringIDPart("-")); - pattern.add(new AlphabeticIDPart("a")); - assertEquals("2009.1-a", pattern.getCurrentID()); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("0")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("0")); - assertEquals("2009.0.0", pattern.getCurrentID()); - - } - - public void testCurrentIDWithPartialSuppliedID() { - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new StringIDPart("E")); - pattern.add(new NumericIDPart("1")); - assertEquals("E1", pattern.getCurrentID("E")); - assertEquals("E2", pattern.nextID()); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart()); - pattern.add(new StringIDPart(".")); - assertEquals("2009.", pattern.getCurrentID("2009")); - assertEquals("2009.", pattern.nextID()); - assertEquals("2010.", pattern.getCurrentID("2010")); - assertEquals("2010.", pattern.nextID()); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart()); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - assertEquals("2009.1", pattern.getCurrentID("2009.")); - assertEquals("2009.2", pattern.nextID()); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart()); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("55")); - assertEquals("2010.55", pattern.getCurrentID("2010.")); - assertEquals("2010.56", pattern.nextID()); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart()); - assertEquals("2009.1", pattern.getCurrentID("2009.")); - assertEquals("2009.2", pattern.nextID()); - // Test a repeat of the last two operations. - assertEquals("2009.1", pattern.getCurrentID("2009.")); - assertEquals("2009.2", pattern.nextID()); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - pattern.add(new StringIDPart("-")); - pattern.add(new AlphabeticIDPart("a")); - assertEquals("2009.1-a", pattern.getCurrentID("2009.1-")); - assertEquals("2009.1-b", pattern.nextID()); - assertEquals("2009.3-a", pattern.getCurrentID("2009.3-")); - - } - - public void testCurrentIDWithFullSuppliedID() { - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("55")); - assertEquals("2009.55", pattern.getCurrentID("2009.55")); - assertEquals("2009.56", pattern.nextID()); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - pattern.add(new StringIDPart("-")); - pattern.add(new AlphabeticIDPart("a")); - assertEquals("2009.1-a", pattern.getCurrentID("2009.1-a")); - assertEquals("2009.1-b", pattern.nextID()); - - } - - public void testNextID() { - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - assertEquals("2009.2", pattern.nextID()); - assertEquals("2009.3", pattern.nextID()); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - pattern.add(new StringIDPart("-")); - pattern.add(new AlphabeticIDPart("a")); - assertEquals("2009.1-b", pattern.nextID()); - assertEquals("2009.1-c", pattern.nextID()); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new StringIDPart("T")); - pattern.add(new NumericIDPart("1005")); - assertEquals("T1006", pattern.nextID()); - assertEquals("T1007", pattern.nextID()); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - assertEquals("2009.1.2", pattern.nextID()); - - } - - public void testNextIDWithConstantStringID() { - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - pattern.add(new StringIDPart("-")); - assertEquals("2009.1-", pattern.nextID()); - assertEquals("2009.1-", pattern.nextID()); - - } - - public void testNextIDWithSuppliedID() { - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - assertEquals("2009.2", pattern.nextID("2009.1")); - assertEquals("2009.3", pattern.nextID("2009.2")); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - pattern.add(new StringIDPart("-")); - pattern.add(new AlphabeticIDPart("a")); - assertEquals("2009.1-b", pattern.nextID("2009.1-a")); - assertEquals("2009.3-c", pattern.nextID("2009.3-b")); - - } - - public void testEmptyPartsListCurrentID() { - - pattern = new IDPattern(DEFAULT_CSID); - assertEquals("", pattern.getCurrentID()); - - } - - public void testIsValidIDYearPattern() { - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - - assertTrue(pattern.isValidID("2009")); - assertTrue(pattern.isValidID("5555")); - - assertFalse(pattern.isValidID("456")); - assertFalse(pattern.isValidID("10000")); - - } - - - public void testGetRegex() { - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - assertEquals("(\\d{4})(\\.)(\\d{1,6})", pattern.getRegex()); - - } - - public void testIsValidIDYearSeparatorItemPattern() { - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - - assertTrue(pattern.isValidID("2009.1")); - assertTrue(pattern.isValidID("5555.55")); - - assertFalse(pattern.isValidID("456.1")); - assertFalse(pattern.isValidID("2009-1")); - assertFalse(pattern.isValidID("2009.a")); - assertFalse(pattern.isValidID("2009-a")); - assertFalse(pattern.isValidID("non-pattern conforming text")); - - pattern = new IDPattern(DEFAULT_CSID); - pattern.add(new YearIDPart("2009")); - pattern.add(new StringIDPart("ZZ.AND.")); - pattern.add(new NumericIDPart("1")); - - assertTrue(pattern.isValidID("2009ZZ.AND.1")); - assertFalse(pattern.isValidID("2009ZZ-AND-1")); - - } - - // @TODO: Add more tests of boundary conditions, exceptions ... - -} diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/NumericIDPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/NumericIDPartTest.java deleted file mode 100644 index 5cb7089ce..000000000 --- a/services/id/service/src/test/java/org/collectionspace/services/id/NumericIDPartTest.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * NumericIDPartTest - * - * Test class for NumericIDPart. - * - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ - */ - -package org.collectionspace.services.id; - -import static org.junit.Assert.fail; -import junit.framework.TestCase; - -public class NumericIDPartTest extends TestCase { - - IDPart part; - - public void testNextID() { - - part = new NumericIDPart("0"); - assertEquals("1", part.nextID()); - assertEquals("2", part.nextID()); - assertEquals("3", part.nextID()); - - part = new NumericIDPart("25"); - assertEquals("26", part.nextID()); - assertEquals("27", part.nextID()); - assertEquals("28", part.nextID()); - - part = new NumericIDPart(); - assertEquals("2", part.nextID()); - - } - - public void testNextIDOverflow() { - - try { - part = new NumericIDPart("997", "3"); - assertEquals("998", part.nextID()); - assertEquals("999", part.nextID()); - assertEquals("1000", part.nextID()); - 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.nextID()); - assertEquals("999999", part.nextID()); - assertEquals("1000000", part.nextID()); - fail("Should have thrown IllegalStateException here"); - } catch (IllegalStateException expected) { - // This Exception should be thrown, and thus the test should pass. - } - - } - - public void testResetID() { - - part = new NumericIDPart("25"); - assertEquals("26", part.nextID()); - assertEquals("27", part.nextID()); - assertEquals("28", part.nextID()); - part.resetID(); - assertEquals("26", part.nextID()); - - } - - public void testInitialID() { - - part = new NumericIDPart("0"); - assertEquals("0", part.getInitialID()); - - part = new NumericIDPart("25"); - assertEquals("25", part.getInitialID()); - - } - - public void testCurrentID() { - - part = new NumericIDPart("0"); - assertEquals("0", part.getCurrentID()); - assertEquals("1", part.nextID()); - assertEquals("2", part.nextID()); - assertEquals("2", part.getCurrentID()); - assertEquals("3", part.nextID()); - - part = new NumericIDPart("25"); - assertEquals("25", part.getCurrentID()); - - } - - public void testNullInitialValue() { - - try { - part = new NumericIDPart(null); - fail("Should have thrown IllegalArgumentException here"); - } catch (IllegalArgumentException expected) { - // This Exception should be thrown, and thus the test should pass. - } - - } - - public void testNonLongParseableInitialValue() { - - try { - part = new NumericIDPart("not a long parseable value"); - fail("Should have thrown IllegalArgumentException here"); - } catch (IllegalArgumentException expected) { - // This Exception should be thrown, and thus the test should pass. - } - - } - - 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 testNegativeInitialValue() { - - try { - part = new NumericIDPart("-1"); - 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")); - - part = new NumericIDPart("1", "3"); - assertFalse(part.isValidID(null)); - - part = new NumericIDPart("1", "3"); - assertFalse(part.isValidID("")); - - } - - // @TODO: Add more tests of boundary conditions, exceptions ... - -} diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/YearIDPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/YearIDPartTest.java deleted file mode 100644 index 90d6bfb75..000000000 --- a/services/id/service/src/test/java/org/collectionspace/services/id/YearIDPartTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * YearIDPartTest - * - * Test class for YearIDPart. - * - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ - */ - -package org.collectionspace.services.id; - -import static org.junit.Assert.fail; -import java.util.Calendar; -import java.util.GregorianCalendar; -import junit.framework.TestCase; - -public class YearIDPartTest extends TestCase { - - IDPart part; - String year = "1999"; - - public String getCurrentYear() { - Calendar cal = GregorianCalendar.getInstance(); - int y = cal.get(Calendar.YEAR); - return Integer.toString(y); - } - - public void testCurrentID() { - - part = new YearIDPart(); - assertEquals(getCurrentYear(), part.getCurrentID()); - - part = new YearIDPart(year); - assertEquals(year, part.getCurrentID()); - - } - - public void testSetCurrentID() { - - part = new YearIDPart("1999"); - part.setCurrentID("1999"); - assertEquals("1999", part.getCurrentID()); - part.setCurrentID("2000"); - assertEquals("2000", part.getCurrentID()); - - } - - public void testSetCurrentIDNullOrEmpty() { - - part = new YearIDPart(); - - try { - part.setCurrentID(null); - fail("Should have thrown IllegalArgumentException here"); - } catch (IllegalArgumentException expected) { - // This Exception should be thrown, and thus the test should pass. - } - - try { - part.setCurrentID(""); - fail("Should have thrown IllegalArgumentException here"); - } catch (IllegalArgumentException expected) { - // This Exception should be thrown, and thus the test should pass. - } - - } - - public void testNextID() { - - part = new YearIDPart("1999"); - assertEquals("1999", part.nextID()); - - } - - public void testresetID() { - - part = new YearIDPart("1999"); - assertEquals("1999", part.nextID()); - part.resetID(); - assertEquals("1999", part.getCurrentID()); - - } - - public void testInitialID() { - - part = new YearIDPart("1999"); - assertEquals("1999", part.getInitialID()); - - } - - - public void testNullInitialValue() { - - try { - part = new YearIDPart(null); - fail("Should have thrown IllegalArgumentException here"); - } catch (IllegalArgumentException expected) { - // This Exception should be thrown, and thus the test should pass. - } - - } - - public void testEmptyInitialValue() { - - try { - part = new YearIDPart(""); - 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 YearIDPart(); - assertTrue(part.isValidID("2009")); - - part = new YearIDPart(); - assertFalse(part.isValidID("839")); - - part = new YearIDPart(); - assertFalse(part.isValidID("10100")); - - part = new YearIDPart(); - assertFalse(part.isValidID("non-numeric value")); - - part = new YearIDPart(); - assertFalse(part.isValidID(null)); - - part = new YearIDPart(); - assertFalse(part.isValidID("")); - - } - - // @TODO: Add more tests of boundary conditions, exceptions ... - -} diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/AlphabeticIDPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/AlphabeticIDGeneratorPartTest.java similarity index 77% rename from services/id/service/src/test/java/org/collectionspace/services/id/AlphabeticIDPartTest.java rename to services/id/service/src/test/java/org/collectionspace/services/id/test/AlphabeticIDGeneratorPartTest.java index abde5674a..751202acc 100644 --- a/services/id/service/src/test/java/org/collectionspace/services/id/AlphabeticIDPartTest.java +++ b/services/id/service/src/test/java/org/collectionspace/services/id/test/AlphabeticIDGeneratorPartTest.java @@ -1,8 +1,4 @@ -/* - * AlphabeticIDPartTest - * - * Test class for AlphabeticIDPart. - * +/** * This document is a part of the source code and related artifacts * for CollectionSpace, an open source collections management system * for museums and related institutions: @@ -17,10 +13,6 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ */ package org.collectionspace.services.id; @@ -28,17 +20,25 @@ package org.collectionspace.services.id; import static org.junit.Assert.fail; import junit.framework.TestCase; -public class AlphabeticIDPartTest extends TestCase { +/** + * AlphabeticIDGeneratorPartTest + * + * Test class for AlphabeticIDGeneratorPart. + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ +public class AlphabeticIDGeneratorPartTest extends TestCase { - IDPart part; + IDGeneratorPart part; - public void testnextIDLowercase() { + public void testNextIDLowercase() { - part = new AlphabeticIDPart("a"); + part = new AlphabeticIDGeneratorPart("a"); assertEquals("b", part.nextID()); assertEquals("c", part.nextID()); - part = new AlphabeticIDPart("x"); + part = new AlphabeticIDGeneratorPart("x"); assertEquals("y", part.nextID()); assertEquals("z", part.nextID()); @@ -46,11 +46,11 @@ public class AlphabeticIDPartTest extends TestCase { public void testnextIDLowercase2Chars() { - part = new AlphabeticIDPart("aa"); + part = new AlphabeticIDGeneratorPart("aa"); assertEquals("ab", part.nextID()); assertEquals("ac", part.nextID()); - part = new AlphabeticIDPart("zx"); + part = new AlphabeticIDGeneratorPart("zx"); assertEquals("zy", part.nextID()); assertEquals("zz", part.nextID()); @@ -58,7 +58,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testnextIDLowercase2CharsRolloverFirst() { - part = new AlphabeticIDPart("ay"); + part = new AlphabeticIDGeneratorPart("ay"); assertEquals("az", part.nextID()); assertEquals("ba", part.nextID()); assertEquals("bb", part.nextID()); @@ -67,11 +67,11 @@ public class AlphabeticIDPartTest extends TestCase { public void testnextIDUppercase() { - part = new AlphabeticIDPart("A", "Z", "A"); + part = new AlphabeticIDGeneratorPart("A", "Z", "A"); assertEquals("B", part.nextID()); assertEquals("C", part.nextID()); - part = new AlphabeticIDPart("A", "Z", "X"); + part = new AlphabeticIDGeneratorPart("A", "Z", "X"); assertEquals("Y", part.nextID()); assertEquals("Z", part.nextID()); @@ -79,11 +79,11 @@ public class AlphabeticIDPartTest extends TestCase { public void testnextIDUppercase2Chars() { - part = new AlphabeticIDPart("A", "Z", "AA"); + part = new AlphabeticIDGeneratorPart("A", "Z", "AA"); assertEquals("AB", part.nextID()); assertEquals("AC", part.nextID()); - part = new AlphabeticIDPart("A", "Z", "ZX"); + part = new AlphabeticIDGeneratorPart("A", "Z", "ZX"); assertEquals("ZY", part.nextID()); assertEquals("ZZ", part.nextID()); @@ -91,7 +91,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testnextIDUppercase2CharsRolloverFirst() { - part = new AlphabeticIDPart("A", "Z", "AY"); + part = new AlphabeticIDGeneratorPart("A", "Z", "AY"); assertEquals("AZ", part.nextID()); assertEquals("BA", part.nextID()); assertEquals("BB", part.nextID()); @@ -100,7 +100,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testresetIDLowercase() { - part = new AlphabeticIDPart("zx"); + part = new AlphabeticIDGeneratorPart("zx"); assertEquals("zy", part.nextID()); assertEquals("zz", part.nextID()); part.resetID(); @@ -110,7 +110,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testresetIDUppercase() { - part = new AlphabeticIDPart("A", "Z", "RA"); + part = new AlphabeticIDGeneratorPart("A", "Z", "RA"); assertEquals("RB", part.nextID()); assertEquals("RC", part.nextID()); part.resetID(); @@ -120,21 +120,21 @@ public class AlphabeticIDPartTest extends TestCase { public void testInitialLowercase() { - part = new AlphabeticIDPart("aaa"); + part = new AlphabeticIDGeneratorPart("aaa"); assertEquals("aaa", part.getInitialID()); } public void testInitialUppercase() { - part = new AlphabeticIDPart("A", "Z", "AZ"); + part = new AlphabeticIDGeneratorPart("A", "Z", "AZ"); assertEquals("AZ", part.getInitialID()); } public void testCurrentLowercase() { - part = new AlphabeticIDPart("aaa"); + part = new AlphabeticIDGeneratorPart("aaa"); assertEquals("aaa", part.getCurrentID()); assertEquals("aab", part.nextID()); assertEquals("aac", part.nextID()); @@ -145,7 +145,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testCurrentUppercase() { - part = new AlphabeticIDPart("A", "Z", "A"); + part = new AlphabeticIDGeneratorPart("A", "Z", "A"); assertEquals("A", part.getCurrentID()); assertEquals("B", part.nextID()); assertEquals("C", part.nextID()); @@ -156,7 +156,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testOverflowLowercase() { - part = new AlphabeticIDPart("zx"); + part = new AlphabeticIDGeneratorPart("zx"); assertEquals("zy", part.nextID()); assertEquals("zz", part.nextID()); assertEquals("aaa", part.nextID()); @@ -165,7 +165,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testOverflowUppercase() { - part = new AlphabeticIDPart("A", "Z", "X"); + part = new AlphabeticIDGeneratorPart("A", "Z", "X"); assertEquals("Y", part.nextID()); assertEquals("Z", part.nextID()); assertEquals("AA", part.nextID()); @@ -174,7 +174,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testNonAlphabeticInitialValue() { try { - part = new AlphabeticIDPart("&*432"); + part = new AlphabeticIDGeneratorPart("&*432"); fail("Should have thrown IllegalArgumentException here"); } catch (IllegalArgumentException expected) { // This Exception should be thrown, and thus the test should pass. @@ -183,7 +183,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testNullInitialValue() { try { - part = new AlphabeticIDPart(null); + part = new AlphabeticIDGeneratorPart(null); fail("Should have thrown IllegalArgumentException here"); } catch (IllegalArgumentException expected) { // This Exception should be thrown, and thus the test should pass. @@ -192,7 +192,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testEmptyStringInitialValue() { try { - part = new AlphabeticIDPart(""); + part = new AlphabeticIDGeneratorPart(""); fail("Should have thrown IllegalArgumentException here"); } catch (IllegalArgumentException expected) { // This Exception should be thrown, and thus the test should pass. @@ -201,7 +201,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testAllSpaceCharsInitialValue() { try { - part = new AlphabeticIDPart(" "); + part = new AlphabeticIDGeneratorPart(" "); fail("Should have thrown IllegalArgumentException here"); } catch (IllegalArgumentException expected) { // This Exception should be thrown, and thus the test should pass. @@ -210,7 +210,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testIsValidIDDefaultSeries() { - part = new AlphabeticIDPart(); + part = new AlphabeticIDGeneratorPart(); assertTrue(part.isValidID("a")); assertTrue(part.isValidID("z")); @@ -222,7 +222,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testIsValidIDConstrainedLowerCaseSeries() { - part = new AlphabeticIDPart("a", "f", "a"); + part = new AlphabeticIDGeneratorPart("a", "f", "a"); assertTrue(part.isValidID("a")); assertTrue(part.isValidID("b")); @@ -237,7 +237,7 @@ public class AlphabeticIDPartTest extends TestCase { public void testIsValidIDConstrainedUppercaseSeries() { - part = new AlphabeticIDPart("A", "F", "A"); + part = new AlphabeticIDGeneratorPart("A", "F", "A"); assertTrue(part.isValidID("A")); assertTrue(part.isValidID("B")); diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorSerializerTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorSerializerTest.java index 78cac20d0..585d348b2 100644 --- a/services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorSerializerTest.java +++ b/services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorSerializerTest.java @@ -33,67 +33,65 @@ import static org.junit.Assert.*; * * Unit tests of the ID Service's IDGeneratorSerializer class. * - * - * $LastChangedBy: aron $ * $LastChangedRevision: 302 $ * $LastChangedDate$ */ public class IDGeneratorSerializerTest extends TestCase { String serializedGenerator; - IDPattern pattern; + BaseIDGenerator generator; - final static String DEFAULT_CSID = "TEST-1"; + final static String DEFAULT_CSID = "TEST-1"; final static String DEFAULT_SERIALIZED_ID_GENERATOR = - "\n" + + "\n" + " " + DEFAULT_CSID + "\n" + " \n" + " \n" + " \n" + - ""; + ""; - // @TODO We may want to canonicalize (or otherwise normalize) the expected and - // actual XML in these tests, to avoid failures resulting from differences in - // whitespace, etc. - public void testSerializeIDGenerator() { - IDPattern pattern = new IDPattern(DEFAULT_CSID); - assertEquals(DEFAULT_SERIALIZED_ID_GENERATOR, IDGeneratorSerializer.serialize(pattern)); - } + // @TODO We may want to canonicalize (or otherwise normalize) the expected and + // actual XML in these tests, to avoid failures resulting from differences in + // whitespace, etc. + public void testSerializeIDGenerator() { + BaseIDGenerator generator = new BaseIDGenerator(DEFAULT_CSID); + assertEquals(DEFAULT_SERIALIZED_ID_GENERATOR, IDGeneratorSerializer.serialize(generator)); + } - public void testSerializeNullIDGenerator() { - try { - String serializedPattern = IDGeneratorSerializer.serialize(null); - fail("Should have thrown IllegalArgumentException here"); - } catch (IllegalArgumentException expected) { - // This Exception should be thrown, and thus the test should pass. - } - } + public void testSerializeNullIDGenerator() { + try { + String serializedPattern = IDGeneratorSerializer.serialize(null); + fail("Should have thrown IllegalArgumentException here"); + } catch (IllegalArgumentException expected) { + // This Exception should be thrown, and thus the test should pass. + } + } - public void testDeserializeIDGenerator() { - // This test will fail with different hash codes unless we add an IDPattern.equals() - // method that explicitly defines object equality as, for instance, having identical values - // in each of its instance variables. - // IDPattern pattern = IDGeneratorSerializer.deserialize(DEFAULT_SERIALIZED_ID_PATTERN); - // assertEquals(pattern, new IDPattern(DEFAULT_CSID)); - } + public void testDeserializeIDGenerator() { + // This test will fail with different hash codes unless we add an IDGenerator.equals() + // method that explicitly defines object equality as, for instance, having identical values + // in each of its instance variables. + // IDGenerator generator = IDGeneratorSerializer.deserialize(DEFAULT_SERIALIZED_ID_PATTERN); + // assertEquals(generator, new IDGenerator(DEFAULT_CSID)); + } - public void testDeserializeNullSerializedIDGenerator() { - try { - IDPattern pattern = IDGeneratorSerializer.deserialize(null); - fail("Should have thrown IllegalArgumentException here"); - } catch (IllegalArgumentException expected) { - // This Exception should be thrown, and thus the test should pass. - } - } + public void testDeserializeNullSerializedIDGenerator() { + try { + BaseIDGenerator generator = IDGeneratorSerializer.deserialize(null); + fail("Should have thrown IllegalArgumentException here"); + } catch (IllegalArgumentException expected) { + // This Exception should be thrown, and thus the test should pass. + } + } - public void testDeserializeInvalidSerializedIDGenerator() { - try { - IDPattern pattern = IDGeneratorSerializer.deserialize(""); - fail("Should have thrown IllegalArgumentException here"); - } catch (IllegalArgumentException expected) { - // This Exception should be thrown, and thus the test should pass. - } - } - + public void testDeserializeInvalidSerializedIDGenerator() { + try { + IDGenerator generator = IDGeneratorSerializer.deserialize(""); + fail("Should have thrown IllegalArgumentException here"); + } catch (IllegalArgumentException expected) { + // This Exception should be thrown, and thus the test should pass. + } + } + } diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorTest.java new file mode 100644 index 000000000..50a484a5c --- /dev/null +++ b/services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorTest.java @@ -0,0 +1,271 @@ +/* + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright © 2009 Regents of the University of California + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + */ + +package org.collectionspace.services.id; + +import static org.junit.Assert.fail; +import java.util.Vector; +import junit.framework.TestCase; + +/** + * IDGeneratorTest, Test class for IDGenerator. + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ +public class IDGeneratorTest extends TestCase { + + BaseIDGenerator generator; + IDGeneratorPart part; + + final static String DEFAULT_CSID = "1"; + + // Note: tests may fail with IllegalArgumentException + // if any initialization of new IDParts fails + // due to invalid arguments passed to their constructors. + + public void testCurrentIDViaVector() { + + Vector parts = new Vector(); + parts.add(new YearIDGeneratorPart("2009")); + parts.add(new StringIDGeneratorPart(".")); + parts.add(new NumericIDGeneratorPart("1")); + parts.add(new StringIDGeneratorPart("-")); + parts.add(new AlphabeticIDGeneratorPart("a")); + generator = new BaseIDGenerator(DEFAULT_CSID, parts); + assertEquals("2009.1-a", generator.getCurrentID()); + + } + + public void testCurrentIDViaAdd() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + generator.add(new StringIDGeneratorPart("-")); + generator.add(new AlphabeticIDGeneratorPart("a")); + assertEquals("2009.1-a", generator.getCurrentID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("0")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("0")); + assertEquals("2009.0.0", generator.getCurrentID()); + + } + + public void testCurrentIDWithPartialSuppliedID() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new StringIDGeneratorPart("E")); + generator.add(new NumericIDGeneratorPart("1")); + assertEquals("E1", generator.getCurrentID("E")); + assertEquals("E2", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart()); + generator.add(new StringIDGeneratorPart(".")); + assertEquals("2009.", generator.getCurrentID("2009")); + assertEquals("2009.", generator.newID()); + assertEquals("2010.", generator.getCurrentID("2010")); + assertEquals("2010.", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart()); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + assertEquals("2009.1", generator.getCurrentID("2009.")); + assertEquals("2009.2", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart()); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("55")); + assertEquals("2010.55", generator.getCurrentID("2010.")); + assertEquals("2010.56", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart()); + assertEquals("2009.1", generator.getCurrentID("2009.")); + assertEquals("2009.2", generator.newID()); + // Test a repeat of the last two operations. + assertEquals("2009.1", generator.getCurrentID("2009.")); + assertEquals("2009.2", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + generator.add(new StringIDGeneratorPart("-")); + generator.add(new AlphabeticIDGeneratorPart("a")); + assertEquals("2009.1-a", generator.getCurrentID("2009.1-")); + assertEquals("2009.1-b", generator.newID()); + assertEquals("2009.3-a", generator.getCurrentID("2009.3-")); + + } + + public void testCurrentIDWithFullSuppliedID() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("55")); + assertEquals("2009.55", generator.getCurrentID("2009.55")); + assertEquals("2009.56", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + generator.add(new StringIDGeneratorPart("-")); + generator.add(new AlphabeticIDGeneratorPart("a")); + assertEquals("2009.1-a", generator.getCurrentID("2009.1-a")); + assertEquals("2009.1-b", generator.newID()); + + } + + public void testNewID() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + assertEquals("2009.2", generator.newID()); + assertEquals("2009.3", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + generator.add(new StringIDGeneratorPart("-")); + generator.add(new AlphabeticIDGeneratorPart("a")); + assertEquals("2009.1-b", generator.newID()); + assertEquals("2009.1-c", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new StringIDGeneratorPart("T")); + generator.add(new NumericIDGeneratorPart("1005")); + assertEquals("T1006", generator.newID()); + assertEquals("T1007", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + assertEquals("2009.1.2", generator.newID()); + + } + + public void testNewIDWithConstantStringID() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + generator.add(new StringIDGeneratorPart("-")); + assertEquals("2009.1-", generator.newID()); + assertEquals("2009.1-", generator.newID()); + + } + + public void testNewIDWithSuppliedID() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + assertEquals("2009.2", generator.newID("2009.1")); + assertEquals("2009.3", generator.newID("2009.2")); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + generator.add(new StringIDGeneratorPart("-")); + generator.add(new AlphabeticIDGeneratorPart("a")); + assertEquals("2009.1-b", generator.newID("2009.1-a")); + assertEquals("2009.3-c", generator.newID("2009.3-b")); + + } + + public void testEmptyPartsListCurrentID() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + assertEquals("", generator.getCurrentID()); + + } + + public void testIsValidIDYearPattern() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + + assertTrue(generator.isValidID("2009")); + assertTrue(generator.isValidID("5555")); + + assertFalse(generator.isValidID("456")); + assertFalse(generator.isValidID("10000")); + + } + + + public void testGetRegex() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + assertEquals("(\\d{4})(\\.)(\\d{1,6})", generator.getRegex()); + + } + + public void testIsValidIDYearSeparatorItemPattern() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + + assertTrue(generator.isValidID("2009.1")); + assertTrue(generator.isValidID("5555.55")); + + assertFalse(generator.isValidID("456.1")); + assertFalse(generator.isValidID("2009-1")); + assertFalse(generator.isValidID("2009.a")); + assertFalse(generator.isValidID("2009-a")); + assertFalse(generator.isValidID("non-generator conforming text")); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart("ZZ.AND.")); + generator.add(new NumericIDGeneratorPart("1")); + + assertTrue(generator.isValidID("2009ZZ.AND.1")); + assertFalse(generator.isValidID("2009ZZ-AND-1")); + + } + + // @TODO: Add more tests of boundary conditions, exceptions ... + +} diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/IDServiceJdbcImplTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/IDServiceJdbcImplTest.java index dca62a08b..626352630 100644 --- a/services/id/service/src/test/java/org/collectionspace/services/id/test/IDServiceJdbcImplTest.java +++ b/services/id/service/src/test/java/org/collectionspace/services/id/test/IDServiceJdbcImplTest.java @@ -1,4 +1,4 @@ -/** +/** * This document is a part of the source code and related artifacts * for CollectionSpace, an open source collections management system * for museums and related institutions: @@ -20,163 +20,162 @@ package org.collectionspace.services.id.test; import org.collectionspace.services.id.*; import org.testng.Assert; +import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -/** +/** * IDServiceJdbcImplTest * * Unit tests for the ID Service's JDBC implementation class, IDServiceJdbcImpl. * - * $LastChangedBy: aron $ * $LastChangedRevision: 302 $ * $LastChangedDate$ */ public class IDServiceJdbcImplTest { - // *IMPORTANT* - // @TODO This class is in an early state of a refactoring to - // reflect a change from IDPatterns to IDGenerators at the top level - // of the ID Service. As a result, there will be some naming - // inconsistencies throughout this source file. - - String csid; - String nextId; - String serializedGenerator; - IDPattern pattern; - - IDServiceJdbcImpl jdbc = new IDServiceJdbcImpl(); - IDService service = jdbc; - - final static String TABLE_NAME = "id_generators"; - final static String DEFAULT_CSID = "TEST-1"; - - @Test - public void hasRequiredDatabaseTable() { - Assert.assertTrue( - jdbc.hasTable(TABLE_NAME), - "Table '" + TABLE_NAME + "' must exist in database. " + - "Please first run SQL setup script, 'create_id_generators_table.sql', in 'id' project."); - } - - @Test(dependsOnMethods = {"hasRequiredDatabaseTable"}) - public void addIDGenerator() { - jdbc.addIDGenerator(DEFAULT_CSID, getSpectrumEntryNumberGenerator()); - } - - @Test(dependsOnMethods = {"addIDGenerator"}) - public void readIDGenerator() { - - serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID); - pattern = IDGeneratorSerializer.deserialize(serializedGenerator); - Assert.assertEquals(DEFAULT_CSID, pattern.getCsid()); + String csid; + String nextId; + String serializedGenerator; + BaseIDGenerator generator; - } + IDServiceJdbcImpl jdbc = new IDServiceJdbcImpl(); + IDService service = jdbc; + + final static String TABLE_NAME = "id_generators"; + final static String DEFAULT_CSID = "TEST-1"; + + @Test + public void hasRequiredDatabaseTable() { + Assert.assertTrue( + jdbc.hasTable(TABLE_NAME), + "Table '" + TABLE_NAME + "' must exist in database. " + + "Please first run SQL setup script, " + + "'create_id_generators_table.sql', in 'id' project."); + } - @Test(dependsOnMethods = {"addIDGenerator"}) - public void updateIDGenerator() { + @Test(dependsOnMethods = {"hasRequiredDatabaseTable"}) + public void addIDGenerator() { + jdbc.addIDGenerator(DEFAULT_CSID, getSpectrumEntryNumberGenerator()); + } - final String NEW_DESCRIPTION = "new description"; - - // Retrieve an existing generator, deserialize it, - // update its contents, serialize it, and write it back. - serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID); - pattern = IDGeneratorSerializer.deserialize(serializedGenerator); - pattern.setDescription(NEW_DESCRIPTION); - serializedGenerator = IDGeneratorSerializer.serialize(pattern); - - jdbc.updateIDGenerator(DEFAULT_CSID, serializedGenerator); - - serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID); - pattern = IDGeneratorSerializer.deserialize(serializedGenerator); - - Assert.assertEquals(NEW_DESCRIPTION, pattern.getDescription()); - - } + @Test(dependsOnMethods = {"addIDGenerator"}) + public void readIDGenerator() { - @Test(dependsOnMethods = {"addIDGenerator", "readIDGenerator"}) - public void deleteIDGenerator() { - jdbc.deleteIDGenerator(DEFAULT_CSID); - } - - @Test(dependsOnMethods = {"addIDGenerator", "deleteIDGenerator"}) - public void newIDValidPattern() { - - csid = DEFAULT_CSID; - - try { - jdbc.deleteIDGenerator(csid); - } catch (Exception e) { - // do nothing + serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID); + generator = IDGeneratorSerializer.deserialize(serializedGenerator); + Assert.assertEquals(DEFAULT_CSID, generator.getCsid()); + } - - jdbc.addIDGenerator(csid, getSpectrumEntryNumberGenerator()); - Assert.assertEquals("E1", service.newID("TEST-1")); - Assert.assertEquals("E2", service.newID("TEST-1")); - Assert.assertEquals("E3", service.newID("TEST-1")); - - try { - jdbc.deleteIDGenerator(csid); - } catch (Exception e) { - // do nothing + @Test(dependsOnMethods = {"addIDGenerator"}) + public void updateIDGenerator() { + + final String NEW_DESCRIPTION = "new description"; + + // Retrieve an existing generator, deserialize it, + // update its contents, serialize it, and write it back. + serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID); + generator = IDGeneratorSerializer.deserialize(serializedGenerator); + generator.setDescription(NEW_DESCRIPTION); + serializedGenerator = IDGeneratorSerializer.serialize(generator); + + jdbc.updateIDGenerator(DEFAULT_CSID, serializedGenerator); + + serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID); + generator = IDGeneratorSerializer.deserialize(serializedGenerator); + + Assert.assertEquals(NEW_DESCRIPTION, generator.getDescription()); + } - - jdbc.addIDGenerator(csid, getChinAccessionNumberGenerator()); - String currentYear = YearIDGenerator.getCurrentYear(); - Assert.assertEquals(currentYear + ".1.1", service.newID("TEST-1")); - Assert.assertEquals(currentYear + ".1.2", service.newID("TEST-1")); - Assert.assertEquals(currentYear + ".1.3", service.newID("TEST-1")); + @Test(dependsOnMethods = {"addIDGenerator", "readIDGenerator"}) + public void deleteIDGenerator() { + jdbc.deleteIDGenerator(DEFAULT_CSID); + } + + @Test(dependsOnMethods = {"addIDGenerator", "deleteIDGenerator"}) + public void newIDValidPattern() { + + csid = DEFAULT_CSID; + + try { + jdbc.deleteIDGenerator(csid); + } catch (Exception e) { + // do nothing + } + + jdbc.addIDGenerator(csid, getSpectrumEntryNumberGenerator()); + + Assert.assertEquals("E1", service.newID(csid)); + Assert.assertEquals("E2", service.newID(csid)); + Assert.assertEquals("E3", service.newID(csid)); + + try { + jdbc.deleteIDGenerator(csid); + } catch (Exception e) { + // do nothing + } + + jdbc.addIDGenerator(csid, getChinAccessionNumberGenerator()); + + String currentYear = YearIDGeneratorPart.getCurrentYear(); + Assert.assertEquals(currentYear + ".1.1", service.newID(csid)); + Assert.assertEquals(currentYear + ".1.2", service.newID(csid)); + Assert.assertEquals(currentYear + ".1.3", service.newID(csid)); + + try { + jdbc.deleteIDGenerator(csid); + } catch (Exception e) { + // do nothing + } - try { - jdbc.deleteIDGenerator(csid); - } catch (Exception e) { - // do nothing } - - } - - // This test requires that: - // 1. The ID Service is running and accessible to this test; and - // 2. There is no ID pattern retrievable through that service - // with the identifier 'non-existent identifier'. - @Test(dependsOnMethods = {"hasRequiredDatabaseTable"}, - expectedExceptions = IllegalArgumentException.class) - public void newIDInvalidPattern() { - nextId = service.newID("non-existent identifier"); - } - - // --------------------------------------------------------------- - // Utility methods used by tests above - // --------------------------------------------------------------- - - // @TODO Read test patterns from external configuration. - - public String getSpectrumEntryNumberGenerator() { - - pattern = new IDPattern(DEFAULT_CSID); - pattern.setDescription("SPECTRUM entry number pattern"); - pattern.setURI("urn:collectionspace:idpattern:spectrum-entry-number"); - pattern.add(new StringIDPart("E")); - pattern.add(new NumericIDPart("1")); - - return IDGeneratorSerializer.serialize(pattern); - - } - public String getChinAccessionNumberGenerator() { + // This test requires that: + // 1. The ID Service is running and accessible to this test; and + // 2. There is no ID generator retrievable through that service + // with the identifier 'non-existent identifier'. + @Test(dependsOnMethods = {"hasRequiredDatabaseTable"}, + expectedExceptions = IllegalArgumentException.class) + public void newIDInvalidPattern() { + nextId = service.newID("non-existent identifier"); + } - pattern = new IDPattern(DEFAULT_CSID); - pattern.setDescription("CHIN accession number pattern, for items without parts"); - pattern.setURI("urn:collectionspace:idpattern:chin-accession-number-no-parts"); - pattern.add(new YearIDPart()); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); - pattern.add(new StringIDPart(".")); - pattern.add(new NumericIDPart("1")); + // --------------------------------------------------------------- + // Utility methods used by tests above + // --------------------------------------------------------------- - return IDGeneratorSerializer.serialize(pattern); + // @TODO Read test patterns from external configuration. - } + public String getSpectrumEntryNumberGenerator() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.setDescription( + "SPECTRUM entry number generator"); + generator.setURI( + "urn:collectionspace:idpattern:spectrum-entry-number"); + generator.add(new StringIDGeneratorPart("E")); + generator.add(new NumericIDGeneratorPart("1")); + + return IDGeneratorSerializer.serialize(generator); + + } + + public String getChinAccessionNumberGenerator() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.setDescription( + "CHIN accession number generator, for items without parts"); + generator.setURI( + "urn:collectionspace:idpattern:chin-accession-number-no-parts"); + generator.add(new YearIDGeneratorPart()); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + + return IDGeneratorSerializer.serialize(generator); + + } } diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/NumericIDGeneratorPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/NumericIDGeneratorPartTest.java new file mode 100644 index 000000000..9ecb44c92 --- /dev/null +++ b/services/id/service/src/test/java/org/collectionspace/services/id/test/NumericIDGeneratorPartTest.java @@ -0,0 +1,196 @@ +/* + * NumericIDGeneratorPartTest + * + * Test class for NumericIDGeneratorPart. + * + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright © 2009 Regents of the University of California + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + */ + +package org.collectionspace.services.id; + +import static org.junit.Assert.fail; +import junit.framework.TestCase; + +/** + * NumericIDGeneratorPartTest + * + * Test class for NumericIDGeneratorPart. + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ +public class NumericIDGeneratorPartTest extends TestCase { + + IDGeneratorPart part; + + public void testNextID() { + + part = new NumericIDGeneratorPart("0"); + assertEquals("1", part.nextID()); + assertEquals("2", part.nextID()); + assertEquals("3", part.nextID()); + + part = new NumericIDGeneratorPart("25"); + assertEquals("26", part.nextID()); + assertEquals("27", part.nextID()); + assertEquals("28", part.nextID()); + + part = new NumericIDGeneratorPart(); + assertEquals("2", part.nextID()); + + } + + public void testNextIDOverflow() { + + try { + part = new NumericIDGeneratorPart("997", "3"); + assertEquals("998", part.nextID()); + assertEquals("999", part.nextID()); + assertEquals("1000", part.nextID()); + 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 NumericIDGeneratorPart("999997"); + assertEquals("999998", part.nextID()); + assertEquals("999999", part.nextID()); + assertEquals("1000000", part.nextID()); + fail("Should have thrown IllegalStateException here"); + } catch (IllegalStateException expected) { + // This Exception should be thrown, and thus the test should pass. + } + + } + + public void testResetID() { + + part = new NumericIDGeneratorPart("25"); + assertEquals("26", part.nextID()); + assertEquals("27", part.nextID()); + assertEquals("28", part.nextID()); + part.resetID(); + assertEquals("26", part.nextID()); + + } + + public void testInitialID() { + + part = new NumericIDGeneratorPart("0"); + assertEquals("0", part.getInitialID()); + + part = new NumericIDGeneratorPart("25"); + assertEquals("25", part.getInitialID()); + + } + + public void testCurrentID() { + + part = new NumericIDGeneratorPart("0"); + assertEquals("0", part.getCurrentID()); + assertEquals("1", part.nextID()); + assertEquals("2", part.nextID()); + assertEquals("2", part.getCurrentID()); + assertEquals("3", part.nextID()); + + part = new NumericIDGeneratorPart("25"); + assertEquals("25", part.getCurrentID()); + + } + + public void testNullInitialValue() { + + try { + part = new NumericIDGeneratorPart(null); + fail("Should have thrown IllegalArgumentException here"); + } catch (IllegalArgumentException expected) { + // This Exception should be thrown, and thus the test should pass. + } + + } + + public void testNonLongParseableInitialValue() { + + try { + part = new NumericIDGeneratorPart("not a long parseable value"); + fail("Should have thrown IllegalArgumentException here"); + } catch (IllegalArgumentException expected) { + // This Exception should be thrown, and thus the test should pass. + } + + } + + public void testNonLongParseableMaxLength() { + + try { + part = new NumericIDGeneratorPart("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 testNegativeInitialValue() { + + try { + part = new NumericIDGeneratorPart("-1"); + 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 NumericIDGeneratorPart("1"); + assertTrue(part.isValidID("1")); + + part = new NumericIDGeneratorPart("1"); + assertTrue(part.isValidID("123")); + + part = new NumericIDGeneratorPart("1"); + assertTrue(part.isValidID("123456")); + + part = new NumericIDGeneratorPart("1"); + assertFalse(part.isValidID("1234567")); + + part = new NumericIDGeneratorPart("1", "3"); + assertTrue(part.isValidID("123")); + + part = new NumericIDGeneratorPart("1", "3"); + assertFalse(part.isValidID("1234")); + + part = new NumericIDGeneratorPart("1"); + assertFalse(part.isValidID("not a parseable long")); + + part = new NumericIDGeneratorPart("1", "3"); + assertFalse(part.isValidID("not a parseable long")); + + part = new NumericIDGeneratorPart("1", "3"); + assertFalse(part.isValidID(null)); + + part = new NumericIDGeneratorPart("1", "3"); + assertFalse(part.isValidID("")); + + } + + // @TODO: Add more tests of boundary conditions, exceptions ... + +} diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/StringIDPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/StringIDGeneratorPartTest.java similarity index 69% rename from services/id/service/src/test/java/org/collectionspace/services/id/StringIDPartTest.java rename to services/id/service/src/test/java/org/collectionspace/services/id/test/StringIDGeneratorPartTest.java index 6b26571cd..41eae6832 100644 --- a/services/id/service/src/test/java/org/collectionspace/services/id/StringIDPartTest.java +++ b/services/id/service/src/test/java/org/collectionspace/services/id/test/StringIDGeneratorPartTest.java @@ -1,8 +1,4 @@ -/* - * StringIDPartTest - * - * Test class for StringIDPart. - * +/** * This document is a part of the source code and related artifacts * for CollectionSpace, an open source collections management system * for museums and related institutions: @@ -17,10 +13,6 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ */ package org.collectionspace.services.id; @@ -28,23 +20,31 @@ package org.collectionspace.services.id; import static org.junit.Assert.fail; import junit.framework.TestCase; -public class StringIDPartTest extends TestCase { +/** + * StringIDGeneratorPartTest + * + * Test class for StringIDGeneratorPart. + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ +public class StringIDGeneratorPartTest extends TestCase { - IDPart part; + IDGeneratorPart part; public void testNextID() { - part = new StringIDPart("E"); + part = new StringIDGeneratorPart("E"); assertEquals("E", part.nextID()); - part = new StringIDPart("XYZ"); + part = new StringIDGeneratorPart("XYZ"); assertEquals("XYZ", part.nextID()); } public void testresetID() { - part = new StringIDPart("."); + part = new StringIDGeneratorPart("."); assertEquals(".", part.nextID()); part.resetID(); assertEquals(".", part.nextID()); @@ -52,19 +52,19 @@ public class StringIDPartTest extends TestCase { } public void testInitialID() { - part = new StringIDPart("-"); + part = new StringIDGeneratorPart("-"); assertEquals("-", part.getInitialID()); } public void testCurrentID() { - part = new StringIDPart("- -"); + part = new StringIDGeneratorPart("- -"); assertEquals("- -", part.getCurrentID()); } public void testNullInitialValue() { try { - part = new StringIDPart(null); + part = new StringIDGeneratorPart(null); fail("Should have thrown IllegalArgumentException here"); } catch (IllegalArgumentException expected) { // This Exception should be thrown, and thus the test should pass. @@ -75,7 +75,7 @@ public class StringIDPartTest extends TestCase { public void testEmptyInitialValue() { try { - part = new StringIDPart(""); + part = new StringIDGeneratorPart(""); fail("Should have thrown IllegalArgumentException here"); } catch (IllegalArgumentException expected) { // This Exception should be thrown, and thus the test should pass. @@ -85,30 +85,30 @@ public class StringIDPartTest extends TestCase { public void testIsValidID() { - part = new StringIDPart("-"); + part = new StringIDGeneratorPart("-"); assertTrue(part.isValidID("-")); - part = new StringIDPart("-"); + part = new StringIDGeneratorPart("-"); assertFalse(part.isValidID("--")); // Test chars with special meaning in regexes. - part = new StringIDPart("."); + part = new StringIDGeneratorPart("."); assertTrue(part.isValidID(".")); - part = new StringIDPart("TE"); + part = new StringIDGeneratorPart("TE"); assertTrue(part.isValidID("TE")); - part = new StringIDPart("TE"); + part = new StringIDGeneratorPart("TE"); assertFalse(part.isValidID("T")); - part = new StringIDPart("T"); + part = new StringIDGeneratorPart("T"); assertFalse(part.isValidID("TE")); - part = new StringIDPart("-"); - assertFalse(part.isValidID(null)); - - part = new StringIDPart("-"); - assertFalse(part.isValidID("")); + part = new StringIDGeneratorPart("-"); + assertFalse(part.isValidID(null)); + + part = new StringIDGeneratorPart("-"); + assertFalse(part.isValidID("")); } diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/YearIDGeneratorPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/YearIDGeneratorPartTest.java new file mode 100644 index 000000000..37a0495a3 --- /dev/null +++ b/services/id/service/src/test/java/org/collectionspace/services/id/test/YearIDGeneratorPartTest.java @@ -0,0 +1,154 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright © 2009 Regents of the University of California + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + */ + +package org.collectionspace.services.id; + +import static org.junit.Assert.fail; +import java.util.Calendar; +import java.util.GregorianCalendar; +import junit.framework.TestCase; + +/* + * YearIDGeneratorPartTest + * + * Test class for YearIDGeneratorPart. + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ +public class YearIDGeneratorPartTest extends TestCase { + + IDGeneratorPart part; + final static String year = "1999"; + + public String getCurrentYear() { + Calendar cal = GregorianCalendar.getInstance(); + int y = cal.get(Calendar.YEAR); + return Integer.toString(y); + } + + public void testCurrentID() { + + part = new YearIDGeneratorPart(); + assertEquals(getCurrentYear(), part.getCurrentID()); + + part = new YearIDGeneratorPart(year); + assertEquals(year, part.getCurrentID()); + + } + + public void testSetCurrentID() { + + part = new YearIDGeneratorPart("1999"); + part.setCurrentID("1999"); + assertEquals("1999", part.getCurrentID()); + part.setCurrentID("2000"); + assertEquals("2000", part.getCurrentID()); + + } + + public void testSetCurrentIDNullOrEmpty() { + + part = new YearIDGeneratorPart(); + + try { + part.setCurrentID(null); + fail("Should have thrown IllegalArgumentException here"); + } catch (IllegalArgumentException expected) { + // This Exception should be thrown, and thus the test should pass. + } + + try { + part.setCurrentID(""); + fail("Should have thrown IllegalArgumentException here"); + } catch (IllegalArgumentException expected) { + // This Exception should be thrown, and thus the test should pass. + } + + } + + public void testNextID() { + + part = new YearIDGeneratorPart("1999"); + assertEquals("1999", part.nextID()); + + } + + public void testresetID() { + + part = new YearIDGeneratorPart("1999"); + assertEquals("1999", part.nextID()); + part.resetID(); + assertEquals("1999", part.getCurrentID()); + + } + + public void testInitialID() { + + part = new YearIDGeneratorPart("1999"); + assertEquals("1999", part.getInitialID()); + + } + + + public void testNullInitialValue() { + + try { + part = new YearIDGeneratorPart(null); + fail("Should have thrown IllegalArgumentException here"); + } catch (IllegalArgumentException expected) { + // This Exception should be thrown, and thus the test should pass. + } + + } + + public void testEmptyInitialValue() { + + try { + part = new YearIDGeneratorPart(""); + 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 YearIDGeneratorPart(); + assertTrue(part.isValidID("2009")); + + part = new YearIDGeneratorPart(); + assertFalse(part.isValidID("839")); + + part = new YearIDGeneratorPart(); + assertFalse(part.isValidID("10100")); + + part = new YearIDGeneratorPart(); + assertFalse(part.isValidID("non-numeric value")); + + part = new YearIDGeneratorPart(); + assertFalse(part.isValidID(null)); + + part = new YearIDGeneratorPart(); + assertFalse(part.isValidID("")); + + } + + // @TODO: Add more tests of boundary conditions, exceptions ... + +} -- 2.47.3