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