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.sample;
028:
029: import org.databene.benerator.IllegalGeneratorStateException;
030: import org.databene.benerator.InvalidGeneratorSetupException;
031: import org.databene.benerator.Generator;
032: import org.databene.commons.ConversionException;
033: import org.databene.commons.Converter;
034: import org.databene.commons.converter.NoOpConverter;
035: import org.databene.document.csv.CSVLineIterator;
036:
037: import java.io.IOException;
038: import java.io.FileNotFoundException;
039: import java.util.List;
040: import java.util.ArrayList;
041:
042: /**
043: * Sample Generator for values that are read from a CSV file.
044: * The CSV file needs to be comma-separated and has to contain the values
045: * in the first column. The remaining columns are ignored.
046: * Example:
047: * <pre>
048: * Alpha,sdlkvn,piac
049: * Bravo,lsdknac
050: * Charly,fuv
051: * </pre>
052: *
053: * @see org.databene.benerator.sample.WeightedSampleGenerator<br/>
054: * <br/>
055: * Created: 26.07.2007 18:10:33
056: */
057: public class SequencedCSVSampleGenerator<E> implements Generator<E> {
058:
059: /** The URL to read the samples from */
060: private String url;
061:
062: /** The converter to create instances from the CSV cell strings */
063: private Converter<String, E> converter;
064:
065: /** the SampleGenerator utilized for selecting among the samples */
066: private SequencedSampleGenerator<E> source;
067:
068: /** flag that indicates if the generator needs to be initialized */
069: private boolean dirty;
070:
071: // constructors ----------------------------------------------------------------------------------------------------
072:
073: public SequencedCSVSampleGenerator() {
074: this ((String) null);
075: }
076:
077: public SequencedCSVSampleGenerator(String url) {
078: this (url, new NoOpConverter());
079: }
080:
081: public SequencedCSVSampleGenerator(Converter<String, E> converter) {
082: this (null, converter);
083: }
084:
085: public SequencedCSVSampleGenerator(String url,
086: Converter<String, E> converter) {
087: this .source = new SequencedSampleGenerator<E>(converter
088: .getTargetType());
089: this .converter = converter;
090: if (url != null && url.trim().length() > 0)
091: setUrl(url);
092: }
093:
094: // configuration properties ----------------------------------------------------------------------------------------
095:
096: public void setUrl(String url) {
097: this .url = url;
098: this .dirty = true;
099: }
100:
101: public String getUrl() {
102: return url;
103: }
104:
105: // Generator interface ---------------------------------------------------------------------------------------------
106:
107: public Class<E> getGeneratedType() {
108: return source.getGeneratedType();
109: }
110:
111: public E generate() {
112: if (dirty)
113: validate();
114: return source.generate();
115: }
116:
117: public void validate() {
118: if (dirty) {
119: try {
120: CSVLineIterator parser = new CSVLineIterator(url);
121: String[] tokens;
122: List<E> samples = new ArrayList<E>();
123: while ((tokens = parser.next()) != null
124: && tokens.length > 0)
125: samples.add(converter.convert(tokens[0]));
126: source.setValues(samples);
127: dirty = false;
128: } catch (FileNotFoundException e) {
129: throw new InvalidGeneratorSetupException("url",
130: "not found: " + url);
131: } catch (IOException e) {
132: throw new IllegalGeneratorStateException(e); // file access was interrupted, no fail-over
133: } catch (ConversionException e) {
134: throw new InvalidGeneratorSetupException(
135: "URL content not valid", e);
136: }
137: }
138: }
139:
140: public void reset() {
141: source.reset();
142: }
143:
144: public void close() {
145: source.close();
146: }
147:
148: public boolean available() {
149: return source.available();
150: }
151:
152: // java.lang.Object overrides --------------------------------------------------------------------------------------
153:
154: public String toString() {
155: return getClass().getSimpleName() + "[source=" + source
156: + ", converter=" + converter + ']';
157: }
158: }
|