summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xmake/scripts/runtest.sh6
-rw-r--r--src/java/com/jogamp/common/ExceptionUtils.java32
-rw-r--r--src/java/com/jogamp/common/net/Uri.java9
-rw-r--r--src/java/com/jogamp/common/util/IOUtil.java44
-rw-r--r--src/java/com/jogamp/common/util/JarUtil.java6
-rw-r--r--src/java/com/jogamp/common/util/SourcedInterruptedException.java6
-rw-r--r--src/junit/com/jogamp/common/net/TestUri01.java32
-rw-r--r--src/junit/com/jogamp/common/util/TestIOUtil01.java88
8 files changed, 185 insertions, 38 deletions
diff --git a/make/scripts/runtest.sh b/make/scripts/runtest.sh
index ac56a9c..a132a06 100755
--- a/make/scripts/runtest.sh
+++ b/make/scripts/runtest.sh
@@ -60,7 +60,7 @@ X_ARGS="-Drootrel.build=$ROOTREL_BUILD -Dgluegen.root=$GLUEGEN_ROOT"
#D_ARGS="-Djogamp.debug.Lock"
#D_ARGS="-Djogamp.debug.Lock -Djogamp.debug.Lock.TraceLock"
#D_ARGS="-Djogamp.debug.Lock.TraceLock"
-D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.IOUtil.Exe -Djogamp.debug.IOUtil.Exe.NoStream"
+#D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.IOUtil.Exe -Djogamp.debug.IOUtil.Exe.NoStream"
#D_ARGS="-Djogamp.debug.IOUtil -Djogamp.debug.IOUtil.Exe"
#D_ARGS="-Djogamp.debug.ByteBufferInputStream"
#D_ARGS="-Djogamp.debug.Bitstream"
@@ -106,9 +106,9 @@ function onetest() {
#onetest com.jogamp.common.util.IntIntHashMapTest 2>&1 | tee -a $LOG
#onetest com.jogamp.common.util.IntObjectHashMapTest 2>&1 | tee -a $LOG
#onetest com.jogamp.common.util.LongIntHashMapTest 2>&1 | tee -a $LOG
-onetest com.jogamp.common.util.TestPlatform01 2>&1 | tee -a $LOG
+#onetest com.jogamp.common.util.TestPlatform01 2>&1 | tee -a $LOG
#onetest com.jogamp.common.util.TestRunnableTask01 2>&1 | tee -a $LOG
-#onetest com.jogamp.common.util.TestIOUtil01 2>&1 | tee -a $LOG
+onetest com.jogamp.common.util.TestIOUtil01 2>&1 | tee -a $LOG
#onetest com.jogamp.common.util.TestTempJarCache 2>&1 | tee -a $LOG
#onetest com.jogamp.common.util.TestJarUtil 2>&1 | tee -a $LOG
#onetest com.jogamp.common.util.TestValueConversion 2>&1 | tee -a $LOG
diff --git a/src/java/com/jogamp/common/ExceptionUtils.java b/src/java/com/jogamp/common/ExceptionUtils.java
index 108b466..295a59c 100644
--- a/src/java/com/jogamp/common/ExceptionUtils.java
+++ b/src/java/com/jogamp/common/ExceptionUtils.java
@@ -65,26 +65,26 @@ public class ExceptionUtils {
void printStackTrace(final PrintStream s);
}
- public static int dumpCause(final PrintStream s, final String causeStr, Throwable cause, int causeDepth) {
- for( ; null != cause; cause = cause.getCause() ) {
+ public static int dumpCause(final PrintStream s, final String causeStr, Throwable cause, int causeIdx, final int causeDepth, final int stackDepth) {
+ for(int i=0; null != cause && ( -1 == causeDepth || i < causeDepth ); cause = cause.getCause(), i++) {
if( cause instanceof CustomStackTrace ) {
- ((CustomStackTrace)cause).dumpCauseStack(s, causeStr, causeDepth);
+ ((CustomStackTrace)cause).dumpCauseStack(s, causeStr, causeIdx);
} else {
- s.println(causeStr+"["+causeDepth+"] by "+cause.getClass().getSimpleName()+": "+cause.getMessage()+" on thread "+Thread.currentThread().getName());
- dumpStack(s, cause.getStackTrace(), 0, -1);
+ s.println(causeStr+"["+causeIdx+"] by "+cause.getClass().getSimpleName()+": "+cause.getMessage()+" on thread "+Thread.currentThread().getName());
+ dumpStack(s, cause.getStackTrace(), 0, stackDepth);
}
- causeDepth++;
+ causeIdx++;
}
- return causeDepth;
+ return causeIdx;
}
- public static void printStackTrace(final PrintStream s, final Throwable t) {
+ public static void printStackTrace(final PrintStream s, final Throwable t, final int causeDepth, final int stackDepth) {
if( t instanceof CustomStackTrace ) {
((CustomStackTrace)t).printStackTrace(s);
} else {
s.println(t.getClass().getSimpleName()+": "+t.getMessage()+" on thread "+Thread.currentThread().getName());
- dumpStack(s, t.getStackTrace(), 0, -1);
- dumpCause(s, "Caused", t.getCause(), 1);
+ dumpStack(s, t.getStackTrace(), 0, stackDepth);
+ dumpCause(s, "Caused", t.getCause(), 1, causeDepth, stackDepth);
}
}
@@ -96,7 +96,17 @@ public class ExceptionUtils {
* </p>
*/
public static void dumpThrowable(final String additionalDescr, final Throwable t) {
+ dumpThrowable(additionalDescr, t, -1, -1);
+ }
+ /**
+ * Dumps a {@link Throwable} in a decorating message including the current thread name,
+ * and its {@link #dumpStack(PrintStream, StackTraceElement[], int, int) stack trace}.
+ * <p>
+ * Implementation will iterate through all {@link Throwable#getCause() causes}.
+ * </p>
+ */
+ public static void dumpThrowable(final String additionalDescr, final Throwable t, final int causeDepth, final int stackDepth) {
System.err.print("Caught "+additionalDescr+" ");
- printStackTrace(System.err, t);
+ printStackTrace(System.err, t, causeDepth, stackDepth);
}
}
diff --git a/src/java/com/jogamp/common/net/Uri.java b/src/java/com/jogamp/common/net/Uri.java
index 6bafba2..a6fd4fe 100644
--- a/src/java/com/jogamp/common/net/Uri.java
+++ b/src/java/com/jogamp/common/net/Uri.java
@@ -1232,7 +1232,12 @@ public class Uri {
/** Returns true, if this instance is a {@code file} {@code scheme}, otherwise false. */
public final boolean isFileScheme() {
- return FILE_SCHEME.equals( scheme.get() );
+ return null != scheme && FILE_SCHEME.equals( scheme.get() );
+ }
+
+ /** Returns true, if this instance is a {@code jar} {@code scheme}, otherwise false. */
+ public final boolean isJarScheme() {
+ return null != scheme && JAR_SCHEME.equals( scheme.get() );
}
/**
@@ -1386,7 +1391,7 @@ public class Uri {
if( !emptyString(schemeSpecificPart) ) {
final StringBuilder sb = new StringBuilder();
- if( scheme.equals(JAR_SCHEME) ) {
+ if( isJarScheme() ) {
final int idx = schemeSpecificPart.lastIndexOf(JAR_SCHEME_SEPARATOR);
if (0 > idx) {
throw new URISyntaxException(input.get(), "missing jar separator");
diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java
index 7853555..653520d 100644
--- a/src/java/com/jogamp/common/util/IOUtil.java
+++ b/src/java/com/jogamp/common/util/IOUtil.java
@@ -620,7 +620,7 @@ public class IOUtil {
}
/**
- * @param path assuming a slashified path beginning with "/" as it's root directory, either denotes a file or directory.
+ * @param path assuming a slashified path, either denotes a file or directory, either relative or absolute.
* @return parent of path
* @throws URISyntaxException if path is empty or has no parent directory available
*/
@@ -632,11 +632,11 @@ public class IOUtil {
final int e = path.lastIndexOf("/");
if( e < 0 ) {
- throw new URISyntaxException(path, "path contains no '/'");
+ throw new URISyntaxException(path, "path contains no '/': <"+path+">");
}
if( e == 0 ) {
// path is root directory
- throw new URISyntaxException(path, "path has no parents");
+ throw new URISyntaxException(path, "path has no parents: <"+path+">");
}
if( e < pl - 1 ) {
// path is file, return it's parent directory
@@ -646,23 +646,45 @@ public class IOUtil {
// path is a directory ..
final int p = path.lastIndexOf("/", e-1);
if( p >= j) {
+ // parent itself has '/' - post '!' or no '!' at all
return path.substring(0, p+1);
+ } else {
+ // parent itself has no '/'
+ final String parent = path.substring(j, e);
+ if( parent.equals("..") ) {
+ throw new URISyntaxException(path, "parent is unresolved: <"+path+">");
+ } else {
+ // parent is '!' or empty (relative path)
+ return path.substring(0, j);
+ }
}
- 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.
+ * @param path assuming a slashified path, either denoting a file or directory, either relative or absolute.
+ * @return clean path string where {@code ./} and {@code ../} is resolved,
+ * while keeping a starting {@code ../} at the beginning of a relative path.
* @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code>
*/
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);
+ // Resolve './' before '../' to handle case 'parent/./../a.txt' properly.
+ int idx = path.length() - 1;
+ while ( idx >= 1 && ( idx = path.lastIndexOf("./", idx) ) >= 0 ) {
+ if( 0 < idx && path.charAt(idx-1) == '.' ) {
+ idx-=2; // skip '../' -> idx upfront
+ } else {
+ path = path.substring(0, idx) + path.substring(idx+2);
+ idx--; // idx upfront
+ }
}
- while ( ( idx = path.indexOf("./") ) >= 0 ) {
- path = path.substring(0, idx) + path.substring(idx+2);
+ idx = 0;
+ while ( ( idx = path.indexOf("../", idx) ) >= 0 ) {
+ if( 0 == idx ) {
+ idx += 3; // skip starting '../'
+ } else {
+ path = getParentOf(path.substring(0, idx)) + path.substring(idx+3);
+ idx = 0;
+ }
}
return path;
}
diff --git a/src/java/com/jogamp/common/util/JarUtil.java b/src/java/com/jogamp/common/util/JarUtil.java
index 745dd12..2580714 100644
--- a/src/java/com/jogamp/common/util/JarUtil.java
+++ b/src/java/com/jogamp/common/util/JarUtil.java
@@ -163,7 +163,7 @@ public class JarUtil {
}
}
}
- if( !uri.scheme.equals( Uri.JAR_SCHEME ) ) {
+ if( !uri.isJarScheme() ) {
throw new IllegalArgumentException("Uri is not using scheme "+Uri.JAR_SCHEME+": <"+uri+">");
}
if(DEBUG) {
@@ -190,7 +190,7 @@ public class JarUtil {
if(null == classJarUri) {
throw new IllegalArgumentException("Uri is null");
}
- if( !classJarUri.scheme.equals(Uri.JAR_SCHEME) ) {
+ if( !classJarUri.isJarScheme() ) {
throw new IllegalArgumentException("Uri is not using scheme "+Uri.JAR_SCHEME+": <"+classJarUri+">");
}
Uri.Encoded ssp = classJarUri.schemeSpecificPart;
@@ -262,7 +262,7 @@ public class JarUtil {
if(null == classJarUri) {
throw new IllegalArgumentException("Uri is null");
}
- if( !classJarUri.scheme.equals(Uri.JAR_SCHEME) ) {
+ if( !classJarUri.isJarScheme() ) {
throw new IllegalArgumentException("Uri is not a using scheme "+Uri.JAR_SCHEME+": <"+classJarUri+">");
}
final Uri.Encoded uriSSP = classJarUri.schemeSpecificPart;
diff --git a/src/java/com/jogamp/common/util/SourcedInterruptedException.java b/src/java/com/jogamp/common/util/SourcedInterruptedException.java
index 49dcd86..2483d5b 100644
--- a/src/java/com/jogamp/common/util/SourcedInterruptedException.java
+++ b/src/java/com/jogamp/common/util/SourcedInterruptedException.java
@@ -150,7 +150,7 @@ public class SourcedInterruptedException extends InterruptedException implements
s.println(s0+" by "+getClass().getSimpleName()+": "+getMessage()+" on thread "+Thread.currentThread().getName());
ExceptionUtils.dumpStack(s, getStackTrace(), 0, -1);
if( null != interruptSource ) {
- ExceptionUtils.dumpCause(s, s0, interruptSource, 1);
+ ExceptionUtils.dumpCause(s, s0, interruptSource, 1, -1, -1);
}
}
@@ -158,9 +158,9 @@ public class SourcedInterruptedException extends InterruptedException implements
public final void printStackTrace(final PrintStream s) {
s.println(getClass().getSimpleName()+": "+getMessage()+" on thread "+Thread.currentThread().getName());
ExceptionUtils.dumpStack(s, getStackTrace(), 0, -1);
- final int causeDepth = ExceptionUtils.dumpCause(s, "Caused", getCause(), 1);
+ final int causeDepth = ExceptionUtils.dumpCause(s, "Caused", getCause(), 1, -1, -1);
if( null != interruptSource ) {
- ExceptionUtils.dumpCause(s, "InterruptSource", interruptSource, causeDepth);
+ ExceptionUtils.dumpCause(s, "InterruptSource", interruptSource, causeDepth, -1, -1);
}
}
}
diff --git a/src/junit/com/jogamp/common/net/TestUri01.java b/src/junit/com/jogamp/common/net/TestUri01.java
index 1173610..4205de1 100644
--- a/src/junit/com/jogamp/common/net/TestUri01.java
+++ b/src/junit/com/jogamp/common/net/TestUri01.java
@@ -248,6 +248,20 @@ public class TestUri01 extends SingletonJunitCase {
@Test
public void test08NormalizedHierarchy() throws IOException, URISyntaxException {
{
+ final Uri input = Uri.cast("./dummy/nop/../a.txt");
+ final Uri expected = Uri.cast("dummy/a.txt");
+ URIDumpUtil.showUri(input);
+ final Uri normal = input.getNormalized();
+ Assert.assertEquals(expected, normal);
+ }
+ {
+ final Uri input = Uri.cast("../dummy/nop/../a.txt");
+ final Uri expected = Uri.cast("../dummy/a.txt");
+ URIDumpUtil.showUri(input);
+ final Uri normal = input.getNormalized();
+ Assert.assertEquals(expected, normal);
+ }
+ {
final Uri input = Uri.cast("http://localhost/dummy/../");
final Uri expected = Uri.cast("http://localhost/");
URIDumpUtil.showUri(input);
@@ -255,7 +269,21 @@ public class TestUri01 extends SingletonJunitCase {
Assert.assertEquals(expected, normal);
}
{
- final Uri input = Uri.cast("http://localhost/test/dummy/../text.txt");
+ final Uri input = Uri.cast("http://localhost/dummy/./../");
+ final Uri expected = Uri.cast("http://localhost/");
+ URIDumpUtil.showUri(input);
+ final Uri normal = input.getNormalized();
+ Assert.assertEquals(expected, normal);
+ }
+ {
+ final Uri input = Uri.cast("http://localhost/dummy/../aa/././../");
+ final Uri expected = Uri.cast("http://localhost/");
+ URIDumpUtil.showUri(input);
+ final Uri normal = input.getNormalized();
+ Assert.assertEquals(expected, normal);
+ }
+ {
+ final Uri input = Uri.cast("http://localhost/test/dummy/./../text.txt");
final Uri expected = Uri.cast("http://localhost/test/text.txt");
URIDumpUtil.showUri(input);
final Uri normal = input.getNormalized();
@@ -280,7 +308,7 @@ public class TestUri01 extends SingletonJunitCase {
Assert.assertEquals(expected, normal);
}
{
- final Uri input = Uri.cast("jar:http://localhost/test/dummy/../abc.jar!/");
+ final Uri input = Uri.cast("jar:http://localhost/test/./dummy/../abc.jar!/");
final Uri expected = Uri.cast("jar:http://localhost/test/abc.jar!/");
URIDumpUtil.showUri(input);
final Uri normal = input.getNormalized();
diff --git a/src/junit/com/jogamp/common/util/TestIOUtil01.java b/src/junit/com/jogamp/common/util/TestIOUtil01.java
index be0c9a4..19bc8b0 100644
--- a/src/junit/com/jogamp/common/util/TestIOUtil01.java
+++ b/src/junit/com/jogamp/common/util/TestIOUtil01.java
@@ -35,6 +35,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.net.URISyntaxException;
import java.net.URLConnection;
import java.nio.ByteBuffer;
@@ -43,6 +44,9 @@ import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
+import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.net.URIDumpUtil;
+import com.jogamp.common.net.Uri;
import com.jogamp.common.os.MachineDataInfo;
import com.jogamp.common.os.Platform;
import com.jogamp.junit.util.SingletonJunitCase;
@@ -78,7 +82,85 @@ public class TestIOUtil01 extends SingletonJunitCase {
}
@Test
- public void testCopyStream01Array() throws IOException {
+ public void test01CleanPathString() throws IOException, URISyntaxException {
+ {
+ final String input = "./dummy/nop/../a.txt";
+ final String expected = "dummy/a.txt";
+ Assert.assertEquals(expected, IOUtil.cleanPathString(input));
+ }
+ {
+ final String input = "../dummy/nop/../a.txt";
+ final String expected = "../dummy/a.txt";
+ Assert.assertEquals(expected, IOUtil.cleanPathString(input));
+ }
+ {
+ final String input = ".././dummy/nop/../a.txt";
+ final String expected = "../dummy/a.txt";
+ Assert.assertEquals(expected, IOUtil.cleanPathString(input));
+ }
+ {
+ final String input = "./../dummy/nop/../a.txt";
+ final String expected = "../dummy/a.txt";
+ Assert.assertEquals(expected, IOUtil.cleanPathString(input));
+ }
+ {
+ final String input = "../dummy/./nop/../a.txt";
+ final String expected = "../dummy/a.txt";
+ Assert.assertEquals(expected, IOUtil.cleanPathString(input));
+ }
+ {
+ final String input = "/dummy/nop/./../a.txt";
+ final String expected = "/dummy/a.txt";
+ Assert.assertEquals(expected, IOUtil.cleanPathString(input));
+ }
+ {
+ final String input = "dummy/../nop/./.././aaa/bbb/../../a.txt";
+ final String expected = "a.txt";
+ Assert.assertEquals(expected, IOUtil.cleanPathString(input));
+ }
+ {
+ final String input = "/dummy/../nop/./.././aaa/bbb/././ccc/../../../a.txt";
+ final String expected = "/a.txt";
+ Assert.assertEquals(expected, IOUtil.cleanPathString(input));
+ }
+ {
+ URISyntaxException use = null;
+ try {
+ // Error case!
+ final String input = "../../error.txt";
+ final String expected = "error.txt";
+ final String result = IOUtil.cleanPathString(input); // URISyntaxException
+ System.err.println("input : "+input);
+ System.err.println("expected: "+expected);
+ System.err.println("result : "+result);
+ Assert.assertEquals(expected, result);
+ } catch (final URISyntaxException _use) {
+ use = _use;
+ ExceptionUtils.dumpThrowable("", _use, 0, 3);
+ }
+ Assert.assertNotNull("URISyntaxException expected", use);
+ }
+ {
+ URISyntaxException use = null;
+ try {
+ // Error case!
+ final String input = ".././a/../../error.txt";
+ final String expected = "error.txt";
+ final String result = IOUtil.cleanPathString(input); // URISyntaxException
+ System.err.println("input : "+input);
+ System.err.println("expected: "+expected);
+ System.err.println("result : "+result);
+ Assert.assertEquals(expected, result);
+ } catch (final URISyntaxException _use) {
+ use = _use;
+ ExceptionUtils.dumpThrowable("", _use, 0, 3);
+ }
+ Assert.assertNotNull("URISyntaxException expected", use);
+ }
+ }
+
+ @Test
+ public void test11CopyStream01Array() throws IOException {
final URLConnection urlConn = IOUtil.getResource(tfilename, this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(urlConn);
final BufferedInputStream bis = new BufferedInputStream( urlConn.getInputStream() );
@@ -94,7 +176,7 @@ public class TestIOUtil01 extends SingletonJunitCase {
}
@Test
- public void testCopyStream02Buffer() throws IOException {
+ public void test12CopyStream02Buffer() throws IOException {
final URLConnection urlConn = IOUtil.getResource(tfilename, this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(urlConn);
final BufferedInputStream bis = new BufferedInputStream( urlConn.getInputStream() );
@@ -111,7 +193,7 @@ public class TestIOUtil01 extends SingletonJunitCase {
}
@Test
- public void testCopyStream03Buffer() throws IOException {
+ public void test13CopyStream03Buffer() throws IOException {
final String tfilename2 = "./test2.bin" ;
final URLConnection urlConn1 = IOUtil.getResource(tfilename, this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(urlConn1);