|
Berkeley DB Java Edition version 3.0.12 |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
public interface Converter
Converts an old version of an object value to conform to the current class definition.
Conversions of simple types are generally simple. For example, a String
field that contains only integer values can be easily converted to
an int
field:
// The old class. Version 0 is implied.
//
@Persistent
class Address {
String zipCode;
...
}
// The new class. A new version number must be assigned.
//
@Persistent(version=1)
class Address {
int zipCode;
...
}
// The converter class.
//
class MyConverter1 implements Converter {
public void initialize(EntityModel model) {
// No initialization needed.
}
public Object convert(Object fromValue) {
return Integer.valueOf((String) fromValue);
}
}
// Create a field conversion mutation.
//
Conversion conversion = new Conversion(Address.class.getName(), 0,
"zipCode", new MyConverter1());
// Configure the conversion as described here
.
A converter may perform arbitrary transformations on an object. For example, a converter may transform a single String address field into four fields for street, city, state and zip code, or vice versa.
// The old class. Version 0 is implied.
//
@Entity
class Person {
String address;
...
}
// The new class. A new version number must be assigned.
//
@Entity(version=1)
class Person {
Address address;
...
}
// The new address class.
//
@Persistent
class Address {
String street;
String city;
String state;
int zipCode;
...
}
class MyConverter2 implements Converter {
private transient RawType newPersonType;
private transient RawType addressType;
public void initialize(EntityModel model) {
newPersonType = model.getRawType(Person.class.getName());
addressType = model.getRawType(Address.class.getName());
}
public Object convert(Object fromValue) {
// Get field value maps for old and new objects.
//
RawObject person = (RawObject) fromValue;
RawObject address = new RawObject(addressType, null, null);
Map<String,?> personValues = person.getValues();
Map<String,?> addressValues = address.getValues();
// Remove the old address and replace it with a new one.
//
String oldAddress = (String) personValues.remove("address");
addressValues.put("street", parseStreet(oldAddress));
addressValues.put("city", parseCity(oldAddress));
addressValues.put("state", parseState(oldAddress));
addressValues.put("zipCode", parseZipCode(oldAddress));
personValues.put("address", address);
return new RawObject(newPersonType, personValues, person.getSuper());
}
private String parseStreet(String oldAddress) { ... }
private String parseCity(String oldAddress) { ... }
private String parseState(String oldAddress) { ... }
private Integer parseZipCode(String oldAddress) { ... }
}
// Create a field conversion mutation.
//
Conversion conversion = new Conversion(Person.class.getName(), 0,
"address", new MyConverter2());
// Configure the conversion as described here
.
Note that when a converter returns a RawObject
, it must return
it with a RawType
that is current as defined by the current class
definitions. The proper types can be obtained from the EntityModel
in the converter's initialize
method.
A converter can handle changes to class hierarchies. For example, if a "name" field originally declared in class A is moved to its superclass B, a converter can move the field value accordingly:
// The old classes. Version 0 is implied.
//
@Persistent
class A extends B {
String name;
...
}
@Persistent
class B {
...
}
// The new classes. A new version number must be assigned.
//
@Persistent(version=1)
class A extends B {
...
}
@Persistent(version=1)
class B {
String name;
...
}
class MyConverter3 implements Converter {
private transient RawType newAType;
private transient RawType newBType;
public void initialize(EntityModel model) {
newAType = model.getRawType(A.class.getName());
newBType = model.getRawType(B.class.getName());
}
public Object convert(Object fromValue) {
RawObject oldA = (RawObject) fromValue;
RawObject oldB = oldA.getSuper();
Map<String,?> aValues = oldA.getValues();
Map<String,?> bValues = oldB.getValues();
bValues.put("name", aValues.remove("name"));
RawObject newB = new RawObject(newBType, bValues, oldB.getSuper());
RawObject newA = new RawObject(newAType, aValues, newB);
return newA;
}
}
// Create a class conversion mutation.
//
Conversion conversion = new Conversion(B.class.getName(), 0,
new MyConverter3());
// Configure the conversion as described here
.
A converter may return an instance of a different class entirely, as long as it conforms to current class definitions. For example, a field that is used to discriminate between two types of objects could be removed and replaced by two new subclasses:
// The old class. Version 0 is implied.
//
@Persistent
class Pet {
boolean isCatNotDog;
...
}
// The new classes. A new version number must be assigned to the Pet class.
//
@Persistent(version=1)
class Pet {
...
}
@Persistent
class Cat extends Pet {
...
}
@Persistent
class Dog extends Pet {
...
}
class MyConverter4 implements Converter {
private transient RawType newPetType;
private transient RawType dogType;
private transient RawType catType;
public void initialize(EntityModel model) {
newPetType = model.getRawType(Pet.class.getName());
dogType = model.getRawType(Dog.class.getName());
catType = model.getRawType(Cat.class.getName());
}
public Object convert(Object fromValue) {
RawObject pet = (RawObject) fromValue;
Map<String,?> petValues = pet.getValues();
Boolean isCat = (Boolean) petValues.remove("isCatNotDog");
RawObject newPet = new RawObject(newPetType, petValues,
pet.getSuper());
RawType newType = isCat.booleanValue() ? catType : dogType;
return new RawObject(newType, null, newPet);
}
}
// Create a class conversion mutation.
//
Conversion conversion = new Conversion(Pet.class.getName(), 0,
new MyConverter4());
// Configure the conversion as described here
.
The primary limitation is that a converter may access at most a single
entity instance at one time. Conversions involving multiple entities at
once may be performed using a ConversionStore
.
Method Summary | |
---|---|
Object |
convert(Object fromValue)
Converts an old version of an object value to conform to the current class definition. |
void |
initialize(EntityModel model)
Initializes the converter, allowing it to obtain raw type information from the entity model. |
Method Detail |
---|
void initialize(EntityModel model)
Object convert(Object fromValue)
If a RuntimeException
is thrown by this method, it will be
wrapped in a DatabaseException
and thrown to the original
caller. Similarly, a DatabaseException
will be thrown if the
object returned by this method does not conform to current class
definitions.
The class of the input and output object may be one of the simple
types or RawObject
, or an array of one of these types.
fromValue
- the object value being converted. The type of this
value is defined by the old class version that is being converted.
|
Berkeley DB Java Edition version 3.0.12 |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |