From 74e6b3e046556035112d937239d2de048e65cc6b Mon Sep 17 00:00:00 2001
From: Nikolaus Krismer <niko@krismer.de>
Date: Mon, 19 May 2014 16:04:17 +0200
Subject: [PATCH] reworked config file retrieval for dataset configurations

---
 .../inf/isochrone/config/ConfigDataset.java   |  52 ++++++--
 .../inf/isochrone/util/ResourceHelper.java    | 119 ++++++++----------
 2 files changed, 98 insertions(+), 73 deletions(-)

diff --git a/src/main/java/it/unibz/inf/isochrone/config/ConfigDataset.java b/src/main/java/it/unibz/inf/isochrone/config/ConfigDataset.java
index 867653d2..09f2fff3 100644
--- a/src/main/java/it/unibz/inf/isochrone/config/ConfigDataset.java
+++ b/src/main/java/it/unibz/inf/isochrone/config/ConfigDataset.java
@@ -17,6 +17,7 @@ import it.unibz.inf.isochrone.util.ResourceHelper;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 import java.text.DateFormat;
 import java.text.ParseException;
@@ -26,6 +27,7 @@ import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -35,7 +37,9 @@ import java.util.regex.Pattern;
 
 import javax.validation.constraints.NotNull;
 
+import org.apache.commons.io.Charsets;
 import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -77,7 +81,8 @@ public class ConfigDataset {
 
 	private static final Logger LOGGER = LoggerFactory.getLogger(ConfigDataset.class);
 	private static final Collection<String> ALL_DATASETS = getAvailableDatasets(true);
-	private static final String DS_CONFIG_PATTERN = ".*config\\_(.*)\\.xml";
+	private static final String DS_CONFIG_EXTENSION = "xml";
+	private static final String DS_CONFIG_PATTERN = ".*config\\_(.*)\\." + DS_CONFIG_EXTENSION;
 	private static Map<String, ConfigDataset> instanceMap = new HashMap<>();
 
 	@PropertyValue("client.tArrival")
@@ -361,23 +366,56 @@ public class ConfigDataset {
 
 	protected static Collection<String> getAvailableDatasets(final boolean filterInvalid) {
 		LOGGER.info("Getting available datasets");
+
+		final ClassLoader cLoader = Thread.currentThread().getContextClassLoader();
 		final Pattern dsConfigPattern = Pattern.compile(DS_CONFIG_PATTERN);
 
+		URL r = null;
+		InputStream r2 = null;
 		Collection<String> resources = null;
 		try {
-			final URL r = Thread.currentThread().getContextClassLoader().getResource("/");
-			if (r == null) {
-				resources = ResourceHelper.getResources(dsConfigPattern);
-			} else {
-				final Collection<File> files = FileUtils.listFiles(new File(r.getFile()), null, false);
+			// find resources on disk and add to available ones
+			r = cLoader.getResource("/");
+			if (r != null) {
+				final Collection<File> files = FileUtils.listFiles(new File(r.getFile()), new String[] {DS_CONFIG_EXTENSION}, true);
 				resources = new ArrayList<>(files.size());
 				for (File file : files) {
-					resources.add(file.getName());
+					final String filename = file.getName();
+					if (dsConfigPattern.matcher(filename).matches()) {
+						resources.add(filename);
+					}
+				}
+			}
+
+			// find resources on classpath (in jar files...) and add to available ones
+			r2 = cLoader.getResourceAsStream("/");
+			if (r2 != null) {
+				final Collection<String> files = IOUtils.readLines(r2, Charsets.UTF_8);
+				for (String filename : files) {
+					if (dsConfigPattern.matcher(filename).matches()) {
+						resources.add(filename);
+					}
 				}
 			}
+
+			// find resources on webapp resources (in tomcat lib folder, in WEB-INF...)  and add to available ones
+			final Enumeration<URL> e = cLoader.getResources("../lib");
+			if (e != null) {
+				final Collection<URL> webappResources = Collections.list(e);
+				final Collection<String> files = ResourceHelper.findFilesInResources(webappResources, dsConfigPattern);
+				resources.addAll(files);
+			}
 		} catch (IOException e) {
 			resources = null;
 			LOGGER.warn("Datasets could not be read. There might be no configured datasets available!");
+		} finally {
+			if (r2 != null) {
+				try {
+					r2.close();
+				} catch (IOException e) {
+					LOGGER.debug("Could not close input stream after searching for config files in classpath");
+				}
+			}
 		}
 
 		if (resources == null || resources.size() <= 0) {
diff --git a/src/main/java/it/unibz/inf/isochrone/util/ResourceHelper.java b/src/main/java/it/unibz/inf/isochrone/util/ResourceHelper.java
index f6a64960..2a6c23f2 100644
--- a/src/main/java/it/unibz/inf/isochrone/util/ResourceHelper.java
+++ b/src/main/java/it/unibz/inf/isochrone/util/ResourceHelper.java
@@ -2,103 +2,90 @@ package it.unibz.inf.isochrone.util;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
+import java.net.URL;
 import java.util.Collection;
 import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
 import java.util.regex.Pattern;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
 
-/**
- * Gets available resources (from the classpath) by a regular expression pattern.
- */
 public final class ResourceHelper {
+	private static final String EXTENSION_JAR = ".jar";
+	private static final String PROPERTY_CP = "java.class.path";
 
-	// Constructor
-
-	private ResourceHelper() {}
-
-	// Public static methods
+	private ResourceHelper() { }
 
 	/**
-	 * Gets all resources matching the given pattern.
+	 * Gets all resources matching the given pattern from the path elements given.
 	 *
-	 * @param pattern the pattern to match against (as string)
+	 * @param fileNamePattern the pattern to match against
 	 * @return the resources in the order they are found
 	 * @throws IOException if an I/O error occurs
 	 */
-	public static Collection<String> getResources(final String pattern) throws IOException {
-		return getResources(Pattern.compile(pattern));
-	}
+	public static Set<String> findFilesInResources(final Collection<URL> classPathElements, final Pattern fileNamePattern) throws IOException {
+		final String[] retval = new String[classPathElements.size()];
 
-	/**
-	 * Gets all resources matching the given pattern.
-	 *
-	 * @param pattern the pattern to match against
-	 * @return the resources in the order they are found
-	 * @throws IOException if an I/O error occurs
-	 */
-	public static Collection<String> getResources(final Pattern pattern) throws IOException {
-		final Collection<String> retval = new ArrayList<>();
-		final String classPath = System.getProperty("java.class.path", ".");
-		final String[] classPathElements = classPath.split(File.pathSeparator);
-		for (final String element : classPathElements) {
-			retval.addAll(getResources(element, pattern));
+		int i = 0;
+		for (final URL element : classPathElements) {
+			retval[i++] = element.getFile();
 		}
 
-		return retval;
+		return findFilesInResources(retval, fileNamePattern);
 	}
 
-	// Private static methods
+	public static Set<String> findFilesInResources(final String[] pathElements, final Pattern fileNamePattern) throws IOException {
+		Set<String> result = new HashSet<String>();
+		for (String element : pathElements) {
+			final File newFile = new File(element);
+			if (newFile.isDirectory()) {
+				result.addAll(findResourceInDirectory(newFile, fileNamePattern));
+			} else {
+				result.addAll(findResourceInFile(newFile, fileNamePattern));
+			}
+		}
 
-	private static Collection<String> getResources(final String element, final Pattern pattern) throws IOException {
-		final Collection<String> retval = new ArrayList<>();
+		return result;
+	}
 
-		final File file = new File(element);
-		if (file.isDirectory()) {
-			retval.addAll(getResourcesFromDirectory(file, pattern));
-		} else {
-			retval.addAll(getResourcesFromJarFile(file, pattern));
-		}
+	public static Set<String> findFilesInClassPath(final Pattern fileNamePattern) throws IOException {
+		final String classPath = System.getProperty(PROPERTY_CP);
+		final String[] pathElements = classPath.split(File.pathSeparator);
 
-		return retval;
+		return findFilesInResources(pathElements, fileNamePattern);
 	}
 
-	private static Collection<String> getResourcesFromJarFile(final File file, final Pattern pattern) throws IOException {
-		final Collection<String> retval = new ArrayList<>();
-		try (final ZipFile zf = new ZipFile(file)) {
-			final Enumeration<? extends ZipEntry> e = zf.entries();
-			while (e.hasMoreElements()) {
-				final ZipEntry ze = e.nextElement();
-				final String fileName = ze.getName();
-				final boolean accept = pattern.matcher(fileName).matches();
-				if (accept) {
-					retval.add(fileName);
+	private static Collection<String> findResourceInFile(final File resourceFile, final Pattern fileNamePattern) throws IOException {
+		final Set<String> result = new HashSet<String>();
+		if (resourceFile.canRead() && resourceFile.getAbsolutePath().endsWith(EXTENSION_JAR)) {
+			try (final JarFile jarFile = new JarFile(resourceFile)) {
+				final Enumeration<JarEntry> entries = jarFile.entries();
+				while (entries.hasMoreElements()) {
+					final JarEntry singleEntry = entries.nextElement();
+					if (fileNamePattern.matcher(singleEntry.getName()).matches()) {
+						result.add(jarFile.getName() + File.separatorChar + singleEntry.getName());
+					}
 				}
 			}
-		} catch (final IOException ioe) {
-			throw ioe;
 		}
 
-		return retval;
+		return result;
 	}
 
-	private static Collection<String> getResourcesFromDirectory(final File directory, final Pattern pattern) throws IOException {
-		final Collection<String> retval = new ArrayList<>();
-
-		final File[] fileList = directory.listFiles();
-		for (final File file : fileList) {
-			if (file.isDirectory()) {
-				retval.addAll(getResourcesFromDirectory(file, pattern));
+	private static Set<String> findResourceInDirectory(final File directory, final Pattern fileNamePattern) throws IOException {
+		final Set<String> result = new HashSet<String>();
+		final File[] files = directory.listFiles();
+		for (final File currentFile : files) {
+			if (fileNamePattern.matcher(currentFile.getAbsolutePath()).matches()) {
+				result.add(currentFile.getAbsolutePath());
+			} else if (currentFile.isDirectory()) {
+				result.addAll(findResourceInDirectory(currentFile, fileNamePattern));
 			} else {
-				final String fileName = file.getCanonicalPath();
-				final boolean accept = pattern.matcher(fileName).matches();
-				if (accept) {
-					retval.add(fileName);
-				}
+				result.addAll(findResourceInFile(currentFile, fileNamePattern));
 			}
 		}
 
-		return retval;
+		return result;
 	}
 }
-- 
GitLab