From 41fce94f95448bbea110a455ea508740fac8d8c9 Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Mon, 7 Oct 2013 01:06:42 +0200
Subject: Bug 820: Escape SPACE in filenames for URI ctor, use decoded URI
 components when compiling new URI.

Add IOUtil:
  - String encodeToURI(String)
  - String decodeFromURI(String)

Both only handle escaping of SPACE only. Determine whether other chars need to be treated.
---
 src/java/com/jogamp/common/util/IOUtil.java  | 35 +++++++++++++++++++++++-----
 src/java/com/jogamp/common/util/JarUtil.java | 14 +++++------
 2 files changed, 36 insertions(+), 13 deletions(-)

(limited to 'src/java/com')

diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java
index 5918213..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;
@@ -312,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);        
     }
     
     /** 
@@ -321,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);        
     }
 
     /**
@@ -462,7 +463,7 @@ public class IOUtil {
      * <i>protocol</i> may be "file", "http", etc..
      * </p>
      * 
-     * @param uri "<i>protocol</i>:/some/path/gluegen-rt.jar"
+     * @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 
@@ -727,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());
     }
     
     /**
@@ -753,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
@@ -777,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 481fe92..29e7dc7 100644
--- a/src/java/com/jogamp/common/util/JarUtil.java
+++ b/src/java/com/jogamp/common/util/JarUtil.java
@@ -193,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
@@ -275,7 +275,7 @@ public class JarUtil {
         //   file:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class
         // to
         //   file:/some/path/gluegen-rt.jar
-        final String uriS0 = classJarURI.getRawSchemeSpecificPart();        
+        final String uriS0 = classJarURI.getSchemeSpecificPart();        
         int idx = uriS0.lastIndexOf('!');
         final String uriS1;
         if (0 <= idx) {
@@ -283,14 +283,14 @@ public class JarUtil {
         } else {
             throw new IllegalArgumentException("JAR URI does not contain jar uri terminator '!', uri <"+classJarURI+">");
         }
-        
         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: "+classJarURI+" -> "+uriS0+" -> "+uriS1+" -> "+uriS1);
+            System.out.println("getJarSubURI res: "+classJarURI+" -> "+uriS0+" -> "+uriS1+" -> "+uriS2);
         }
-        return new URI(uriS1);
+        return new URI(uriS2);
     }
     
     /**
@@ -309,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
-- 
cgit v1.2.3