package org.nutz.ioc.java;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import org.nutz.ioc.IocMaking;
import org.nutz.lang.Lang;
import org.nutz.lang.Mirror;

public class StaticFunctionNode extends ChainNode {

	private Method method;
	private ChainNode[] args;
	
	private Field field;

	public StaticFunctionNode(String className, String name, ChainNode[] args) {
		try {
			Mirror<?> mirror = Mirror.me(Lang.loadClass(className));
			if (null == args || args.length == 0) {
				try {
					method = mirror.getGetter(name);
				}
				catch (NoSuchMethodException e) {
					try {
						field = mirror.getField(name);
						if (!Modifier.isStatic(field.getModifiers()))
							throw Lang.makeThrow("Field '%s' of '%s' must be static", name, mirror);
						return;
					} catch (NoSuchFieldException e1) {
						throw Lang.makeThrow("Method or field '%s' don't find in '%s'", name, mirror);
					}
				}
			} else {
				Method[] ms = mirror.findMethods(name, args.length);
				if (0 == ms.length)
					throw Lang.makeThrow("Method '%s' don't find in '%s'", name, mirror);
				this.args = args;
				this.method = ms[0];
			}
			if (!Modifier.isStatic(method.getModifiers()))
				throw Lang.makeThrow("Method '%s' of '%s' must be static", name, mirror);
		}
		catch (ClassNotFoundException e) {
			throw Lang.wrapThrow(e);
		}
	}

	protected Object getValue(IocMaking ing, Object obj) throws Exception {
		if (method != null){
			if (null == args || args.length == 0)
				return method.invoke(obj);
			Object[] fas = new Object[args.length];
			for (int i = 0; i < args.length; i++)
				fas[i] = args[i].getValue(ing, null);
			return method.invoke(obj, fas);
		}
		return field.get(null);
	}

	protected String asString() {
		StringBuilder sb = new StringBuilder();
		if (null != args && args.length > 0) {
			sb.append(args[0].toString());
			for (int i = 1; i < args.length; i++)
				sb.append(", ").append(args[i].toString());
		}
		if (method != null)
			return String.format(	"%s.%s(%s)",
								method.getDeclaringClass().getName(),
								method.getName(),
								sb);
		else
			return String.format(	"%s.%s(%s)",
					field.getDeclaringClass().getName(),
					field.getName(),
					sb);
	}

}

@@ -220,16 +220,125 @@
 ror;%0D%0A%0D%0A
+/**%0D%0A * %E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95%E6%88%96%E9%9D%99%E6%80%81%E5%AD%97%E6%AE%B5%E8%8A%82%E7%82%B9%0D%0A * @author zozoh(zozohtnt@gmail.com)%0D%0A * @author wendal(wendal1985@gmail.com)%0D%0A *%0D%0A */%0D%0A
 public c
@@ -704,24 +704,158 @@
 ter(name);%0D%0A
+%09%09%09%09%09if (!Modifier.isStatic(method.getModifiers()))%0D%0A%09%09%09%09%09%09throw Lang.makeThrow(%22Method '%25s' of '%25s' must be static%22, name, mirror);%0D%0A
 %09%09%09%09%7D%0D%0A%09%09%09%09c
@@ -1311,17 +1311,17 @@
 %09%09if (0 
-=
+!
 = ms.len
@@ -1335,111 +1335,104 @@
 %09%09%09%09
-throw Lang.makeThrow(%22Method '%25s' don't find in '%25s'%22, name, mirror);
+for (int i = 0; i %3C ms.length; i++)
 %0D%0A%09%09%09%09
+%09
-this.args = args;
+%09if(Modifier.isStatic(ms%5Bi%5D.getModifiers()))
 %0D%0A%09%09%09%09
-this.
+%09%09%09%09
 meth
@@ -1443,70 +1443,39 @@
  ms%5B
-0
+i
 %5D;%0D%0A%09%09%09
-%7D%0D%0A%09%09%09if (!Modifier.isStatic(method.getModifiers())
+%09if (method == null
 )%0D%0A
+%09
 %09%09%09%09
@@ -1512,47 +1512,92 @@
 %25s' 
-of '%25s' must be static%22, name, mirror);
+don't find in '%25s' or it is NOT static%22, name, mirror);%0D%0A%09%09%09%09this.args = args;%0D%0A%09%09%09%7D
 %0D%0A%09%09

优化StaticFunctionNode获取正确方法的可能性.