Java tutorial
/* * Copyright 2007-2012 Jiemamy Project and the Others. * * This file is part of Jiemamy. * * 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 org.jiemamy.utils; import java.io.File; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.apache.commons.lang.Validate; import org.jiemamy.utils.reflect.ClassUtil; /** * ???????? * * @version $Id$ * @author j5ik2o */ public final class ClassTraversal { private static final String CLASS_EXTENSION = ".class"; private static final String WAR_FILE_EXTENSION = ".war"; private static final String WEB_INF_CLASSES_PATH = "WEB-INF/classes/"; /** * root????? * * @param rootDir * @param handler ? * @throws TraversalHandlerException ??????? */ public static void forEach(File rootDir, ClassHandler handler) throws TraversalHandlerException { forEach(rootDir, null, handler); } /** * root??root??????? * * @param rootDir * @param rootPackage . {@code null}??? * @param handler ? * @throws TraversalHandlerException ??????? * @throws IllegalArgumentException {@code rootDir}, {@code handler}?{@code null}??? */ public static void forEach(File rootDir, String rootPackage, ClassHandler handler) throws TraversalHandlerException { Validate.notNull(rootDir); Validate.notNull(handler); File packageDir = getPackageDir(rootDir, rootPackage); if (packageDir.exists()) { traverseFileSystem(packageDir, rootPackage, handler); } } /** * ??jar???? * * @param jarFile Jar * @param handler ? * @throws TraversalHandlerException ??????? * @throws IllegalArgumentException ?{@code null}??? */ public static void forEach(JarFile jarFile, ClassHandler handler) throws TraversalHandlerException { Validate.notNull(jarFile); Validate.notNull(handler); boolean hasWarExtension = jarFile.getName().endsWith(WAR_FILE_EXTENSION); Enumeration<JarEntry> enumeration = jarFile.entries(); while (enumeration.hasMoreElements()) { JarEntry entry = enumeration.nextElement(); String entryName = entry.getName().replace('\\', '/'); if (entryName.endsWith(CLASS_EXTENSION)) { int startPos = hasWarExtension && entryName.startsWith(WEB_INF_CLASSES_PATH) ? WEB_INF_CLASSES_PATH.length() : 0; String className = entryName.substring(startPos, entryName.length() - CLASS_EXTENSION.length()) .replace('/', '.'); int pos = className.lastIndexOf('.'); String packageName = (pos == -1) ? null : className.substring(0, pos); String shortClassName = (pos == -1) ? className : className.substring(pos + 1); handler.processClass(packageName, shortClassName); } } } private static File getPackageDir(File rootDir, String rootPackage) { File packageDir = rootDir; if (rootPackage != null) { String[] names = rootPackage.split("\\."); for (String name : names) { packageDir = new File(packageDir, name); } } return packageDir; } private static void traverseFileSystem(File dir, String packageName, ClassHandler handler) throws TraversalHandlerException { for (File file : dir.listFiles()) { String fileName = file.getName(); if (file.isDirectory()) { traverseFileSystem(file, ClassUtil.concatName(packageName, fileName), handler); } else if (fileName.endsWith(".class")) { String shortClassName = fileName.substring(0, fileName.length() - CLASS_EXTENSION.length()); handler.processClass(packageName, shortClassName); } } } private ClassTraversal() { } /** * ???????? * */ public interface ClassHandler { /** * ?? * * @param packageName ?? * @param shortClassName ?? * @throws TraversalHandlerException ??????? */ void processClass(String packageName, String shortClassName) throws TraversalHandlerException; } }