com.fasterxml.aalto.util.URLUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aalto-xml Show documentation
Show all versions of aalto-xml Show documentation
Ultra-high performance non-blocking XML processor (Stax/Stax2, SAX/SAX2)
/* Aalto XML processor
*
* Copyright (c) 2006- Tatu Saloranta, [email protected]
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fasterxml.aalto.util;
import java.io.*;
import java.net.URL;
import java.net.MalformedURLException;
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. We could perhaps use
* java.net.URI class in future?
*/
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);
}
return fileToURL(new File(sysId));
} catch (MalformedURLException e) {
throwIoException(e, sysId);
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) {
throwIoException(e, sysId);
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 IOException /* an IOException */
{
/* This seems to work; independent of whether there happens to
* be such/file dir or not.
*/
return fileToURL(new File("a").getAbsoluteFile().getParentFile());
}
/**
* 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())) {
/* On Windows, we can only create file readers for local
* files... not sure about NFS, but let's be conservative:
*/
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 with inputStreamFromURL, avoid probs with Windows network mounts:
String host = url.getHost();
if (host == null || host.length() == 0) {
return new FileOutputStream(url.getPath());
}
}
return url.openConnection().getOutputStream();
}
/**
* This method is added because the default conversion using
* file.toURL()
turns out to be rather slow, as
* it tries to figure out if the file is actually a directory.
* Now, for our use cases this is irrelevant, so we can optimize
* out that expensive part.
*/
public static URL fileToURL(File f)
throws IOException
{
/* Based on earlier experiences, looked like using
* File.toURL() is rather expensive (at least on jdk1.4/1.5),
* so let's just use a faster replacement
*/
String absPath = f.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);
}
public static String fileToSystemId(File f)
throws IOException
{
return fileToURL(f).toExternalForm();
}
public static String urlToSystemId(URL u)
{
return u.toExternalForm();
}
/*
///////////////////////////////////////////
// Private helper methods
///////////////////////////////////////////
*/
/**
* Helper method that tries to fully convert strange URL-specific exception
* to more general IO exception. Also, to try to use JDK 1.4 feature without
* creating requirement, uses reflection to try to set the root cause, if
* we are running on JDK1.4
*/
private static void throwIoException(MalformedURLException mex, String sysId)
throws IOException
{
IOException ie = new IOException("[resolving systemId '"+sysId
+"']: "+mex.toString());
ie.initCause(mex);
throw ie;
}
}