]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-361: Initial steps toward larger refactoring of ID Service
authorAron Roberts <aron@socrates.berkeley.edu>
Fri, 4 Sep 2009 19:28:13 +0000 (19:28 +0000)
committerAron Roberts <aron@socrates.berkeley.edu>
Fri, 4 Sep 2009 19:28:13 +0000 (19:28 +0000)
30 files changed:
services/id/client/pom.xml [new file with mode: 0644]
services/id/client/src/test/resources/log4j.properties [new file with mode: 0644]
services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java [deleted file]
services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGeneratorPart.java [new file with mode: 0644]
services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDPart.java [deleted file]
services/id/service/src/main/java/org/collectionspace/services/id/BaseIDGenerator.java [moved from services/id/service/src/main/java/org/collectionspace/services/id/IDPattern.java with 81% similarity]
services/id/service/src/main/java/org/collectionspace/services/id/IDGenerator.java
services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorPart.java [new file with mode: 0644]
services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorSerializer.java
services/id/service/src/main/java/org/collectionspace/services/id/IDPart.java [deleted file]
services/id/service/src/main/java/org/collectionspace/services/id/IDResource.java
services/id/service/src/main/java/org/collectionspace/services/id/IDServiceJdbcImpl.java
services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGenerator.java [deleted file]
services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGeneratorPart.java [new file with mode: 0644]
services/id/service/src/main/java/org/collectionspace/services/id/NumericIDPart.java [deleted file]
services/id/service/src/main/java/org/collectionspace/services/id/StringIDGenerator.java [deleted file]
services/id/service/src/main/java/org/collectionspace/services/id/StringIDGeneratorPart.java [new file with mode: 0644]
services/id/service/src/main/java/org/collectionspace/services/id/StringIDPart.java [deleted file]
services/id/service/src/main/java/org/collectionspace/services/id/YearIDGeneratorPart.java [moved from services/id/service/src/main/java/org/collectionspace/services/id/YearIDGenerator.java with 90% similarity]
services/id/service/src/main/java/org/collectionspace/services/id/YearIDPart.java [deleted file]
services/id/service/src/test/java/org/collectionspace/services/id/IDPatternTest.java [deleted file]
services/id/service/src/test/java/org/collectionspace/services/id/NumericIDPartTest.java [deleted file]
services/id/service/src/test/java/org/collectionspace/services/id/YearIDPartTest.java [deleted file]
services/id/service/src/test/java/org/collectionspace/services/id/test/AlphabeticIDGeneratorPartTest.java [moved from services/id/service/src/test/java/org/collectionspace/services/id/AlphabeticIDPartTest.java with 77% similarity]
services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorSerializerTest.java
services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorTest.java [new file with mode: 0644]
services/id/service/src/test/java/org/collectionspace/services/id/test/IDServiceJdbcImplTest.java
services/id/service/src/test/java/org/collectionspace/services/id/test/NumericIDGeneratorPartTest.java [new file with mode: 0644]
services/id/service/src/test/java/org/collectionspace/services/id/test/StringIDGeneratorPartTest.java [moved from services/id/service/src/test/java/org/collectionspace/services/id/StringIDPartTest.java with 69% similarity]
services/id/service/src/test/java/org/collectionspace/services/id/test/YearIDGeneratorPartTest.java [new file with mode: 0644]

