import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
public final class URLUtil {
private URLUtil() {
}
/**
* Method that tries to figure out how to create valid URL from a system id,
* without additional contextual information. If we could use URIs this might
* be easier to do, but they are part of JDK 1.4, and preferably code should
* only require 1.2 (or maybe 1.3)
*/
public static URL urlFromSystemId(String sysId) throws IOException {
try {
/*
* Ok, does it look like a full URL? For one, you need a colon. Also, to
* reduce likelihood of collision with Windows paths, let's only accept it
* if there are 3 preceding other chars... Not sure if Mac might be a
* problem? (it uses ':' as file path separator, alas, at least prior to
* MacOS X)
*/
int ix = sysId.indexOf(':', 0);
/*
* Also, protocols are generally fairly short, usually 3 or 4 chars (http,
* ftp, urn); so let's put upper limit of 8 chars too
*/
if (ix >= 3 && ix <= 8) {
return new URL(sysId);
}
// Ok, let's just assume it's local file reference...
/*
* 24-May-2006, TSa: Amazingly, this single call does show in profiling,
* for small docs. The problem is that deep down it tries to check
* physical file system, to check if the File pointed to is a directory:
* and that is (relatively speaking) a very expensive call. Since in this
* particular case it should never be a dir (and/or doesn't matter), let's
* just implement conversion locally
*/
String absPath = new java.io.File(sysId).getAbsolutePath();
// Need to convert colons/backslashes to regular slashes?
{
char sep = File.separatorChar;
if (sep != '/') {
absPath = absPath.replace(sep, '/');
}
}
if (absPath.length() > 0 && absPath.charAt(0) != '/') {
absPath = "/" + absPath;
}
return new URL("file", "", absPath);
} catch (MalformedURLException e) {
return null; // never gets here
}
}
public static URL urlFromSystemId(String sysId, URL ctxt) throws IOException {
if (ctxt == null) {
return urlFromSystemId(sysId);
}
try {
return new URL(ctxt, sysId);
} catch (MalformedURLException e) {
return null; // never gets here
}
}
/**
* Method that tries to create and return URL that denotes current working
* directory. Usually used to create a context, when one is not explicitly
* passed.
*/
public static URL urlFromCurrentDir() throws java.net.MalformedURLException /*
* an
* IOException
*/
{
/*
* This seems to work; independent of whether there happens to be such/file
* dir or not.
*/
return new File("a").getAbsoluteFile().getParentFile().toURL();
}
/**
* Method that tries to get a stream (ideally, optimal one) to read from the
* specified URL. Currently it just means creating a simple file input stream
* if the URL points to a (local) file, and otherwise relying on URL classes
* input stream creation method.
*/
public static InputStream inputStreamFromURL(URL url) throws IOException {
if ("file".equals(url.getProtocol())) {
/*
* As per [WSTX-82], can not do this if the path refers to a network drive
* on windows. This fixes the problem; might not be needed on all
* platforms (NFS?), but should not matter a lot: performance penalty of
* extra wrapping is more relevant when accessing local file system.
*/
String host = url.getHost();
if (host == null || host.length() == 0) {
return new FileInputStream(url.getPath());
}
}
return url.openStream();
}
/**
* Method that tries to get a stream (ideally, optimal one) to write to the
* resource specified by given URL. Currently it just means creating a simple
* file output stream if the URL points to a (local) file, and otherwise
* relying on URL classes input stream creation method.
*/
public static OutputStream outputStreamFromURL(URL url) throws IOException {
if ("file".equals(url.getProtocol())) {
/*
* As per [WSTX-82], can not do this if the path refers to a network drive
* on windows.
*/
String host = url.getHost();
if (host == null || host.length() == 0) {
return new FileOutputStream(url.getPath());
}
}
return url.openConnection().getOutputStream();
}
}
|