Package org.nutz.ioc

Source Code of org.nutz.ioc.IocLoading

package org.nutz.ioc;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.nutz.castor.Castors;
import org.nutz.castor.FailToCastObjectException;
import org.nutz.ioc.meta.IocEventSet;
import org.nutz.ioc.meta.IocField;
import org.nutz.ioc.meta.IocObject;
import org.nutz.ioc.meta.IocValue;
import org.nutz.json.Json;
import org.nutz.lang.Each;
import org.nutz.lang.Lang;
import org.nutz.lang.Mirror;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;


import static org.nutz.ioc.Iocs.*;

public class IocLoading {

  private static final Log log = Logs.get();
 
  private Set<String> supportedTypes;

  public IocLoading(Set<String> supportedTypes) {
    this.supportedTypes = supportedTypes;
  }

  private static ObjectLoadException E(Throwable e, String fmt, Object... args) {
    return new ObjectLoadException(String.format(fmt, args), e);
  }

  @SuppressWarnings("unchecked")
  public IocObject map2iobj(Map<String, Object> map) throws ObjectLoadException {
    final IocObject iobj = new IocObject();
    if (!isIocObject(map)) {
      for (Entry<String, Object> en : map.entrySet()) {
        IocField ifld = new IocField();
        ifld.setName(en.getKey());
        ifld.setValue(object2value(en.getValue()));
        iobj.addField(ifld);
      }
      if(log.isWarnEnabled()) //TODO 移除这种兼容性
        log.warn("Using *Declared* ioc-define (without type or events)!!! Pls use Standard Ioc-Define!!" +
            " Bean will define as:\n"+Json.toJson(iobj));
    } else {
      Object v = map.get("type");
      // type
      try {
        String typeName = (String) v;
        if (!Strings.isBlank(typeName)) {
          iobj.setType(Lang.loadClass(typeName));
        }
      }
      catch (Exception e) {
        throw E(e, "Wrong type name: '%s'", v);
      }
      // singleton
      try {
        v = map.get("singleton");
        if (null != v)
          iobj.setSingleton(Castors.me().castTo(v, boolean.class));
      }
      catch (FailToCastObjectException e) {
        throw E(e, "Wrong singleton: '%s'", v);
      }
      // scope
      v = map.get("scope");
      if (null != v)
        iobj.setScope(v.toString());
      // events
      try {
        v = map.get("events");
        if (null != v) {
          IocEventSet ies = Lang.map2Object((Map<?, ?>) v, IocEventSet.class);
          iobj.setEvents(ies);
        }
      }
      catch (Exception e) {
        throw E(e, "Wrong events: '%s'", v);
      }
      // args
      try {
        v = map.get("args");
        if (null != v) {
          Lang.each(v, new Each<Object>() {
            public void invoke(int i, Object ele, int length) {
              iobj.addArg(object2value(ele));
            }
          });
        }
      }
      catch (Exception e) {
        throw E(e, "Wrong args: '%s'", v);
      }
      // fields
      try {
        v = map.get("fields");
        if (null != v) {
          Map<String, Object> fields = (Map<String, Object>) v;
          for (Entry<String, Object> en : fields.entrySet()) {
            IocField ifld = new IocField();
            ifld.setName(en.getKey());
            ifld.setValue(object2value(en.getValue()));
            iobj.addField(ifld);
          }
        }
      }
      catch (Exception e) {
        throw E(e, "Wrong args: '%s'", v);
      }
    }
    return iobj;
  }

  @SuppressWarnings("unchecked")
  IocValue object2value(Object obj) {
    IocValue iv = new IocValue();
    // Null
    if (null == obj) {
      iv.setType("null");
      return iv;
    }
    // IocValue
    else if (obj instanceof IocValue) {
      return (IocValue) obj;
    }
    // Map
    else if (obj instanceof Map<?, ?>) {
      Map<String, Object> map = (Map<String, Object>) obj;
      if (map.size() == 1) {
        Entry<String, ?> en = map.entrySet().iterator().next();
        String key = en.getKey();
        // support this type or not?
        if (supportedTypes.contains(key)) {
          iv.setType(key);
          iv.setValue(en.getValue());
          return iv;
        }
      }
      // Inner
      if (isIocObject(map)) {
        iv.setType(IocValue.TYPE_INNER);
        try {
          iv.setValue(map2iobj(map));
        }
        catch (ObjectLoadException e) {
          throw Lang.wrapThrow(e);
        }
        return iv;
      }
      // Normal map
      Map<String, IocValue> newmap = new HashMap<String, IocValue>();
      for (Entry<String, Object> en : map.entrySet()) {
        IocValue v = object2value(en.getValue());
        newmap.put(en.getKey(), v);
      }
      iv.setType(IocValue.TYPE_NORMAL);
      iv.setValue(newmap);
      return iv;
    }
    // Array
    else if (obj.getClass().isArray()) {
      Object[] array = (Object[]) obj;
      IocValue[] ivs = new IocValue[array.length];
      for (int i = 0; i < ivs.length; i++) {
        ivs[i] = object2value(ivs[i]);
      }
      iv.setType(IocValue.TYPE_NORMAL);
      iv.setValue(ivs);
    }
    // Collection
    else if (obj instanceof Collection<?>) {
      try {
        Collection<IocValue> values = (Collection<IocValue>) Mirror.me(obj).born();
        Iterator<?> it = ((Collection<?>) obj).iterator();
        while (it.hasNext()) {
          Object o = it.next();
          IocValue v = object2value(o);
          values.add(v);
        }
        iv.setType(IocValue.TYPE_NORMAL);
        iv.setValue(values);
        return iv;
      }
      catch (Exception e) {
        throw Lang.wrapThrow(e);
      }
    }
    // Normal
    iv.setType(IocValue.TYPE_NORMAL);
    iv.setValue(obj);
    return iv;
  }

}
TOP

Related Classes of org.nutz.ioc.IocLoading

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.