集册 Java实例教程 通过Ant在jar文件中查找与给定位置模式匹配的所有资源

通过Ant在jar文件中查找与给定位置模式匹配的所有资源

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

507
通过Ant样式的PathMatcher在jar文件中找到与给定位置模式匹配的所有资源。


//package com.nowjava;

import java.io.File;

import java.io.IOException;
/* from 
n o w j a v a . c o m - 时代Java*/

import java.lang.annotation.Annotation;

import java.lang.annotation.ElementType;

import java.lang.annotation.Target;

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import java.net.JarURLConnection;

import java.net.URI;

import java.net.URISyntaxException;

import java.net.URL;

import java.net.URLConnection;


import java.util.Enumeration;

import java.util.LinkedHashSet;
/*
n  o  w  j  a  v  a . c o m 提供
*/


import java.util.Set;

import java.util.jar.JarEntry;

import java.util.jar.JarFile;


public class Main {

    /** URL prefix for loading from the file system: "file:" */

    public static final String FILE_URL_PREFIX = "file:";

    /** Separator between JAR URL and file path within the JAR */

    public static final String JAR_URL_SEPARATOR = "!/";


    /**

     * Find all resources in jar files that match the given location pattern

     * via the Ant-style PathMatcher.

     * 

     * @param rootDirResource the root directory as Resource

     * @param subPattern the sub pattern to match (below the root directory)

     * @return the Set of matching Resource instances

     * @throws IOException in case of I/O errors

     * @see java.net.JarURLConnection

     * @see org.springframework.util.PathMatcher

     */

    protected static <T extends Annotation> Set<Class<?>> doFindPathMatchingJarResources(

            URL sourceUrl, String basePackage, Class<T> searchedAnnotation)

            throws IOException {


        URLConnection con = sourceUrl.openConnection();

        JarFile jarFile;

        String jarFileUrl;

        String rootEntryPath;

        boolean newJarFile = false;


        if (con instanceof JarURLConnection) {

            // Should usually be the case for traditional JAR files.

            JarURLConnection jarCon = (JarURLConnection) con;

            jarFile = jarCon.getJarFile();

            jarFileUrl = jarCon.getJarFileURL().toExternalForm();

            JarEntry jarEntry = jarCon.getJarEntry();

            rootEntryPath = (jarEntry != null ? jarEntry.getName() : "");

        } else {

            // No JarURLConnection -> need to resort to URL file parsing.

            // We'll assume URLs of the format "jar:path!/entry", with the protocol

            // being arbitrary as long as following the entry format.

            // We'll also handle paths with and without leading "file:" prefix.

            String urlFile = sourceUrl.getFile();

            int separatorIndex = urlFile.indexOf(JAR_URL_SEPARATOR);

            if (separatorIndex != -1) {

                jarFileUrl = urlFile.substring(0, separatorIndex);

                rootEntryPath = urlFile.substring(separatorIndex

                        + JAR_URL_SEPARATOR.length());

                jarFile = getJarFile(jarFileUrl);

            } else {

                jarFile = new JarFile(urlFile);

                jarFileUrl = urlFile;

                rootEntryPath = "";

            }

            newJarFile = true;

        }


        try {

            if (!"".equals(rootEntryPath) && !rootEntryPath.endsWith("/")) {

                // Root entry path must end with slash to allow for proper matching.

                // The Sun JRE does not return a slash here, but BEA JRockit does.

                rootEntryPath = rootEntryPath + "/";

            }

            Set<Class<?>> result = new LinkedHashSet<Class<?>>(8);

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

                    .hasMoreElements();) {

                JarEntry entry = entries.nextElement();

                String entryPath = entry.getName();

                if (entryPath.startsWith(rootEntryPath)

                        && entryPath.endsWith(".class")) {

                    int entryLength = entryPath.length();

                    String className = entryPath.replaceAll(File.separator,

                            ".").substring(0, entryLength - 6);

                    Class<?> foundClass = checkCandidate(className,

                            searchedAnnotation);

                    if (foundClass != null)

                        result.add(foundClass);

                }

            }

            return result;

        } finally {

            // Close jar file, but only if freshly obtained -

            // not from JarURLConnection, which might cache the file reference.

            if (newJarFile) {

                jarFile.close();

            }

        }

    }


    /**

     * Resolve the given jar file URL into a JarFile object.

     */

    protected static JarFile getJarFile(String jarFileUrl)

            throws IOException {

        if (jarFileUrl.startsWith(FILE_URL_PREFIX)) {

            try {

                return new JarFile(

                        new URI(jarFileUrl.replaceAll(" ", "%20"))

                                .getSchemeSpecificPart());

            } catch (URISyntaxException ex) {

                // Fallback for URLs that are not valid URIs (should hardly ever happen).

                return new JarFile(jarFileUrl.substring(FILE_URL_PREFIX

                        .length()));

            }

        } else {

            return new JarFile(jarFileUrl);

        }

    }


    public static <T extends Annotation> Class<?> checkCandidate(

            String className, Class<T> searchedAnnotation) {

        try {

            Class<?> candidateClass = Class.forName(className);

            Target target = searchedAnnotation.getAnnotation(Target.class);

            for (ElementType elementType : target.value()) {

                switch (elementType) {

                case TYPE:

                    if (candidateClass.getAnnotation(searchedAnnotation) != null)

                        return candidateClass;

                    
展开阅读全文