Hi John,

Hudson is unhappy after this commit
http://hudson.zones.apache.org/hudson/view/Shindig/job/Shindig/520/

Cheers,

Vincent

2009/3/26  <[email protected]>:
> Author: johnh
> Date: Thu Mar 26 22:15:43 2009
> New Revision: 758884
>
> URL: http://svn.apache.org/viewvc?rev=758884&view=rev
> Log:
> Implements Uri.resolve(...) natively instead of in terms of java.net.URI.
>
> In addition to being a performance improvement (40%+), this allows 
> UriParser-parsed Uris that don't conform to java.net.URI's restrictions
> (eg. chars like | or ^) to resolve appropriately.
>
>
> Modified:
>    
> incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/Uri.java
>    
> incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriTest.java
>
> Modified: 
> incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/Uri.java
> URL: 
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/Uri.java?rev=758884&r1=758883&r2=758884&view=diff
> ==============================================================================
> --- 
> incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/Uri.java
>  (original)
> +++ 
> incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/Uri.java
>  Thu Mar 26 22:15:43 2009
> @@ -18,6 +18,7 @@
>  */
>  package org.apache.shindig.common.uri;
>
> +import com.google.common.base.Join;
>  import com.google.common.base.Objects;
>  import com.google.common.collect.Maps;
>  import com.google.inject.Inject;
> @@ -26,8 +27,10 @@
>  import java.net.URISyntaxException;
>  import java.util.Collection;
>  import java.util.Collections;
> +import java.util.LinkedList;
>  import java.util.List;
>  import java.util.Map;
> +import java.util.StringTokenizer;
>
>  /**
>  * Represents a Uniform Resource Identifier (URI) reference as defined by <a
> @@ -124,11 +127,99 @@
>    * @return The new url.
>    */
>   public Uri resolve(Uri other) {
> -    // TODO: We can probably make this more efficient by implementing 
> resolve ourselves.
>     if (other == null) {
>       return null;
>     }
> -    return fromJavaUri(toJavaUri().resolve(other.toJavaUri()));
> +
> +    String scheme = other.getScheme();
> +    String authority = other.getAuthority();
> +    String path = other.getPath();
> +    String query = other.getQuery();
> +    String fragment = other.getFragment();
> +
> +    if (scheme != null && scheme.length() > 0) {
> +      // Do nothing - this will accept other's fields verbatim.
> +    } else if (authority != null) {
> +      // Schema-relative ie. "//newhost.com/foo?q=s". Take base scheme.
> +      scheme = getScheme();
> +    } else if (path != null && path.length() > 0) {
> +      // Resolve other path against current. Keep prerequisites.
> +      scheme = getScheme();
> +      authority = getAuthority();
> +      path = resolvePath(path);
> +    } else if (query != null && query.length() > 0) {
> +      // Accept query + fragment verbatim. Use base scheme/authority/path.
> +      scheme = getScheme();
> +      authority = getAuthority();
> +      // Treat query-relative as ""-path with query.
> +      path = resolvePath("");
> +    } else if (fragment != null && fragment.length() > 0) {
> +      // Accept fragment verbatim. Use base scheme/authority/path/query.
> +      scheme = getScheme();
> +      authority = getAuthority();
> +      path = getPath();
> +      query = getQuery();
> +    }
> +
> +    return new UriBuilder()
> +        .setScheme(scheme)
> +        .setAuthority(authority)
> +        .setPath(path)
> +        .setQuery(query)
> +        .setFragment(fragment)
> +        .toUri();
> +  }
> +
> +  /**
> +   * Resolves {...@code otherPath} against the current path, returning the 
> result.
> +   * Implements RFC 2396 resolution rules.
> +   */
> +  private String resolvePath(String otherPath) {
> +    if (otherPath.startsWith("/")) {
> +      // Optimization: just accept other.
> +      return otherPath;
> +    }
> +    // Relative path. Treat current path as a stack, otherPath as a List
> +    // in order to merge.
> +    LinkedList<String> pathStack = new LinkedList<String>();
> +    String curPath = getPath() != null ? getPath() : "/";  // Just in case.
> +    StringTokenizer tok = new StringTokenizer(curPath, "/");
> +    while (tok.hasMoreTokens()) {
> +      pathStack.add(tok.nextToken());
> +    }
> +    if (!curPath.endsWith("/")) {
> +      // The first entry in mergePath overwrites the last in the pathStack.
> +      // eg. curPath = "/foo/bar", otherPath = "baz" --> "/foo/baz".
> +      pathStack.removeLast();
> +    }
> +
> +    LinkedList<String> mergePath = new LinkedList<String>();
> +    StringTokenizer tok2 = new StringTokenizer(otherPath, "/");
> +    while (tok2.hasMoreTokens()) {
> +      mergePath.add(tok2.nextToken());
> +    }
> +    if (otherPath.endsWith("/") || otherPath.equals("")) {
> +      // Retains the ending slash in the final join.
> +      mergePath.add("");
> +    }
> +
> +    // Merge mergePath into pathStack.
> +    for (String mergeComponent : mergePath) {
> +      if (mergeComponent.equals(".")) {
> +        // Retain current position in the path. Continue.
> +        continue;
> +      } else if (mergeComponent.equals("..")) {
> +        // Pop one off the path stack if available. If not do nothing.
> +        if (!pathStack.isEmpty()) {
> +          pathStack.removeLast();
> +        }
> +      } else {
> +        // Append latest to the path.
> +        pathStack.add(mergeComponent);
> +      }
> +    }
> +
> +    return "/" + Join.join("/", pathStack);
>   }
>
>   /**
>
> Modified: 
> incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriTest.java
> URL: 
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriTest.java?rev=758884&r1=758883&r2=758884&view=diff
> ==============================================================================
> --- 
> incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriTest.java
>  (original)
> +++ 
> incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriTest.java
>  Thu Mar 26 22:15:43 2009
> @@ -174,6 +174,22 @@
>   }
>
>   @Test
> +  public void resolvePathIncludesSubdirs() throws Exception {
> +    Uri base = Uri.parse("http://example.org/foo/bar/baz?blah=blah#boo";);
> +    Uri other = Uri.parse("fez/../huey/./dewey/../louis");
> +
> +    assertEquals("http://example.org/foo/bar/huey/louis";, 
> base.resolve(other).toString());
> +  }
> +
> + �...@test
> +  public void resolvePathSubdirsExtendsBeyondRoot() throws Exception {
> +    Uri base = Uri.parse("http://example.org/foo/bar/baz?blah=blah#boo";);
> +    Uri other = Uri.parse("../random/../../../../../home");
> +
> +    assertEquals("http://example.org/home";, base.resolve(other).toString());
> +  }
> +
> + �...@test
>   public void resolvePathRelative() throws Exception {
>     Uri base = Uri.parse("http://example.org/foo/bar/baz?blah=blah#boo";);
>     Uri other = Uri.parse("wee");
>
>
>

Reply via email to