001: /*
002: * (c) Copyright 2007 by Volker Bergmann. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, is permitted under the terms of the
006: * GNU General Public License.
007: *
008: * For redistributing this software or a derivative work under a license other
009: * than the GPL-compatible Free Software License as defined by the Free
010: * Software Foundation or approved by OSI, you must first obtain a commercial
011: * license to this software product from Volker Bergmann.
012: *
013: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
014: * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
015: * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
016: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
017: * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
018: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
019: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
020: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
021: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
022: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
023: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
024: * POSSIBILITY OF SUCH DAMAGE.
025: */
026:
027: package org.databene.benerator.primitive;
028:
029: import org.databene.benerator.Generator;
030: import org.databene.benerator.SimpleRandom;
031: import org.databene.benerator.IllegalGeneratorStateException;
032: import org.databene.commons.CollectionUtil;
033: import org.databene.commons.CharSet;
034: import org.databene.commons.ArrayFormat;
035:
036: import java.util.Set;
037:
038: /**
039: * Generates unique strings of variable length.<br/>
040: * <br/>
041: * Created: 16.11.2007 11:56:15
042: * @author Volker Bergmann
043: */
044: public class UniqueStringGenerator implements Generator<String> {
045:
046: private int minLength;
047: private int maxLength;
048: private char[] charSet;
049: private Generator<String>[] subGens;
050: private boolean dirty;
051:
052: public UniqueStringGenerator() {
053: this (4, 8, new CharSet('A', 'Z').getSet());
054: }
055:
056: public UniqueStringGenerator(int minLength, int maxLength,
057: Set<Character> charSet) {
058: this (minLength, maxLength, CollectionUtil.toArray(charSet));
059: }
060:
061: public UniqueStringGenerator(int minLength, int maxLength,
062: char... charSet) {
063: this .minLength = minLength;
064: this .maxLength = maxLength;
065: this .charSet = charSet;
066: this .subGens = new Generator[0];
067: dirty = true;
068: }
069:
070: public int getMinLength() {
071: return minLength;
072: }
073:
074: public void setMinLength(int minLength) {
075: this .minLength = minLength;
076: dirty = true;
077: }
078:
079: public int getMaxLength() {
080: return maxLength;
081: }
082:
083: public void setMaxLength(int maxLength) {
084: this .maxLength = maxLength;
085: dirty = true;
086: }
087:
088: // Generator interface ---------------------------------------------------------------------------------------------
089:
090: public Class<String> getGeneratedType() {
091: return String.class;
092: }
093:
094: public void validate() {
095: if (dirty) {
096: this .subGens = new Generator[maxLength - minLength + 1];
097: for (int i = minLength; i <= maxLength; i++)
098: subGens[i - minLength] = new UniqueFixedLengthStringGenerator(
099: i, charSet);
100: dirty = false;
101: }
102: }
103:
104: public boolean available() {
105: if (dirty)
106: validate();
107: for (int i = maxLength - minLength; i >= 0; i--)
108: if (subGens[i].available())
109: return true;
110: return false;
111: }
112:
113: public String generate() {
114: if (!available())
115: throw new IllegalGeneratorStateException(
116: "Generator is no longer available");
117: int generatorIndex;
118: do {
119: generatorIndex = SimpleRandom.randomInt(0, maxLength
120: - minLength);
121: } while (!subGens[generatorIndex].available());
122: return subGens[generatorIndex].generate();
123: }
124:
125: public void reset() {
126: for (Generator<String> generator : subGens)
127: generator.reset();
128: dirty = true;
129: }
130:
131: public void close() {
132: for (Generator<String> generator : subGens)
133: generator.close();
134: subGens = null;
135: dirty = true;
136: }
137:
138: public String toString() {
139: return getClass().getSimpleName() + '[' + minLength
140: + "<=length<=" + maxLength + ", " + "charSet=["
141: + ArrayFormat.formatChars(", ", charSet) + "]]";
142: }
143: }
|