aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/com/jogamp')
-rw-r--r--src/java/com/jogamp/common/jvm/JNILibLoaderBase.java140
-rw-r--r--src/java/com/jogamp/common/net/URIQueryProps.java137
-rw-r--r--src/java/com/jogamp/common/os/Platform.java14
-rw-r--r--src/java/com/jogamp/common/util/IOUtil.java119
-rw-r--r--src/java/com/jogamp/common/util/JarUtil.java83
-rw-r--r--src/java/com/jogamp/common/util/PropertyAccess.java9
-rw-r--r--src/java/com/jogamp/common/util/VersionUtil.java4
-rw-r--r--src/java/com/jogamp/common/util/cache/TempJarCache.java101
8 files changed, 434 insertions, 173 deletions
diff --git a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
index 2023162..67cc05c 100644
--- a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
+++ b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
@@ -44,6 +44,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
@@ -147,24 +148,56 @@ public class JNILibLoaderBase {
loaderAction = action;
}
- /* pp */ static final boolean addNativeJarLibsImpl(Class<?> classFromJavaJar, URI classJarURI, String nativeJarBasename, StringBuilder msg)
+ /**
+ *
+ * @param classFromJavaJar
+ * @param classJarURI
+ * @param jarBasename jar basename w/ suffix
+ * @param nativeJarBasename native jar basename w/ suffix
+ * @param msg
+ * @return
+ * @throws IOException
+ * @throws SecurityException
+ * @throws URISyntaxException
+ */
+ /* pp */ static final boolean addNativeJarLibsImpl(Class<?> classFromJavaJar, URI classJarURI, String jarBasename, String nativeJarBasename, StringBuilder msg)
throws IOException, SecurityException, URISyntaxException
{
msg.setLength(0); // reset
- msg.append("addNativeJarLibsImpl(classFromJavaJar ").append(classFromJavaJar).append(", classJarURI ").append(classJarURI).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 URI jarUriRoot = IOUtil.getDirname( 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());
+ if(TempJarCache.isInitialized()) {
+ final URI jarSubURI = JarUtil.getJarSubURI( classJarURI );
+ if(null == jarSubURI) {
+ throw new IllegalArgumentException("JarSubURI is null of: "+classJarURI);
+ }
+ final String jarUriRoot_s = IOUtil.getURIDirname( jarSubURI.toString() );
+ msg.append("[ ").append(jarSubURI.toString()).append(" -> ").append(jarUriRoot_s).append(" ] + ");
+
+ final String nativeLibraryPath = "natives/"+PlatformPropsImpl.os_and_arch+"/";
+ final ClassLoader cl = classFromJavaJar.getClassLoader();
+ final URL nativeLibraryURI = cl.getResource(nativeLibraryPath);
+ if( null != nativeLibraryURI ) {
+ // We probably have one big-fat jar file, containing java classes
+ // and all native platform libraries under 'natives/os.and.arch'!
+ final URI nativeJarURI = JarUtil.getJarFileURI(jarUriRoot_s+jarBasename);
+ if( TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI, nativeLibraryPath) ) {
+ ok = true;
+ msg.append(jarBasename).append(" -> fat: ").append(nativeJarURI);
+ }
}
- TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI);
- ok = true;
+ if( !ok ) {
+ // We assume one slim native jar file per 'os.and.arch'!
+ final URI nativeJarURI = JarUtil.getJarFileURI(jarUriRoot_s+nativeJarBasename);
+ msg.append(nativeJarBasename).append(" -> slim: ").append(nativeJarURI);
+ ok = TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI, null /* nativeLibraryPath */);
+ }
+ } else {
+ msg.append("TempJarCache n/a");
+ }
+ if(DEBUG) {
+ System.err.println(msg.toString()+" - OK "+ok);
}
return ok;
}
@@ -193,7 +226,8 @@ public class JNILibLoaderBase {
final StringBuilder msg = new StringBuilder();
try {
final URI classJarURI = JarUtil.getJarURI(classFromJavaJar.getName(), classFromJavaJar.getClassLoader());
- return addNativeJarLibsImpl(classFromJavaJar, classJarURI, nativeJarBasename, msg);
+ final String jarName = JarUtil.getJarBasename(classJarURI);
+ return addNativeJarLibsImpl(classFromJavaJar, classJarURI, jarName, nativeJarBasename+"-natives-"+PlatformPropsImpl.os_and_arch+".jar", msg);
} catch (Exception e0) {
// IllegalArgumentException, IOException
System.err.println("Catched "+e0.getClass().getSimpleName()+": "+e0.getMessage()+", while "+msg.toString());
@@ -208,6 +242,30 @@ public class JNILibLoaderBase {
}
/**
+ * Loads and adds a JAR file's native library to the TempJarCache,
+ * calling {@link JNILibLoaderBase#addNativeJarLibs(Class[], String, String[])}
+ * with default JOGL deployment configuration:
+ * <pre>
+ return JNILibLoaderBase.addNativeJarLibs(classesFromJavaJars, "-all", new String[] { "-noawt", "-mobile", "-core", "-android" } );
+ * </pre>
+ * If <code>Class1.class</code> is contained in a JAR file which name includes <code>singleJarMarker</code> <i>-all</i>,
+ * implementation will attempt to resolve the native JAR file as follows:
+ * <ul>
+ * <li><i>ClassJar-all</i>[-noawt,-mobile,-android]?.jar to <i>ClassJar-all</i>-natives-<i>os.and.arch</i>.jar</li>
+ * </ul>
+ * Otherwise the native JAR files will be resolved for each class's JAR file:
+ * <ul>
+ * <li><i>ClassJar1</i>[-noawt,-mobile,-core,-android]?.jar to <i>ClassJar1</i>-natives-<i>os.and.arch</i>.jar</li>
+ * <li><i>ClassJar2</i>[-noawt,-mobile,-core,-android]?.jar to <i>ClassJar2</i>-natives-<i>os.and.arch</i>.jar</li>
+ * <li>..</li>
+ * </ul>
+ */
+ public static final boolean addNativeJarLibsJoglCfg(final Class<?>[] classesFromJavaJars) {
+ return addNativeJarLibs(classesFromJavaJars, "-all", joglDeployCfg);
+ }
+ private static final String[] joglDeployCfg = new String[] { "-noawt", "-mobile", "-core", "-android" };
+
+ /**
* Loads and adds a JAR file's native library to the TempJarCache.<br>
* The native library JAR file's URI is derived as follows:
* <ul>
@@ -223,37 +281,59 @@ public class JNILibLoaderBase {
* <li> [3] is it's <i>base URI</i></li>
* <li> [4] is the derived native JAR filename</li>
* </ul>
- *
- * Examples:<br>
- * <br>
+ * <p>
+ * Generic description:
+ * <pre>
+ final ClassLoader cl = GLProfile.class.getClassLoader();
+ final String newtFactoryClassName = "com.jogamp.newt.NewtFactory";
+ final Class<?>[] classesFromJavaJars = new Class<?>[] { Class1.class, Class2.class };
+ JNILibLoaderBase.addNativeJarLibs(classesFromJavaJars, "-all", new String[] { "-suff1", "-suff2" } );
+ * </pre>
+ * If <code>Class1.class</code> is contained in a JAR file which name includes <code>singleJarMarker</code>, here <i>-all</i>,
+ * implementation will attempt to resolve the native JAR file as follows:
+ * <ul>
+ * <li><i>ClassJar-all</i>[-suff1,-suff2]?.jar to <i>ClassJar-all</i>-natives-<i>os.and.arch</i>.jar</li>
+ * </ul>
+ * Otherwise the native JAR files will be resolved for each class's JAR file:
+ * <ul>
+ * <li><i>Class1Jar</i>[-suff1,-suff2]?.jar to <i>Class1Jar</i>-natives-<i>os.and.arch</i>.jar</li>
+ * <li><i>Class2Jar</i>[-suff1,-suff2]?.jar to <i>Class2Jar</i>-natives-<i>os.and.arch</i>.jar</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Examples:
+ * </p>
+ * <p>
* JOCL:
* <pre>
- // only: jocl.jar -> jocl-natives-'os.and.arch'.jar
+ // only: jocl.jar -> jocl-natives-<i>os.and.arch</i>.jar
addNativeJarLibs(new Class<?>[] { JOCLJNILibLoader.class }, null, null );
* </pre>
*
* Newt Only:
* <pre>
- // either: [jogl-all.jar, jogl-all-noawt.jar, jogl-all-mobile.jar] -> jogl-all-natives-<os.and.arch>.jar
- // or: nativewindow-core.jar -> nativewindow-natives-<os.and.arch>.jar,
- // newt-core.jar -> newt-natives-<os.and.arch>.jar
- JNILibLoaderBase.addNativeJarLibs(new Class<?>[] { NWJNILibLoader.class, NEWTJNILibLoader.class }, "-all", new String[] { "-noawt", "-mobile", "-core" } );
+ // either: [jogl-all.jar, jogl-all-noawt.jar, jogl-all-mobile.jar, jogl-all-android.jar] -> jogl-all-natives-<i>os.and.arch</i>.jar
+ // or: nativewindow-core.jar -> nativewindow-natives-<i>os.and.arch</i>.jar,
+ // newt-core.jar -> newt-natives-<i>os.and.arch</i>.jar
+ JNILibLoaderBase.addNativeJarLibs(new Class<?>[] { NWJNILibLoader.class, NEWTJNILibLoader.class }, "-all", new String[] { "-noawt", "-mobile", "-core", "-android" } );
* </pre>
- *
+ * </p>
+ * <p>
* JOGL:
* <pre>
final ClassLoader cl = GLProfile.class.getClassLoader();
- // either: [jogl-all.jar, jogl-all-noawt.jar, jogl-all-mobile.jar] -> jogl-all-natives-<os.and.arch>.jar
- // or: nativewindow-core.jar -> nativewindow-natives-<os.and.arch>.jar,
- // jogl-core.jar -> jogl-natives-<os.and.arch>.jar,
- // (newt-core.jar -> newt-natives-<os.and.arch>.jar)? (if available)
+ // either: [jogl-all.jar, jogl-all-noawt.jar, jogl-all-mobile.jar, jogl-all-android.jar] -> jogl-all-natives-<i>os.and.arch</i>.jar
+ // or: nativewindow-core.jar -> nativewindow-natives-<i>os.and.arch</i>.jar,
+ // jogl-core.jar -> jogl-natives-<i>os.and.arch</i>.jar,
+ // (newt-core.jar -> newt-natives-<i>os.and.arch</i>.jar)? (if available)
final String newtFactoryClassName = "com.jogamp.newt.NewtFactory";
final Class<?>[] classesFromJavaJars = new Class<?>[] { NWJNILibLoader.class, GLProfile.class, null };
if( ReflectionUtil.isClassAvailable(newtFactoryClassName, cl) ) {
classesFromJavaJars[2] = ReflectionUtil.getClass(newtFactoryClassName, false, cl);
}
- JNILibLoaderBase.addNativeJarLibs(classesFromJavaJars, "-all", new String[] { "-noawt", "-mobile", "-core" } );
+ JNILibLoaderBase.addNativeJarLibs(classesFromJavaJars, "-all", new String[] { "-noawt", "-mobile", "-core", "-android" } );
* </pre>
+ * </p>
*
* @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
@@ -281,9 +361,9 @@ public class JNILibLoaderBase {
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);
+ final String nativeJarBasename = stripName(jarBasename, stripBasenameSuffixes)+"-natives-"+PlatformPropsImpl.os_and_arch+".jar";
done = null != singleJarMarker && jarBasename.indexOf(singleJarMarker) >= 0; // done if single-jar ('all' variant)
- ok = JNILibLoaderBase.addNativeJarLibsImpl(classesFromJavaJars[i], classJarURI, nativeJarBasename, msg);
+ ok = JNILibLoaderBase.addNativeJarLibsImpl(classesFromJavaJars[i], classJarURI, jarName, 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/URIQueryProps.java b/src/java/com/jogamp/common/net/URIQueryProps.java
new file mode 100644
index 0000000..fd91b9b
--- /dev/null
+++ b/src/java/com/jogamp/common/net/URIQueryProps.java
@@ -0,0 +1,137 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.common.net;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Helper class to process URI's query, handled as properties.
+ * <p>
+ * The order of the URI segments (any properties) are <i>not</i> preserved.
+ * </p>
+ * <pre>
+ * URI: [scheme:][//authority][path][?query][#fragment]
+ * w/ authority: [user-info@]host[:port]
+ * Note: 'path' starts w/ fwd slash
+ * </pre>
+ */
+public class URIQueryProps {
+ private static final String QMARK = "?";
+ private static final char ASSIG = '=';
+ private static final String EMPTY = "";
+ private final String query_separator;
+
+ private final HashMap<String, String> properties = new HashMap<String, String>();
+
+ private URIQueryProps(char querySeparator) {
+ query_separator = String.valueOf(querySeparator);
+ }
+
+ public final Map<String, String> getProperties() { return properties; }
+ public final char getQuerySeparator() { return query_separator.charAt(0); }
+
+ public final String appendQuery(String baseQuery) {
+ boolean needsSep = false;
+ final StringBuilder sb = new StringBuilder();
+ if ( null != baseQuery ) {
+ if( !baseQuery.startsWith(QMARK) ) {
+ baseQuery = baseQuery.substring(1);
+ }
+ sb.append(baseQuery);
+ if( !baseQuery.endsWith(query_separator) ) {
+ needsSep = true;
+ }
+ }
+ Iterator<Entry<String, String>> entries = properties.entrySet().iterator();
+ while(entries.hasNext()) {
+ if(needsSep) {
+ sb.append(query_separator);
+ }
+ final Entry<String, String> entry = entries.next();
+ sb.append(entry.getKey());
+ if( EMPTY != entry.getValue() ) {
+ sb.append(ASSIG).append(entry.getValue());
+ }
+ needsSep = true;
+ }
+ return sb.toString();
+ }
+
+ public final URI appendQuery(URI base) throws URISyntaxException {
+ return new URI(base.getScheme(),
+ base.getRawUserInfo(), base.getHost(), base.getPort(),
+ base.getRawPath(), appendQuery(base.getRawQuery()), base.getRawFragment());
+ }
+
+ /**
+ *
+ * @param uri
+ * @param querySeparator should be either <i>;</i> or <i>&</i>, <i>;</i> is encouraged due to troubles of escaping <i>&</i>.
+ * @return
+ * @throws IllegalArgumentException if <code>querySeparator</code> is illegal, i.e. neither <i>;</i> nor <i>&</i>
+ */
+ public static final URIQueryProps create(URI uri, char querySeparator) throws IllegalArgumentException {
+ if( ';' != querySeparator && '&' != querySeparator ) {
+ throw new IllegalArgumentException("querySeparator is invalid: "+querySeparator);
+ }
+ final URIQueryProps data = new URIQueryProps(querySeparator);
+ final String q = uri.getQuery();
+ final int q_l = null != q ? q.length() : -1;
+ int q_e = -1;
+ while(q_e < q_l) {
+ int q_b = q_e + 1; // next term
+ q_e = q.indexOf(querySeparator, q_b);
+ if(0 == q_e) {
+ // single separator
+ continue;
+ }
+ if(0 > q_e) {
+ // end
+ q_e = q_l;
+ }
+ // n-part
+ final String part = q.substring(q_b, q_e);
+ final int assignment = part.indexOf(ASSIG);
+ if(0 < assignment) {
+ // assignment
+ final String k = part.substring(0, assignment);
+ final String v = part.substring(assignment+1);
+ data.properties.put(k, v);
+ } else {
+ // property key only
+ data.properties.put(part, EMPTY);
+ }
+ }
+ return data;
+ }
+}
diff --git a/src/java/com/jogamp/common/os/Platform.java b/src/java/com/jogamp/common/os/Platform.java
index 32fc9f4..a01a4b4 100644
--- a/src/java/com/jogamp/common/os/Platform.java
+++ b/src/java/com/jogamp/common/os/Platform.java
@@ -33,7 +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.jvm.JNILibLoaderBase;
import com.jogamp.common.util.JarUtil;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.VersionNumber;
@@ -192,19 +192,11 @@ public class Platform extends PlatformPropsImpl {
// load GluegenRT native library
if(_USE_TEMP_JAR_CACHE[0] && TempJarCache.initSingleton()) {
- String nativeJarName = null;
- URI jarUriRoot = null;
- URI nativeJarURI = null;
try {
- 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 = IOUtil.getDirname( JarUtil.getJarSubURI( platformClassJarURI ) );
- nativeJarURI = JarUtil.getJarFileURI(jarUriRoot, nativeJarName);
- TempJarCache.bootstrapNativeLib(Platform.class, libBaseName, nativeJarURI);
+ JNILibLoaderBase.addNativeJarLibs(new Class<?>[] { Platform.class }, null, null );
} catch (Exception e0) {
// IllegalArgumentException, IOException
- System.err.println("Catched "+e0.getClass().getSimpleName()+": "+e0.getMessage()+", while TempJarCache.bootstrapNativeLib() of "+nativeJarURI+" ("+jarUriRoot+" + "+nativeJarName+")");
+ System.err.println("Catched "+e0.getClass().getSimpleName()+": "+e0.getMessage()+", while JNILibLoaderBase.addNativeJarLibs(..)");
}
}
DynamicLibraryBundle.GlueJNILibLoader.loadLibrary(libBaseName, false, cl);
diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java
index de5a8ea..242f300 100644
--- a/src/java/com/jogamp/common/util/IOUtil.java
+++ b/src/java/com/jogamp/common/util/IOUtil.java
@@ -43,6 +43,7 @@ import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteBuffer;
+import java.util.regex.Pattern;
import jogamp.common.Debug;
import jogamp.common.os.AndroidUtils;
@@ -169,7 +170,22 @@ public class IOUtil {
* @throws IOException
*/
public static int copyStream2Stream(InputStream in, OutputStream out, int totalNumBytes) throws IOException {
- final byte[] buf = new byte[Platform.getMachineDescription().pageSizeInBytes()];
+ return copyStream2Stream(Platform.getMachineDescription().pageSizeInBytes(), in, out, totalNumBytes);
+ }
+
+ /**
+ * Copy the specified input stream to the specified output stream. The total
+ * number of bytes written is returned.
+ *
+ * @param bufferSize the intermediate buffer size, should be {@link MachineDescription#pageSizeInBytes()} for best performance.
+ * @param in the source
+ * @param out the destination
+ * @param totalNumBytes informal number of expected bytes, maybe used for user feedback while processing. -1 if unknown
+ * @return
+ * @throws IOException
+ */
+ public static int copyStream2Stream(int bufferSize, InputStream in, OutputStream out, int totalNumBytes) throws IOException {
+ final byte[] buf = new byte[bufferSize];
int numBytes = 0;
while (true) {
int count;
@@ -181,7 +197,7 @@ public class IOUtil {
}
return numBytes;
}
-
+
/**
* Copy the specified input stream to a byte array, which is being returned.
*/
@@ -281,7 +297,7 @@ public class IOUtil {
* @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 URISyntaxException {
- String p = path.replace('\\', '/'); // unify file seperator
+ String p = path.replace('\\', '/'); // unify file separator
if (startWithSlash && !p.startsWith("/")) {
p = "/" + p;
}
@@ -297,7 +313,7 @@ public class IOUtil {
* @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);
+ return new URI(FILE_SCHEME, null, encodeToURI(slashify(file.getAbsolutePath(), true, file.isDirectory())), null);
}
/**
@@ -306,7 +322,7 @@ public class IOUtil {
* @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);
+ return new URI(protocol, null, encodeToURI(slashify(file, true, isDirectory)), null);
}
/**
@@ -429,7 +445,7 @@ public class IOUtil {
* @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 {
+ public static URI getURIDirname(URI uri) throws IllegalArgumentException, URISyntaxException {
if(null == uri) {
throw new IllegalArgumentException("URI is null");
}
@@ -437,6 +453,25 @@ public class IOUtil {
if( DEBUG ) {
System.out.println("getURIDirname "+uri+", extForm: "+uriS);
}
+ return new URI( getURIDirname(uriS) );
+ }
+
+ /**
+ * 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" (URI encoded)
+ * @return "<i>protocol</i>:/some/path/"
+ * @throws IllegalArgumentException if the URI doesn't match the expected formatting, or is null
+ * @throws URISyntaxException
+ */
+ public static String getURIDirname(String uriS) throws IllegalArgumentException, URISyntaxException {
+ if(null == uriS) {
+ throw new IllegalArgumentException("uriS is null");
+ }
// from
// file:/some/path/gluegen-rt.jar _or_ rsrc:gluegen-rt.jar
// to
@@ -446,7 +481,7 @@ public class IOUtil {
// no abs-path, check for protocol terminator ':'
idx = uriS.lastIndexOf(':');
if(0 > idx) {
- throw new IllegalArgumentException("URI does not contain protocol terminator ':', in <"+uri+">");
+ throw new IllegalArgumentException("URI does not contain protocol terminator ':', in <"+uriS+">");
}
}
uriS = uriS.substring(0, idx+1); // exclude jar name, include terminal '/' or ':'
@@ -454,7 +489,7 @@ public class IOUtil {
if( DEBUG ) {
System.out.println("getJarURIDirname res: "+uriS);
}
- return new URI(uriS);
+ return uriS;
}
/**
@@ -479,22 +514,40 @@ public class IOUtil {
* @throws URISyntaxException
*/
public static URL toURL(URI uri) throws IOException, IllegalArgumentException, URISyntaxException {
- final URL url;
+ URL url = null;
final String uriSchema = uri.getScheme();
final boolean isJAR = IOUtil.JAR_SCHEME.equals(uriSchema);
- final URI specificURI = isJAR ? JarUtil.getJarSubURI(uri) : uri;
+ final URI specificURI = isJAR ? JarUtil.getJarSubURI(uri) : uri;
+ int mode = 0;
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);
+ File f;
+ try {
+ f = new File(specificURI);
+ } catch( IllegalArgumentException iae) {
+ if( DEBUG ) {
+ System.out.println("toURL: "+uri+" -> File("+specificURI+") failed: "+iae.getMessage());
+ }
+ f = null;
}
- } else {
+ if( null != f ) {
+ 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!
+ mode = 1;
+ } 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);
+ mode = 2;
+ }
+ }
+ }
+ if( null == url ) {
url = uri.toURL();
+ mode = 3;
+ }
+ if( DEBUG ) {
+ System.err.println("IOUtil.toURL: "+uri+", isJar "+isJAR+": "+specificURI+" -> mode "+mode+", "+url);
}
return url;
}
@@ -675,7 +728,7 @@ public class IOUtil {
* @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());
+ return compose(baseURI.getScheme(), baseURI.getSchemeSpecificPart(), encodeToURI(relativePath), baseURI.getFragment());
}
/**
@@ -701,9 +754,11 @@ public class IOUtil {
* </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
+ * @param schemeSpecificPart may include a query, which is separated while processing (URI encoded)
+ * @param relativePath denotes a relative file to the baseLocation's parent directory (URI encoded)
+ * @param fragment the URI fragment (URI encoded)
* @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code>
+ * @see #encodeToURI(String)
*/
public static URI compose(String scheme, String schemeSpecificPart, String relativePath, String fragment) throws URISyntaxException {
// cut off optional query in scheme-specific-part
@@ -725,6 +780,26 @@ public class IOUtil {
return new URI(scheme, null == query ? schemeSpecificPart : schemeSpecificPart + "?" + query, fragment);
}
+ private static final Pattern patternSpaceRaw = Pattern.compile(" ");
+ private static final Pattern patternSpaceEnc = Pattern.compile("%20");
+
+ /**
+ * Escapes characters not complying w/ RFC 2396 and the {@link URI#URI(String)} ctor.
+ * <ul>
+ * <li>SPACE -> %20</li>
+ * </ul>
+ */
+ public static String encodeToURI(String s) {
+ return patternSpaceRaw.matcher(s).replaceAll("%20");
+ }
+
+ /**
+ * Reverses escaping of characters as performed via {@link #encodeToURI(String)}.
+ */
+ public static String decodeFromURI(String s) {
+ return patternSpaceEnc.matcher(s).replaceAll(" ");
+ }
+
/**
* Returns the connected URLConnection, or null if not url is not available
*/
diff --git a/src/java/com/jogamp/common/util/JarUtil.java b/src/java/com/jogamp/common/util/JarUtil.java
index 5604c3d..29e7dc7 100644
--- a/src/java/com/jogamp/common/util/JarUtil.java
+++ b/src/java/com/jogamp/common/util/JarUtil.java
@@ -53,6 +53,8 @@ import jogamp.common.Debug;
public class JarUtil {
private static final boolean DEBUG = Debug.debug("JarUtil");
+ private static final int BUFFER_SIZE = 4096;
+
/**
* 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.
@@ -138,8 +140,9 @@ public class JarUtil {
throw new IllegalArgumentException("null arguments: clazzBinName "+clazzBinName+", cl "+cl);
}
final URI uri;
+ final URL url;
{
- final URL url = IOUtil.getClassURL(clazzBinName, cl);
+ url = IOUtil.getClassURL(clazzBinName, cl);
final String scheme = url.getProtocol();
if( null != resolver &&
!scheme.equals( IOUtil.JAR_SCHEME ) &&
@@ -163,6 +166,9 @@ public class JarUtil {
if( !uri.getScheme().equals( IOUtil.JAR_SCHEME ) ) {
throw new IllegalArgumentException("URI is not using scheme "+IOUtil.JAR_SCHEME+": <"+uri+">");
}
+ if(DEBUG) {
+ System.out.println("getJarURI res: "+clazzBinName+" -> "+url+" -> "+uri);
+ }
return uri;
}
@@ -187,7 +193,7 @@ public class JarUtil {
if( !classJarURI.getScheme().equals(IOUtil.JAR_SCHEME) ) {
throw new IllegalArgumentException("URI is not using scheme "+IOUtil.JAR_SCHEME+": <"+classJarURI+">");
}
- String uriS = classJarURI.getRawSchemeSpecificPart();
+ String uriS = classJarURI.getSchemeSpecificPart();
// from
// file:/some/path/gluegen-rt.jar!/com/jogamp/common/util/cache/TempJarCache.class
@@ -264,26 +270,27 @@ public class JarUtil {
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('!');
+ final String uriS0 = classJarURI.getSchemeSpecificPart();
+ int idx = uriS0.lastIndexOf('!');
+ final String uriS1;
if (0 <= idx) {
- uriS = uriS.substring(0, idx); // exclude '!/'
+ uriS1 = uriS0.substring(0, idx); // exclude '!/'
} else {
throw new IllegalArgumentException("JAR URI does not contain jar uri terminator '!', uri <"+classJarURI+">");
}
-
- if(0 >= uriS.lastIndexOf(".jar")) {
+ if(0 >= uriS1.lastIndexOf(".jar")) {
throw new IllegalArgumentException("No Jar name in <"+classJarURI+">");
- }
+ }
+ final String uriS2 = IOUtil.encodeToURI(uriS1);
if(DEBUG) {
- System.out.println("getJarSubURI res: "+uriS);
+ System.out.println("getJarSubURI res: "+classJarURI+" -> "+uriS0+" -> "+uriS1+" -> "+uriS2);
}
- return new URI(uriS);
+ return new URI(uriS2);
}
/**
@@ -302,7 +309,7 @@ public class JarUtil {
if( !classJarURI.getScheme().equals(IOUtil.JAR_SCHEME) ) {
throw new IllegalArgumentException("URI is not a using scheme "+IOUtil.JAR_SCHEME+": <"+classJarURI+">");
}
- String uriS = classJarURI.getRawSchemeSpecificPart();
+ String uriS = classJarURI.getSchemeSpecificPart();
// from
// file:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class
@@ -391,6 +398,19 @@ public class JarUtil {
}
/**
+ * @param jarSubUriS file:/some/path/gluegen-rt.jar
+ * @return jar:file:/some/path/gluegen-rt.jar!/
+ * @throws IllegalArgumentException null arguments
+ * @throws URISyntaxException
+ */
+ public static URI getJarFileURI(String jarSubUriS) throws IllegalArgumentException, URISyntaxException {
+ if(null == jarSubUriS) {
+ throw new IllegalArgumentException("jarSubURIS is null");
+ }
+ return new URI(IOUtil.JAR_SCHEME, jarSubUriS+"!/", null);
+ }
+
+ /**
* @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
@@ -499,22 +519,23 @@ public class JarUtil {
* @param dest
* @param nativeLibMap
* @param jarFile
- * @param deepDirectoryTraversal
+ * @param nativeLibraryPath if not null, only extracts native libraries within this path.
* @param extractNativeLibraries
* @param extractClassFiles
* @param extractOtherFiles
+ * @param deepDirectoryTraversal
* @return
* @throws IOException
*/
public static final int extract(File dest, Map<String, String> nativeLibMap,
JarFile jarFile,
+ String nativeLibraryPath,
boolean extractNativeLibraries,
- boolean extractClassFiles,
- boolean extractOtherFiles) throws IOException {
+ boolean extractClassFiles, boolean extractOtherFiles) throws IOException {
if (DEBUG) {
System.err.println("JarUtil: extract: "+jarFile.getName()+" -> "+dest+
- ", extractNativeLibraries "+extractNativeLibraries+
+ ", extractNativeLibraries "+extractNativeLibraries+" ("+nativeLibraryPath+")"+
", extractClassFiles "+extractClassFiles+
", extractOtherFiles "+extractOtherFiles);
}
@@ -528,11 +549,29 @@ public class JarUtil {
// Match entries with correct prefix and suffix (ignoring case)
final String libBaseName = NativeLibrary.isValidNativeLibraryName(entryName, false);
final boolean isNativeLib = null != libBaseName;
- if(isNativeLib && !extractNativeLibraries) {
- if (DEBUG) {
- System.err.println("JarUtil: JarEntry : " + entryName + " native-lib skipped");
+ if(isNativeLib) {
+ if(!extractNativeLibraries) {
+ if (DEBUG) {
+ System.err.println("JarUtil: JarEntry : " + entryName + " native-lib skipped, skip all native libs");
+ }
+ continue;
+ }
+ if(null != nativeLibraryPath) {
+ final String nativeLibraryPathS;
+ final String dirnameS;
+ try {
+ nativeLibraryPathS = IOUtil.slashify(nativeLibraryPath, false /* startWithSlash */, true /* endWithSlash */);
+ dirnameS = IOUtil.getDirname(entryName);
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
+ if( !nativeLibraryPathS.equals(dirnameS) ) {
+ if (DEBUG) {
+ System.err.println("JarUtil: JarEntry : " + entryName + " native-lib skipped, not in path: "+nativeLibraryPathS);
+ }
+ continue;
+ }
}
- continue;
}
final boolean isClassFile = entryName.endsWith(".class");
@@ -566,20 +605,20 @@ public class JarUtil {
if (DEBUG) {
System.err.println("JarUtil: MKDIR: " + entryName + " -> " + destFile );
}
- destFile.mkdir();
+ destFile.mkdirs();
} else {
final File destFolder = new File(destFile.getParent());
if(!destFolder.exists()) {
if (DEBUG) {
System.err.println("JarUtil: MKDIR (parent): " + entryName + " -> " + destFolder );
}
- destFolder.mkdir();
+ destFolder.mkdirs();
}
final InputStream in = new BufferedInputStream(jarFile.getInputStream(entry));
final OutputStream out = new BufferedOutputStream(new FileOutputStream(destFile));
int numBytes = -1;
try {
- numBytes = IOUtil.copyStream2Stream(in, out, -1);
+ numBytes = IOUtil.copyStream2Stream(BUFFER_SIZE, in, out, -1);
} finally {
in.close();
out.close();
diff --git a/src/java/com/jogamp/common/util/PropertyAccess.java b/src/java/com/jogamp/common/util/PropertyAccess.java
index 1a4bc7e..fdb2665 100644
--- a/src/java/com/jogamp/common/util/PropertyAccess.java
+++ b/src/java/com/jogamp/common/util/PropertyAccess.java
@@ -40,12 +40,19 @@ public class PropertyAccess {
public static final String javaws_prefix = "javaws.";
static final HashSet<String> trustedPrefixes;
+ static final HashSet<String> trusted;
static {
trustedPrefixes = new HashSet<String>();
trustedPrefixes.add(javaws_prefix);
trustedPrefixes.add(jnlp_prefix);
// 'jogamp.' and maybe other trusted prefixes will be added later via 'addTrustedPrefix()'
+
+ trusted = new HashSet<String>();
+ trusted.add("sun.java2d.opengl");
+ trusted.add("sun.java2d.noddraw");
+ trusted.add("sun.java2d.d3d");
+ trusted.add("sun.awt.noerasebackground");
}
/**
@@ -60,7 +67,7 @@ public class PropertyAccess {
public static final boolean isTrusted(String propertyKey) {
final int dot1 = propertyKey.indexOf('.');
if(0<=dot1) {
- return trustedPrefixes.contains(propertyKey.substring(0, dot1+1));
+ return trustedPrefixes.contains(propertyKey.substring(0, dot1+1)) || trusted.contains(propertyKey);
} else {
return false;
}
diff --git a/src/java/com/jogamp/common/util/VersionUtil.java b/src/java/com/jogamp/common/util/VersionUtil.java
index 8d9e6a9..8030e94 100644
--- a/src/java/com/jogamp/common/util/VersionUtil.java
+++ b/src/java/com/jogamp/common/util/VersionUtil.java
@@ -55,7 +55,7 @@ public class VersionUtil {
sb.append(SEPERATOR).append(Platform.getNewline());
// environment
- sb.append("Platform: ").append(Platform.getOSType()).append(" / ").append(Platform.getOSName()).append(' ').append(Platform.getOSVersion()).append(" (os), ");
+ sb.append("Platform: ").append(Platform.getOSType()).append(" / ").append(Platform.getOSName()).append(' ').append(Platform.getOSVersion()).append(" (").append(Platform.getOSVersionNumber()).append("), ");
sb.append(Platform.getArchName()).append(" (arch), ").append(Platform.getABIType()).append(", ");
sb.append(Runtime.getRuntime().availableProcessors()).append(" cores");
sb.append(Platform.getNewline());
@@ -68,7 +68,7 @@ public class VersionUtil {
Platform.getMachineDescription().toString(sb).append(Platform.getNewline());
// JVM/JRE
- sb.append("Platform: Java Version: ").append(Platform.getJavaVersion()).append(", VM: ").append(Platform.getJavaVMName());
+ sb.append("Platform: Java Version: ").append(Platform.getJavaVersion()).append(" (").append(Platform.getJavaVersionNumber()).append("u").append(Platform.JAVA_VERSION_UPDATE).append("), VM: ").append(Platform.getJavaVMName());
sb.append(", Runtime: ").append(Platform.getJavaRuntimeName()).append(Platform.getNewline());
sb.append("Platform: Java Vendor: ").append(Platform.getJavaVendor()).append(", ").append(Platform.getJavaVendorURL());
sb.append(", JavaSE: ").append(Platform.isJavaSE());
diff --git a/src/java/com/jogamp/common/util/cache/TempJarCache.java b/src/java/com/jogamp/common/util/cache/TempJarCache.java
index 30dea45..ecf6e56 100644
--- a/src/java/com/jogamp/common/util/cache/TempJarCache.java
+++ b/src/java/com/jogamp/common/util/cache/TempJarCache.java
@@ -27,20 +27,13 @@
*/
package com.jogamp.common.util.cache;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.cert.Certificate;
-import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
-import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import jogamp.common.Debug;
@@ -204,25 +197,32 @@ public class TempJarCache {
*
* @param certClass if class is certified, the JarFile entries needs to have the same certificate
* @param jarURI
+ * @param nativeLibraryPath if not null, only extracts native libraries within this path.
+ * @return true if native libraries were added or previously loaded from given jarURI, otherwise false
* @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, IllegalArgumentException, URISyntaxException {
+ public synchronized static final boolean addNativeLibs(Class<?> certClass, URI jarURI, String nativeLibraryPath) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException {
final LoadState nativeLibJarsLS = nativeLibJars.get(jarURI);
if( !testLoadState(nativeLibJarsLS, LoadState.LOOKED_UP) ) {
nativeLibJars.put(jarURI, LoadState.LOOKED_UP);
final JarFile jarFile = JarUtil.getJarFile(jarURI);
if(DEBUG) {
- System.err.println("TempJarCache: addNativeLibs: "+jarURI+": nativeJar "+jarFile.getName());
+ System.err.println("TempJarCache: addNativeLibs: "+jarURI+": nativeJar "+jarFile.getName()+" (NEW)");
}
validateCertificates(certClass, jarFile);
- JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile, true, false, false);
+ final int num = JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile, nativeLibraryPath, true, false, false);
nativeLibJars.put(jarURI, LoadState.LOADED);
- } else if( !testLoadState(nativeLibJarsLS, LoadState.LOADED) ) {
- throw new IOException("TempJarCache: addNativeLibs: "+jarURI+", previous load attempt failed");
+ return num > 0;
+ } else if( testLoadState(nativeLibJarsLS, LoadState.LOADED) ) {
+ if(DEBUG) {
+ System.err.println("TempJarCache: addNativeLibs: "+jarURI+": nativeJar "+jarURI+" (REUSE)");
+ }
+ return true;
}
+ throw new IOException("TempJarCache: addNativeLibs: "+jarURI+", previous load attempt failed");
}
/**
@@ -248,7 +248,7 @@ public class TempJarCache {
}
validateCertificates(certClass, jarFile);
JarUtil.extract(tmpFileCache.getTempDir(), null, jarFile,
- false, true, false);
+ null /* nativeLibraryPath */, false, true, false);
classFileJars.put(jarURI, LoadState.LOADED);
} else if( !testLoadState(classFileJarsLS, LoadState.LOADED) ) {
throw new IOException("TempJarCache: addClasses: "+jarURI+", previous load attempt failed");
@@ -276,7 +276,7 @@ public class TempJarCache {
}
validateCertificates(certClass, jarFile);
JarUtil.extract(tmpFileCache.getTempDir(), null, jarFile,
- false, false, true);
+ null /* nativeLibraryPath */, false, false, true);
resourceFileJars.put(jarURI, LoadState.LOADED);
} else if( !testLoadState(resourceFileJarsLS, LoadState.LOADED) ) {
throw new IOException("TempJarCache: addResources: "+jarURI+", previous load attempt failed");
@@ -330,7 +330,7 @@ public class TempJarCache {
}
validateCertificates(certClass, jarFile);
JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile,
- extractNativeLibraries, extractClassFiles, extractOtherFiles);
+ null /* nativeLibraryPath */, extractNativeLibraries, extractClassFiles, extractOtherFiles);
// mark loaded (those were just loaded)
if(extractNativeLibraries) {
@@ -397,76 +397,7 @@ public class TempJarCache {
}
return null;
}
-
-
- /**
- * Bootstrapping version extracting the JAR files root entry containing libBaseName,
- * assuming it's a native library. This is used to get the 'gluegen-rt'
- * native library, hence bootstrapping.
- *
- * @param certClass if class is certified, the JarFile entries needs to have the same certificate
- *
- * @throws IOException
- * @throws SecurityException
- * @throws URISyntaxException
- * @throws IllegalArgumentException
- */
- public synchronized static final void bootstrapNativeLib(Class<?> certClass, String libBaseName, URI jarURI)
- throws IOException, SecurityException, IllegalArgumentException, URISyntaxException {
- checkInitialized();
- boolean ok = false;
- int countEntries = 0;
- 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+", jarURI "+jarURI+")");
- }
- nativeLibJars.put(jarURI, LoadState.LOOKED_UP);
- final JarFile jarFile = JarUtil.getJarFile(jarURI);
- if(DEBUG) {
- System.err.println("TempJarCache: bootstrapNativeLib: nativeJar "+jarFile.getName());
- }
- validateCertificates(certClass, jarFile);
- final Enumeration<JarEntry> entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- final JarEntry entry = entries.nextElement();
- final String entryName = entry.getName();
-
- if( entryName.indexOf('/') == -1 &&
- entryName.indexOf(File.separatorChar) == -1 &&
- entryName.indexOf(libBaseName) >= 0 )
- {
- final File destFile = new File(tmpFileCache.getTempDir(), entryName);
- final InputStream in = new BufferedInputStream(jarFile.getInputStream(entry));
- final OutputStream out = new BufferedOutputStream(new FileOutputStream(destFile));
- int numBytes = 0;
- try {
- final byte[] buf = new byte[ 2048 ];
- while (true) {
- int countBytes;
- if ((countBytes = in.read(buf)) == -1) { break; }
- out.write(buf, 0, countBytes);
- numBytes += countBytes;
- }
- } finally { in.close(); out.close(); }
- if (numBytes>0) {
- nativeLibMap.put(libBaseName, destFile.getAbsolutePath());
- nativeLibJars.put(jarURI, LoadState.LOADED);
- ok = true;
- countEntries++;
- }
- }
- }
- } else if( testLoadState(nativeLibJarsLS, LoadState.LOADED) ) {
- ok = true; // already loaded
- } else {
- throw new IOException("TempJarCache: bootstrapNativeLib: "+jarURI+", previous load attempt failed");
- }
- if(DEBUG) {
- System.err.println("TempJarCache: bootstrapNativeLib() done, count "+countEntries+", ok "+ok);
- }
- }
-
+
private static void validateCertificates(Class<?> certClass, JarFile jarFile) throws IOException, SecurityException {
if(null == certClass) {
throw new IllegalArgumentException("certClass is null");