From 30fafc72b286425df0d7c4d565eccc9dc61f9d47 Mon Sep 17 00:00:00 2001 From: Aron Roberts Date: Tue, 23 Jun 2009 00:27:38 +0000 Subject: [PATCH] NOJIRA Implemented a simple getNextID() method for IDPatterns. --- .../services/id/AlphabeticIDGenerator.java | 10 +++- .../collectionspace/services/id/IDPart.java | 2 +- .../services/id/IDPattern.java | 6 ++ .../services/id/StringIDGenerator.java | 8 +-- .../services/id/YearIDGenerator.java | 34 +++++++---- .../services/id/IDPatternTest.java | 56 +++++++++++++++++-- 6 files changed, 91 insertions(+), 25 deletions(-) diff --git a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java index ab22083ba..8fbea616d 100644 --- a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java +++ b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/AlphabeticIDGenerator.java @@ -33,11 +33,19 @@ // generated IDs can grow, likely as an additional parameter to be // passed to a constructor, with a default value hard-coded in the class. -// @TODO: Handle escaped character sequences representing Unicode code points, +// @TODO: Handle 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: This class currently hard-codes the assumption that the values in // alphabetic identifiers are ordered in significance from left-to-right; diff --git a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDPart.java b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDPart.java index 32bcb7511..41c7d309e 100644 --- a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDPart.java +++ b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDPart.java @@ -36,7 +36,7 @@ public abstract class IDPart { protected IDGenerator generator; // Constructor - public IDPart(IDGenerator idGenerator) { + public IDPart(IDGenerator idGenerator) throws IllegalArgumentException { this.generator = idGenerator; } diff --git a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDPattern.java b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDPattern.java index e94df2786..c220d7cfe 100644 --- a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDPattern.java +++ b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/IDPattern.java @@ -57,6 +57,12 @@ public class IDPattern { // Returns the next value of this ID. public synchronized String getNextID() { StringBuffer sb = new StringBuffer(MAX_ID_LENGTH); + // Obtain the last (least significant) IDPart, + // call its getNextID() method, and + int last = this.parts.size() - 1; + this.parts.get(last).getNextID(); + // lastPart.getNextID(); + // this.parts.set(last, lastPart); for (IDPart part : this.parts) { sb.append(part.getCurrentID()); } diff --git a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/StringIDGenerator.java b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/StringIDGenerator.java index d9e548449..42f16ce82 100644 --- a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/StringIDGenerator.java +++ b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/StringIDGenerator.java @@ -29,12 +29,8 @@ public class StringIDGenerator implements IDGenerator { public StringIDGenerator(String initialValue) throws IllegalArgumentException { - if ( initialValue == null ) { - throw new IllegalArgumentException("Initial value must not be null"); - } - - if ( initialValue == "" ) { - throw new IllegalArgumentException("Initial value must not be empty"); + if ( initialValue == null || initialValue == "") { + throw new IllegalArgumentException("Initial value must not be null or empty"); } this.initialValue = initialValue; diff --git a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/YearIDGenerator.java b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/YearIDGenerator.java index b8c41f930..bf3c93126 100644 --- a/sandbox/aron/id/src/main/java/org/collectionspace/services/id/YearIDGenerator.java +++ b/sandbox/aron/id/src/main/java/org/collectionspace/services/id/YearIDGenerator.java @@ -19,7 +19,22 @@ // @TODO: Add Javadoc comments -// @TODO: Need to understand and reflect time zone issues. +// @TODO: Need to understand and reflect time zone issues; +// what happens when a year rollover occurs: +// - In the time zone of the end user. +// - In the time zone of the museum or other institution. +// - In the time zone of the physical server where the code is hosted. + +// NOTE: This class currently hard-codes the assumption that the +// Gregorian Calendar system is in use. +// +// We may wish to use the Joda-Time framework if handling of +// additional calendar systems is needed, or additional treatment +// of time zones is warranted: +// http://joda-time.sourceforge.net/ +// +// There may also be a need to have a structured set of date-time +// classes related to identifier generation. package org.collectionspace.services.id; @@ -41,16 +56,13 @@ public class YearIDGenerator implements IDGenerator { public YearIDGenerator(String initialValue) throws IllegalArgumentException { - if ( initialValue == null ) { - throw new IllegalArgumentException("Initial value must not be null"); - } - - if ( initialValue == "" ) { - throw new IllegalArgumentException("Initial value must not be empty"); + if ( initialValue == null || initialValue == "") { + throw new IllegalArgumentException("Initial value must not be null or empty"); } // @TODO: Add regex-based validation here, by calling a - // to-be-added validate() method + // to-be-added validate() method. Consider implications + // for Internationalization when doing so. this.initialValue = initialValue; this.currentValue = initialValue; @@ -70,9 +82,9 @@ public class YearIDGenerator implements IDGenerator { } // @TODO: We'll need to decide what a "next" ID means in the context of: - // * An initially supplied value. - // * A year value that has not changed from its previous value. - // * A year value that has changed, as a result of a rollover + // - An initially supplied value. + // - A year value that has not changed from its previous value. + // - A year value that has changed, as a result of a rollover // to a new instant in time. public synchronized String getNextID() { return this.currentValue; diff --git a/sandbox/aron/id/src/test/java/org/collectionspace/services/id/IDPatternTest.java b/sandbox/aron/id/src/test/java/org/collectionspace/services/id/IDPatternTest.java index 07a352c5e..4d86afac9 100644 --- a/sandbox/aron/id/src/test/java/org/collectionspace/services/id/IDPatternTest.java +++ b/sandbox/aron/id/src/test/java/org/collectionspace/services/id/IDPatternTest.java @@ -27,29 +27,73 @@ public class IDPatternTest extends TestCase { IDPattern pattern; IDPart part; - public void testCurrentID() { + // 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(parts); - - assertEquals("2009.1", pattern.getCurrentID()); + assertEquals("2009.1-a", pattern.getCurrentID()); } - public void testAddCurrentID() { + public void testCurrentIDViaAdd() { + + pattern = new IDPattern(); + 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()); + + } + + public void testNextID() { + + pattern = new IDPattern(); + pattern.add(new YearIDPart("2009")); + pattern.add(new StringIDPart(".")); + pattern.add(new NumericIDPart("1")); + assertEquals("2009.2", pattern.getNextID()); + assertEquals("2009.3", pattern.getNextID()); pattern = new IDPattern(); pattern.add(new YearIDPart("2009")); pattern.add(new StringIDPart(".")); pattern.add(new NumericIDPart("1")); - - assertEquals("2009.1", pattern.getCurrentID()); + pattern.add(new StringIDPart("-")); + pattern.add(new AlphabeticIDPart("a")); + assertEquals("2009.1-b", pattern.getNextID()); + assertEquals("2009.1-c", pattern.getNextID()); + + pattern = new IDPattern(); + pattern.add(new StringIDPart("T")); + pattern.add(new NumericIDPart("1005")); + assertEquals("T1006", pattern.getNextID()); + assertEquals("T1007", pattern.getNextID()); } + public void testNextIDWithConstantStringID() { + + pattern = new IDPattern(); + pattern.add(new YearIDPart("2009")); + pattern.add(new StringIDPart(".")); + pattern.add(new NumericIDPart("1")); + pattern.add(new StringIDPart("-")); + assertEquals("2009.1-", pattern.getNextID()); + assertEquals("2009.1-", pattern.getNextID()); + + } + public void testEmptyPartsListCurrentID() { pattern = new IDPattern(); -- 2.47.3