package jfun.yan.xml.nuts;
import java.beans.PropertyEditor;
import jfun.yan.Container;
import jfun.yan.Creator;
import jfun.yan.TypeMismatchException;
import jfun.yan.containers.DefaultContainer;
import jfun.yan.util.ReflectionUtil;
import jfun.yan.util.deserializer.Deserializer;
import jfun.yan.util.deserializer.PropertyEditorDeserializer;
import jfun.yan.xml.ConfigurationException;
import jfun.yan.xml.nut.Nut;
/**
* For example,
* <pre>
* <deserializer target-type="SoapVersion" class="MySoapVersionPropertyEditor"/>
* </pre>
* <br>
* or,
* <pre>
* <deserializer target-type="SoapVersion" deserializer="$mydeserializer"/>
* </pre>
* or,
* <pre>
* <deserializer target-type="SoapVersion">
* <bean .../>
* </deserializer>
* </pre>
* <p>
* Default value for "overriding" and "mandatory" is false.
* </p>
* <p>
* @author Ben Yu
* Feb 1, 2006 1:29:23 AM
*/
public class DeserializerNut extends Nut {
private Class target_type;
private Deserializer deserializer;
private boolean overriding = false;
private boolean mandatory = false;
private Class clazz;
public boolean isMandatory() {
return mandatory;
}
public void setMandatory(boolean mandatory) {
this.mandatory = mandatory;
}
public boolean isOverriding() {
return overriding;
}
public void setOverriding(boolean overriding) {
this.overriding = overriding;
}
public void setClass(Class clazz)
throws IllegalAccessException, InstantiationException{
checkDuplicate("deserializer", this.deserializer);
this.clazz = clazz;
this.deserializer = getStatelessDeserializer(clazz);
}
public Class getTargetType() {
return target_type;
}
public void setTarget_type(Class target_type) {
this.target_type = target_type;
}
public void eval()
throws IllegalAccessException, InstantiationException{
checkMandatory("target-type", target_type);
checkMandatory("class or deserializer", deserializer);
this.getNutEnvironment()
.registerDeserializer(target_type, deserializer,
overriding, mandatory);
}
public void setDeserializer(Object ds) {
if(ds==null)
raise("cannot set deserializer to null");
checkDuplicate("class", this.clazz);
delegateTo(toDeserializer(ds));
}
public void add(Object sub){
checkDuplicate("class", this.clazz);
checkDuplicate("deserializer", this.deserializer);
delegateTo(toDeserializer(sub));
}
private Deserializer getStatelessDeserializer(Class type)
throws IllegalAccessException, InstantiationException{
if(Deserializer.class.isAssignableFrom(type)){
return (Deserializer)type.newInstance();
}
else if(PropertyEditor.class.isAssignableFrom(type)){
return new PropertyEditorDeserializer(type);
}
else{
throw mismatchType(type);
}
}
protected void delegateTo(Deserializer deserializer){
this.deserializer = deserializer;
}
private Deserializer toDeserializer(Object obj){
if(obj instanceof Deserializer){
return (Deserializer)obj;
}
else if(obj instanceof Creator){
return instantiateDeserializer((Creator)obj);
}
else{
return (Deserializer)this.convert(Deserializer.class, obj);
}
}
private ConfigurationException mismatchType(Class type){
return raise(new TypeMismatchException(Deserializer.class, type));
}
private ConfigurationException mismatch(Object obj){
return mismatchType(obj==null?null:obj.getClass());
}
private Deserializer instantiateDeserializer(Creator c){
final Class type = c.getType();
if(type!=null && !ReflectionUtil.isCompatible(Deserializer.class, type)){
throw mismatchType(type);
}
final Object r = empty.instantiateComponent(c);
if(r instanceof Deserializer){
return (Deserializer)r;
}
else{
throw mismatch(r);
}
}
private static Container empty = new DefaultContainer();
}