You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2010/04/01 13:48:49 UTC

svn commit: r929938 - in /openejb/trunk/openejb3/container: openejb-core/src/main/java/org/apache/openejb/util/URLs.java openejb-loader/src/main/java/org/apache/openejb/loader/JarLocation.java

Author: dblevins
Date: Thu Apr  1 11:48:49 2010
New Revision: 929938

URL: http://svn.apache.org/viewvc?rev=929938&view=rev
Log:
OPENEJB-1252: URL->File decoding should avoid "+" in paths

Modified:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/URLs.java
    openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/JarLocation.java

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/URLs.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/URLs.java?rev=929938&r1=929937&r2=929938&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/URLs.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/URLs.java Thu Apr  1 11:48:49 2010
@@ -16,11 +16,11 @@
  */
 package org.apache.openejb.util;
 
+import static org.apache.openejb.loader.JarLocation.decode;
+
 import java.io.File;
-import java.net.URI;
-import java.net.URL;
-import java.net.URLDecoder;
 import java.net.MalformedURLException;
+import java.net.URL;
 
 /**
  * @version $Rev$ $Date$
@@ -28,27 +28,28 @@ import java.net.MalformedURLException;
 public class URLs {
 
     public static File toFile(URL url) {
+        if ("jar".equals(url.getProtocol())) {
+            try {
+                String spec = url.getFile();
 
-        String path = url.getPath();
-
-        if (path.contains("!")){
-            path = path.substring(0, path.indexOf('!'));
-        }
+                int separator = spec.indexOf('!');
+                /*
+                 * REMIND: we don't handle nested JAR URLs
+                 */
+                if (separator == -1) throw new MalformedURLException("no ! found in jar url spec:" + spec);
 
-        if (path.startsWith("file:")){
-            try {
-                url = new URL(path);
-                path = url.getPath();
+                return toFile(new URL(spec.substring(0, separator++)));
             } catch (MalformedURLException e) {
+                throw new IllegalStateException(e);
             }
+        } else if ("file".equals(url.getProtocol())) {
+            return new File(decode(url.getFile()));
+        } else {
+            throw new IllegalArgumentException("Unsupported URL scheme: " + url.toExternalForm());
         }
-
-        return new File(URI.create(path).getPath());
     }
 
     public static String toFilePath(URL url) {
         return toFile(url).getAbsolutePath();
     }
-
-
 }

Modified: openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/JarLocation.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/JarLocation.java?rev=929938&r1=929937&r2=929938&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/JarLocation.java (original)
+++ openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/JarLocation.java Thu Apr  1 11:48:49 2010
@@ -16,10 +16,10 @@
  */
 package org.apache.openejb.loader;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.net.URI;
+import java.net.MalformedURLException;
 import java.net.URL;
-import java.net.URLDecoder;
 
 /**
  * @version $Rev$ $Date$
@@ -34,29 +34,86 @@ public class JarLocation {
         try {
             String classFileName = clazz.getName().replace(".", "/") + ".class";
 
-            URL classURL = clazz.getClassLoader().getResource(classFileName);
-
-            URI uri = null;
-            String url = classURL.toExternalForm();
-            if (url.contains(" ")) {
-                url = url.replaceAll(" ", "%20");
+            ClassLoader loader = clazz.getClassLoader();
+            URL url;
+            if (loader != null) {
+                url = loader.getResource(classFileName);
+            } else {
+                url = clazz.getResource(classFileName);
             }
-            uri = new URI(url);
 
-            if (uri.getPath() == null){
-                uri = new URI(uri.getRawSchemeSpecificPart());
+            if (url == null) {
+                throw new IllegalStateException("classloader.getResource(classFileName) returned a null URL");
             }
 
-            String path = uri.getPath();
-            if (path.contains("!")){
-                path = path.substring(0, path.indexOf('!'));
-            } else {
+            if ("jar".equals(url.getProtocol())) {
+                String spec = url.getFile();
+
+                int separator = spec.indexOf('!');
+                /*
+                 * REMIND: we don't handle nested JAR URLs
+                 */
+                if (separator == -1) throw new MalformedURLException("no ! found in jar url spec:" + spec);
+
+                url = new URL(spec.substring(0, separator++));
+
+                return new File(decode(url.getFile()));
+
+            } else if ("file".equals(url.getProtocol())) {
+                String path = url.getFile();
                 path = path.substring(0, path.length() - classFileName.length());
+                return new File(decode(path));
+            } else {
+                throw new IllegalArgumentException("Unsupported URL scheme: " + url.toExternalForm());
             }
-
-            return new File(URLDecoder.decode(path));
+        } catch (RuntimeException e) {
+            throw e;
         } catch (Exception e) {
             throw new IllegalStateException(e);
         }
     }
+
+
+    public static String decode(String fileName) {
+        if (fileName.indexOf('%') == -1) return fileName;
+
+        StringBuilder result = new StringBuilder(fileName.length());
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        for (int i = 0; i < fileName.length();) {
+            char c = fileName.charAt(i);
+
+            if (c == '%') {
+                out.reset();
+                do {
+                    if (i + 2 >= fileName.length()) {
+                        throw new IllegalArgumentException("Incomplete % sequence at: " + i);
+                    }
+
+                    int d1 = Character.digit(fileName.charAt(i + 1), 16);
+                    int d2 = Character.digit(fileName.charAt(i + 2), 16);
+
+                    if (d1 == -1 || d2 == -1) {
+                        throw new IllegalArgumentException("Invalid % sequence (" + fileName.substring(i, i + 3) + ") at: " + String.valueOf(i));
+                    }
+
+                    out.write((byte) ((d1 << 4) + d2));
+
+                    i += 3;
+
+                } while (i < fileName.length() && fileName.charAt(i) == '%');
+
+
+                result.append(out.toString());
+
+                continue;
+            } else {
+                result.append(c);
+            }
+
+            i++;
+        }
+        return result.toString();
+    }
+
 }