diff options
author | Sven Gothel <[email protected]> | 2013-06-09 05:33:16 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-06-09 05:33:16 +0200 |
commit | b98825eb7cfb61aead4a7dff57471cd2d2c26823 (patch) | |
tree | 8190c7eaac697e4150e47424dc975be512a3979d /src/java/com | |
parent | 959d6d83ec26152343d538287c02eeebf0dcf238 (diff) |
Fix Bug 683 part1: IOUtil, JarUtil, TempJarCache, .. uses URI instead of URL to remove DNS Lookups etc ..
Diffstat (limited to 'src/java/com')
-rw-r--r-- | src/java/com/jogamp/common/jvm/JNILibLoaderBase.java | 41 | ||||
-rw-r--r-- | src/java/com/jogamp/common/net/AssetURLContext.java | 9 | ||||
-rw-r--r-- | src/java/com/jogamp/common/os/NativeLibrary.java | 15 | ||||
-rw-r--r-- | src/java/com/jogamp/common/os/Platform.java | 28 | ||||
-rw-r--r-- | src/java/com/jogamp/common/util/IOUtil.java | 150 | ||||
-rw-r--r-- | src/java/com/jogamp/common/util/JarUtil.java | 271 | ||||
-rw-r--r-- | src/java/com/jogamp/common/util/cache/TempJarCache.java | 149 |
7 files changed, 350 insertions, 313 deletions
diff --git a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java index d0d8003..5621396 100644 --- a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java +++ b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java @@ -42,7 +42,8 @@ package com.jogamp.common.jvm; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Arrays; @@ -145,23 +146,23 @@ public class JNILibLoaderBase { loaderAction = action; } - /* pp */ static final boolean addNativeJarLibsImpl(Class<?> classFromJavaJar, URL classJarURL, String nativeJarBasename, StringBuilder msg) - throws IOException, IllegalArgumentException, SecurityException + /* pp */ static final boolean addNativeJarLibsImpl(Class<?> classFromJavaJar, URI classJarURI, String nativeJarBasename, StringBuilder msg) + throws IOException, SecurityException, URISyntaxException { msg.setLength(0); // reset - msg.append("addNativeJarLibsImpl(classFromJavaJar ").append(classFromJavaJar).append(", classJarURL ").append(classJarURL).append(", nativeJarBaseName ").append(nativeJarBasename).append("): "); + msg.append("addNativeJarLibsImpl(classFromJavaJar ").append(classFromJavaJar).append(", classJarURI ").append(classJarURI).append(", nativeJarBaseName ").append(nativeJarBasename).append("): "); boolean ok = false; if(TempJarCache.isInitialized()) { final String nativeJarName = nativeJarBasename+"-natives-"+PlatformPropsImpl.os_and_arch+".jar"; msg.append(nativeJarName); - final URL jarUrlRoot = JarUtil.getURLDirname( JarUtil.getJarSubURL( classJarURL ) ); - msg.append(" + ").append(jarUrlRoot); - final URL nativeJarURL = JarUtil.getJarFileURL(jarUrlRoot, nativeJarName); - msg.append(" -> ").append(nativeJarURL); + final URI jarUriRoot = JarUtil.getURIDirname( JarUtil.getJarSubURI( classJarURI ) ); + msg.append(" + ").append(jarUriRoot); + final URI nativeJarURI = JarUtil.getJarFileURI(jarUriRoot, nativeJarName); + msg.append(" -> ").append(nativeJarURI); if(DEBUG) { System.err.println(msg.toString()); } - TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURL); + TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI); ok = true; } return ok; @@ -169,7 +170,7 @@ public class JNILibLoaderBase { /** * Loads and adds a JAR file's native library to the TempJarCache.<br> - * The native library JAR file's URL is derived as follows: + * The native library JAR file's URI is derived as follows: * <ul> * <li> [1] <code>GLProfile.class</code> -> </li> * <li> [2] <code>http://lala/</code> -> </li> @@ -178,7 +179,7 @@ public class JNILibLoaderBase { * Where: * <ul> * <li> [1] is the <code>classFromJavaJar</code></li> - * <li> [2] is it's <i>URL path</i></li> + * <li> [2] is it's <i>URI path</i></li> * <li> [4] is the derived native JAR filename</li> * </ul> * @@ -190,8 +191,8 @@ public class JNILibLoaderBase { if(TempJarCache.isInitialized()) { final StringBuilder msg = new StringBuilder(); try { - final URL classJarURL = JarUtil.getJarURL(classFromJavaJar.getName(), classFromJavaJar.getClassLoader()); - return addNativeJarLibsImpl(classFromJavaJar, classJarURL, nativeJarBasename, msg); + final URI classJarURI = JarUtil.getJarURI(classFromJavaJar.getName(), classFromJavaJar.getClassLoader()); + return addNativeJarLibsImpl(classFromJavaJar, classJarURI, nativeJarBasename, msg); } catch (Exception e0) { // IllegalArgumentException, IOException System.err.println("Catched "+e0.getClass().getSimpleName()+": "+e0.getMessage()+", while "+msg.toString()); @@ -207,7 +208,7 @@ public class JNILibLoaderBase { /** * Loads and adds a JAR file's native library to the TempJarCache.<br> - * The native library JAR file's URL is derived as follows: + * The native library JAR file's URI is derived as follows: * <ul> * <li> [1] <code>GLProfile.class</code> -> </li> * <li> [2] <code>http://lala/gluegen-rt.jar</code> -> </li> @@ -217,8 +218,8 @@ public class JNILibLoaderBase { * Where: * <ul> * <li> [1] is one of <code>classesFromJavaJars</code></li> - * <li> [2] is it's complete URL</li> - * <li> [3] is it's <i>base URL</i></li> + * <li> [2] is it's complete URI</li> + * <li> [3] is it's <i>base URI</i></li> * <li> [4] is the derived native JAR filename</li> * </ul> * @@ -256,7 +257,7 @@ public class JNILibLoaderBase { * @param classesFromJavaJars For each given Class, load the native library JAR. * @param singleJarMarker Optional string marker like "-all" to identify the single 'all-in-one' JAR file * after which processing of the class array shall stop. - * @param stripBasenameSuffixes Optional substrings to be stripped of the <i>base URL</i> + * @param stripBasenameSuffixes Optional substrings to be stripped of the <i>base URI</i> * * @return true if either the 'all-in-one' native JAR or all native JARs loaded successful or were loaded already, * false in case of an error @@ -274,14 +275,14 @@ public class JNILibLoaderBase { ok = true; for(int i=0; !done && ok && i<classesFromJavaJars.length && null!=classesFromJavaJars[i]; i++) { final ClassLoader cl = classesFromJavaJars[i].getClassLoader(); - final URL classJarURL = JarUtil.getJarURL(classesFromJavaJars[i].getName(), cl); - final String jarName = JarUtil.getJarBasename(classJarURL); + final URI classJarURI = JarUtil.getJarURI(classesFromJavaJars[i].getName(), cl); + final String jarName = JarUtil.getJarBasename(classJarURI); ok = null != jarName; if(ok) { final String jarBasename = jarName.substring(0, jarName.indexOf(".jar")); // ".jar" already validated w/ JarUtil.getJarBasename(..) final String nativeJarBasename = stripName(jarBasename, stripBasenameSuffixes); done = null != singleJarMarker && jarBasename.indexOf(singleJarMarker) >= 0; // done if single-jar ('all' variant) - ok = JNILibLoaderBase.addNativeJarLibsImpl(classesFromJavaJars[i], classJarURL, nativeJarBasename, msg); + ok = JNILibLoaderBase.addNativeJarLibsImpl(classesFromJavaJars[i], classJarURI, nativeJarBasename, msg); if(ok) { count++; } if(DEBUG && done) { System.err.println("JNILibLoaderBase: addNativeJarLibs0: end after all-in-one JAR: "+jarBasename); diff --git a/src/java/com/jogamp/common/net/AssetURLContext.java b/src/java/com/jogamp/common/net/AssetURLContext.java index 411d986..470530e 100644 --- a/src/java/com/jogamp/common/net/AssetURLContext.java +++ b/src/java/com/jogamp/common/net/AssetURLContext.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; @@ -152,7 +153,11 @@ public abstract class AssetURLContext implements PiggybackURLContext { if(DEBUG) { System.err.println("AssetURLContext.resolve: <"+path+">"); } - path = IOUtil.cleanPathString(path); + try { + path = IOUtil.cleanPathString(path); + } catch (URISyntaxException uriEx) { + throw new IOException(uriEx); + } try { // lookup as valid sub-protocol @@ -180,7 +185,7 @@ public abstract class AssetURLContext implements PiggybackURLContext { try { File file = new File(path); if(file.exists()) { - url = IOUtil.toURLSimple(file); + url = IOUtil.toURISimple(file).toURL(); conn = open(url); type = null != conn ? 3 : -1; } diff --git a/src/java/com/jogamp/common/os/NativeLibrary.java b/src/java/com/jogamp/common/os/NativeLibrary.java index 130812c..2351391 100644 --- a/src/java/com/jogamp/common/os/NativeLibrary.java +++ b/src/java/com/jogamp/common/os/NativeLibrary.java @@ -50,6 +50,7 @@ import jogamp.common.os.WindowsDynamicLinkerImpl; import java.io.*; import java.lang.reflect.*; +import java.net.URISyntaxException; import java.security.*; import java.util.*; @@ -254,7 +255,12 @@ public class NativeLibrary implements DynamicLookupHelper { * @return basename of libName w/o path, ie. /usr/lib/libDrinkBeer.so -> DrinkBeer on Unix systems, but null on Windows. */ public static String isValidNativeLibraryName(String libName, boolean isLowerCaseAlready) { - final String libBaseName = IOUtil.getBasename(libName); + final String libBaseName; + try { + libBaseName = IOUtil.getBasename(libName); + } catch (URISyntaxException uriEx) { + throw new IllegalArgumentException(uriEx); + } final String libBaseNameLC = isLowerCaseAlready ? libBaseName : libBaseName.toLowerCase(); int prefixIdx = -1; for(int i=0; i<prefixes.length && 0 > prefixIdx; i++) { @@ -405,7 +411,12 @@ public class NativeLibrary implements DynamicLookupHelper { // If the library name already has the prefix / suffix added // (principally because we want to force a version number on Unix // operating systems) then just return the library name. - final String libBaseNameLC = IOUtil.getBasename(libName).toLowerCase(); + final String libBaseNameLC; + try { + libBaseNameLC = IOUtil.getBasename(libName).toLowerCase(); + } catch (URISyntaxException uriEx) { + throw new IllegalArgumentException(uriEx); + } int prefixIdx = -1; for(int i=0; i<prefixes.length && 0 > prefixIdx; i++) { diff --git a/src/java/com/jogamp/common/os/Platform.java b/src/java/com/jogamp/common/os/Platform.java index e58e72c..aa9bccd 100644 --- a/src/java/com/jogamp/common/os/Platform.java +++ b/src/java/com/jogamp/common/os/Platform.java @@ -28,7 +28,7 @@ package com.jogamp.common.os; -import java.net.URL; +import java.net.URI; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.concurrent.TimeUnit; @@ -162,19 +162,19 @@ public class Platform extends PlatformPropsImpl { /** <code>true</code> if AWT is available and not in headless mode, otherwise <code>false</code>. */ public static final boolean AWT_AVAILABLE; - private static final URL platformClassJarURL; + private static final URI platformClassJarURI; static { PlatformPropsImpl.initSingleton(); // just documenting the order of static initialization { - URL _platformClassJarURL; + URI _platformClassJarURI; try { - _platformClassJarURL = JarUtil.getJarURL(Platform.class.getName(), Platform.class.getClassLoader()); + _platformClassJarURI = JarUtil.getJarURI(Platform.class.getName(), Platform.class.getClassLoader()); } catch (Exception e) { - _platformClassJarURL = null; + _platformClassJarURI = null; } - platformClassJarURL = _platformClassJarURL; + platformClassJarURI = _platformClassJarURI; } USE_TEMP_JAR_CACHE = (OS_TYPE != OSType.ANDROID) && isRunningFromJarURL() && @@ -228,24 +228,24 @@ public class Platform extends PlatformPropsImpl { * @return true if we're running from a Jar URL, otherwise false */ public static final boolean isRunningFromJarURL() { - return null != platformClassJarURL; + return null != platformClassJarURI; } private static final void loadGlueGenRTImpl() { if(USE_TEMP_JAR_CACHE && TempJarCache.initSingleton()) { String nativeJarName = null; - URL jarUrlRoot = null; - URL nativeJarURL = null; + URI jarUriRoot = null; + URI nativeJarURI = null; try { - final String jarName = JarUtil.getJarBasename(platformClassJarURL); + final String jarName = JarUtil.getJarBasename(platformClassJarURI); final String nativeJarBasename = jarName.substring(0, jarName.indexOf(".jar")); // ".jar" already validated w/ JarUtil.getJarBasename(..) nativeJarName = nativeJarBasename+"-natives-"+PlatformPropsImpl.os_and_arch+".jar"; - jarUrlRoot = JarUtil.getURLDirname( JarUtil.getJarSubURL(platformClassJarURL) ); - nativeJarURL = JarUtil.getJarFileURL(jarUrlRoot, nativeJarName); - TempJarCache.bootstrapNativeLib(Platform.class, libBaseName, nativeJarURL); + jarUriRoot = JarUtil.getURIDirname( JarUtil.getJarSubURI( platformClassJarURI ) ); + nativeJarURI = JarUtil.getJarFileURI(jarUriRoot, nativeJarName); + TempJarCache.bootstrapNativeLib(Platform.class, libBaseName, nativeJarURI); } catch (Exception e0) { // IllegalArgumentException, IOException - System.err.println("Catched "+e0.getClass().getSimpleName()+": "+e0.getMessage()+", while TempJarCache.bootstrapNativeLib() of "+nativeJarURL+" ("+jarUrlRoot+" + "+nativeJarName+")"); + System.err.println("Catched "+e0.getClass().getSimpleName()+": "+e0.getMessage()+", while TempJarCache.bootstrapNativeLib() of "+nativeJarURI+" ("+jarUriRoot+" + "+nativeJarName+")"); } } DynamicLibraryBundle.GlueJNILibLoader.loadLibrary(libBaseName, false, Platform.class.getClassLoader()); diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java index c07ca63..d2b97a0 100644 --- a/src/java/com/jogamp/common/util/IOUtil.java +++ b/src/java/com/jogamp/common/util/IOUtil.java @@ -40,7 +40,8 @@ import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; import java.lang.reflect.Constructor; -import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.nio.ByteBuffer; @@ -57,6 +58,11 @@ import com.jogamp.common.os.Platform; public class IOUtil { public static final boolean DEBUG = Debug.debug("IOUtil"); + public static final String JAR_SCHEME = "jar"; + public static final String FILE_SCHEME = "file"; + public static final String HTTP_SCHEME = "http"; + public static final String HTTPS_SCHEME = "https"; + /** Std. temporary directory property key <code>java.io.tmpdir</code> */ public static final String java_io_tmpdir_propkey = "java.io.tmpdir"; public static final String user_home_propkey = "user.home"; @@ -266,9 +272,9 @@ public class IOUtil { * @param startWithSlash * @param endWithSlash * @return - * @throws RuntimeException if final path is empty or has no parent directory available while resolving <code>../</code> + * @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code> */ - public static String slashify(String path, boolean startWithSlash, boolean endWithSlash) throws RuntimeException { + public static String slashify(String path, boolean startWithSlash, boolean endWithSlash) throws URISyntaxException { String p = path.replace('\\', '/'); // unify file seperator if (startWithSlash && !p.startsWith("/")) { p = "/" + p; @@ -276,25 +282,25 @@ public class IOUtil { if (endWithSlash && !p.endsWith("/")) { p = p + "/"; } - try { - return cleanPathString(p); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - } - - /** Using the proper advertised conversion via File -> URI -> URL */ - public static URL toURL(File file) throws MalformedURLException { - return file.toURI().toURL(); + return cleanPathString(p); } - /** Using the simple conversion via File -> URL, assuming proper characters. */ - public static URL toURLSimple(File file) throws MalformedURLException { - return new URL("file", "", slashify(file.getAbsolutePath(), true, file.isDirectory())); + /** + * Using the simple conversion via File -> URI, assuming proper characters. + * @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code> + * @throws URISyntaxException if the resulting string does not comply w/ an RFC 2396 URI + */ + public static URI toURISimple(File file) throws URISyntaxException { + return new URI(FILE_SCHEME, null, slashify(file.getAbsolutePath(), true, file.isDirectory()), null); } - public static URL toURLSimple(String protocol, String file, boolean isDirectory) throws MalformedURLException { - return new URL(protocol, "", slashify(file, true, isDirectory)); + /** + * Using the simple conversion via File -> URI, assuming proper characters. + * @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code> + * @throws URISyntaxException if the resulting string does not comply w/ an RFC 2396 URI + */ + public static URI toURISimple(String protocol, String file, boolean isDirectory) throws URISyntaxException { + return new URI(protocol, null, slashify(file, true, isDirectory), null); } /** @@ -374,8 +380,9 @@ public class IOUtil { /** * Returns the basename of the given fname w/o directory part + * @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code> */ - public static String getBasename(String fname) { + public static String getBasename(String fname) throws URISyntaxException { fname = slashify(fname, false, false); int lios = fname.lastIndexOf('/'); // strip off dirname if(lios>=0) { @@ -386,8 +393,9 @@ public class IOUtil { /** * Returns unified '/' dirname including the last '/' + * @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code> */ - public static String getDirname(String fname) { + public static String getDirname(String fname) throws URISyntaxException { fname = slashify(fname, false, false); int lios = fname.lastIndexOf('/'); // strip off dirname if(lios>=0) { @@ -502,8 +510,9 @@ public class IOUtil { * * @param baseLocation denotes a directory * @param relativeFile denotes a relative file to the baseLocation + * @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code> */ - public static String getRelativeOf(File baseLocation, String relativeFile) { + public static String getRelativeOf(File baseLocation, String relativeFile) throws URISyntaxException { if(null == relativeFile) { return null; } @@ -519,21 +528,21 @@ public class IOUtil { /** * @param path assuming a slashified path beginning with "/" as it's root directory, either denotes a file or directory. * @return parent of path - * @throws MalformedURLException if path is empty or has parent no directory available + * @throws URISyntaxException if path is empty or has no parent directory available */ - public static String getParentOf(String path) throws MalformedURLException { + public static String getParentOf(String path) throws URISyntaxException { final int pl = null!=path ? path.length() : 0; if(pl == 0) { - throw new MalformedURLException("path is empty <"+path+">"); + throw new IllegalArgumentException("path is empty <"+path+">"); } final int e = path.lastIndexOf("/"); if( e < 0 ) { - throw new MalformedURLException("path contains no '/' <"+path+">"); + throw new URISyntaxException(path, "path contains no '/'"); } if( e == 0 ) { // path is root directory - throw new MalformedURLException("path has no parents <"+path+">"); + throw new URISyntaxException(path, "path has no parents"); } if( e < pl - 1 ) { // path is file, return it's parent directory @@ -545,15 +554,15 @@ public class IOUtil { if( p >= j) { return path.substring(0, p+1); } - throw new MalformedURLException("parent of path contains no '/' <"+path+">"); + throw new URISyntaxException(path, "parent of path contains no '/'"); } /** * @param path assuming a slashified path beginning with "/" as it's root directory, either denotes a file or directory. * @return clean path string where <code>../</code> and <code>./</code> is resolved. - * @throws MalformedURLException if path is empty or has no parent directory available while resolving <code>../</code> + * @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code> */ - public static String cleanPathString(String path) throws MalformedURLException { + public static String cleanPathString(String path) throws URISyntaxException { int idx; while ( ( idx = path.indexOf("../") ) >= 0 ) { path = getParentOf(path.substring(0, idx)) + path.substring(idx+3); @@ -565,51 +574,56 @@ public class IOUtil { } /** - * Generates a path for the 'relativeFile' relative to the 'baseLocation', + * Generates a URI for the <i>relativePath</i> relative to the <i>baseURI</i>, * hence the result is a absolute location. + * <p> + * Impl. operates on the <i>scheme-specific-part</i>, and hence is sub-protocol savvy. + * </p> + * <p> + * In case <i>baseURI</i> is not a path ending w/ '/', it's a assumed to be a file and it's parent is being used. + * </p> * - * @param baseLocation denotes a URL to a directory if ending w/ '/', otherwise we assume a file - * @param relativeFile denotes a relative file to the baseLocation's parent directory - * @throws MalformedURLException - */ - public static URL getRelativeOf(URL baseLocation, String relativeFile) throws MalformedURLException { - final String scheme = baseLocation.getProtocol(); - final String auth = baseLocation.getAuthority(); - String path = baseLocation.getPath(); - String query = baseLocation.getQuery(); - String fragment = baseLocation.getRef(); - - if(!path.endsWith("/")) { - path = getParentOf(path); - } - return compose(scheme, auth, path, relativeFile, query, fragment); + * @param baseURI denotes a URI to a directory ending w/ '/', or a file. In the latter case the file's directory is being used. + * @param relativePath denotes a relative file to the baseLocation's parent directory + * @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code> + */ + public static URI getRelativeOf(URI baseURI, String relativePath) throws URISyntaxException { + return compose(baseURI.getScheme(), baseURI.getRawSchemeSpecificPart(), relativePath, baseURI.getRawFragment()); } - public static URL compose(String scheme, String auth, String path1, String path2, String query, String fragment) throws MalformedURLException { - StringBuilder sb = new StringBuilder(); - if(null!=scheme) { - sb.append(scheme); - sb.append(":"); - } - if(null!=auth) { - sb.append("//"); - sb.append(auth); - } - if(null!=path1) { - sb.append(path1); - } - if(null!=path2) { - sb.append(path2); - } - if(null!=query) { - sb.append("?"); - sb.append(query); + /** + * Generates a URI for the <i>relativePath</i> relative to the <i>schemeSpecificPart</i>, + * hence the result is a absolute location. + * <p> + * <i>schemeSpecificPart</i>'s query, if exist is split to <i>path</i> and <i>query</i>. + * </p> + * <p> + * In case <i>path</i> is not a path ending w/ '/', it's a assumed to be a file and it's parent is being used. + * </p> + * + * @param scheme scheme of the resulting URI + * @param schemeSpecificPart may include a query, which is separated while processing + * @param relativePath denotes a relative file to the baseLocation's parent directory + * @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code> + */ + public static URI compose(String scheme, String schemeSpecificPart, String relativePath, String fragment) throws URISyntaxException { + // cut off optional query in scheme-specific-part + final String query; + final int queryI = schemeSpecificPart.lastIndexOf('?'); + if( queryI >= 0 ) { + query = schemeSpecificPart.substring(queryI+1); + schemeSpecificPart = schemeSpecificPart.substring(0, queryI); + } else { + query = null; } - if(null!=fragment) { - sb.append("#"); - sb.append(fragment); + if( null != relativePath ) { + if( null != relativePath && !schemeSpecificPart.endsWith("/") ) { + schemeSpecificPart = getParentOf(schemeSpecificPart); + } + schemeSpecificPart = schemeSpecificPart + relativePath; } - return new URL(cleanPathString(sb.toString())); + schemeSpecificPart = cleanPathString( schemeSpecificPart ); + return new URI(scheme, null == query ? schemeSpecificPart : schemeSpecificPart + "?" + query, fragment); } /** diff --git a/src/java/com/jogamp/common/util/JarUtil.java b/src/java/com/jogamp/common/util/JarUtil.java index cfdf126..4045cfa 100644 --- a/src/java/com/jogamp/common/util/JarUtil.java +++ b/src/java/com/jogamp/common/util/JarUtil.java @@ -35,7 +35,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.JarURLConnection; -import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.security.cert.Certificate; @@ -56,11 +57,11 @@ public class JarUtil { * Interface allowing users to provide an URL resolver that will convert custom classloader * URLs like Eclipse/OSGi <i>bundleresource:</i> URLs to normal <i>jar:</i> URLs. * <p> - * This might be required for custom classloader where the URL protocol is unknown + * This might be required for custom classloader where the URI protocol is unknown * to the standard runtime environment. * </p> * <p> - * Note: The provided resolver is only utilized if a given URL's protocol could not be resolved. + * Note: The provided resolver is only utilized if a given URI's protocol could not be resolved. * I.e. it will not be invoked for known protocols like <i>http</i>, <i>https</i>, <i>jar</i> or <i>file</i>. * </p> */ @@ -98,8 +99,8 @@ public class JarUtil { /** * Returns <code>true</code> if the Class's <code>"com.jogamp.common.GlueGenVersion"</code> - * is loaded from a JarFile and hence has a Jar URL like - * URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class"</code>. + * is loaded from a JarFile and hence has a Jar URI like + * URI <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class"</code>. * <p> * <i>sub_protocol</i> may be "file", "http", etc.. * </p> @@ -107,19 +108,18 @@ public class JarUtil { * @param clazzBinName "com.jogamp.common.GlueGenVersion" * @param cl * @return true if the class is loaded from a Jar file, otherwise false. - * @see {@link #getJarURL(String, ClassLoader)} + * @see {@link #getJarURI(String, ClassLoader)} */ - public static boolean hasJarURL(String clazzBinName, ClassLoader cl) { + public static boolean hasJarURI(String clazzBinName, ClassLoader cl) { try { - final URL url = getJarURL(clazzBinName, cl); - return null != url; + return null != getJarURI(clazzBinName, cl); } catch (Exception e) { /* ignore */ } return false; } /** * The Class's <code>"com.jogamp.common.GlueGenVersion"</code> - * URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class"</code> + * URI <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class"</code> * will be returned. * <p> * <i>sub_protocol</i> may be "file", "http", etc.. @@ -128,103 +128,104 @@ public class JarUtil { * @param clazzBinName "com.jogamp.common.GlueGenVersion" * @param cl ClassLoader to locate the JarFile * @return "jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class" - * @throws IllegalArgumentException if the URL doesn't match the expected formatting or null arguments + * @throws IllegalArgumentException if the URI doesn't match the expected formatting or null arguments * @throws IOException if the class's Jar file could not been found by the ClassLoader + * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static URL getJarURL(String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException { + public static URI getJarURI(String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException { if(null == clazzBinName || null == cl) { throw new IllegalArgumentException("null arguments: clazzBinName "+clazzBinName+", cl "+cl); } - final URL url; - final String urlS; + final URI uri; { - final URL _url = IOUtil.getClassURL(clazzBinName, cl); - final String _urlS = _url.toExternalForm(); - if( resolver != null && - !_urlS.startsWith("jar:") && - !_urlS.startsWith("file:") && - !_urlS.startsWith("http:") && - !_urlS.startsWith("https:") ) + final URL url = IOUtil.getClassURL(clazzBinName, cl); + final String scheme = url.getProtocol(); + if( null != resolver && + !scheme.startsWith( IOUtil.JAR_SCHEME ) && + !scheme.startsWith( IOUtil.FILE_SCHEME ) && + !scheme.startsWith( IOUtil.HTTP_SCHEME ) && + !scheme.startsWith( IOUtil.HTTPS_SCHEME ) ) { - url = resolver.resolve(_url); - urlS = url.toExternalForm(); + final URL _url = resolver.resolve( url ); + uri = _url.toURI(); if(DEBUG) { - System.out.println("getJarURL Resolver: "+_urlS+" -> "+urlS); + System.out.println("getJarURI Resolver: "+url+"\n\t-> "+_url+"\n\t-> "+uri); } } else { - url = _url; - urlS = _urlS; + uri = url.toURI(); + if(DEBUG) { + System.out.println("getJarURI Default "+url+"\n\t-> "+uri); + } } } // test name .. - if(DEBUG) { - System.out.println("getJarURL "+urlS); + if( !uri.getScheme().equals( IOUtil.JAR_SCHEME ) ) { + throw new IllegalArgumentException("URI is not using scheme "+IOUtil.JAR_SCHEME+": <"+uri+">"); } - if(!urlS.startsWith("jar:")) { - throw new IllegalArgumentException("JAR URL doesn't start with 'jar:', got <"+urlS+">"); - } - return url; + return uri; } /** - * The Class's Jar URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class</code> + * The Class's Jar URI <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class</code> * Jar basename <code>gluegen-rt.jar</code> will be returned. * <p> * <i>sub_protocol</i> may be "file", "http", etc.. * </p> * - * @param classJarURL as retrieved w/ {@link #getJarURL(String, ClassLoader) getJarURL("com.jogamp.common.GlueGenVersion", cl)}, + * @param classJarURI as retrieved w/ {@link #getJarURI(String, ClassLoader) getJarURI("com.jogamp.common.GlueGenVersion", cl).toURI()}, * i.e. <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class</code> * @return <code>gluegen-rt.jar</code> - * @throws IllegalArgumentException if the URL doesn't match the expected formatting or is null + * @throws IllegalArgumentException if the URI doesn't match the expected formatting or is null * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static String getJarBasename(URL classJarURL) throws IllegalArgumentException { - if(null == classJarURL) { - throw new IllegalArgumentException("URL is null"); + public static String getJarBasename(URI classJarURI) throws IllegalArgumentException { + if(null == classJarURI) { + throw new IllegalArgumentException("URI is null"); + } + if( !classJarURI.getScheme().equals(IOUtil.JAR_SCHEME) ) { + throw new IllegalArgumentException("URI is not using scheme "+IOUtil.JAR_SCHEME+": <"+classJarURI+">"); } - String urlS = classJarURL.toExternalForm(); - urlS = urlS.substring(4, urlS.length()); // exclude 'jar:' + String uriS = classJarURI.getRawSchemeSpecificPart(); // from // file:/some/path/gluegen-rt.jar!/com/jogamp/common/util/cache/TempJarCache.class // to // file:/some/path/gluegen-rt.jar - int idx = urlS.lastIndexOf('!'); + int idx = uriS.lastIndexOf('!'); if (0 <= idx) { - urlS = urlS.substring(0, idx); // exclude '!/' + uriS = uriS.substring(0, idx); // exclude '!/' } else { - throw new IllegalArgumentException("JAR URL does not contain jar url terminator '!', in <"+classJarURL.toExternalForm()+">, got <"+urlS+">"); + throw new IllegalArgumentException("JAR URI does not contain jar uri terminator '!', in <"+classJarURI+">"); } // from // file:/some/path/gluegen-rt.jar // to // gluegen-rt.jar - idx = urlS.lastIndexOf('/'); + idx = uriS.lastIndexOf('/'); if(0 > idx) { // no abs-path, check for protocol terminator ':' - idx = urlS.lastIndexOf(':'); + idx = uriS.lastIndexOf(':'); if(0 > idx) { - throw new IllegalArgumentException("JAR URL does not contain protocol terminator ':', in <"+classJarURL.toExternalForm()+">, got <"+urlS+">"); + throw new IllegalArgumentException("JAR URI does not contain protocol terminator ':', in <"+classJarURI+">"); } } - urlS = urlS.substring(idx+1); // just the jar name + uriS = uriS.substring(idx+1); // just the jar name - if(0 >= urlS.lastIndexOf(".jar")) { - throw new IllegalArgumentException("No Jar name in <"+classJarURL.toExternalForm()+">, got <"+urlS+">"); + if(0 >= uriS.lastIndexOf(".jar")) { + throw new IllegalArgumentException("No Jar name in <"+classJarURI+">"); } if(DEBUG) { - System.out.println("getJarName res: "+urlS); + System.out.println("getJarName res: "+uriS); } - return urlS; + return uriS; } /** * The Class's <code>com.jogamp.common.GlueGenVersion</code> - * URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class</code> + * URI <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class</code> * Jar basename <code>gluegen-rt.jar</code> will be returned. * <p> * <i>sub_protocol</i> may be "file", "http", etc.. @@ -233,60 +234,63 @@ public class JarUtil { * @param clazzBinName <code>com.jogamp.common.GlueGenVersion</code> * @param cl * @return <code>gluegen-rt.jar</code> - * @throws IllegalArgumentException if the URL doesn't match the expected formatting - * @throws IOException if the class's Jar file could not been found by the ClassLoader + * @throws IllegalArgumentException if the URI doesn't match the expected formatting + * @throws IOException if the class's Jar file could not been found by the ClassLoader. + * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static String getJarBasename(String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException { - return getJarBasename(getJarURL(clazzBinName, cl)); + public static String getJarBasename(String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException { + return getJarBasename( getJarURI(clazzBinName, cl) ); } /** - * The Class's Jar URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class</code> - * Jar file's sub URL <code><i>sub_protocol</i>:/some/path/gluegen-rt.jar</code> will be returned. + * The Class's Jar URI <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class</code> + * Jar file's sub URI <code><i>sub_protocol</i>:/some/path/gluegen-rt.jar</code> will be returned. * <p> * <i>sub_protocol</i> may be "file", "http", etc.. * </p> * - * @param classJarURL as retrieved w/ {@link #getJarURL(String, ClassLoader) getJarURL("com.jogamp.common.GlueGenVersion", cl)}, + * @param classJarURI as retrieved w/ {@link #getJarURI(String, ClassLoader) getJarURI("com.jogamp.common.GlueGenVersion", cl).toURI()}, * i.e. <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class</code> * @param cl * @return <code><i>sub_protocol</i>:/some/path/gluegen-rt.jar</code> - * @throws IllegalArgumentException if the URL doesn't match the expected formatting or is null - * @throws MalformedURLException if the computed URL specifies an unknown protocol + * @throws IllegalArgumentException if the URI doesn't match the expected formatting or is null + * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static URL getJarSubURL(URL classJarURL) throws IllegalArgumentException, MalformedURLException { - if(null == classJarURL) { - throw new IllegalArgumentException("URL is null"); + public static URI getJarSubURI(URI classJarURI) throws IllegalArgumentException, URISyntaxException { + if(null == classJarURI) { + throw new IllegalArgumentException("URI is null"); + } + if( !classJarURI.getScheme().equals(IOUtil.JAR_SCHEME) ) { + throw new IllegalArgumentException("URI is not a using scheme "+IOUtil.JAR_SCHEME+": <"+classJarURI+">"); } - String urlS = classJarURL.toExternalForm(); - urlS = urlS.substring(4, urlS.length()); // exclude 'jar:' + String uriS = classJarURI.getRawSchemeSpecificPart(); // from // file:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class // to // file:/some/path/gluegen-rt.jar - int idx = urlS.lastIndexOf('!'); + int idx = uriS.lastIndexOf('!'); if (0 <= idx) { - urlS = urlS.substring(0, idx); // exclude '!/' + uriS = uriS.substring(0, idx); // exclude '!/' } else { - throw new IllegalArgumentException("JAR URL does not contain jar url terminator '!', url <"+urlS+">"); + throw new IllegalArgumentException("JAR URI does not contain jar uri terminator '!', uri <"+classJarURI+">"); } - if(0 >= urlS.lastIndexOf(".jar")) { - throw new IllegalArgumentException("No Jar name in <"+classJarURL.toExternalForm()+">, got <"+urlS+">"); + if(0 >= uriS.lastIndexOf(".jar")) { + throw new IllegalArgumentException("No Jar name in <"+classJarURI+">"); } if(DEBUG) { - System.out.println("getJarSubURL res: "+urlS); + System.out.println("getJarSubURI res: "+uriS); } - return new URL(urlS); + return new URI(uriS); } /** * The Class's <code>com.jogamp.common.GlueGenVersion</code> - * URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class</code> - * Jar file's sub URL <code><i>sub_protocol</i>:/some/path/gluegen-rt.jar</code> will be returned. + * URI <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class</code> + * Jar file's sub URI <code><i>sub_protocol</i>:/some/path/gluegen-rt.jar</code> will be returned. * <p> * <i>sub_protocol</i> may be "file", "http", etc.. * </p> @@ -294,18 +298,19 @@ public class JarUtil { * @param clazzBinName <code>com.jogamp.common.GlueGenVersion</code> * @param cl * @return <code><i>sub_protocol</i>:/some/path/gluegen-rt.jar</code> - * @throws IllegalArgumentException if the URL doesn't match the expected formatting + * @throws IllegalArgumentException if the URI doesn't match the expected formatting * @throws IOException if the class's Jar file could not been found by the ClassLoader + * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static URL getJarSubURL(String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException { - return getJarSubURL(getJarURL(clazzBinName, cl)); + public static URI getJarSubURI(String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException { + return getJarSubURI( getJarURI(clazzBinName, cl) ); } /** * The Class's <code>"com.jogamp.common.GlueGenVersion"</code> - * URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class"</code> - * Jar file URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/</code> will be returned. + * URI <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class"</code> + * Jar file URI <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/</code> will be returned. * <p> * <i>sub_protocol</i> may be "file", "http", etc.. * </p> @@ -313,101 +318,101 @@ public class JarUtil { * @param clazzBinName "com.jogamp.common.GlueGenVersion" * @param cl * @return "jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/" - * @throws IllegalArgumentException if the URL doesn't match the expected formatting or null arguments + * @throws IllegalArgumentException if the URI doesn't match the expected formatting or null arguments * @throws IOException if the class's Jar file could not been found by the ClassLoader + * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static URL getJarFileURL(String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException { + public static URI getJarFileURI(String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException { if(null == clazzBinName || null == cl) { throw new IllegalArgumentException("null arguments: clazzBinName "+clazzBinName+", cl "+cl); } - URL url = getJarSubURL(clazzBinName, cl); - url = new URL("jar:"+url.toExternalForm()+"!/"); + final URI uri = new URI(IOUtil.JAR_SCHEME, getJarSubURI(clazzBinName, cl).toString()+"!/", null); if(DEBUG) { - System.out.println("getJarFileURL res: "+url); + System.out.println("getJarFileURI res: "+uri); } - return url; + return uri; } /** - * The URL's <code><i>protocol</i>:/some/path/gluegen-rt.jar</code> - * parent dirname URL <code><i>protocol</i>:/some/path/</code> will be returned. + * The URI's <code><i>protocol</i>:/some/path/gluegen-rt.jar</code> + * parent dirname URI <code><i>protocol</i>:/some/path/</code> will be returned. * <p> * <i>protocol</i> may be "file", "http", etc.. * </p> * - * @param aURL "<i>protocol</i>:/some/path/gluegen-rt.jar" + * @param aURI "<i>protocol</i>:/some/path/gluegen-rt.jar" * @return "<i>protocol</i>:/some/path/" - * @throws IllegalArgumentException if the URL doesn't match the expected formatting, or is null - * @throws MalformedURLException + * @throws IllegalArgumentException if the URI doesn't match the expected formatting, or is null + * @throws URISyntaxException */ - public static URL getURLDirname(URL aURL) throws IllegalArgumentException, MalformedURLException { - if(null == aURL) { - throw new IllegalArgumentException("URL is null"); + public static URI getURIDirname(URI aURI) throws IllegalArgumentException, URISyntaxException { + if(null == aURI) { + throw new IllegalArgumentException("URI is null"); } - String urlS = aURL.toExternalForm(); + String uriS = aURI.toString(); if(DEBUG) { - System.out.println("getURLDirname "+aURL+", extForm: "+urlS); + System.out.println("getURIDirname "+aURI+", extForm: "+uriS); } // from // file:/some/path/gluegen-rt.jar _or_ rsrc:gluegen-rt.jar // to // file:/some/path/ _or_ rsrc: - int idx = urlS.lastIndexOf('/'); + int idx = uriS.lastIndexOf('/'); if(0 > idx) { // no abs-path, check for protocol terminator ':' - idx = urlS.lastIndexOf(':'); + idx = uriS.lastIndexOf(':'); if(0 > idx) { - throw new IllegalArgumentException("URL does not contain protocol terminator ':', in <"+aURL.toExternalForm()+">, got <"+urlS+">"); + throw new IllegalArgumentException("URI does not contain protocol terminator ':', in <"+aURI+">"); } } - urlS = urlS.substring(0, idx+1); // exclude jar name, include terminal '/' or ':' + uriS = uriS.substring(0, idx+1); // exclude jar name, include terminal '/' or ':' if(DEBUG) { - System.out.println("getJarURLDirname res: "+urlS); + System.out.println("getJarURIDirname res: "+uriS); } - return new URL(urlS); + return new URI(uriS); } /** - * @param baseUrl file:/some/path/ + * @param baseUri file:/some/path/ * @param jarFileName gluegen-rt.jar * @return jar:file:/some/path/gluegen-rt.jar!/ - * @throws MalformedURLException + * @throws URISyntaxException * @throws IllegalArgumentException null arguments */ - public static URL getJarFileURL(URL baseUrl, String jarFileName) throws IOException, MalformedURLException { - if(null == baseUrl || null == jarFileName) { - throw new IllegalArgumentException("null arguments: baseUrl "+baseUrl+", jarFileName "+jarFileName); + public static URI getJarFileURI(URI baseUri, String jarFileName) throws IllegalArgumentException, URISyntaxException { + if(null == baseUri || null == jarFileName) { + throw new IllegalArgumentException("null arguments: baseURI "+baseUri+", jarFileName "+jarFileName); } - return new URL("jar:"+baseUrl.toExternalForm()+jarFileName+"!/"); + return new URI(IOUtil.JAR_SCHEME, baseUri.toString()+jarFileName+"!/", null); } /** - * @param jarSubUrl file:/some/path/gluegen-rt.jar + * @param jarSubUri file:/some/path/gluegen-rt.jar * @return jar:file:/some/path/gluegen-rt.jar!/ - * @throws MalformedURLException * @throws IllegalArgumentException null arguments + * @throws URISyntaxException */ - public static URL getJarFileURL(URL jarSubUrl) throws MalformedURLException, IllegalArgumentException { - if(null == jarSubUrl) { - throw new IllegalArgumentException("jarSubUrl is null"); + public static URI getJarFileURI(URI jarSubUri) throws IllegalArgumentException, URISyntaxException { + if(null == jarSubUri) { + throw new IllegalArgumentException("jarSubURI is null"); } - return new URL("jar:"+jarSubUrl.toExternalForm()+"!/"); + return new URI(IOUtil.JAR_SCHEME, jarSubUri.toString()+"!/", null); } /** - * @param jarFileURL jar:file:/some/path/gluegen-rt.jar!/ + * @param jarFileURI jar:file:/some/path/gluegen-rt.jar!/ * @param jarEntry com/jogamp/common/GlueGenVersion.class * @return jar:file:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class - * @throws MalformedURLException * @throws IllegalArgumentException null arguments + * @throws URISyntaxException */ - public static URL getJarEntryURL(URL jarFileURL, String jarEntry) throws MalformedURLException, IllegalArgumentException { + public static URI getJarEntryURI(URI jarFileURI, String jarEntry) throws IllegalArgumentException, URISyntaxException { if(null == jarEntry) { throw new IllegalArgumentException("jarEntry is null"); } - return new URL(jarFileURL.toExternalForm()+jarEntry); + return new URI(jarFileURI.toString()+jarEntry); } /** @@ -416,28 +421,30 @@ public class JarUtil { * @return JarFile containing the named class within the given ClassLoader * @throws IOException if the class's Jar file could not been found by the ClassLoader * @throws IllegalArgumentException null arguments - * @see {@link #getJarFileURL(String, ClassLoader)} + * @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI + * @see {@link #getJarFileURI(String, ClassLoader)} */ - public static JarFile getJarFile(String clazzBinName, ClassLoader cl) throws IOException, IllegalArgumentException { - return getJarFile(getJarFileURL(clazzBinName, cl)); + public static JarFile getJarFile(String clazzBinName, ClassLoader cl) throws IOException, IllegalArgumentException, URISyntaxException { + return getJarFile( getJarFileURI(clazzBinName, cl) ); } /** - * @param jarFileURL jar:file:/some/path/gluegen-rt.jar!/ - * @return JarFile as named by URL within the given ClassLoader + * @param jarFileURI jar:file:/some/path/gluegen-rt.jar!/ + * @return JarFile as named by URI within the given ClassLoader * @throws IllegalArgumentException null arguments * @throws IOException if the Jar file could not been found */ - public static JarFile getJarFile(URL jarFileUrl) throws IOException, IllegalArgumentException { - if(null == jarFileUrl) { - throw new IllegalArgumentException("null jarFileUrl"); + public static JarFile getJarFile(URI jarFileURI) throws IOException, IllegalArgumentException { + if(null == jarFileURI) { + throw new IllegalArgumentException("null jarFileURI"); } if(DEBUG) { - System.out.println("getJarFile: "+jarFileUrl); - } - URLConnection urlc = jarFileUrl.openConnection(); + System.out.println("getJarFile: "+jarFileURI); + } + final URL jarFileURL = jarFileURI.toURL(); + final URLConnection urlc = jarFileURL.openConnection(); if(urlc instanceof JarURLConnection) { - JarURLConnection jarConnection = (JarURLConnection)jarFileUrl.openConnection(); + JarURLConnection jarConnection = (JarURLConnection)jarFileURL.openConnection(); JarFile jarFile = jarConnection.getJarFile(); if(DEBUG) { System.out.println("getJarFile res: "+jarFile.getName()); @@ -458,8 +465,8 @@ public class JarUtil { System.err.println("JarUtil: getNativeLibNames: "+jarFile); } - Map<String,String> nameMap = new HashMap<String, String>(); - Enumeration<JarEntry> entries = jarFile.entries(); + final Map<String,String> nameMap = new HashMap<String, String>(); + final Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { final JarEntry entry = entries.nextElement(); diff --git a/src/java/com/jogamp/common/util/cache/TempJarCache.java b/src/java/com/jogamp/common/util/cache/TempJarCache.java index 6f24c68..b17dd52 100644 --- a/src/java/com/jogamp/common/util/cache/TempJarCache.java +++ b/src/java/com/jogamp/common/util/cache/TempJarCache.java @@ -34,8 +34,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.security.cert.Certificate; import java.util.Enumeration; import java.util.HashMap; @@ -75,9 +75,9 @@ public class TempJarCache { } // Set of jar files added - private static Map<URL, LoadState> nativeLibJars; - private static Map<URL, LoadState> classFileJars; - private static Map<URL, LoadState> resourceFileJars; + private static Map<URI, LoadState> nativeLibJars; + private static Map<URI, LoadState> classFileJars; + private static Map<URI, LoadState> resourceFileJars; private static TempFileCache tmpFileCache; @@ -104,9 +104,9 @@ public class TempJarCache { if(!staticInitError) { // Initialize the collections of resources nativeLibMap = new HashMap<String, String>(); - nativeLibJars = new HashMap<URL, LoadState>(); - classFileJars = new HashMap<URL, LoadState>(); - resourceFileJars = new HashMap<URL, LoadState>(); + nativeLibJars = new HashMap<URI, LoadState>(); + classFileJars = new HashMap<URI, LoadState>(); + resourceFileJars = new HashMap<URI, LoadState>(); } if(DEBUG) { System.err.println("TempJarCache.initSingleton(): ok "+(false==staticInitError)+", "+ tmpFileCache.getTempDir()); @@ -175,52 +175,51 @@ public class TempJarCache { return tmpFileCache; } - public synchronized static boolean checkNativeLibs(URL jarURL, LoadState exp) throws IOException { + public synchronized static boolean checkNativeLibs(URI jarURI, LoadState exp) throws IOException { checkInitialized(); - if(null == jarURL) { - throw new IllegalArgumentException("jarURL is null"); + if(null == jarURI) { + throw new IllegalArgumentException("jarURI is null"); } - return testLoadState(nativeLibJars.get(jarURL), exp); + return testLoadState(nativeLibJars.get(jarURI), exp); } - public synchronized static boolean checkClasses(URL jarURL, LoadState exp) throws IOException { + public synchronized static boolean checkClasses(URI jarURI, LoadState exp) throws IOException { checkInitialized(); - if(null == jarURL) { - throw new IllegalArgumentException("jarURL is null"); + if(null == jarURI) { + throw new IllegalArgumentException("jarURI is null"); } - return testLoadState(classFileJars.get(jarURL), exp); + return testLoadState(classFileJars.get(jarURI), exp); } - public synchronized static boolean checkResources(URL jarURL, LoadState exp) throws IOException { + public synchronized static boolean checkResources(URI jarURI, LoadState exp) throws IOException { checkInitialized(); - if(null == jarURL) { - throw new IllegalArgumentException("jarURL is null"); + if(null == jarURI) { + throw new IllegalArgumentException("jarURI is null"); } - return testLoadState(resourceFileJars.get(jarURL), exp); + return testLoadState(resourceFileJars.get(jarURI), exp); } /** * Adds native libraries, if not yet added. * * @param certClass if class is certified, the JarFile entries needs to have the same certificate - * @param jarURL - * @throws IOException if the <code>jarURL</code> could not be loaded or a previous load attempt failed + * @param jarURI + * @throws IOException if the <code>jarURI</code> could not be loaded or a previous load attempt failed * @throws SecurityException */ - public synchronized static final void addNativeLibs(Class<?> certClass, URL jarURL) throws IOException, SecurityException { - final LoadState nativeLibJarsLS = nativeLibJars.get(jarURL); + public synchronized static final void addNativeLibs(Class<?> certClass, URI jarURI) throws IOException, SecurityException { + final LoadState nativeLibJarsLS = nativeLibJars.get(jarURI); if( !testLoadState(nativeLibJarsLS, LoadState.LOOKED_UP) ) { - nativeLibJars.put(jarURL, LoadState.LOOKED_UP); - final JarFile jarFile = JarUtil.getJarFile(jarURL); + nativeLibJars.put(jarURI, LoadState.LOOKED_UP); + final JarFile jarFile = JarUtil.getJarFile(jarURI); if(DEBUG) { - System.err.println("TempJarCache: addNativeLibs: "+jarURL+": nativeJar "+jarFile.getName()); + System.err.println("TempJarCache: addNativeLibs: "+jarURI+": nativeJar "+jarFile.getName()); } validateCertificates(certClass, jarFile); - JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile, - true, false, false); - nativeLibJars.put(jarURL, LoadState.LOADED); + JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile, true, false, false); + nativeLibJars.put(jarURI, LoadState.LOADED); } else if( !testLoadState(nativeLibJarsLS, LoadState.LOADED) ) { - throw new IOException("TempJarCache: addNativeLibs: "+jarURL+", previous load attempt failed"); + throw new IOException("TempJarCache: addNativeLibs: "+jarURI+", previous load attempt failed"); } } @@ -231,24 +230,24 @@ public class TempJarCache { * needs Classloader.defineClass(..) access, ie. own derivation - will do when needed .. * * @param certClass if class is certified, the JarFile entries needs to have the same certificate - * @param jarFile - * @throws IOException if the <code>jarURL</code> could not be loaded or a previous load attempt failed + * @param jarURI + * @throws IOException if the <code>jarURI</code> could not be loaded or a previous load attempt failed * @throws SecurityException */ - public synchronized static final void addClasses(Class<?> certClass, URL jarURL) throws IOException, SecurityException { - final LoadState classFileJarsLS = classFileJars.get(jarURL); + public synchronized static final void addClasses(Class<?> certClass, URI jarURI) throws IOException, SecurityException { + final LoadState classFileJarsLS = classFileJars.get(jarURI); if( !testLoadState(classFileJarsLS, LoadState.LOOKED_UP) ) { - classFileJars.put(jarURL, LoadState.LOOKED_UP); - final JarFile jarFile = JarUtil.getJarFile(jarURL); + classFileJars.put(jarURI, LoadState.LOOKED_UP); + final JarFile jarFile = JarUtil.getJarFile(jarURI); if(DEBUG) { - System.err.println("TempJarCache: addClasses: "+jarURL+": nativeJar "+jarFile.getName()); + System.err.println("TempJarCache: addClasses: "+jarURI+": nativeJar "+jarFile.getName()); } validateCertificates(certClass, jarFile); JarUtil.extract(tmpFileCache.getTempDir(), null, jarFile, false, true, false); - classFileJars.put(jarURL, LoadState.LOADED); + classFileJars.put(jarURI, LoadState.LOADED); } else if( !testLoadState(classFileJarsLS, LoadState.LOADED) ) { - throw new IOException("TempJarCache: addClasses: "+jarURL+", previous load attempt failed"); + throw new IOException("TempJarCache: addClasses: "+jarURI+", previous load attempt failed"); } } @@ -256,25 +255,25 @@ public class TempJarCache { * Adds native resources, if not yet added. * * @param certClass if class is certified, the JarFile entries needs to have the same certificate - * @param jarFile + * @param jarURI * @return - * @throws IOException if the <code>jarURL</code> could not be loaded or a previous load attempt failed + * @throws IOException if the <code>jarURI</code> could not be loaded or a previous load attempt failed * @throws SecurityException */ - public synchronized static final void addResources(Class<?> certClass, URL jarURL) throws IOException, SecurityException { - final LoadState resourceFileJarsLS = resourceFileJars.get(jarURL); + public synchronized static final void addResources(Class<?> certClass, URI jarURI) throws IOException, SecurityException { + final LoadState resourceFileJarsLS = resourceFileJars.get(jarURI); if( !testLoadState(resourceFileJarsLS, LoadState.LOOKED_UP) ) { - resourceFileJars.put(jarURL, LoadState.LOOKED_UP); - final JarFile jarFile = JarUtil.getJarFile(jarURL); + resourceFileJars.put(jarURI, LoadState.LOOKED_UP); + final JarFile jarFile = JarUtil.getJarFile(jarURI); if(DEBUG) { - System.err.println("TempJarCache: addResources: "+jarURL+": nativeJar "+jarFile.getName()); + System.err.println("TempJarCache: addResources: "+jarURI+": nativeJar "+jarFile.getName()); } validateCertificates(certClass, jarFile); JarUtil.extract(tmpFileCache.getTempDir(), null, jarFile, false, false, true); - resourceFileJars.put(jarURL, LoadState.LOADED); + resourceFileJars.put(jarURI, LoadState.LOADED); } else if( !testLoadState(resourceFileJarsLS, LoadState.LOADED) ) { - throw new IOException("TempJarCache: addResources: "+jarURL+", previous load attempt failed"); + throw new IOException("TempJarCache: addResources: "+jarURI+", previous load attempt failed"); } } @@ -286,18 +285,18 @@ public class TempJarCache { * needs Classloader.defineClass(..) access, ie. own derivation - will do when needed .. * * @param certClass if class is certified, the JarFile entries needs to have the same certificate - * @param jarFile - * @throws IOException if the <code>jarURL</code> could not be loaded or a previous load attempt failed + * @param jarURI + * @throws IOException if the <code>jarURI</code> could not be loaded or a previous load attempt failed * @throws SecurityException */ - public synchronized static final void addAll(Class<?> certClass, URL jarURL) throws IOException, SecurityException { + public synchronized static final void addAll(Class<?> certClass, URI jarURI) throws IOException, SecurityException { checkInitialized(); - if(null == jarURL) { - throw new IllegalArgumentException("jarURL is null"); + if(null == jarURI) { + throw new IllegalArgumentException("jarURI is null"); } - final LoadState nativeLibJarsLS = nativeLibJars.get(jarURL); - final LoadState classFileJarsLS = classFileJars.get(jarURL); - final LoadState resourceFileJarsLS = resourceFileJars.get(jarURL); + final LoadState nativeLibJarsLS = nativeLibJars.get(jarURI); + final LoadState classFileJarsLS = classFileJars.get(jarURI); + final LoadState resourceFileJarsLS = resourceFileJars.get(jarURI); if( !testLoadState(nativeLibJarsLS, LoadState.LOOKED_UP) || !testLoadState(classFileJarsLS, LoadState.LOOKED_UP) || !testLoadState(resourceFileJarsLS, LoadState.LOOKED_UP) ) { @@ -308,18 +307,18 @@ public class TempJarCache { // mark looked-up (those who are not loaded) if(extractNativeLibraries) { - nativeLibJars.put(jarURL, LoadState.LOOKED_UP); + nativeLibJars.put(jarURI, LoadState.LOOKED_UP); } if(extractClassFiles) { - classFileJars.put(jarURL, LoadState.LOOKED_UP); + classFileJars.put(jarURI, LoadState.LOOKED_UP); } if(extractOtherFiles) { - resourceFileJars.put(jarURL, LoadState.LOOKED_UP); + resourceFileJars.put(jarURI, LoadState.LOOKED_UP); } - final JarFile jarFile = JarUtil.getJarFile(jarURL); + final JarFile jarFile = JarUtil.getJarFile(jarURI); if(DEBUG) { - System.err.println("TempJarCache: addAll: "+jarURL+": nativeJar "+jarFile.getName()); + System.err.println("TempJarCache: addAll: "+jarURI+": nativeJar "+jarFile.getName()); } validateCertificates(certClass, jarFile); JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile, @@ -327,18 +326,18 @@ public class TempJarCache { // mark loaded (those were just loaded) if(extractNativeLibraries) { - nativeLibJars.put(jarURL, LoadState.LOADED); + nativeLibJars.put(jarURI, LoadState.LOADED); } if(extractClassFiles) { - classFileJars.put(jarURL, LoadState.LOADED); + classFileJars.put(jarURI, LoadState.LOADED); } if(extractOtherFiles) { - resourceFileJars.put(jarURL, LoadState.LOADED); + resourceFileJars.put(jarURI, LoadState.LOADED); } } else if( !testLoadState(nativeLibJarsLS, LoadState.LOADED) || !testLoadState(classFileJarsLS, LoadState.LOADED) || !testLoadState(resourceFileJarsLS, LoadState.LOADED) ) { - throw new IOException("TempJarCache: addAll: "+jarURL+", previous load attempt failed"); + throw new IOException("TempJarCache: addAll: "+jarURI+", previous load attempt failed"); } } @@ -382,11 +381,11 @@ public class TempJarCache { return null; } - public synchronized static final URL getResource(String name) throws MalformedURLException { + public synchronized static final URI getResource(String name) throws URISyntaxException { checkInitialized(); final File f = new File(tmpFileCache.getTempDir(), name); if(f.exists()) { - return IOUtil.toURLSimple(f); + return IOUtil.toURISimple(f); } return null; } @@ -402,18 +401,18 @@ public class TempJarCache { * @throws IOException * @throws SecurityException */ - public synchronized static final void bootstrapNativeLib(Class<?> certClass, String libBaseName, URL jarURL) + public synchronized static final void bootstrapNativeLib(Class<?> certClass, String libBaseName, URI jarURI) throws IOException, SecurityException { checkInitialized(); boolean ok = false; int countEntries = 0; - final LoadState nativeLibJarsLS = nativeLibJars.get(jarURL); + final LoadState nativeLibJarsLS = nativeLibJars.get(jarURI); if( !testLoadState(nativeLibJarsLS, LoadState.LOOKED_UP) && !nativeLibMap.containsKey(libBaseName) ) { if(DEBUG) { - System.err.println("TempJarCache: bootstrapNativeLib(certClass: "+certClass+", libBaseName "+libBaseName+", jarURL "+jarURL+")"); + System.err.println("TempJarCache: bootstrapNativeLib(certClass: "+certClass+", libBaseName "+libBaseName+", jarURI "+jarURI+")"); } - nativeLibJars.put(jarURL, LoadState.LOOKED_UP); - final JarFile jarFile = JarUtil.getJarFile(jarURL); + nativeLibJars.put(jarURI, LoadState.LOOKED_UP); + final JarFile jarFile = JarUtil.getJarFile(jarURI); if(DEBUG) { System.err.println("TempJarCache: bootstrapNativeLib: nativeJar "+jarFile.getName()); } @@ -442,7 +441,7 @@ public class TempJarCache { } finally { in.close(); out.close(); } if (numBytes>0) { nativeLibMap.put(libBaseName, destFile.getAbsolutePath()); - nativeLibJars.put(jarURL, LoadState.LOADED); + nativeLibJars.put(jarURI, LoadState.LOADED); ok = true; countEntries++; } @@ -451,7 +450,7 @@ public class TempJarCache { } else if( testLoadState(nativeLibJarsLS, LoadState.LOADED) ) { ok = true; // already loaded } else { - throw new IOException("TempJarCache: bootstrapNativeLib: "+jarURL+", previous load attempt failed"); + throw new IOException("TempJarCache: bootstrapNativeLib: "+jarURI+", previous load attempt failed"); } if(DEBUG) { System.err.println("TempJarCache: bootstrapNativeLib() done, count "+countEntries+", ok "+ok); |