/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import net.sourceforge.pmd.RuleSetNotFoundException;
/**
*/
public final class ResourceLoader {
public static final int TIMEOUT;
static {
int timeoutProperty = 5000;
try {
timeoutProperty = Integer.parseInt(System.getProperty("net.sourceforge.pmd.http.timeout", "5000"));
} catch (NumberFormatException e) {
e.printStackTrace();
}
TIMEOUT = timeoutProperty;
}
// Only static methods, so we shouldn't allow an instance to be created
/**
* Constructor for ResourceLoader.
*/
private ResourceLoader() {
}
/**
* Method to find a file, first by finding it as a file (either by the
* absolute or relative path), then as a URL, and then finally seeing if it
* is on the classpath.
* <p>
* Caller is responsible for closing the {@link InputStream}.
*
* @param name
* String
* @return InputStream
* @throws RuleSetNotFoundException
*/
public static InputStream loadResourceAsStream(String name) throws RuleSetNotFoundException {
InputStream stream = loadResourceAsStream(name, ResourceLoader.class.getClassLoader());
if (stream == null) {
throw new RuleSetNotFoundException("Can't find resource " + name
+ ". Make sure the resource is a valid file or URL or is on the CLASSPATH");
}
return stream;
}
/**
* Uses the ClassLoader passed in to attempt to load the resource if it's
* not a File or a URL
* <p>
* Caller is responsible for closing the {@link InputStream}.
*
* @param name
* String
* @param loader
* ClassLoader
* @return InputStream
* @throws RuleSetNotFoundException
*/
public static InputStream loadResourceAsStream(String name, ClassLoader loader) throws RuleSetNotFoundException {
File file = new File(name);
if (file.exists()) {
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
// if the file didn't exist, we wouldn't be here
}
} else {
try {
HttpURLConnection connection = (HttpURLConnection) new URL(name).openConnection();
connection.setConnectTimeout(TIMEOUT);
connection.setReadTimeout(TIMEOUT);
return connection.getInputStream();
} catch (Exception e) {
try {
/*
* Don't use getResourceAsStream to void reusing connections between threads
* See https://github.com/pmd/pmd/issues/234
*/
URL resource = loader.getResource(name);
if (resource == null) {
// Don't throw RuleSetNotFoundException, keep API compatibility
return null;
} else {
final URLConnection connection = resource.openConnection();
// This avoids reusing the underlaying file, if the resource is loaded from a Jar file.
// The file is closed with the input stream then thus not leaving a leaked resource behind.
// See https://github.com/pmd/pmd/issues/364 and https://github.com/pmd/pmd/issues/337
connection.setUseCaches(false);
final InputStream inputStream = connection.getInputStream();
return inputStream;
}
} catch (IOException e1) {
// Ignored
}
}
}
throw new RuleSetNotFoundException("Can't find resource " + name
+ ". Make sure the resource is a valid file or URL or is on the CLASSPATH");
}
}