01: /*
02: * (c) Copyright 2006 by Volker Bergmann. All rights reserved.
03: *
04: * Redistribution and use in source and binary forms, with or without
05: * modification, is permitted under the terms of the
06: * GNU General Public License.
07: *
08: * For redistributing this software or a derivative work under a license other
09: * than the GPL-compatible Free Software License as defined by the Free
10: * Software Foundation or approved by OSI, you must first obtain a commercial
11: * license to this software product from Volker Bergmann.
12: *
13: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14: * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
15: * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
16: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
17: * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24: * POSSIBILITY OF SUCH DAMAGE.
25: */
26:
27: package org.databene.benerator;
28:
29: import org.apache.commons.logging.Log;
30: import org.apache.commons.logging.LogFactory;
31: import org.databene.commons.Validator;
32:
33: /**
34: * Provides an abstract implementation of a generator that validates its generated values.<br/>
35: * <br/>
36: * Created: 23.09.2006 00:03:04
37: */
38: public abstract class ValidatingGenerator<P> implements Generator<P> {
39:
40: /** The Logger */
41: private static Log logger = LogFactory
42: .getLog(ValidatingGenerator.class);
43:
44: /** The number of invalid consecutive generations that causes a warning */
45: public static final int WARNING_THRESHOLD = 100;
46:
47: /** The number of invalid consecutive generations that causes an exception */
48: public static final int ERROR_THRESHOLD = 1000;
49:
50: /** The validator used for validation */
51: protected Validator<P> validator;
52:
53: /** Constructor that takes the validator */
54: public ValidatingGenerator(Validator<P> validator) {
55: this .validator = validator;
56: }
57:
58: /**
59: * Generator implementation that calls generateImpl() to generate values
60: * and validator.validate() in order to validate them.
61: * Consecutive invalid values are counted. If this count reaches the
62: * WARNING_THRESHOLD value, a warning is logged, if the count reaches the
63: * ERROR_THRESHOLD, an exception is raised.
64: */
65:
66: public P generate() {
67: P product;
68: boolean valid;
69: int count = 0;
70: do {
71: product = generateImpl();
72: valid = validator.valid(product);
73: count++;
74: if (count >= ERROR_THRESHOLD)
75: throw new IllegalGeneratorStateException(
76: "Aborting generation, because of "
77: + ERROR_THRESHOLD
78: + " consecutive invalid generations. Validator is: "
79: + validator + ". Last attempt was: "
80: + product);
81: } while (!valid);
82: if (count >= WARNING_THRESHOLD)
83: logger.warn("Inefficient generation: needed " + count
84: + " tries to generate a valid value. ");
85: return product;
86: }
87:
88: /**
89: * Callback method that does the job of creating values.
90: * This is to be implemented by child classes.
91: */
92: protected abstract P generateImpl();
93: }
|