package org.nutz.el.opt.object;

import java.util.List;
import java.util.Map;

import org.nutz.el.ElException;
import org.nutz.el.Operator;
import org.nutz.el.obj.Elobj;
import org.nutz.el.obj.FieldObj;
import org.nutz.el.opt.RunMethod;
import org.nutz.el.opt.TwoTernary;
import org.nutz.lang.InvokingException;
import org.nutz.lang.Lang;
import org.nutz.lang.Mirror;
import org.nutz.lang.util.Context;

/**
 * 访问符:'.'
 * @author juqkai(juqkai@gmail.com)
 *
 */
public class AccessOpt extends TwoTernary implements RunMethod{
    public int fetchPriority() {
        return 1;
    }

    public Object calculate() {
        //如果直接调用计算方法,那基本上就是直接调用属性了吧...我也不知道^^
        Object obj = fetchVar();
        if (obj == null) {
            throw new ElException("obj is NULL, can't call obj." + right);
        }
        if(obj instanceof Map){
            Map<?,?> om = (Map<?, ?>) obj;
            if(om.containsKey(right.toString())){
                return om.get(right.toString());
            }
        }
        if (obj instanceof Context) {
            Context sc = (Context) obj;
            if (sc.has(right.toString())) {
                return sc.get(right.toString());
            }
        }
        
        Mirror<?> me = Mirror.me(obj);
        return me.getValue(obj, right.toString());
    }
    
    public Object run(List<Object> param) {
        Object obj = fetchVar();
        Mirror<?> me = null;
        if (obj == null)
            throw new NullPointerException();
        if (obj instanceof Class) {
            //也许是个静态方法
            me = Mirror.me(obj);
            try {
                return me.invoke(obj, right.toString(), param.toArray());
            } catch (InvokingException e) {
                throw e;
            } catch (Throwable e) {
                if (Lang.unwrapThrow(e) instanceof NoSuchMethodException) {
                    me = Mirror.me(obj.getClass().getClass());
                    return me.invoke(obj, right.toString(), param.toArray());
                }
                throw Lang.wrapThrow(e);
            }
        }
        else {
            me = Mirror.me(obj);
            return me.invoke(obj, right.toString(), param.toArray());
        }
    }
    
    /**
     * 取得变得的值
     */
    public Object fetchVar(){
        if(left instanceof AccessOpt){
            return ((AccessOpt)left).fetchVar();
        }
        if(left instanceof Operator){
            return ((Operator) left).calculate();
        }
        if(left instanceof Elobj){
            Object obj = ((Elobj) left).fetchVal();
            if(right instanceof FieldObj){
                return Mirror.me(obj).getValue(obj, ((Elobj)right).getVal());
            }
            return obj;
        }
        return left;
    }

    public String fetchSelf() {
        return ".";
    }
}

@@ -167,41 +167,8 @@
 bj;%0A
-import org.nutz.el.obj.FieldObj;%0A
 impo
@@ -2076,32 +2076,53 @@
 Mirror.me(obj);%0A
+            try%7B%0A    
             retu
@@ -2187,178 +2187,187 @@
     
-%7D%0A
     %7D
-%0A    %0A    /**%0A     * %E5%8F%96%E5%BE%97%E5%8F%98%E5%BE%97%E7%9A%84%E5%80%BC%0A
+catch (Exception e)%7B%0A      
      
-*/%0A
     
-public Object fetchVar()%7B%0A        if(left instanceof AccessOpt)%7B%0A            return ((AccessOpt)left).fetchVar();%0A        %7D
+ return me.getValue(obj, right.toString());%0A            %7D%0A        %7D%0A    %7D%0A    %0A    /**%0A     * %E5%8F%96%E5%BE%97%E5%8F%98%E5%BE%97%E7%9A%84%E5%80%BC%0A     */%0A    public Object fetchVar()%7B
 %0A   
@@ -2508,28 +2508,22 @@
         
-Object obj =
+return
  ((Elobj
@@ -2546,167 +2546,8 @@
 ();%0A
-            if(right instanceof FieldObj)%7B%0A                return Mirror.me(obj).getValue(obj, ((Elobj)right).getVal());%0A            %7D%0A            return obj;%0A
     

fix #411