001: /*
002: * (c) Copyright 2006 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.*;
030: import org.databene.regex.RegexParser;
031: import org.databene.regex.RegexTokenizer;
032: import org.databene.benerator.sample.WeightedSampleGenerator;
033: import org.databene.commons.LocaleUtil;
034:
035: import java.util.*;
036: import java.text.ParseException;
037:
038: /**
039: * Generates Character values from a character set or a regular expression.<br/>
040: * <br/>
041: * Created: 09.06.2006 20:34:55
042: * @author Volker Bergmann
043: */
044: public class CharacterGenerator implements Generator<Character> {
045:
046: /** The regular exception */
047: private String pattern;
048:
049: /** The locale */
050: private Locale locale;
051:
052: /** The set of characters to generate from */
053: private Set<Character> values;
054:
055: /** dirty flag for consistency control */
056: private boolean dirty;
057:
058: /** The SampleGenerator to choose from the character set */
059: private WeightedSampleGenerator<Character> source;
060:
061: // constructors ----------------------------------------------------------------------------------------------------
062:
063: /**
064: * initializes the generator to use letters of the fallback locale.
065: * @see org.databene.commons.LocaleUtil#getFallbackLocale()
066: */
067: public CharacterGenerator() {
068: this ("\\w");
069: }
070:
071: /**
072: * initializes the generator to create character that match a regular expressions and the fallback locale.
073: * @see org.databene.commons.LocaleUtil#getFallbackLocale()
074: */
075: public CharacterGenerator(String pattern) {
076: this (pattern, LocaleUtil.getFallbackLocale());
077: }
078:
079: /**
080: * initializes the generator to create character that match a regular expressions and a locale.
081: * @see org.databene.commons.LocaleUtil#getFallbackLocale()
082: */
083: public CharacterGenerator(String pattern, Locale locale) {
084: this .pattern = pattern;
085: this .locale = locale;
086: this .values = new HashSet<Character>();
087: this .dirty = true;
088: }
089:
090: /**
091: * initializes the generator to create characters from a character collection.
092: * @see org.databene.commons.LocaleUtil#getFallbackLocale()
093: */
094: public CharacterGenerator(Collection<Character> values) {
095: this .pattern = null;
096: this .locale = LocaleUtil.getFallbackLocale();
097: this .values = new HashSet<Character>(values);
098: this .dirty = true;
099: }
100:
101: // config properties -----------------------------------------------------------------------------------------------
102:
103: /** Returns the regular expression to match */
104: public String getPattern() {
105: return pattern;
106: }
107:
108: /** Sets the regular expression to match */
109: public void setPattern(String pattern) throws ParseException {
110: this .pattern = pattern;
111: this .dirty = true;
112: }
113:
114: /** Returns the locale of which letters are taken */
115: public Locale getLocale() {
116: return locale;
117: }
118:
119: /** Sets the locale of which letters are taken */
120: public void setLocale(Locale locale) {
121: this .locale = locale;
122: this .dirty = true;
123: }
124:
125: /** Returns the available values */
126: public Set<Character> getValues() {
127: return values;
128: }
129:
130: /** Sets the available values */
131: public void setValues(Set<Character> set) {
132: source.setValues(set);
133: this .dirty = true;
134: }
135:
136: // source interface ------------------------------------------------------------------------------------------------
137:
138: public Class<Character> getGeneratedType() {
139: return Character.class;
140: }
141:
142: /**
143: * Initializes the generator's state.
144: */
145: public void validate() {
146: if (dirty) {
147: try {
148: if (pattern != null)
149: values = new RegexParser(locale)
150: .parseCharSet(new RegexTokenizer(pattern));
151: this .source = new WeightedSampleGenerator<Character>(
152: values);
153: source.validate();
154: this .dirty = false;
155: } catch (ParseException e) {
156: throw new IllegalGeneratorStateException(e);
157: }
158: }
159: }
160:
161: /** @see org.databene.benerator.Generator#generate() */
162: public Character generate() {
163: if (dirty)
164: validate();
165: return source.generate();
166: }
167:
168: public void reset() {
169: if (dirty)
170: validate();
171: source.reset();
172: }
173:
174: public void close() {
175: if (dirty)
176: validate();
177: source.close();
178: }
179:
180: public boolean available() {
181: if (dirty)
182: validate();
183: return source.available();
184: }
185:
186: public String toString() {
187: return getClass().getSimpleName() + values;
188: }
189: }
|