diff --git a/services/id/client/pom.xml b/services/id/client/pom.xml
new file mode 100644 (file)
index 0000000..66fbd1a
--- /dev/null
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <parent>
+        <artifactId>org.collectionspace.services.id</artifactId>
+        <groupId>org.collectionspace.services</groupId>
+        <version>1.0</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.collectionspace.services</groupId>
+    <artifactId>org.collectionspace.services.id.client</artifactId>
+    <version>1.0</version>
+    <name>services.id.client</name>
+    
+    <dependencies>
+        <!-- keep slf4j dependencies on the top -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.collectionspace.services</groupId>
+            <artifactId>org.collectionspace.services.client</artifactId>
+            <version>1.0</version>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>5.6</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jaxrs</artifactId>
+            <version>1.0.2.GA</version>
+            <!-- filter out unwanted jars -->
+            <exclusions>
+                <exclusion>
+                    <groupId>tjws</groupId>
+                    <artifactId>webserver</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jaxb-provider</artifactId>
+            <version>1.0.2.GA</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-multipart-provider</artifactId>
+            <version>1.0.2.GA</version>
+        </dependency>
+    </dependencies>
+    
+    <build>
+        <finalName>cspace-services-id-client</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <systemProperties>
+                        <property>
+                            <name>log4j.configuration</name>
+                            <value>file:target/test-classes/log4j.properties</value>
+                        </property>
+                    </systemProperties>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.0.2</version>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
+
diff --git a/services/id/client/src/test/resources/log4j.properties b/services/id/client/src/test/resources/log4j.properties
new file mode 100644 (file)
index 0000000..148a3e8
--- /dev/null
@@ -0,0 +1,23 @@
+log4j.rootLogger=debug, stdout, R
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+
+# Pattern to output the caller's file name and line number.
+log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n
+
+log4j.appender.R=org.apache.log4j.RollingFileAppender
+log4j.appender.R.File=target/test-client.log
+
+log4j.appender.R.MaxFileSize=100KB
+# Keep one backup file
+log4j.appender.R.MaxBackupIndex=1
+
+log4j.appender.R.layout=org.apache.log4j.PatternLayout
+log4j.appender.R.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n
+
+#packages
+log4j.logger.org.collectionspace=DEBUG
+log4j.logger.org.apache=INFO
+log4j.logger.httpclient=INFO
+log4j.logger.org.jboss.resteasy=INFO
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java b/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java
deleted file mode 100644 (file)
index 4f5444d..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/*     
- * AlphabeticIDGenerator
- *
- * Generates identifiers (IDs) that consist of incrementing alphabetic
- * characters, from within a sequence of characters.
- *
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
- */
-
-// @TODO: Add Javadoc comments
-
-// @TODO: When auto expanding, we'll need to allow setting of a maximum length to
-// which the generated IDs can grow, likely as an additional parameter to be
-// passed to a constructor, with a default value hard-coded in the class.
-// If that length is exceeded, nextID() should throw an IllegalStateException.
-
-// @TODO: Consider handling escaped characters or sequences which represent Unicode
-// code points, both in the start and end characters of the sequence, and in the initial value.
-// (Example: '\u0072' for the USASCII 'r' character; see
-// http://www.fileformat.info/info/unicode/char/0072/index.htm)
-//
-// Ideally, we should read these in free-text patterns, alongside unescaped characters,
-// but in practice we may wish to require some structured form for arguments
-// containing such characters.
-//
-// Some initial research on this:
-// http://www.velocityreviews.com/forums/t367758-unescaping-unicode-code-points-in-a-java-string.html
-// We might also look into the (protected) source code for java.util.Properties.load()
-// which reads escaped Unicode values.
-//
-// Note also that, if the goal is to cycle through a sequence of alphabetic identifiers,
-// such as the sequence of characters used in a particular human language, it may or may not
-// be the case that any contiguous Unicode code point sequence reflects such a character sequence.
-
-// NOTE: This class currently hard-codes the assumption that the values in
-// alphabetic identifiers are ordered in significance from left-to-right;
-// that is, the most significant value appears in the left-most position.
-
-package org.collectionspace.services.id;
-
-import java.util.Collections;
-import java.util.Vector;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class AlphabeticIDGenerator implements IDGenerator {
-   
-  private static final char NULL_CHAR = '\u0000';
-
-  private static final String DEFAULT_START_CHAR = "a";
-  private static final String DEFAULT_END_CHAR = "z";
-  private static final String DEFAULT_INITIAL_VALUE = "a";
-         
-  private char startChar = NULL_CHAR;
-  private char endChar = NULL_CHAR;
-  
-       private Vector<Character> initialValue = new Vector<Character>();
-       private Vector<Character> currentValue = new Vector<Character>();
-
-       // Constructor using defaults for character sequence and initial value.
-       //
-  // If no start and end characters are provided for the alphabetic character
-  // sequence, default to an 'a-z' sequence, representing the lowercase alphabetic
-  // characters in the USASCII character set (within Java's internal
-  // Unicode UTF-16 representation).
-  //
-  // Additionally defaults to an initial value of "a".
-       public AlphabeticIDGenerator() throws IllegalArgumentException {
-         
-         this(DEFAULT_START_CHAR, DEFAULT_END_CHAR, DEFAULT_INITIAL_VALUE);
-         
-       }
-
-       // Constructor using defaults for character sequence.
-       //
-  // If no start and end characters are provided for the alphabetic character
-  // sequence, default to an 'a-z' sequence, representing the lowercase alphabetic
-  // characters in the USASCII character set (within Java's internal
-  // Unicode UTF-16 representation).
-       public AlphabeticIDGenerator(String initial) throws IllegalArgumentException {
-         
-         this(DEFAULT_START_CHAR, DEFAULT_END_CHAR, initial);
-         
-       }
-       
-       // Constructor.
-       public AlphabeticIDGenerator(String sequenceStart, String sequenceEnd, String initial)
-         throws IllegalArgumentException {
-         
-         // Validate and store the start character in the character sequence.
-         
-         if (sequenceStart == null || sequenceStart.equals("")) {
-                       throw new IllegalArgumentException(
-                         "Start character in the character sequence must not be null or empty");
-               }
-         
-         if (sequenceStart.length() == 1) {
-      this.startChar = sequenceStart.charAt(0);
-    } else if (false) {
-      // Handle representations of Unicode code points here
-    } else {
-                       throw new IllegalArgumentException(
-                         "Start character must be one character in length");
-                         // "Start character must be one character in length or a Unicode value such as '\u0000'");
-               }
-
-         // Validate and store the end character in the character sequence.
-
-         if (sequenceEnd == null || sequenceEnd.equals("")) {
-                       throw new IllegalArgumentException(
-                         "End character in the character sequence must not be null or empty");
-               }
-         
-         if (sequenceEnd.length() == 1) {
-      this.endChar = sequenceEnd.charAt(0);
-    } else if (false) {
-      // Handle representations of Unicode code points here
-    } else {
-                       throw new IllegalArgumentException(
-                         "End character must be one character in length");
-                         // "End character must be one character in length or a Unicode value such as '\u0000'");
-               }
-    
-         if (this.endChar <= this.startChar) {
-                       throw new IllegalArgumentException(
-                         "End (last) character in the character sequence must be greater than the start character");
-               }
-               
-         // Validate and store the initial value of this identifier.
-
-               if (initial == null || initial.equals("")) {
-                       throw new IllegalArgumentException("Initial value must not be null or empty");
-               }
-               
-               // @TODO: Add a check for maximum length of the initial value here.
-       
-         // Store the chars in the initial value as Characters in a Vector,
-         // validating each character to identify whether it falls within
-         // the provided sequence.
-         //
-         // (Since we're performing casts from char to Character, we can't just
-         // use Arrays.asList() to copy the initial array to a Vector.)
-               char[] chars = initial.toCharArray();
-               char ch;
-               for (int i = 0; i < chars.length; i++) {
-
-      // If the character falls within the provided sequence, copy it to the Vector.
-      ch = chars[i];
-                       if (ch >= this.startChar && ch <= this.endChar) {
-                         this.initialValue.add(new Character(ch));
-      // Otherwise, we've detected a character not in the sequence.
-                       } else {
-        throw new IllegalArgumentException("character " + "\'" + ch + "\'" + " is not valid");
-      }
-                 
-               }
-
-               // Initialize the current value from the initial value.
-               this.currentValue = new Vector<Character>(this.initialValue);
-
-       }
-
-  // Returns the initial value.
-       public String getInitialID() {
-               return getIDString(this.initialValue);
-       }
-
-  // Returns the current value.
-       public String getCurrentID() {
-               return getIDString(this.currentValue);
-       }
-
-  // Sets the current value.
-       public void setCurrentID(String value) throws IllegalArgumentException {
-       
-         // @TODO Much of this code is copied from the main constructor,
-         // and may be ripe for refactoring.
-         
-               if (value == null || value.equals("")) {
-                       throw new IllegalArgumentException("Initial value must not be null or empty");
-               }
-               
-               // @TODO: Add a check for maximum length of the value here.
-       
-         // Store the chars in the value as Characters in a Vector,
-         // validating each character to identify whether it falls within
-         // the provided sequence.
-         //
-         // (Since we're performing casts from char to Character, we can't just
-         // use Arrays.asList() to copy the initial array to a Vector.)
-               char[] chars = value.toCharArray();
-               char ch;
-               Vector v = new Vector<Character>();
-               for (int i = 0; i < chars.length; i++) {
-
-      // If the character falls within the range bounded by the start and end
-      // characters, copy it to the Vector.
-      ch = chars[i];
-                       if (ch >= this.startChar && ch <= this.endChar) {
-                         v.add(new Character(ch));
-      // Otherwise, we've detected a character not in the sequence.
-                       } else {
-        throw new IllegalArgumentException("character " + "\'" + ch + "\'" + " is not valid");
-      }
-                 
-               }
-
-               // Set the current value.
-               this.currentValue = new Vector<Character>(v);
-               
-       }
-
-  // Reset the current value to the initial value.
-       public void resetID() {
-         Collections.copy(this.currentValue, this.initialValue);
-       }
-
-       
-       // Returns the next alphabetic ID in the sequence.
-       //
-  // Currently, the number of characters auto-expands as the
-  // value of the most significant character rolls over.
-  // E.g. a call to getNextID(), where the current ID is "z",
-  // auto-expands to "aa", and "ZZ" auto-expands to "AAA".
-  //
-  // See the TODOs at the top of this class for additional
-  // functionality that needs to be implemented.
-  public String nextID() throws IllegalStateException {
-
-               // Get next values for each character, from right to left
-               // (least significant to most significant).
-               boolean expandIdentifier = false;
-               int size = this.currentValue.size();
-               char ch;
-               for (int i = (size - 1); i >= 0; i--) {
-
-      ch = this.currentValue.get(i).charValue();
-
-      // When we reach the maximum value for any character,
-      // 'roll over' to the minimum value in our character range.
-      if (ch == this.endChar) {
-                   this.currentValue.set(i, Character.valueOf(this.startChar));
-                   // If this rollover occurs in the most significant value,
-                   // set a flag to later expand the size of the identifier.
-                   //
-                   // @TODO: Set another flag to enable or disable this behavior,
-                   // as well as a mechanism for setting the maximum expansion permitted.
-                   if (i == 0) {
-                     expandIdentifier = true;
-                   }
-      // When we reach the most significant character whose value
-      // doesn't roll over, increment that character and exit the loop.
-                 } else {
-        ch++;
-        this.currentValue.set(i, Character.valueOf(ch));
-        i = -1;
-        break;           
-                 }
-
-               }
-
-    // If we are expanding the size of the identifier, insert a new
-    // value at the most significant (leftmost) character position,
-    // sliding other values to the right.
-    if (expandIdentifier) {
-      this.currentValue.add(0, Character.valueOf(this.startChar));
-    }
-               
-               return getIDString(this.currentValue);
-               
-  }
-
-  // Returns a String representation of the ID, by appending
-  // the String values of each character.
-  public String getIDString(Vector<Character> v) {
-               StringBuffer sb = new StringBuffer();
-         for ( Character ch : v ) {
-      sb.append(ch.toString());
-               }
-               return sb.toString();
-       }
-
-       public boolean isValidID(String value) {
-
-               if (value == null || value.equals("")) {
-                       return false;
-               }
-
-               Pattern pattern = Pattern.compile(getRegex());
-               Matcher matcher = pattern.matcher(value);
-               if (matcher.matches()) {
-                       return true;
-               } else {
-                       return false;
-               }
-               
-       }
-
-       public String getRegex() {
-         // @TODO: May need to constrain the number of alphabetic characters based
-         // on a maximum value, TBA.  Currently, this regex simply matches sequences
-         // of one or more characters.
-               String regex = 
-                 "(" + "[" + 
-                 String.valueOf(this.startChar) + "-" + String.valueOf(this.endChar) +
-                 "]+" + ")";
-               return regex;
-       }
-       
-}
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGeneratorPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDGeneratorPart.java
new file mode 100644 (file)
index 0000000..9a9b59d
--- /dev/null
@@ -0,0 +1,333 @@
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+ *
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+ *
+ * Copyright © 2009 Regents of the University of California
+ *
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+ *
+ * You may obtain a copy of the ECL 2.0 License at
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+
+// @TODO: Add Javadoc comments
+
+// @TODO: When auto expanding, we'll need to allow setting of a maximum length to
+// which the generated IDs can grow, likely as an additional parameter to be
+// passed to a constructor, with a default value hard-coded in the class.
+// If that length is exceeded, nextID() should throw an IllegalStateException.
+
+// @TODO: Consider handling escaped characters or sequences which represent Unicode
+// code points, both in the start and end characters of the sequence, and in the initial value.
+// (Example: '\u0072' for the USASCII 'r' character; see
+// http://www.fileformat.info/info/unicode/char/0072/index.htm)
+//
+// Ideally, we should read these in free-text patterns, alongside unescaped characters,
+// but in practice we may wish to require some structured form for arguments
+// containing such characters.
+//
+// Some initial research on this:
+// http://www.velocityreviews.com/forums/t367758-unescaping-unicode-code-points-in-a-java-string.html
+// We might also look into the (protected) source code for java.util.Properties.load()
+// which reads escaped Unicode values.
+//
+// Note also that, if the goal is to cycle through a sequence of alphabetic identifiers,
+// such as the sequence of characters used in a particular human language, it may or may not
+// be the case that any contiguous Unicode code point sequence reflects such a character sequence.
+
+// NOTE: This class currently hard-codes the assumption that the values in
+// alphabetic identifiers are ordered in significance from left-to-right;
+// that is, the most significant value appears in the left-most position.
+
+package org.collectionspace.services.id;
+
+import java.util.Collections;
+import java.util.Vector;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * AlphabeticIDGeneratorPart
+ *
+ * Generates identifiers (IDs) that consist of incrementing alphabetic
+ * characters, from within a sequence of characters.
+ *
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
+public class AlphabeticIDGeneratorPart implements IDGeneratorPart {
+   
+    private static final char NULL_CHAR = '\u0000';
+    
+    private static final String DEFAULT_START_CHAR = "a";
+    private static final String DEFAULT_END_CHAR = "z";
+    private static final String DEFAULT_INITIAL_VALUE = "a";
+      
+    private char startChar = NULL_CHAR;
+    private char endChar = NULL_CHAR;
+  
+    private Vector<Character> initialValue = new Vector<Character>();
+    private Vector<Character> currentValue = new Vector<Character>();
+
+    // Constructor using defaults for character sequence and initial value.
+    //
+    // If no start and end characters are provided for the alphabetic character
+    // sequence, default to an 'a-z' sequence, representing the lowercase alphabetic
+    // characters in the USASCII character set (within Java's internal
+    // Unicode UTF-16 representation).
+    //
+    // Additionally defaults to an initial value of "a".
+    public AlphabeticIDGeneratorPart() throws IllegalArgumentException {
+      
+      this(DEFAULT_START_CHAR, DEFAULT_END_CHAR, DEFAULT_INITIAL_VALUE);
+      
+    }
+
+    // Constructor using defaults for character sequence.
+    //
+    // If no start and end characters are provided for the alphabetic character
+    // sequence, default to an 'a-z' sequence, representing the lowercase alphabetic
+    // characters in the USASCII character set (within Java's internal
+    // Unicode UTF-16 representation).
+    public AlphabeticIDGeneratorPart(String initial) throws IllegalArgumentException {
+      
+      this(DEFAULT_START_CHAR, DEFAULT_END_CHAR, initial);
+      
+    }
+    
+    // Constructor.
+    public AlphabeticIDGeneratorPart(String sequenceStart, String sequenceEnd, String initial)
+      throws IllegalArgumentException {
+      
+        // Validate and store the start character in the character sequence.
+      
+        if (sequenceStart == null || sequenceStart.equals("")) {
+            throw new IllegalArgumentException(
+              "Start character in the character sequence must not be null or empty");
+        }
+      
+        if (sequenceStart.length() == 1) {
+            this.startChar = sequenceStart.charAt(0);
+        } else if (false) {
+          // Handle representations of Unicode code points here
+        } else {
+            throw new IllegalArgumentException(
+              "Start character must be one character in length");
+              // "Start character must be one character in length or
+              // a Unicode value such as '\u0000'");
+        }
+    
+        // Validate and store the end character in the character sequence.
+        
+        if (sequenceEnd == null || sequenceEnd.equals("")) {
+            throw new IllegalArgumentException(
+                "End character in the character sequence must not be null or empty");
+        }
+          
+        if (sequenceEnd.length() == 1) {
+            this.endChar = sequenceEnd.charAt(0);
+        } else if (false) {
+          // Handle representations of Unicode code points here
+        } else {
+            throw new IllegalArgumentException(
+              "End character must be one character in length");
+              // "End character must be one character in length or
+              // a Unicode value such as '\u0000'");
+        }
+    
+        if (this.endChar <= this.startChar) {
+            throw new IllegalArgumentException(
+              "End (last) character in the character sequence must be greater than the start character");
+        }
+        
+        // Validate and store the initial value of this identifier.
+
+        if (initial == null || initial.equals("")) {
+            throw new IllegalArgumentException("Initial value must not be null or empty");
+        }
+        
+        // @TODO: Add a check for maximum length of the initial value here.
+    
+        // Store the chars in the initial value as Characters in a Vector,
+        // validating each character to identify whether it falls within
+        // the provided sequence.
+        //
+        // (Since we're performing casts from char to Character, we can't just
+        // use Arrays.asList() to copy the initial array to a Vector.)
+        char[] chars = initial.toCharArray();
+        char ch;
+        for (int i = 0; i < chars.length; i++) {
+
+            // If the character falls within the provided sequence,
+            // copy it to the Vector.
+            ch = chars[i];
+            if (ch >= this.startChar && ch <= this.endChar) {
+                this.initialValue.add(new Character(ch));
+            // Otherwise, we've detected a character not in the sequence.
+            } else {
+                throw new IllegalArgumentException(
+                    "character " + "\'" + ch + "\'" + " is not valid");
+            }
+          
+        }
+
+        // Initialize the current value from the initial value.
+        this.currentValue = new Vector<Character>(this.initialValue);
+
+    }
+
+    // Returns the initial value.
+    public String getInitialID() {
+        return getIDString(this.initialValue);
+    }
+
+    // Returns the current value.
+    public String getCurrentID() {
+        return getIDString(this.currentValue);
+    }
+
+    // Sets the current value.
+    public void setCurrentID(String value) throws IllegalArgumentException {
+    
+        // @TODO Much of this code is copied from the main constructor,
+        // and may be ripe for refactoring.
+      
+        if (value == null || value.equals("")) {
+            throw new IllegalArgumentException("Initial value must not be null or empty");
+        }
+        
+        // @TODO: Add a check for maximum length of the value here.
+    
+        // Store the chars in the value as Characters in a Vector,
+        // validating each character to identify whether it falls within
+        // the provided sequence.
+        //
+        // (Since we're performing casts from char to Character, we can't just
+        // use Arrays.asList() to copy the initial array to a Vector.)
+        char[] chars = value.toCharArray();
+        char ch;
+        Vector v = new Vector<Character>();
+        for (int i = 0; i < chars.length; i++) {
+
+            // If the character falls within the range bounded by
+            // the start and end characters, copy it to the Vector.
+            ch = chars[i];
+            if (ch >= this.startChar && ch <= this.endChar) {
+                v.add(new Character(ch));
+            // Otherwise, we've detected a character not in the sequence.
+            } else {
+                throw new IllegalArgumentException(
+                    "character " + "\'" + ch + "\'" + " is not valid");
+            }
+          
+        }
+
+        // Set the current value.
+        this.currentValue = new Vector<Character>(v);
+        
+    }
+
+    // Reset the current value to the initial value.
+    public void resetID() {
+        Collections.copy(this.currentValue, this.initialValue);
+    }
+
+    
+    // Returns the next alphabetic ID in the sequence.
+    //
+    // Currently, the number of characters auto-expands as the
+    // value of the most significant character rolls over.
+    // E.g. a call to getNextID(), where the current ID is "z",
+    // auto-expands to "aa", and "ZZ" auto-expands to "AAA".
+    //
+    // See the TODOs at the top of this class for additional
+    // functionality that needs to be implemented.
+    public String nextID() throws IllegalStateException {
+    
+        // Get next values for each character, from right to left
+        // (least significant to most significant).
+        boolean expandIdentifier = false;
+        int size = this.currentValue.size();
+        char ch;
+        for (int i = (size - 1); i >= 0; i--) {
+
+            ch = this.currentValue.get(i).charValue();
+
+            // When we reach the maximum value for any character,
+            // 'roll over' to the minimum value in our character range.
+            if (ch == this.endChar) {
+                this.currentValue.set(i, Character.valueOf(this.startChar));
+                // If this rollover occurs in the most significant value,
+                // set a flag to later expand the size of the identifier.
+                //
+                // @TODO: Set another flag to enable or disable this behavior,
+                // as well as a mechanism for setting the maximum expansion permitted.
+                if (i == 0) {
+                  expandIdentifier = true;
+                }
+            // When we reach the most significant character whose value
+            // doesn't roll over, increment that character and exit the loop.
+            } else {
+                ch++;
+                this.currentValue.set(i, Character.valueOf(ch));
+                i = -1;
+                break;          
+            }
+            
+        }
+
+        // If we are expanding the size of the identifier, insert a new
+        // value at the most significant (leftmost) character position,
+        // sliding other values to the right.
+        if (expandIdentifier) {
+            this.currentValue.add(0, Character.valueOf(this.startChar));
+        }
+        
+        return getIDString(this.currentValue);
+        
+    }
+
+    // Returns a String representation of the ID, by appending
+    // the String values of each character.
+    public String getIDString(Vector<Character> v) {
+        StringBuffer sb = new StringBuffer();
+        for ( Character ch : v ) {
+            sb.append(ch.toString());
+        }
+        return sb.toString();
+    }
+
+    public boolean isValidID(String value) {
+
+        if (value == null || value.equals("")) {
+            return false;
+        }
+
+        Pattern pattern = Pattern.compile(getRegex());
+        Matcher matcher = pattern.matcher(value);
+        if (matcher.matches()) {
+            return true;
+        } else {
+            return false;
+        }
+        
+    }
+
+    public String getRegex() {
+        // @TODO: May need to constrain the number of alphabetic characters based
+        // on a maximum value, TBA.  Currently, this regex simply matches sequences
+        // of one or more characters.
+        String regex = 
+          "(" + "[" + 
+          String.valueOf(this.startChar) + "-" + String.valueOf(this.endChar) +
+          "]+" + ")";
+        return regex;
+    }
+    
+}
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/AlphabeticIDPart.java
deleted file mode 100644 (file)
index c90d867..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
- /*    
- * AlphabeticIDPart
- *
- * Models a part of an identifier (ID) whose values consist of incrementing
- * alphabetic characters, from within a sequence of characters.
- *
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
- */
-
-// @TODO: Add Javadoc comments
-
-package org.collectionspace.services.id;
-
-public class AlphabeticIDPart extends IDPart {
-
-       public AlphabeticIDPart() {
-               super(new AlphabeticIDGenerator());
-       };
-
-       public AlphabeticIDPart(String baseVal) {
-               super(new AlphabeticIDGenerator(baseVal));
-       };
-
-       public AlphabeticIDPart(String startVal, String endVal, String baseVal) {
-               super(new AlphabeticIDGenerator(startVal, endVal, baseVal));
-       };
-                       
-}
similarity index 81%
rename from services/id/service/src/main/java/org/collectionspace/services/id/IDPattern.java
rename to services/id/service/src/main/java/org/collectionspace/services/id/BaseIDGenerator.java
index f703387691a45952e3c7ee22aa72c3b7201e5591..5f1339d987c0f21755278e55c2439034dabf2cbe 100644 (file)
@@ -1,7 +1,7 @@
 /**
- * IDPattern
+ * BaseIDGenerator
  *
- * Models an identifier (ID), which consists of multiple IDParts.
+ * Models an identifier (ID), which consists of multiple IDGeneratorParts.
  *
  * This document is a part of the source code and related artifacts
  * for CollectionSpace, an open source collections management system
@@ -25,8 +25,8 @@
 
 // @TODO: Add Javadoc comments
 
-// @TODO: Catch Exceptions thrown by IDPart, then
-// reflect this in the corresponding IDPatternTest class.
+// @TODO: Catch Exceptions thrown by IDGeneratorPart, then
+// reflect this in the corresponding BaseIDGeneratorTest class.
 
 package org.collectionspace.services.id;
 
@@ -36,24 +36,24 @@ import java.util.Vector;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-public class IDPattern {
+public class BaseIDGenerator implements IDGenerator {
 
        private String csid = "";
        private String uri = "";
        private String description = "";
-       private Vector<IDPart> parts = new Vector<IDPart>();
+       private Vector<IDGeneratorPart> parts = new Vector<IDGeneratorPart>();
 
        final static int MAX_ID_LENGTH = 50;
        
        // Constructor
-       public IDPattern(String csid) {
+       public BaseIDGenerator(String csid) {
          if (csid != null && ! csid.equals("")) {
            this.csid = csid;
          }
        }
        
        // Constructor
-       public IDPattern(String csid, Vector<IDPart> partsList) {
+       public BaseIDGenerator(String csid, Vector<IDGeneratorPart> partsList) {
          if (csid != null && ! csid.equals("")) {
            this.csid = csid;
          }
@@ -93,7 +93,7 @@ public class IDPattern {
     return this.description;
   }
   
-       public void add(IDPart part) {
+       public void add(IDGeneratorPart part) {
                if (part != null) {
                        this.parts.add(part);
                }
@@ -102,7 +102,7 @@ public class IDPattern {
        // Returns the current value of this ID.
        public String getCurrentID() {
                StringBuffer sb = new StringBuffer(MAX_ID_LENGTH);
-               for (IDPart part : this.parts) {
+               for (IDGeneratorPart part : this.parts) {
                        sb.append(part.getCurrentID());
                }
                return sb.toString();
@@ -122,9 +122,9 @@ public class IDPattern {
        //
        // Examples:
        // * 2009.5." becomes "2009.5.1", in a case where the
-       //   next ID component is an incrementing numeric IDPart.
+       //   next ID component is an incrementing numeric IDGeneratorPart.
        // * "E55-" becomes "E55-a", where the next ID component
-       //   is an incrementing alphabetic IDPart.
+       //   is an incrementing alphabetic IDGeneratorPart.
        public String getCurrentID(String value)
                throws IllegalArgumentException {
 
@@ -134,19 +134,19 @@ public class IDPattern {
          // by incrementally appending each part's regex, until no
          // (more) matches are found.
          //
-         // In so doing, build a subset of this IDPattern's regex
+         // In so doing, build a subset of this BaseIDGenerator's regex
          // that fully matches the supplied value.
          Pattern pattern = null;
          Matcher matcher = null;
          int matchedParts = 0;
          StringBuffer regexToTry = new StringBuffer();
          StringBuffer regex = new StringBuffer();
-         for (IDPart partToTryMatching : this.parts) {
+         for (IDGeneratorPart partToTryMatching : this.parts) {
                regexToTry.append(partToTryMatching.getRegex());
                pattern = Pattern.compile(regexToTry.toString());
                        matcher = pattern.matcher(value);
                        // If a stem match was found on the current regex,
-                       // store a count of matched IDParts and the regex pattern
+                       // store a count of matched IDGeneratorParts and the regex pattern
                        // that has matched to this point.
                        if (matcher.lookingAt()) {
                                matchedParts++;
@@ -175,24 +175,24 @@ public class IDPattern {
                
                // Otherwise, if the supplied ID matches the pattern,
                // split the ID into its components and store those
-               // values in each of the pattern's IDParts.
-               IDPart currentPart;
+               // values in each of the pattern's IDGeneratorParts.
+               IDGeneratorPart currentPart;
                for (int i = 1; i <= matchedParts; i++) {
                  currentPart = this.parts.get(i - 1);
       currentPart.setCurrentID(matcher.group(i));
                }
 
-               // Obtain the initial value of the next IDPart, and
+               // Obtain the initial value of the next IDGeneratorPart, and
                // set the current value of that part to its initial value.
                //
                // If the supplied ID fully matches the pattern, there will
-               // be no 'next' IDPart, and we must catch that Exception below. 
+               // be no 'next' IDGeneratorPart, and we must catch that Exception below. 
                int nextPartNum = matchedParts;
                try {
                        String initial = this.parts.get(nextPartNum).getInitialID();
                        this.parts.get(nextPartNum).setCurrentID(initial);
                        // Increment the number of matched parts to reflect the
-                       // addition of this next IDPart.
+                       // addition of this next IDGeneratorPart.
                        matchedParts++;
                } catch (ArrayIndexOutOfBoundsException e ) {
                        // Do nothing here; we simply won't increment
@@ -200,7 +200,7 @@ public class IDPattern {
                }
                
                // Call the getCurrentID() method on each of the
-               // supplied IDParts, as well as on the added IDPart
+               // supplied IDGeneratorParts, as well as on the added IDGeneratorPart
                // whose initial value was just obtained, if any.
                StringBuffer sb = new StringBuffer();
                for (int i = 1; i <= matchedParts; i++) {
@@ -212,18 +212,18 @@ public class IDPattern {
        }
 
        // Returns the next value of this ID, and sets the current value to that ID.
-       public String nextID() throws IllegalStateException {
+       public String newID() throws IllegalStateException {
        
-               // Obtain the last (least significant) IDPart,
+               // Obtain the last (least significant) IDGeneratorPart,
                // and call its nextID() method, which will
                // concurrently set the current value of that ID
                // to the next ID.
                int lastPartNum = this.parts.size() - 1;
                this.parts.get(lastPartNum).nextID();
                
-               // Then call the getCurrentID() method on all of the IDParts
+               // Then call the getCurrentID() method on all of the IDGeneratorParts
                StringBuffer sb = new StringBuffer(MAX_ID_LENGTH);
-               for (IDPart part : this.parts) {
+               for (IDGeneratorPart part : this.parts) {
                        sb.append(part.getCurrentID());
                }
                
@@ -234,7 +234,7 @@ public class IDPattern {
        // Returns the next value of this ID, given a
        // supplied ID that entirely matches the pattern,
        // and sets the current value to that ID.
-       public String nextID(String value)
+       public String newID(String value)
                throws IllegalStateException, IllegalArgumentException {
 
          if (value == null) { 
@@ -252,14 +252,14 @@ public class IDPattern {
                
                // Otherwise, if the supplied ID entirely matches the pattern,
                // split the ID into its components and store those values in
-               // each of the pattern's IDParts.
-               IDPart currentPart;
+               // each of the pattern's IDGeneratorParts.
+               IDGeneratorPart currentPart;
                for (int i = 1; i <= (matcher.groupCount() - 1); i++) {
                  currentPart = this.parts.get(i - 1);
       currentPart.setCurrentID(matcher.group(i));
                }
 
-               // Obtain the last (least significant) IDPart,
+               // Obtain the last (least significant) IDGeneratorPart,
                // and call its nextID() method, which will
                // concurrently set the current value of that ID
                // to the next ID.
@@ -269,9 +269,9 @@ public class IDPattern {
                int lastPartNum = this.parts.size() - 1;
                this.parts.get(lastPartNum).nextID();
                
-               // Then call the getCurrentID() method on all of the IDParts
+               // Then call the getCurrentID() method on all of the IDGeneratorParts
                StringBuffer sb = new StringBuffer();
-               for (IDPart part : this.parts) {
+               for (IDGeneratorPart part : this.parts) {
                        sb.append(part.getCurrentID());
                }
                
@@ -300,7 +300,7 @@ public class IDPattern {
        // Returns a regular expression to validate this ID.
        public String getRegex() {
                StringBuffer sb = new StringBuffer();
-               for (IDPart part : this.parts) {
+               for (IDGeneratorPart part : this.parts) {
                        sb.append(part.getRegex());
                }
                return sb.toString();
index f9c69b2e67ad59f7a69d0b1de224c8e6bbb53f75..829e6a964e2e2abd59ab472e8f1748ce7da2f9aa 100644 (file)
@@ -1,8 +1,4 @@
- /*    
- * IDGenerator
- *
- * Interface for a generator class that returns IDs.
- *
+/**    
  * This document is a part of the source code and related artifacts
  * for CollectionSpace, an open source collections management system
  * for museums and related institutions:
  * $LastChangedDate$
  */
  
