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

io.github.albertus82.util.ClasspathResourceUtils Maven / Gradle / Ivy

Go to download

Java SWT/JFace Utility Library including a Preferences Framework, Lightweight HTTP Server and macOS support.

There is a newer version: 20.1.0
Show newest version
package io.github.albertus82.util;

import java.io.File;
import java.io.IOError;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import io.github.albertus82.util.logging.LoggerFactory;

/**
 * List resources available from the classpath.
 * 
 * @see Get a list of
 *      resources from classpath directory - Stack Overflow
 */
public class ClasspathResourceUtils {

	private static final int THRESHOLD_ENTRIES = 0xFFFF;

	private static final Logger log = LoggerFactory.getLogger(ClasspathResourceUtils.class);

	private ClasspathResourceUtils() {
		throw new IllegalAccessError("Utility class");
	}

	/**
	 * For all elements of java.class.path get a Collection of resources Pattern
	 * pattern = Pattern.compile(".*"); gets all resources.
	 * 
	 * @param pattern the pattern to match.
	 * @return the resources in the order they are found.
	 */
	public static List getResourceList(final Pattern pattern) {
		final List retval = new ArrayList<>();
		final String classPath = System.getProperty("java.class.path", ".");
		final String[] classPathElements = classPath.split(System.getProperty("path.separator"));
		for (final String element : classPathElements) {
			retval.addAll(getResources(element, pattern));
		}
		return retval;
	}

	private static List getResources(final String element, final Pattern pattern) {
		final List retval = new ArrayList<>();
		final File file = new File(element);
		if (file.isDirectory()) {
			retval.addAll(getResourcesFromDirectory(file, pattern));
		}
		else {
			retval.addAll(getResourcesFromJarFile(file, pattern));
		}
		return retval;
	}

	private static List getResourcesFromJarFile(final File file, final Pattern pattern) {
		final List retval = new ArrayList<>();
		ZipFile zf = null;
		try {
			zf = new ZipFile(file);
			final String currentPath = new File("").getCanonicalPath();
			log.log(Level.FINEST, "currentPath: {0}", currentPath);
			final Enumeration e = zf.entries();
			int entryCount = 0;
			while (e.hasMoreElements()) {
				if (++entryCount > THRESHOLD_ENTRIES) {
					log.log(Level.WARNING, "Too many ZIP entries!");
					break;
				}
				final ZipEntry ze = e.nextElement();
				final String fileName = ze.getName();
				final String entryPath = new File(currentPath, fileName).getCanonicalPath();
				log.log(Level.FINEST, "entryPath: {0}", entryPath);
				if (!entryPath.startsWith(currentPath)) { // https://blog.ripstech.com/2019/hidden-flaws-of-archives-java/
					log.log(Level.WARNING, "Ignoring ZIP entry {0} not within target directory!", ze);
					continue;
				}
				final boolean accept = pattern.matcher(fileName).matches();
				if (accept && !ze.isDirectory()) {
					retval.add(new Resource(fileName, ze.getSize(), ze.getTime()));
				}
			}
		}
		catch (final IOException e) {
			throw new IOError(e);
		}
		finally {
			if (zf != null) {
				try {
					zf.close();
				}
				catch (final IOException e) {
					log.log(Level.WARNING, "Exception closing " + zf, e);
				}
			}
		}
		return retval;
	}

	private static List getResourcesFromDirectory(final File directory, final Pattern pattern) {
		final List retval = new ArrayList<>();
		final File[] fileList = directory.listFiles();
		for (final File file : fileList) {
			if (file.isDirectory()) {
				retval.addAll(getResourcesFromDirectory(file, pattern));
			}
			else {
				final String fileName = file.getPath();
				final boolean accept = pattern.matcher(fileName).matches();
				if (accept) {
					retval.add(new Resource(fileName, file.length(), file.lastModified()));
				}
			}
		}
		return retval;
	}

	/**
	 * List the resources that match args[0].
	 * 
	 * @param args args[0] is the pattern to match, or list all resources if there
	 *        are no args.
	 */
	public static void main(final String[] args) {
		final Pattern pattern;
		if (args.length < 1) {
			pattern = Pattern.compile(".*");
		}
		else {
			pattern = Pattern.compile(args[0]);
		}
		final Collection list = ClasspathResourceUtils.getResourceList(pattern);
		for (final Resource name : list) {
			System.out.println(name);
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy