package org.nutz.lang;

import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.nutz.castor.Castors;
import org.nutz.lang.inject.Injecting;

public class Lang2 {
    public static Object inject(Object model, Type type){
        Mirror<?> me = Mirror.me(type);
        if(List.class.isAssignableFrom(me.getType())){
            return injectList(model, me);
        } else if(Map.class.isAssignableFrom(me.getType())){
            return injectMap(model, me);
//        } else if(me.is(Set.class)){
//            return injectSet(me);
        } else if(me.getType().isArray()){
            return injectArray(model, me);
        }
        return injectObj(model, me);
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private static Object injectArray(Object model, Mirror<?> me){
        Class<?> clazz = me.getType().getComponentType();
        List list = (List) model;
        List vals = new ArrayList();
        for(Object obj : list){
            if(isLeaf(obj)){
                vals.add(Castors.me().castTo(obj, clazz));
                continue;
            }
            vals.add(inject(obj, clazz));
        }
        Object obj = Array.newInstance(clazz, vals.size());
        for(int i = 0; i < vals.size(); i++){
            Array.set(obj, i, vals.get(i));
        }
        return obj;
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private static Object injectMap(Object model, Mirror<?> me){
        Map re = null;
        if(me.isInterface()){
            re = new HashMap();
        } else {
            re = (Map) me.born();
        }
        
        Map map = (Map) model;
        if(me.getGenericsTypes() == null){
            re.putAll(map);
            return re;
        }
        
        Type type = me.getGenericsType(1);
        for(Object key : map.keySet()){
            Object val = map.get(key);
            if(isLeaf(val)){
                re.put(key, Castors.me().castTo(val, Lang.getTypeClass(type)));
                continue;
            }
            re.put(key, inject(val, type));
        }
        return re;
    }
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private static Object injectList(Object model, Mirror<?> me){
        List re = null;
        if(me.isInterface()){
            re = new ArrayList();
        } else {
            re = (List) me.born();
        }
        if(me.getGenericsTypes() == null){
            return model;
        }
        Type type = me.getGenericsType(0);
        for(Object obj : (List) model){
            if(isLeaf(obj)){
                re.add(Castors.me().castTo(obj, Lang.getTypeClass(type)));
                continue;
            }
            re.add(inject(obj, type));
        }
        return re;
    }
    
    @SuppressWarnings("unchecked")
    private static Object injectObj(Object model, Mirror<?> me) {
        Object obj = me.born();
        Map<String, ?> map = (Map<String, ?>) model;
        for(String key : map.keySet()){
            try{
                Object val = map.get(key);
                Injecting in = me.getInjecting(key);
                if(isLeaf(val)){
                    Type t = Lang.getFieldType(me, key);
                    in.inject(obj, Castors.me().castTo(val, Lang.getTypeClass(t)));
                    continue;
                }
                in.inject(obj, inject(val, Lang.getFieldType(me, key)));
            } catch (Exception e){
                continue;
            }
            
        }
        return obj;
    }
    
    private static boolean isLeaf(Object obj){
        if(obj instanceof Map){
            return false;
        }
        if(obj instanceof List){
            return false;
        }
        return true;
    }
}

@@ -49,16 +49,48 @@
 .Array;%0A
+import java.lang.reflect.Field;%0A
 import j
@@ -244,16 +244,61 @@
 astors;%0A
+import org.nutz.json.entity.JsonEntityField;%0A
 import o
@@ -3036,17 +3036,16 @@
 r%3C?%3E me)
- 
 %7B%0A      
@@ -3139,102 +3139,237 @@
 for(
-String key : map.keySet())%7B%0A            try%7B%0A                Object val = map.get(key);%0A      
+Field field : me.getFields())%7B%0A            JsonEntityField jef = JsonEntityField.eval(me, field);%0A            Object val = map.get(jef.getName());%0A            if(val == null)%7B%0A                continue;%0A            %7D%0A            %0A
     
@@ -3374,16 +3374,18 @@
         
+  
 Injectin
@@ -3407,26 +3407,34 @@
 jecting(
-key);%0A    
+field.getName());%0A
         
@@ -3466,28 +3466,24 @@
             
-    
 Type t = Lan
@@ -3501,26 +3501,24 @@
 ype(me, 
-key);%0A    
+field);%0A
         
@@ -3552,35 +3552,57 @@
 ors.me().castTo(
+jef.createValue(obj, 
 val
+)
 , Lang.getTypeCl
@@ -3619,36 +3619,32 @@
                 
-    
 continue;%0A      
@@ -3645,34 +3645,26 @@
             
-   
- 
 %7D%0A
-    
             
@@ -3677,16 +3677,37 @@
 ect(obj,
+ jef.createValue(obj,
  inject(
@@ -3737,90 +3737,18 @@
 me, 
-key)));%0A            %7D catch (Exception e)%7B%0A                continue;%0A            %7D
+field))));
 %0A   

添加对@JsonField的支持