-// @TODO: Consider making this class, or a class that implements
-// this interface, abstract, in part because we're duplicating code
-// in isValidID() in multiple Generator subclasses.
 package org.collectionspace.services.id;
 
+/**
+ * IDGenerator, interface for an IDGenerator, which returns identifiers (IDs).
+ *
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
 public interface IDGenerator {
-    
-       // Returns the initial value of the ID.
-       public String getInitialID();
 
-       // Gets the current value of an ID.
-       public String getCurrentID();
-       
-       // Sets the current value of an ID.
-       public void setCurrentID(String value) throws IllegalArgumentException;
+    /**
+     * Returns a new identifier (ID).
+     */
+       public String newID();
 
-       // Resets an ID to its initial value.
-       public void resetID();
+    /**
+     * Returns a new identifier (ID), based on a supplied identifier.
+     */
+       public String newID(String id);
 
-       // Returns the next ID in the sequence, and sets
-       // the current value to that ID.
-       public String nextID() throws IllegalStateException;
-
-       // Validates an ID against a pattern of generated IDs.
-       public boolean isValidID(String value);
+    /**
+     * Returns the current identifier (ID).
+     */
+       public String getCurrentID();
 
-       // Returns a String representation of the regular expression ("regex")
-       // pattern used to validate instance values of generated IDs.  
-       public String getRegex();
-               
 }
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDGeneratorPart.java
new file mode 100644 (file)
index 0000000..b76a12f
--- /dev/null
@@ -0,0 +1,51 @@
+ /*    
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+ *
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+ *
+ * Copyright © 2009 Regents of the University of California
+ *
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+ *
+ * You may obtain a copy of the ECL 2.0 License at
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+
+ /*    
+ * IDGeneratorPart, interface for a component part of an ID Generator.
+ *
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
+package org.collectionspace.services.id;
+
+public interface IDGeneratorPart {
+    
+       // Returns the initial value of the ID.
+       public String getInitialID();
+
+       // Gets the current value of an ID.
+       public String getCurrentID();
+       
+       // Sets the current value of an ID.
+       public void setCurrentID(String value) throws IllegalArgumentException;
+
+       // Resets an ID to its initial value.
+       public void resetID();
+
+       // Returns the next ID in the sequence, and sets
+       // the current value to that ID.
+       public String nextID() throws IllegalStateException;
+
+       // Validates an ID against a pattern of generated IDs.
+       public boolean isValidID(String value);
+
+       // Returns a String representation of the regular expression ("regex")
+       // pattern used to validate instance values of generated IDs.  
+       public String getRegex();
+               
+}
index ada47f8bcc5302429aca039060e73b6acb3d29e5..fcb95a3528231415ec9362884fd7bbfe518ed273 100644 (file)
@@ -30,20 +30,13 @@ import com.thoughtworks.xstream.io.xml.DomDriver;
 /**
  * IDGeneratorSerializer
  *
- * Serializer and deserializer for ID patterns.
+ * Serializer and deserializer for ID generators.
  *
- * $LastChangedBy: aron $
  * $LastChangedRevision: 414 $
  * $LastChangedDate$
  */
 public class IDGeneratorSerializer {
 
-  // *IMPORTANT*
-  // @TODO: This class is in an early state of a refactoring to
-  // reflect a change from IDPatterns to IDGenerators at the top level
-  // of the ID Service.  As a result, there will be some naming
-  // inconsistencies throughout this source file.
-
   //////////////////////////////////////////////////////////////////////
   /**
    * Constructor (no-argument).
@@ -53,17 +46,19 @@ public class IDGeneratorSerializer {
 
   //////////////////////////////////////////////////////////////////////
   /**
-   * Serializes an ID generator, converting it from a Java object into an XML representation.
+   * Serializes an ID generator, converting it from a Java object
+   * into an XML representation.
    *
-   * @param  pattern  An ID generator.
+   * @param  generator  An ID generator.
    *
    * @return  A serialized representation of that ID generator.
    *
    * @throws  IllegalArgumentException if the ID generator cannot be serialized.
    */
-       public static String serialize(IDPattern pattern) throws IllegalArgumentException {
+       public static String serialize(BaseIDGenerator generator)
+           throws IllegalArgumentException {
        
-         if (pattern == null) {
+         if (generator == null) {
            throw new IllegalArgumentException("ID generator cannot be null.");
          }
   
@@ -71,10 +66,10 @@ public class IDGeneratorSerializer {
     
     String serializedGenerator = "";
     try {
-      serializedGenerator = xstream.toXML(pattern);
+      serializedGenerator = xstream.toXML(generator);
     } catch (XStreamException e) {
            throw new IllegalArgumentException(
-             "Could not convert ID pattern to XML for storage in database.");
+             "Could not convert ID generator to XML for storage in database.");
     }
     
     return serializedGenerator;
@@ -92,7 +87,7 @@ public class IDGeneratorSerializer {
    *
    * @throws  IllegalArgumentException if the ID generator cannot be deserialized.
    */
-       public static IDPattern deserialize(String serializedGenerator)
+       public static BaseIDGenerator deserialize(String serializedGenerator)
          throws IllegalArgumentException {
 
          if (serializedGenerator == null || serializedGenerator.equals("")) {
@@ -101,15 +96,15 @@ public class IDGeneratorSerializer {
 
     XStream xstream = new XStream(new DomDriver());
 
-    IDPattern pattern;
+    BaseIDGenerator generator;
     try {
-      pattern = (IDPattern) xstream.fromXML(serializedGenerator);
+      generator = (BaseIDGenerator) xstream.fromXML(serializedGenerator);
     } catch (XStreamException e) {
            throw new IllegalArgumentException(
              "Could not understand or parse this representation of an ID generator.");
     }
 
-    return pattern;
+    return generator;
   
   }
   
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDPart.java
deleted file mode 100644 (file)
index cde6f10..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
- /*    
- * IDPart
- *
- * <p>Models a part of an identifier (ID).</p>
- *
- * <p>Some representative examples of data that can be
- * managed within IDParts include:</p>
- *
- * <ul>
- *   <li>Incrementing numeric or alphabetic values</li>
- *   <li>Date values</li>
- *   <li>Static separators</li>
- * </ul>
- *
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
- */
-
-// @TODO: Add Javadoc comments
-
-package org.collectionspace.services.id;
-
-public abstract class IDPart {
-
-       // A generator for the types of IDs that are generated by this part.
-       // This generator is passed in at construction time.
-       protected IDGenerator generator;
-       
-       // Constructor
-       public IDPart(IDGenerator idGenerator) throws IllegalArgumentException {
-               this.generator = idGenerator;
-       }
-
-       // Returns the initial value of the ID associated with this IDPart.
-       public String getInitialID() {
-               return generator.getInitialID();
-       }
-
-       // Returns the current value of the ID associated with this IDPart.
-       public String getCurrentID() {
-               return generator.getCurrentID();
-       }
-
-       // Sets the current value of the ID associated with this IDPart.
-       public void setCurrentID(String value) throws IllegalArgumentException {
-               generator.setCurrentID(value);
-       }
-
-       // Resets the ID associated with this IDPart to its initial value.
-       public void resetID() {
-               generator.resetID();
-       }
-
-       // Returns the next ID in the sequence, and sets the current value
-       // of the ID associated with this IDPart to that next ID.
-       public String nextID() throws IllegalStateException {
-               return generator.nextID();
-       }
-
-       // Validates a supplied ID against the pattern of this IDPart.
-       //
-       // Some IDParts may offer generic validation,
-       // while others may offer per-instance valiadation
-       // based on the values, series, etc. that are
-       // stored within those parts.
-       public boolean isValidID(String value) throws IllegalArgumentException {
-               return generator.isValidID(value);
-       }
-
-       // Returns a String representation of the regular expression ("regex")
-       // pattern used to validate instance values of this IDPart.  
-       public String getRegex() {
-               return generator.getRegex();
-       }
-}
index 56e757dcd8f2dba0eb3275322959a7c13eb2e728..0ad1b6f5b0aad4e5d7a9e72b2267f7bd18cffcb5 100644 (file)
@@ -13,8 +13,6 @@
  *
  * You may obtain a copy of the ECL 2.0 License at
  * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * Based in part on work by Richard Millet and Sanjay Dalal.
  */
   
 package org.collectionspace.services.id;
@@ -33,145 +31,137 @@ import javax.xml.bind.Marshaller;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-// Set the base path component for URLs that access this service.
-@Path("/idgenerators")
-
-// Identify the default MIME media types consumed and produced by this service.
-@Consumes(MediaType.APPLICATION_XML)
-@Produces(MediaType.APPLICATION_XML)
-
 /**
  * IDResource
  *
  * Resource class to handle requests to the ID Service.
  *
- * $LastChangedBy$
  * $LastChangedRevision$
  * $LastChangedDate$
  */
+// Set the base path component for URLs that access this service.
+@Path("/idgenerators")
+// Identify the default MIME media types consumed and produced by this service.
+@Consumes(MediaType.TEXT_PLAIN)
+@Produces(MediaType.TEXT_PLAIN)
 public class IDResource {
 
-       final Logger logger = LoggerFactory.getLogger(IDResource.class);
+    final Logger logger = LoggerFactory.getLogger(IDResource.class);
 
-       // @TODO Determine if this is pertinent here:
-       // Per Richard's comment in the CollectionObject Resource class, from which
-       // this class was derived: "This should be a DI wired by a container like
-       // Spring, Seam, or EJB3."
-       
-       final static IDService service = new IDServiceJdbcImpl();
+    final static IDService service = new IDServiceJdbcImpl();
 
-  //////////////////////////////////////////////////////////////////////
-       /**
-        * Constructor (no argument).
-   */
-       public IDResource() {
-               // do nothing
-       }
+    //////////////////////////////////////////////////////////////////////
+    /**
+    * Constructor (no argument).
+    */
+    public IDResource() {
+        // do nothing
+    }
 
 
-  //////////////////////////////////////////////////////////////////////
-  /**
-   * Placeholder for retrieving list of available ID Generators.
-   * Currently returns an empty entity body.
-   * 
-   * Implemented to facilitate a HEAD method test in ServicesTest
-   *
-   * @return  An empty entity body (for now).
-   */
-       @GET
-       @Path("")
-  @Produces("text/plain")
-       public Response getIDGenerators() {
-       
-         logger.debug("> in getIDGenerators()");
-               
-               // @TODO Replace this placeholder code.
-               Response response = Response.status(Response.Status.NO_CONTENT)
-                         .entity("").type(MediaType.TEXT_PLAIN).build();
-                               
-               return response;
+    //////////////////////////////////////////////////////////////////////
+    /**
+    * Placeholder for retrieving list of available ID Generators.
+    * Currently returns an empty entity body.
+    * 
+    * Implemented to facilitate a HEAD method test in ServicesTest
+    *
+    * @return  An empty entity body (for now).
+    */
+    @GET
+    @Path("")
+    public Response getIDGenerators() {
+    
+      logger.debug("> in getIDGenerators()");
+        
+        // @TODO Replace this placeholder code.
+        Response response = Response.status(Response.Status.NO_CONTENT)
+              .entity("").type(MediaType.TEXT_PLAIN).build();
+                
+        return response;
   }
 
-  //////////////////////////////////////////////////////////////////////
-  /**
-   * Generates and returns a new ID, from the specified ID generator.
-   *
-   * @param  csid  An identifier for an ID generator.
-   *
-   * @return  A new ID from the specified ID generator.
-   */
-       @POST
-       @Path("/{csid}/ids")
-  @Produces("text/plain")
-       public Response newID(@PathParam("csid") String csid) {
-       
-         logger.debug("> in newID(String)");
-
-    // @TODO The JavaDoc description reflects an as-yet-to-be-carried out
-    // refactoring, in which the highest object type in the ID service
-    // is that of an IDGenerator, some or all of which may be composed
-    // of IDParts.  Some IDGenerators generate IDs based on patterns,
-    // which may be composed in part of incrementing numeric or alphabetic
-    // components, while others may not (e.g. UUIDs, web services-based
-    // responses).
+    //////////////////////////////////////////////////////////////////////
+    /**
+    * Generates and returns a new ID, from the specified ID generator.
+    *
+    * @param  csid  An identifier for an ID generator.
+    *
+    * @return  A new ID from the specified ID generator.
+    */
+    @POST
+    @Path("/{csid}/ids")
+    public Response newID(@PathParam("csid") String csid) {
     
-    // @TODO We're currently using simple integer IDs to identify ID generators
-    // in this initial iteration.
-    //
-    // To uniquely identify ID generators in production, we'll need to handle
-    // both CollectionSpace IDs (csids) - a form of UUIDs/GUIDs - and some
-    // other form of identifier to be determined, such as URLs or URNs.
+        logger.debug("> in newID(String)");
     
-    // @TODO We're currently returning IDs in plain text.  Identify whether
-    // there is a requirement to return an XML representation, and/or any
-    // other representations.
-         
-         // Unless the 'response' variable is explicitly initialized here,
-         // the compiler gives the error: "variable response might not have
-         // been initialized."
-         Response response = null;
-         response = response.ok().build();
-               String newId = "";
-       
-               try {
-               
-                 // Obtain a new ID from the specified ID generator,
-                 // and return it in the entity body of the response.
-                       newId = service.newID(csid);
-                       
-      if (newId == null || newId.equals("")) {
-        response = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
-          .entity("ID Service returned null or empty ID").type(MediaType.TEXT_PLAIN).build();
+        // @TODO The JavaDoc description reflects an as-yet-to-be-carried out
+        // refactoring, in which the highest object type in the ID service
+        // is that of an IDGenerator, some or all of which may be composed
+        // of IDParts.  Some IDGenerators generate IDs based on patterns,
+        // which may be composed in part of incrementing numeric or alphabetic
+        // components, while others may not (e.g. UUIDs, web services-based
+        // responses).
+        
+        // @TODO We're currently using simple integer IDs to identify ID generators
+        // in this initial iteration.
+        //
+        // To uniquely identify ID generators in production, we'll need to handle
+        // both CollectionSpace IDs (csids) - a form of UUIDs/GUIDs - and some
+        // other form of identifier to be determined, such as URLs or URNs.
+        
+        // @TODO We're currently returning IDs in plain text.  Identify whether
+        // there is a requirement to return an XML representation, and/or any
+        // other representations.
+          
+        // Unless the 'response' variable is explicitly initialized here,
+        // the compiler gives the error: "variable response might not have
+        // been initialized."
+        Response response = null;
+        response = response.ok().build();
+        String newId = "";
+        
+        try {
+        
+            // Obtain a new ID from the specified ID generator,
+            // and return it in the entity body of the response.
+            newId = service.newID(csid);
+                
+            if (newId == null || newId.equals("")) {
+                response = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
+                    .entity("ID Service returned null or empty ID")
+                    .type(MediaType.TEXT_PLAIN)
+                    .build();
+                return response;
+            }
+                    
+            response = Response.status(Response.Status.OK)
+              .entity(newId).type(MediaType.TEXT_PLAIN).build();
+                
+            // @TODO Return an XML-based error results format with the
+            // responses below.
+            
+            // @TODO An IllegalStateException often indicates an overflow
+            // of an IDPart.  Consider whether returning a 400 Bad Request
+            // status code is still warranted, or whether returning some other
+            // status would be more appropriate.
+        
+        } catch (IllegalStateException ise) {
+          response = Response.status(Response.Status.BAD_REQUEST)
+              .entity(ise.getMessage()).type(MediaType.TEXT_PLAIN).build();
+        
+        } catch (IllegalArgumentException iae) {
+            response = Response.status(Response.Status.BAD_REQUEST)
+              .entity(iae.getMessage()).type(MediaType.TEXT_PLAIN).build();
+        
+        // This is guard code that should never be reached.
+        } catch (Exception e) {
+          response = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
+              .entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
+        }
+        
         return response;
-      }
-                       
-                       response = Response.status(Response.Status.OK)
-                         .entity(newId).type(MediaType.TEXT_PLAIN).build();
-               
-               // @TODO Return an XML-based error results format with the
-               // responses below.
-               
-               // @TODO An IllegalStateException often indicates an overflow
-               // of an IDPart.  Consider whether returning a 400 Bad Request
-               // status code is still warranted, or whether returning some other
-               // status would be more appropriate.
-               
-               } catch (IllegalStateException ise) {
-                 response = Response.status(Response.Status.BAD_REQUEST)
-                         .entity(ise.getMessage()).type(MediaType.TEXT_PLAIN).build();
-
-               } catch (IllegalArgumentException iae) {
-                       response = Response.status(Response.Status.BAD_REQUEST)
-                         .entity(iae.getMessage()).type(MediaType.TEXT_PLAIN).build();
-         
-         // This is guard code that should never be reached.
-               } catch (Exception e) {
-                 response = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
-                         .entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
-               }
-               
-               return response;
-  }
+     
+    }
 
 }
index 8b182af49c22fd362230d6c0fe3004f6f778521a..da5c69f94a754e5a4a2e9002660c3c5b159145a8 100644 (file)
  */
 
 // *IMPORTANT*
-// @TODO: This class is in an early state of a refactoring to
-// reflect a change from IDPatterns to IDGenerators at the top level
-// of the ID Service.  As a result, there will be some naming
-// inconsistencies throughout this source file.
-
 // @TODO Revise exception handling to return custom Exceptions,
 // perhaps mirroring the subset of HTTP status codes returned.
 //
@@ -50,7 +45,7 @@
 // @TODO Handle concurrency.
 //
 // Right now, with each new request we're simply instantiating
-// a new IDPattern and returning its next ID.  As a result,
+// a new BaseIDGenerator and returning its next ID.  As a result,
 // the generated IDs may well duplicate other, previously-generated IDs.
 //
 // When we start storing ID generators and IDs in a database,
@@ -299,40 +294,41 @@ public class IDServiceJdbcImpl implements IDService {
                // Guard code - should not be needed.
                if (serializedGenerator == null || serializedGenerator.equals("")) {
                        throw new IllegalArgumentException(
-                               "Pattern with ID " + "\'" + csid + "\'" + " could not be found.");
+                               "ID generator " + "\'" + csid + "\'" + " could not be found.");
                }
 
-    IDPattern pattern;
+    BaseIDGenerator generator;
     try {
-      pattern = IDGeneratorSerializer.deserialize(serializedGenerator);
+      generator = IDGeneratorSerializer.deserialize(serializedGenerator);
     } catch (IllegalArgumentException e) {
            throw e;
     }
                
                try {
 
-      // Retrieve the last ID associated with this pattern from persistent storage.
+      // Retrieve the last ID associated with this generator
+      // from persistent storage.
       lastId = getLastID(csid);
 
-                 // If there was no last generated ID associated with this pattern,
+                 // If there was no last generated ID associated with this generator,
                  // get the current ID generated by the ID generator as the 'new' ID.
                  if (lastId == null || lastId.equals("")) {
-                   newId = pattern.getCurrentID();
+                   newId = generator.getCurrentID();
 
       // Otherwise, generate a new ID, potentially based on the last ID.
       // (This also sets the current ID of the ID generator's state
       // to this just-generated 'new' ID.)
                  } else {
-        newId = pattern.nextID(lastId);
+        newId = generator.newID(lastId);
       }
       
-                 // Store the 'new' ID as the last-generated ID for this pattern.
+                 // Store the 'new' ID as the last-generated ID for this generator.
                  updateLastID(csid, newId);
                  
                  // Store the new state of this ID generator, reflecting that
                  // one of its parts may possibly have had its value updated as
                  // a result of the generation of this 'new' ID.
-                 updateIDGenerator(csid, pattern);
+                 updateIDGenerator(csid, generator);
                  
                } catch (IllegalArgumentException e ) {
                  throw e;
@@ -351,7 +347,7 @@ public class IDServiceJdbcImpl implements IDService {
    *
    * @param  csid     An identifier for an ID generator.
    *
-   * @param  pattern  An ID Pattern, including the values of its constituent parts.
+   * @param  generator  An ID generator, including the values of its constituent parts.
    *
    * @param  lastId  The value of the last-generated ID associated with that ID generator.
    *
@@ -380,7 +376,7 @@ public class IDServiceJdbcImpl implements IDService {
                          
                        if (rowsUpdated != 1) {
         throw new IllegalStateException(
-          "Error updating last-generated ID in the database for ID Pattern '" + csid + "'");
+          "Error updating last-generated ID in the database for ID generator '" + csid + "'");
       }
 
                  logger.debug("> successfully updated last-generated ID: " + lastId);
@@ -434,7 +430,7 @@ public class IDServiceJdbcImpl implements IDService {
                        boolean moreRows = rs.next();
                        if (! moreRows) {
         throw new IllegalArgumentException(
-          "Pattern with ID " + "\'" + csid + "\'" + " could not be found.");
+          "ID generator " + "\'" + csid + "\'" + " could not be found.");
       }
 
                        lastId = rs.getString(1);
@@ -467,25 +463,25 @@ public class IDServiceJdbcImpl implements IDService {
    *
    * @param  csid     An identifier for an ID generator.
    *
-   * @param  pattern  An ID generator, reflecting its current state,
+   * @param  generator  An ID generator, reflecting its current state,
    *                  including the values of its constituent parts.
    *
    * @throws  IllegalStateException if a storage-related error occurred.
    */
-       public void addIDGenerator(String csid, IDPattern pattern)
+       public void addIDGenerator(String csid, BaseIDGenerator generator)
          throws IllegalArgumentException, IllegalStateException {
     
-               logger.debug("> in addIDGenerator(String, IDPattern)");
+               logger.debug("> in addIDGenerator(String, BaseIDGenerator)");
 
     // @TODO: Add checks for authorization to perform this operation.
 
-         if (pattern == null) {
+         if (generator == null) {
            throw new IllegalArgumentException("New ID generator to add cannot be null.");
          }
 
     String serializedGenerator = "";
     try {
-      serializedGenerator = IDGeneratorSerializer.serialize(pattern);
+      serializedGenerator = IDGeneratorSerializer.serialize(generator);
     } catch (IllegalArgumentException e) {
            throw e;
     }
@@ -536,7 +532,7 @@ public class IDServiceJdbcImpl implements IDService {
 
       // Test whether this ID generator already exists in the database.
                        //
-                       // @TODO This check should extend further, to other aspects of the pattern,
+                       // @TODO This check should extend further, to other aspects of the generator,
                        // such as its URI, if any, and its structure.
                        ResultSet rs = stmt.executeQuery(
                          "SELECT id_generator_csid FROM id_generators WHERE id_generator_csid='" + csid + "'");
@@ -554,7 +550,7 @@ public class IDServiceJdbcImpl implements IDService {
                        // occurred, so that this status can be reported to the client.
                        if (idGeneratorFound) {
         throw new IllegalStateException(
-          "Conflict with existing pattern when attempting to add new ID generator with ID '" +
+          "Conflict with existing generator when attempting to add new ID generator with ID '" +
           csid +
           "' to the database.");
           
@@ -583,7 +579,7 @@ public class IDServiceJdbcImpl implements IDService {
         
        } // end if (idGeneratorFound)
 
-                 logger.debug("> successfully added ID Pattern: " + csid);
+                 logger.debug("> successfully added ID generator: " + csid);
 
     } catch (SQLException e) {
       throw new IllegalStateException("Error adding new ID generator to the database: " + e.getMessage());
@@ -605,26 +601,26 @@ public class IDServiceJdbcImpl implements IDService {
    *
    * @param  csid     An identifier for an ID generator.
    *
-   * @param  pattern  An ID generator, reflecting its current state,
+   * @param  generator  An ID generator, reflecting its current state,
    *                  including the values of its constituent parts.
    *
    * @throws  IllegalStateException if a storage-related error occurred.
    */
-       public void updateIDGenerator(String csid, IDPattern pattern)
+       public void updateIDGenerator(String csid, BaseIDGenerator generator)
          throws IllegalArgumentException, IllegalStateException {
     
-               logger.debug("> in updateIDGenerator(String, IDPattern)");
+               logger.debug("> in updateIDGenerator(String, BaseIDGenerator)");
 
     // @TODO: Add checks for authorization to perform this operation.
 
-         if (pattern == null) {
+         if (generator == null) {
            throw new IllegalArgumentException(
-             "ID generator supplied in an attempt to update an existing ID generator cannot be null.");
+             "ID generator provided in update operation cannot be null.");
          }
 
     String serializedGenerator = "";
     try {
-      serializedGenerator = IDGeneratorSerializer.serialize(pattern);
+      serializedGenerator = IDGeneratorSerializer.serialize(generator);
     } catch (IllegalArgumentException e) {
            throw e;
     }
@@ -642,7 +638,7 @@ public class IDServiceJdbcImpl implements IDService {
   //////////////////////////////////////////////////////////////////////
   /**
    * Updates an existing ID generator in persistent storage,
-   * from a serialization of the current state of that pattern.
+   * from a serialization of the current state of that generator.
    *
    * The serialization method recognized by this method has implementation
    * dependencies.  Currently, this method expects serialization via XStream's
@@ -650,7 +646,7 @@ public class IDServiceJdbcImpl implements IDService {
    *
    * @param  csid     An identifier for an ID generator.
    *
-   * @param  serializedGenerator  A serialized ID Pattern, reflecting its current state,
+   * @param  serializedGenerator  A serialized ID generator, reflecting its current state,
    *                            including the values of its constituent parts.
    *
    * @throws  IllegalStateException if a storage-related error occurred.
@@ -693,13 +689,13 @@ public class IDServiceJdbcImpl implements IDService {
                               "last_generated_id = ? " + 
                            "WHERE id_generator_csid = ?";
                            
-                         IDPattern pattern;
+                         BaseIDGenerator generator;
         try {
-          pattern = IDGeneratorSerializer.deserialize(serializedGenerator);
+          generator = IDGeneratorSerializer.deserialize(serializedGenerator);
         } catch (IllegalArgumentException e) {
           throw e;
         }
-                   String lastId = pattern.getCurrentID();
+                   String lastId = generator.getCurrentID();
                        
         PreparedStatement ps = conn.prepareStatement(SQL_STATEMENT_STRING);
         ps.setString(1, serializedGenerator);
@@ -888,7 +884,7 @@ public class IDServiceJdbcImpl implements IDService {
       }
     }
     
-         logger.debug("> retrieved IDGenerator: " + serializedGenerator);
+         logger.debug("> retrieved BaseIDGenerator: " + serializedGenerator);
 
     return serializedGenerator;
 
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGenerator.java b/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGenerator.java
deleted file mode 100644 (file)
index 2369a9b..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*     
- * NumericIDGenerator
- *
- * Generates identifiers (IDs) that consist of a sequence of
- * numeric values, beginning from an initial value.
- *
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
- */
-
-// @TODO: Add Javadoc comments
-
-// @TODO: Need to set and enforce maximum value.
-package org.collectionspace.services.id;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class NumericIDGenerator implements IDGenerator {
-  
-  final static private int DEFAULT_MAX_LENGTH = 6;
-  private int maxLength = DEFAULT_MAX_LENGTH;
-  
-  final static private int DEFAULT_INITIAL_VALUE = 1;
-  private long initialValue = DEFAULT_INITIAL_VALUE;
-       private long currentValue = DEFAULT_INITIAL_VALUE;
-
-       // Constructor using defaults for initial value and maximum length.
-       public NumericIDGenerator() throws IllegalArgumentException {
-               this(Integer.toString(DEFAULT_INITIAL_VALUE), Integer.toString(DEFAULT_MAX_LENGTH));
-       }
-
-       // Constructor using default maximum length.
-       public NumericIDGenerator(String initialValue) throws IllegalArgumentException {
-               this(initialValue, Integer.toString(DEFAULT_MAX_LENGTH));
-       }
-
-       // Constructor.
-       public NumericIDGenerator(String initialValue, String maxLength)
-               throws IllegalArgumentException {
-
-               if (initialValue == null || initialValue.equals("")) {
-                       throw new IllegalArgumentException("Initial ID value must not be null or empty");
-               }
-               
-               try {
-                       long l = Long.parseLong(initialValue.trim());
-                       if ( l < 0 ) {
-                               throw new IllegalArgumentException("Initial ID value should be zero (0) or greater");
-                       }
-                       this.currentValue = l;
-                       this.initialValue = l;
-               } catch (NullPointerException e) {
-                       throw new IllegalArgumentException("Initial ID value should not be null");
-               } catch (NumberFormatException e) {
-                       throw new IllegalArgumentException("Initial ID value must be parseable as a number");
-               }
-
-               if (maxLength == null || maxLength.equals("")) {
-                       throw new IllegalArgumentException("Initial ID value must not be null or empty");
-               }
-
-               try {
-                       this.maxLength = Integer.parseInt(maxLength);
-               } catch (NumberFormatException e) {
-                       throw new IllegalArgumentException("Maximum ID length must be parseable as a number");
-               }
-               
-       }
-
-       public String getInitialID() {
-               return Long.toString(this.initialValue);
-       }
-
-       public String getCurrentID() {
-               return Long.toString(this.currentValue);
-       }
-
-  // Sets the current value of the ID.
-       public void setCurrentID(String value) throws IllegalArgumentException {
-
-         // @TODO Much of this code is copied from the main constructor,
-         // and may be ripe for refactoring.
-
-               if (value == null || value.equals("")) {
-                       throw new IllegalArgumentException("ID value must not be null or empty");
-               }
-               
-               try {
-                       long l = Long.parseLong(value.trim());
-                       if ( l < 0 ) {
-                               throw new IllegalArgumentException("ID value should be zero (0) or greater");
-                       }
-                       this.currentValue = l;
-                       this.initialValue = l;
-               } catch (NullPointerException e) {
-                       throw new IllegalArgumentException("ID value should not be null");
-               } catch (NumberFormatException e) {
-                       throw new IllegalArgumentException("ID value must be parseable as a number");
-               }
-               
-               // @TODO An expedient; we may need to check the String length of the
-               // provided ID and calculate a maximum length here.
-               this.maxLength = DEFAULT_MAX_LENGTH;
-       }
-       
-       public void resetID() {
-               this.currentValue = this.initialValue;
-       }
-
-       // Returns the next ID in the sequence, and sets the current value to that ID.
-       public String nextID() throws IllegalStateException {
-               this.currentValue++;
-               String nextID = Long.toString(this.currentValue);
-               if (nextID.length() > this.maxLength) {
-                       throw new IllegalStateException("Next ID cannot exceed maximum length");
-               }
-               return nextID;
-       }
-
-       public boolean isValidID(String value) {
-
-               if ( value == null || value == "") {
-                       return false;
-               }
-
-               Pattern pattern = Pattern.compile(getRegex());
-               Matcher matcher = pattern.matcher(value);
-               if (matcher.matches()) {
-                       return true;
-               } else {
-                       return false;
-               }
-               
-       }
-
-       public String getRegex() {
-               String regex = "(" + "\\d" + "{1," + Integer.toString(this.maxLength) + "}" + ")";
-               return regex;
-       }
-       
-}
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGeneratorPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDGeneratorPart.java
new file mode 100644 (file)
index 0000000..6dc5ae0
--- /dev/null
@@ -0,0 +1,177 @@
+/**  
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+ *
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+ *
+ * Copyright © 2009 Regents of the University of California
+ *
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+ *
+ * You may obtain a copy of the ECL 2.0 License at
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ *
+ * $LastChangedBy$
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
+
+// @TODO: Add Javadoc comments
+
+// @TODO: Need to set and enforce maximum value.
+package org.collectionspace.services.id;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**  
+ * NumericIDGeneratorPart
+ *
+ * Generates identifiers (IDs) that consist of a sequence of
+ * numeric values, beginning from an initial value.
+ *
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
+public class NumericIDGeneratorPart implements IDGeneratorPart {
+  
+    final static private int DEFAULT_MAX_LENGTH = 6;
+    private int maxLength = DEFAULT_MAX_LENGTH;
+    
+    final static private int DEFAULT_INITIAL_VALUE = 1;
+    private long initialValue = DEFAULT_INITIAL_VALUE;
+    private long currentValue = DEFAULT_INITIAL_VALUE;
+
+    // Constructor using defaults for initial value and maximum length.
+    public NumericIDGeneratorPart() throws IllegalArgumentException {
+        this(Integer.toString(DEFAULT_INITIAL_VALUE), 
+            Integer.toString(DEFAULT_MAX_LENGTH));
+    }
+
+    // Constructor using default maximum length.
+    public NumericIDGeneratorPart(String initialValue)
+        throws IllegalArgumentException {
+        this(initialValue, Integer.toString(DEFAULT_MAX_LENGTH));
+    }
+
+    // Constructor.
+    public NumericIDGeneratorPart(String initialValue, String maxLength)
+        throws IllegalArgumentException {
+
+        if (initialValue == null || initialValue.equals("")) {
+            throw new IllegalArgumentException(
+                "Initial ID value must not be null or empty");
+        }
+        
+        try {
+            long l = Long.parseLong(initialValue.trim());
+            if ( l < 0 ) {
+                throw new IllegalArgumentException(
+                    "Initial ID value should be zero (0) or greater");
+            }
+            this.currentValue = l;
+            this.initialValue = l;
+        } catch (NullPointerException e) {
+            throw new IllegalArgumentException(
+                "Initial ID value should not be null");
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException(
+                "Initial ID value must be parseable as a number");
+        }
+
+        if (maxLength == null || maxLength.equals("")) {
+            throw new IllegalArgumentException(
+                "Initial ID value must not be null or empty");
+        }
+
+        try {
+            this.maxLength = Integer.parseInt(maxLength);
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException(
+                "Maximum ID length must be parseable as a number");
+        }
+        
+    }
+
+    public String getInitialID() {
+        return Long.toString(this.initialValue);
+    }
+
+    public String getCurrentID() {
+        return Long.toString(this.currentValue);
+    }
+
+    // Sets the current value of the ID.
+    public void setCurrentID(String value) throws IllegalArgumentException {
+
+      // @TODO Much of this code is copied from the main constructor,
+      // and may be ripe for refactoring.
+
+        if (value == null || value.equals("")) {
+            throw new IllegalArgumentException(
+                "ID value must not be null or empty");
+        }
+        
+        try {
+            long l = Long.parseLong(value.trim());
+            if ( l < 0 ) {
+                throw new IllegalArgumentException(
+                    "ID value should be zero (0) or greater");
+            }
+            this.currentValue = l;
+            this.initialValue = l;
+        } catch (NullPointerException e) {
+            throw new IllegalArgumentException(
+                "ID value should not be null");
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException(
+                "ID value must be parseable as a number");
+        }
+        
+        // @TODO An expedient; we may need to check the String length of the
+        // provided ID and calculate a maximum length here.
+        this.maxLength = DEFAULT_MAX_LENGTH;
+    }
+    
+    public void resetID() {
+        this.currentValue = this.initialValue;
+    }
+
+    // Returns the next ID in the sequence, and sets the current value to that ID.
+    public String nextID() throws IllegalStateException {
+        this.currentValue++;
+        String nextID = Long.toString(this.currentValue);
+        if (nextID.length() > this.maxLength) {
+            throw new IllegalStateException(
+                "Next ID cannot exceed maximum length");
+        }
+        return nextID;
+    }
+
+    public boolean isValidID(String value) {
+
+        if ( value == null || value == "") {
+            return false;
+        }
+
+        Pattern pattern = Pattern.compile(getRegex());
+        Matcher matcher = pattern.matcher(value);
+        if (matcher.matches()) {
+            return true;
+        } else {
+            return false;
+        }
+        
+    }
+
+    public String getRegex() {
+        String regex =
+            "(" + "\\d" + "{1," + Integer.toString(this.maxLength) + "}" + ")";
+        return regex;
+    }
+    
+}
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/NumericIDPart.java
deleted file mode 100644 (file)
index bb3e5b0..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
- /*    
- * NumericIDPart
- *
- * Models a part of an identifier (ID) whose values consist of an
- * incrementing numeric series, with those values represented as
- * String objects.
- *
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
- */
-
-// @TODO: Add Javadoc comments
-
-package org.collectionspace.services.id;
-
-public class NumericIDPart extends IDPart {
-
-       public NumericIDPart() throws IllegalArgumentException {
-               super(new NumericIDGenerator());
-       };
-
-       // Store the appropriate Numeric ID generator and the base value for this part.
-       public NumericIDPart(String baseVal) throws IllegalArgumentException {
-               super(new NumericIDGenerator(baseVal));
-       };
-
-       // Store the appropriate Numeric ID generator, and the base value
-       // and maximum length for this part.
-       public NumericIDPart(String baseVal, String maxLength) throws IllegalArgumentException {
-               super(new NumericIDGenerator(baseVal, maxLength));
-       };
-
-}
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/StringIDGenerator.java b/services/id/service/src/main/java/org/collectionspace/services/id/StringIDGenerator.java
deleted file mode 100644 (file)
index 98e9b2d..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*     
- * StringIDGenerator
- *
- * Generates identifiers (IDs) that consist of a static String value.
- *
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
- */
-
-// @TODO: Add Javadoc comments
-
-// @TODO: Need to set and enforce maximum String length.
-
-package org.collectionspace.services.id;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-public class StringIDGenerator implements IDGenerator {
-    
-       private String initialValue = null;
-       private String currentValue = null;
-       
-       public StringIDGenerator(String initialValue) throws IllegalArgumentException {
-
-               if (initialValue == null || initialValue.equals("")) {
-                       throw new IllegalArgumentException("Initial ID value must not be null or empty");
-               }
-               
-               this.initialValue = initialValue;
-               this.currentValue = initialValue;
-
-       }
-
-       public String getInitialID() {
-               return this.initialValue;
-       }
-
-       public String getCurrentID() {
-               return this.currentValue;
-       }
-
-       public void setCurrentID(String value) throws IllegalArgumentException {
-               if (value == null || value.equals("")) {
-                       throw new IllegalArgumentException("ID value must not be null or empty");
-               }
-               this.currentValue = value;
-       }
-       
-       public void resetID() {
-               // Do nothing
-       }
-
-       public String nextID() {
-               return this.currentValue;
-  }
-
-       public boolean isValidID(String value) {
-
-               if (value == null || value.equals("")) {
-                       return false;
-               }
-
-               Pattern pattern = Pattern.compile(getRegex());
-               Matcher matcher = pattern.matcher(value);
-               if (matcher.matches()) {
-                       return true;
-               } else {
-                       return false;
-               }
-               
-       }
-
-       public String getRegex() {
-
-         String initial = this.initialValue;
-
-         // Escape or otherwise modify various characters that have
-         // significance in regular expressions.
-         //
-         // @TODO Test these thoroughly, add processing of more
-         // special characters as needed.
-
-    // Escape un-escaped period/full stop characters.
-               Pattern pattern = Pattern.compile("([^\\\\]{0,1})\\.");
-               Matcher matcher = pattern.matcher(initial);
-    String escapedInitial = matcher.replaceAll("$1\\\\.");
-
-               String regex = "(" + escapedInitial + ")";
-               return regex;
-       }
-       
-}
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/StringIDGeneratorPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/StringIDGeneratorPart.java
new file mode 100644 (file)
index 0000000..19254a3
--- /dev/null
@@ -0,0 +1,113 @@
+/**   
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+ *
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+ *
+ * Copyright © 2009 Regents of the University of California
+ *
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+ *
+ * You may obtain a copy of the ECL 2.0 License at
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+
+// @TODO: Add Javadoc comments
+
+// @TODO: Need to set and enforce maximum String length.
+
+package org.collectionspace.services.id;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * StringIDGeneratorPart
+ *
+ * Generates identifiers (IDs) that consist of a static String value.
+ *
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
+public class StringIDGeneratorPart implements IDGeneratorPart {
+    
+    private String initialValue = null;
+    private String currentValue = null;
+    
+    public StringIDGeneratorPart(String initialValue)
+        throws IllegalArgumentException {
+
+        if (initialValue == null || initialValue.equals("")) {
+            throw new IllegalArgumentException(
+                "Initial ID value must not be null or empty");
+        }
+        
+        this.initialValue = initialValue;
+        this.currentValue = initialValue;
+
+    }
+
+    public String getInitialID() {
+        return this.initialValue;
+    }
+
+    public String getCurrentID() {
+        return this.currentValue;
+    }
+
+    public void setCurrentID(String value) throws IllegalArgumentException {
+        if (value == null || value.equals("")) {
+            throw new IllegalArgumentException(
+            "ID value must not be null or empty");
+        }
+        this.currentValue = value;
+    }
+    
+    public void resetID() {
+        // Do nothing
+    }
+
+    public String nextID() {
+        return this.currentValue;
+  }
+
+    public boolean isValidID(String value) {
+
+        if (value == null || value.equals("")) {
+            return false;
+        }
+
+        Pattern pattern = Pattern.compile(getRegex());
+        Matcher matcher = pattern.matcher(value);
+        if (matcher.matches()) {
+            return true;
+        } else {
+            return false;
+        }
+        
+    }
+
+    public String getRegex() {
+
+        String initial = this.initialValue;
+        
+        // Escape or otherwise modify various characters that have
+        // significance in regular expressions.
+        //
+        // @TODO Test these thoroughly, add processing of more
+        // special characters as needed.
+        
+        // Escape un-escaped period/full stop characters.
+        Pattern pattern = Pattern.compile("([^\\\\]{0,1})\\.");
+        Matcher matcher = pattern.matcher(initial);
+        String escapedInitial = matcher.replaceAll("$1\\\\.");
+
+        String regex = "(" + escapedInitial + ")";
+        return regex;
+    }
+    
+}
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/StringIDPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/StringIDPart.java
deleted file mode 100644 (file)
index 7fd8981..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
- /*    
- * StringIDPart
- *
- * Models a part of an identifier (ID) that stores and returns a static String value.
- *
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
- */
-
-// @TODO: Add Javadoc comments
-
-package org.collectionspace.services.id;
-
-public class StringIDPart extends IDPart {
-
-       public StringIDPart(String baseVal) {
-               super(new StringIDGenerator(baseVal));
-       };
-               
-}
similarity index 90%
rename from services/id/service/src/main/java/org/collectionspace/services/id/YearIDGenerator.java
rename to services/id/service/src/main/java/org/collectionspace/services/id/YearIDGeneratorPart.java
index 49f42b2d2c7ad8fdd2909301bdabf044367ade59..286fa843edc063cdc48971d167cf54d7720619e7 100644 (file)
@@ -1,9 +1,4 @@
-/*     
- * YearIDGenerator
- *
- * Generates identifiers (IDs) that store and returns the current year
- * or a supplied year as a String object.
- *
+/**
  * This document is a part of the source code and related artifacts
  * for CollectionSpace, an open source collections management system
  * for museums and related institutions:
  *
  * You may obtain a copy of the ECL 2.0 License at
  * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
  */
 
 // @TODO: Add Javadoc comments
@@ -51,12 +42,21 @@ import java.util.GregorianCalendar;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-public class YearIDGenerator implements IDGenerator {
+/**
+ * YearIDGeneratorPart
+ *
+ * Generates identifiers (IDs) that store and returns the current year
+ * or a supplied year as a String object.
+ *
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
+public class YearIDGeneratorPart implements IDGeneratorPart {
     
        private String initialValue = null;
        private String currentValue = null;
        
-       public YearIDGenerator() throws IllegalArgumentException {
+       public YearIDGeneratorPart() throws IllegalArgumentException {
 
                String currentYear = getCurrentYear();
                this.initialValue = currentYear;
@@ -64,10 +64,12 @@ public class YearIDGenerator implements IDGenerator {
 
        }
        
-       public YearIDGenerator(String initialValue) throws IllegalArgumentException {
+       public YearIDGeneratorPart(String initialValue)
+           throws IllegalArgumentException {
 
                if (initialValue == null || initialValue.equals("")) {
-                       throw new IllegalArgumentException("Initial ID value must not be null or empty");
+                       throw new IllegalArgumentException(
+                           "Initial ID value must not be null or empty");
                }
                
                // @TODO: Add regex-based validation here, by calling isValidID().
@@ -114,11 +116,11 @@ public class YearIDGenerator implements IDGenerator {
        //   to a new instant in time.
        public String nextID() {
                return this.currentValue;
-  }
+    }
 
        public static String getCurrentYear() {
                Calendar cal = GregorianCalendar.getInstance();
-    int y = cal.get(Calendar.YEAR);
+        int y = cal.get(Calendar.YEAR);
                return Integer.toString(y);
        }       
 
diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/YearIDPart.java b/services/id/service/src/main/java/org/collectionspace/services/id/YearIDPart.java
deleted file mode 100644 (file)
index d66bfd9..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
- /*    
- * YearIDGenerator
- *
- * Models a part of an identifier (ID) whose value is the current year
- * or a supplied year.
- *
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
- */
-
-// @TODO: Add Javadoc comments
-
-package org.collectionspace.services.id;
-
-public class YearIDPart extends IDPart {
-
-       public YearIDPart() {
-               super(new YearIDGenerator());
-       };
-
-       public YearIDPart(String baseVal) {
-               super(new YearIDGenerator(baseVal));
-       };
-               
-}
diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/IDPatternTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/IDPatternTest.java
deleted file mode 100644 (file)
index 27ec02f..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/*     
- * IDPatternTest
- *
- * Test class for IDPattern.
- *
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
- */
-
-package org.collectionspace.services.id;
-
-import static org.junit.Assert.fail;
-import java.util.Vector;
-import junit.framework.TestCase;
-
-public class IDPatternTest extends TestCase {
-
-       IDPattern pattern;
-       IDPart part;
-       
-       final static String DEFAULT_CSID = "1";
-
-       // Note: tests may fail with IllegalArgumentException
-       // if any initialization of new IDParts fails
-       // due to invalid arguments passed to their constructors.
-
-       public void testCurrentIDViaVector() {
-
-               Vector parts = new Vector();
-               parts.add(new YearIDPart("2009"));
-               parts.add(new StringIDPart("."));
-               parts.add(new NumericIDPart("1"));
-               parts.add(new StringIDPart("-"));
-               parts.add(new AlphabeticIDPart("a"));
-               pattern = new IDPattern(DEFAULT_CSID, parts);
-               assertEquals("2009.1-a", pattern.getCurrentID());
-                       
-       }
-
-       public void testCurrentIDViaAdd() {
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               pattern.add(new StringIDPart("-"));
-               pattern.add(new AlphabeticIDPart("a")); 
-               assertEquals("2009.1-a", pattern.getCurrentID());
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("0"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("0"));
-               assertEquals("2009.0.0", pattern.getCurrentID());
-                       
-       }
-
-       public void testCurrentIDWithPartialSuppliedID() {
-                       
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new StringIDPart("E"));
-               pattern.add(new NumericIDPart("1"));
-               assertEquals("E1", pattern.getCurrentID("E"));
-               assertEquals("E2", pattern.nextID());
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart());
-               pattern.add(new StringIDPart("."));
-               assertEquals("2009.", pattern.getCurrentID("2009"));
-               assertEquals("2009.", pattern.nextID());
-               assertEquals("2010.", pattern.getCurrentID("2010"));
-               assertEquals("2010.", pattern.nextID());
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart());
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               assertEquals("2009.1", pattern.getCurrentID("2009."));
-               assertEquals("2009.2", pattern.nextID());
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart());
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("55"));
-               assertEquals("2010.55", pattern.getCurrentID("2010."));
-               assertEquals("2010.56", pattern.nextID());
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart());
-               assertEquals("2009.1", pattern.getCurrentID("2009."));
-               assertEquals("2009.2", pattern.nextID());
-               // Test a repeat of the last two operations.
-               assertEquals("2009.1", pattern.getCurrentID("2009."));
-               assertEquals("2009.2", pattern.nextID());
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               pattern.add(new StringIDPart("-"));
-               pattern.add(new AlphabeticIDPart("a"));
-               assertEquals("2009.1-a", pattern.getCurrentID("2009.1-"));
-               assertEquals("2009.1-b", pattern.nextID());
-               assertEquals("2009.3-a", pattern.getCurrentID("2009.3-"));
-
-       }
-
-       public void testCurrentIDWithFullSuppliedID() {
-       
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("55"));
-               assertEquals("2009.55", pattern.getCurrentID("2009.55"));
-               assertEquals("2009.56", pattern.nextID());
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               pattern.add(new StringIDPart("-"));
-               pattern.add(new AlphabeticIDPart("a"));
-               assertEquals("2009.1-a", pattern.getCurrentID("2009.1-a"));
-               assertEquals("2009.1-b", pattern.nextID());
-
-       }
-
-       public void testNextID() {
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               assertEquals("2009.2", pattern.nextID());
-               assertEquals("2009.3", pattern.nextID());
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               pattern.add(new StringIDPart("-"));
-               pattern.add(new AlphabeticIDPart("a"));
-               assertEquals("2009.1-b", pattern.nextID());
-               assertEquals("2009.1-c", pattern.nextID());
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new StringIDPart("T"));
-               pattern.add(new NumericIDPart("1005"));
-               assertEquals("T1006", pattern.nextID());
-               assertEquals("T1007", pattern.nextID());
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               assertEquals("2009.1.2", pattern.nextID());
-                       
-       }
-
-       public void testNextIDWithConstantStringID() {
-       
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               pattern.add(new StringIDPart("-"));
-               assertEquals("2009.1-", pattern.nextID());
-               assertEquals("2009.1-", pattern.nextID());
-
-       }
-
-       public void testNextIDWithSuppliedID() {
-       
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               assertEquals("2009.2", pattern.nextID("2009.1"));
-               assertEquals("2009.3", pattern.nextID("2009.2"));
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               pattern.add(new StringIDPart("-"));
-               pattern.add(new AlphabeticIDPart("a"));
-               assertEquals("2009.1-b", pattern.nextID("2009.1-a"));
-               assertEquals("2009.3-c", pattern.nextID("2009.3-b"));
-
-       }
-
-       public void testEmptyPartsListCurrentID() {
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               assertEquals("", pattern.getCurrentID());
-                       
-       }
-
-       public void testIsValidIDYearPattern() {
-       
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-
-               assertTrue(pattern.isValidID("2009"));
-               assertTrue(pattern.isValidID("5555"));
-
-               assertFalse(pattern.isValidID("456"));
-               assertFalse(pattern.isValidID("10000"));
-               
-       }
-
-
-       public void testGetRegex() {
-       
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               assertEquals("(\\d{4})(\\.)(\\d{1,6})", pattern.getRegex());
-       
-       }
-
-       public void testIsValidIDYearSeparatorItemPattern() {
-       
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("."));
-               pattern.add(new NumericIDPart("1"));
-               
-               assertTrue(pattern.isValidID("2009.1"));
-               assertTrue(pattern.isValidID("5555.55"));
-
-               assertFalse(pattern.isValidID("456.1"));
-               assertFalse(pattern.isValidID("2009-1"));
-               assertFalse(pattern.isValidID("2009.a"));
-               assertFalse(pattern.isValidID("2009-a"));
-               assertFalse(pattern.isValidID("non-pattern conforming text"));
-
-               pattern = new IDPattern(DEFAULT_CSID);
-               pattern.add(new YearIDPart("2009"));
-               pattern.add(new StringIDPart("ZZ.AND."));
-               pattern.add(new NumericIDPart("1"));
-
-               assertTrue(pattern.isValidID("2009ZZ.AND.1"));
-               assertFalse(pattern.isValidID("2009ZZ-AND-1"));
-       
-       }
-
-       // @TODO: Add more tests of boundary conditions, exceptions ...
-}
diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/NumericIDPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/NumericIDPartTest.java
deleted file mode 100644 (file)
index 5cb7089..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*     
- * NumericIDPartTest
- *
- * Test class for NumericIDPart.
- *
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
- */
-
-package org.collectionspace.services.id;
-
-import static org.junit.Assert.fail;
-import junit.framework.TestCase;
-
-public class NumericIDPartTest extends TestCase {
-
-       IDPart part;
-
-       public void testNextID() {
-
-               part = new NumericIDPart("0");          
-               assertEquals("1", part.nextID());
-               assertEquals("2", part.nextID());
-               assertEquals("3", part.nextID());
-
-               part = new NumericIDPart("25");
-               assertEquals("26", part.nextID());
-               assertEquals("27", part.nextID());
-               assertEquals("28", part.nextID());
-               
-               part = new NumericIDPart();
-               assertEquals("2", part.nextID());
-                       
-       }
-
-       public void testNextIDOverflow() {
-
-               try {
-                       part = new NumericIDPart("997", "3");           
-                       assertEquals("998", part.nextID());
-                       assertEquals("999", part.nextID());
-                       assertEquals("1000", part.nextID());
-                       fail("Should have thrown IllegalStateException here");
-               } catch (IllegalStateException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-
-               // Tests default MAX_LENGTH value of 6 decimal places
-               try {
-                       part = new NumericIDPart("999997");             
-                       assertEquals("999998", part.nextID());
-                       assertEquals("999999", part.nextID());
-                       assertEquals("1000000", part.nextID());
-                       fail("Should have thrown IllegalStateException here");
-               } catch (IllegalStateException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-                       
-       }
-
-       public void testResetID() {
-       
-               part = new NumericIDPart("25");
-               assertEquals("26", part.nextID());
-               assertEquals("27", part.nextID());
-               assertEquals("28", part.nextID());
-               part.resetID();
-               assertEquals("26", part.nextID());
-                       
-       }
-
-       public void testInitialID() {
-
-               part = new NumericIDPart("0");
-               assertEquals("0", part.getInitialID());
-
-               part = new NumericIDPart("25");
-               assertEquals("25", part.getInitialID());
-               
-       }
-
-       public void testCurrentID() {
-
-               part = new NumericIDPart("0");
-               assertEquals("0", part.getCurrentID());
-               assertEquals("1", part.nextID());
-               assertEquals("2", part.nextID());
-               assertEquals("2", part.getCurrentID());
-               assertEquals("3", part.nextID());
-
-               part = new NumericIDPart("25");
-               assertEquals("25", part.getCurrentID());
-               
-       }
-       
-       public void testNullInitialValue() {
-       
-               try {
-                       part = new NumericIDPart(null);
-                       fail("Should have thrown IllegalArgumentException here");
-               } catch (IllegalArgumentException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-               
-       }
-
-       public void testNonLongParseableInitialValue() {
-       
-               try {
-                       part = new NumericIDPart("not a long parseable value");
-                       fail("Should have thrown IllegalArgumentException here");
-               } catch (IllegalArgumentException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-
-       }
-
-       public void testNonLongParseableMaxLength() {
-       
-               try {
-                       part = new NumericIDPart("1", "not an int parseable value");
-                       fail("Should have thrown IllegalArgumentException here");
-               } catch (IllegalArgumentException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-
-       }
-
-       public void testNegativeInitialValue() {
-
-               try {
-                       part = new NumericIDPart("-1");
-                       fail("Should have thrown IllegalArgumentException here");
-               } catch (IllegalArgumentException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-       }
-
-
-       public void testIsValidID() {
-       
-               part = new NumericIDPart("1");
-               assertTrue(part.isValidID("1"));
-
-               part = new NumericIDPart("1");
-               assertTrue(part.isValidID("123"));
-
-               part = new NumericIDPart("1");
-               assertTrue(part.isValidID("123456"));
-
-               part = new NumericIDPart("1");
-               assertFalse(part.isValidID("1234567"));
-               
-               part = new NumericIDPart("1", "3");
-               assertTrue(part.isValidID("123"));
-               
-               part = new NumericIDPart("1", "3");
-               assertFalse(part.isValidID("1234"));
-
-               part = new NumericIDPart("1");
-               assertFalse(part.isValidID("not a parseable long"));
-
-               part = new NumericIDPart("1", "3");
-               assertFalse(part.isValidID("not a parseable long"));
-
-               part = new NumericIDPart("1", "3");
-               assertFalse(part.isValidID(null));
-
-               part = new NumericIDPart("1", "3");
-               assertFalse(part.isValidID(""));
-       
-       }       
-       
-       // @TODO: Add more tests of boundary conditions, exceptions ...
-}
diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/YearIDPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/YearIDPartTest.java
deleted file mode 100644 (file)
index 90d6bfb..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*     
- * YearIDPartTest
- *
- * Test class for YearIDPart.
- *
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
- */
-
-package org.collectionspace.services.id;
-
-import static org.junit.Assert.fail;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import junit.framework.TestCase;
-
-public class YearIDPartTest extends TestCase {
-
-       IDPart part;
-       String year = "1999";
-
-       public String getCurrentYear() {
-               Calendar cal = GregorianCalendar.getInstance();
-    int y = cal.get(Calendar.YEAR);
-               return Integer.toString(y);
-       }
-
-       public void testCurrentID() {
-
-               part = new YearIDPart();
-               assertEquals(getCurrentYear(), part.getCurrentID());
-
-               part = new YearIDPart(year);
-               assertEquals(year, part.getCurrentID());
-
-       }
-
-       public void testSetCurrentID() {
-
-               part = new YearIDPart("1999");
-               part.setCurrentID("1999");
-               assertEquals("1999", part.getCurrentID());
-               part.setCurrentID("2000");
-               assertEquals("2000", part.getCurrentID());
-
-       }
-
-       public void testSetCurrentIDNullOrEmpty() {
-
-               part = new YearIDPart();
-
-               try {
-                 part.setCurrentID(null);
-                       fail("Should have thrown IllegalArgumentException here");
-               } catch (IllegalArgumentException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-
-               try {
-                 part.setCurrentID("");
-                       fail("Should have thrown IllegalArgumentException here");
-               } catch (IllegalArgumentException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-
-  }
-       
-       public void testNextID() {
-       
-               part = new YearIDPart("1999");          
-               assertEquals("1999", part.nextID());            
-               
-       }
-
-       public void testresetID() {
-       
-               part = new YearIDPart("1999");
-               assertEquals("1999", part.nextID());
-               part.resetID();
-               assertEquals("1999", part.getCurrentID());
-                       
-       }
-
-       public void testInitialID() {
-       
-               part = new YearIDPart("1999");
-               assertEquals("1999", part.getInitialID());
-               
-       }
-
-
-       public void testNullInitialValue() {
-       
-               try {
-                       part = new YearIDPart(null);
-                       fail("Should have thrown IllegalArgumentException here");
-               } catch (IllegalArgumentException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-               
-       }
-
-       public void testEmptyInitialValue() {
-       
-               try {
-                       part = new YearIDPart("");
-                       fail("Should have thrown IllegalArgumentException here");
-               } catch (IllegalArgumentException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-
-       }
-
-       public void testIsValidID() {
-       
-               part = new YearIDPart();
-               assertTrue(part.isValidID("2009"));
-
-               part = new YearIDPart();
-               assertFalse(part.isValidID("839"));
-
-               part = new YearIDPart();
-               assertFalse(part.isValidID("10100"));
-               
-               part = new YearIDPart();
-               assertFalse(part.isValidID("non-numeric value"));
-
-    part = new YearIDPart();
-    assertFalse(part.isValidID(null));
-    
-    part = new YearIDPart();
-    assertFalse(part.isValidID(""));
-
-       }
-
-       // @TODO: Add more tests of boundary conditions, exceptions ...
-}
similarity index 77%
rename from services/id/service/src/test/java/org/collectionspace/services/id/AlphabeticIDPartTest.java
rename to services/id/service/src/test/java/org/collectionspace/services/id/test/AlphabeticIDGeneratorPartTest.java
index abde5674a14c92bd909ee5d0dc5cd5bc563cd928..751202acc7eb9be1e028862cc60e81efc2d03fbd 100644 (file)
@@ -1,8 +1,4 @@
-/*     
- * AlphabeticIDPartTest
- *
- * Test class for AlphabeticIDPart.
- *
+/**    
  * This document is a part of the source code and related artifacts
  * for CollectionSpace, an open source collections management system
  * for museums and related institutions:
  *
  * You may obtain a copy of the ECL 2.0 License at
  * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
  */
 
 package org.collectionspace.services.id;
@@ -28,17 +20,25 @@ package org.collectionspace.services.id;
 import static org.junit.Assert.fail;
 import junit.framework.TestCase;
 
-public class AlphabeticIDPartTest extends TestCase {
+/**    
+ * AlphabeticIDGeneratorPartTest
+ *
+ * Test class for AlphabeticIDGeneratorPart.
+ *
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
+public class AlphabeticIDGeneratorPartTest extends TestCase {
 
-       IDPart part;
+       IDGeneratorPart part;
        
-       public void testnextIDLowercase() {
+       public void testNextIDLowercase() {
 
-               part = new AlphabeticIDPart("a");
+               part = new AlphabeticIDGeneratorPart("a");
                assertEquals("b", part.nextID());
                assertEquals("c", part.nextID());
 
-               part = new AlphabeticIDPart("x");
+               part = new AlphabeticIDGeneratorPart("x");
                assertEquals("y", part.nextID());
                assertEquals("z", part.nextID());
 
@@ -46,11 +46,11 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testnextIDLowercase2Chars() {
 
-               part = new AlphabeticIDPart("aa");
+               part = new AlphabeticIDGeneratorPart("aa");
                assertEquals("ab", part.nextID());
                assertEquals("ac", part.nextID());
 
-               part = new AlphabeticIDPart("zx");
+               part = new AlphabeticIDGeneratorPart("zx");
                assertEquals("zy", part.nextID());
                assertEquals("zz", part.nextID());
 
@@ -58,7 +58,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testnextIDLowercase2CharsRolloverFirst() {
 
-               part = new AlphabeticIDPart("ay");
+               part = new AlphabeticIDGeneratorPart("ay");
                assertEquals("az", part.nextID());
                assertEquals("ba", part.nextID());
                assertEquals("bb", part.nextID());
@@ -67,11 +67,11 @@ public class AlphabeticIDPartTest extends TestCase {
        
        public void testnextIDUppercase() {
                
-               part = new AlphabeticIDPart("A", "Z", "A");
+               part = new AlphabeticIDGeneratorPart("A", "Z", "A");
                assertEquals("B", part.nextID());
                assertEquals("C", part.nextID());
 
-               part = new AlphabeticIDPart("A", "Z", "X");
+               part = new AlphabeticIDGeneratorPart("A", "Z", "X");
                assertEquals("Y", part.nextID());
                assertEquals("Z", part.nextID());
 
@@ -79,11 +79,11 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testnextIDUppercase2Chars() {
 
-               part = new AlphabeticIDPart("A", "Z", "AA");
+               part = new AlphabeticIDGeneratorPart("A", "Z", "AA");
                assertEquals("AB", part.nextID());
                assertEquals("AC", part.nextID());
 
-               part = new AlphabeticIDPart("A", "Z", "ZX");
+               part = new AlphabeticIDGeneratorPart("A", "Z", "ZX");
                assertEquals("ZY", part.nextID());
                assertEquals("ZZ", part.nextID());
                        
@@ -91,7 +91,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testnextIDUppercase2CharsRolloverFirst() {
 
-               part = new AlphabeticIDPart("A", "Z", "AY");
+               part = new AlphabeticIDGeneratorPart("A", "Z", "AY");
                assertEquals("AZ", part.nextID());
                assertEquals("BA", part.nextID());
                assertEquals("BB", part.nextID());
@@ -100,7 +100,7 @@ public class AlphabeticIDPartTest extends TestCase {
   
        public void testresetIDLowercase() {
                
-               part = new AlphabeticIDPart("zx");
+               part = new AlphabeticIDGeneratorPart("zx");
                assertEquals("zy", part.nextID());
                assertEquals("zz", part.nextID());
                part.resetID();
@@ -110,7 +110,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testresetIDUppercase() {
                
-               part = new AlphabeticIDPart("A", "Z", "RA");
+               part = new AlphabeticIDGeneratorPart("A", "Z", "RA");
                assertEquals("RB", part.nextID());
                assertEquals("RC", part.nextID());
                part.resetID();
@@ -120,21 +120,21 @@ public class AlphabeticIDPartTest extends TestCase {
        
        public void testInitialLowercase() {
                
-               part = new AlphabeticIDPart("aaa");
+               part = new AlphabeticIDGeneratorPart("aaa");
                assertEquals("aaa", part.getInitialID());
                
        }
 
        public void testInitialUppercase() {
                
-               part = new AlphabeticIDPart("A", "Z", "AZ");
+               part = new AlphabeticIDGeneratorPart("A", "Z", "AZ");
                assertEquals("AZ", part.getInitialID());
                
        }
 
        public void testCurrentLowercase() {
                
-               part = new AlphabeticIDPart("aaa");
+               part = new AlphabeticIDGeneratorPart("aaa");
                assertEquals("aaa", part.getCurrentID());
                assertEquals("aab", part.nextID());
                assertEquals("aac", part.nextID());
@@ -145,7 +145,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testCurrentUppercase() {
                
-               part = new AlphabeticIDPart("A", "Z", "A");
+               part = new AlphabeticIDGeneratorPart("A", "Z", "A");
                assertEquals("A", part.getCurrentID());
                assertEquals("B", part.nextID());
                assertEquals("C", part.nextID());
@@ -156,7 +156,7 @@ public class AlphabeticIDPartTest extends TestCase {
        
        public void testOverflowLowercase() {
        
-    part = new AlphabeticIDPart("zx");
+    part = new AlphabeticIDGeneratorPart("zx");
     assertEquals("zy", part.nextID());
     assertEquals("zz", part.nextID());
     assertEquals("aaa", part.nextID());
@@ -165,7 +165,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testOverflowUppercase() {
        
-    part = new AlphabeticIDPart("A", "Z", "X");
+    part = new AlphabeticIDGeneratorPart("A", "Z", "X");
     assertEquals("Y", part.nextID());
     assertEquals("Z", part.nextID());
     assertEquals("AA", part.nextID());
@@ -174,7 +174,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testNonAlphabeticInitialValue() {
                try {
-                       part = new AlphabeticIDPart("&*432");
+                       part = new AlphabeticIDGeneratorPart("&*432");
                        fail("Should have thrown IllegalArgumentException here");
                } catch (IllegalArgumentException expected) {
                        // This Exception should be thrown, and thus the test should pass.
@@ -183,7 +183,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testNullInitialValue() {
                try {
-                       part = new AlphabeticIDPart(null);
+                       part = new AlphabeticIDGeneratorPart(null);
                        fail("Should have thrown IllegalArgumentException here");
                } catch (IllegalArgumentException expected) {
                        // This Exception should be thrown, and thus the test should pass.
@@ -192,7 +192,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testEmptyStringInitialValue() {
                try {
-                       part = new AlphabeticIDPart("");
+                       part = new AlphabeticIDGeneratorPart("");
                        fail("Should have thrown IllegalArgumentException here");
                } catch (IllegalArgumentException expected) {
                        // This Exception should be thrown, and thus the test should pass.
@@ -201,7 +201,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testAllSpaceCharsInitialValue() {
                try {
-                       part = new AlphabeticIDPart("  ");
+                       part = new AlphabeticIDGeneratorPart("  ");
                        fail("Should have thrown IllegalArgumentException here");
                } catch (IllegalArgumentException expected) {
                        // This Exception should be thrown, and thus the test should pass.
@@ -210,7 +210,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testIsValidIDDefaultSeries() {
        
-               part = new AlphabeticIDPart();
+               part = new AlphabeticIDGeneratorPart();
 
                assertTrue(part.isValidID("a"));
                assertTrue(part.isValidID("z"));
@@ -222,7 +222,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testIsValidIDConstrainedLowerCaseSeries() {
        
-               part = new AlphabeticIDPart("a", "f", "a");
+               part = new AlphabeticIDGeneratorPart("a", "f", "a");
                
                assertTrue(part.isValidID("a"));
                assertTrue(part.isValidID("b"));
@@ -237,7 +237,7 @@ public class AlphabeticIDPartTest extends TestCase {
 
        public void testIsValidIDConstrainedUppercaseSeries() {
        
-               part = new AlphabeticIDPart("A", "F", "A");
+               part = new AlphabeticIDGeneratorPart("A", "F", "A");
 
                assertTrue(part.isValidID("A"));
                assertTrue(part.isValidID("B"));
index 78cac20d07cd5ceb55d4def7f0ae95087df6f324..585d348b2661fa7cf77805eaa1d5440a5b0cc169 100644 (file)
@@ -33,67 +33,65 @@ import static org.junit.Assert.*;
  *
  * Unit tests of the ID Service's IDGeneratorSerializer class.
  *
- *
- * $LastChangedBy: aron $
  * $LastChangedRevision: 302 $
  * $LastChangedDate$
  */
 public class IDGeneratorSerializerTest extends TestCase {
 
   String serializedGenerator;
-  IDPattern pattern;
+  BaseIDGenerator generator;
   
-       final static String DEFAULT_CSID = "TEST-1";
+  final static String DEFAULT_CSID = "TEST-1";
 
   final static String DEFAULT_SERIALIZED_ID_GENERATOR =
-    "<org.collectionspace.services.id.IDPattern>\n" +
+    "<org.collectionspace.services.id.BaseIDGenerator>\n" +
     "  <csid>" + DEFAULT_CSID + "</csid>\n" +
     "  <uri></uri>\n" +
     "  <description></description>\n" +
     "  <parts/>\n" +
-    "</org.collectionspace.services.id.IDPattern>";
+    "</org.collectionspace.services.id.BaseIDGenerator>";
 
-  // @TODO We may want to canonicalize (or otherwise normalize) the expected and
-  // actual XML in these tests, to avoid failures resulting from differences in
-  // whitespace, etc.
-       public void testSerializeIDGenerator() {
-         IDPattern pattern = new IDPattern(DEFAULT_CSID);
-               assertEquals(DEFAULT_SERIALIZED_ID_GENERATOR, IDGeneratorSerializer.serialize(pattern));
-       }
+    // @TODO We may want to canonicalize (or otherwise normalize) the expected and
+    // actual XML in these tests, to avoid failures resulting from differences in
+    // whitespace, etc.
+    public void testSerializeIDGenerator() {
+      BaseIDGenerator generator = new BaseIDGenerator(DEFAULT_CSID);
+        assertEquals(DEFAULT_SERIALIZED_ID_GENERATOR, IDGeneratorSerializer.serialize(generator));
+    }
 
-       public void testSerializeNullIDGenerator() {
-         try {
-           String serializedPattern = IDGeneratorSerializer.serialize(null);
-                       fail("Should have thrown IllegalArgumentException here");
-               } catch (IllegalArgumentException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-       }
+    public void testSerializeNullIDGenerator() {
+      try {
+        String serializedPattern = IDGeneratorSerializer.serialize(null);
+            fail("Should have thrown IllegalArgumentException here");
+        } catch (IllegalArgumentException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+    }
 
-       public void testDeserializeIDGenerator() {
-         // This test will fail with different hash codes unless we add an IDPattern.equals()
-         // method that explicitly defines object equality as, for instance, having identical values
-         // in each of its instance variables.
-         // IDPattern pattern = IDGeneratorSerializer.deserialize(DEFAULT_SERIALIZED_ID_PATTERN);
-         // assertEquals(pattern, new IDPattern(DEFAULT_CSID));
-       }
+    public void testDeserializeIDGenerator() {
+      // This test will fail with different hash codes unless we add an IDGenerator.equals()
+      // method that explicitly defines object equality as, for instance, having identical values
+      // in each of its instance variables.
+      // IDGenerator generator = IDGeneratorSerializer.deserialize(DEFAULT_SERIALIZED_ID_PATTERN);
+      // assertEquals(generator, new IDGenerator(DEFAULT_CSID));
+    }
 
-       public void testDeserializeNullSerializedIDGenerator() {
-         try {
-           IDPattern pattern = IDGeneratorSerializer.deserialize(null);
-                       fail("Should have thrown IllegalArgumentException here");
-               } catch (IllegalArgumentException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-       }
+    public void testDeserializeNullSerializedIDGenerator() {
+      try {
+        BaseIDGenerator generator = IDGeneratorSerializer.deserialize(null);
+            fail("Should have thrown IllegalArgumentException here");
+        } catch (IllegalArgumentException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+    }
 
-       public void testDeserializeInvalidSerializedIDGenerator() {
-         try {
-           IDPattern pattern = IDGeneratorSerializer.deserialize("<invalid_serialized_generator/>");
-                       fail("Should have thrown IllegalArgumentException here");
-               } catch (IllegalArgumentException expected) {
-                       // This Exception should be thrown, and thus the test should pass.
-               }
-       }
-       
+    public void testDeserializeInvalidSerializedIDGenerator() {
+      try {
+        IDGenerator generator = IDGeneratorSerializer.deserialize("<invalid_serialized_generator/>");
+            fail("Should have thrown IllegalArgumentException here");
+        } catch (IllegalArgumentException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+    }
+    
 }
diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/IDGeneratorTest.java
new file mode 100644 (file)
index 0000000..50a484a
--- /dev/null
@@ -0,0 +1,271 @@
+/*     
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+ *
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+ *
+ * Copyright © 2009 Regents of the University of California
+ *
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+ *
+ * You may obtain a copy of the ECL 2.0 License at
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+
+package org.collectionspace.services.id;
+
+import static org.junit.Assert.fail;
+import java.util.Vector;
+import junit.framework.TestCase;
+
+/**    
+ * IDGeneratorTest, Test class for IDGenerator.
+ *
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
+public class IDGeneratorTest extends TestCase {
+
+       BaseIDGenerator generator;
+       IDGeneratorPart part;
+       
+       final static String DEFAULT_CSID = "1";
+
+       // Note: tests may fail with IllegalArgumentException
+       // if any initialization of new IDParts fails
+       // due to invalid arguments passed to their constructors.
+
+       public void testCurrentIDViaVector() {
+
+               Vector parts = new Vector();
+               parts.add(new YearIDGeneratorPart("2009"));
+               parts.add(new StringIDGeneratorPart("."));
+               parts.add(new NumericIDGeneratorPart("1"));
+               parts.add(new StringIDGeneratorPart("-"));
+               parts.add(new AlphabeticIDGeneratorPart("a"));
+               generator = new BaseIDGenerator(DEFAULT_CSID, parts);
+               assertEquals("2009.1-a", generator.getCurrentID());
+                       
+       }
+
+       public void testCurrentIDViaAdd() {
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               generator.add(new StringIDGeneratorPart("-"));
+               generator.add(new AlphabeticIDGeneratorPart("a"));      
+               assertEquals("2009.1-a", generator.getCurrentID());
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("0"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("0"));
+               assertEquals("2009.0.0", generator.getCurrentID());
+                       
+       }
+
+       public void testCurrentIDWithPartialSuppliedID() {
+                       
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new StringIDGeneratorPart("E"));
+               generator.add(new NumericIDGeneratorPart("1"));
+               assertEquals("E1", generator.getCurrentID("E"));
+               assertEquals("E2", generator.newID());
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart());
+               generator.add(new StringIDGeneratorPart("."));
+               assertEquals("2009.", generator.getCurrentID("2009"));
+               assertEquals("2009.", generator.newID());
+               assertEquals("2010.", generator.getCurrentID("2010"));
+               assertEquals("2010.", generator.newID());
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart());
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               assertEquals("2009.1", generator.getCurrentID("2009."));
+               assertEquals("2009.2", generator.newID());
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart());
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("55"));
+               assertEquals("2010.55", generator.getCurrentID("2010."));
+               assertEquals("2010.56", generator.newID());
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart());
+               assertEquals("2009.1", generator.getCurrentID("2009."));
+               assertEquals("2009.2", generator.newID());
+               // Test a repeat of the last two operations.
+               assertEquals("2009.1", generator.getCurrentID("2009."));
+               assertEquals("2009.2", generator.newID());
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               generator.add(new StringIDGeneratorPart("-"));
+               generator.add(new AlphabeticIDGeneratorPart("a"));
+               assertEquals("2009.1-a", generator.getCurrentID("2009.1-"));
+               assertEquals("2009.1-b", generator.newID());
+               assertEquals("2009.3-a", generator.getCurrentID("2009.3-"));
+
+       }
+
+       public void testCurrentIDWithFullSuppliedID() {
+       
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("55"));
+               assertEquals("2009.55", generator.getCurrentID("2009.55"));
+               assertEquals("2009.56", generator.newID());
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               generator.add(new StringIDGeneratorPart("-"));
+               generator.add(new AlphabeticIDGeneratorPart("a"));
+               assertEquals("2009.1-a", generator.getCurrentID("2009.1-a"));
+               assertEquals("2009.1-b", generator.newID());
+
+       }
+
+       public void testNewID() {
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               assertEquals("2009.2", generator.newID());
+               assertEquals("2009.3", generator.newID());
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               generator.add(new StringIDGeneratorPart("-"));
+               generator.add(new AlphabeticIDGeneratorPart("a"));
+               assertEquals("2009.1-b", generator.newID());
+               assertEquals("2009.1-c", generator.newID());
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new StringIDGeneratorPart("T"));
+               generator.add(new NumericIDGeneratorPart("1005"));
+               assertEquals("T1006", generator.newID());
+               assertEquals("T1007", generator.newID());
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               assertEquals("2009.1.2", generator.newID());
+                       
+       }
+
+       public void testNewIDWithConstantStringID() {
+       
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               generator.add(new StringIDGeneratorPart("-"));
+               assertEquals("2009.1-", generator.newID());
+               assertEquals("2009.1-", generator.newID());
+
+       }
+
+       public void testNewIDWithSuppliedID() {
+       
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               assertEquals("2009.2", generator.newID("2009.1"));
+               assertEquals("2009.3", generator.newID("2009.2"));
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               generator.add(new StringIDGeneratorPart("-"));
+               generator.add(new AlphabeticIDGeneratorPart("a"));
+               assertEquals("2009.1-b", generator.newID("2009.1-a"));
+               assertEquals("2009.3-c", generator.newID("2009.3-b"));
+
+       }
+
+       public void testEmptyPartsListCurrentID() {
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               assertEquals("", generator.getCurrentID());
+                       
+       }
+
+       public void testIsValidIDYearPattern() {
+       
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+
+               assertTrue(generator.isValidID("2009"));
+               assertTrue(generator.isValidID("5555"));
+
+               assertFalse(generator.isValidID("456"));
+               assertFalse(generator.isValidID("10000"));
+               
+       }
+
+
+       public void testGetRegex() {
+       
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               assertEquals("(\\d{4})(\\.)(\\d{1,6})", generator.getRegex());
+       
+       }
+
+       public void testIsValidIDYearSeparatorItemPattern() {
+       
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("."));
+               generator.add(new NumericIDGeneratorPart("1"));
+               
+               assertTrue(generator.isValidID("2009.1"));
+               assertTrue(generator.isValidID("5555.55"));
+
+               assertFalse(generator.isValidID("456.1"));
+               assertFalse(generator.isValidID("2009-1"));
+               assertFalse(generator.isValidID("2009.a"));
+               assertFalse(generator.isValidID("2009-a"));
+               assertFalse(generator.isValidID("non-generator conforming text"));
+
+               generator = new BaseIDGenerator(DEFAULT_CSID);
+               generator.add(new YearIDGeneratorPart("2009"));
+               generator.add(new StringIDGeneratorPart("ZZ.AND."));
+               generator.add(new NumericIDGeneratorPart("1"));
+
+               assertTrue(generator.isValidID("2009ZZ.AND.1"));
+               assertFalse(generator.isValidID("2009ZZ-AND-1"));
+       
+       }
+
+       // @TODO: Add more tests of boundary conditions, exceptions ...
+}
index dca62a08b9509c9546eab7944679783ceb48092a..62635263060524b39ad653631ebda68da84340bf 100644 (file)
@@ -1,4 +1,4 @@
-/**    
+/**        
  * This document is a part of the source code and related artifacts
  * for CollectionSpace, an open source collections management system
  * for museums and related institutions:
@@ -20,163 +20,162 @@ package org.collectionspace.services.id.test;
 import org.collectionspace.services.id.*;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
-/**    
+/**        
  * IDServiceJdbcImplTest
  *
  * Unit tests for the ID Service's JDBC implementation class, IDServiceJdbcImpl.
  *
- * $LastChangedBy: aron $
  * $LastChangedRevision: 302 $
  * $LastChangedDate$
  */
 public class IDServiceJdbcImplTest {
 
-  // *IMPORTANT*
-  // @TODO This class is in an early state of a refactoring to
-  // reflect a change from IDPatterns to IDGenerators at the top level
-  // of the ID Service.  As a result, there will be some naming
-  // inconsistencies throughout this source file.
-
-  String csid;
-  String nextId;
-  String serializedGenerator;
-  IDPattern pattern;
-  
-  IDServiceJdbcImpl jdbc = new IDServiceJdbcImpl();
-  IDService service = jdbc;
-  
-  final static String TABLE_NAME = "id_generators";
-       final static String DEFAULT_CSID = "TEST-1";
-
-  @Test
-  public void hasRequiredDatabaseTable() {
-    Assert.assertTrue(
-      jdbc.hasTable(TABLE_NAME), 
-      "Table '" + TABLE_NAME + "' must exist in database. " + 
-      "Please first run SQL setup script, 'create_id_generators_table.sql', in 'id' project.");
-  }
-
-  @Test(dependsOnMethods = {"hasRequiredDatabaseTable"})
-  public void addIDGenerator() {
-    jdbc.addIDGenerator(DEFAULT_CSID, getSpectrumEntryNumberGenerator());
-  }
-
-  @Test(dependsOnMethods = {"addIDGenerator"})
-  public void readIDGenerator() {
-
-    serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID);
-    pattern = IDGeneratorSerializer.deserialize(serializedGenerator);
-    Assert.assertEquals(DEFAULT_CSID, pattern.getCsid());
+    String csid;
+    String nextId;
+    String serializedGenerator;
+    BaseIDGenerator generator;
     
-  }
+    IDServiceJdbcImpl jdbc = new IDServiceJdbcImpl();
+    IDService service = jdbc;
+    
+    final static String TABLE_NAME = "id_generators";
+    final static String DEFAULT_CSID = "TEST-1";
+
+    @Test
+    public void hasRequiredDatabaseTable() {
+        Assert.assertTrue(
+            jdbc.hasTable(TABLE_NAME), 
+            "Table '" + TABLE_NAME + "' must exist in database. " + 
+            "Please first run SQL setup script, " +
+            "'create_id_generators_table.sql', in 'id' project.");
+    }
 
-  @Test(dependsOnMethods = {"addIDGenerator"})
-  public void updateIDGenerator() {
+    @Test(dependsOnMethods = {"hasRequiredDatabaseTable"})
+    public void addIDGenerator() {
+        jdbc.addIDGenerator(DEFAULT_CSID, getSpectrumEntryNumberGenerator());
+    }
 
-    final String NEW_DESCRIPTION = "new description";
-    
-    // Retrieve an existing generator, deserialize it,
-    // update its contents, serialize it, and write it back.
-    serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID);
-    pattern = IDGeneratorSerializer.deserialize(serializedGenerator);
-    pattern.setDescription(NEW_DESCRIPTION);
-    serializedGenerator = IDGeneratorSerializer.serialize(pattern);
-    
-    jdbc.updateIDGenerator(DEFAULT_CSID, serializedGenerator);
-    
-    serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID);
-    pattern = IDGeneratorSerializer.deserialize(serializedGenerator);
-    
-    Assert.assertEquals(NEW_DESCRIPTION, pattern.getDescription());
-    
-  }
+    @Test(dependsOnMethods = {"addIDGenerator"})
+    public void readIDGenerator() {
 
-  @Test(dependsOnMethods = {"addIDGenerator", "readIDGenerator"})
-  public void deleteIDGenerator() {
-    jdbc.deleteIDGenerator(DEFAULT_CSID);
-  }
-  @Test(dependsOnMethods = {"addIDGenerator", "deleteIDGenerator"})
-       public void newIDValidPattern() {
-       
-    csid = DEFAULT_CSID;
-    
-    try {
-      jdbc.deleteIDGenerator(csid);
-    } catch (Exception e) {
-      // do nothing
+        serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID);
+        generator = IDGeneratorSerializer.deserialize(serializedGenerator);
+        Assert.assertEquals(DEFAULT_CSID, generator.getCsid());
+        
     }
-    
-    jdbc.addIDGenerator(csid, getSpectrumEntryNumberGenerator());
 
-    Assert.assertEquals("E1", service.newID("TEST-1"));
-    Assert.assertEquals("E2", service.newID("TEST-1"));
-    Assert.assertEquals("E3", service.newID("TEST-1"));
-    
-    try {
-      jdbc.deleteIDGenerator(csid);
-    } catch (Exception e) {
-      // do nothing
+    @Test(dependsOnMethods = {"addIDGenerator"})
+    public void updateIDGenerator() {
+
+        final String NEW_DESCRIPTION = "new description";
+        
+        // Retrieve an existing generator, deserialize it,
+        // update its contents, serialize it, and write it back.
+        serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID);
+        generator = IDGeneratorSerializer.deserialize(serializedGenerator);
+        generator.setDescription(NEW_DESCRIPTION);
+        serializedGenerator = IDGeneratorSerializer.serialize(generator);
+        
+        jdbc.updateIDGenerator(DEFAULT_CSID, serializedGenerator);
+        
+        serializedGenerator = jdbc.getIDGenerator(DEFAULT_CSID);
+        generator = IDGeneratorSerializer.deserialize(serializedGenerator);
+        
+        Assert.assertEquals(NEW_DESCRIPTION, generator.getDescription());
+        
     }
-    
-    jdbc.addIDGenerator(csid, getChinAccessionNumberGenerator());
 
-    String currentYear = YearIDGenerator.getCurrentYear();
-    Assert.assertEquals(currentYear + ".1.1", service.newID("TEST-1"));
-    Assert.assertEquals(currentYear + ".1.2", service.newID("TEST-1"));
-    Assert.assertEquals(currentYear + ".1.3", service.newID("TEST-1"));
+    @Test(dependsOnMethods = {"addIDGenerator", "readIDGenerator"})
+    public void deleteIDGenerator() {
+        jdbc.deleteIDGenerator(DEFAULT_CSID);
+    }
+    @Test(dependsOnMethods = {"addIDGenerator", "deleteIDGenerator"})
+        public void newIDValidPattern() {
+        
+        csid = DEFAULT_CSID;
+        
+        try {
+            jdbc.deleteIDGenerator(csid);
+        } catch (Exception e) {
+            // do nothing
+        }
+        
+        jdbc.addIDGenerator(csid, getSpectrumEntryNumberGenerator());
+
+        Assert.assertEquals("E1", service.newID(csid));
+        Assert.assertEquals("E2", service.newID(csid));
+        Assert.assertEquals("E3", service.newID(csid));
+        
+        try {
+            jdbc.deleteIDGenerator(csid);
+        } catch (Exception e) {
+            // do nothing
+        }
+        
+        jdbc.addIDGenerator(csid, getChinAccessionNumberGenerator());
+
+        String currentYear = YearIDGeneratorPart.getCurrentYear();
+        Assert.assertEquals(currentYear + ".1.1", service.newID(csid));
+        Assert.assertEquals(currentYear + ".1.2", service.newID(csid));
+        Assert.assertEquals(currentYear + ".1.3", service.newID(csid));
+
+        try {
+            jdbc.deleteIDGenerator(csid);
+        } catch (Exception e) {
+            // do nothing
+        }
 
-    try {
-      jdbc.deleteIDGenerator(csid);
-    } catch (Exception e) {
-      // do nothing
     }
-    
-       }
-
-  // This test requires that:
-  // 1. The ID Service is running and accessible to this test; and
-  // 2. There is no ID pattern retrievable through that service
-  //    with the identifier 'non-existent identifier'.
-  @Test(dependsOnMethods = {"hasRequiredDatabaseTable"}, 
-    expectedExceptions = IllegalArgumentException.class)
-       public void newIDInvalidPattern() {
-    nextId = service.newID("non-existent identifier");         
-       }
-
-  // ---------------------------------------------------------------
-  // Utility methods used by tests above
-  // ---------------------------------------------------------------
-
-  // @TODO Read test patterns from external configuration.
-  
-  public String getSpectrumEntryNumberGenerator() {
-    
-    pattern = new IDPattern(DEFAULT_CSID);
-    pattern.setDescription("SPECTRUM entry number pattern");
-    pattern.setURI("urn:collectionspace:idpattern:spectrum-entry-number");
-    pattern.add(new StringIDPart("E"));
-    pattern.add(new NumericIDPart("1"));
-    
-    return IDGeneratorSerializer.serialize(pattern);
-    
-  }
 
-  public String getChinAccessionNumberGenerator() {
+    // This test requires that:
+    // 1. The ID Service is running and accessible to this test; and
+    // 2. There is no ID generator retrievable through that service
+    //        with the identifier 'non-existent identifier'.
+    @Test(dependsOnMethods = {"hasRequiredDatabaseTable"}, 
+        expectedExceptions = IllegalArgumentException.class)
+    public void newIDInvalidPattern() {
+        nextId = service.newID("non-existent identifier");                
+    }
 
-    pattern = new IDPattern(DEFAULT_CSID);
-    pattern.setDescription("CHIN accession number pattern, for items without parts");
-    pattern.setURI("urn:collectionspace:idpattern:chin-accession-number-no-parts");
-    pattern.add(new YearIDPart());
-    pattern.add(new StringIDPart("."));
-    pattern.add(new NumericIDPart("1"));
-    pattern.add(new StringIDPart("."));
-    pattern.add(new NumericIDPart("1"));    
+    // ---------------------------------------------------------------
+    // Utility methods used by tests above
+    // ---------------------------------------------------------------
 
-    return IDGeneratorSerializer.serialize(pattern);
+    // @TODO Read test patterns from external configuration.
     
-  }
+    public String getSpectrumEntryNumberGenerator() {
+        
+        generator = new BaseIDGenerator(DEFAULT_CSID);
+        generator.setDescription(
+            "SPECTRUM entry number generator");
+        generator.setURI(
+            "urn:collectionspace:idpattern:spectrum-entry-number");
+        generator.add(new StringIDGeneratorPart("E"));
+        generator.add(new NumericIDGeneratorPart("1"));
+        
+        return IDGeneratorSerializer.serialize(generator);
+        
+    }
+
+    public String getChinAccessionNumberGenerator() {
+
+        generator = new BaseIDGenerator(DEFAULT_CSID);
+        generator.setDescription(
+            "CHIN accession number generator, for items without parts");
+        generator.setURI(
+            "urn:collectionspace:idpattern:chin-accession-number-no-parts");
+        generator.add(new YearIDGeneratorPart());
+        generator.add(new StringIDGeneratorPart("."));
+        generator.add(new NumericIDGeneratorPart("1"));
+        generator.add(new StringIDGeneratorPart("."));
+        generator.add(new NumericIDGeneratorPart("1"));        
+
+        return IDGeneratorSerializer.serialize(generator);
+        
+    }
 
 }
diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/NumericIDGeneratorPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/NumericIDGeneratorPartTest.java
new file mode 100644 (file)
index 0000000..9ecb44c
--- /dev/null
@@ -0,0 +1,196 @@
+/*    
+ * NumericIDGeneratorPartTest
+ *
+ * Test class for NumericIDGeneratorPart.
+ *
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+ *
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+ *
+ * Copyright © 2009 Regents of the University of California
+ *
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+ *
+ * You may obtain a copy of the ECL 2.0 License at
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+
+package org.collectionspace.services.id;
+
+import static org.junit.Assert.fail;
+import junit.framework.TestCase;
+
+/**
+ * NumericIDGeneratorPartTest
+ *
+ * Test class for NumericIDGeneratorPart.
+ *
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
+public class NumericIDGeneratorPartTest extends TestCase {
+
+    IDGeneratorPart part;
+
+    public void testNextID() {
+
+        part = new NumericIDGeneratorPart("0");        
+        assertEquals("1", part.nextID());
+        assertEquals("2", part.nextID());
+        assertEquals("3", part.nextID());
+    
+        part = new NumericIDGeneratorPart("25");
+        assertEquals("26", part.nextID());
+        assertEquals("27", part.nextID());
+        assertEquals("28", part.nextID());
+        
+        part = new NumericIDGeneratorPart();
+        assertEquals("2", part.nextID());
+            
+    }
+
+    public void testNextIDOverflow() {
+
+        try {
+            part = new NumericIDGeneratorPart("997", "3");        
+            assertEquals("998", part.nextID());
+            assertEquals("999", part.nextID());
+            assertEquals("1000", part.nextID());
+            fail("Should have thrown IllegalStateException here");
+        } catch (IllegalStateException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+
+        // Tests default MAX_LENGTH value of 6 decimal places
+        try {
+            part = new NumericIDGeneratorPart("999997");        
+            assertEquals("999998", part.nextID());
+            assertEquals("999999", part.nextID());
+            assertEquals("1000000", part.nextID());
+            fail("Should have thrown IllegalStateException here");
+        } catch (IllegalStateException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+            
+    }
+
+    public void testResetID() {
+    
+        part = new NumericIDGeneratorPart("25");
+        assertEquals("26", part.nextID());
+        assertEquals("27", part.nextID());
+        assertEquals("28", part.nextID());
+        part.resetID();
+        assertEquals("26", part.nextID());
+            
+    }
+
+    public void testInitialID() {
+
+        part = new NumericIDGeneratorPart("0");
+        assertEquals("0", part.getInitialID());
+
+        part = new NumericIDGeneratorPart("25");
+        assertEquals("25", part.getInitialID());
+        
+    }
+
+    public void testCurrentID() {
+
+        part = new NumericIDGeneratorPart("0");
+        assertEquals("0", part.getCurrentID());
+        assertEquals("1", part.nextID());
+        assertEquals("2", part.nextID());
+        assertEquals("2", part.getCurrentID());
+        assertEquals("3", part.nextID());
+
+        part = new NumericIDGeneratorPart("25");
+        assertEquals("25", part.getCurrentID());
+        
+    }
+    
+    public void testNullInitialValue() {
+    
+        try {
+            part = new NumericIDGeneratorPart(null);
+            fail("Should have thrown IllegalArgumentException here");
+        } catch (IllegalArgumentException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+        
+    }
+
+    public void testNonLongParseableInitialValue() {
+    
+        try {
+            part = new NumericIDGeneratorPart("not a long parseable value");
+            fail("Should have thrown IllegalArgumentException here");
+        } catch (IllegalArgumentException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+
+    }
+
+    public void testNonLongParseableMaxLength() {
+    
+        try {
+            part = new NumericIDGeneratorPart("1", "not an int parseable value");
+            fail("Should have thrown IllegalArgumentException here");
+        } catch (IllegalArgumentException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+
+    }
+
+    public void testNegativeInitialValue() {
+
+        try {
+            part = new NumericIDGeneratorPart("-1");
+            fail("Should have thrown IllegalArgumentException here");
+        } catch (IllegalArgumentException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+    }
+
+
+    public void testIsValidID() {
+    
+        part = new NumericIDGeneratorPart("1");
+        assertTrue(part.isValidID("1"));
+
+        part = new NumericIDGeneratorPart("1");
+        assertTrue(part.isValidID("123"));
+
+        part = new NumericIDGeneratorPart("1");
+        assertTrue(part.isValidID("123456"));
+
+        part = new NumericIDGeneratorPart("1");
+        assertFalse(part.isValidID("1234567"));
+        
+        part = new NumericIDGeneratorPart("1", "3");
+        assertTrue(part.isValidID("123"));
+        
+        part = new NumericIDGeneratorPart("1", "3");
+        assertFalse(part.isValidID("1234"));
+
+        part = new NumericIDGeneratorPart("1");
+        assertFalse(part.isValidID("not a parseable long"));
+
+        part = new NumericIDGeneratorPart("1", "3");
+        assertFalse(part.isValidID("not a parseable long"));
+
+        part = new NumericIDGeneratorPart("1", "3");
+        assertFalse(part.isValidID(null));
+
+        part = new NumericIDGeneratorPart("1", "3");
+        assertFalse(part.isValidID(""));
+    
+    }    
+    
+    // @TODO: Add more tests of boundary conditions, exceptions ...
+}
similarity index 69%
rename from services/id/service/src/test/java/org/collectionspace/services/id/StringIDPartTest.java
rename to services/id/service/src/test/java/org/collectionspace/services/id/test/StringIDGeneratorPartTest.java
index 6b26571cd613cfe389b8e1acfd955c4c14f4dfaf..41eae683221cecd6f740e8651231a6218377cd03 100644 (file)
@@ -1,8 +1,4 @@
-/*     
- * StringIDPartTest
- *
- * Test class for StringIDPart.
- *
+/**
  * This document is a part of the source code and related artifacts
  * for CollectionSpace, an open source collections management system
  * for museums and related institutions:
  *
  * You may obtain a copy of the ECL 2.0 License at
  * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * $LastChangedBy$
- * $LastChangedRevision$
- * $LastChangedDate$
  */
 
 package org.collectionspace.services.id;
@@ -28,23 +20,31 @@ package org.collectionspace.services.id;
 import static org.junit.Assert.fail;
 import junit.framework.TestCase;
 
-public class StringIDPartTest extends TestCase {
+/**    
+ * StringIDGeneratorPartTest
+ *
+ * Test class for StringIDGeneratorPart.
+ *
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
+public class StringIDGeneratorPartTest extends TestCase {
 
-       IDPart part;
+       IDGeneratorPart part;
 
        public void testNextID() {
 
-               part = new StringIDPart("E");           
+               part = new StringIDGeneratorPart("E");          
                assertEquals("E", part.nextID());       
                
-               part = new StringIDPart("XYZ");         
+               part = new StringIDGeneratorPart("XYZ");                
                assertEquals("XYZ", part.nextID());             
                
        }
 
        public void testresetID() {
        
-               part = new StringIDPart(".");
+               part = new StringIDGeneratorPart(".");
                assertEquals(".", part.nextID());
                part.resetID();
                assertEquals(".", part.nextID());
@@ -52,19 +52,19 @@ public class StringIDPartTest extends TestCase {
        }
 
        public void testInitialID() {
-               part = new StringIDPart("-");
+               part = new StringIDGeneratorPart("-");
                assertEquals("-", part.getInitialID());
        }
 
        public void testCurrentID() {
-               part = new StringIDPart("- -");
+               part = new StringIDGeneratorPart("- -");
                assertEquals("- -", part.getCurrentID());
        }
        
        public void testNullInitialValue() {
        
                try {
-                       part = new StringIDPart(null);
+                       part = new StringIDGeneratorPart(null);
                        fail("Should have thrown IllegalArgumentException here");
                } catch (IllegalArgumentException expected) {
                        // This Exception should be thrown, and thus the test should pass.
@@ -75,7 +75,7 @@ public class StringIDPartTest extends TestCase {
        public void testEmptyInitialValue() {
        
                try {
-                       part = new StringIDPart("");
+                       part = new StringIDGeneratorPart("");
                        fail("Should have thrown IllegalArgumentException here");
                } catch (IllegalArgumentException expected) {
                        // This Exception should be thrown, and thus the test should pass.
@@ -85,30 +85,30 @@ public class StringIDPartTest extends TestCase {
 
        public void testIsValidID() {
        
-               part = new StringIDPart("-");
+               part = new StringIDGeneratorPart("-");
                assertTrue(part.isValidID("-"));
 
-               part = new StringIDPart("-");
+               part = new StringIDGeneratorPart("-");
                assertFalse(part.isValidID("--"));
 
                // Test chars with special meaning in regexes.
-               part = new StringIDPart(".");
+               part = new StringIDGeneratorPart(".");
                assertTrue(part.isValidID("."));
 
-               part = new StringIDPart("TE");
+               part = new StringIDGeneratorPart("TE");
                assertTrue(part.isValidID("TE"));
 
-               part = new StringIDPart("TE");
+               part = new StringIDGeneratorPart("TE");
                assertFalse(part.isValidID("T"));
 
-               part = new StringIDPart("T");
+               part = new StringIDGeneratorPart("T");
                assertFalse(part.isValidID("TE"));
 
-    part = new StringIDPart("-");
-    assertFalse(part.isValidID(null));
-
-    part = new StringIDPart("-");
-    assertFalse(part.isValidID(""));
+        part = new StringIDGeneratorPart("-");
+        assertFalse(part.isValidID(null));
+        
+        part = new StringIDGeneratorPart("-");
+        assertFalse(part.isValidID(""));
        
        }       
 
diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/YearIDGeneratorPartTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/YearIDGeneratorPartTest.java
new file mode 100644 (file)
index 0000000..37a0495
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+ *
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+ *
+ * Copyright © 2009 Regents of the University of California
+ *
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+ *
+ * You may obtain a copy of the ECL 2.0 License at
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+
+package org.collectionspace.services.id;
+
+import static org.junit.Assert.fail;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import junit.framework.TestCase;
+
+/*    
+ * YearIDGeneratorPartTest
+ *
+ * Test class for YearIDGeneratorPart.
+ *
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ */
+public class YearIDGeneratorPartTest extends TestCase {
+
+    IDGeneratorPart part;
+    final static String year = "1999";
+
+    public String getCurrentYear() {
+        Calendar cal = GregorianCalendar.getInstance();
+        int y = cal.get(Calendar.YEAR);
+        return Integer.toString(y);
+    }
+
+    public void testCurrentID() {
+
+        part = new YearIDGeneratorPart();
+        assertEquals(getCurrentYear(), part.getCurrentID());
+
+        part = new YearIDGeneratorPart(year);
+        assertEquals(year, part.getCurrentID());
+
+    }
+
+    public void testSetCurrentID() {
+
+        part = new YearIDGeneratorPart("1999");
+        part.setCurrentID("1999");
+        assertEquals("1999", part.getCurrentID());
+        part.setCurrentID("2000");
+        assertEquals("2000", part.getCurrentID());
+
+    }
+
+    public void testSetCurrentIDNullOrEmpty() {
+
+        part = new YearIDGeneratorPart();
+
+        try {
+          part.setCurrentID(null);
+            fail("Should have thrown IllegalArgumentException here");
+        } catch (IllegalArgumentException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+
+        try {
+          part.setCurrentID("");
+            fail("Should have thrown IllegalArgumentException here");
+        } catch (IllegalArgumentException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+
+  }
+    
+    public void testNextID() {
+    
+        part = new YearIDGeneratorPart("1999");        
+        assertEquals("1999", part.nextID());        
+        
+    }
+
+    public void testresetID() {
+    
+        part = new YearIDGeneratorPart("1999");
+        assertEquals("1999", part.nextID());
+        part.resetID();
+        assertEquals("1999", part.getCurrentID());
+            
+    }
+
+    public void testInitialID() {
+    
+        part = new YearIDGeneratorPart("1999");
+        assertEquals("1999", part.getInitialID());
+        
+    }
+
+
+    public void testNullInitialValue() {
+    
+        try {
+            part = new YearIDGeneratorPart(null);
+            fail("Should have thrown IllegalArgumentException here");
+        } catch (IllegalArgumentException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+        
+    }
+
+    public void testEmptyInitialValue() {
+    
+        try {
+            part = new YearIDGeneratorPart("");
+            fail("Should have thrown IllegalArgumentException here");
+        } catch (IllegalArgumentException expected) {
+            // This Exception should be thrown, and thus the test should pass.
+        }
+
+    }
+
+    public void testIsValidID() {
+    
+        part = new YearIDGeneratorPart();
+        assertTrue(part.isValidID("2009"));
+
+        part = new YearIDGeneratorPart();
+        assertFalse(part.isValidID("839"));
+
+        part = new YearIDGeneratorPart();
+        assertFalse(part.isValidID("10100"));
+        
+        part = new YearIDGeneratorPart();
+        assertFalse(part.isValidID("non-numeric value"));
+
+        part = new YearIDGeneratorPart();
+        assertFalse(part.isValidID(null));
+        
+        part = new YearIDGeneratorPart();
+        assertFalse(part.isValidID(""));
+
+    }
+
+    // @TODO: Add more tests of boundary conditions, exceptions ...
+}