Overview | Package | Class | Use | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

## net.sf.hibernate.tool.class2hbm
Class MapGenerator

    java.lang.Object
      |
      +--net.sf.hibernate.tool.class2hbm.MapGenerator

public class MapGenerator
extends Object

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.

Version:
  1.x
Author:
  e

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

### maxDepth

    protected int maxDepth

  how low will you go? the depth of component nesting followed

### niceKeys

    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)

### buf

    protected StringBuffer buf

  the XML we make; this buffer is shared by all string emitters created by this MapGenerator instance

### rClasses

    protected Hashtable rClasses

  a cache of seen reflected classes; Class -> ReflectedClass
  also necessary to avoid infinite regress

### abstractClasses

    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= use to add a class which will have its properties persisted only by its subclasses. Multiple --abstract entries can be used, but they must all come before any class names to be mapped. Classes listed by this option do not need to actually be abstract in the Java language sense.

  Note that the name abstract is somewhat misleading as abstract classes can otherwise be handled as a top level class by Hibernate.

### cycleBuster

    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

Constructor Detail

### MapGenerator

    public MapGenerator(String[] className,
                        ClassLoader loader)

  the only MapGenerator constructor

Parameters:
  `className` - an array of fully specified class names to add, or null

Method Detail

### main

    public static void main(String[] args)

### writeXML

    public void writeXML(Writer outputWriter)

### reset

    public void reset()

  start over

### addClass

    public void addClass(String className,
                         boolean verbose)

  add a class to the map and reflect upon it

  Parameters:
    `className` - a fully qualified class name in the class path
    `verbose` - squawk (as a comment into the final XML) if there are problems with this class

### setUID

    public void setUID(String uid)

  set the list of candidate UIDs to a single name

  Parameters:
    `uid` - the new candidate UID

### addUID

    public void addUID(String uid)

  add a new name to the front of the list of candidate UIDs

  Parameters:
    `uid` - the new candidate UID

### getRoots

    public ReflectedClass[] getRoots()

  used by gui

### nextName

    protected String nextName(String best,
                              Hashtable h)

  used to make unique table and column names

  Parameters:
    `best` - is the desired name
    `h` - is the uniqifying hashtable
  Returns:
    the unique name

### tableNameFor

    protected String tableNameFor(String name)

### columnNameFor

    protected String columnNameFor(String best)

### emitPrefix

    protected void emitPrefix(int n)

  adds spaces to the front of lines in buf for indentation

  Parameters:
    `n` - indentation level

### getXML

    public String getXML()

  after all classes are added

  Returns:
    the XML

### makeProperty

    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

  Parameters:
    `name` - the property name
    `cls` - the property class
  Returns:
    the new ReflectedProperty

### checkClass

    protected Class checkClass(Class clazz,
                               String className,
                               boolean v)

  verify that a class is hibernate-persistable

  Parameters:
    `clazz` - the class to ckeck
    `className` - the name of the class for error reporting
    `v` - verbose - should be true for supplied classes, but false for chased superclasses
  Returns:
    the class clazz if it is hibernate-persistable, else null

### checkComponent

    protected Class checkComponent(Class clazz,
                                   String className,
                                   boolean v)

  verify that a class is hibernate-persistable as a component

  Parameters:
    `clazz` - the class to ckeck
    `className` - the name of the class for error reporting
    `v` - verbose - should probably always be true, but can be false to ignore the property's status
  Returns:
    the class clazz if it is hibernate-persistable as a component, else null

### setClassLoader

    public void setClassLoader(ClassLoader classLoader)

Overview | Package | Class | Use | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD