001: package com.bm.creators;
002:
003: import java.util.List;
004:
005: import org.apache.log4j.Logger;
006:
007: import com.bm.datagen.DataGenerator;
008: import com.bm.datagen.Generator;
009: import com.bm.introspectors.Introspector;
010: import com.bm.introspectors.PersistentPropertyInfo;
011: import com.bm.introspectors.PrimaryKeyInfo;
012: import com.bm.introspectors.Property;
013: import com.bm.utils.Ejb3Utils;
014:
015: /**
016: * This class creates instances of different classes with random data, like
017: * entity beans, inner classes etc..
018: *
019: * @author Daniel Wiese
020: * @param <T> -
021: * the type of the class to create
022: * @since 07.10.2005
023: */
024: public class EntityInstanceCreator<T> {
025:
026: private static final Logger log = Logger
027: .getLogger(EntityInstanceCreator.class);
028:
029: private final Introspector<T> intro;
030:
031: private final Class<T> toCreate;
032:
033: private final DataGenerator dataGen;
034:
035: /**
036: * Default constructor.
037: *
038: * @param intro -
039: * different types of introspectors
040: * @param toCreate -
041: * the class to create
042: * @param generators -
043: * the generator list
044: */
045: public EntityInstanceCreator(Introspector<T> intro,
046: Class<T> toCreate, List<Generator> generators) {
047: this .intro = intro;
048: this .toCreate = toCreate;
049: this .dataGen = new DataGenerator();
050: // register current generators
051: for (Generator actGen : generators) {
052: this .dataGen.registerGen(actGen);
053: }
054: }
055:
056: /**
057: * This method should be called every time before an entity creation task >
058: * this method tells every generator to call his prepare method(annotation).
059: */
060: public void prepare() {
061: this .dataGen.prepare();
062: }
063:
064: /**
065: * This method should be called every time before an entity creation task >
066: * this method tells every generator to call his clenup method (annotation).
067: */
068: public void cleanup() {
069: this .dataGen.cleanup();
070: }
071:
072: /**
073: * Creates a instance of the class (filled with random data).
074: *
075: * @return -a filled instance of the class (@see DataGenerator)
076: */
077: public T createInstance() {
078: // for error messages
079: String aktFieldName = "unknown";
080: try {
081: final T back = Ejb3Utils.getNewInstance(this .toCreate);
082: // iterate over all fields
083: for (Property aktProperty : this .intro
084: .getPersitentProperties()) {
085: aktFieldName = aktProperty.getName();
086: final PersistentPropertyInfo pfi = this .intro
087: .getPresistentFieldInfo(aktProperty);
088: // donīt not generate values for embedded class fields
089: // and not for TABLE, SEQUENCE, IDENTITY, AUTO pk fields
090: if (!pfi.isEmbeddedClass()
091: && shouldPkValueBeGenerated(aktProperty,
092: this .intro)) {
093: // delegate to the data generator
094: this .setField(back, aktProperty,
095: this .dataGen.getNextValue(aktProperty,
096: this .intro, back));
097: }
098:
099: }
100:
101: return back;
102: } catch (IllegalAccessException e) {
103: log.error("Canīt set the value to the NON TANSIENT field: "
104: + aktFieldName + "\n(Class: " + toCreate.getName()
105: + ") Perhaps itīs not marked as @Tansient!");
106: log.error("Canīt create the entity bean", e);
107: throw new RuntimeException("Canīt create the entity bean",
108: e);
109: } catch (IllegalArgumentException e) {
110: log.error("Canīt create the entity bean", e);
111: throw new RuntimeException("Canīt create the entity bean",
112: e);
113: } catch (SecurityException e) {
114: throw new RuntimeException(
115: "Insufficient access rights to create the entity bean ("
116: + this .toCreate.getName() + ")");
117: }
118:
119: }
120:
121: /**
122: * Check if the property is a autogenerated PK class The TABLE strategy
123: * indicates that the persistence provider should assign identifiers using
124: * an underlying database table to ensure uniqueness. The SEQUENCE and
125: * IDENTITY strategies specify the use of a database sequence or identity
126: * column, respectively. AUTO indicates that the persistence provider should
127: * pick an appropriate strategy for the particular database. Specifying NONE
128: * indicates that no primary key generation by the persistence provider
129: * should occur, and that the application will be responsible for assigning
130: * the primary key--> ONLY IN THIS CASE A VALUE IS GENERATED
131: *
132: * @param toCheck -
133: * the property to check
134: * @param intro -
135: * the introspector
136: *
137: * @return - false if not autogenerated
138: */
139: private boolean shouldPkValueBeGenerated(Property toCheck,
140: Introspector<T> intro) {
141: boolean back = true;
142: if (intro.getPkFields().contains(toCheck)) {
143: final PrimaryKeyInfo info = intro
144: .getPrimaryKeyInfo(toCheck);
145: if (info != null) {
146: // is a pk field
147: // Only pk wher he @GeneratedValue tag is present will not be
148: // generatet
149: if (info.getGenValue() != null) {
150: back = false;
151: }
152: }
153:
154: }
155: return back;
156: }
157:
158: private void setField(T instance, Property toSet, Object value)
159: throws IllegalAccessException {
160: toSet.setField(instance, value);
161: }
162:
163: }
|