From: Aron Roberts Date: Thu, 10 Sep 2009 02:50:33 +0000 (+0000) Subject: CSPACE-361: More work on refactoring ID Service to a hierarchy of IDGeneratorParts... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=1db1fecca57665ac32eea7db918bece25fac411f;p=tmp%2Fjakarta-migration.git CSPACE-361: More work on refactoring ID Service to a hierarchy of IDGeneratorParts interfaces. --- 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 index 9a9b59d0c..c29975c62 100644 --- 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 @@ -13,6 +13,12 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ // @TODO: Add Javadoc comments @@ -61,7 +67,7 @@ import java.util.regex.Pattern; * $LastChangedRevision$ * $LastChangedDate$ */ -public class AlphabeticIDGeneratorPart implements IDGeneratorPart { +public class AlphabeticIDGeneratorPart implements SequenceIDGeneratorPart { private static final char NULL_CHAR = '\u0000'; @@ -178,7 +184,7 @@ public class AlphabeticIDGeneratorPart implements IDGeneratorPart { } // Initialize the current value from the initial value. - this.currentValue = new Vector(this.initialValue); + // this.currentValue = new Vector(this.initialValue); } @@ -189,7 +195,11 @@ public class AlphabeticIDGeneratorPart implements IDGeneratorPart { // Returns the current value. public String getCurrentID() { - return getIDString(this.currentValue); + if (this.currentValue == null || this.currentValue.size() == 0) { + return getIDString(this.initialValue); + } else { + return getIDString(this.currentValue); + } } // Sets the current value. @@ -235,10 +245,10 @@ public class AlphabeticIDGeneratorPart implements IDGeneratorPart { // Reset the current value to the initial value. public void resetID() { - Collections.copy(this.currentValue, this.initialValue); + this.currentValue = this.initialValue; + // Collections.copy(this.currentValue, this.initialValue); } - // Returns the next alphabetic ID in the sequence. // // Currently, the number of characters auto-expands as the @@ -292,25 +302,34 @@ public class AlphabeticIDGeneratorPart implements IDGeneratorPart { 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()); + + /** + * Returns a new identifier. + */ + @Override + public String newID() { + // If there is no current value, return the initial value + // and set the current value to the initial value. + if (this.currentValue == null || this.currentValue.size() == 0) { + this.currentValue = this.initialValue; + return getIDString(this.currentValue); + // Otherwise, return a new value. + } else { + return nextID(); } - return sb.toString(); } - public boolean isValidID(String value) { - - if (value == null || value.equals("")) { - return false; - } + @Override + public boolean isValidID(String id) { + + if (id == null) return false; + + // @TODO May potentially throw at least one pattern-related exception. + // We'll need to catch and handle this here, as well as in all + // derived classes and test cases that invoke validation. Pattern pattern = Pattern.compile(getRegex()); - Matcher matcher = pattern.matcher(value); + Matcher matcher = pattern.matcher(id); if (matcher.matches()) { return true; } else { @@ -319,15 +338,36 @@ public class AlphabeticIDGeneratorPart implements IDGeneratorPart { } + @Override 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. + // @TODO May need to constrain the number of alphabetic + // characters based on a maximum length value. + // + // Currently, this regex simply matches any sequence of one + // or more alphabetic characters, with no explicit constraint + // on length. String regex = "(" + "[" + String.valueOf(this.startChar) + "-" + String.valueOf(this.endChar) + - "]+" + ")"; + "]" + "+" + ")"; return regex; } + + /** + * Returns a String representation of the ID, by concatenating + * the String values of each alphabetic character constituting the ID. + * + * @param characters The alphabetic characters constituting the ID. + * + * @return A String representation of the ID. + */ + public String getIDString(Vector characters) { + StringBuffer sb = new StringBuffer(); + for ( Character ch : characters ) { + sb.append(ch.toString()); + } + return sb.toString(); + } + } diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/BaseIDGenerator.java b/services/id/service/src/main/java/org/collectionspace/services/id/BaseIDGenerator.java index 5f1339d98..fbad490f2 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/BaseIDGenerator.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/BaseIDGenerator.java @@ -1,8 +1,4 @@ /** - * BaseIDGenerator - * - * 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 * for museums and related institutions: @@ -18,9 +14,11 @@ * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ // @TODO: Add Javadoc comments @@ -36,274 +34,368 @@ import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * BaseIDGenerator + * + * Models an identifier (ID) generator, consisting of + * multiple IDGeneratorParts. + * + * $LastChangedRevision$ + * $LastChangedDate$ + */ public class BaseIDGenerator implements IDGenerator { - private String csid = ""; - private String uri = ""; - private String description = ""; - private Vector parts = new Vector(); - - final static int MAX_ID_LENGTH = 50; - - // Constructor - public BaseIDGenerator(String csid) { - if (csid != null && ! csid.equals("")) { - this.csid = csid; - } - } - - // Constructor - public BaseIDGenerator(String csid, Vector partsList) { - if (csid != null && ! csid.equals("")) { - this.csid = csid; - } - if (partsList != null) { - this.parts = partsList; - } - } + private String csid = ""; + private String uri = ""; + private String description = ""; + private Vector parts = new Vector(); - public String getCsid() { - return this.csid; - } + final static int MAX_ID_LENGTH = 50; + + /** + * Constructor. + * + * @param csid A CollectionSpace ID (CSID) identifying this ID generator. + * + */ + public BaseIDGenerator(String csid) { + if (csid != null && ! csid.equals("")) { + this.csid = csid; + } + } + + /** + * Constructor. + * + * @param csid A CollectionSpace ID (CSID) identifying this ID generator. + * + * @param parts A collection of ID generator parts. + * + */ + public BaseIDGenerator(String csid, Vector parts) { + if (csid != null && ! csid.equals("")) { + this.csid = csid; + } + if (parts != null) { + this.parts = parts; + } + } - public void setURI(String uriStr) { - if (uriStr == null || uriStr.equals("")) { - return; + /** + * Returns the CollectionSpace ID (CSID) identifying this ID generator. + */ + public String getCsid() { + return this.csid; } - // Validate that this is a legal URI. - try { - URI uri = new URI(uriStr); - } catch (URISyntaxException e) { - return; + + /** + * Sets a URI as a second type of identifier for this ID generator, + * in addition to the CollectionSpace ID (CSID). + * + * @param uriStr A String representation of a URI. + */ + public void setURI(String uriStr) { + if (uriStr == null || uriStr.equals("")) { + return; + } + // Validate that this is a legal URI. + try { + URI uri = new URI(uriStr); + } catch (URISyntaxException e) { + // Fail silently without setting the URI. + return; + } + this.uri = uriStr; } - this.uri = uriStr; - } - public String getURI() { - return this.uri; - } + /** + * Returns the URI, if any, that is used as a second type of + * identifier for this ID generator. + */ + public String getURI() { + return this.uri; + } - public void setDescription(String description) { - if (description != null) { - this.description = description; + /** + * Sets an optional, human-readable description of this ID generator. + * + * @param description A human-readable description of this ID generator. + */ + public void setDescription(String description) { + if (description != null) { + this.description = description; + } } - } - public String getDescription() { - return this.description; - } + /** + * Returns the human-readable description of this ID generator, if any. + */ + public String getDescription() { + return this.description; + } - public void add(IDGeneratorPart part) { - if (part != null) { - this.parts.add(part); - } - } + /** + * Adds a single ID generator part. + * + * @param part An ID generator part. + */ + public void add(IDGeneratorPart part) { + if (part != null) { + this.parts.add(part); + } + } - // Returns the current value of this ID. - public String getCurrentID() { - StringBuffer sb = new StringBuffer(MAX_ID_LENGTH); - for (IDGeneratorPart part : this.parts) { - sb.append(part.getCurrentID()); - } - return sb.toString(); - } + /** + * Removes all ID generator parts. + */ + public void clear() { + this.parts.clear(); + } - // Returns the current value of this ID, given a - // supplied ID that partly matches the pattern. - // - // If the supplied ID fully matches the pattern, - // will return the supplied ID. - // - // However, if the supplied ID is a partial ID, which - // partly "stem-matches" the pattern but does not - // ully match the pattern, will return the partial ID with - // its next ID component appended. The next ID component - // will be set to its initial value. - // - // Examples: - // * 2009.5." becomes "2009.5.1", in a case where the - // next ID component is an incrementing numeric IDGeneratorPart. - // * "E55-" becomes "E55-a", where the next ID component - // is an incrementing alphabetic IDGeneratorPart. - public String getCurrentID(String value) - throws IllegalArgumentException { + @Override + public String getCurrentID() { + StringBuffer sb = new StringBuffer(MAX_ID_LENGTH); + for (IDGeneratorPart part : this.parts) { + sb.append(part.getCurrentID()); + } + return sb.toString(); + } - if (value == null) return value; - - // Try ever-larger stem matches against the supplied value, - // by incrementally appending each part's regex, until no - // (more) matches are found. - // - // 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 (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 IDGeneratorParts and the regex pattern - // that has matched to this point. - if (matcher.lookingAt()) { - matchedParts++; - regex.append(partToTryMatching.getRegex()); - // Otherwise, exit the loop. - } else { - break; - } - } - // If the supplied ID doesn't partly match the pattern, - // throw an Exception. - if (matchedParts == 0) { - throw new IllegalArgumentException("Supplied ID does not match this ID pattern."); - } +/* + @Override + public String newID() { + StringBuffer sb = new StringBuffer(MAX_ID_LENGTH); + int lastPart = parts.size() - 1; + int i = 0; + for (IDGeneratorPart part : this.parts) { + if (i == lastPart){ + sb.append(part.newID()); + } else { + sb.append(part.getCurrentID()); + } + i++; + } + return sb.toString(); + } +*/ - pattern = Pattern.compile(regex.toString()); - matcher = pattern.matcher(value); - - // If the supplied ID doesn't match the pattern built above, - // throw an Exception. (This error condition should likely - // never be reached, but it's here as a guard.) - if (! matcher.matches()) { - throw new IllegalArgumentException("Supplied ID does not match this ID pattern."); - } - - // Otherwise, if the supplied ID matches the pattern, - // split the ID into its components and store those - // 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)); - } + // Returns the current value of this ID, given a + // supplied ID that partly matches the pattern. + // + // If the supplied ID fully matches the pattern, + // will return the supplied ID. + // + // However, if the supplied ID is a partial ID, which + // partly "stem-matches" the pattern but does not + // ully match the pattern, will return the partial ID with + // its next ID component appended. The next ID component + // will be set to its initial value. + // + // Examples: + // * 2009.5." becomes "2009.5.1", in a case where the + // next ID component is an incrementing numeric IDGeneratorPart. + // * "E55-" becomes "E55-a", where the next ID component + // is an incrementing alphabetic IDGeneratorPart. + public String getCurrentID(String value) + throws IllegalArgumentException { - // 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' 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 IDGeneratorPart. - matchedParts++; - } catch (ArrayIndexOutOfBoundsException e ) { - // Do nothing here; we simply won't increment - // the number of matched parts, used in the loop below. - } - - // Call the getCurrentID() method on each of the - // 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++) { - sb.append(this.parts.get(i - 1).getCurrentID()); - } - - return sb.toString(); + if (value == null) return value; + + // Try ever-larger stem matches against the supplied value, + // by incrementally appending each part's regex, until no + // (more) matches are found. + // + // 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 (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 IDGeneratorParts and the regex pattern + // that has matched to this point. + if (matcher.lookingAt()) { + matchedParts++; + regex.append(partToTryMatching.getRegex()); + // Otherwise, exit the loop. + } else { + break; + } + } - } + // If the supplied ID doesn't partly match the pattern, + // throw an Exception. + if (matchedParts == 0) { + throw new IllegalArgumentException("Supplied ID does not match this ID pattern."); + } - // Returns the next value of this ID, and sets the current value to that ID. - public String newID() throws IllegalStateException { - - // 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 IDGeneratorParts - StringBuffer sb = new StringBuffer(MAX_ID_LENGTH); - for (IDGeneratorPart part : this.parts) { - sb.append(part.getCurrentID()); - } - - return sb.toString(); - - } + pattern = Pattern.compile(regex.toString()); + matcher = pattern.matcher(value); + + // If the supplied ID doesn't match the pattern built above, + // throw an Exception. (This error condition should likely + // never be reached, but it's here as a guard.) + if (! matcher.matches()) { + throw new IllegalArgumentException("Supplied ID does not match this ID pattern."); + } + + // Otherwise, if the supplied ID matches the pattern, + // split the ID into its components and store those + // 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)); + } - // 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 newID(String value) - throws IllegalStateException, IllegalArgumentException { + // 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' 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); + String currentID = this.parts.get(nextPartNum).getCurrentID(); + // Increment the number of matched parts to reflect the + // addition of this next IDGeneratorPart. + matchedParts++; + } catch (ArrayIndexOutOfBoundsException e ) { + // Do nothing here; we simply won't increment + // the number of matched parts, used in the loop below. + } + + // Call the getCurrentID() method on each of the + // 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++) { + sb.append(this.parts.get(i - 1).getCurrentID()); + } + + return sb.toString(); - if (value == null) { - throw new IllegalArgumentException("Supplied ID cannot be null."); - } - - Pattern pattern = Pattern.compile(getRegex()); - Matcher matcher = pattern.matcher(value); - - // If the supplied ID doesn't entirely match the pattern, - // throw an Exception. - if (! matcher.matches()) { - throw new IllegalArgumentException("Supplied ID does not match this ID pattern."); - } - - // 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 IDGeneratorParts. - IDGeneratorPart currentPart; - for (int i = 1; i <= (matcher.groupCount() - 1); i++) { - currentPart = this.parts.get(i - 1); - currentPart.setCurrentID(matcher.group(i)); - } + } + + // Returns the next value of this ID, and sets the current value to that ID. + @Override + public String newID() throws IllegalStateException { + + int lastPartNum = this.parts.size(); + StringBuffer sb = new StringBuffer(MAX_ID_LENGTH); + int i = 0; + for (IDGeneratorPart part : this.parts) { + i++; + if (i < lastPartNum) { + sb.append(part.getCurrentID()); + } else { + sb.append(part.newID()); + } + } + + return sb.toString(); + + } - // 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. - // - // @TODO: This code is duplicated in nextID(), above, - // and thus we may want to refactor this. - int lastPartNum = this.parts.size() - 1; - this.parts.get(lastPartNum).nextID(); - - // Then call the getCurrentID() method on all of the IDGeneratorParts - StringBuffer sb = new StringBuffer(); - for (IDGeneratorPart part : this.parts) { - sb.append(part.getCurrentID()); - } - - return sb.toString(); - - } - // Validates a provided ID against the pattern. - // - // @TODO May potentially throw at least one pattern-related exception; - // we'll need to catch and handle this. - public boolean isValidID(String value) { - - if (value == null) return false; - - Pattern pattern = Pattern.compile(getRegex()); - Matcher matcher = pattern.matcher(value); - if (matcher.matches()) { - return true; - } else { - return false; - } - - } + // Returns the new value of this ID, given a + // supplied ID that entirely matches the pattern, + // and sets the current value to that ID. + public String newID(String value) + throws IllegalStateException, IllegalArgumentException { - // Returns a regular expression to validate this ID. - public String getRegex() { - StringBuffer sb = new StringBuffer(); - for (IDGeneratorPart part : this.parts) { - sb.append(part.getRegex()); - } - return sb.toString(); - } + if (value == null) { + throw new IllegalArgumentException("Supplied ID cannot be null."); + } + + Pattern pattern = Pattern.compile(getRegex()); + Matcher matcher = pattern.matcher(value); + + // If the supplied ID doesn't entirely match the pattern, + // throw an Exception. + if (! matcher.matches()) { + throw new IllegalArgumentException( + "Supplied ID does not match this ID pattern."); + } + + // 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 IDGeneratorParts. + IDGeneratorPart currentPart; + for (int i = 1; i <= (matcher.groupCount() - 1); i++) { + currentPart = this.parts.get(i - 1); + currentPart.setCurrentID(matcher.group(i)); + } + + // @TODO This code is duplicated in newID(), above, + // and thus we may want to refactor this. + int lastPartNum = this.parts.size(); + StringBuffer sb = new StringBuffer(MAX_ID_LENGTH); + int i = 0; + for (IDGeneratorPart part : this.parts) { + i++; + if (i < lastPartNum) { + sb.append(part.getCurrentID()); + } else { + sb.append(part.newID()); + } + } + + return sb.toString(); + + } + + + @Override + public boolean isValidID(String id) { + return isValidID(id, getRegex()); + } + + /** + * Validates a supplied ID against the format of the IDs + * generated by this ID generator. + * + * @param id An ID. + * + * @param regex A regular expression for validating IDs against + * a format. + * + * @return true if the supplied ID matches the format of the + * IDs generated by this ID generator; + * false if it does not match that format. + */ + public boolean isValidID(String id, String regex) { + + if (id == null) return false; + + // @TODO May potentially throw at least one pattern-related exception. + // We'll need to catch and handle this here, as well as in all + // derived classes and test cases that invoke validation. + + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(id); + if (matcher.matches()) { + return true; + } else { + return false; + } + + } + + @Override + public String getRegex() { + StringBuffer sb = new StringBuffer(); + 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 829e6a964..b8d733f66 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 @@ -14,9 +14,11 @@ * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.collectionspace.services.id; @@ -30,18 +32,44 @@ package org.collectionspace.services.id; public interface IDGenerator { /** - * Returns a new identifier (ID). + * Returns a new ID. + * + * @return A new ID. */ public String newID(); /** - * Returns a new identifier (ID), based on a supplied identifier. + * Returns a new ID, based on a supplied identifier. + * + * @return A new ID. */ public String newID(String id); - + /** - * Returns the current identifier (ID). + * Returns the current ID. + * + * @return The current ID. */ public String getCurrentID(); + /** + * Validates a supplied ID against the format of the IDs + * generated by this ID generator. + * + * @param id An ID. + * + * @return true if the supplied ID matches the format of the + * IDs generated by this ID generator; + * false if it does not match that format. + */ + public boolean isValidID(String id); + + /** + * Returns a regular expression that can be used to validate the IDs + * generated by this ID generator. + * + * @return A regular expression that can be used to validate 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 index b76a12f97..4193c4eb1 100644 --- 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 @@ -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: @@ -13,9 +13,15 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ - /* +/** * IDGeneratorPart, interface for a component part of an ID Generator. * * $LastChangedRevision$ @@ -25,27 +31,47 @@ 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. + /** + * Returns the current value of the ID + * associated with this part. + * + * @return The current value of the 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(); + /** + * Sets the current value of the ID + * associated with this part. + * + * @return The current value of the ID. + */ + public void setCurrentID(String value) throws IllegalArgumentException; - // Returns the next ID in the sequence, and sets - // the current value to that ID. - public String nextID() throws IllegalStateException; + /** + * Returns a new ID. + * + * @return An ID. + */ + public String newID(); - // Validates an ID against a pattern of generated IDs. - public boolean isValidID(String value); + /** + * Validates a supplied ID against the format of the IDs + * generated by this ID generator. + * + * @param id An ID. + * + * @return true if the supplied ID matches the format of the + * IDs generated by this ID generator; + * false if it does not match that format. + */ + public boolean isValidID(String id); - // Returns a String representation of the regular expression ("regex") - // pattern used to validate instance values of generated IDs. - public String getRegex(); + /** + * Returns a regular expression that can be used to validate the IDs + * generated by this ID generator. + * + * @return A regular expression that can be used to validate IDs. + */ + public String 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 0ad1b6f5b..90932fbf0 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,6 +13,12 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.collectionspace.services.id; diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDService.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDService.java index ce333f3f0..c437d7c8d 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/IDService.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/IDService.java @@ -28,44 +28,44 @@ package org.collectionspace.services.id; */ public interface IDService { - // ---------------------------------------- - // IDs - // ---------------------------------------- + // ---------------------------------------- + // IDs + // ---------------------------------------- - // Create + // Create - // Read single object - + // Read single object + // Generates and returns a new ID from the specified ID generator. public String newID(String csid) throws IllegalArgumentException, IllegalStateException; // Returns the last-generated ID associated with the specified ID generator. public String getLastID(String csid) - throws IllegalArgumentException, IllegalStateException; + throws IllegalArgumentException, IllegalStateException; - // Read a list of objects (aka read multiple) - - // ---------------------------------------- - // ID Generators - // ---------------------------------------- - - // Create - - // Adds a new ID generator. + // Read a list of objects (aka read multiple) + + // ---------------------------------------- + // ID Generators + // ---------------------------------------- + + // Create + + // Adds a new ID generator. public void addIDGenerator(String csid, String serializedIDGenerator) - throws IllegalArgumentException, IllegalStateException; - - // Read single object + throws IllegalArgumentException, IllegalStateException; + + // Read single object public String getIDGenerator(String csid) - throws IllegalArgumentException, IllegalStateException; - - // Read a list of objects (aka read multiple) - - // Update (may need to check for changes in the ID generator structure) + throws IllegalArgumentException, IllegalStateException; + + // Read a list of objects (aka read multiple) + + // Update (may need to check for changes in the ID generator structure) public void updateIDGenerator(String csid, String serializedIDGenerator) - throws IllegalArgumentException, IllegalStateException; - - // Delete (possibly not permitted - deactivate instead?) + throws IllegalArgumentException, IllegalStateException; + + // Delete (possibly not permitted - deactivate instead?) } 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 da5c69f94..93d9ad698 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 @@ -13,6 +13,12 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ // *IMPORTANT* @@ -85,195 +91,194 @@ import org.slf4j.LoggerFactory; * Manages the storage of ID generators and persistence of their * current state, via a JDBC interface to an underlying database. * - * $LastChangedBy$ * $LastChangedRevision$ * $LastChangedDate$ */ public class IDServiceJdbcImpl implements IDService { final Logger logger = LoggerFactory.getLogger(IDServiceJdbcImpl.class); + + final String JDBC_DRIVER_CLASSNAME = "com.mysql.jdbc.Driver"; + final String DATABASE_NAME = "cspace"; + final String DATABASE_URL = "jdbc:mysql://localhost:3306/" + DATABASE_NAME; + final String DATABASE_USERNAME = "test"; + final String DATABASE_PASSWORD = "test"; + final String TABLE_NAME = "id_generator"; + + boolean hasPreconditions = true; - final String JDBC_DRIVER_CLASSNAME = "com.mysql.jdbc.Driver"; - final String DATABASE_NAME = "cspace"; - final String DATABASE_URL = "jdbc:mysql://localhost:3306/" + DATABASE_NAME; - final String DATABASE_USERNAME = "test"; - final String DATABASE_PASSWORD = "test"; - final String TABLE_NAME = "id_generator"; - - boolean hasPreconditions = true; - - ////////////////////////////////////////////////////////////////////// - /** - * Constructor (no-argument). - */ - public void IDServiceJdbcImpl() throws IllegalStateException { - - // @TODO Decide when and how to fail at startup, or else to correct - // failure conditions automatically, when preconditions are not met. - // - // Currently, errors at initialization are merely informative and - // result in exceptions that can be persistently logged. - - try { - init(); - } catch (IllegalStateException e) { - throw e; - } - - } - - // @TODO init() is currently UNTESTED as of 2009-08-11T13:00-0700. - - ////////////////////////////////////////////////////////////////////// - /** - * Initializes the service. - * - * @throws IllegalStateException if one or more of the required preconditions - * for the service is not present, or is not in its required state. - */ - public void init() throws IllegalStateException { - + ////////////////////////////////////////////////////////////////////// + /** + * Constructor (no-argument). + */ + public void IDServiceJdbcImpl() throws IllegalStateException { + + // @TODO Decide when and how to fail at startup, or else to correct + // failure conditions automatically, when preconditions are not met. + // + // Currently, errors at initialization are merely informative and + // result in exceptions that can be persistently logged. + + try { + init(); + } catch (IllegalStateException e) { + throw e; + } + + } + + // @TODO init() is currently UNTESTED as of 2009-08-11T13:00-0700. + + ////////////////////////////////////////////////////////////////////// + /** + * Initializes the service. + * + * @throws IllegalStateException if one or more of the required preconditions + * for the service is not present, or is not in its required state. + */ + public void init() throws IllegalStateException { + logger.debug("> in init"); - - try { - instantiateJdbcDriver(JDBC_DRIVER_CLASSNAME); - } catch (IllegalStateException e) { - throw e; - } - - try { - boolean hasTable = hasTable(TABLE_NAME); - if (! hasTable) { - String msg = - "Required table " + - "\'" + TABLE_NAME + "\'" + - " could not be found in the database."; - logger.warn(msg); - throw new IllegalStateException(msg); - } - } catch (IllegalStateException e) { - throw e; - } - - } - - ////////////////////////////////////////////////////////////////////// - /** - * Creates a new instance of the specified JDBC driver class. - * - * @param jdbcDriverClassname The name of a JDBC driver class. - * - * @throws IllegalStateException if a new instance of the specified - * JDBC driver class cannot be created. - */ - public void instantiateJdbcDriver(String jdbcDriverClassname) - throws IllegalStateException { - + + try { + instantiateJdbcDriver(JDBC_DRIVER_CLASSNAME); + } catch (IllegalStateException e) { + throw e; + } + + try { + boolean hasTable = hasTable(TABLE_NAME); + if (! hasTable) { + String msg = + "Required table " + + "\'" + TABLE_NAME + "\'" + + " could not be found in the database."; + logger.warn(msg); + throw new IllegalStateException(msg); + } + } catch (IllegalStateException e) { + throw e; + } + + } + + ////////////////////////////////////////////////////////////////////// + /** + * Creates a new instance of the specified JDBC driver class. + * + * @param jdbcDriverClassname The name of a JDBC driver class. + * + * @throws IllegalStateException if a new instance of the specified + * JDBC driver class cannot be created. + */ + public void instantiateJdbcDriver(String jdbcDriverClassname) + throws IllegalStateException { + logger.debug("> in instantiateJdbcDriver(String)"); - - try { - Class.forName(jdbcDriverClassname).newInstance(); - } catch (ClassNotFoundException e) { - throw new IllegalStateException( - "Error finding JDBC driver class '" + - JDBC_DRIVER_CLASSNAME + - "' to set up database connection."); - } catch (InstantiationException e) { - throw new IllegalStateException( - "Error instantiating JDBC driver class '" + - JDBC_DRIVER_CLASSNAME + - "' to set up database connection."); - } catch (IllegalAccessException e) { - throw new IllegalStateException( - "Error accessing JDBC driver class '" + - JDBC_DRIVER_CLASSNAME + - "' to set up database connection."); - } - - } - - ////////////////////////////////////////////////////////////////////// - /** - * Identifies whether a specified table exists in the database. - * - * @param tablename The name of a database table. - * - * @return True if the specified table exists in the database; - * false if the specified table does not exist in the database. - * - * @throws IllegalStateException if an error occurs while checking for the - * existence of the specified table. - */ - public boolean hasTable(String tablename) throws IllegalStateException { - + + try { + Class.forName(jdbcDriverClassname).newInstance(); + } catch (ClassNotFoundException e) { + throw new IllegalStateException( + "Error finding JDBC driver class '" + + JDBC_DRIVER_CLASSNAME + + "' to set up database connection."); + } catch (InstantiationException e) { + throw new IllegalStateException( + "Error instantiating JDBC driver class '" + + JDBC_DRIVER_CLASSNAME + + "' to set up database connection."); + } catch (IllegalAccessException e) { + throw new IllegalStateException( + "Error accessing JDBC driver class '" + + JDBC_DRIVER_CLASSNAME + + "' to set up database connection."); + } + + } + + ////////////////////////////////////////////////////////////////////// + /** + * Identifies whether a specified table exists in the database. + * + * @param tablename The name of a database table. + * + * @return True if the specified table exists in the database; + * false if the specified table does not exist in the database. + * + * @throws IllegalStateException if an error occurs while checking for the + * existence of the specified table. + */ + public boolean hasTable(String tablename) throws IllegalStateException { + logger.debug("> in hasTable"); - + if (tablename == null || tablename.equals("")) { return false; } - - Connection conn = null; - try { - - conn = getJdbcConnection(); - - // Retrieve a list of tables in the current database. - final String CATALOG_NAME = null; - final String SCHEMA_NAME_PATTERN = null; - final String[] TABLE_TYPES = null; - ResultSet tablesMatchingTableName = - conn.getMetaData().getTables( - CATALOG_NAME, SCHEMA_NAME_PATTERN, tablename, TABLE_TYPES); - - // Check whether a table with the specified name is in that list. + + Connection conn = null; + try { + + conn = getJdbcConnection(); + + // Retrieve a list of tables in the current database. + final String CATALOG_NAME = null; + final String SCHEMA_NAME_PATTERN = null; + final String[] TABLE_TYPES = null; + ResultSet tablesMatchingTableName = + conn.getMetaData().getTables( + CATALOG_NAME, SCHEMA_NAME_PATTERN, tablename, TABLE_TYPES); + + // Check whether a table with the specified name is in that list. boolean moreRows = tablesMatchingTableName.next(); if (! moreRows) { - return false; - } else { - return true; - } - - } catch (SQLException e) { - throw new IllegalStateException( - "Error while checking for existence of tablebase table: " + e.getMessage()); - } finally { - try { - if (conn != null) { - conn.close(); - } - } catch(SQLException e) { - // Do nothing here - } - } - - } - - ////////////////////////////////////////////////////////////////////// - /** - * Generates and returns a new ID associated with a specified ID generator. - * - * This method has an intentional side-effect: it sets the - * current ID of that ID generator to the just-generated ID. - * - * @param csid An identifier for an ID generator. - * - * @return A new ID associated with the specified ID generator. - * - * @throws IllegalArgumentException if the provided csid is null or empty, - * or if the specified ID generator can't be found. - * - * @throws IllegalStateException if a storage-related error occurred. - */ + return false; + } else { + return true; + } + + } catch (SQLException e) { + throw new IllegalStateException( + "Error while checking for existence of tablebase table: " + e.getMessage()); + } finally { + try { + if (conn != null) { + conn.close(); + } + } catch(SQLException e) { + // Do nothing here + } + } + + } + + ////////////////////////////////////////////////////////////////////// + /** + * Generates and returns a new ID associated with a specified ID generator. + * + * This method has an intentional side-effect: it sets the + * current ID of that ID generator to the just-generated ID. + * + * @param csid An identifier for an ID generator. + * + * @return A new ID associated with the specified ID generator. + * + * @throws IllegalArgumentException if the provided csid is null or empty, + * or if the specified ID generator can't be found. + * + * @throws IllegalStateException if a storage-related error occurred. + */ public String newID(String csid) throws IllegalArgumentException, IllegalStateException { logger.debug("> in newID"); - - // @TODO Where relevant, implement logic to check for ID availability, - // after generating a candidate ID. - - // @TODO: Add checks for authorization to perform this operation. - + + // @TODO Where relevant, implement logic to check for ID availability, + // after generating a candidate ID. + + // @TODO: Add checks for authorization to perform this operation. + String newId = ""; String lastId = ""; @@ -281,8 +286,8 @@ public class IDServiceJdbcImpl implements IDService { throw new IllegalArgumentException( "Identifier for ID generator must not be null or empty."); } - - String serializedGenerator = ""; + + String serializedGenerator = ""; try { serializedGenerator = getIDGenerator(csid); } catch (IllegalArgumentException e ) { @@ -296,241 +301,245 @@ public class IDServiceJdbcImpl implements IDService { throw new IllegalArgumentException( "ID generator " + "\'" + csid + "\'" + " could not be found."); } - - BaseIDGenerator generator; - try { - generator = IDGeneratorSerializer.deserialize(serializedGenerator); - } catch (IllegalArgumentException e) { - throw e; - } + BaseIDGenerator generator; try { - - // Retrieve the last ID associated with this generator - // from persistent storage. - lastId = getLastID(csid); - - // 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 = 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 = generator.newID(lastId); - } - - // 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, generator); + generator = IDGeneratorSerializer.deserialize(serializedGenerator); + } catch (IllegalArgumentException e) { + throw e; + } + + try { + + // Retrieve the last ID associated with this generator + // from persistent storage. + lastId = getLastID(csid); + + // If there was no last generated ID associated with this generator, + // get a new ID. + if (lastId == null || lastId.equals("")) { + newId = generator.newID(); + + // 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 = generator.newID(lastId); + } + + // 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, generator); } catch (IllegalArgumentException e ) { - throw e; + throw e; } catch (IllegalStateException e ) { throw e; } return newId; - - } - ////////////////////////////////////////////////////////////////////// - /** - * Stores the last-generated ID, corresponding to a specified ID generator, - * into persistent storage. - * - * @param csid An identifier for an ID generator. - * - * @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. - * - * @throws IllegalArgumentException if the requested ID generator could not be found. - * - * @throws IllegalStateException if a storage-related error occurred. - */ + } + + ////////////////////////////////////////////////////////////////////// + /** + * Stores the last-generated ID, corresponding to a specified ID generator, + * into persistent storage. + * + * @param csid An identifier for an ID generator. + * + * @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. + * + * @throws IllegalArgumentException if the requested ID generator could not be found. + * + * @throws IllegalStateException if a storage-related error occurred. + */ public void updateLastID(String csid, String lastId) throws IllegalArgumentException, IllegalStateException { - + logger.debug("> in updateLastID"); - - // @TODO Where relevant, implement logic to check for ID availability, - // after generating a candidate ID. - - // @TODO: Add checks for authorization to perform this operation. - - Connection conn = null; - try { - - conn = getJdbcConnection(); - Statement stmt = conn.createStatement(); + + // @TODO Where relevant, implement logic to check for ID availability, + // after generating a candidate ID. + + // @TODO: Add checks for authorization to perform this operation. + + Connection conn = null; + try { + + conn = getJdbcConnection(); + Statement stmt = conn.createStatement(); int rowsUpdated = stmt.executeUpdate( - "UPDATE id_generators SET last_generated_id='" + lastId + "' WHERE id_generator_csid='" + csid + "'"); + "UPDATE id_generators SET last_generated_id='" + lastId + + "' WHERE id_generator_csid='" + csid + "'"); if (rowsUpdated != 1) { - throw new IllegalStateException( - "Error updating last-generated ID in the database for ID generator '" + csid + "'"); - } - + throw new IllegalStateException( + "Error updating last-generated ID in the database for ID generator '" + + csid + "'"); + } + logger.debug("> successfully updated last-generated ID: " + lastId); - - } catch (SQLException e) { - throw new IllegalStateException("Error updating last-generated ID in the database: " + e.getMessage()); - } finally { - try { - if (conn != null) { - conn.close(); - } - } catch(SQLException e) { - // Do nothing here - } - } - - } - - ////////////////////////////////////////////////////////////////////// - /** - * Returns the last-generated ID, corresponding to a specified ID generator, - * from persistent storage. - * - * @param csid An identifier for an ID generator. - * - * @return The last ID generated that corresponds to the requested ID generator. - * - * @throws IllegalArgumentException if the requested ID generator could not be found. - * - * @throws IllegalStateException if a storage-related error occurred. - */ - public String getLastID(String csid) throws IllegalArgumentException, IllegalStateException { - + + } catch (SQLException e) { + throw new IllegalStateException("Error updating last-generated ID in the database: " + + e.getMessage()); + } finally { + try { + if (conn != null) { + conn.close(); + } + } catch(SQLException e) { + // Do nothing here + } + } + + } + + ////////////////////////////////////////////////////////////////////// + /** + * Returns the last-generated ID, corresponding to a specified ID generator, + * from persistent storage. + * + * @param csid An identifier for an ID generator. + * + * @return The last ID generated that corresponds to the requested ID generator. + * + * @throws IllegalArgumentException if the requested ID generator could not be found. + * + * @throws IllegalStateException if a storage-related error occurred. + */ + public String getLastID(String csid) throws IllegalArgumentException, + IllegalStateException { + logger.debug("> in getLastID"); - - // @TODO Where relevant, implement logic to check for ID availability, - // after generating a candidate ID. - - // @TODO: Add checks for authorization to perform this operation. - - String lastId = null; - Connection conn = null; - try { - - conn = getJdbcConnection(); - Statement stmt = conn.createStatement(); + + // @TODO Where relevant, implement logic to check for ID availability, + // after generating a candidate ID. + + // @TODO: Add checks for authorization to perform this operation. + + String lastId = null; + Connection conn = null; + try { + + conn = getJdbcConnection(); + Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery( "SELECT last_generated_id FROM id_generators WHERE id_generator_csid='" + csid + "'"); boolean moreRows = rs.next(); if (! moreRows) { - throw new IllegalArgumentException( - "ID generator " + "\'" + csid + "\'" + " could not be found."); - } - + throw new IllegalArgumentException( + "ID generator " + "\'" + csid + "\'" + " could not be found."); + } + lastId = rs.getString(1); - - logger.debug("> retrieved ID: " + lastId); - + logger.debug("> retrieved ID: " + lastId); + rs.close(); - - } catch (SQLException e) { - throw new IllegalStateException("Error retrieving last ID from the database: " + e.getMessage()); - } finally { - try { - if (conn != null) { - conn.close(); - } - } catch(SQLException e) { - // Do nothing here - } - } - + + } catch (SQLException e) { + throw new IllegalStateException("Error retrieving last ID from the database: " + + e.getMessage()); + } finally { + try { + if (conn != null) { + conn.close(); + } + } catch(SQLException e) { + // Do nothing here + } + } + logger.debug("> returning ID: " + lastId); - - return lastId; - - } - - ////////////////////////////////////////////////////////////////////// - /** - * Adds a new ID generator to persistent storage. - * - * @param csid An identifier for an ID generator. - * - * @param generator An ID generator, reflecting its current state, - * including the values of its constituent parts. - * - * @throws IllegalStateException if a storage-related error occurred. - */ + + return lastId; + + } + + ////////////////////////////////////////////////////////////////////// + /** + * Adds a new ID generator to persistent storage. + * + * @param csid An identifier for an ID generator. + * + * @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, BaseIDGenerator generator) throws IllegalArgumentException, IllegalStateException { - + logger.debug("> in addIDGenerator(String, BaseIDGenerator)"); - - // @TODO: Add checks for authorization to perform this operation. - - if (generator == null) { - throw new IllegalArgumentException("New ID generator to add cannot be null."); - } - - String serializedGenerator = ""; - try { - serializedGenerator = IDGeneratorSerializer.serialize(generator); - } catch (IllegalArgumentException e) { - throw e; - } - + + // @TODO: Add checks for authorization to perform this operation. + + if (generator == null) { + throw new IllegalArgumentException("New ID generator to add cannot be null."); + } + + String serializedGenerator = ""; + try { + serializedGenerator = IDGeneratorSerializer.serialize(generator); + } catch (IllegalArgumentException e) { + throw e; + } + try { addIDGenerator(csid, serializedGenerator); - } catch (IllegalArgumentException e ) { + } catch (IllegalArgumentException e) { throw e; - } catch (IllegalStateException e ) { + } catch (IllegalStateException e) { throw e; } - - } - - ////////////////////////////////////////////////////////////////////// - /** - * Adds a new ID generator to persistent storage, from a serialization - * of that generator. - * - * The serialization method recognized by this method has implementation - * dependencies. Currently, this method expects serialization via XStream's - * out-of-the-box serializer, without custom configuration. - * - * @param csid An identifier for an ID generator. - * - * @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. - */ + + } + + ////////////////////////////////////////////////////////////////////// + /** + * Adds a new ID generator to persistent storage, from a serialization + * of that generator. + * + * The serialization method recognized by this method has implementation + * dependencies. Currently, this method expects serialization via XStream's + * out-of-the-box serializer, without custom configuration. + * + * @param csid An identifier for an ID generator. + * + * @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. + */ public void addIDGenerator(String csid, String serializedGenerator) throws IllegalArgumentException, IllegalStateException { - + logger.debug("> in addIDGenerator(String, String)"); - - // @TODO Add checks for authorization to perform this operation. - + + // @TODO Add checks for authorization to perform this operation. + if (serializedGenerator == null || serializedGenerator.equals("")) { - throw new IllegalArgumentException( - "Could not understand or parse this representation of an ID generator."); - } - - Connection conn = null; - try { - - conn = getJdbcConnection(); - Statement stmt = conn.createStatement(); - - // Test whether this ID generator already exists in the database. + throw new IllegalArgumentException( + "Could not understand or parse this representation of an ID generator."); + } + + Connection conn = null; + try { + + conn = getJdbcConnection(); + Statement stmt = conn.createStatement(); + + // Test whether this ID generator already exists in the database. // // @TODO This check should extend further, to other aspects of the generator, // such as its URI, if any, and its structure. @@ -541,90 +550,92 @@ public class IDServiceJdbcImpl implements IDService { boolean idGeneratorFound = true; if (! moreRows) { - idGeneratorFound = false; - } - + idGeneratorFound = false; + } + // If this ID generator already exists in the database, throw an Exception. // // @TODO This exception needs to convey the meaning that a conflict has // occurred, so that this status can be reported to the client. if (idGeneratorFound) { - throw new IllegalStateException( - "Conflict with existing generator when attempting to add new ID generator with ID '" + - csid + - "' to the database."); - - // Otherwise, add this new ID generator, as a new record to the database. - } else { - - final String SQL_STATEMENT_STRING = - "INSERT INTO id_generators " + - "(" + - "id_generator_csid, " + - "id_generator_state, " + - "last_generated_id" + - ")" + - " VALUES (?, ?, ?)"; - - PreparedStatement ps = conn.prepareStatement(SQL_STATEMENT_STRING); - ps.setString(1, csid); - ps.setString(2, serializedGenerator); - ps.setNull(3, java.sql.Types.VARCHAR); - - int rowsUpdated = ps.executeUpdate(); - if (rowsUpdated != 1) { - throw new IllegalStateException( - "Error adding new ID generator '" + csid + "'" + " to the database."); - } - - } // end if (idGeneratorFound) - - logger.debug("> successfully added ID generator: " + csid); - - } catch (SQLException e) { - throw new IllegalStateException("Error adding new ID generator to the database: " + e.getMessage()); - } finally { - try { - if (conn != null) { - conn.close(); - } - } catch(SQLException e) { - // Do nothing here - } - } - - } - - ////////////////////////////////////////////////////////////////////// - /** - * Updates an existing ID generator in persistent storage. - * - * @param csid An identifier for an ID generator. - * - * @param generator An ID generator, reflecting its current state, - * including the values of its constituent parts. - * - * @throws IllegalStateException if a storage-related error occurred. - */ + throw new IllegalStateException( + "Conflict with existing generator when attempting to add " + + "new ID generator with ID '" + + csid + + "' to the database."); + + // Otherwise, add this new ID generator, as a new record to the database. + } else { + + final String SQL_STATEMENT_STRING = + "INSERT INTO id_generators " + + "(" + + "id_generator_csid, " + + "id_generator_state, " + + "last_generated_id" + + ")" + + " VALUES (?, ?, ?)"; + + PreparedStatement ps = conn.prepareStatement(SQL_STATEMENT_STRING); + ps.setString(1, csid); + ps.setString(2, serializedGenerator); + ps.setNull(3, java.sql.Types.VARCHAR); + + int rowsUpdated = ps.executeUpdate(); + if (rowsUpdated != 1) { + throw new IllegalStateException( + "Error adding new ID generator '" + csid + "'" + " to the database."); + } + + } // end if (idGeneratorFound) + + logger.debug("> successfully added ID generator: " + csid); + + } catch (SQLException e) { + throw new IllegalStateException("Error adding new ID generator to the database: " + + e.getMessage()); + } finally { + try { + if (conn != null) { + conn.close(); + } + } catch(SQLException e) { + // Do nothing here + } + } + + } + + ////////////////////////////////////////////////////////////////////// + /** + * Updates an existing ID generator in persistent storage. + * + * @param csid An identifier for an ID generator. + * + * @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, BaseIDGenerator generator) throws IllegalArgumentException, IllegalStateException { - + logger.debug("> in updateIDGenerator(String, BaseIDGenerator)"); - - // @TODO: Add checks for authorization to perform this operation. - - if (generator == null) { - throw new IllegalArgumentException( - "ID generator provided in update operation cannot be null."); - } - - String serializedGenerator = ""; - try { - serializedGenerator = IDGeneratorSerializer.serialize(generator); - } catch (IllegalArgumentException e) { - throw e; - } - + + // @TODO: Add checks for authorization to perform this operation. + + if (generator == null) { + throw new IllegalArgumentException( + "ID generator provided in update operation cannot be null."); + } + + String serializedGenerator = ""; + try { + serializedGenerator = IDGeneratorSerializer.serialize(generator); + } catch (IllegalArgumentException e) { + throw e; + } + try { updateIDGenerator(csid, serializedGenerator); } catch (IllegalArgumentException e ) { @@ -632,262 +643,260 @@ public class IDServiceJdbcImpl implements IDService { } catch (IllegalStateException e ) { throw e; } - - } - - ////////////////////////////////////////////////////////////////////// - /** - * Updates an existing ID generator in persistent storage, - * 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 - * out-of-the-box serializer, without custom configuration. - * - * @param csid An identifier for an ID generator. - * - * @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. - */ + + } + + ////////////////////////////////////////////////////////////////////// + /** + * Updates an existing ID generator in persistent storage, + * 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 + * out-of-the-box serializer, without custom configuration. + * + * @param csid An identifier for an ID generator. + * + * @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. + */ public void updateIDGenerator(String csid, String serializedGenerator) throws IllegalArgumentException, IllegalStateException { - + logger.debug("> in updateIDGenerator(String, String)"); - - // @TODO: Add checks for authorization to perform this operation. + + // @TODO: Add checks for authorization to perform this operation. if (serializedGenerator == null || serializedGenerator.equals("")) { throw new IllegalArgumentException( - "Could not understand or parse this representation of an ID generator."); - } - - Connection conn = null; - try { - - conn = getJdbcConnection(); - Statement stmt = conn.createStatement(); - - // Test whether this ID generator already exists in the database. + "Could not understand or parse this representation of an ID generator."); + } + + Connection conn = null; + try { + + conn = getJdbcConnection(); + Statement stmt = conn.createStatement(); + + // Test whether this ID generator already exists in the database. ResultSet rs = stmt.executeQuery( - "SELECT id_generator_csid FROM id_generators WHERE id_generator_csid='" + csid + "'"); - + "SELECT id_generator_csid FROM id_generators WHERE id_generator_csid='" + + csid + "'"); + boolean moreRows = rs.next(); - + boolean idGeneratorFound = true; if (! moreRows) { - idGeneratorFound = false; - } - + idGeneratorFound = false; + } + // If this ID generator already exists in the database, update its record. if (idGeneratorFound) { - - final String SQL_STATEMENT_STRING = - "UPDATE id_generators SET " + - "id_generator_state = ?, " + - "last_generated_id = ? " + - "WHERE id_generator_csid = ?"; - - BaseIDGenerator generator; - try { - generator = IDGeneratorSerializer.deserialize(serializedGenerator); - } catch (IllegalArgumentException e) { - throw e; - } - String lastId = generator.getCurrentID(); - - PreparedStatement ps = conn.prepareStatement(SQL_STATEMENT_STRING); - ps.setString(1, serializedGenerator); - ps.setString(2, lastId); - ps.setString(3, csid); - - int rowsUpdated = ps.executeUpdate(); - if (rowsUpdated != 1) { - throw new IllegalStateException( - "Error updating ID generator '" + csid + "'" + " in the database."); - } - + + final String SQL_STATEMENT_STRING = + "UPDATE id_generators SET " + + "id_generator_state = ?, " + + "last_generated_id = ? " + + "WHERE id_generator_csid = ?"; + + BaseIDGenerator generator; + try { + generator = IDGeneratorSerializer.deserialize(serializedGenerator); + } catch (IllegalArgumentException e) { + throw e; + } + String lastId = generator.getCurrentID(); + + PreparedStatement ps = conn.prepareStatement(SQL_STATEMENT_STRING); + ps.setString(1, serializedGenerator); + ps.setString(2, lastId); + ps.setString(3, csid); + + int rowsUpdated = ps.executeUpdate(); + if (rowsUpdated != 1) { + throw new IllegalStateException( + "Error updating ID generator '" + csid + "'" + " in the database."); + } + // Otherwise, throw an exception, which indicates that the requested // ID generator was not found. - } else { - - throw new IllegalArgumentException( - "Error updating ID generator '" + csid + "': generator could not be found in the database."); - - } // end if (idGeneratorFound) - - logger.debug("> successfully updated ID Generator: " + csid); - - } catch (SQLException e) { - throw new IllegalStateException("Error updating ID generator in the database: " + e.getMessage()); - } finally { - try { - if (conn != null) { - conn.close(); - } - } catch(SQLException e) { - // Do nothing here - } - } - - } - - ////////////////////////////////////////////////////////////////////// - /** - * Deletes an existing ID generator from persistent storage. - * - * @param csid An identifier for an ID generator. - * - * @throws IllegalStateException if a storage-related error occurred. - */ + } else { + throw new IllegalArgumentException( + "Error updating ID generator '" + csid + + "': generator could not be found in the database."); + } // end if (idGeneratorFound) + + logger.debug("> successfully updated ID Generator: " + csid); + + } catch (SQLException e) { + throw new IllegalStateException( + "Error updating ID generator in the database: " + e.getMessage()); + } finally { + try { + if (conn != null) { + conn.close(); + } + } catch(SQLException e) { + // Do nothing here + } + } + + } + + ////////////////////////////////////////////////////////////////////// + /** + * Deletes an existing ID generator from persistent storage. + * + * @param csid An identifier for an ID generator. + * + * @throws IllegalStateException if a storage-related error occurred. + */ public void deleteIDGenerator(String csid) throws IllegalArgumentException, IllegalStateException { - + logger.debug("> in deleteIDGenerator"); - - // @TODO: Add checks for authorization to perform this operation. - - Connection conn = null; - try { - - conn = getJdbcConnection(); - Statement stmt = conn.createStatement(); - - // Test whether this ID generator already exists in the database. + + // @TODO: Add checks for authorization to perform this operation. + + Connection conn = null; + try { + + conn = getJdbcConnection(); + Statement stmt = conn.createStatement(); + + // Test whether this ID generator already exists in the database. ResultSet rs = stmt.executeQuery( - "SELECT id_generator_csid FROM id_generators WHERE id_generator_csid='" + csid + "'"); - + "SELECT id_generator_csid FROM id_generators WHERE id_generator_csid='" + + csid + "'"); boolean moreRows = rs.next(); boolean idGeneratorFound = true; if (! moreRows) { - idGeneratorFound = false; - } + idGeneratorFound = false; + } // If this ID generator already exists in the database, update its record. if (idGeneratorFound) { - - final String SQL_STATEMENT_STRING = - "DELETE FROM id_generators WHERE id_generator_csid = ?"; - - PreparedStatement ps = conn.prepareStatement(SQL_STATEMENT_STRING); - ps.setString(1, csid); - - int rowsUpdated = ps.executeUpdate(); - if (rowsUpdated != 1) { - throw new IllegalStateException( - "Error deleting ID generator '" + csid + "'" + " in the database."); - } - + + final String SQL_STATEMENT_STRING = + "DELETE FROM id_generators WHERE id_generator_csid = ?"; + + PreparedStatement ps = conn.prepareStatement(SQL_STATEMENT_STRING); + ps.setString(1, csid); + + int rowsUpdated = ps.executeUpdate(); + if (rowsUpdated != 1) { + throw new IllegalStateException( + "Error deleting ID generator '" + csid + "'" + " in the database."); + } + // Otherwise, throw an exception, which indicates that the requested // ID generator was not found. - } else { - - throw new IllegalArgumentException( - "Error deleting ID generator '" + csid + "': generator could not be found in the database."); - - } // end if (idGeneratorFound) - - logger.debug("> successfully deleted ID generator: " + csid); - - } catch (SQLException e) { - throw new IllegalStateException("Error deleting ID generator in database: " + e.getMessage()); - } finally { - try { - if (conn != null) { - conn.close(); - } - } catch(SQLException e) { - // Do nothing here - } - } - - } - - ////////////////////////////////////////////////////////////////////// - /** - * Opens a connection to the database and returns a JDBC Connection object. - * - * @return A JDBC database Connection object. - * - * @throws SQLException if a storage-related error occurred. - */ - public Connection getJdbcConnection() throws SQLException { - - logger.debug("> in getJdbcConnection"); - - Connection conn = null; - try { - - conn = DriverManager.getConnection(DATABASE_URL, DATABASE_USERNAME, DATABASE_PASSWORD); - - } catch (SQLException e) { - throw e; - } - - return conn; - - } - - ////////////////////////////////////////////////////////////////////// - /** - * Returns a requested ID generator from persistent storage. - * - * @param csid An identifier for an ID generator. - * - * @return A serialized representation of the requested ID generator. - * - * @throws IllegalArgumentException if the requested ID generator could not be found. - * - * @throws IllegalStateException if a storage-related error occurred. - */ + } else { + throw new IllegalArgumentException( + "Error deleting ID generator '" + csid + + "': generator could not be found in the database."); + } // end if (idGeneratorFound) + + logger.debug("> successfully deleted ID generator: " + csid); + + } catch (SQLException e) { + throw new IllegalStateException( + "Error deleting ID generator in database: " + e.getMessage()); + } finally { + try { + if (conn != null) { + conn.close(); + } + } catch(SQLException e) { + // Do nothing here + } + } + + } + + ////////////////////////////////////////////////////////////////////// + /** + * Opens a connection to the database and returns a JDBC Connection object. + * + * @return A JDBC database Connection object. + * + * @throws SQLException if a storage-related error occurred. + */ + public Connection getJdbcConnection() throws SQLException { + + logger.debug("> in getJdbcConnection"); + + Connection conn = null; + try { + conn = DriverManager.getConnection(DATABASE_URL, DATABASE_USERNAME, DATABASE_PASSWORD); + } catch (SQLException e) { + throw e; + } + return conn; + + } + + ////////////////////////////////////////////////////////////////////// + /** + * Returns a requested ID generator from persistent storage. + * + * @param csid An identifier for an ID generator. + * + * @return A serialized representation of the requested ID generator. + * + * @throws IllegalArgumentException if the requested ID generator could not be found. + * + * @throws IllegalStateException if a storage-related error occurred. + */ public String getIDGenerator (String csid) throws IllegalArgumentException, IllegalStateException { - + logger.debug("> in getIDGenerator"); - - String serializedGenerator = null; - - Connection conn = null; - try { - - conn = getJdbcConnection(); - Statement stmt = conn.createStatement(); + + String serializedGenerator = null; + + Connection conn = null; + try { + + conn = getJdbcConnection(); + Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery( "SELECT id_generator_state FROM id_generators WHERE id_generator_csid='" + csid + "'"); boolean moreRows = rs.next(); if (! moreRows) { - throw new IllegalArgumentException( - "ID generator with ID " + - "\'" + csid + "\'" + - " could not be found."); - } - + throw new IllegalArgumentException( + "ID generator with ID " + + "\'" + csid + "\'" + + " could not be found."); + } + serializedGenerator = rs.getString(1); rs.close(); - - } catch (SQLException e) { - throw new IllegalStateException( - "Error retrieving ID generator " + - "\'" + csid + "\'" + - " from database: " + e.getMessage()); - } finally { - try { - if (conn != null) { - conn.close(); - } - } catch(SQLException e) { - // Do nothing here - } - } - - logger.debug("> retrieved BaseIDGenerator: " + serializedGenerator); - - return serializedGenerator; - - } - -} + + } catch (SQLException e) { + throw new IllegalStateException( + "Error retrieving ID generator " + + "\'" + csid + "\'" + + " from database: " + e.getMessage()); + } finally { + try { + if (conn != null) { + conn.close(); + } + } catch(SQLException e) { + // Do nothing here + } + } + + logger.debug("> retrieved BaseIDGenerator: " + serializedGenerator); + + return serializedGenerator; + + } + + } 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 index 6dc5ae05a..8580f0de5 100644 --- 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 @@ -14,9 +14,11 @@ * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt * - * $LastChangedBy$ - * $LastChangedRevision$ - * $LastChangedDate$ + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ // @TODO: Add Javadoc comments @@ -37,14 +39,15 @@ import java.util.regex.Pattern; * $LastChangedRevision$ * $LastChangedDate$ */ -public class NumericIDGeneratorPart implements IDGeneratorPart { +public class NumericIDGeneratorPart implements SequenceIDGeneratorPart { final static private int DEFAULT_MAX_LENGTH = 6; private int maxLength = DEFAULT_MAX_LENGTH; final static private int DEFAULT_INITIAL_VALUE = 1; + final static private long CURRENT_VALUE_NOT_SET = -1; private long initialValue = DEFAULT_INITIAL_VALUE; - private long currentValue = DEFAULT_INITIAL_VALUE; + private long currentValue = CURRENT_VALUE_NOT_SET; // Constructor using defaults for initial value and maximum length. public NumericIDGeneratorPart() throws IllegalArgumentException { @@ -73,7 +76,7 @@ public class NumericIDGeneratorPart implements IDGeneratorPart { throw new IllegalArgumentException( "Initial ID value should be zero (0) or greater"); } - this.currentValue = l; + // this.currentValue = l; this.initialValue = l; } catch (NullPointerException e) { throw new IllegalArgumentException( @@ -102,7 +105,11 @@ public class NumericIDGeneratorPart implements IDGeneratorPart { } public String getCurrentID() { - return Long.toString(this.currentValue); + if (this.currentValue == CURRENT_VALUE_NOT_SET) { + return Long.toString(this.initialValue); + } else { + return Long.toString(this.currentValue); + } } // Sets the current value of the ID. @@ -123,7 +130,6 @@ public class NumericIDGeneratorPart implements IDGeneratorPart { "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"); @@ -137,13 +143,13 @@ public class NumericIDGeneratorPart implements IDGeneratorPart { 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++; + if (this.currentValue == CURRENT_VALUE_NOT_SET) { + this.currentValue = this.initialValue; + } else { + this.currentValue++; + } String nextID = Long.toString(this.currentValue); if (nextID.length() > this.maxLength) { throw new IllegalStateException( @@ -151,15 +157,26 @@ public class NumericIDGeneratorPart implements IDGeneratorPart { } return nextID; } + + /** + * Returns a new identifier. + */ + @Override + public String newID() { + return nextID(); + } - public boolean isValidID(String value) { - - if ( value == null || value == "") { - return false; - } + @Override + public boolean isValidID(String id) { + + if (id == null) return false; + + // @TODO May potentially throw at least one pattern-related exception. + // We'll need to catch and handle this here, as well as in all + // derived classes and test cases that invoke validation. Pattern pattern = Pattern.compile(getRegex()); - Matcher matcher = pattern.matcher(value); + Matcher matcher = pattern.matcher(id); if (matcher.matches()) { return true; } else { @@ -168,6 +185,7 @@ public class NumericIDGeneratorPart implements IDGeneratorPart { } + @Override public String getRegex() { String regex = "(" + "\\d" + "{1," + Integer.toString(this.maxLength) + "}" + ")"; 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 index 19254a351..435162d0a 100644 --- 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 @@ -13,6 +13,12 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ // @TODO: Add Javadoc comments @@ -33,7 +39,8 @@ import java.util.regex.PatternSyntaxException; * $LastChangedRevision$ * $LastChangedDate$ */ -public class StringIDGeneratorPart implements IDGeneratorPart { +public class StringIDGeneratorPart implements IDGeneratorPart, + StoredValueIDGeneratorPart { private String initialValue = null; private String currentValue = null; @@ -51,10 +58,12 @@ public class StringIDGeneratorPart implements IDGeneratorPart { } + @Override public String getInitialID() { return this.initialValue; } + @Override public String getCurrentID() { return this.currentValue; } @@ -66,23 +75,23 @@ public class StringIDGeneratorPart implements IDGeneratorPart { } this.currentValue = value; } - - public void resetID() { - // Do nothing - } - public String nextID() { + @Override + public String newID() { return this.currentValue; - } - - public boolean isValidID(String value) { + } - if (value == null || value.equals("")) { - return false; - } + @Override + public boolean isValidID(String id) { + + if (id == null) return false; + + // @TODO May potentially throw at least one pattern-related exception. + // We'll need to catch and handle this here, as well as in all + // derived classes and test cases that invoke validation. Pattern pattern = Pattern.compile(getRegex()); - Matcher matcher = pattern.matcher(value); + Matcher matcher = pattern.matcher(id); if (matcher.matches()) { return true; } else { @@ -91,6 +100,7 @@ public class StringIDGeneratorPart implements IDGeneratorPart { } + @Override public String getRegex() { String initial = this.initialValue; diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/UUIDGeneratorPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/UUIDGeneratorPart.java new file mode 100644 index 000000000..eea702df7 --- /dev/null +++ b/services/id/service/src/main/java/org/collectionspace/services/id/UUIDGeneratorPart.java @@ -0,0 +1,115 @@ +/** + * 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 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.collectionspace.services.id; + +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +/** + * UUIDGeneratorPart + * + * Generates universally unique identifiers (UUIDs) in the Version 4 format + * (random or pseudorandom numbers), described at + * http://en.wikipedia.org/wiki/Universally_Unique_Identifier#Version_4_.28random.29 + * + * $LastChangedRevision: 625 $ + * $LastChangedDate$ + */ +public class UUIDGeneratorPart implements IDGeneratorPart { + + String currentValue = ""; + + final static String REGEX_PATTERN = + "(" + + "[a-z0-9\\-]{8}" + + "\\-" + + "[a-z0-9\\-]{4}" + + "\\-" + + "4" + + "[a-z0-9\\-]{3}" + + "\\-" + + "[89ab]" + + "[a-z0-9\\-]{3}" + + "\\-" + + "[a-z0-9\\-]{12}" + + ")"; + + final static int UUID_LENGTH = 36; + + /** + * Constructor (no-argument). + */ + public UUIDGeneratorPart() { + } + + public void setCurrentID(String id) { + if (id == null || id.equals("") || (! isValidID(id) )) { + this.currentValue = newID(); + } else { + this.currentValue = id; + } + } + + public String getCurrentID() { + if (this.currentValue == null || this.currentValue.equals("")) { + return newID(); + } else { + return this.currentValue; + } + } + + @Override + public String newID() { + String id = UUID.randomUUID().toString(); + this.currentValue = id; + return id; + } + + @Override + public boolean isValidID(String id) { + + if (id == null) return false; + + // @TODO May potentially throw at least one pattern-related exception. + // We'll need to catch and handle this here, as well as in all + // derived classes and test cases that invoke validation. + + Pattern pattern = Pattern.compile(getRegex()); + Matcher matcher = pattern.matcher(id); + if (matcher.matches()) { + return true; + } else { + return false; + } + + } + + @Override + public String getRegex() { + return REGEX_PATTERN; + } + +} diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/YearIDGeneratorPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/YearIDGeneratorPart.java index 286fa843e..2b0364e11 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/YearIDGeneratorPart.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/YearIDGeneratorPart.java @@ -13,6 +13,12 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ // @TODO: Add Javadoc comments @@ -56,6 +62,10 @@ public class YearIDGeneratorPart implements IDGeneratorPart { private String initialValue = null; private String currentValue = null; + // NOTE: Currently hard-coded to accept only a range of + // four-digit Gregorian Calendar year dates. + final static String REGEX_PATTERN = "(\\d{4})"; + public YearIDGeneratorPart() throws IllegalArgumentException { String currentYear = getCurrentYear(); @@ -117,34 +127,40 @@ public class YearIDGeneratorPart implements IDGeneratorPart { public String nextID() { return this.currentValue; } + + @Override + public String newID() { + return getCurrentYear(); + } + + @Override + public boolean isValidID(String id) { + + if (id == null) return false; + + // @TODO May potentially throw at least one pattern-related exception. + // We'll need to catch and handle this here, as well as in all + // derived classes and test cases that invoke validation. + + Pattern pattern = Pattern.compile(getRegex()); + Matcher matcher = pattern.matcher(id); + if (matcher.matches()) { + return true; + } else { + return false; + } + + } + + @Override + public String getRegex() { + return REGEX_PATTERN; + } public static String getCurrentYear() { Calendar cal = GregorianCalendar.getInstance(); int y = cal.get(Calendar.YEAR); return Integer.toString(y); } - - public boolean isValidID(String value) throws IllegalArgumentException { - - 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() { - // NOTE: Currently hard-coded to accept only a range of - // four-digit Gregorian Calendar year dates. - String regex = "(\\d{4})"; - return regex; - } } diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/AlphabeticIDGeneratorPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/AlphabeticIDGeneratorPartTest.java index 751202acc..85e601397 100644 --- a/services/id/service/src/test/java/org/collectionspace/services/id/test/AlphabeticIDGeneratorPartTest.java +++ b/services/id/service/src/test/java/org/collectionspace/services/id/test/AlphabeticIDGeneratorPartTest.java @@ -13,6 +13,12 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.collectionspace.services.id; @@ -30,94 +36,84 @@ import junit.framework.TestCase; */ public class AlphabeticIDGeneratorPartTest extends TestCase { - IDGeneratorPart part; + SequenceIDGeneratorPart part; public void testNextIDLowercase() { part = new AlphabeticIDGeneratorPart("a"); - assertEquals("b", part.nextID()); - assertEquals("c", part.nextID()); + assertEquals("a", part.newID()); + assertEquals("b", part.newID()); + assertEquals("c", part.newID()); part = new AlphabeticIDGeneratorPart("x"); - assertEquals("y", part.nextID()); - assertEquals("z", part.nextID()); + assertEquals("x", part.newID()); + assertEquals("y", part.newID()); + assertEquals("z", part.newID()); } - public void testnextIDLowercase2Chars() { + public void testnewIDLowercase2Chars() { part = new AlphabeticIDGeneratorPart("aa"); - assertEquals("ab", part.nextID()); - assertEquals("ac", part.nextID()); + assertEquals("aa", part.newID()); + assertEquals("ab", part.newID()); + assertEquals("ac", part.newID()); part = new AlphabeticIDGeneratorPart("zx"); - assertEquals("zy", part.nextID()); - assertEquals("zz", part.nextID()); + assertEquals("zx", part.newID()); + assertEquals("zy", part.newID()); + assertEquals("zz", part.newID()); } - public void testnextIDLowercase2CharsRolloverFirst() { + public void testnewIDLowercase2CharsRolloverFirst() { part = new AlphabeticIDGeneratorPart("ay"); - assertEquals("az", part.nextID()); - assertEquals("ba", part.nextID()); - assertEquals("bb", part.nextID()); + assertEquals("ay", part.newID()); + assertEquals("az", part.newID()); + assertEquals("ba", part.newID()); + assertEquals("bb", part.newID()); - } + } - public void testnextIDUppercase() { + public void testnewIDUppercase() { part = new AlphabeticIDGeneratorPart("A", "Z", "A"); - assertEquals("B", part.nextID()); - assertEquals("C", part.nextID()); + assertEquals("A", part.newID()); + assertEquals("B", part.newID()); + assertEquals("C", part.newID()); part = new AlphabeticIDGeneratorPart("A", "Z", "X"); - assertEquals("Y", part.nextID()); - assertEquals("Z", part.nextID()); + assertEquals("X", part.newID()); + assertEquals("Y", part.newID()); + assertEquals("Z", part.newID()); -} + } - public void testnextIDUppercase2Chars() { + public void testnewIDUppercase2Chars() { part = new AlphabeticIDGeneratorPart("A", "Z", "AA"); - assertEquals("AB", part.nextID()); - assertEquals("AC", part.nextID()); + assertEquals("AA", part.newID()); + assertEquals("AB", part.newID()); + assertEquals("AC", part.newID()); part = new AlphabeticIDGeneratorPart("A", "Z", "ZX"); - assertEquals("ZY", part.nextID()); - assertEquals("ZZ", part.nextID()); + assertEquals("ZX", part.newID()); + assertEquals("ZY", part.newID()); + assertEquals("ZZ", part.newID()); } - public void testnextIDUppercase2CharsRolloverFirst() { + public void testnewIDUppercase2CharsRolloverFirst() { part = new AlphabeticIDGeneratorPart("A", "Z", "AY"); - assertEquals("AZ", part.nextID()); - assertEquals("BA", part.nextID()); - assertEquals("BB", part.nextID()); + assertEquals("AY", part.newID()); + assertEquals("AZ", part.newID()); + assertEquals("BA", part.newID()); + assertEquals("BB", part.newID()); } - - public void testresetIDLowercase() { - - part = new AlphabeticIDGeneratorPart("zx"); - assertEquals("zy", part.nextID()); - assertEquals("zz", part.nextID()); - part.resetID(); - assertEquals("zx", part.getCurrentID()); - - } - public void testresetIDUppercase() { - - part = new AlphabeticIDGeneratorPart("A", "Z", "RA"); - assertEquals("RB", part.nextID()); - assertEquals("RC", part.nextID()); - part.resetID(); - assertEquals("RB", part.nextID()); - - } - public void testInitialLowercase() { part = new AlphabeticIDGeneratorPart("aaa"); @@ -136,10 +132,11 @@ public class AlphabeticIDGeneratorPartTest extends TestCase { part = new AlphabeticIDGeneratorPart("aaa"); assertEquals("aaa", part.getCurrentID()); - assertEquals("aab", part.nextID()); - assertEquals("aac", part.nextID()); + assertEquals("aaa", part.newID()); + assertEquals("aab", part.newID()); + assertEquals("aac", part.newID()); assertEquals("aac", part.getCurrentID()); - assertEquals("aad", part.nextID()); + assertEquals("aad", part.newID()); } @@ -147,28 +144,31 @@ public class AlphabeticIDGeneratorPartTest extends TestCase { part = new AlphabeticIDGeneratorPart("A", "Z", "A"); assertEquals("A", part.getCurrentID()); - assertEquals("B", part.nextID()); - assertEquals("C", part.nextID()); + assertEquals("A", part.newID()); + assertEquals("B", part.newID()); + assertEquals("C", part.newID()); assertEquals("C", part.getCurrentID()); - assertEquals("D", part.nextID()); + assertEquals("D", part.newID()); } - + public void testOverflowLowercase() { - part = new AlphabeticIDGeneratorPart("zx"); - assertEquals("zy", part.nextID()); - assertEquals("zz", part.nextID()); - assertEquals("aaa", part.nextID()); + part = new AlphabeticIDGeneratorPart("zx"); + assertEquals("zx", part.newID()); + assertEquals("zy", part.newID()); + assertEquals("zz", part.newID()); + assertEquals("aaa", part.newID()); } public void testOverflowUppercase() { - part = new AlphabeticIDGeneratorPart("A", "Z", "X"); - assertEquals("Y", part.nextID()); - assertEquals("Z", part.nextID()); - assertEquals("AA", part.nextID()); + part = new AlphabeticIDGeneratorPart("A", "Z", "X"); + assertEquals("X", part.newID()); + assertEquals("Y", part.newID()); + assertEquals("Z", part.newID()); + assertEquals("AA", part.newID()); } 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 index 50a484a5c..4f3b9f0d7 100644 --- 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 @@ -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: @@ -13,15 +13,25 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.collectionspace.services.id; -import static org.junit.Assert.fail; +import java.util.Calendar; +import java.util.GregorianCalendar; import java.util.Vector; + import junit.framework.TestCase; +import static org.junit.Assert.fail; + -/** +/** * IDGeneratorTest, Test class for IDGenerator. * * $LastChangedRevision$ @@ -29,243 +39,405 @@ import junit.framework.TestCase; */ 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 ... + 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 testEmptyPartsListCurrentID() { + generator = new BaseIDGenerator(DEFAULT_CSID); + assertEquals("", generator.getCurrentID()); + } + + public void testEmptyPartsListNewID() { + generator = new BaseIDGenerator(DEFAULT_CSID); + assertEquals("", generator.newID()); + } + + public void testCurrentIDViaVector() { + + Vector parts = new Vector(); + + parts.clear(); + parts.add(new AlphabeticIDGeneratorPart("a")); + generator = new BaseIDGenerator(DEFAULT_CSID, parts); + assertEquals("a", generator.getCurrentID()); + + parts.clear(); + parts.add(new NumericIDGeneratorPart("1")); + generator = new BaseIDGenerator(DEFAULT_CSID, parts); + assertEquals("1", generator.getCurrentID()); + + parts.clear(); + parts.add(new StringIDGeneratorPart("PREFIX")); + parts.add(new StringIDGeneratorPart("-")); + parts.add(new StringIDGeneratorPart("SUFFIX")); + generator = new BaseIDGenerator(DEFAULT_CSID, parts); + assertEquals("PREFIX-SUFFIX", generator.getCurrentID()); + + parts.clear(); + parts.add(new YearIDGeneratorPart()); + generator = new BaseIDGenerator(DEFAULT_CSID, parts); + assertEquals(getCurrentYear(), generator.getCurrentID()); + + parts.clear(); + parts.add(new UUIDGeneratorPart()); + generator = new BaseIDGenerator(DEFAULT_CSID, parts); + assertTrue(generator.getCurrentID().length() == + UUIDGeneratorPart.UUID_LENGTH); + + parts.clear(); + 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("E1", generator.getCurrentID("E")); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart()); + generator.add(new StringIDGeneratorPart(".")); + assertEquals("2009.", generator.getCurrentID("2009")); + assertEquals("2009.", generator.getCurrentID("2009")); + assertEquals("2010.", generator.getCurrentID("2010")); + assertEquals("2010.", generator.getCurrentID("2010")); + + 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.1", generator.getCurrentID("2009.")); + + 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.55", generator.getCurrentID("2010.")); + + 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.1", generator.getCurrentID("2009.")); + + 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-a", generator.getCurrentID("2009.1-")); + assertEquals("2009.3-a", generator.getCurrentID("2009.3-")); + 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 testNewAlphabeticLowercaseID() { + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new AlphabeticIDGeneratorPart("a")); + assertEquals("a", generator.newID()); + assertEquals("b", generator.newID()); + assertEquals("c", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new AlphabeticIDGeneratorPart("aa")); + assertEquals("aa", generator.newID()); + assertEquals("ab", generator.newID()); + assertEquals("ac", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new AlphabeticIDGeneratorPart("az")); + assertEquals("az", generator.newID()); + assertEquals("ba", generator.newID()); + assertEquals("bb", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new AlphabeticIDGeneratorPart("a")); + generator.add(new AlphabeticIDGeneratorPart("yy")); + assertEquals("ayy", generator.newID()); + assertEquals("ayz", generator.newID()); + assertEquals("aza", generator.newID()); + } + + public void testNewAlphabeticUppercaseID() { + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new AlphabeticIDGeneratorPart("A", "Z", "A")); + assertEquals("A", generator.newID()); + assertEquals("B", generator.newID()); + assertEquals("C", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new AlphabeticIDGeneratorPart("A", "Z", "AA")); + assertEquals("AA", generator.newID()); + assertEquals("AB", generator.newID()); + assertEquals("AC", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new AlphabeticIDGeneratorPart("A", "Z", "AZ")); + assertEquals("AZ", generator.newID()); + assertEquals("BA", generator.newID()); + assertEquals("BB", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new AlphabeticIDGeneratorPart("A", "Z", "A")); + generator.add(new AlphabeticIDGeneratorPart("A", "Z", "YY")); + assertEquals("AYY", generator.newID()); + assertEquals("AYZ", generator.newID()); + assertEquals("AZA", generator.newID()); + } + + public void testNewStringID() { + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new StringIDGeneratorPart("PREFIX")); + assertEquals("PREFIX", generator.newID()); + assertEquals("PREFIX", generator.newID()); + assertEquals("PREFIX", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new AlphabeticIDGeneratorPart("A", "Z", "AA")); + assertEquals("AA", generator.newID()); + assertEquals("AB", generator.newID()); + assertEquals("AC", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new AlphabeticIDGeneratorPart("A", "Z", "AZ")); + assertEquals("AZ", generator.newID()); + assertEquals("BA", generator.newID()); + assertEquals("BB", generator.newID()); + } + + public void testNewUUID() { + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new UUIDGeneratorPart()); + String firstID = generator.newID(); + String secondID = generator.newID(); + String thirdID = generator.newID(); + assertTrue(firstID.length() == UUIDGeneratorPart.UUID_LENGTH); + assertTrue(secondID.length() == UUIDGeneratorPart.UUID_LENGTH); + assertTrue(thirdID.length() == UUIDGeneratorPart.UUID_LENGTH); + assertTrue(firstID.compareTo(secondID) != 0); + assertTrue(firstID.compareTo(thirdID) != 0); + assertTrue(secondID.compareTo(thirdID) != 0); + } + + public void testNewID() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new NumericIDGeneratorPart("1")); + assertEquals("1", generator.newID()); + assertEquals("2", generator.newID()); + assertEquals("3", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart()); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + assertEquals(getCurrentYear() + ".1", generator.newID()); + assertEquals(getCurrentYear() + ".2", generator.newID()); + assertEquals(getCurrentYear() + ".3", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart()); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + generator.add(new StringIDGeneratorPart("-")); + generator.add(new AlphabeticIDGeneratorPart("a")); + assertEquals(getCurrentYear() + ".1-a", generator.newID()); + assertEquals(getCurrentYear() + ".1-b", generator.newID()); + assertEquals(getCurrentYear() + ".1-c", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new StringIDGeneratorPart("T")); + generator.add(new NumericIDGeneratorPart("1005")); + assertEquals("T1005", generator.newID()); + assertEquals("T1006", generator.newID()); + assertEquals("T1007", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart()); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + assertEquals(getCurrentYear() + ".1.1", generator.newID()); + assertEquals(getCurrentYear() + ".1.2", generator.newID()); + assertEquals(getCurrentYear() + ".1.3", generator.newID()); + + } + + public void testNewIDWithTrailingConstantStringID() { + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart()); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("1")); + generator.add(new StringIDGeneratorPart("-")); + assertEquals(getCurrentYear() + ".1-", generator.newID()); + assertEquals(getCurrentYear() + ".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.1", generator.newID("2009.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-a", generator.newID("2009.1-a")); + assertEquals("2009.1-b", generator.newID()); + assertEquals("2009.1-c", generator.newID()); + + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart("2009")); + generator.add(new StringIDGeneratorPart(".")); + generator.add(new NumericIDGeneratorPart("3")); + generator.add(new StringIDGeneratorPart("-")); + generator.add(new AlphabeticIDGeneratorPart("b")); + assertEquals("2009.3-b", generator.newID("2009.3-b")); + assertEquals("2009.3-c", generator.newID()); + assertEquals("2009.3-d", generator.newID()); + + } + + public void testValidUUID() { + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new UUIDGeneratorPart()); + + assertTrue(generator.isValidID("4c9395a8-1669-41f9-806c-920d86e40912")); + + // Invalid character in 15th position (should be '4'). + assertFalse(generator.isValidID("4c9395a8-1669-31f9-806c-920d86e40912")); + // Invalid character in 20th position (should be '8', '9', 'a', or 'b'). + assertFalse(generator.isValidID("4c9395a8-1669-41f9-106c-920d86e40912")); + assertFalse(generator.isValidID(null)); + assertFalse(generator.isValidID("")); + assertFalse(generator.isValidID("not a UUID")); + assertFalse(generator.isValidID("12345")); + } + + public void testValidYearID() { + generator = new BaseIDGenerator(DEFAULT_CSID); + generator.add(new YearIDGeneratorPart()); + + 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")); + + } + + public static String getCurrentYear() { + Calendar cal = GregorianCalendar.getInstance(); + int y = cal.get(Calendar.YEAR); + return Integer.toString(y); + } + + // @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 626352630..1576429fa 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 @@ -13,6 +13,12 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.collectionspace.services.id.test; @@ -43,6 +49,9 @@ public class IDServiceJdbcImplTest { final static String TABLE_NAME = "id_generators"; final static String DEFAULT_CSID = "TEST-1"; + + final static String CURRENT_YEAR = YearIDGeneratorPart.getCurrentYear(); + @Test public void hasRequiredDatabaseTable() { @@ -55,19 +64,24 @@ public class IDServiceJdbcImplTest { @Test(dependsOnMethods = {"hasRequiredDatabaseTable"}) public void addIDGenerator() { + try { + jdbc.deleteIDGenerator(DEFAULT_CSID); + } catch (Exception e) { + // Fail silently; this is guard code. + } jdbc.addIDGenerator(DEFAULT_CSID, getSpectrumEntryNumberGenerator()); } - @Test(dependsOnMethods = {"addIDGenerator"}) + @Test(dependsOnMethods = {"hasRequiredDatabaseTable", "addIDGenerator"}) public void readIDGenerator() { serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID); generator = IDGeneratorSerializer.deserialize(serializedGenerator); - Assert.assertEquals(DEFAULT_CSID, generator.getCsid()); + Assert.assertEquals(generator.getCsid(), DEFAULT_CSID); } - @Test(dependsOnMethods = {"addIDGenerator"}) + @Test(dependsOnMethods = {"hasRequiredDatabaseTable", "addIDGenerator", "readIDGenerator"}) public void updateIDGenerator() { final String NEW_DESCRIPTION = "new description"; @@ -84,53 +98,54 @@ public class IDServiceJdbcImplTest { serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID); generator = IDGeneratorSerializer.deserialize(serializedGenerator); - Assert.assertEquals(NEW_DESCRIPTION, generator.getDescription()); + Assert.assertEquals(generator.getDescription(), NEW_DESCRIPTION); } - @Test(dependsOnMethods = {"addIDGenerator", "readIDGenerator"}) + @Test(dependsOnMethods = {"hasRequiredDatabaseTable", "addIDGenerator", + "readIDGenerator", "updateIDGenerator"}) public void deleteIDGenerator() { jdbc.deleteIDGenerator(DEFAULT_CSID); } + - @Test(dependsOnMethods = {"addIDGenerator", "deleteIDGenerator"}) + @Test(dependsOnMethods = {"hasRequiredDatabaseTable", "addIDGenerator", "readIDGenerator", + "updateIDGenerator", "deleteIDGenerator"}) public void newIDValidPattern() { - - csid = DEFAULT_CSID; - + try { - jdbc.deleteIDGenerator(csid); + jdbc.deleteIDGenerator(DEFAULT_CSID); } catch (Exception e) { - // do nothing + // Fail silently; this is guard code. } - - jdbc.addIDGenerator(csid, getSpectrumEntryNumberGenerator()); - Assert.assertEquals("E1", service.newID(csid)); - Assert.assertEquals("E2", service.newID(csid)); - Assert.assertEquals("E3", service.newID(csid)); + jdbc.addIDGenerator(DEFAULT_CSID, getSpectrumEntryNumberGenerator()); + + Assert.assertEquals(service.newID(DEFAULT_CSID), "E1"); + Assert.assertEquals(service.newID(DEFAULT_CSID), "E2"); + Assert.assertEquals(service.newID(DEFAULT_CSID), "E3"); try { - jdbc.deleteIDGenerator(csid); + jdbc.deleteIDGenerator(DEFAULT_CSID); } catch (Exception e) { - // do nothing + Assert.fail("Could not delete ID generator '" + DEFAULT_CSID + "'."); } - jdbc.addIDGenerator(csid, getChinAccessionNumberGenerator()); + jdbc.addIDGenerator(DEFAULT_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)); + Assert.assertEquals(service.newID(DEFAULT_CSID), CURRENT_YEAR + ".1.1"); + Assert.assertEquals(service.newID(DEFAULT_CSID), CURRENT_YEAR + ".1.2"); + Assert.assertEquals(service.newID(DEFAULT_CSID), CURRENT_YEAR + ".1.3"); try { - jdbc.deleteIDGenerator(csid); + jdbc.deleteIDGenerator(DEFAULT_CSID); } catch (Exception e) { - // do nothing + Assert.fail("Could not delete ID generator '" + DEFAULT_CSID + "'."); } } + // 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 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 index 9ecb44c92..eb51afa1b 100644 --- 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 @@ -17,6 +17,12 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.collectionspace.services.id; @@ -34,32 +40,37 @@ import junit.framework.TestCase; */ public class NumericIDGeneratorPartTest extends TestCase { - IDGeneratorPart part; + SequenceIDGeneratorPart part; - public void testNextID() { + public void testNewID() { part = new NumericIDGeneratorPart("0"); - assertEquals("1", part.nextID()); - assertEquals("2", part.nextID()); - assertEquals("3", part.nextID()); + assertEquals("0", part.newID()); + assertEquals("1", part.newID()); + assertEquals("2", part.newID()); + assertEquals("3", part.newID()); part = new NumericIDGeneratorPart("25"); - assertEquals("26", part.nextID()); - assertEquals("27", part.nextID()); - assertEquals("28", part.nextID()); + assertEquals("25", part.newID()); + assertEquals("26", part.newID()); + assertEquals("27", part.newID()); + assertEquals("28", part.newID()); part = new NumericIDGeneratorPart(); - assertEquals("2", part.nextID()); + assertEquals("1", part.newID()); + assertEquals("2", part.newID()); + assertEquals("3", part.newID()); } - public void testNextIDOverflow() { + public void testNewIDOverflow() { try { part = new NumericIDGeneratorPart("997", "3"); - assertEquals("998", part.nextID()); - assertEquals("999", part.nextID()); - assertEquals("1000", part.nextID()); + assertEquals("997", part.newID()); + assertEquals("998", part.newID()); + assertEquals("999", part.newID()); + assertEquals("1000", part.newID()); fail("Should have thrown IllegalStateException here"); } catch (IllegalStateException expected) { // This Exception should be thrown, and thus the test should pass. @@ -68,9 +79,10 @@ public class NumericIDGeneratorPartTest extends TestCase { // 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()); + assertEquals("999997", part.newID()); + assertEquals("999998", part.newID()); + assertEquals("999999", part.newID()); + assertEquals("1000000", part.newID()); fail("Should have thrown IllegalStateException here"); } catch (IllegalStateException expected) { // This Exception should be thrown, and thus the test should pass. @@ -78,17 +90,6 @@ public class NumericIDGeneratorPartTest extends TestCase { } - 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"); @@ -103,16 +104,17 @@ public class NumericIDGeneratorPartTest extends TestCase { part = new NumericIDGeneratorPart("0"); assertEquals("0", part.getCurrentID()); - assertEquals("1", part.nextID()); - assertEquals("2", part.nextID()); + assertEquals("0", part.newID()); + assertEquals("1", part.newID()); + assertEquals("2", part.newID()); assertEquals("2", part.getCurrentID()); - assertEquals("3", part.nextID()); + assertEquals("3", part.newID()); part = new NumericIDGeneratorPart("25"); assertEquals("25", part.getCurrentID()); } - + public void testNullInitialValue() { try { diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/StringIDGeneratorPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/StringIDGeneratorPartTest.java index 41eae6832..a13db7ab5 100644 --- a/services/id/service/src/test/java/org/collectionspace/services/id/test/StringIDGeneratorPartTest.java +++ b/services/id/service/src/test/java/org/collectionspace/services/id/test/StringIDGeneratorPartTest.java @@ -13,6 +13,12 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.collectionspace.services.id; @@ -30,26 +36,28 @@ import junit.framework.TestCase; */ public class StringIDGeneratorPartTest extends TestCase { - IDGeneratorPart part; + StoredValueIDGeneratorPart part; - public void testNextID() { + public void testnewID() { part = new StringIDGeneratorPart("E"); - assertEquals("E", part.nextID()); + assertEquals("E", part.newID()); part = new StringIDGeneratorPart("XYZ"); - assertEquals("XYZ", part.nextID()); + assertEquals("XYZ", part.newID()); } +/* public void testresetID() { part = new StringIDGeneratorPart("."); - assertEquals(".", part.nextID()); + assertEquals(".", part.newID()); part.resetID(); - assertEquals(".", part.nextID()); + assertEquals(".", part.newID()); } +*/ public void testInitialID() { part = new StringIDGeneratorPart("-"); diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/UUIDGeneratorPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/UUIDGeneratorPartTest.java new file mode 100644 index 000000000..2ab2116e7 --- /dev/null +++ b/services/id/service/src/test/java/org/collectionspace/services/id/test/UUIDGeneratorPartTest.java @@ -0,0 +1,77 @@ +/* + * 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 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.collectionspace.services.id; + +import static org.junit.Assert.fail; +import junit.framework.TestCase; + +/** + * UUIDGeneratorPartTest + * + * Test class for UUIDGeneratorPart. + * + * $LastChangedRevision: 625 $ + * $LastChangedDate$ + */ +public class UUIDGeneratorPartTest extends TestCase { + + IDGeneratorPart part; + + public void testnewID() { + + part = new UUIDGeneratorPart(); + + String firstID = part.newID(); + String secondID = part.newID(); + String thirdID = part.newID(); + + assertTrue(firstID.length() == UUIDGeneratorPart.UUID_LENGTH); + assertTrue(secondID.length() == UUIDGeneratorPart.UUID_LENGTH); + assertTrue(thirdID.length() == UUIDGeneratorPart.UUID_LENGTH); + + assertTrue(firstID.compareTo(secondID) != 0); + assertTrue(firstID.compareTo(thirdID) != 0); + assertTrue(secondID.compareTo(thirdID) != 0); + + } + + public void testIsValidID() { + + part = new UUIDGeneratorPart(); + assertTrue(part.isValidID("2d5ef3cc-bfb2-4383-a4c6-35645cd5dd81")); + + part = new UUIDGeneratorPart(); + assertFalse(part.isValidID("foo")); + + part = new UUIDGeneratorPart(); + assertFalse(part.isValidID(null)); + + part = new UUIDGeneratorPart(); + assertFalse(part.isValidID("")); + + } + + // @TODO: Add more tests of boundary conditions, exceptions ... + +} 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 index 37a0495a3..41ae11b1a 100644 --- 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 @@ -13,6 +13,12 @@ * * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.collectionspace.services.id; @@ -41,6 +47,7 @@ public class YearIDGeneratorPartTest extends TestCase { return Integer.toString(y); } +/* public void testCurrentID() { part = new YearIDGeneratorPart(); @@ -80,30 +87,43 @@ public class YearIDGeneratorPartTest extends TestCase { } } - - public void testNextID() { +*/ + +/* + public void testnewID() { part = new YearIDGeneratorPart("1999"); - assertEquals("1999", part.nextID()); + assertEquals("1999", part.newID()); + + } +*/ + + public void testnewID() { + + part = new YearIDGeneratorPart(); + assertEquals(getCurrentYear(), part.newID()); } +/* public void testresetID() { part = new YearIDGeneratorPart("1999"); - assertEquals("1999", part.nextID()); + assertEquals("1999", part.newID()); part.resetID(); assertEquals("1999", part.getCurrentID()); } +*/ +/* public void testInitialID() { part = new YearIDGeneratorPart("1999"); assertEquals("1999", part.getInitialID()); } - +*/ public void testNullInitialValue() {