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.regex;
028:
029: import org.databene.benerator.Generator;
030: import org.databene.benerator.SimpleRandom;
031: import org.databene.benerator.InvalidGeneratorSetupException;
032: import org.databene.benerator.wrapper.UniqueAlternativeGenerator;
033: import org.databene.regex.AlternativePattern;
034: import org.databene.regex.SubPattern;
035: import org.databene.regex.Group;
036:
037: /**
038: * Creates a unique string of variable length from am character set.<br/>
039: * <br/>
040: * Created: 17.11.2007 19:21:58
041: */
042: public class UniqueCompositeStringGenerator implements
043: Generator<String> {
044:
045: private SubPattern pattern;
046: private int min;
047: private int max;
048:
049: private Generator<String>[] sources;
050:
051: public UniqueCompositeStringGenerator() {
052: this (null, 1, 1, 30);
053: }
054:
055: public UniqueCompositeStringGenerator(SubPattern pattern, int min,
056: int max, int maxQuantity) {
057: if (pattern == null)
058: return;
059: this .pattern = pattern;
060: this .min = min;
061: this .max = max;
062: sources = new Generator[max - min + 1];
063: for (int length = min; length <= max; length++) {
064: // create UniqueFixedCoundCompositeStringGenerator for this count
065: if (pattern instanceof AlternativePattern) {
066: Generator<String>[] subGens = new Generator[length];
067: for (int j = 0; j < length; j++) {
068: Generator<String>[] altGens = RegexPartGeneratorFactory
069: .getRegexGenerators(
070: (AlternativePattern) pattern,
071: maxQuantity, true);
072: subGens[j] = new UniqueAlternativeGenerator<String>(
073: String.class, altGens);
074: }
075: sources[length - min] = new UniqueFixedCountCompositeStringGenerator(
076: subGens);
077: } else if (pattern instanceof Group) {
078: Generator<String>[] subGens = new Generator[length];
079: for (int j = 0; j < length; j++) {
080: Group group = (Group) pattern;
081: subGens[j] = new RegexStringGenerator(group
082: .getRegex(), maxQuantity, true);
083: }
084: sources[length - min] = new UniqueFixedCountCompositeStringGenerator(
085: subGens);
086: } else
087: throw new UnsupportedOperationException(
088: "Not a supported pattern: " + pattern);
089: }
090: }
091:
092: // Generator interface ---------------------------------------------------------------------------------------------
093:
094: public Class<String> getGeneratedType() {
095: return String.class;
096: }
097:
098: public void validate() {
099: if (sources == null || sources.length == 0)
100: throw new InvalidGeneratorSetupException("sources",
101: "not set");
102: for (Generator<String> source : sources)
103: source.validate();
104: }
105:
106: public boolean available() {
107: for (Generator<String> source : sources)
108: if (source.available())
109: return true;
110: return false;
111: }
112:
113: public String generate() {
114: int index;
115: do {
116: index = SimpleRandom.randomInt(0, sources.length - 1);
117: } while (!sources[index].available());
118: return sources[index].generate();
119: }
120:
121: public void reset() {
122: for (Generator<String> source : sources)
123: source.reset();
124: }
125:
126: public void close() {
127: for (Generator<String> source : sources)
128: source.close();
129: }
130:
131: // java.lang.Object overrides --------------------------------------------------------------------------------------
132:
133: public String toString() {
134: return getClass().getSimpleName() + "['" + pattern + ", " + min
135: + "<=length<=" + max + ']';
136: }
137: }
|