/** * * Copyright 2008 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loonframework * @author chenpeng * @email:ceponline@yahoo.com.cn * @version 0.1 */ package org.ripple.power.ioc.reflect; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.ripple.power.collection.ArrayIterator; import org.ripple.power.collection.ConverterMap; import org.ripple.power.collection.MapArray; import org.ripple.power.config.LSystem; import org.ripple.power.ioc.ClassMethod; import org.ripple.power.ioc.ClassUtils; import org.ripple.power.utils.CollectionUtils; import org.ripple.power.utils.ReflectorUtils; final public class Reflector { private static final Map<Object, Object> reflectorMap = Collections .synchronizedMap(new HashMap<Object, Object>(1000)); private Class<?> clazz; private MapArray invokables; /** * 从Object中获得一个Reflector对象 * * @param target * @return */ public static Reflector getReflector(final Object target) { return getReflector(target.getClass()); } /** * 从Class中获得一个Reflector对象 * * @param clazz * @return */ public static Reflector getReflector(final Class<?> clazz) { Reflector reflector = (Reflector) reflectorMap.get(clazz); if (reflector == null) { reflector = new Reflector(clazz); reflectorMap.put(clazz, reflector); } return reflector; } /** * 通过指定的String获得一个Reflector对象 * * @param className * @return */ public static Reflector getReflector(final String className) { return getReflector(className, LSystem.classLoader); } /** * 通过指定的String获得一个Reflector对象,并设定加载用的ClassLoader * * @param className * @param classLoader * @return */ public static Reflector getReflector(final String className, ClassLoader classLoader) { if (className == null) { throw new IllegalArgumentException("class name is null!"); } Reflector reflector = (Reflector) reflectorMap.get(className); if (reflector == null) { reflector = new Reflector(className, classLoader); reflectorMap.put(className, reflector); } return reflector; } /** * 通过Class实例化Reflector * * @param clazz */ private Reflector(Class<?> clazz) { super(); this.clazz = clazz; reflect(); } /** * 通过Class字符串实例化Reflector * * @param className * @param classLoader */ private Reflector(String className, ClassLoader classLoader) { super(); if (className == null || className.trim().length() == 0) { this.clazz = void.class; } else { try { this.clazz = Class.forName(className, true, classLoader); } catch (Exception ex) { throw new RuntimeException(ex); } } reflect(); } /** * 构建类的构成反射 * */ private void reflect() { this.invokables = CollectionUtils.createArrayMap(); reflectConstructors(); reflectMethods(); } private void reflectConstructors() { Constructor<?>[] c = clazz.getConstructors(); int size = c.length; for (int i = 0; i < size; i++) { invokables.put(TypeArrays.getNamedTypeArray(c[i]), c[i]); } } /** * 构建类的方法反射 * */ private void reflectMethods() { ClassMethod clsMethod = ClassUtils.getFieldInspector(clazz); MapArray methods = (MapArray) clsMethod.getMethods(); int size = methods.size(); for (int i = 0; i < size; i++) { Method method = (Method) methods.get(i); invokables.put(TypeArrays.getNamedTypeArray(method), method); } } /** * 匹配方法 * * @param name * @param parameterTypes * @param converterMap * @param throwException * @return */ public Method lookupMethod(String name, Class<?>[] parameterTypes, ConverterMap converterMap, boolean throwException) { TypeArrays desired = new TypeArrays(name, parameterTypes); Object value = invokables.get(desired); if (value != null) { return (Method) value; } return (Method) lookupInvokable(desired, converterMap, throwException); } /** * 匹配方法 * * @param name * @param parameters * @return */ public Method lookupMethod(String name, Class<?>[] parameters) { Method method = lookupMethod(name, ReflectorUtils.parameterToTypeArray(parameters), ReflectorUtils.converterMap, true); return method; } /** * 匹配构造 * * @param parameterTypes * @param converterMap * @param throwException * @return */ public Constructor<?> lookupConstructor(Class<?>[] parameterTypes, ConverterMap converterMap, boolean throwException) { TypeArrays desired = new TypeArrays(TypeArrays.CONSTRUCTOR_METHOD_NAME, parameterTypes); Object object = invokables.get(desired); if (object != null) { return (Constructor<?>) object; } return (Constructor<?>) lookupInvokable(desired, converterMap, throwException); } /** * 返回所有字段 * * @return */ public Set<Object> getFields() { return ReflectorUtils.getFields(clazz); } /** * 比较两个Class数组,返回是非匹配 * * @param appleParams * @param orangeParams * @return * @throws Exception */ public int compareTypes(Class<?>[] appleParams, Class<?>[] orangeParams) throws Exception { Boolean chose = null; for (int i = 0; i < appleParams.length; i++) { if (!appleParams[i].equals(orangeParams[i])) { if (orangeParams[i].isAssignableFrom(appleParams[i])) { if (chose != null) { throw new RuntimeException("chose != null!"); } chose = Boolean.TRUE; } else if (appleParams[i].isAssignableFrom(orangeParams[i])) { if (chose != null) { throw new RuntimeException("chose != null!"); } chose = Boolean.FALSE; } } } return (chose == null ? 0 : (chose.booleanValue() ? -1 : +1)); } /** * 返回一个可供Reflector调用的Object * * @param desired * @param converterMap * @param throwException * @return */ private AccessibleObject lookupInvokable(TypeArrays desired, ConverterMap converterMap, boolean throwException) { Invokable candidate = null; Invokable current = null; TypeArrays currentDescriptor = null; @SuppressWarnings("unchecked") TypeArrays[] ntarrays = (TypeArrays[]) invokables.keySet().toArray( new TypeArrays[invokables.size()]); for (int i = 0; i < ntarrays.length; i++) { currentDescriptor = ntarrays[i]; if (!currentDescriptor.isAliased() && currentDescriptor.getName().equals(desired.getName())) { current = new Invokable( (AccessibleObject) invokables.get(currentDescriptor)); if (converterMap.typesAssignable(current.getParameterTypes(), desired.getParameterTypes())) { try { if (candidate == null || compareTypes( currentDescriptor.getParameterTypes(), candidate.getParameterTypes()) < 0) { candidate = current; } } catch (Exception e) { if (candidate.getDeclaringClass().isAssignableFrom( current.getDeclaringClass()) && !candidate.getDeclaringClass().equals( current.getDeclaringClass())) { candidate = current; } } } } } if (candidate == null) { return null; } desired.setAliased(true); invokables.put(desired, candidate.unwrap()); return candidate.unwrap(); } /** * 查询指定Class是否为目标反射类的实现 * * @param className * @return */ public boolean isImplInterface(String className) { boolean result; try { result = isImplInterface(Class.forName(className)); } catch (ClassNotFoundException e) { result = false; } return result; } /** * 查询指定Class是否为目标反射类的实现 * * @param objClass * @return */ public boolean isImplInterface(Class<?> objClass) { Object[] names = ReflectorUtils.getInterfaceToObjects(clazz); if (names != null && names.length > 0) { for (Iterator<Object> it = new ArrayIterator(names); it.hasNext();) { String name = it.next().toString(); if (name.equalsIgnoreCase(objClass.getName())) { return true; } } } return false; } /** * 查询指定方法是否存在 * * @param name * @param types * @return */ public boolean methodExists(String name, Class<?>[] types) { return (lookupMethod(name, types, ReflectorUtils.converterMap, false) != null); } /** * 查询指定构造是否存在 * * @param types * @return */ public boolean constructorExists(Class<?>[] types) { return (lookupConstructor(types, ReflectorUtils.converterMap, false) != null); } /** * 传递数值到指定对象的方法中去 * * @param object * @param methodName * @param parameters */ public void setInvoke(final Object object, String methodName, Object[] parameters) { if (methodName.lastIndexOf(")") == -1) { methodName += ReflectorUtils.getConstruct(parameters); } String keyName = ReflectorUtils.getMatchSetMethod(clazz, methodName); Object beanObject = ReflectorUtils.doSetMethod(clazz, keyName); try { Method method = (Method) beanObject; method.invoke(object, parameters); } catch (Exception e) { throw new RuntimeException("setInvoke : ", e); } } /** * 传递数值到Reflector的匹配方法中去 * * @param name * @param parameters * @return * @throws Exception */ public Object doInvoke(String name, Object[] parameters) throws Exception { return doInvoke(newInstance(), name, parameters); } /** * 静态传递数值到指定对象的匹配方法中去(自动匹配类型) * * @param object * @param beanProperty * @param value */ public static void doStaticInvokeRegister(final Object object, final String beanProperty, final String value) { Object[] beanObject = doStaticInvokeMatch(object.getClass(), beanProperty); Object[] cache = new Object[1]; Method getter = (Method) beanObject[0]; Method setter = (Method) beanObject[1]; try { String methodType = getter.getReturnType().getName(); if (methodType.equalsIgnoreCase("long")) { cache[0] = new Long(value); setter.invoke(object, cache); } else if (methodType.equalsIgnoreCase("int") || methodType.equalsIgnoreCase("integer")) { cache[0] = new Integer(value); setter.invoke(object, cache); } else if (methodType.equalsIgnoreCase("short")) { cache[0] = new Short(value); setter.invoke(object, cache); } else if (methodType.equalsIgnoreCase("float")) { cache[0] = new Float(value); setter.invoke(object, cache); } else if (methodType.equalsIgnoreCase("double")) { cache[0] = new Double(value); setter.invoke(object, cache); } else if (methodType.equalsIgnoreCase("boolean")) { cache[0] = new Boolean(value); setter.invoke(object, cache); } else if (methodType.equalsIgnoreCase("java.lang.String")) { cache[0] = value; setter.invoke(object, cache); } else if (methodType.equalsIgnoreCase("java.io.InputStream")) { } else if (methodType.equalsIgnoreCase("char")) { cache[0] = new Character(value.charAt(0)); setter.invoke(object, cache); } } catch (Exception ex) { throw new RuntimeException(beanProperty + " is " + ex.getMessage()); } } /** * 匹配静态注入的数据类型 * * @param clazz * @param beanProperty * @return */ final static public Object[] doStaticInvokeMatch(final Class<?> clazz, final String beanProperty) { Object[] result = new Object[2]; String nowPropertyName = ReflectorUtils.initialUppercase(beanProperty); String names[] = { ("set" + nowPropertyName).intern(), ("get" + nowPropertyName).intern(), ("is" + nowPropertyName).intern() }; Method getter = null; Method setter = null; Method methods[] = clazz.getMethods(); int length = methods.length; for (int i = 0; i < length; i++) { Method method = methods[i]; if (!Modifier.isPublic(method.getModifiers())) continue; String methodName = method.getName().intern(); for (int j = 0; j < names.length; j++) { String name = names[j]; if (!name.equals(methodName)) continue; if (methodName.startsWith("set")) { setter = method; } else { getter = method; } } } result[0] = getter; result[1] = setter; return result; } /** * 静态传递数值到指定对象的匹配方法中去 * * @param object * @param beanProperty * @param parameters */ public static void doStaticInvoke(final Object object, final String beanProperty, final Object parameters) { Reflector reflector = Reflector.getReflector(object); Class<?> clazz = reflector.getReflectedClass(); String keyName = ReflectorUtils.getMatchSetMethod(clazz, beanProperty); Object beanObject = ReflectorUtils.doSetMethod(clazz, keyName); Object[] nowParameters = new Object[1]; boolean isArgs = parameters instanceof Object[]; if (isArgs) { nowParameters = (Object[]) parameters; } String type = ReflectorUtils.getSetMethodType(beanObject); try { if (!isArgs) { nowParameters[0] = ReflectorUtils.getReturnObject(type, parameters); } Method method = (Method) beanObject; method.invoke(object, nowParameters); } catch (Exception e) { } } /** * 传递数值到指定对象的匹配方法中去 * * @param object * @param methodName * @param parameters * @return * @throws Exception */ public Object doInvoke(Object object, String methodName, Object[] parameters) throws Exception { if (methodName.lastIndexOf(")") == -1) { methodName += ReflectorUtils.getConstruct(parameters); } methodName = ReflectorUtils.getMatchGetMethod(clazz, methodName); try { Method method = lookupMethod(methodName, ReflectorUtils.parameterToTypeArray(parameters), ReflectorUtils.converterMap, true); Object[] parametersToUse = ReflectorUtils.converterMap .convertParameters(method.getParameterTypes(), parameters); return method.invoke(object, parametersToUse); } catch (Exception ex) { throw new Exception( (methodName + " method can not be invoke ! exception : " + ex .getMessage()).intern()); } } /** * 实例化当前Reflector的目标对象 * * @param args * @return */ public Object newInstance(Object[] args) { Constructor<?> constructor = lookupConstructor( ReflectorUtils.parameterToTypeArray(args), ReflectorUtils.converterMap, true); Object[] parametersToUse = ReflectorUtils.converterMap .convertParameters(constructor.getParameterTypes(), args); try { return constructor.newInstance(parametersToUse); } catch (Exception e) { throw new RuntimeException("Reflector newInstance : ", e); } } /** * 实例化当前Reflector的目标对象 * * @return */ public Object newInstance() { return newInstance(null); } /** * 返回当前当前Reflector的作用类 * * @return */ public Class<?> getReflectedClass() { return clazz; } }