|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectnet.sf.hibernate.tool.class2hbm.MapGenerator
public class MapGenerator
MapGenerator provides a mechanism to produce a Hibernate XML OR-Mapping from compiled classes. It does this using Java reflection to find properties to be persisted in the classes, and using the types of the properties to further guide the reflection.
The usual way to use MapGenerator is to place your compiled
classes on the classpath, and start Java in the MapGenerator
static main() method. As arguments you can either supply all of the
classes to be processed, or the single argument --interact
which will provide an interactive prompt/response console. Using this
mode you can set the UID property name for each class using the
uid=XXX
command where XXX is the UID property name. Other
command alternatives are simply a fully qualified class name, or the
command done
which emits the XML and terminates.
MapGenerator will reject classes that are not hibernate perisitable. To be hibernate persistable a class must not be a primitive type, an array, an interface, or a nested class, and it must have a default (zero argument) constructor.
MapGenerator will climb the superclass chain of all added classes attempting to add as many hibernate perisitable superclasses as possible to the same database table. The search stops as soon as a property is found that has a name appearing on the list of candidate UID names, and has type String, Long, or long.
Properties are discovered when there are two methods in the class,
a setter and a getter, where the type of the setter's single argument is
the same as the return type of the zero argument getter, and the setter
returns void
. Furthermore, the setter's name must start with
the string "set" and either the getter's name starts with "get" or the
getter's name starts with "is" and the type of the property is
boolean
. In either case, the remainder of their names must
match. This matching portion is the name of the property, except that the
initial character of the property name is made lower case if the second
letter is lower case.
The rules for determing the database type of each property are as
follows. If the Java type is Hibernate.basic(), then the property is a
simple column of that type. For hibernate.type.Type custom types and
PersistentEnum a simple column is used as well. If the property type
is an array, then a Hibernate array is used, and MapGenerator
attempts to reflect on the array element type. If the property has
type java.util.List, java.util.Map, or java.util.Set, then the
corresponding Hibernate types are used, but MapGenerator cannot
further process the insides of these types. If the property's type is
any other class, MapGenerator defers the decision on the database
representation until all classes have been processed (i.e., until
done
is typed at the interactive prompt. At this point, if
the class was discovered through the superclass search described above,
then the property is an association (many-to-one). If the class has any
properties, then it is a component. Otherwise it is serializable, or
not persistable.
Field Summary | |
---|---|
protected Hashtable |
abstractClasses
A list of class names which are treated as 'abstract' in that they are not allowed to be root classes. |
protected StringBuffer |
buf
the XML we make; this buffer is shared by all string emitters created by this MapGenerator instance |
protected Hashtable |
cycleBuster
a cache of emitted components for the current property; Class -> Integer also necessary to avoid infinite regress by tracking the depth of data recursion |
protected int |
maxDepth
how low will you go? the depth of component nesting followed |
protected String[] |
niceKeys
candidate UID property names; presence of one of these with a supported type (String, Long, long) will stop the reflect code from chasing the superclass chain any further except to find additional properties (not classes) |
protected Hashtable |
rClasses
a cache of seen reflected classes; Class -> ReflectedClass also necessary to avoid infinite regress |
Constructor Summary | |
---|---|
MapGenerator(String[] className,
ClassLoader loader)
the only MapGenerator constructor |
Method Summary | |
---|---|
void |
addClass(String className,
boolean verbose)
add a class to the map and reflect upon it |
void |
addUID(String uid)
add a new name to the front of the list of candidate UIDs |
protected Class |
checkClass(Class clazz,
String className,
boolean v)
verify that a class is hibernate-persistable |
protected Class |
checkComponent(Class clazz,
String className,
boolean v)
verify that a class is hibernate-persistable as a component |
protected String |
columnNameFor(String best)
|
protected void |
emitPrefix(int n)
adds spaces to the front of lines in buf for indentation |
ReflectedClass[] |
getRoots()
used by gui |
String |
getXML()
after all classes are added |
static void |
main(String[] args)
|
protected ReflectedProperty |
makeProperty(String name,
Class cls)
this is the factory to make a ReflectedProperty using this factory will insure that the property types are inferred consistently |
protected String |
nextName(String best,
Hashtable h)
used to make unique table and column names |
void |
reset()
start over |
void |
setClassLoader(ClassLoader classLoader)
|
void |
setUID(String uid)
set the list of candidate UIDs to a single name |
protected String |
tableNameFor(String name)
|
void |
writeXML(Writer outputWriter)
|
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
protected int maxDepth
protected String[] niceKeys
protected StringBuffer buf
protected Hashtable rClasses
protected Hashtable abstractClasses
A list of class names which are treated as 'abstract' in that they are not
allowed to be root classes. Classes added to this list will have their
properties (and their superclass properties) mapped to any subclasses
extending the base classes listed here.
Documentation notes:
--abstract= Note that the name abstract is somewhat misleading as abstract classes
can otherwise be handled as a top level class by Hibernate.
protected Hashtable cycleBuster
Constructor Detail |
---|
public MapGenerator(String[] className, ClassLoader loader)
className
- an array of fully specified class names to add, or nullMethod Detail |
---|
public static void main(String[] args)
public void writeXML(Writer outputWriter)
public void reset()
public void addClass(String className, boolean verbose)
className
- a fully qualified class name in the class pathverbose
- squawk (as a comment into the final XML) if
there are problems with this classpublic void setUID(String uid)
uid
- the new candidate UIDpublic void addUID(String uid)
uid
- the new candidate UIDpublic ReflectedClass[] getRoots()
protected String nextName(String best, Hashtable h)
best
- is the desired nameh
- is the uniqifying hashtable
protected String tableNameFor(String name)
protected String columnNameFor(String best)
protected void emitPrefix(int n)
n
- indentation levelpublic String getXML()
protected ReflectedProperty makeProperty(String name, Class cls)
name
- the property namecls
- the property class
protected Class checkClass(Class clazz, String className, boolean v)
clazz
- the class to ckeckclassName
- the name of the class for error reportingv
- verbose - should be true for supplied classes,
but false for chased superclasses
protected Class checkComponent(Class clazz, String className, boolean v)
clazz
- the class to ckeckclassName
- the name of the class for error reportingv
- verbose - should probably always be true,
but can be false to ignore the property's status
public void setClassLoader(ClassLoader classLoader)
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |