package org.nutz.ioc.loader.combo; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.nutz.ioc.IocLoader; import org.nutz.ioc.IocLoading; import org.nutz.ioc.ObjectLoadException; import org.nutz.ioc.loader.annotation.AnnotationIocLoader; import org.nutz.ioc.loader.json.JsonLoader; import org.nutz.ioc.loader.xml.XmlIocLoader; import org.nutz.ioc.meta.IocObject; import org.nutz.json.Json; import org.nutz.lang.Lang; import org.nutz.lang.Mirror; import org.nutz.log.Log; import org.nutz.log.Logs; /** * 融化多种IocLoader * * @author wendal(wendal1985@gmail.com) * */ public class ComboIocLoader implements IocLoader { private static final Log log = Logs.get(); private List<IocLoader> iocLoaders = new ArrayList<IocLoader>(); /** * 这个构造方法需要一组特殊的参数 * <p/> * 第一种,以*开头,后面接类名, 如 <code>*org.nutz.ioc.loader.json.JsonLoader</code> * <p/>1.b.45版开始支持类别名: js , json, xml, annotation 分别对应其加载类 * <p/> * 第二种,为具体的参数 * <p/> * 处理规律, 当遇到第一种参数(*),则认为接下来的一个或多个参数为这一个IocLoader的参数,直至遇到另外一个*开头的参数 * <p/> * <p/> * 例子: * <p/> * <code>{"*org.nutz.ioc.loader.json.JsonLoader","dao.js","service.js","*org.nutz.ioc.loader.xml.XmlIocLoader","config.xml"}</code> * <p/> * 这样的参数, 会生成一个以{"dao.js","service.js"}作为参数的JsonLoader,一个以{"dao.xml"} * 作为参数的XmlIocLoader * * @throws ClassNotFoundException * 如果*开头的参数所指代的类不存在 */ public ComboIocLoader(String... args) throws ClassNotFoundException { if (loaders.isEmpty()) { loaders.put("js", JsonLoader.class); loaders.put("json", JsonLoader.class); loaders.put("xml", XmlIocLoader.class); loaders.put("annotation", AnnotationIocLoader.class); } ArrayList<String> argsList = null; String currentClassName = null; for (String str : args) { if (str.length() > 0 && str.charAt(0) == '*') { if (argsList != null) createIocLoader(currentClassName, argsList); currentClassName = str.substring(1); argsList = new ArrayList<String>(); } else { if (argsList == null) { throw new IllegalArgumentException("ioc args without Loader ClassName. " + args); } argsList.add(str); } } if (currentClassName != null) createIocLoader(currentClassName, argsList); Set<String> beanNames = new HashSet<String>(); for (IocLoader loader : iocLoaders) { for (String beanName : loader.getName()) { if (!beanNames.add(beanName) && log.isWarnEnabled()) log.warnf("Found Duplicate beanName=%s, pls check you config!", beanName); } } } @SuppressWarnings("unchecked") private void createIocLoader(String className, List<String> args) throws ClassNotFoundException { Class<? extends IocLoader> klass = loaders.get(className); if (klass == null) klass = (Class<? extends IocLoader>) Lang.loadClass(className); iocLoaders.add((IocLoader) Mirror.me(klass).born(args.toArray(new Object[args.size()]))); } public ComboIocLoader(IocLoader... loaders) { for (IocLoader iocLoader : loaders) if (iocLoader != null) iocLoaders.add(iocLoader); } public String[] getName() { ArrayList<String> list = new ArrayList<String>(); for (IocLoader iocLoader : iocLoaders) { for (String name : iocLoader.getName()) list.add(name); } return list.toArray(new String[list.size()]); } public boolean has(String name) { for (IocLoader iocLoader : iocLoaders) if (iocLoader.has(name)) return true; return false; } public IocObject load(IocLoading loading, String name) throws ObjectLoadException { for (IocLoader iocLoader : iocLoaders) if (iocLoader.has(name)) { IocObject iocObject = iocLoader.load(loading, name); if (log.isDebugEnabled()) log.debugf("Found IocObject(%s) in IocLoader(%s)", name, iocLoader.getClass().getSimpleName() + "@" + iocLoader.hashCode()); return iocObject; } throw new ObjectLoadException("Object '" + name + "' without define!"); } /** * 类别名 */ private static Map<String, Class<? extends IocLoader>> loaders = new HashMap<String, Class<? extends IocLoader>>(); // TODO 这个方法好好整理一下 ... public String toString() { StringBuilder sb = new StringBuilder(); sb.append("/*ComboIocLoader*/\n{"); for (IocLoader loader : iocLoaders) { String str = Json.toJson(loader); str = str.replaceFirst("[{]", ""); // 肯定有!! int index = str.lastIndexOf("}"); // 肯定有!! StringBuilder sb2 = new StringBuilder(str); sb2.setCharAt(index, ' '); sb.append(sb2).append("\n"); } sb.append("}"); return sb.toString(); } }