blob: eab0a08b49c6aa942cc28cad460843a7422666b1 [file] [log] [blame]
package org.apache.ode.bpel.obj;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.ode.bpel.obj.serde.jacksonhack.UniqueStringIdGenerator;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnore;
@JsonIdentityInfo(generator = UniqueStringIdGenerator.class, property = "@id")
public class ExtensibleImpl implements Extensible<Object>, Serializable{
public static final long serialVersionUID = -1L;
public static final int CURRENT_CLASS_VERSION = 1;
/** The wrapper wraps fields. Fields can be deleted, added or updated */
transient protected Map<String, Object> fieldContainer;
/** Version of this class*/
private static final String CLASSVERSION = "classVersion";
/** Original version before migration*/
private static final String ORIGINALVERSION = "originalVersion";
protected ExtensibleImpl() {
this(new LinkedHashMap<String, Object>());
}
protected ExtensibleImpl(Map<String, Object> container) {
fieldContainer = container;
int currentVersion = 0;
try {
currentVersion = (Integer) this.getClass().getField("CURRENT_CLASS_VERSION").get(this);
} catch (Exception e) {
// should never get here
e.printStackTrace();
}
setClassVersion(currentVersion);
setOriginalVersion(currentVersion); //if this is called by deserializer, original will be set later.
}
// @JsonAnyGetter
public Map<String, Object> getFieldContainer() {
return fieldContainer;
}
public void setFieldContainer(Map<String, Object> fieldContainer){
this.fieldContainer = fieldContainer;
}
// @JsonAnySetter
public void addField(String name, Object value) {
fieldContainer.put(name, value);
}
public Object getField(String name) {
return fieldContainer.get(name);
}
@Override
public Object delField(String fieldName) {
return fieldContainer.remove(fieldName);
}
@JsonIgnore
public int getClassVersion() {
Object o = fieldContainer.get(CLASSVERSION);
return o == null ? 0 : (Integer)o;
}
public void setClassVersion(int version) {
fieldContainer.put(CLASSVERSION, version);
}
@JsonIgnore
public int getOriginalVersion(){
Object o = fieldContainer.get(ORIGINALVERSION);
return o == null? -1 : (Integer)o;
}
public void setOriginalVersion(int version){
fieldContainer.put(ORIGINALVERSION, version);
}
private void writeObject(ObjectOutputStream oos) throws IOException{
oos.defaultWriteObject();
oos.writeInt(fieldContainer.size());
oos.writeObject(fieldContainer.getClass().getName());
for (String key : fieldContainer.keySet()){
oos.writeObject(key);
oos.writeObject(fieldContainer.get(key));
}
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
ois.defaultReadObject();
int size = ois.readInt();
String cls = (String)ois.readObject();
try {
fieldContainer = (Map<String, Object>)(Class.forName(cls).newInstance());
} catch (Exception e) {
//should never get here
e.printStackTrace();
}
for (int i = 0; i < size; i++){
String key = (String)ois.readObject();
Object value = ois.readObject();
fieldContainer.put(key, value);
}
}
@Override
public void upgrade2Newest(){
int version = getClassVersion();
int currentVersion = version;
try {
currentVersion = (Integer) this.getClass().getField("CURRENT_CLASS_VERSION").get(this);
} catch (Exception e) {
// should never get here
e.printStackTrace();
}
if (version == currentVersion) return;
if (version > currentVersion){
//should never get here.
throw new RuntimeException("class version is newer than newest!");
}
setClassVersion(currentVersion);
return;
}
}