Add Identifier generators to Lang from Util
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@137212 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
14dee9055c
commit
33113bfe79
|
@ -0,0 +1,591 @@
|
|||
/* ====================================================================
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
* Copyright (c) 2002 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution, if
|
||||
* any, must include the following acknowlegement:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowlegement may appear in the software itself,
|
||||
* if and wherever such third-party acknowlegements normally appear.
|
||||
*
|
||||
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
|
||||
* Foundation" must not be used to endorse or promote products derived
|
||||
* from this software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache"
|
||||
* nor may "Apache" appear in their names without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
package org.apache.commons.lang.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.commons.lang.functor.Factory;
|
||||
import org.apache.commons.lang.functor.FactoryException;
|
||||
/**
|
||||
* <p><code>IdentifierUtils</code> provides a number of different identifier
|
||||
* reference implementations.</p>
|
||||
*
|
||||
* <p>All the identifer factories are serializable and synchronized. The
|
||||
* factories all implement the <i>functor</i>
|
||||
* {@link org.apache.commons.lang.functor.Factory Factory} interface</p>
|
||||
*
|
||||
* @author Stephen Colebourne
|
||||
* @version $Id: IdentifierUtils.java,v 1.1 2002/12/29 21:35:04 scolebourne Exp $
|
||||
*/
|
||||
public class IdentifierUtils {
|
||||
|
||||
/**
|
||||
* <p>Singleton instance of the
|
||||
* <code>LongIdentifierFactory</code>.</p>
|
||||
*
|
||||
* <p>The singleton instance will wrap, so in a long-lived server, the id
|
||||
* may be duplicated.</p>
|
||||
*
|
||||
* <p>The objects returned are:</p>
|
||||
* <ul>
|
||||
* <li>new Long(0L)
|
||||
* <li>new Long(1L)
|
||||
* <li>new Long(2L)
|
||||
* <li>...
|
||||
* </ul>
|
||||
*/
|
||||
public static final Factory LONG_IDENTIFIER_FACTORY = new LongIdentifierFactory(true, 0L);
|
||||
/**
|
||||
* <p>Singleton instance of the <code>StringNumericIdentifierFactory</code>.
|
||||
* </p>
|
||||
*
|
||||
* <p>The singleton instance will wrap, so in a long-lived server, the id
|
||||
* may be duplicated.</p>
|
||||
*
|
||||
* <p>The objects returned are:</p>
|
||||
* <ul>
|
||||
* <li>"0"
|
||||
* <li>"1"
|
||||
* <li>"2"
|
||||
* <li>...
|
||||
* </ul>
|
||||
*/
|
||||
public static final Factory STRING_NUMERIC_IDENTIFIER_FACTORY = new StringNumericIdentifierFactory(true, 0L);
|
||||
/**
|
||||
* <p>Singleton instance of the
|
||||
* <code>StringAlphanumericIdentifierFactory</code>.</p>
|
||||
*
|
||||
* <p>The singleton instance will wrap, so in a long-lived server, the id
|
||||
* may be duplicated. However, the length is 15 in base-36, so thats a
|
||||
* lot of identifiers.</p>
|
||||
*
|
||||
* <p>The objects returned are:</p>
|
||||
* <ul>
|
||||
* <li>"000000000000001"
|
||||
* <li>"000000000000002"
|
||||
* <li>"000000000000003"
|
||||
* <li>...
|
||||
* <li>"00000000000000y"
|
||||
* <li>"00000000000000z"
|
||||
* <li>"000000000000010"
|
||||
* <li>"000000000000011"
|
||||
* <li>...
|
||||
* <li>"00000000000001z"
|
||||
* <li>"000000000000020"
|
||||
* <li>...
|
||||
* </ul>
|
||||
*/
|
||||
public static final Factory STRING_ALPHANUMERIC_IDENTIFIER_FACTORY = new StringAlphanumericIdentifierFactory(true, 15);
|
||||
/**
|
||||
* <p>Singleton instance of the
|
||||
* <code>StringSessionIdentifierFactory</code>.</p>
|
||||
*
|
||||
* <p>The singleton instance may produce duplicates in a long-lived server,
|
||||
* but its unlikely.</p>
|
||||
*
|
||||
* <p>The objects returned are 10 or more base-36 digits.</p>
|
||||
*/
|
||||
public static final Factory STRING_SESSION_IDENTIFIER_FACTORY = new StringSessionIdentifierFactory();
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <p><code>IdentifierUtils</code> instances should NOT be constructed in
|
||||
* standard programming.</p>
|
||||
*
|
||||
* <p>This constructor is public to permit tools that require a JavaBean instance
|
||||
* to operate.</p>
|
||||
*/
|
||||
public IdentifierUtils() {
|
||||
super();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <p>Gets the next identifier using the singleton instance of the
|
||||
* Long factory.
|
||||
* </p>
|
||||
*
|
||||
* <p>The singleton instance will wrap, so in a long-lived server, the id
|
||||
* may be duplicated.</p>
|
||||
*
|
||||
* @return a new identifier
|
||||
*/
|
||||
public static Long nextLongIdentifier() {
|
||||
return (Long) LONG_IDENTIFIER_FACTORY.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets a new identifier factory that returns a series of Long objects
|
||||
* increasing in size.</p>
|
||||
*
|
||||
* <p>The factory will wrap when the maximum <code>long</code> is
|
||||
* reached and return negative numbers. It will start from zero.</p>
|
||||
*
|
||||
* @return a new identifier factory
|
||||
*/
|
||||
public static Factory longIdentifierFactory() {
|
||||
return new LongIdentifierFactory(true, 0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets a new identifier factory that returns a series of Long objects
|
||||
* increasing in size.</p>
|
||||
*
|
||||
* @param wrap should the factory wrap when it reaches the maximum
|
||||
* long value (or throw an exception)
|
||||
* @param initialValue the initial long value to start at
|
||||
* @return a new identifier factory
|
||||
*/
|
||||
public static Factory longIdentifierFactory(boolean wrap, long initialValue) {
|
||||
return new LongIdentifierFactory(wrap, initialValue);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <p>Gets the next identifier using the singleton instance of the
|
||||
* String Numeric factory.
|
||||
* </p>
|
||||
*
|
||||
* <p>The singleton instance will wrap, so in a long-lived server, the id
|
||||
* may be duplicated.</p>
|
||||
*
|
||||
* @return a new identifier
|
||||
*/
|
||||
public static String nextStringNumericIdentifier() {
|
||||
return (String) STRING_NUMERIC_IDENTIFIER_FACTORY.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets a new identifier factory that returns a series of String objects
|
||||
* representing numbers increasing in size.</p>
|
||||
*
|
||||
* <p>The factory will wrap when the maximum <code>long</code> is
|
||||
* reached and return negative numbers. It will start from zero.</p>
|
||||
*
|
||||
* @return a new identifier factory
|
||||
*/
|
||||
public static Factory stringNumericIdentifierFactory() {
|
||||
return new StringNumericIdentifierFactory(true, 0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets a new identifier factory that returns a series of String objects
|
||||
* representing numbers increasing in size.</p>
|
||||
*
|
||||
* @param wrap should the factory wrap when it reaches the maximum
|
||||
* long value (or throw an exception)
|
||||
* @param initialValue the initial long value to start at
|
||||
* @return a new identifier factory
|
||||
*/
|
||||
public static Factory stringNumericIdentifierFactory(boolean wrap, long initialValue) {
|
||||
return new StringNumericIdentifierFactory(wrap, initialValue);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <p>Gets the next identifier using the singleton instance of the
|
||||
* String Alphanumeric factory.
|
||||
* </p>
|
||||
*
|
||||
* <p>The singleton instance will wrap, so in a long-lived server, the id
|
||||
* may be duplicated.</p>
|
||||
*
|
||||
* @return a new identifier
|
||||
*/
|
||||
public static String nextStringAlphanumericIdentifier() {
|
||||
return (String) STRING_ALPHANUMERIC_IDENTIFIER_FACTORY.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets a new identifier factory that returns a series of String objects
|
||||
* representing numbers increasing in size in base-36.</p>
|
||||
*
|
||||
* <p>The factory will wrap when the maximum size (15) is reached.</p>
|
||||
*
|
||||
* @return a new identifier factory
|
||||
*/
|
||||
public static Factory stringAlphanumericIdentifierFactory() {
|
||||
return new StringAlphanumericIdentifierFactory(true, 15);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets a new identifier factory that returns a series of String objects
|
||||
* representing numbers increasing in size in base-36.</p>
|
||||
*
|
||||
* @param wrap should the factory wrap when it reaches the maximum
|
||||
* size (or throw an exception)
|
||||
* @param size the number of characters the id should fill
|
||||
* @return a new identifier factory
|
||||
*/
|
||||
public static Factory stringAlphanumericIdentifierFactory(boolean wrap, int size) {
|
||||
return new StringAlphanumericIdentifierFactory(wrap, size);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <p>Gets the next identifier using the singleton instance of the
|
||||
* String Session factory.
|
||||
* </p>
|
||||
*
|
||||
* <p>The singleton instance is not guaranteed to be unique (although its
|
||||
* pretty unlikely), so in a long- lived server, the id may be duplicated.
|
||||
* </p>
|
||||
*
|
||||
* @return a new identifier
|
||||
*/
|
||||
public static String nextStringSessionIdentifier() {
|
||||
return (String) STRING_SESSION_IDENTIFIER_FACTORY.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets a new identifier factory that returns a series of String objects
|
||||
* that appear to be random and are suitable for use as session identifiers.
|
||||
* </p>
|
||||
*
|
||||
* <p>The generation routine is based on a random number and a counter
|
||||
* within a 2 second time interval.</p>
|
||||
*
|
||||
* @return a new identifier factory
|
||||
*/
|
||||
public static Factory stringSessionIdentifierFactory() {
|
||||
return new StringSessionIdentifierFactory();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <code>LongIdentifierFactory</code> is an Identifier Factory
|
||||
* that generates an incrementing number as a Long object.
|
||||
*
|
||||
* @author Stephen Colebourne
|
||||
*/
|
||||
private static class LongIdentifierFactory implements Factory, Serializable {
|
||||
|
||||
/** Should the counter wrap. */
|
||||
private final boolean wrap;
|
||||
/** The counter. */
|
||||
private long count = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param wrap should the factory wrap when it reaches the maximum
|
||||
* long value (or throw an exception)
|
||||
* @param initialValue the initial long value to start at
|
||||
*/
|
||||
private LongIdentifierFactory(boolean wrap, long initialValue) {
|
||||
super();
|
||||
this.wrap = wrap;
|
||||
this.count = initialValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new identifier.
|
||||
*
|
||||
* @return a new identifier as a Long
|
||||
*/
|
||||
public Object create() {
|
||||
long value = 0;
|
||||
if (wrap) {
|
||||
synchronized (this) {
|
||||
value = count++;
|
||||
}
|
||||
} else {
|
||||
synchronized (this) {
|
||||
if (count == Long.MAX_VALUE) {
|
||||
throw new FactoryException("The maximum number of identifiers has been reached");
|
||||
}
|
||||
value = count++;
|
||||
}
|
||||
}
|
||||
return new Long(value);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <code>StringNumericIdentifierFactory</code> is an Identifier Factory
|
||||
* that generates an incrementing number as a String object.
|
||||
*
|
||||
* @author Stephen Colebourne
|
||||
*/
|
||||
private static class StringNumericIdentifierFactory implements Factory, Serializable {
|
||||
|
||||
/** Should the counter wrap. */
|
||||
private final boolean wrap;
|
||||
/** The counter. */
|
||||
private long count = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param wrap should the factory wrap when it reaches the maximum
|
||||
* long value (or throw an exception)
|
||||
* @param initialValue the initial long value to start at
|
||||
*/
|
||||
private StringNumericIdentifierFactory(boolean wrap, long initialValue) {
|
||||
super();
|
||||
this.wrap = wrap;
|
||||
this.count = initialValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new identifier.
|
||||
*
|
||||
* @return a new identifier as a String
|
||||
*/
|
||||
public Object create() {
|
||||
long value = 0;
|
||||
if (wrap) {
|
||||
synchronized (this) {
|
||||
value = count++;
|
||||
}
|
||||
} else {
|
||||
synchronized (this) {
|
||||
if (count == Long.MAX_VALUE) {
|
||||
throw new FactoryException("The maximum number of identifiers has been reached");
|
||||
}
|
||||
value = count++;
|
||||
}
|
||||
}
|
||||
return Long.toString(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <code>StringAlphanumericIdentifierFactory</code> is an Identifier Factory
|
||||
* that generates an incrementing incrementing number in base 36 as a String
|
||||
* object.
|
||||
*
|
||||
* @author Stephen Colebourne
|
||||
*/
|
||||
private static class StringAlphanumericIdentifierFactory implements Factory, Serializable {
|
||||
|
||||
/** Should the counter wrap. */
|
||||
private final boolean wrap;
|
||||
/** The counter. */
|
||||
private char[] count = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param wrap should the factory wrap when it reaches the maximum
|
||||
* long value (or throw an exception)
|
||||
* @param size the size of the identifier
|
||||
*/
|
||||
private StringAlphanumericIdentifierFactory(boolean wrap, int size) {
|
||||
super();
|
||||
this.wrap = wrap;
|
||||
if (size < 1) {
|
||||
throw new IllegalArgumentException("The size must be at least one");
|
||||
}
|
||||
this.count = new char[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
count[i] = '0'; // zero
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new identifier.
|
||||
*
|
||||
* @return a new identifier as a String
|
||||
*/
|
||||
public synchronized Object create() {
|
||||
for (int i = count.length - 1; i >= 0; i--) {
|
||||
switch (count[i]) {
|
||||
case 122: // z
|
||||
count[i] = '0';
|
||||
if (i == 0 && wrap == false) {
|
||||
throw new FactoryException("The maximum number of identifiers has been reached");
|
||||
}
|
||||
break;
|
||||
|
||||
case 57: // 9
|
||||
count[i] = 'a';
|
||||
i = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
count[i]++;
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new String(count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <p><code>StringSessionIdentifierFactory</code> is an Identifier
|
||||
* Factory that generates an alphanumeric 10+ character identifier. The
|
||||
* exact length depends on the number of ids requested per time period.</p>
|
||||
*
|
||||
* <p>Originally designed for JServ sessions. Uses synchronized count and
|
||||
* time to ensure uniqueness. Not guaranteed unique across JVMs, but
|
||||
* fairly safe none the less.</p>
|
||||
*
|
||||
* @author Jon S. Stevens
|
||||
* @author Neeme Praks
|
||||
* @author Stephen Colebourne
|
||||
*/
|
||||
private static class StringSessionIdentifierFactory implements Factory, Serializable {
|
||||
|
||||
/**
|
||||
* We want to have a random string with a length of 6 characters.
|
||||
* Since we encode it base-36, we modulo the random number with
|
||||
* this value.
|
||||
*/
|
||||
private static final long MAX_RANDOM_LEN = 2176782336L; // 36 ** 6
|
||||
/**
|
||||
* The identifier must be unique within the typical lifespan of a
|
||||
* session; the value can roll over after that. 3 characters:
|
||||
* (this means a roll over after over a day, which is much larger
|
||||
* than a typical lifespan).
|
||||
*/
|
||||
private static final long MAX_TIME_SECTION_LEN = 46656L; // 36 ** 3
|
||||
/**
|
||||
* Milliseconds between different tics. The 3-character time
|
||||
* string has a new value every 2 seconds.
|
||||
*/
|
||||
private static final long TIC_DIFFERENCE = 2000;
|
||||
|
||||
/** The incrementing counter. */
|
||||
private int counter = 0;
|
||||
/** The last time. */
|
||||
private long lastTimeValue = 0;
|
||||
/** The randmonizer. */
|
||||
private Random randomizer = new Random();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
private StringSessionIdentifierFactory() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new identifier. Only guaranteed unique within
|
||||
* this JVM, but fairly safe for cross JVM usage as well.
|
||||
*
|
||||
* <p>Format of identifier is
|
||||
* [6 chars random][3 chars time][1+ chars count]</p>
|
||||
*
|
||||
* @return a new identifier as a Long
|
||||
*/
|
||||
public Object create() {
|
||||
// Random value
|
||||
//--------------
|
||||
long currentRandom = randomizer.nextLong();
|
||||
if (currentRandom < 0) {
|
||||
currentRandom = -currentRandom;
|
||||
}
|
||||
// force value into 6 char range, and add to pad with zeros
|
||||
// this gives a length of 7, when converted to base 36, and
|
||||
// the first character (always 1 from the add) is dropped
|
||||
currentRandom %= MAX_RANDOM_LEN;
|
||||
currentRandom += MAX_RANDOM_LEN;
|
||||
|
||||
long currentTimeValue = 0;
|
||||
int currentCount = 0;
|
||||
|
||||
synchronized (this) {
|
||||
// Time
|
||||
//--------------
|
||||
currentTimeValue = (System.currentTimeMillis() / TIC_DIFFERENCE);
|
||||
|
||||
// force value into 3 char range, and add to pad with zeros
|
||||
// this gives a length of 4, when converted to base 36, and
|
||||
// the first character (always 1 from the add) is dropped
|
||||
currentTimeValue %= MAX_TIME_SECTION_LEN;
|
||||
currentTimeValue += MAX_TIME_SECTION_LEN;
|
||||
|
||||
// Count
|
||||
//--------------
|
||||
// Make the string unique by appending the count since last
|
||||
// time flip.
|
||||
|
||||
// Count sessions only within tics (so the 'real' counter
|
||||
// isn't exposed to the public).
|
||||
if (lastTimeValue != currentTimeValue) {
|
||||
lastTimeValue = currentTimeValue;
|
||||
counter = 0;
|
||||
}
|
||||
currentCount = counter++;
|
||||
}
|
||||
|
||||
// build string
|
||||
//--------------
|
||||
StringBuffer id = new StringBuffer(15);
|
||||
id.append(Long.toString(currentRandom, 36).substring(1)); // 6 chars
|
||||
id.append(Long.toString(currentTimeValue, 36).substring(1)); // 3 chars
|
||||
id.append(Long.toString(currentCount, 36)); // 1+ chars
|
||||
return id.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,320 @@
|
|||
/* ====================================================================
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
* Copyright (c) 2002 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution, if
|
||||
* any, must include the following acknowlegement:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowlegement may appear in the software itself,
|
||||
* if and wherever such third-party acknowlegements normally appear.
|
||||
*
|
||||
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
|
||||
* Foundation" must not be used to endorse or promote products derived
|
||||
* from this software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache"
|
||||
* nor may "Apache" appear in their names without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
package org.apache.commons.lang.util;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.apache.commons.lang.functor.Factory;
|
||||
import org.apache.commons.lang.functor.FactoryException;
|
||||
/**
|
||||
* Tests the org.apache.commons.lang.util.IdentifierUtils class.
|
||||
*
|
||||
* @author Stephen Colebourne
|
||||
* @version $Id: IdentifierUtilsTest.java,v 1.1 2002/12/29 21:35:03 scolebourne Exp $
|
||||
*/
|
||||
public class IdentifierUtilsTest extends junit.framework.TestCase {
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*/
|
||||
public IdentifierUtilsTest(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return class aa a test suite.
|
||||
*/
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite(IdentifierUtilsTest.class);
|
||||
suite.setName("IdentifierUtils Tests");
|
||||
return suite;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
public void testLongIncrementing() {
|
||||
Factory f = IdentifierUtils.LONG_IDENTIFIER_FACTORY;
|
||||
assertEquals(new Long(0), f.create());
|
||||
assertEquals(new Long(1), f.create());
|
||||
assertEquals(new Long(2), f.create());
|
||||
assertEquals(new Long(3), f.create());
|
||||
assertEquals(new Long(4), IdentifierUtils.nextLongIdentifier());
|
||||
assertEquals(new Long(5), f.create());
|
||||
assertEquals(new Long(6), IdentifierUtils.nextLongIdentifier());
|
||||
assertEquals(new Long(7), IdentifierUtils.nextLongIdentifier());
|
||||
}
|
||||
|
||||
public void testLongIncrementingNoArgs() {
|
||||
Factory f = IdentifierUtils.longIdentifierFactory();
|
||||
assertEquals(new Long(0), f.create());
|
||||
assertEquals(new Long(1), f.create());
|
||||
assertTrue(f != IdentifierUtils.LONG_IDENTIFIER_FACTORY);
|
||||
}
|
||||
|
||||
public void testLongIncrementingInit() {
|
||||
Factory f = IdentifierUtils.longIdentifierFactory(true, 100);
|
||||
assertEquals(new Long(100), f.create());
|
||||
assertEquals(new Long(101), f.create());
|
||||
}
|
||||
|
||||
public void testLongIncrementingWrap() {
|
||||
Factory f = IdentifierUtils.longIdentifierFactory(true, Long.MAX_VALUE);
|
||||
assertEquals(new Long(Long.MAX_VALUE), f.create());
|
||||
assertEquals(new Long(Long.MIN_VALUE), f.create());
|
||||
}
|
||||
|
||||
public void testLongIncrementingNoWrap() {
|
||||
Factory f = IdentifierUtils.longIdentifierFactory(false, Long.MAX_VALUE);
|
||||
try {
|
||||
f.create();
|
||||
fail();
|
||||
} catch (FactoryException ex) {}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
public void testStringNumericLong() {
|
||||
Factory f = IdentifierUtils.STRING_NUMERIC_IDENTIFIER_FACTORY;
|
||||
assertEquals("0", f.create());
|
||||
assertEquals("1", f.create());
|
||||
assertEquals("2", f.create());
|
||||
assertEquals("3", f.create());
|
||||
assertEquals("4", IdentifierUtils.nextStringNumericIdentifier());
|
||||
assertEquals("5", f.create());
|
||||
assertEquals("6", IdentifierUtils.nextStringNumericIdentifier());
|
||||
assertEquals("7", IdentifierUtils.nextStringNumericIdentifier());
|
||||
}
|
||||
|
||||
public void testStringNumericNoArgs() {
|
||||
Factory f = IdentifierUtils.stringNumericIdentifierFactory();
|
||||
assertEquals("0", f.create());
|
||||
assertEquals("1", f.create());
|
||||
assertTrue(f != IdentifierUtils.STRING_NUMERIC_IDENTIFIER_FACTORY);
|
||||
}
|
||||
|
||||
public void testStringNumericInit() {
|
||||
Factory f = IdentifierUtils.stringNumericIdentifierFactory(true, 100);
|
||||
assertEquals("100", f.create());
|
||||
assertEquals("101", f.create());
|
||||
}
|
||||
|
||||
public void testStringNumericWrap() {
|
||||
Factory f = IdentifierUtils.stringNumericIdentifierFactory(true, Long.MAX_VALUE);
|
||||
assertEquals(Long.toString(Long.MAX_VALUE), f.create());
|
||||
assertEquals(Long.toString(Long.MIN_VALUE), f.create());
|
||||
}
|
||||
|
||||
public void testStringNumericNoWrap() {
|
||||
Factory f = IdentifierUtils.stringNumericIdentifierFactory(false, Long.MAX_VALUE);
|
||||
try {
|
||||
f.create();
|
||||
fail();
|
||||
} catch (FactoryException ex) { }
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
public void testStringAlphanumeric() {
|
||||
Factory f = IdentifierUtils.STRING_ALPHANUMERIC_IDENTIFIER_FACTORY;
|
||||
assertEquals("000000000000001", f.create());
|
||||
assertEquals("000000000000002", f.create());
|
||||
assertEquals("000000000000003", f.create());
|
||||
assertEquals("000000000000004", f.create());
|
||||
assertEquals("000000000000005", f.create());
|
||||
assertEquals("000000000000006", f.create());
|
||||
assertEquals("000000000000007", f.create());
|
||||
assertEquals("000000000000008", f.create());
|
||||
assertEquals("000000000000009", f.create());
|
||||
assertEquals("00000000000000a", f.create());
|
||||
assertEquals("00000000000000b", f.create());
|
||||
assertEquals("00000000000000c", f.create());
|
||||
assertEquals("00000000000000d", IdentifierUtils.nextStringAlphanumericIdentifier());
|
||||
assertEquals("00000000000000e", f.create());
|
||||
assertEquals("00000000000000f", f.create());
|
||||
assertEquals("00000000000000g", f.create());
|
||||
assertEquals("00000000000000h", f.create());
|
||||
assertEquals("00000000000000i", f.create());
|
||||
assertEquals("00000000000000j", f.create());
|
||||
assertEquals("00000000000000k", f.create());
|
||||
assertEquals("00000000000000l", f.create());
|
||||
assertEquals("00000000000000m", f.create());
|
||||
assertEquals("00000000000000n", f.create());
|
||||
assertEquals("00000000000000o", f.create());
|
||||
assertEquals("00000000000000p", f.create());
|
||||
assertEquals("00000000000000q", f.create());
|
||||
assertEquals("00000000000000r", f.create());
|
||||
assertEquals("00000000000000s", f.create());
|
||||
assertEquals("00000000000000t", f.create());
|
||||
assertEquals("00000000000000u", f.create());
|
||||
assertEquals("00000000000000v", f.create());
|
||||
assertEquals("00000000000000w", f.create());
|
||||
assertEquals("00000000000000x", f.create());
|
||||
assertEquals("00000000000000y", f.create());
|
||||
assertEquals("00000000000000z", f.create());
|
||||
assertEquals("000000000000010", f.create());
|
||||
assertEquals("000000000000011", f.create());
|
||||
assertEquals("000000000000012", f.create());
|
||||
assertEquals("000000000000013", f.create());
|
||||
}
|
||||
|
||||
public void testLongAlphanumericNoArgs() {
|
||||
Factory f = IdentifierUtils.stringAlphanumericIdentifierFactory();
|
||||
assertEquals("000000000000001", f.create());
|
||||
assertEquals("000000000000002", f.create());
|
||||
assertTrue(f != IdentifierUtils.STRING_ALPHANUMERIC_IDENTIFIER_FACTORY);
|
||||
}
|
||||
|
||||
public void testStringAlphanumericWrap() {
|
||||
Factory f = IdentifierUtils.stringAlphanumericIdentifierFactory(true, 1);
|
||||
assertEquals("1", f.create());
|
||||
assertEquals("2", f.create());
|
||||
assertEquals("3", f.create());
|
||||
assertEquals("4", f.create());
|
||||
assertEquals("5", f.create());
|
||||
assertEquals("6", f.create());
|
||||
assertEquals("7", f.create());
|
||||
assertEquals("8", f.create());
|
||||
assertEquals("9", f.create());
|
||||
assertEquals("a", f.create());
|
||||
assertEquals("b", f.create());
|
||||
assertEquals("c", f.create());
|
||||
assertEquals("d", f.create());
|
||||
assertEquals("e", f.create());
|
||||
assertEquals("f", f.create());
|
||||
assertEquals("g", f.create());
|
||||
assertEquals("h", f.create());
|
||||
assertEquals("i", f.create());
|
||||
assertEquals("j", f.create());
|
||||
assertEquals("k", f.create());
|
||||
assertEquals("l", f.create());
|
||||
assertEquals("m", f.create());
|
||||
assertEquals("n", f.create());
|
||||
assertEquals("o", f.create());
|
||||
assertEquals("p", f.create());
|
||||
assertEquals("q", f.create());
|
||||
assertEquals("r", f.create());
|
||||
assertEquals("s", f.create());
|
||||
assertEquals("t", f.create());
|
||||
assertEquals("u", f.create());
|
||||
assertEquals("v", f.create());
|
||||
assertEquals("w", f.create());
|
||||
assertEquals("x", f.create());
|
||||
assertEquals("y", f.create());
|
||||
assertEquals("z", f.create());
|
||||
assertEquals("0", f.create());
|
||||
}
|
||||
|
||||
public void testStringAlphanumericNoWrap() {
|
||||
Factory f = IdentifierUtils.stringAlphanumericIdentifierFactory(false, 1);
|
||||
assertEquals("1", f.create());
|
||||
assertEquals("2", f.create());
|
||||
assertEquals("3", f.create());
|
||||
assertEquals("4", f.create());
|
||||
assertEquals("5", f.create());
|
||||
assertEquals("6", f.create());
|
||||
assertEquals("7", f.create());
|
||||
assertEquals("8", f.create());
|
||||
assertEquals("9", f.create());
|
||||
assertEquals("a", f.create());
|
||||
assertEquals("b", f.create());
|
||||
assertEquals("c", f.create());
|
||||
assertEquals("d", f.create());
|
||||
assertEquals("e", f.create());
|
||||
assertEquals("f", f.create());
|
||||
assertEquals("g", f.create());
|
||||
assertEquals("h", f.create());
|
||||
assertEquals("i", f.create());
|
||||
assertEquals("j", f.create());
|
||||
assertEquals("k", f.create());
|
||||
assertEquals("l", f.create());
|
||||
assertEquals("m", f.create());
|
||||
assertEquals("n", f.create());
|
||||
assertEquals("o", f.create());
|
||||
assertEquals("p", f.create());
|
||||
assertEquals("q", f.create());
|
||||
assertEquals("r", f.create());
|
||||
assertEquals("s", f.create());
|
||||
assertEquals("t", f.create());
|
||||
assertEquals("u", f.create());
|
||||
assertEquals("v", f.create());
|
||||
assertEquals("w", f.create());
|
||||
assertEquals("x", f.create());
|
||||
assertEquals("y", f.create());
|
||||
assertEquals("z", f.create());
|
||||
try {
|
||||
f.create();
|
||||
fail();
|
||||
} catch (FactoryException ex) {}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
public void testStringSession() {
|
||||
Factory f = IdentifierUtils.STRING_SESSION_IDENTIFIER_FACTORY;
|
||||
assertTrue(f != IdentifierUtils.stringSessionIdentifierFactory());
|
||||
|
||||
String a = (String) f.create();
|
||||
String b = (String) IdentifierUtils.nextStringSessionIdentifier();
|
||||
assertTrue(a.length() >= 10);
|
||||
assertTrue(b.length() >= 10);
|
||||
// could fail, but unlikely
|
||||
assertTrue(a.substring(6, 9) != b.substring(6, 9));
|
||||
assertEquals("0", a.substring(9));
|
||||
assertEquals("1", b.substring(9));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
}
|
|
@ -61,7 +61,7 @@ import junit.textui.TestRunner;
|
|||
* Test suite for the Util package.
|
||||
*
|
||||
* @author <a href="mailto:bayard@apache.org">Henri Yandell</a>
|
||||
* @version $Id: UtilTestSuite.java,v 1.1 2002/12/18 02:50:36 bayard Exp $
|
||||
* @version $Id: UtilTestSuite.java,v 1.2 2002/12/29 21:35:03 scolebourne Exp $
|
||||
*/
|
||||
public class UtilTestSuite extends TestCase {
|
||||
|
||||
|
@ -86,6 +86,7 @@ public class UtilTestSuite extends TestCase {
|
|||
TestSuite suite = new TestSuite();
|
||||
suite.setName("Commons-Lang-Util Tests");
|
||||
suite.addTest(BitFieldTest.suite());
|
||||
suite.addTest(IdentifierUtilsTest.suite());
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue