集册 Java实例教程 递归获取给定包和所有子包中所有类的列表。

递归获取给定包和所有子包中所有类的列表。

欢马劈雪     最近更新时间:2020-01-02 10:19:05

557
递归获取给定包和所有子包中所有类的列表。
/*来自 时 代 J a v a 公 众 号*/

/*

 * Copyright (c) 2012 Data Harmonisation Panel

 * 

 * All rights reserved. This program and the accompanying materials are made

 * available under the terms of the GNU Lesser General Public License as

 * published by the Free Software Foundation, either version 3 of the License,

 * or (at your option) any later version.

 * 

 * You should have received a copy of the GNU Lesser General Public License

 * along with this distribution. If not, see <http://www.gnu.org/licenses/>.

 * 

 * Contributors:

 *     HUMBOLDT EU Integrated Project #030962

 *     Data Harmonisation Panel <http://www.dhpanel.eu>

 */

import java.io.File;

import java.io.IOException;

import java.lang.reflect.Field;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.lang.reflect.Modifier;

import java.net.JarURLConnection;

import java.net.MalformedURLException;

import java.net.URI;

import java.net.URISyntaxException;

import java.net.URL;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Enumeration;

import java.util.Iterator;

import java.util.List;

import java.util.jar.JarEntry;

import java.util.jar.JarFile;

import java.util.zip.ZipException;
/** nowjava.com - 时  代  Java 提供 **/

public class Main{

    /**

     * The package resolver used to retrieve URLs to packages

     */

    private static PackageResolver _packageResolver = new DefaultPackageResolver();

    /**

     * Gets a list of all classes in the given package and all subpackages

     * recursively.

     * 

     * @param pkg the package

     * @param classLoader the class loader to use

     * @return the list of classes

     * @throws IOException if a subpackage or a class could not be loaded

     */

    public static List<Class<?>> getClassesFromPackage(String pkg,

            ClassLoader classLoader) throws IOException {

        return getClassesFromPackage(pkg, classLoader, true);

    }

    /**

     * Gets a list of all classes in the given package

     * 

     * @param pkg the package

     * @param classLoader the class loader to use

     * @param recursive true if all subpackages shall be traversed too

     * @return the list of classes

     * @throws IOException if a subpackage or a class could not be loaded

     */

    public static List<Class<?>> getClassesFromPackage(String pkg,

            ClassLoader classLoader, boolean recursive) throws IOException {

        List<Class<?>> result = new ArrayList<Class<?>>();

        getClassesFromPackage(pkg, result, classLoader, recursive);

        return result;

    }

    private static void getClassesFromPackage(String pkg, List<Class<?>> l,

            ClassLoader classLoader, boolean recursive) throws IOException {

        File[] files = getFilesFromPackage(pkg);

        for (File f : files) {

            String name = f.getName();

            if (f.isDirectory() && recursive) {

                if (!name.startsWith(".")) { //$NON-NLS-1$

                    getClassesFromPackage(

                            pkg + "." + name, l, classLoader, true); //$NON-NLS-1$

                }

            } else if (name.toLowerCase().endsWith(".class")) { //$NON-NLS-1$

                // the following lines make sure we also handle classes

                // in subpackages. These subpackages may be returned by

                // ApplicationContext.getFilesFromPackage() when we are

                // in a jar file

                String classPath = f.toURI().toString().replace('/', '.')

                        .replace('\\', '.');

                String className = classPath.substring(

                        classPath.lastIndexOf(pkg),

                        classPath.lastIndexOf('.'));

                Class<?> c;

                try {

                    c = Class.forName(className, true, classLoader);

                } catch (ClassNotFoundException e) {

                    throw new IOException("Could not load class: " + //$NON-NLS-1$

                            e.getMessage());

                }


                l.add(c);

            }

        }

    }

    /**

     * Returns an array of all files contained by a given package

     * 

     * @param pkg the package (e.g. "de.igd.fhg.CityServer3D")

     * @return an array of files

     * @throws IOException if the package could not be found

     */

    public static synchronized File[] getFilesFromPackage(String pkg)

            throws IOException {


        File[] files;

        JarFile jarFile = null;

        try {

            URL u = _packageResolver.resolve(pkg);

            if (u != null && !u.toString().startsWith("jar:")) { //$NON-NLS-1$

                // we got the package as an URL. Simply create a file

                // from this URL

                File dir;

                try {

                    dir = new File(u.toURI());

                } catch (URISyntaxException e) {

                    // if the URL contains spaces and they have not been

                    // replaced by %20 then we'll have to use the following line

                    dir = new File(u.getFile());

                }

                if (!dir.isDirectory()) {

                    // try another method

                    dir = new File(u.getFile());

                }

                files = null;

                if (dir.isDirectory()) {

                    files = dir.listFiles();

                }

            } else {

                // the package may be in a jar file

                // get the current jar file and search it

                if (u != null && u.toString().startsWith("jar:file:")) { //$NON-NLS-1$

                    // first try using URL and File

                    try {

                        String p = u.toString().substring(4);

                        p = p.substring(0, p.indexOf("!/")); //$NON-NLS-1$

                        File file = new File(URI.create(p));

                        p = file.getAbsolutePath();

                        try {

                            jarFile = new JarFile(p);

                        } catch (ZipException e) {

                            throw new IllegalArgumentException(

                                    "No zip file: " + p, e); //$NON-NLS-1$

                        }

                    } catch (Throwable e1) {

                        // second try directly using path

                        String p = u.toString().substring(9);

                        p = p.substring(0, p.indexOf("!/")); //$NON-NLS-1$

                        try {

                            jarFile = new JarFile(p);

                        } catch (ZipException e2) {

                            throw new IllegalArgumentException(

                                    "No zip file: " + p, e2); //$NON-NLS-1$

                        }

                    }

                } else {

                    u = getCurrentJarURL();


                    // open jar file

                    JarURLConnection juc = (JarURLConnection) u

                            .openConnection();

                    jarFile = juc.getJarFile();

                }


                // enumerate entries and add those that match the package path

                Enumeration<JarEntry> entries = jarFile.entries();

                ArrayList<String> file_names = new ArrayList<String>();

                String package_path = pkg.replaceAll("\\.", "/"); //$NON-NLS-1$ //$NON-NLS-2$

                boolean slashed = false;

                if (package_path.charAt(0) == '/') {

                    package_path = package_path.substring(1);

                    slashed = true;

                }

                while (entries.hasMoreElements()) {

                    JarEntry j = entries.nextElement();

                    if (j.getName().matches("^" + package_path + ".+\\..+")) { //$NON-NLS-1$ //$NON-NLS-2$

                        if (slashed) {

                            file_names.add("/" + j.getName()); //$NON-NLS-1$

                        } else {

                            file_names.add(j.getName());

                        }

                    }

                }


                // convert list to array

                files = new File[file_names.size()];

                Iterator<String> i = file_names.iterator();

                int n = 0;

                while (i.hasNext()) {

                    files[n++] = new File(
展开阅读全文