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

info.unterrainer.commons.jreutils.Resources Maven / Gradle / Ivy

There is a newer version: 0.3.15
Show newest version
package info.unterrainer.commons.jreutils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@UtilityClass
public class Resources {

	/**
	 * Read a file from resources as a String. Works within JAR files as well, since
	 * it's using the stream accessor.
	 *
	 * @param path the path of the file you want to read
	 * @return the contents of the file as a String
	 * @throws IOException if there is a problem opening or reading the file given
	 */
	public static String readResource(final Class classLoaderSource, final String path) throws IOException {
		InputStream inputStream = classLoaderSource.getResourceAsStream(path);
		if (inputStream == null)
			throw new FileNotFoundException(String.format("The file %s could not be found.", path));

		StringBuilder textBuilder = new StringBuilder();
		try (Reader reader = new BufferedReader(
				new InputStreamReader(inputStream, Charset.forName(StandardCharsets.UTF_8.name())))) {
			int c = 0;
			while ((c = reader.read()) != -1)
				textBuilder.append((char) c);
		}
		return textBuilder.toString();
	}

	/**
	 * Walks the directory tree and returns a List of {@link Path} with all the
	 * paths.
	 * 

* This method starts walking the tree in the base-directory (so it walks all * the files within your distribution). * * @return the List of Paths * @throws IOException if something went wrong opening a directory */ public static List walk(final Class classLoaderSource) throws IOException { return walk(classLoaderSource, e -> true); } /** * Walks the directory tree and returns a List of {@link Path} with all the * paths. *

* path: "", "/" or null... the execution folder of the runtime (this is the * default for this method. If you send an empty string, the slash is appended * automatically). *

* This method strips the base-path you have given from the result file-names so * you can easily get those with class.getResource(). * * @param path the path to start searching in * @return the List of Paths * @throws IOException if something went wrong opening a directory */ public static List walk(final Class classLoaderSource, final String path) throws IOException { return walk(classLoaderSource, path, e -> true); } /** * Walks the directory tree and returns a List of {@link Path} with all the * paths. *

* This method starts walking the tree in the base-directory (so it walks all * the files within your distribution). * * @param fileNameFilters a single or multiple filters to match the file-names * against (and is implied) * @return the List of Paths * @throws IOException if something went wrong opening a directory */ @SafeVarargs public static List walk(final Class classLoaderSource, final Predicate... fileNameFilters) throws IOException { return walk(classLoaderSource, null, fileNameFilters); } /** * Walks the directory tree and returns a List of relative {@link Path} objects * with all the paths matching your 'fileNameFilter' {@link Predicate}. *

* path: "", "/" or null... the execution folder of the runtime (this is the * default for this method. If you send an empty string, the slash is appended * automatically). *

* This method strips the base-path you have given from the result file-names so * you can easily get those with class.getResource(). * * @param relativePath the path to start searching in * @param fileNameFilters a single or multiple filters to match the file-names * against (and is implied) * @return the List of Paths * @throws IOException if something went wrong opening a directory */ @SafeVarargs public static List walk(final Class classLoaderSource, final String relativePath, final Predicate... fileNameFilters) throws IOException { Stream stream = null; List> allPredicates = Arrays.asList(fileNameFilters); String path = relativePath; if (path == null || path.isEmpty()) path = "/"; try { URL url = classLoaderSource.getResource(path); if (url == null) throw new FileNotFoundException(String.format("The file %s could not be found.", path)); URI uri = url.toURI(); if ("jar".equals(uri.getScheme())) { log.debug("Jar found. Running zip-walker."); return walkJar(classLoaderSource, allPredicates); } else { log.debug("Running file-walker."); Path basePath = Paths.get(uri); log.debug("Walking from base-directory: [{}]", basePath); stream = Files.walk(basePath, Integer.MAX_VALUE, FileVisitOption.FOLLOW_LINKS); List list = stream.collect(Collectors.toList()); List results = new ArrayList<>(); for (Path p : list) filterFor(allPredicates, results, basePath.relativize(p)); return results; } } catch (URISyntaxException e) { log.error("This should never happen!", e); // NOOP (never happens) } finally { if (stream != null) stream.close(); } return null; } private static List walkJar(final Class classLoaderSource, final List> allPredicates) throws URISyntaxException, IOException, FileNotFoundException { File jarFile = new File(classLoaderSource.getProtectionDomain().getCodeSource().getLocation().toURI()); try (ZipInputStream zip = new ZipInputStream(new FileInputStream(jarFile))) { List results = new ArrayList<>(); for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) { String name = entry.getName(); filterFor(allPredicates, results, Path.of(name)); } return results; } } private static void filterFor(final List> allPredicates, final List results, final Path p) { boolean failed = false; for (Predicate predicate : allPredicates) if (!predicate.test(p)) { failed = true; break; } if (!p.toString().isEmpty() && !failed) { log.debug("pathscan accepted [{}]", p.toString()); results.add(p); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy