package jfun.yan.xml.nuts;
import java.lang.reflect.Method;
import jfun.yan.Component;
import jfun.yan.Components;
import jfun.yan.Functions;
import jfun.yan.util.ReflectionUtil;
/**
* Nut class for <method> tag.
* <p>
* @author Ben Yu
* Nov 9, 2005 11:42:15 PM
*/
public class MethodNut extends ArgumentsAndPropertiesNut
implements LifecycleDeclaration{
private Class hostclass;
private Component cc;
private String method_name;
private boolean private_access = false;
public void add(Component cn){
checkDuplicate("component", cc);
this.cc = cn;
}
/*
private void targetComponentElement(ComponentNut cn)
throws Exception{
checkDuplicate("component", cc);
this.cc = cn.eval();
}
public void addBean(BeanNut bn)
throws Exception{
targetComponentElement(bn);
}
public void addCtor(ConstructorNut cn)
throws Exception{
targetComponentElement(cn);
}
public void addMethod(MethodNut mn)
throws Exception{
targetComponentElement(mn);
}
public void addField(FieldNut fn)
throws Exception{
targetComponentElement(fn);
}
public void addGetter(GetterNut gn)
throws Exception{
targetComponentElement(gn);
}*/
public boolean isPrivate_access() {
return private_access;
}
public void setPrivate_access(boolean private_access) {
this.private_access = private_access;
}
public void setClass(Class type){
//checkDuplicate("component", cc);
this.hostclass = type;
}
public void setComponent(Component c){
//checkDuplicate("class", hostclass);
this.cc = c;
}
public void setName(String name){
method_name = name.trim();
}
public String getName(){
return method_name;
}
private String initializer;
private String starter;
private String stopper;
private String disposer;
public String getInitializer() {
return initializer;
}
public void setInitializer(String initializer) {
this.initializer = initializer;
}
public String getStarter() {
return starter;
}
public void setStarter(String starter) {
this.starter = starter;
}
public String getStopper() {
return stopper;
}
public void setStopper(String stopper) {
this.stopper = stopper;
}
public String getDisposer() {
return disposer;
}
public void setDisposer(String disposer) {
this.disposer = disposer;
}
private Method lookupMethod(Class[] param_types){
if(param_types==null){
final int argcount = getMaxArgsCount();
if(argcount <0){
if(this.getParameterAutowireMode()==null){
return ReflectionUtil.getMethod(hostclass, method_name,
null, private_access);
}
else return ReflectionUtil.getMethod(hostclass, method_name,
private_access);
}
else{
return ReflectionUtil.getMethod(hostclass, method_name,
argcount, private_access);
}
}
else{
return ReflectionUtil.getMethod(hostclass, method_name,
param_types, private_access);
}
}
private Component lookupComponent(Class[] param_types){
if(param_types==null){
final int argcount = getMaxArgsCount();
if(argcount<0){
return cc.method(method_name,
private_access);
}
else{
return Components.bindMethod(cc, method_name,
argcount, private_access);
}
}
else{
return cc.method(method_name, param_types, private_access);
}
}
private Method lookupStaticMethod(Class[] param_types){
if(param_types==null){
final int argcount = getMaxArgsCount();
if(argcount < 0){
return ReflectionUtil.getStaticMethod(hostclass, method_name,
private_access);
}
else{
return ReflectionUtil.getStaticMethod(hostclass, method_name,
argcount, private_access);
}
}
else{
return ReflectionUtil.getMethod(hostclass, method_name, param_types,
private_access);
}
}
/**
* Evaluate the Component without applying life cycle.
* Subclass can call this method and apply customized lifecycle.
*/
protected Component evaluateNoLifecycle(){
checkMandatory("class", hostclass, "component", cc);
checkMandatory("name", method_name);
Component result;
final Class[] param_types = getParameterTypes();
if(cc != null){
if(hostclass != null){
final Method mtd = lookupMethod(param_types);
result = cc.method(mtd);
}
else{
result = lookupComponent(param_types);
/*
result = param_types==null?
Components.bindMethod(cc, method_name,
getMaxArgsCount(), private_access)
:cc.method(method_name, param_types, private_access);
*/
}
}
else{
final Method mtd = lookupStaticMethod(param_types);
result = Components.fun(Functions.static_method(mtd));
/*
if(param_types==null)
setParams(mtd.getParameterTypes());*/
}
return decorateComponent(result);
//return applyArguments(result);
}
public Component eval(){
return Util.wrapLifecycle(evaluateNoLifecycle(), this);
}
}