| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is possible with BeanKeeper to create so-called dynamic objects, which are basically instances of runtime
defined classes. To mark an object as "dynamic", it's class must implement the DynamicObject interface:
public interface DynamicObject extends Map
{
String getPersistenceDynamicName();
void setPersistenceDynamicName(String dynamicName);
}
|
And additionally it must offer the following static method:
public static Map getPersistenceAttributeTypes(Class c, String dynamicName); |
There are two aspects to dynamic objects. First, they define which attributes the object holds. These attributes
are stored in the object through the Map interface. The getPersistenceAttributeTypes() method
returns a mapping between attribute names and their types (Integer, String, Date, beans, etc.). The
attributes defined in this map are stored in the database, the same way they would be stored, if they were
"static" member attributes of the class. Additionally all inherited or local member attributes are
also stored, like in normal case. This map may change runtime, in which case the library will adjust
the database table accordingly: if an attribute is removed, the corresponding table column will be dropped, and
if an attribute is added, a column is added to the table. When the object is loaded, the library will set
all attributes in the database through the put() method of the Map interface.
Implementation note: You can easily subclass the HashMap class to fulfill the Map interface specification,
because the library disregards all super- or sub-classes of dynamic objects. This also means these can not be
subclassed.
The second aspect is, that they also can define their "classname". Why would they want that? Because each different class is treated as a separate entity. They can be referred to in query statements with their dynamic name, they have their own table with their own schema. Suppose, you are building an application to store a user's all acounts to all systems.
The following code demonstrates all aspects of dynamic objects:
public class Vehicle extends HashMap implements DynamicObject
{
private transient String persistenceDynamicName;
public int wheelCount;
public int doorCount;
public String licensePlate;
public static Map getPersistenceAttributeTypes(Class c, String dynamicName)
{
...get application specific types, for example
dynamicName: Car
dynamicName: Truck
etc., and return specific attributes for them...
}
..setter getters...
}
|
Let's consider an application, in which the programmer does not know which types of Vehicles will be kept in the database, but he makes some userinterface on which the user can create new vehicle types, and can specify attributes for that kind of vehicle. All these specific "dynamic" Vehicle types will be defined runtime, and all will subclass the Vehicle class. The dynamic name can be considered the classname, for example: Car, Truck, Tank, etc.
So all dynamic Vehicle types are maintained in the application's database. To create an instance of "Car", which is a dynamic class, one must execute the following code:
Vehicle car = new Vehicle();
car.setPersistenceDynamicName("Car");
|
To set Car specific attributes, one must use the Map interface. When the object
is read back from the database, BeanKeeper will set the dynamic name through the
setPersistenceDynamicName method, this is why the class should store it's dynamic
name in a transient attribute.
Additionally the getPersistenceAttributeTypes method generates a Map of
attribute name-type pairs from the application's own data about that dynamic type. This
data is used by BeanKeeper to determine which attributes are to be saved from the Map
(rememeber, the object implements Map), and which are to be loaded when selected.
Using this mechanism dynamic classes can be created runtime, but the type's data must be managed by the application itself.
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Robert Brautigam on November, 21 2009 using texi2html 1.78.