All Downloads are FREE. Search and download functionalities are using the official Maven repository.

blade.kit.ReflectKit Maven / Gradle / Ivy

/**
 * Copyright (c) 2015, biezhi 王爵 ([email protected])
 *
 * 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.
 */
package blade.kit;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import blade.kit.log.Logger;

/**
 * 有关 Reflection处理的工具类。
 * 
 * 这个类中的每个方法都可以“安全”地处理 null ,而不会抛出 NullPointerException。
 * 
 * @author	biezhi
 * @since	1.0
 */
public abstract class ReflectKit {

	private static final Logger LOGGER = Logger.getLogger(ReflectKit.class);
	
	/** 新建对象 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws ClassNotFoundException */
	public static Object newInstance(String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		Object obj = null;
		Class clazz = Class.forName(className);
		obj = clazz.newInstance();
		LOGGER.debug("new %s", className);
		return obj;
	}
	
	/**
     * 创建一个实例对象
     * @param clazz class对象
     * @return
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
     */
    public static Object newInstance(Class clazz) throws InstantiationException, IllegalAccessException{
    	return clazz.newInstance();
    }

	/** 用setter设置bean属性 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException */
	public static void setProperty(Object bean, String name, Object value) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		String methodName = "set" + StringKit.firstUpperCase(name);
		invokeMehodByName(bean, methodName, value);
	}

	/** 用getter获取bean属性 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException */
	public static Object getProperty(Object bean, String name) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		String methodName = "get" + StringKit.firstUpperCase(name);
		return invokeMehodByName(bean, methodName);
	}

	/** 类型转换 */
	@SuppressWarnings("unchecked")
	public static  T cast(Object value, Class type) {
		if (value != null && !type.isAssignableFrom(value.getClass())) {
			if (is(type, int.class, Integer.class)) {
				value = Integer.parseInt(String.valueOf(value));
			} else if (is(type, long.class, Long.class)) {
				value = Long.parseLong(String.valueOf(value));
			} else if (is(type, float.class, Float.class)) {
				value = Float.parseFloat(String.valueOf(value));
			} else if (is(type, double.class, Double.class)) {
				value = Double.parseDouble(String.valueOf(value));
			} else if (is(type, boolean.class, Boolean.class)) {
				value = Boolean.parseBoolean(String.valueOf(value));
			} else if (is(type, String.class)) {
				value = String.valueOf(value);
			}
		}
		return (T) value;
	}

	/** 查找方法 */
	public static Method getMethodByName(Object classOrBean, String methodName) {
		Method ret = null;
		if (classOrBean != null) {
			Class clazz = null;
			if (classOrBean instanceof Class) {
				clazz = (Class) classOrBean;
			} else {
				clazz = classOrBean.getClass();
			}
			for (Method method : clazz.getMethods()) {
				if (method.getName().equals(methodName)) {
					ret = method;
					break;
				}
			}
		}
		return ret;
	}
	
	public static Method getMethodByName(Class clazz, String methodName) {
		Method ret = null;
		for (Method method : clazz.getMethods()) {
			if (method.getName().equals(methodName)) {
				ret = method;
				break;
			}
		}
		return ret;
	}
	
	/**
	 * 
	 * @param bean 类实例
	 * @param methodName 方法名称
	 * @param args 方法参数
	 * @return
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 */
	public static Object invokeMehodByName(Object bean, String methodName, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Method method = getMethodByName(bean, methodName);
		Class[] types = method.getParameterTypes();

		int argCount = args == null ? 0 : args.length;

		// 参数个数对不上
		ExceptionKit.makeRunTimeWhen(argCount != types.length,
				"%s in %s", methodName, bean);

		// 转参数类型
		for (int i = 0; i < argCount; i++) {
			args[i] = cast(args[i], types[i]);
		}
		return method.invoke(bean, args);
	}

	/**
	 * 
	 * @param bean 类实例
	 * @param methodName 方法名称
	 * @param args 方法参数
	 * @return
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 */
	public static Object invokeMehod(Object bean, Method method, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class[] types = method.getParameterTypes();

		int argCount = args == null ? 0 : args.length;

		// 参数个数对不上
		ExceptionKit.makeRunTimeWhen(argCount != types.length, "%s in %s", method.getName(), bean);
		
		// 转参数类型
		for (int i = 0; i < argCount; i++) {
			args[i] = cast(args[i], types[i]);
		}
		return method.invoke(bean, args);
	}
	
	// ------------------------------------------------------

	/** 对象是否其中一个 */
	public static boolean is(Object obj, Object... mybe) {
		if (obj != null && mybe != null) {
			for (Object mb : mybe)
				if (obj.equals(mb))
					return true;
		}
		return false;
	}

	public static boolean isNot(Object obj, Object... mybe) {
		return !is(obj, mybe);
	}
	
	// ------------------------------------------------------

	/** 扫描包下面所有的类 */
	public static List scanPackageClass(String rootPackageName) {
		List classNames = new ArrayList();
		try {
			ClassLoader loader = Thread.currentThread().getContextClassLoader();
			URL url = loader.getResource(rootPackageName.replace('.', '/'));

			ExceptionKit.makeRunTimeWhen(url == null,
					"package[%s] not found!", rootPackageName);

			String protocol = url.getProtocol();
			if ("file".equals(protocol)) {
				LOGGER.debug("scan in file");
				File[] files = new File(url.toURI()).listFiles();
				for (File f : files) {
					scanPackageClassInFile(rootPackageName, f, classNames);
				}
			} else if ("jar".equals(protocol)) {
				LOGGER.debug("scan in jar");
				JarFile jar = ((JarURLConnection) url.openConnection())
						.getJarFile();
				scanPackageClassInJar(jar, rootPackageName, classNames);
			}

		} catch (URISyntaxException e) {
		} catch (IOException e) {
		}
		return classNames;
	}

	/** 扫描文件夹下所有class文件 */
	private static void scanPackageClassInFile(String rootPackageName,
			File rootFile, List classNames) {
		String absFileName = rootPackageName + "." + rootFile.getName();
		if (rootFile.isFile() && absFileName.endsWith(".class")) {
			classNames.add(absFileName.substring(0, absFileName.length() - 6));
		} else if (rootFile.isDirectory()) {
			String tmPackageName = rootPackageName + "." + rootFile.getName();
			for (File f : rootFile.listFiles()) {
				scanPackageClassInFile(tmPackageName, f, classNames);
			}
		}
	}

	/**
	 * 扫描jar里面的类
	 * @param jar jar包文件
	 * @param packageDirName 包目录 
	 * @param classNames class名称列表
	 */
	private static void scanPackageClassInJar(JarFile jar, String packageDirName, List classNames) {
		Enumeration entries = jar.entries();
		while (entries.hasMoreElements()) {
			JarEntry entry = entries.nextElement();
			String name = entry.getName().replace('/', '.');
			if (name.startsWith(packageDirName) && name.endsWith(".class")) {
				classNames.add(name.substring(0, name.length() - 6));
			}
		}
	}
		

    /**
     * 方法调用,如果clazznull,返回null;
     * 

* 如果methodnull,返回null *

* 如果targetnull,则为静态方法 * * @param method 调用的方法 * @param target 目标对象 * @param args 方法的参数值 * @return 调用结果 * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException */ public static Object invokeMethod(Method method, Object target, Object...args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (method == null) { return null; } method.setAccessible(true); return method.invoke(target, args); } /** *

* 调用一个命名的方法,其参数类型相匹配的对象类型。 *

* * * @param object 调用方法作用的对象 * @param methodName 方法名 * @param args 参数值 * @param parameterTypes 参数类型 * @return 调用的方法的返回值 * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException * */ public static Object invokeMethod(Object object, String methodName, Object[] args, Class...parameterTypes) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (object == null || StringKit.isEmpty(methodName)) { return null; } if (parameterTypes == null) { parameterTypes = Emptys.EMPTY_CLASS_ARRAY; } if (args == null) { args = Emptys.EMPTY_OBJECT_ARRAY; } Method method; try { method = object.getClass().getDeclaredMethod(methodName, parameterTypes); } catch (Exception ex) { throw ExceptionKit.toRuntimeException(ex); } if (method == null) { return null; } return invokeMethod(method, object, args); } /** *

* 调用一个命名的静态方法,其参数类型相匹配的对象类型。 *

* * * @param clazz 调用方法作用的类 * @param methodName 方法名 * @param args 参数值 * @param parameterTypes 参数类型 * @return 调用的方法的返回值 * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException * */ public static Object invokeStaticMethod(Class clazz, String methodName, Object[] args, Class...parameterTypes) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (parameterTypes == null) { parameterTypes = Emptys.EMPTY_CLASS_ARRAY; } if (args == null) { args = Emptys.EMPTY_OBJECT_ARRAY; } Method method; try { method = clazz.getDeclaredMethod(methodName, parameterTypes); } catch (Exception ex) { throw ExceptionKit.toRuntimeException(ex); } if (method == null) { return null; } return invokeMethod(method, null, args); } // ========================================================================== // 辅助方法。 // ========================================================================== private static final Method IS_SYNTHETIC; static { Method isSynthetic = null; if (SystemKit.getJavaInfo().isJavaVersionAtLeast(1.5f)) { // cannot call synthetic methods: try { isSynthetic = Member.class.getMethod("isSynthetic", Emptys.EMPTY_CLASS_ARRAY); } catch (Exception e) { // ignore } } IS_SYNTHETIC = isSynthetic; } public static boolean isAccessible(Member m) { return m != null && Modifier.isPublic(m.getModifiers()) && !isSynthetic(m); } static boolean isSynthetic(Member m) { if (IS_SYNTHETIC != null) { try { return ((Boolean) IS_SYNTHETIC.invoke(m, (Object[]) null)).booleanValue(); } catch (Exception e) { } } return false; } /** * Check whether the {@link Class} identified by the supplied name is present. * * @param className the name of the class to check * @return true if class is present, false otherwise */ public static boolean isPresent(String className) { try { // what's wrong with old plain Class.forName // this code supposed to work everywhere including containers Class.forName(className); // getClassLoader().loadClass(className); return true; } catch (Throwable ex) { return false; } } public static boolean isPublic(Member m) { return m != null && Modifier.isPublic(m.getModifiers()); } public static void forceAccess(AccessibleObject object) { if (object == null || object.isAccessible()) { return; } try { object.setAccessible(true); } catch (SecurityException e) { throw ExceptionKit.toRuntimeException(e); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy