package jfun.yan;
import java.beans.IntrospectionException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import jfun.util.beans.BeanType;
import jfun.yan.util.MemberPredicate;
import jfun.yan.util.Utils;
/**
* This implementation only attempts to inject a property when this property
* satisfies a MemberPredicate object.
* <p>
* @author Ben Yu
* Dec 31, 2005 12:51:53 PM
*/
public class FilteredPropertiesInjector implements PropertiesInjector {
/*The meta information of the bean. null if unknown*/
private final BeanType btype;
private final MemberPredicate filter;
private final Set propnames;
/**
* Create an instance of FilteredPropertiesInjector.
* If type is null, dynamic binding will be used.
* @param type the bean class.
* @param pred the MemberPredicate object.
* @return the instance.
* @throws IntrospectionException
*/
public static PropertiesInjector instance(Class type,
MemberPredicate pred)
throws IntrospectionException{
final BeanType bt = Utils.toBeanType(type);
return new FilteredPropertiesInjector(bt, pred);
}
/**
* Create an instance of FilteredPropertiesInjector.
* @param btype the bean type. If null, dynamic binding is used.
* @param pred the MemberPredicate object to filter the properties.
*/
public FilteredPropertiesInjector(final BeanType btype,
final MemberPredicate pred){
this.btype = btype;
this.filter = pred;
this.propnames = btype==null?null:getPropertyNames(btype, pred);
}
private BeanType obtainBeanType(Class type){
//dynamically get the bean type.
//if the bean type is not early bound,
//use the object type to dynamically create it.
if(btype!=null) return btype;
else{
return jfun.yan.util.Utils.toBeanType(type);
}
}
public void injectProperties(Object obj, Dependency dep){
if(obj==null){
throw new NullBeanObjectException("null component");
}
//dynamically resolve bean type and properties if necessary.
final Class objtype = obj.getClass();
final BeanType btype = obtainBeanType(objtype);
final Set props = getPropertyNames(btype);
Utils.injectProperties(btype, obj, props, dep);
}
public void verifyProperties(Class type, Dependency dep){
//dynamically resolve bean type and properties if necessary.
//the type cannot be null now.
final BeanType btype = obtainBeanType(type);
final Set props = getPropertyNames(btype);
Utils.verifyProperties(btype, props, dep);
}
public String toString(){
return "bean";
}
private Set getPropertyNames(BeanType bt){
return propnames==null?getPropertyNames(bt, this.filter):propnames;
}
private static Set getPropertyNames(BeanType bt, MemberPredicate pred){
final HashSet props = new HashSet();
for(Iterator it = bt.getPropertyNames().iterator(); it.hasNext();){
final String name = (String)it.next();
Method mtd = bt.getWriter(name);
if(mtd==null)
mtd = bt.getIndexedWriter(name);
if(mtd!=null){
if(pred.isMember(name, mtd)){
props.add(name);
}
}
}
return props;
}
}