summaryrefslogtreecommitdiffstats
path: root/src/java/com
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-06-19 04:44:14 +0200
committerSven Gothel <[email protected]>2013-06-19 04:44:14 +0200
commit4376174ad35fdaf76f59430328582e913f468674 (patch)
treeeb1faa41eb440b1fec0c5f9932007050e5bd7e8b /src/java/com
parent88dca02541d96f68a892ae7824e9e1b29793ae55 (diff)
Fix Bug 757: Regression of URL to URI conversion (Encoded path not compatible w/ file scheme.
Regression of (Bug 683, Commit b98825eb7cfb61aead4a7dff57471cd2d2c26823). The URI encoded path cannot be read by File I/O (if file scheme), since the latter requests an UTF8/16 name, not an URI encoded name (i.e. %20 for space). The encoded URL is produced if calling 'uri.toURL()' and hence the new 'IOUtil.toURL(URI)' provides a custom conversion recovering the UTF name via 'new File(uri).getPath()'. Tested w/ - synthetic URI/URL coposition (unit test) - manual w/ moving 'build' to 'build öä lala' for gluegen, joal and jogl. +++ Misc.: - 'URI JarUtil.getURIDirname(URI)' -> 'URI IOUtil.getDirname(URI)' ++
Diffstat (limited to 'src/java/com')
-rw-r--r--src/java/com/jogamp/common/jvm/JNILibLoaderBase.java3
-rw-r--r--src/java/com/jogamp/common/os/Platform.java3
-rw-r--r--src/java/com/jogamp/common/util/IOUtil.java109
-rw-r--r--src/java/com/jogamp/common/util/JarUtil.java87
-rw-r--r--src/java/com/jogamp/common/util/cache/TempJarCache.java20
5 files changed, 157 insertions, 65 deletions
diff --git a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
index 456c35a..2023162 100644
--- a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
+++ b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
@@ -52,6 +52,7 @@ import java.util.Iterator;
import java.util.List;
import com.jogamp.common.os.NativeLibrary;
+import com.jogamp.common.util.IOUtil;
import com.jogamp.common.util.JarUtil;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.common.util.cache.TempJarCache;
@@ -155,7 +156,7 @@ public class JNILibLoaderBase {
if(TempJarCache.isInitialized()) {
final String nativeJarName = nativeJarBasename+"-natives-"+PlatformPropsImpl.os_and_arch+".jar";
msg.append(nativeJarName);
- final URI jarUriRoot = JarUtil.getURIDirname( JarUtil.getJarSubURI( classJarURI ) );
+ final URI jarUriRoot = IOUtil.getDirname( JarUtil.getJarSubURI( classJarURI ) );
msg.append(" + ").append(jarUriRoot);
final URI nativeJarURI = JarUtil.getJarFileURI(jarUriRoot, nativeJarName);
msg.append(" -> ").append(nativeJarURI);
diff --git a/src/java/com/jogamp/common/os/Platform.java b/src/java/com/jogamp/common/os/Platform.java
index 0ae3cbb..9971cf4 100644
--- a/src/java/com/jogamp/common/os/Platform.java
+++ b/src/java/com/jogamp/common/os/Platform.java
@@ -33,6 +33,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.TimeUnit;
+import com.jogamp.common.util.IOUtil;
import com.jogamp.common.util.JarUtil;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.VersionNumber;
@@ -198,7 +199,7 @@ public class Platform extends PlatformPropsImpl {
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";
- jarUriRoot = JarUtil.getURIDirname( JarUtil.getJarSubURI( platformClassJarURI ) );
+ jarUriRoot = IOUtil.getDirname( JarUtil.getJarSubURI( platformClassJarURI ) );
nativeJarURI = JarUtil.getJarFileURI(jarUriRoot, nativeJarName);
TempJarCache.bootstrapNativeLib(Platform.class, libBaseName, nativeJarURI);
} catch (Exception e0) {
diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java
index 2f0c77f..2c3c756 100644
--- a/src/java/com/jogamp/common/util/IOUtil.java
+++ b/src/java/com/jogamp/common/util/IOUtil.java
@@ -56,14 +56,22 @@ import com.jogamp.common.os.Platform;
public class IOUtil {
public static final boolean DEBUG = Debug.debug("IOUtil");
- public static final String JAR_SCHEME = "jar";
+ /** {@value} */
+ public static final String SCHEME_SEPARATOR = ":";
+ /** {@value} */
public static final String FILE_SCHEME = "file";
+ /** {@value} */
public static final String HTTP_SCHEME = "http";
+ /** {@value} */
public static final String HTTPS_SCHEME = "https";
+ /** {@value} */
+ public static final String JAR_SCHEME = "jar";
+ /** A JAR subprotocol is separeted from the JAR entry w/ this separator {@value}. Even if no class is specified '!/' must follow!. */
+ public static final String JAR_SCHEME_SEPARATOR = "!";
- /** 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";
+ /** Std. temporary directory property key <code>java.io.tmpdir</code>. */
+ private static final String java_io_tmpdir_propkey = "java.io.tmpdir";
+ private static final String user_home_propkey = "user.home";
private static final String XDG_CACHE_HOME_envkey = "XDG_CACHE_HOME";
/** Subdirectory within platform's temporary root directory where all JogAmp related temp files are being stored: {@code jogamp} */
@@ -300,7 +308,7 @@ public class IOUtil {
public static URI toURISimple(String protocol, String file, boolean isDirectory) throws URISyntaxException {
return new URI(protocol, null, slashify(file, true, isDirectory), null);
}
-
+
/**
* Returns the lowercase suffix of the given file name (the text
* after the last '.' in the file name). Returns null if the file
@@ -333,7 +341,14 @@ public class IOUtil {
}
return toLowerCase(filename.substring(lastDot + 1));
}
+ private static String toLowerCase(String arg) {
+ if (arg == null) {
+ return null;
+ }
+ return arg.toLowerCase();
+ }
+
/***
* @param file
* @param allowOverwrite
@@ -402,14 +417,88 @@ public class IOUtil {
return fname;
}
- private static String toLowerCase(String arg) {
- if (arg == null) {
- return null;
+ /**
+ * 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 uri "<i>protocol</i>:/some/path/gluegen-rt.jar"
+ * @return "<i>protocol</i>:/some/path/"
+ * @throws IllegalArgumentException if the URI doesn't match the expected formatting, or is null
+ * @throws URISyntaxException
+ */
+ public static URI getDirname(URI uri) throws IllegalArgumentException, URISyntaxException {
+ if(null == uri) {
+ throw new IllegalArgumentException("URI is null");
}
-
- return arg.toLowerCase();
+ String uriS = uri.toString();
+ if( DEBUG ) {
+ System.out.println("getURIDirname "+uri+", extForm: "+uriS);
+ }
+ // from
+ // file:/some/path/gluegen-rt.jar _or_ rsrc:gluegen-rt.jar
+ // to
+ // file:/some/path/ _or_ rsrc:
+ int idx = uriS.lastIndexOf('/');
+ if(0 > idx) {
+ // no abs-path, check for protocol terminator ':'
+ idx = uriS.lastIndexOf(':');
+ if(0 > idx) {
+ throw new IllegalArgumentException("URI does not contain protocol terminator ':', in <"+uri+">");
+ }
+ }
+ uriS = uriS.substring(0, idx+1); // exclude jar name, include terminal '/' or ':'
+
+ if( DEBUG ) {
+ System.out.println("getJarURIDirname res: "+uriS);
+ }
+ return new URI(uriS);
}
+ /**
+ * Converts an {@link URI} to an {@link URL} while using a non encoded path
+ * for <i>file scheme</i>, i.e. <code>file:/</code>.
+ * Otherwise the default {@link URL} translation {@link URI#toURL()} is being used.
+ * <p>
+ * The folloing cases are considered:
+ * <ul>
+ * <li><i>file schema</i> is converted via <code>new File(uri).getPath()</code>.</li>
+ * <li><i>jar scheme</i>
+ * <ul>
+ * <li>subprotocol is being converted as above, if <i>file scheme</i>.</li>
+ * <li>JAR entry is not converted but preserved.</li>
+ * </ul></li>
+ * </ul>
+ * </p>
+ * @param uri
+ * @return
+ * @throws IOException
+ * @throws IllegalArgumentException
+ * @throws URISyntaxException
+ */
+ public static URL toURL(URI uri) throws IOException, IllegalArgumentException, URISyntaxException {
+ final URL url;
+ final String uriSchema = uri.getScheme();
+ final boolean isJAR = IOUtil.JAR_SCHEME.equals(uriSchema);
+ final URI specificURI = isJAR ? JarUtil.getJarSubURI(uri) : uri;
+ if( IOUtil.FILE_SCHEME.equals( specificURI.getScheme() ) ) {
+ final File f = new File(specificURI);
+ if( specificURI == uri ) {
+ url = new URL(IOUtil.FILE_SCHEME+IOUtil.SCHEME_SEPARATOR+f.getPath());
+ // url = f.toURI().toURL(); // Doesn't work, since it uses encoded path!
+ } else {
+ final String post = isJAR ? IOUtil.JAR_SCHEME_SEPARATOR + JarUtil.getJarEntry(uri) : "";
+ final String urlS = uriSchema+IOUtil.SCHEME_SEPARATOR+IOUtil.FILE_SCHEME+IOUtil.SCHEME_SEPARATOR+f.getPath()+post;
+ url = new URL(urlS);
+ }
+ } else {
+ url = uri.toURL();
+ }
+ return url;
+ }
+
/***
*
* RESOURCE LOCATION STUFF
diff --git a/src/java/com/jogamp/common/util/JarUtil.java b/src/java/com/jogamp/common/util/JarUtil.java
index 4045cfa..9ea6f70 100644
--- a/src/java/com/jogamp/common/util/JarUtil.java
+++ b/src/java/com/jogamp/common/util/JarUtil.java
@@ -142,10 +142,10 @@ public class JarUtil {
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 ) )
+ !scheme.equals( IOUtil.JAR_SCHEME ) &&
+ !scheme.equals( IOUtil.FILE_SCHEME ) &&
+ !scheme.equals( IOUtil.HTTP_SCHEME ) &&
+ !scheme.equals( IOUtil.HTTPS_SCHEME ) )
{
final URL _url = resolver.resolve( url );
uri = _url.toURI();
@@ -252,7 +252,6 @@ public class JarUtil {
*
* @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 URI doesn't match the expected formatting or is null
* @throws URISyntaxException if the URI could not be translated into a RFC 2396 URI
@@ -286,6 +285,36 @@ public class JarUtil {
}
return new URI(uriS);
}
+
+ /**
+ * 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 entry <code>/com/jogamp/common/GlueGenVersion.class</code> will be returned.
+ *
+ * @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>/com/jogamp/common/GlueGenVersion.class</code>
+ * @see {@link IOUtil#getClassURL(String, ClassLoader)}
+ */
+ public static String getJarEntry(URI classJarURI) {
+ 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 uriS = classJarURI.getRawSchemeSpecificPart();
+
+ // from
+ // file:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class
+ // to
+ // file:/some/path/gluegen-rt.jar
+ int idx = uriS.lastIndexOf('!');
+ if (0 <= idx) {
+ return uriS.substring(idx+1); // right of '!'
+ } else {
+ throw new IllegalArgumentException("JAR URI does not contain jar uri terminator '!', uri <"+classJarURI+">");
+ }
+ }
/**
* The Class's <code>com.jogamp.common.GlueGenVersion</code>
@@ -335,46 +364,6 @@ public class JarUtil {
}
/**
- * 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 aURI "<i>protocol</i>:/some/path/gluegen-rt.jar"
- * @return "<i>protocol</i>:/some/path/"
- * @throws IllegalArgumentException if the URI doesn't match the expected formatting, or is null
- * @throws URISyntaxException
- */
- public static URI getURIDirname(URI aURI) throws IllegalArgumentException, URISyntaxException {
- if(null == aURI) {
- throw new IllegalArgumentException("URI is null");
- }
- String uriS = aURI.toString();
- if(DEBUG) {
- 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 = uriS.lastIndexOf('/');
- if(0 > idx) {
- // no abs-path, check for protocol terminator ':'
- idx = uriS.lastIndexOf(':');
- if(0 > idx) {
- throw new IllegalArgumentException("URI does not contain protocol terminator ':', in <"+aURI+">");
- }
- }
- uriS = uriS.substring(0, idx+1); // exclude jar name, include terminal '/' or ':'
-
- if(DEBUG) {
- System.out.println("getJarURIDirname res: "+uriS);
- }
- return new URI(uriS);
- }
-
- /**
* @param baseUri file:/some/path/
* @param jarFileName gluegen-rt.jar
* @return jar:file:/some/path/gluegen-rt.jar!/
@@ -433,15 +422,17 @@ public class JarUtil {
* @return JarFile as named by URI within the given ClassLoader
* @throws IllegalArgumentException null arguments
* @throws IOException if the Jar file could not been found
+ * @throws URISyntaxException
*/
- public static JarFile getJarFile(URI jarFileURI) throws IOException, IllegalArgumentException {
+ public static JarFile getJarFile(URI jarFileURI) throws IOException, IllegalArgumentException, URISyntaxException {
if(null == jarFileURI) {
throw new IllegalArgumentException("null jarFileURI");
}
if(DEBUG) {
- System.out.println("getJarFile: "+jarFileURI);
+ System.out.println("getJarFile: "+jarFileURI.toString());
}
- final URL jarFileURL = jarFileURI.toURL();
+ final URL jarFileURL = IOUtil.toURL(jarFileURI);
+ // final URL jarFileURL = jarFileURI.toURL(); // doesn't work due to encoded path even w/ file schema!
final URLConnection urlc = jarFileURL.openConnection();
if(urlc instanceof JarURLConnection) {
JarURLConnection jarConnection = (JarURLConnection)jarFileURL.openConnection();
diff --git a/src/java/com/jogamp/common/util/cache/TempJarCache.java b/src/java/com/jogamp/common/util/cache/TempJarCache.java
index b17dd52..4c505f9 100644
--- a/src/java/com/jogamp/common/util/cache/TempJarCache.java
+++ b/src/java/com/jogamp/common/util/cache/TempJarCache.java
@@ -206,8 +206,10 @@ public class TempJarCache {
* @param jarURI
* @throws IOException if the <code>jarURI</code> could not be loaded or a previous load attempt failed
* @throws SecurityException
+ * @throws URISyntaxException
+ * @throws IllegalArgumentException
*/
- public synchronized static final void addNativeLibs(Class<?> certClass, URI jarURI) throws IOException, SecurityException {
+ public synchronized static final void addNativeLibs(Class<?> certClass, URI jarURI) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException {
final LoadState nativeLibJarsLS = nativeLibJars.get(jarURI);
if( !testLoadState(nativeLibJarsLS, LoadState.LOOKED_UP) ) {
nativeLibJars.put(jarURI, LoadState.LOOKED_UP);
@@ -233,8 +235,10 @@ public class TempJarCache {
* @param jarURI
* @throws IOException if the <code>jarURI</code> could not be loaded or a previous load attempt failed
* @throws SecurityException
+ * @throws URISyntaxException
+ * @throws IllegalArgumentException
*/
- public synchronized static final void addClasses(Class<?> certClass, URI jarURI) throws IOException, SecurityException {
+ public synchronized static final void addClasses(Class<?> certClass, URI jarURI) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException {
final LoadState classFileJarsLS = classFileJars.get(jarURI);
if( !testLoadState(classFileJarsLS, LoadState.LOOKED_UP) ) {
classFileJars.put(jarURI, LoadState.LOOKED_UP);
@@ -259,8 +263,10 @@ public class TempJarCache {
* @return
* @throws IOException if the <code>jarURI</code> could not be loaded or a previous load attempt failed
* @throws SecurityException
+ * @throws URISyntaxException
+ * @throws IllegalArgumentException
*/
- public synchronized static final void addResources(Class<?> certClass, URI jarURI) throws IOException, SecurityException {
+ public synchronized static final void addResources(Class<?> certClass, URI jarURI) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException {
final LoadState resourceFileJarsLS = resourceFileJars.get(jarURI);
if( !testLoadState(resourceFileJarsLS, LoadState.LOOKED_UP) ) {
resourceFileJars.put(jarURI, LoadState.LOOKED_UP);
@@ -288,8 +294,10 @@ public class TempJarCache {
* @param jarURI
* @throws IOException if the <code>jarURI</code> could not be loaded or a previous load attempt failed
* @throws SecurityException
+ * @throws URISyntaxException
+ * @throws IllegalArgumentException
*/
- public synchronized static final void addAll(Class<?> certClass, URI jarURI) throws IOException, SecurityException {
+ public synchronized static final void addAll(Class<?> certClass, URI jarURI) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException {
checkInitialized();
if(null == jarURI) {
throw new IllegalArgumentException("jarURI is null");
@@ -400,9 +408,11 @@ public class TempJarCache {
*
* @throws IOException
* @throws SecurityException
+ * @throws URISyntaxException
+ * @throws IllegalArgumentException
*/
public synchronized static final void bootstrapNativeLib(Class<?> certClass, String libBaseName, URI jarURI)
- throws IOException, SecurityException {
+ throws IOException, SecurityException, IllegalArgumentException, URISyntaxException {
checkInitialized();
boolean ok = false;
int countEntries = 0;