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.factory;
028:
029: import org.databene.model.data.*;
030: import org.databene.model.storage.StorageSystem;
031: import org.databene.benerator.*;
032: import org.databene.benerator.composite.EntityGenerator;
033: import org.databene.benerator.wrapper.*;
034: import org.databene.commons.*;
035: import org.databene.document.flat.FlatFileColumnDescriptor;
036: import org.databene.document.flat.FlatFileUtil;
037: import org.databene.platform.dbunit.DbUnitEntityIterable;
038: import org.databene.platform.flat.FlatFileEntityIterable;
039: import org.databene.platform.csv.CSVEntityIterable;
040: import org.databene.script.ScriptConverter;
041: import org.apache.commons.logging.Log;
042: import org.apache.commons.logging.LogFactory;
043:
044: import java.util.*;
045:
046: /**
047: * Creates entity generators from entity metadata.<br/>
048: * <br/>
049: * Created: 08.09.2007 07:45:40
050: * @author Volker Bergmann
051: */
052: public class EntityGeneratorFactory extends FeatureGeneratorFactory {
053:
054: private static final Log logger = LogFactory
055: .getLog(EntityGeneratorFactory.class);
056:
057: // descriptor feature names ----------------------------------------------------------------------------------------
058:
059: private static final String COUNT = "count";
060:
061: // attributes ------------------------------------------------------------------------------------------------------
062:
063: private static Escalator escalator = new LoggerEscalator();
064:
065: // private constructor for preventing instatiation -----------------------------------------------------------------
066:
067: private EntityGeneratorFactory() {
068: }
069:
070: // public utility methods ------------------------------------------------------------------------------------------
071:
072: public static Generator<Entity> createEntityGenerator(
073: EntityDescriptor descriptor, Context context,
074: GenerationSetup setup) {
075: if (logger.isDebugEnabled())
076: logger.debug("createEntityGenerator("
077: + descriptor.getName() + ")");
078: Set<String> usedDetails = new HashSet<String>();
079: // create original generator
080: Generator<Entity> generator = createSourceEntityGenerator(
081: descriptor, context, setup, usedDetails);
082: if (generator == null)
083: generator = createGeneratingEntityGenerator(descriptor,
084: context, setup);
085: else
086: generator = createMutatingEntityGenerator(descriptor,
087: context, generator, setup);
088: // create wrappers
089: generator = createValidatingGenerator(descriptor, generator,
090: usedDetails);
091: generator = createLimitCountGenerator(descriptor, generator,
092: usedDetails);
093: checkUsedDetails(descriptor, usedDetails);
094: if (logger.isDebugEnabled())
095: logger.debug("Created " + generator);
096: return generator;
097: }
098:
099: // private helpers -------------------------------------------------------------------------------------------------
100:
101: private static Generator<Entity> createLimitCountGenerator(
102: EntityDescriptor descriptor, Generator<Entity> generator,
103: Set<String> usedDetails) {
104: if (descriptor.getCount() != null) {
105: usedDetails.add(COUNT);
106: generator = new NShotGeneratorProxy<Entity>(generator,
107: descriptor.getCount());
108: }
109: return generator;
110: }
111:
112: private static Generator<Entity> createGeneratingEntityGenerator(
113: EntityDescriptor descriptor, Context context,
114: GenerationSetup setup) {
115: Map<String, Generator<? extends Object>> componentGenerators = new HashMap<String, Generator<? extends Object>>();
116: Collection<ComponentDescriptor> descriptors = descriptor
117: .getComponentDescriptors();
118: for (ComponentDescriptor component : descriptors) {
119: if (component.getMode() != Mode.ignored) {
120: Generator<? extends Object> componentGenerator = ComponentGeneratorFactory
121: .getComponentGenerator(component, context,
122: setup);
123: componentGenerators.put(component.getName(),
124: componentGenerator);
125: }
126: }
127: return new EntityGenerator(descriptor, componentGenerators,
128: context);
129: }
130:
131: private static Generator<Entity> createMutatingEntityGenerator(
132: EntityDescriptor descriptor, Context context,
133: Generator<Entity> generator, GenerationSetup setup) {
134: Map<String, Generator<? extends Object>> componentGenerators = new HashMap<String, Generator<? extends Object>>();
135: Collection<ComponentDescriptor> descriptors = descriptor
136: .getDeclaredComponentDescriptors();
137: for (ComponentDescriptor component : descriptors) {
138: if (component.getMode() != Mode.ignored) {
139: Generator<? extends Object> componentGenerator = ComponentGeneratorFactory
140: .getComponentGenerator(component, context,
141: setup);
142: componentGenerators.put(component.getName(),
143: componentGenerator);
144: }
145: }
146: return new EntityGenerator(descriptor, generator,
147: componentGenerators, context);
148: }
149:
150: private static Generator<Entity> createSourceEntityGenerator(
151: EntityDescriptor descriptor, Context context,
152: GenerationSetup setup, Set<String> usedDetails) {
153: // if no sourceObject is specified, there's nothing to do
154: String sourceName = descriptor.getSource();
155: if (sourceName == null)
156: return null;
157: usedDetails.add(SOURCE);
158: // create sourceObject generator
159: Generator<Entity> generator = null;
160: Object sourceObject = context.get(sourceName);
161: if (sourceObject != null) {
162: if (sourceObject instanceof StorageSystem) {
163: StorageSystem storage = (StorageSystem) sourceObject;
164: String selector = descriptor.getSelector();
165: generator = new IteratingGenerator<Entity>(storage
166: .queryEntities(descriptor.getName(), selector));
167: } else if (sourceObject instanceof org.databene.model.system.System) {
168: escalator.escalate("Using deprecated class: "
169: + sourceObject.getClass().getName(),
170: EntityGeneratorFactory.class, null);
171: org.databene.model.system.System system = (org.databene.model.system.System) sourceObject;
172: generator = new IteratingGenerator<Entity>(system
173: .getEntities(descriptor.getName()));
174: } else if (sourceObject instanceof TypedIterable) {
175: generator = new IteratingGenerator(
176: (TypedIterable) sourceObject);
177: } else if (sourceObject instanceof Generator) {
178: generator = (Generator) sourceObject;
179: } else
180: throw new UnsupportedOperationException(
181: "Source type not supported: "
182: + sourceObject.getClass());
183: } else {
184: if (sourceName.endsWith(".xml"))
185: generator = new IteratingGenerator<Entity>(
186: new DbUnitEntityIterable(sourceName, context,
187: setup.getDefaultScript()));
188: else if (sourceName.endsWith(".csv")) {
189: String encoding = descriptor.getEncoding();
190: if (encoding != null)
191: usedDetails.add(ENCODING);
192: else
193: encoding = setup.getDefaultEncoding();
194: ScriptConverter scriptConverter = new ScriptConverter(
195: context, setup.getDefaultScript());
196: CSVEntityIterable iterable = new CSVEntityIterable(
197: sourceName, descriptor.getName(),
198: scriptConverter, ',', encoding);
199: generator = new IteratingGenerator(iterable);
200: } else if (sourceName.endsWith(".flat")) {
201: String encoding = descriptor.getEncoding();
202: if (encoding != null)
203: usedDetails.add(ENCODING);
204: else
205: encoding = setup.getDefaultEncoding();
206: String pattern = descriptor.getPattern();
207: if (pattern != null)
208: usedDetails.add(ENCODING);
209: else
210: throw new ConfigurationError(
211: "No pattern specified for flat file import: "
212: + sourceName);
213: FlatFileColumnDescriptor[] ffcd = FlatFileUtil
214: .parseProperties(pattern);
215: ScriptConverter scriptConverter = new ScriptConverter(
216: context, setup.getDefaultScript());
217: FlatFileEntityIterable iterable = new FlatFileEntityIterable(
218: sourceName, descriptor, scriptConverter,
219: encoding, ffcd);
220: generator = new IteratingGenerator(iterable);
221: } else
222: throw new UnsupportedOperationException(
223: "Unknown source type: " + sourceName);
224: }
225: return createProxy(descriptor, generator, usedDetails);
226: }
227:
228: }
|