]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-234: Fixed broken Gregorian date ID Part test; modified log level for reportin...
authorAron Roberts <aron@socrates.berkeley.edu>
Tue, 1 Dec 2009 21:25:30 +0000 (21:25 +0000)
committerAron Roberts <aron@socrates.berkeley.edu>
Tue, 1 Dec 2009 21:25:30 +0000 (21:25 +0000)
services/id/service/src/main/java/org/collectionspace/services/id/part/AlphabeticSequenceIDPart.java
services/id/service/src/main/java/org/collectionspace/services/id/part/JavaRandomNumberIDPartAlgorithm.java
services/id/service/src/test/java/org/collectionspace/services/id/part/test/GregorianDateIDPartTest.java
services/id/service/src/test/java/org/collectionspace/services/id/part/test/RandomNumberIDPartTest.java

index 6974535d4341fff9031074e05e95ecb972285128..8a10cc96eb1976c1873e2b1b1b72bb82482bc252 100644 (file)
@@ -1,19 +1,38 @@
 package org.collectionspace.services.id.part;
 
-// @TODO Largely unimplemented at present.
-// Corresponding test class has not yet been created.
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+
+// @TODO Largely unimplemented at present.  Much code is non-working.
 
 public class AlphabeticSequenceIDPart extends SequenceIDPart {
 
+    private IDPartOutputFormatter formatter = new NoOpIDPartOutputFormatter();
+    private IDPartValidator validator = new NoOpIDPartValidator();
+
     // @TODO Externalize character sequences to their own class.
     private AlphabeticSequenceIDPart.AlphabeticCharSequence charsInSequence;
-    private IDPartOutputFormatter formatter;
-    private IDPartValidator validator;
-    private char initialValue;
+
+    LinkedHashSet<Character> alphabeticSequence = new LinkedHashSet<Character>();
+    private ArrayList<Character> initialValue = new ArrayList<Character>();
+    private ArrayList<Character> currentValue = new ArrayList<Character>();
+
+    private static final char NULL_CHAR = '\u0000';
+
+    private char startChar = NULL_CHAR;
+    private char endChar = NULL_CHAR;
 
     public AlphabeticSequenceIDPart () {
     }
 
+    public AlphabeticSequenceIDPart(LinkedHashSet<Character> sequence) {
+        this.alphabeticSequence = sequence;
+        Character[] chars = (Character[]) alphabeticSequence.toArray();
+        this.startChar = chars[0].charValue();
+        // initialValue.add(new Character(start.char));
+        this.endChar = chars[chars.length - 1].charValue();
+    }
+
     @Override
     public IDPartOutputFormatter getOutputFormatter () {
         return formatter;
@@ -50,15 +69,57 @@ public class AlphabeticSequenceIDPart extends SequenceIDPart {
 
     @Override
     public String nextID() {
-        throw new UnsupportedOperationException("Not supported yet.");
+
+        // 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 toIDString(this.currentValue);
+
     }
 
     public char getInitialValue () {
-        return initialValue;
+        throw new UnsupportedOperationException("Not supported yet.");
     }
 
     public void setInitialValue (char val) {
-        this.initialValue = val;
+        throw new UnsupportedOperationException("Not supported yet.");
     }
 
     public AlphabeticSequenceIDPart.AlphabeticCharSequence getCharsInSequence () {
@@ -74,5 +135,12 @@ public class AlphabeticSequenceIDPart extends SequenceIDPart {
         ;
     }
 
+    public String toIDString(ArrayList<Character> characters) {
+        StringBuffer sb = new StringBuffer();
+        for ( Character ch : characters ) {
+            sb.append(ch.toString());
+        }
+        return sb.toString();
+    }
 }
 
index cd72ec135c27f168b7ea7cefd9b6f418858df493..7f1112f88a2eb6e79a560f74619b9665111e0bec 100644 (file)
@@ -32,7 +32,7 @@ public class JavaRandomNumberIDPartAlgorithm implements IDPartAlgorithm {
     // other invocation of this constructor."
     private static Random r = new Random();
 
-    public final static int DEFAULT_MAX_VALUE = Integer.MAX_VALUE - 1;
+    public final static int DEFAULT_MAX_VALUE = Integer.MAX_VALUE - 2;
     public final static int DEFAULT_MIN_VALUE = 0;
 
     private int maxValue = DEFAULT_MAX_VALUE;
@@ -57,14 +57,17 @@ public class JavaRandomNumberIDPartAlgorithm implements IDPartAlgorithm {
     }
 
     private void setMaxValue(int maxVal) {
-        if (0 < maxVal && maxVal < DEFAULT_MAX_VALUE) {
+        if (0 < maxVal && maxVal <= DEFAULT_MAX_VALUE) {
             this.maxValue = maxVal;
         } else {
             String msg =
-                "Invalid maximum value for random number. " +
+                "Invalid maximum value '" +
+                Integer.toString(maxVal) +
+                "' for random number. " +
                 "Must be between 1 and " +
-                Integer.toString(DEFAULT_MAX_VALUE - 1) + ".";
-            logger.error(msg);
+                Integer.toString(DEFAULT_MAX_VALUE) +
+                ", inclusive.";
+            logger.info(msg);
             throw new IllegalArgumentException(msg);
         }
     }
@@ -74,10 +77,14 @@ public class JavaRandomNumberIDPartAlgorithm implements IDPartAlgorithm {
             this.minValue = minVal;
         } else {
             String msg =
-                "Invalid minimum value for random number. " +
+                "Invalid minimum value '" +
+                Integer.toString(minVal) +
+                "' for random number. " +
                 "Must be between 0 and " +
-                Integer.toString(this.maxValue - 1) + ".";
-            logger.error(msg);
+                Integer.toString(this.maxValue - 1) + 
+                ", inclusive (i.e. less than the supplied maximum value " +
+                "of " + Integer.toString(this.maxValue) + ").";
+            logger.info(msg);
             throw new IllegalArgumentException(msg);
         }
     }
@@ -85,11 +92,18 @@ public class JavaRandomNumberIDPartAlgorithm implements IDPartAlgorithm {
     @Override
     public String generateID(){
         // Returns an evenly distributed random value between 0
-        // and the maximum value.
+        // and the maximum value.  An even distribution decreases
+        // randomness but is more likely to meet end user requirements
+        // and expectations.
+        //
         // See http://mindprod.com/jgloss/pseudorandom.html
         //
         // Note: Random.nextInt() returns a pseudorandom number
         // between 0 and n-1 inclusive, not a number between 0 and n.
+
+        // @TODO Consider adding code to ensure the uniqueness of
+        // each generated pseudorandom number, until all possible
+        // values within the inclusive set have been generated.
         return
             Integer.toString(r.nextInt(
             this.maxValue - this.minValue + 1) + this.minValue);
index 9f1f4053355046ba809c02162fa7bea06535080a..f341b0e1836e827478704cdb08a11b33139715b0 100644 (file)
@@ -2,6 +2,12 @@ package org.collectionspace.services.id.part.test;
 
 import org.collectionspace.services.id.part.GregorianDateIDPart;
 
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -15,24 +21,27 @@ public class GregorianDateIDPartTest {
 
     GregorianDateIDPart part;
 
+    final static String MONTH_FULL_NAME_PATTERN = "MMMM";
+    final static String FRENCH_LANGUAGE_ISO_CODE = "fr";
+    final static Locale FRENCH_LANGUAGE_LOCALE =
+        new Locale(FRENCH_LANGUAGE_ISO_CODE, "");
+
     @Test
     public void newID() {
-
-        // @TODO Replace these hard-coded expedients, which will all fail
-        // when the current month or year doesn't match these asserted values.
         
         part = new GregorianDateIDPart("yyyy");
-        Assert.assertEquals(part.newID(), "2009");
+        Assert.assertEquals(part.newID(), currentYearAsString());
 
         part = new GregorianDateIDPart("M");
-        Assert.assertEquals(part.newID(), "11");
+        Assert.assertEquals(part.newID(), currentMonthNumberAsString());
 
-        part = new GregorianDateIDPart("MMMM");
-        Assert.assertEquals(part.newID(), "November");
+        part = new GregorianDateIDPart(MONTH_FULL_NAME_PATTERN);
+        Assert.assertEquals(part.newID(), currentMonthFullName());
 
-        part = new GregorianDateIDPart("MMMM", "fr");
-        // Month names are not capitalized in French.
-        Assert.assertEquals(part.newID(), "novembre");
+        part = new GregorianDateIDPart(MONTH_FULL_NAME_PATTERN,
+            FRENCH_LANGUAGE_ISO_CODE);
+        Assert.assertEquals(part.newID(),
+                currentMonthFullNameLocalized(FRENCH_LANGUAGE_LOCALE));
         
     }
 
@@ -47,4 +56,27 @@ public class GregorianDateIDPartTest {
         Assert.assertTrue(part.getValidator().isValid(part.newID()));
     }
 
+    public String currentYearAsString() {
+        int y = GregorianCalendar.getInstance().get(Calendar.YEAR);
+        return Integer.toString(y);
+    }
+
+    public String currentMonthNumberAsString() {
+        // Calendar.MONTH numbers begin with 0; hence the need to add 1.
+        int m = GregorianCalendar.getInstance().get(Calendar.MONTH) + 1;
+        return Integer.toString(m);
+    }
+
+    public String currentMonthFullName() {
+        SimpleDateFormat df =
+            new SimpleDateFormat(MONTH_FULL_NAME_PATTERN,
+                Locale.getDefault());
+        return df.format(GregorianCalendar.getInstance().getTime());
+    }
+
+    public String currentMonthFullNameLocalized(Locale locale) {
+        SimpleDateFormat df =
+            new SimpleDateFormat(MONTH_FULL_NAME_PATTERN, locale);
+        return df.format(GregorianCalendar.getInstance().getTime());
+    }
 }
index bfb3f204b47adbca5f1e8e4a8e5f69440046f313..3349b9ecb8470995bfb0ca86618f7dabc2c0ce27 100644 (file)
@@ -86,16 +86,32 @@ public class RandomNumberIDPartTest {
         }
     }
 
-    @Test(expectedExceptions = IllegalArgumentException.class)
-    public void minValueTooLow() {
-        int minValue = -1;
+    @Test
+    public void defaultMaxValue() {
+        part = new RandomNumberIDPart(
+            JavaRandomNumberIDPartAlgorithm.DEFAULT_MAX_VALUE);
+        part.newID();
+    }
+
+     @Test(dependsOnMethods = {"defaultMaxValue"})
+    public void defaultMinValue() {
         part = new RandomNumberIDPart(
-            JavaRandomNumberIDPartAlgorithm.DEFAULT_MAX_VALUE, minValue);
+            JavaRandomNumberIDPartAlgorithm.DEFAULT_MAX_VALUE,
+            JavaRandomNumberIDPartAlgorithm.DEFAULT_MIN_VALUE);
+        part.newID();
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class)
     public void maxValueTooHigh() {
-        part = new RandomNumberIDPart(Integer.MAX_VALUE);
+        int maxValue = Integer.MAX_VALUE; // Value too high
+        part = new RandomNumberIDPart(maxValue);
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void minValueTooLow() {
+        int maxValue = 10;
+        int minValue = -1; // Value too low
+        part = new RandomNumberIDPart(maxValue, minValue);
     }
 
     @Test