View Javadoc
1   package com.zone.weixin4j.util;
2   
3   import com.zone.weixin4j.exception.WeixinException;
4   
5   import java.io.*;
6   import java.lang.reflect.ParameterizedType;
7   import java.lang.reflect.Type;
8   import java.net.JarURLConnection;
9   import java.net.URISyntaxException;
10  import java.net.URL;
11  import java.util.ArrayList;
12  import java.util.Enumeration;
13  import java.util.List;
14  import java.util.jar.JarEntry;
15  import java.util.jar.JarFile;
16  
17  /**
18   * 对class的获取
19   * 
20   * @className ClassUtil
21   * @author jinyu(foxinmy@gmail.com)
22   * @date 2014年10月31日
23   * @since JDK 1.6
24   * @see
25   */
26  public final class ClassUtil {
27  	private final static String POINT = ".";
28  	private final static String CLASS = ".class";
29  
30  	/**
31  	 * 获取某个包下所有的class信息
32  	 * 
33  	 * @param packageName
34  	 *            包名
35  	 * @return
36  	 */
37  	public static List<Class<?>> getClasses(String packageName)
38  			throws WeixinException {
39  		String packageFileName = packageName.replace(POINT, File.separator);
40  		URL fullPath = getDefaultClassLoader().getResource(packageFileName);
41  		String protocol = fullPath.getProtocol();
42  		if (protocol.equals(ServerToolkits.PROTOCOL_FILE)) {
43  			try {
44  				File dir = new File(fullPath.toURI());
45  				return findClassesByFile(dir, packageName);
46  			} catch (URISyntaxException e) {
47  				throw new WeixinException(e);
48  			}
49  		} else if (protocol.equals(ServerToolkits.PROTOCOL_JAR)) {
50  			try {
51  				return findClassesByJar(
52  						((JarURLConnection) fullPath.openConnection())
53  								.getJarFile(),
54  						packageName);
55  			} catch (IOException e) {
56  				throw new WeixinException(e);
57  			}
58  		}
59  		return null;
60  	}
61  
62  	/**
63  	 * 扫描目录下所有的class对象
64  	 * 
65  	 * @param dir
66  	 *            文件目录
67  	 * @param packageName
68  	 *            包的全限类名
69  	 * @return
70  	 */
71  	private static List<Class<?>> findClassesByFile(File dir, String packageName) {
72  		List<Class<?>> classes = new ArrayList<Class<?>>();
73  		File[] files = dir.listFiles(new FilenameFilter() {
74  			@Override
75  			public boolean accept(File file, String name) {
76  				return file.isDirectory() || file.getName().endsWith(CLASS);
77  			}
78  		});
79  		if (files != null) {
80  			for (File file : files) {
81  				if (file.isDirectory()) {
82  					classes.addAll(findClassesByFile(file, packageName + POINT
83  							+ file.getName()));
84  				} else {
85  					try {
86  						classes.add(Class.forName(packageName + POINT
87  								+ file.getName().replace(CLASS, "")));
88  					} catch (ClassNotFoundException e) {
89  						;
90  					}
91  				}
92  			}
93  		}
94  		return classes;
95  	}
96  
97  	/**
98  	 * 扫描jar包下所有的class对象
99  	 * 
100 	 * @param jar
101 	 *            jar包对象
102 	 * @param packageName
103 	 *            包的全限类名
104 	 * @return
105 	 */
106 	private static List<Class<?>> findClassesByJar(JarFile jar,
107 			String packageName) {
108 		List<Class<?>> classes = new ArrayList<Class<?>>();
109 		Enumeration<JarEntry> jarEntries = jar.entries();
110 		while (jarEntries.hasMoreElements()) {
111 			JarEntry jarEntry = jarEntries.nextElement();
112 			if (jarEntry.isDirectory()) {
113 				continue;
114 			}
115 			String className = jarEntry.getName()
116 					.replace(File.separator, POINT);
117 			if (!className.startsWith(packageName)
118 					|| !className.endsWith(CLASS)) {
119 				continue;
120 			}
121 			try {
122 				classes.add(Class.forName(className.replace(CLASS, "")));
123 			} catch (ClassNotFoundException e) {
124 				;
125 			}
126 		}
127 		return classes;
128 	}
129 
130 	public static Object deepClone(Object obj) throws WeixinException {
131 		ByteArrayOutputStream bos = null;
132 		ObjectOutputStream oos = null;
133 		ByteArrayInputStream bis = null;
134 		ObjectInputStream ois = null;
135 		try {
136 			bos = new ByteArrayOutputStream();
137 			oos = new ObjectOutputStream(bos);
138 			oos.writeObject(obj);
139 			bis = new ByteArrayInputStream(bos.toByteArray());
140 			ois = new ObjectInputStream(bis);
141 			return ois.readObject();
142 		} catch (IOException e) {
143 			throw new WeixinException(e);
144 		} catch (ClassNotFoundException e) {
145 			throw new WeixinException(e);
146 		} finally {
147 			try {
148 				if (bos != null) {
149 					bos.close();
150 				}
151 				if (oos != null) {
152 					oos.close();
153 				}
154 				if (bis != null) {
155 					bis.close();
156 				}
157 				if (ois != null) {
158 					ois.close();
159 				}
160 			} catch (IOException e) {
161 				;// ignore
162 			}
163 		}
164 	}
165 
166 	/**
167 	 * 获得泛型类型
168 	 * 
169 	 * @param object
170 	 * @return
171 	 */
172 	public static Class<?> getGenericType(Class<?> clazz) {
173 		if(clazz == Object.class){
174 			return null;
175 		}
176 		Type type = clazz.getGenericSuperclass();
177 		if (type instanceof ParameterizedType) {
178 			ParameterizedType ptype = ((ParameterizedType) type);
179 			Type[] args = ptype.getActualTypeArguments();
180 			return (Class<?>) args[0];
181 		}
182 		return getGenericType(clazz.getSuperclass());
183 	}
184 
185 	public static ClassLoader getDefaultClassLoader() {
186 		ClassLoader cl = null;
187 		try {
188 			cl = Thread.currentThread().getContextClassLoader();
189 		} catch (Throwable ex) {
190 			// Cannot access thread context ClassLoader - falling back...
191 		}
192 		if (cl == null) {
193 			// No thread context class loader -> use class loader of this class.
194 			cl = ClassUtil.class.getClassLoader();
195 			if (cl == null) {
196 				// getClassLoader() returning null indicates the bootstrap
197 				// ClassLoader
198 				try {
199 					cl = ClassLoader.getSystemClassLoader();
200 				} catch (Throwable ex) {
201 					// Cannot access system ClassLoader - oh well, maybe the
202 					// caller can live with null...
203 				}
204 			}
205 		}
206 		return cl;
207 	}
208 
209 	public static void main(String[] args) throws WeixinException {
210 		System.err.println(getClasses("com.foxinmy.weixin4j.qy.event"));
211 	}
212 }