All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.gdface.utils.ClassResourceUtils Maven / Gradle / Ivy

There is a newer version: 3.2.1
Show newest version
package net.gdface.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * classpath resource 工具
 * @author guyadong
 *
 */
public class ClassResourceUtils {

	/**
	 * 文件名过滤器接口
	 * @author guyadong
	 *
	 */
	public static interface FileFilter{
		/**
		 * Tests if a specified file should be included in a file list.
		 * @param filename
		 * @return true/false
		 */
		boolean accept(String filename);
	}
	/**
	 * 参见 {@link #getResourceFileList(Class, String)},
* {@link IOException}封装为{@link RuntimeException}, */ public static List getFilesUnchedked(Class clazz, String path){ try { return getResourceFileList(ClassResourceUtils.class,path); } catch (IOException e) { throw new RuntimeException(e); } } /** * @see #getFilesUnchedked(Class, String) */ public static List getFilesUnchecked(Class clazz,String path, FileFilter filter){ List list = getFilesUnchedked(clazz, path); if(null != filter){ for(Iterator itor = list.iterator();itor.hasNext();){ String file = itor.next(); if(!filter.accept(file)){ itor.remove(); } } } return list; } /** * Returns true if resource exist. * @param clazz Class to use when getting the System classloader * @param resource * @return true/false */ public static boolean resourceExist(Class clazz, String resource){ return getResource(clazz,resource)!=null; } /** * Return a context-relative path, beginning with a "/", that represents * the canonical version of the specified path after ".." and "." elements * are resolved out. If the specified path attempts to go outside the * boundaries of the current context (i.e. too many ".." path elements * are present), return null instead. * * @param path Path to be normalized * @return String normalized path */ public static String normalizePath(String path) { return normalizePath(path,true); } /** * Return a context-relative path, that represents * the canonical version of the specified path after ".." and "." elements * are resolved out. If the specified path attempts to go outside the * boundaries of the current context (i.e. too many ".." path elements * are present), return null instead. * * @param path Path to be normalized * @param startSlash beginning with a "/" * @return String normalized path */ public static String normalizePath(String path,boolean startSlash) { // Normalize the slashes and add leading slash if necessary String normalized = path; if (normalized.indexOf('\\') >= 0) { normalized = normalized.replace('\\', '/'); } if (startSlash && !normalized.startsWith("/")) { normalized = "/" + normalized; } // Resolve occurrences of "//" in the normalized path while (true) { int index = normalized.indexOf("//"); if (index < 0){ break; } normalized = normalized.substring(0, index) + normalized.substring(index + 1); } // Resolve occurrences of "%20" in the normalized path while (true) { int index = normalized.indexOf("%20"); if (index < 0){ break; } normalized =new StringBuilder() .append(normalized.substring(0, index)) .append(" ") .append(normalized.substring(index + 3)).toString(); } // Resolve occurrences of "/./" in the normalized path while (true) { int index = normalized.indexOf("/./"); if (index < 0){ break; } normalized = normalized.substring(0, index) + normalized.substring(index + 2); } // Resolve occurrences of "/../" in the normalized path while (true) { int index = normalized.indexOf("/../"); if (index < 0){ break; } if (index == 0){ // Trying to go outside our context return (null); } int index2 = normalized.lastIndexOf('/', index - 1); normalized = normalized.substring(0, index2) + normalized.substring(index + 3); } // Resolve occurrences of ends with "." in the normalized path if(normalized.endsWith("/.")){ normalized = normalized.substring(0, normalized.length() - 2); } // Resolve occurrences of ends with ".." in the normalized path if(normalized.endsWith("/..")){ String tmp = normalized.substring(0, normalized.length() - 3); int index = tmp.lastIndexOf("/"); if(index > 0){ normalized = tmp.substring(0, index ); }else if(index == 0){ normalized = "/"; } } // Return the normalized path that we have completed return (normalized); } /** * * Return a normalized directory path, end with "/", but not start with one * @param path Path to be normalized * @return Path to be normalized * @see #normalizePath(String) */ public static String normalizeDirPath(String path){ path = normalizePath(path); if (path.startsWith("/")) { path = path.substring(1); } if(!path.endsWith("/")){ path += "/"; } return path; } /** * Returns an input stream for reading the specified resource. * @param clazz Class to use when getting the System classloader (used if no Thread * Context classloader available or fails to get resource). * @param name name of the resource * @return InputStream for the resource. * @see #getResource(Class, String) */ public static InputStream getResourceAsStream(Class clazz, String name) { URL url = getResource(clazz,name); try { return url != null ? url.openStream() : null; } catch (IOException e) { return null; } } /** * Finds a resource with the given name. Checks the Thread Context * classloader, then uses the System classloader. Should replace all * calls to Class.getResourceAsString when the resource * might come from a different classloader. (e.g. a webapp). * @param claz Class to use when getting the System classloader (used if no Thread * Context classloader available or fails to get resource). * @param path name of the resource * @return A URL object for reading the resource, or * null if the resource could not be found or the invoker * doesn't have adequate privileges to get the resource. */ public static URL getResource(Class claz, String path) { URL result = null; path = normalizePath(path); /** * remove leading slash so path will work with classes in a JAR file */ path = path.substring(1); ClassLoader classLoader = Thread.currentThread() .getContextClassLoader(); if (classLoader == null) { classLoader = claz.getClassLoader(); result = classLoader.getResource( path ); } else { result= classLoader.getResource( path ); /** * for compatibility with texen / ant tasks, fall back to * old method when resource is not found. */ if (result == null) { classLoader = claz.getClassLoader(); if (classLoader != null){ result = classLoader.getResource( path ); } } } return result; } private static final String PROTOCOL_FILE = "file"; private static final String PROTOCOL_JAR = "jar"; public enum TypeFilter{ DEFAULT,FILE_ONLY,DIRECTORY_ONLY } /** * List file names(directory excluded) for a resource folder. Not recursive. * This is basically a brute-force implementation. * Works for regular files and also JARs.
* refer to: Java: Listing the contents of a resource directory * @param clazz Any java class that lives in the same place as the resources you want. * @param dirPath path of directory * @return Just the name of each member item, not the full paths. * @throws IOException IO error * @throws FileNotFoundException not found resource OR not a directory */ public static List getResourceFileList(Class clazz, String dirPath) throws IOException, FileNotFoundException { return getResourceList(clazz, dirPath, TypeFilter.FILE_ONLY); } /** * List file names for a resource folder. Not recursive. * This is basically a brute-force implementation. * Works for regular files and also JARs.
* refer to: Java: Listing the contents of a resource directory * @param clazz Any java class that lives in the same place as the resources you want. * @param dirPath path of directory * @param type * @return Just the name of each member item, not the full paths. * @throws IOException IO error * @throws FileNotFoundException not found resource OR not a directory */ public static List getResourceList(Class clazz, String dirPath,final TypeFilter type ) throws IOException, FileNotFoundException { if(null == dirPath || dirPath.isEmpty()){ throw new IllegalArgumentException("path must not be null or empty"); } dirPath = normalizeDirPath(dirPath); URL dirURL = getResource(clazz,dirPath); if(null == dirURL){ throw new FileNotFoundException(dirPath); } switch(dirURL.getProtocol()){ case PROTOCOL_FILE: /* A file path: easy enough */ File dir = new File(URI.create(dirURL.toString())); if(dir.isDirectory()){ FilenameFilter nameFilterWrap = new FilenameFilter(){ @Override public boolean accept(File dir, String name) { File file = new File(dir,name); switch(type){ case FILE_ONLY: return file.isFile(); case DIRECTORY_ONLY: return file.isDirectory(); default: return true; } }}; String[] dirEntires = dir.list(nameFilterWrap); if(dirEntires != null){ // 文件夹名后加'/'区分 for(int i=0; i(Arrays.asList(dirEntires)); } throw new IOException("FAIL TO LIST:" + dirPath); } throw new FileNotFoundException("NOT DIRECTORY:" + dirPath); case PROTOCOL_JAR: /* A JAR path */ //strip out only the JAR file String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!")); LinkedList result = new LinkedList(); try(JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"))){ // gives ALL entries in jar Enumeration entries = jar.entries(); while(entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); switch(type){ case FILE_ONLY: if(entry.isDirectory()){ continue; } break; case DIRECTORY_ONLY: if(!entry.isDirectory()){ continue; } break; default: break; } // if it is a subdirectory, skip String name = entry.getName(); if (name.startsWith(dirPath)) { // filter according to the path String element = name.substring(dirPath.length()); if(!element.isEmpty()){ int checkSubdir = element.indexOf("/"); if(entry.isDirectory()){ if(checkSubdir < element.length()-1){ result.add(element); } }else if (checkSubdir < 0 ) { result.add(element); } } } } } return result; default: throw new UnsupportedOperationException("Cannot list files for URL "+dirURL); } } /** * check if input path is folder * @param clazz Any java class that lives in the same place as the resources you want. * @param input resource path * @return true if input is a folder,otherwise false */ public static boolean isResourceFolder(Class clazz, String input){ try { getResourceList(clazz, input, TypeFilter.DEFAULT); return true; } catch (FileNotFoundException e) { return false; } catch (IOException e) { throw new RuntimeException(e); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy