This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 30080637d8 Fix JUNEAU-117
30080637d8 is described below

commit 30080637d84f01acf1fb8c492c20974cdf4a2133
Author: James Bognar <[email protected]>
AuthorDate: Tue Oct 14 11:51:25 2025 -0400

    Fix JUNEAU-117
---
 .../main/java/org/apache/juneau/UriResolver.java   | 130 +++++++-----
 juneau-docs/docs/release-notes/9.2.0.md            |   7 +
 .../juneau/serializer/UriResolution_Test.java      |  68 +++----
 .../utils/UriContextResolutionCombo_Test.java      | 220 +++++++++++++++------
 scripts/cleanup-whitespace.py                      |  25 ++-
 5 files changed, 301 insertions(+), 149 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/UriResolver.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/UriResolver.java
index c97832b56a..924c78023c 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/UriResolver.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/UriResolver.java
@@ -37,7 +37,7 @@ import org.apache.juneau.common.utils.*;
  * <p>
  * Three special protocols are used to represent context-root-relative, 
servlet-relative, and request-path-relative
  * URIs:
- *     <js>"context:/"</js>, <js>"servlet:/"</js>, and <js>"request:/"</js>.
+ *     <js>"context:"</js>, <js>"servlet:"</js>, and <js>"request:"</js>.
  *
  * <p>
  * The following list shows the protocols of URLs that can be resolved with 
this class:
@@ -45,12 +45,15 @@ import org.apache.juneau.common.utils.*;
  *     <li><js>"foo://foo"</js> - Absolute URI.
  *     <li><js>"/foo"</js> - Root-relative URI.
  *     <li><js>"/"</js> - Root URI.
- *     <li><js>"context:/foo"</js> - Context-root-relative URI.
+ *     <li><js>"context:/foo"</js> - Context-root-relative URI with path.
  *     <li><js>"context:/"</js> - Context-root URI.
- *     <li><js>"servlet:/foo"</js> - Servlet-path-relative URI.
+ *     <li><js>"context:?foo=bar"</js> - Context-root URI with query string.
+ *     <li><js>"servlet:/foo"</js> - Servlet-path-relative URI with path.
  *     <li><js>"servlet:/"</js> - Servlet-path URI.
- *     <li><js>"request:/foo"</js> - Request-path-relative URI.
+ *     <li><js>"servlet:?foo=bar"</js> - Servlet-path URI with query string.
+ *     <li><js>"request:/foo"</js> - Request-path-relative URI with path.
  *     <li><js>"request:/"</js> - Request-path URI.
+ *     <li><js>"request:?foo=bar"</js> - Request-path URI with query string.
  *     <li><js>"foo"</js> - Path-info-relative URI.
  *     <li><js>""</js> - Path-info URI.
  * </ul>
@@ -109,12 +112,15 @@ public class UriResolver {
         *              <li><js>"foo://foo"</js> - Absolute URI.
         *              <li><js>"/foo"</js> - Root-relative URI.
         *              <li><js>"/"</js> - Root URI.
-        *              <li><js>"context:/foo"</js> - Context-root-relative URI.
+        *              <li><js>"context:/foo"</js> - Context-root-relative URI 
with path.
         *              <li><js>"context:/"</js> - Context-root URI.
-        *              <li><js>"servlet:/foo"</js> - Servlet-path-relative URI.
+        *              <li><js>"context:?foo=bar"</js> - Context-root URI with 
query string.
+        *              <li><js>"servlet:/foo"</js> - Servlet-path-relative URI 
with path.
         *              <li><js>"servlet:/"</js> - Servlet-path URI.
-        *              <li><js>"request:/foo"</js> - Request-path-relative URI.
+        *              <li><js>"servlet:?foo=bar"</js> - Servlet-path URI with 
query string.
+        *              <li><js>"request:/foo"</js> - Request-path-relative URI 
with path.
         *              <li><js>"request:/"</js> - Request-path URI.
+        *              <li><js>"request:?foo=bar"</js> - Request-path URI with 
query string.
         *              <li><js>"foo"</js> - Path-info-relative URI.
         *              <li><js>""</js> - Path-info URI.
         *      </ul>
@@ -193,47 +199,77 @@ public class UriResolver {
                                        a2.append('/');
                        }
 
-                       // Context-relative path
-                       else if (uri != null && uri.startsWith("context:/")) {
-                               if (resolution == ABSOLUTE && authority != null)
-                                       a2.append(authority);
-                               if (contextRoot != null)
-                                       a2.append('/').append(contextRoot);
-                               if (uri.length() > 9)
-                                       a2.append('/').append(uri.substring(9));
-                               else if (contextRoot == null && (authority == 
null || resolution != ABSOLUTE))
-                                       a2.append('/');
-                       }
+               // Context-relative path
+               else if (uri != null && uri.startsWith("context:")) {
+                       if (resolution == ABSOLUTE && authority != null)
+                               a2.append(authority);
+                       boolean hasContext = contextRoot != null && ! 
contextRoot.isEmpty();
+                       if (hasContext)
+                               a2.append('/').append(contextRoot);
+                       if (uri.length() > 8) {
+                               String remainder = uri.substring(8);
+                               // Skip if remainder is just "/" and something 
was appended OR we're at authority level with nothing else
+                               if (remainder.equals("/") && (hasContext || 
(resolution == ABSOLUTE && authority != null))) {
+                                       // Do nothing
+                               } else if (! remainder.isEmpty() && 
remainder.charAt(0) != '/' && remainder.charAt(0) != '?' && remainder.charAt(0) 
!= '#') {
+                                       a2.append('/').append(remainder);
+                               } else {
+                                       a2.append(remainder);
+                               }
+                       } else if (! hasContext && (authority == null || 
resolution != ABSOLUTE))
+                               a2.append('/');
+               }
 
-                       // Resource-relative path
-                       else if (uri != null && uri.startsWith("servlet:/")) {
-                               if (resolution == ABSOLUTE && authority != null)
-                                       a2.append(authority);
-                               if (contextRoot != null)
-                                       a2.append('/').append(contextRoot);
-                               if (servletPath != null)
-                                       a2.append('/').append(servletPath);
-                               if (uri.length() > 9)
-                                       a2.append('/').append(uri.substring(9));
-                               else if (servletPath == null && contextRoot == 
null && (authority == null || resolution != ABSOLUTE))
-                                       a2.append('/');
-                       }
+               // Resource-relative path
+               else if (uri != null && uri.startsWith("servlet:")) {
+                       if (resolution == ABSOLUTE && authority != null)
+                               a2.append(authority);
+                       boolean hasContext = contextRoot != null && ! 
contextRoot.isEmpty();
+                       boolean hasServlet = servletPath != null && ! 
servletPath.isEmpty();
+                       if (hasContext)
+                               a2.append('/').append(contextRoot);
+                       if (hasServlet)
+                               a2.append('/').append(servletPath);
+                       if (uri.length() > 8) {
+                               String remainder = uri.substring(8);
+                               // Skip if remainder is just "/" and something 
was appended OR we're at authority level with nothing else
+                               if (remainder.equals("/") && (hasContext || 
hasServlet || (resolution == ABSOLUTE && authority != null))) {
+                                       // Do nothing
+                               } else if (! remainder.isEmpty() && 
remainder.charAt(0) != '/' && remainder.charAt(0) != '?' && remainder.charAt(0) 
!= '#') {
+                                       a2.append('/').append(remainder);
+                               } else {
+                                       a2.append(remainder);
+                               }
+                       } else if (! hasServlet && ! hasContext && (authority 
== null || resolution != ABSOLUTE))
+                               a2.append('/');
+               }
 
-                       // Request-relative path
-                       else if (uri != null && uri.startsWith("request:/")) {
-                               if (resolution == ABSOLUTE && authority != null)
-                                       a2.append(authority);
-                               if (contextRoot != null)
-                                       a2.append('/').append(contextRoot);
-                               if (servletPath != null)
-                                       a2.append('/').append(servletPath);
-                               if (pathInfo != null)
-                                       a2.append('/').append(pathInfo);
-                               if (uri.length() > 9)
-                                       a2.append('/').append(uri.substring(9));
-                               else if (servletPath == null && contextRoot == 
null && pathInfo == null && (authority == null || resolution != ABSOLUTE))
-                                       a2.append('/');
-                       }
+               // Request-relative path
+               else if (uri != null && uri.startsWith("request:")) {
+                       if (resolution == ABSOLUTE && authority != null)
+                               a2.append(authority);
+                       boolean hasContext = contextRoot != null && ! 
contextRoot.isEmpty();
+                       boolean hasServlet = servletPath != null && ! 
servletPath.isEmpty();
+                       boolean hasPath = pathInfo != null && ! 
pathInfo.isEmpty();
+                       if (hasContext)
+                               a2.append('/').append(contextRoot);
+                       if (hasServlet)
+                               a2.append('/').append(servletPath);
+                       if (hasPath)
+                               a2.append('/').append(pathInfo);
+                       if (uri.length() > 8) {
+                               String remainder = uri.substring(8);
+                               // Skip if remainder is just "/" and something 
was appended OR we're at authority level with nothing else
+                               if (remainder.equals("/") && (hasContext || 
hasServlet || hasPath || (resolution == ABSOLUTE && authority != null))) {
+                                       // Do nothing
+                               } else if (! remainder.isEmpty() && 
remainder.charAt(0) != '/' && remainder.charAt(0) != '?' && remainder.charAt(0) 
!= '#') {
+                                       a2.append('/').append(remainder);
+                               } else {
+                                       a2.append(remainder);
+                               }
+                       } else if (! hasServlet && ! hasContext && ! hasPath && 
(authority == null || resolution != ABSOLUTE))
+                               a2.append('/');
+               }
 
                        // Relative path
                        else {
@@ -274,7 +310,7 @@ public class UriResolver {
                char c = s.charAt(0);
                if (c != 's' && c != 'c' && c != 'r')
                        return false;
-               return s.startsWith("servlet:/") || s.startsWith("context:/") 
|| s.startsWith("request:/");
+               return s.startsWith("servlet:") || s.startsWith("context:") || 
s.startsWith("request:");
        }
 
        private static String normalize(String s) {
diff --git a/juneau-docs/docs/release-notes/9.2.0.md 
b/juneau-docs/docs/release-notes/9.2.0.md
index 5b514837d6..6099289d41 100644
--- a/juneau-docs/docs/release-notes/9.2.0.md
+++ b/juneau-docs/docs/release-notes/9.2.0.md
@@ -386,6 +386,13 @@ Major changes include:
   }
   ```
 
+- **@HtmlDocConfig(navlinks) Query String Support**: Fixed a limitation where 
`@HtmlDocConfig(navlinks)` required special protocols (`context:`, `servlet:`, 
`request:`) to include a slash before query strings or hash fragments. Now 
supports more natural syntax:
+  - `foo:request:?key=value` (previously required `foo:request:/?key=value`)
+  - `foo:request:#section` (previously required `foo:request:/#section`)
+  - `foo:context:?key=value` (previously required `foo:context:/?key=value`)
+  
+  The `UriResolver` class now correctly handles these special protocols with 
or without a trailing slash, making it easier to construct navigation links 
with query parameters or hash fragments.
+
 ### juneau-bct (NEW MODULE)
 
 #### Bean-Centric Testing Framework
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/serializer/UriResolution_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/serializer/UriResolution_Test.java
index d01393937c..407a4f3665 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/serializer/UriResolution_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/serializer/UriResolution_Test.java
@@ -42,8 +42,8 @@ class UriResolution_Test extends TestBase {
                final Input input;
                final Results results;
 
-               Tester(String label, Input input, Results results) {
-                       this.label = label;
+               Tester(int index, String label, Input input, Results results) {
+                       this.label = "[" + index + "] " + label;
                        this.input = input;
                        this.results = results;
                }
@@ -122,14 +122,14 @@ class UriResolution_Test extends TestBase {
                return new Results(json, xml, html, uon, urlEncoding, msgPack, 
rdfXml);
        }
 
-       private static Tester tester(String label, Input input, Results 
results) {
-               return new Tester(label, input, results);
+       private static Tester tester(int index, String label, Input input, 
Results results) {
+               return new Tester(index, label, input, results);
        }
 
        private static final Tester[] TESTERS = {
 
                // Happy cases - All URL parts known.
-               tester(
+               tester(1,
                        "Happy-1-ABSOLUTE",
                        input(
                                UriResolution.ABSOLUTE, UriRelativity.RESOURCE, 
"http://foo.com:123","/context","/resource","/path";
@@ -144,7 +144,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='http://foo.com:123/context/resource/f0/x0'>\n<jp:f3a 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f1g
 rdf:resource='http://foo.com:123/context/resource/f1g/x'/>\n<jp:f2m 
rdf:resource='http://foo.com:123/context'/>\n<jp:f2i 
rdf:resource='http://foo.com:123/context/resource'/>\n<jp:f5 
rdf:resource='http://foo.com:123/context/resource/f5/x'/>\n<jp:f1k 
rdf:resource='http://foo.com:123/context/f1j/x'/>\n<jp:f2f rdf:re [...]
                        )
                ),
-               tester(
+               tester(2,
                        "Happy-1-ROOT_RELATIVE",
                        input(
                                UriResolution.ROOT_RELATIVE, 
UriRelativity.RESOURCE, "http://foo.com:123","/context","/resource","/path";
@@ -159,7 +159,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/context/resource/f0/x0'>\n<jp:f2h>/context/resource/f2h</jp:f2h>\n<jp:f2f>/context/resource</jp:f2f>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1h>/context/resource/f1h</jp:f1h>\n<jp:f5>/context/resource/f5/x</jp:f5>\n<jp:f1e>/context/resource/f1e/x/y</jp:f1e>\n<jp:f3c>/context/resource/&lt;&gt;&amp;''</jp:f3c>\n<jp:f2k>/context/f2j/x</jp:f2k>\n<jp:f1j>/context</jp:f1j>\n<jp:f2m>/context</jp:f2m>\n<jp:f2i>/context/resource</jp:f2i>\n<jp:f1d>/context/res
 [...]
                        )
                ),
-               tester(
+               tester(3,
                        "Happy-1-NONE",
                        input(
                                UriResolution.NONE, UriRelativity.RESOURCE, 
"http://foo.com:123","/context","/resource","/path";
@@ -174,7 +174,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='f0/x0'>\n<jp:f2l>/context/f2k</jp:f2l>\n<jp:f1a 
rdf:resource='http://www.apache.org/f1a'/>\n<jp:f2g>/context/resource/f2g/x</jp:f2g>\n<jp:f2f></jp:f2f>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f3b>%3C%3E%26%27%22</jp:f3b>\n<jp:f2a
 
rdf:resource='http://www.apache.org/f2a'/>\n<jp:f2c>/f2c/x/y</jp:f2c>\n<jp:f5>f5/x</jp:f5>\n<jp:f2k>/context/f2j/x</jp:f2k>\n<jp:f1e>f1e/x/y</jp:f1e>\n<jp:f2i>/context/reso
 [...]
                        )
                ),
-               tester(
+               tester(4,
                        "Happy-2-ABSOLUTE",
                        input(
                                UriResolution.ABSOLUTE, UriRelativity.RESOURCE, 
"http://foo.com:123","/c1/c2","/r1/r2","/p1/p2";
@@ -189,7 +189,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='http://foo.com:123/c1/c2/r1/r2/f0/x0'>\n<jp:f2m 
rdf:resource='http://foo.com:123/c1/c2'/>\n<jp:f1n 
rdf:resource='http://foo.com:123/c1'/>\n<jp:f2e 
rdf:resource='http://foo.com:123/c1/c2/r1/r2/f2e/x/y'/>\n<jp:f3a 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f1j
 rdf:resource='http://foo.com:123/c1/c2/r1'/>\n<jp:f1c 
rdf:resource='http://foo.com:123/f1c/x/y'/>\n<jp:f1f 
rdf:resource='http://foo.com:123/c1/c2/r1/r2'/>\ [...]
                        )
                ),
-               tester(
+               tester(5,
                        "Happy-2-ROOT_RELATIVE",
                        input(
                                UriResolution.ROOT_RELATIVE, 
UriRelativity.RESOURCE, "http://foo.com:123","/c1/c2","/r1/r2","/p1/p2";
@@ -204,7 +204,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/c1/c2/r1/r2/f0/x0'>\n<jp:f2j>/c1/c2/r1</jp:f2j>\n<jp:f2l>/c1/c2/f2k</jp:f2l>\n<jp:f2m>/c1/c2</jp:f2m>\n<jp:f1i>/c1/c2/r1/r2</jp:f1i>\n<jp:f2h>/c1/c2/r1/r2/f2h</jp:f2h>\n<jp:f1a
 
rdf:resource='http://www.apache.org/f1a'/>\n<jp:f1e>/c1/c2/r1/r2/f1e/x/y</jp:f1e>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f2d>/c1/c2/r1/r2/f2d</jp:f2d>\n<jp:f2c>/f2c/x/y</jp:f2c>\n<jp:f1l>/c1/c2/f1k</jp:f1l>\n<jp:f3c>/c1/c2/r1/r2/&lt;&gt;&amp;''</jp:f3c>\n<jp:f1d>/c1/c2/r1/r2/f
 [...]
                        )
                ),
-               tester(
+               tester(6,
                        "Happy-2-NONE",
                        input(
                                UriResolution.NONE, UriRelativity.RESOURCE, 
"http://foo.com:123","/c1/c2","/r1/r2","/p1/p2";
@@ -219,7 +219,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='f0/x0'>\n<jp:f2n>/c1</jp:f2n>\n<jp:f1a 
rdf:resource='http://www.apache.org/f1a'/>\n<jp:f2l>/c1/c2/f2k</jp:f2l>\n<jp:f2f></jp:f2f>\n<jp:f1m>/c1/c2</jp:f1m>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f3b>%3C%3E%26%27%22</jp:f3b>\n<jp:f2a
 
rdf:resource='http://www.apache.org/f2a'/>\n<jp:f2h>/c1/c2/r1/r2/f2h</jp:f2h>\n<jp:f2c>/f2c/x/y</jp:f2c>\n<jp:f2i>/c1/c2/r1/r2</jp:f2i>\n<jp:f2g>/c1/c2/r1/r2/f2g/x</jp:f
 [...]
                        )
                ),
-               tester(
+               tester(7,
                        "NoAuthority-1-ABSOLUTE",
                        input(
                                UriResolution.ABSOLUTE, UriRelativity.RESOURCE, 
"","/context","/resource","/path"
@@ -234,7 +234,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/context/resource/f0/x0'>\n<jp:f2h>/context/resource/f2h</jp:f2h>\n<jp:f2f>/context/resource</jp:f2f>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1h>/context/resource/f1h</jp:f1h>\n<jp:f5>/context/resource/f5/x</jp:f5>\n<jp:f1e>/context/resource/f1e/x/y</jp:f1e>\n<jp:f3c>/context/resource/&lt;&gt;&amp;''</jp:f3c>\n<jp:f2k>/context/f2j/x</jp:f2k>\n<jp:f1j>/context</jp:f1j>\n<jp:f2m>/context</jp:f2m>\n<jp:f2i>/context/resource</jp:f2i>\n<jp:f1d>/context/res
 [...]
                        )
                ),
-               tester(
+               tester(8,
                        "NoAuthority-1-ROOT_RELATIVE",
                        input(
                                UriResolution.ROOT_RELATIVE, 
UriRelativity.RESOURCE, "","/context","/resource","/path"
@@ -249,7 +249,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/context/resource/f0/x0'>\n<jp:f2h>/context/resource/f2h</jp:f2h>\n<jp:f2f>/context/resource</jp:f2f>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1h>/context/resource/f1h</jp:f1h>\n<jp:f5>/context/resource/f5/x</jp:f5>\n<jp:f1e>/context/resource/f1e/x/y</jp:f1e>\n<jp:f3c>/context/resource/&lt;&gt;&amp;''</jp:f3c>\n<jp:f2k>/context/f2j/x</jp:f2k>\n<jp:f1j>/context</jp:f1j>\n<jp:f2m>/context</jp:f2m>\n<jp:f2i>/context/resource</jp:f2i>\n<jp:f1d>/context/res
 [...]
                        )
                ),
-               tester(
+               tester(9,
                        "NoAuthority-1-NONE",
                        input(
                                UriResolution.NONE, UriRelativity.RESOURCE, 
"","/context","/resource","/path"
@@ -264,7 +264,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='f0/x0'>\n<jp:f2l>/context/f2k</jp:f2l>\n<jp:f1a 
rdf:resource='http://www.apache.org/f1a'/>\n<jp:f2g>/context/resource/f2g/x</jp:f2g>\n<jp:f2f></jp:f2f>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f3b>%3C%3E%26%27%22</jp:f3b>\n<jp:f2a
 
rdf:resource='http://www.apache.org/f2a'/>\n<jp:f2c>/f2c/x/y</jp:f2c>\n<jp:f5>f5/x</jp:f5>\n<jp:f2k>/context/f2j/x</jp:f2k>\n<jp:f1e>f1e/x/y</jp:f1e>\n<jp:f2i>/context/reso
 [...]
                        )
                ),
-               tester(
+               tester(10,
                        "NoContext-1-ABSOLUTE",
                        input(
                                UriResolution.ABSOLUTE, UriRelativity.RESOURCE, 
"http://foo.com:123","","/resource","/path";
@@ -279,7 +279,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='http://foo.com:123/resource/f0/x0'>\n<jp:f2i 
rdf:resource='http://foo.com:123/resource'/>\n<jp:f2j 
rdf:resource='http://foo.com:123'/>\n<jp:f2h 
rdf:resource='http://foo.com:123/resource/f2h'/>\n<jp:f1g 
rdf:resource='http://foo.com:123/resource/f1g/x'/>\n<jp:f1n 
rdf:resource='http://foo.com:123/..'/>\n<jp:f2b 
rdf:resource='http://foo.com:123/f2b'/>\n<jp:f1f 
rdf:resource='http://foo.com:123/resource'/>\n<jp:f2d 
rdf:resource='http://foo.com:123/re [...]
                        )
                ),
-               tester(
+               tester(11,
                        "NoContext-1-ROOT_RELATIVE",
                        input(
                                UriResolution.ROOT_RELATIVE, 
UriRelativity.RESOURCE, "http://foo.com:123","","/resource","/path";
@@ -294,7 +294,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/resource/f0/x0'>\n<jp:f2b>/f2b</jp:f2b>\n<jp:f2e>/resource/f2e/x/y</jp:f2e>\n<jp:f2a
 
rdf:resource='http://www.apache.org/f2a'/>\n<jp:f2n>/..</jp:f2n>\n<jp:f2c>/f2c/x/y</jp:f2c>\n<jp:f3c>/resource/&lt;&gt;&amp;''</jp:f3c>\n<jp:f2h>/resource/f2h</jp:f2h>\n<jp:f1i>/resource</jp:f1i>\n<jp:f1n>/..</jp:f1n>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1e>/resource/f1e/x/y</jp:f1e>\n<jp:f5>/resource/f5/x</jp:f5>\n<jp:f2l>/f2k</jp:f2l>\n<jp:f2d>/resource/f2d</jp:
 [...]
                        )
                ),
-               tester(
+               tester(12,
                        "NoContext-1-NONE",
                        input(
                                UriResolution.NONE, UriRelativity.RESOURCE, 
"http://foo.com:123","","/resource","/path";
@@ -309,7 +309,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='f0/x0'>\n<jp:f1n>/..</jp:f1n>\n<jp:f1a 
rdf:resource='http://www.apache.org/f1a'/>\n<jp:f2h>/resource/f2h</jp:f2h>\n<jp:f2n>/..</jp:f2n>\n<jp:f1h>/resource/f1h</jp:f1h>\n<jp:f1i>/resource</jp:f1i>\n<jp:f1g>/resource/f1g/x</jp:f1g>\n<jp:f2f></jp:f2f>\n<jp:f2k>/f2j/x</jp:f2k>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f3b>%3C%3E%26%27%22</jp:f3b>\n<jp:f2a
 rdf:resource='http://www.apache.org/f2a'/>\n<jp:f2 [...]
                        )
                ),
-               tester(
+               tester(13,
                        "NoResource-1-ABSOLUTE",
                        input(
                                UriResolution.ABSOLUTE, UriRelativity.RESOURCE, 
"http://foo.com:123","/context","","/path";
@@ -324,7 +324,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='http://foo.com:123/context/f0/x0'>\n<jp:f1f 
rdf:resource='http://foo.com:123/context'/>\n<jp:f2c 
rdf:resource='http://foo.com:123/f2c/x/y'/>\n<jp:f3b 
rdf:resource='http://foo.com:123/context/%3C%3E%26%27%22'/>\n<jp:f2d 
rdf:resource='http://foo.com:123/context/f2d'/>\n<jp:f2l 
rdf:resource='http://foo.com:123/context/f2k'/>\n<jp:f1b 
rdf:resource='http://foo.com:123/f1b'/>\n<jp:f1c 
rdf:resource='http://foo.com:123/f1c/x/y'/>\n<jp:f1j rdf:resource= [...]
                        )
                ),
-               tester(
+               tester(14,
                        "NoResource-1-ROOT_RELATIVE",
                        input(
                                UriResolution.ROOT_RELATIVE, 
UriRelativity.RESOURCE, "http://foo.com:123","/context","","/path";
@@ -339,7 +339,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/context/f0/x0'>\n<jp:f2k>/context/f2j/x</jp:f2k>\n<jp:f1f>/context</jp:f1f>\n<jp:f2a
 
rdf:resource='http://www.apache.org/f2a'/>\n<jp:f1e>/context/f1e/x/y</jp:f1e>\n<jp:f2i>/context</jp:f2i>\n<jp:f1j>/</jp:f1j>\n<jp:f3b>/context/%3C%3E%26%27%22</jp:f3b>\n<jp:f2b>/f2b</jp:f2b>\n<jp:f1h>/context/f1h</jp:f1h>\n<jp:f1l>/context/f1k</jp:f1l>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1i>/context</jp:f1i>\n<jp:f2j>/</jp:f2j>\n<jp:f2l>/context/f2k</jp:f2l>\n<jp
 [...]
                        )
                ),
-               tester(
+               tester(15,
                        "NoResource-1-NONE",
                        input(
                                UriResolution.NONE, UriRelativity.RESOURCE, 
"http://foo.com:123","/context","","/path";
@@ -354,7 +354,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='f0/x0'>\n<jp:f2l>/context/f2k</jp:f2l>\n<jp:f1a 
rdf:resource='http://www.apache.org/f1a'/>\n<jp:f2i>/context</jp:f2i>\n<jp:f1i>/context</jp:f1i>\n<jp:f2f></jp:f2f>\n<jp:f1g>/context/f1g/x</jp:f1g>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f3b>%3C%3E%26%27%22</jp:f3b>\n<jp:f2a
 
rdf:resource='http://www.apache.org/f2a'/>\n<jp:f2c>/f2c/x/y</jp:f2c>\n<jp:f5>f5/x</jp:f5>\n<jp:f2k>/context/f2j/x</jp:f2k>\n<j
 [...]
                        )
                ),
-               tester(
+               tester(16,
                        "NoPath-1-ABSOLUTE",
                        input(
                                UriResolution.ABSOLUTE, UriRelativity.RESOURCE, 
"http://foo.com:123","/context","/resource","";
@@ -369,7 +369,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='http://foo.com:123/context/resource/f0/x0'>\n<jp:f3a 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f1g
 rdf:resource='http://foo.com:123/context/resource/f1g/x'/>\n<jp:f2m 
rdf:resource='http://foo.com:123/context'/>\n<jp:f2i 
rdf:resource='http://foo.com:123/context/resource'/>\n<jp:f5 
rdf:resource='http://foo.com:123/context/resource/f5/x'/>\n<jp:f1k 
rdf:resource='http://foo.com:123/context/f1j/x'/>\n<jp:f2f rdf:re [...]
                        )
                ),
-               tester(
+               tester(17,
                        "NoPath-1-ROOT_RELATIVE",
                        input(
                                UriResolution.ROOT_RELATIVE, 
UriRelativity.RESOURCE, "http://foo.com:123","/context","/resource","";
@@ -384,7 +384,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/context/resource/f0/x0'>\n<jp:f2h>/context/resource/f2h</jp:f2h>\n<jp:f2f>/context/resource</jp:f2f>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1h>/context/resource/f1h</jp:f1h>\n<jp:f5>/context/resource/f5/x</jp:f5>\n<jp:f1e>/context/resource/f1e/x/y</jp:f1e>\n<jp:f3c>/context/resource/&lt;&gt;&amp;''</jp:f3c>\n<jp:f2k>/context/f2j/x</jp:f2k>\n<jp:f1j>/context</jp:f1j>\n<jp:f2m>/context</jp:f2m>\n<jp:f2i>/context/resource</jp:f2i>\n<jp:f1d>/context/res
 [...]
                        )
                ),
-               tester(
+               tester(18,
                        "NoPath-1-NONE",
                        input(
                                UriResolution.NONE, UriRelativity.RESOURCE, 
"http://foo.com:123","/context","/resource","";
@@ -399,7 +399,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='f0/x0'>\n<jp:f2l>/context/f2k</jp:f2l>\n<jp:f1a 
rdf:resource='http://www.apache.org/f1a'/>\n<jp:f2g>/context/resource/f2g/x</jp:f2g>\n<jp:f2f></jp:f2f>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f3b>%3C%3E%26%27%22</jp:f3b>\n<jp:f2a
 
rdf:resource='http://www.apache.org/f2a'/>\n<jp:f2c>/f2c/x/y</jp:f2c>\n<jp:f5>f5/x</jp:f5>\n<jp:f2k>/context/f2j/x</jp:f2k>\n<jp:f1e>f1e/x/y</jp:f1e>\n<jp:f2i>/context/reso
 [...]
                        )
                ),
-               tester(
+               tester(19,
                        "NoAuthorityNoContext-1-ABSOLUTE",
                        input(
                                UriResolution.ABSOLUTE, UriRelativity.RESOURCE, 
"","","/resource","/path"
@@ -414,7 +414,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/resource/f0/x0'>\n<jp:f2b>/f2b</jp:f2b>\n<jp:f2e>/resource/f2e/x/y</jp:f2e>\n<jp:f2a
 
rdf:resource='http://www.apache.org/f2a'/>\n<jp:f2n>/..</jp:f2n>\n<jp:f2c>/f2c/x/y</jp:f2c>\n<jp:f3c>/resource/&lt;&gt;&amp;''</jp:f3c>\n<jp:f2h>/resource/f2h</jp:f2h>\n<jp:f1i>/resource</jp:f1i>\n<jp:f1n>/..</jp:f1n>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1e>/resource/f1e/x/y</jp:f1e>\n<jp:f5>/resource/f5/x</jp:f5>\n<jp:f2l>/f2k</jp:f2l>\n<jp:f2d>/resource/f2d</jp:
 [...]
                        )
                ),
-               tester(
+               tester(20,
                        "NoAuthorityNoContext-1-ROOT_RELATIVE",
                        input(
                                UriResolution.ROOT_RELATIVE, 
UriRelativity.RESOURCE, "","","/resource","/path"
@@ -429,7 +429,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/resource/f0/x0'>\n<jp:f2b>/f2b</jp:f2b>\n<jp:f2e>/resource/f2e/x/y</jp:f2e>\n<jp:f2a
 
rdf:resource='http://www.apache.org/f2a'/>\n<jp:f2n>/..</jp:f2n>\n<jp:f2c>/f2c/x/y</jp:f2c>\n<jp:f3c>/resource/&lt;&gt;&amp;''</jp:f3c>\n<jp:f2h>/resource/f2h</jp:f2h>\n<jp:f1i>/resource</jp:f1i>\n<jp:f1n>/..</jp:f1n>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1e>/resource/f1e/x/y</jp:f1e>\n<jp:f5>/resource/f5/x</jp:f5>\n<jp:f2l>/f2k</jp:f2l>\n<jp:f2d>/resource/f2d</jp:
 [...]
                        )
                ),
-               tester(
+               tester(21,
                        "NoAuthorityNoContext-1-NONE",
                        input(
                                UriResolution.NONE, UriRelativity.RESOURCE, 
"","","/resource","/path"
@@ -444,7 +444,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='f0/x0'>\n<jp:f1n>/..</jp:f1n>\n<jp:f1a 
rdf:resource='http://www.apache.org/f1a'/>\n<jp:f2h>/resource/f2h</jp:f2h>\n<jp:f2n>/..</jp:f2n>\n<jp:f1h>/resource/f1h</jp:f1h>\n<jp:f1i>/resource</jp:f1i>\n<jp:f1g>/resource/f1g/x</jp:f1g>\n<jp:f2f></jp:f2f>\n<jp:f2k>/f2j/x</jp:f2k>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f3b>%3C%3E%26%27%22</jp:f3b>\n<jp:f2a
 rdf:resource='http://www.apache.org/f2a'/>\n<jp:f2 [...]
                        )
                ),
-               tester(
+               tester(22,
                        "NoContextNoResource-1-ABSOLUTE",
                        input(
                                UriResolution.ABSOLUTE, UriRelativity.RESOURCE, 
"http://foo.com:123","","","/path";
@@ -459,7 +459,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='http://foo.com:123/f0/x0'>\n<jp:f2f 
rdf:resource='http://foo.com:123'/>\n<jp:f4 
rdf:resource='http://foo.com:123/test/uri/b'/>\n<jp:f1g 
rdf:resource='http://foo.com:123/f1g/x'/>\n<jp:f1l 
rdf:resource='http://foo.com:123/f1k'/>\n<jp:f1c 
rdf:resource='http://foo.com:123/f1c/x/y'/>\n<jp:f1j 
rdf:resource='http://foo.com:123/..'/>\n<jp:f1n 
rdf:resource='http://foo.com:123/..'/>\n<jp:f2c 
rdf:resource='http://foo.com:123/f2c/x/y'/>\n<jp:f2h rdf:resour [...]
                        )
                ),
-               tester(
+               tester(23,
                        "NoContextNoResource-1-ROOT_RELATIVE",
                        input(
                                UriResolution.ROOT_RELATIVE, 
UriRelativity.RESOURCE, "http://foo.com:123","","","/path";
@@ -474,7 +474,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/f0/x0'>\n<jp:f2n>/..</jp:f2n>\n<jp:f2h>/f2h</jp:f2h>\n<jp:f1j>/..</jp:f1j>\n<jp:f1n>/..</jp:f1n>\n<jp:f1i>/</jp:f1i>\n<jp:f5>/f5/x</jp:f5>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1m>/</jp:f1m>\n<jp:f1g>/f1g/x</jp:f1g>\n<jp:f1h>/f1h</jp:f1h>\n<jp:f2b>/f2b</jp:f2b>\n<jp:f2f>/</jp:f2f>\n<jp:f1l>/f1k</jp:f1l>\n<jp:f2i>/</jp:f2i>\n<jp:f1a
 rdf:resource='http://www.apache.org/f [...]
                        )
                ),
-               tester(
+               tester(24,
                        "NoContextNoResource-1-NONE",
                        input(
                                UriResolution.NONE, UriRelativity.RESOURCE, 
"http://foo.com:123","","","/path";
@@ -489,7 +489,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='f0/x0'>\n<jp:f2i>/</jp:f2i>\n<jp:f1n>/..</jp:f1n>\n<jp:f1a 
rdf:resource='http://www.apache.org/f1a'/>\n<jp:f1h>/f1h</jp:f1h>\n<jp:f2n>/..</jp:f2n>\n<jp:f2j>/..</jp:f2j>\n<jp:f2f></jp:f2f>\n<jp:f2k>/f2j/x</jp:f2k>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f3b>%3C%3E%26%27%22</jp:f3b>\n<jp:f2a
 
rdf:resource='http://www.apache.org/f2a'/>\n<jp:f1g>/f1g/x</jp:f1g>\n<jp:f2c>/f2c/x/y</jp:f2c>\n<jp:f1j>/..</jp
 [...]
                        )
                ),
-               tester(
+               tester(25,
                        "NoAuthorityNoContextNoResource-1-ABSOLUTE",
                        input(
                                UriResolution.ABSOLUTE, UriRelativity.RESOURCE, 
"","","","/path"
@@ -504,7 +504,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/f0/x0'>\n<jp:f2n>/..</jp:f2n>\n<jp:f2h>/f2h</jp:f2h>\n<jp:f1j>/..</jp:f1j>\n<jp:f1n>/..</jp:f1n>\n<jp:f1i>/</jp:f1i>\n<jp:f5>/f5/x</jp:f5>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1m>/</jp:f1m>\n<jp:f1g>/f1g/x</jp:f1g>\n<jp:f1h>/f1h</jp:f1h>\n<jp:f2b>/f2b</jp:f2b>\n<jp:f2f>/</jp:f2f>\n<jp:f1l>/f1k</jp:f1l>\n<jp:f2i>/</jp:f2i>\n<jp:f1a
 rdf:resource='http://www.apache.org/f [...]
                        )
                ),
-               tester(
+               tester(26,
                        "NoAuthorityNoContextNoResource-1-ROOT_RELATIVE",
                        input(
                                UriResolution.ROOT_RELATIVE, 
UriRelativity.RESOURCE, "","","","/path"
@@ -519,7 +519,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/f0/x0'>\n<jp:f2n>/..</jp:f2n>\n<jp:f2h>/f2h</jp:f2h>\n<jp:f1j>/..</jp:f1j>\n<jp:f1n>/..</jp:f1n>\n<jp:f1i>/</jp:f1i>\n<jp:f5>/f5/x</jp:f5>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1m>/</jp:f1m>\n<jp:f1g>/f1g/x</jp:f1g>\n<jp:f1h>/f1h</jp:f1h>\n<jp:f2b>/f2b</jp:f2b>\n<jp:f2f>/</jp:f2f>\n<jp:f1l>/f1k</jp:f1l>\n<jp:f2i>/</jp:f2i>\n<jp:f1a
 rdf:resource='http://www.apache.org/f [...]
                        )
                ),
-               tester(
+               tester(27,
                        "NoAuthorityNoContextNoResource-1-NONE",
                        input(
                                UriResolution.NONE, UriRelativity.RESOURCE, 
"","","","/path"
@@ -534,7 +534,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='f0/x0'>\n<jp:f2i>/</jp:f2i>\n<jp:f1n>/..</jp:f1n>\n<jp:f1a 
rdf:resource='http://www.apache.org/f1a'/>\n<jp:f1h>/f1h</jp:f1h>\n<jp:f2n>/..</jp:f2n>\n<jp:f2j>/..</jp:f2j>\n<jp:f2f></jp:f2f>\n<jp:f2k>/f2j/x</jp:f2k>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f3b>%3C%3E%26%27%22</jp:f3b>\n<jp:f2a
 
rdf:resource='http://www.apache.org/f2a'/>\n<jp:f1g>/f1g/x</jp:f1g>\n<jp:f2c>/f2c/x/y</jp:f2c>\n<jp:f1j>/..</jp
 [...]
                        )
                ),
-               tester(
+               tester(28,
                        "Nothing-1-ABSOLUTE",
                        input(
                                UriResolution.ABSOLUTE, UriRelativity.RESOURCE, 
"","","",""
@@ -549,7 +549,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/f0/x0'>\n<jp:f2n>/..</jp:f2n>\n<jp:f2h>/f2h</jp:f2h>\n<jp:f1j>/..</jp:f1j>\n<jp:f1n>/..</jp:f1n>\n<jp:f1i>/</jp:f1i>\n<jp:f5>/f5/x</jp:f5>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1m>/</jp:f1m>\n<jp:f1g>/f1g/x</jp:f1g>\n<jp:f1h>/f1h</jp:f1h>\n<jp:f2b>/f2b</jp:f2b>\n<jp:f2f>/</jp:f2f>\n<jp:f1l>/f1k</jp:f1l>\n<jp:f2i>/</jp:f2i>\n<jp:f1a
 rdf:resource='http://www.apache.org/f [...]
                        )
                ),
-               tester(
+               tester(29,
                        "Nothing-1-ROOT_RELATIVE",
                        input(
                                UriResolution.ROOT_RELATIVE, 
UriRelativity.RESOURCE, "","","",""
@@ -564,7 +564,7 @@ class UriResolution_Test extends TestBase {
                                "<rdf:RDF>\n<rdf:Description 
rdf:about='/f0/x0'>\n<jp:f2n>/..</jp:f2n>\n<jp:f2h>/f2h</jp:f2h>\n<jp:f1j>/..</jp:f1j>\n<jp:f1n>/..</jp:f1n>\n<jp:f1i>/</jp:f1i>\n<jp:f5>/f5/x</jp:f5>\n<jp:f3a
 
rdf:resource='http://www.apache.org/f3a/x?label=MY_LABEL&amp;foo=bar'/>\n<jp:f1c>/f1c/x/y</jp:f1c>\n<jp:f1m>/</jp:f1m>\n<jp:f1g>/f1g/x</jp:f1g>\n<jp:f1h>/f1h</jp:f1h>\n<jp:f2b>/f2b</jp:f2b>\n<jp:f2f>/</jp:f2f>\n<jp:f1l>/f1k</jp:f1l>\n<jp:f2i>/</jp:f2i>\n<jp:f1a
 rdf:resource='http://www.apache.org/f [...]
                        )
                ),
-               tester(
+               tester(30,
                        "Nothing-1-NONE",
                        input(
                                UriResolution.NONE, UriRelativity.RESOURCE, 
"","","",""
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/utils/UriContextResolutionCombo_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/utils/UriContextResolutionCombo_Test.java
index 3448e3411d..27da55ce00 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/utils/UriContextResolutionCombo_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/utils/UriContextResolutionCombo_Test.java
@@ -33,7 +33,7 @@ class UriContextResolutionCombo_Test extends TestBase {
        private static final Tester[] TESTERS = {
 
                // Happy cases - All URL parts known.
-               tester( /* 0 */
+               tester(1,
                        "Happy-1a",
                        input(
                                
"http://host:port","/context","/resource","/path";,
@@ -48,7 +48,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123/foobar";
                        )
                ),
-               tester( /* 1 */
+               tester(2,
                        "Happy-2",
                        input(
                                
"http://host:port","/context","/resource","/path";,
@@ -63,7 +63,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123";
                        )
                ),
-               tester( /* 2 */
+               tester(3,
                        "Happy-3",
                        input(
                                
"http://host:port","/context","/resource","/path";,
@@ -78,7 +78,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/foobar"
                        )
                ),
-               tester( /* 3 */
+               tester(4,
                        "Happy-4",
                        input(
                                
"http://host:port","/context","/resource","/path";,
@@ -93,7 +93,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/"
                        )
                ),
-               tester( /* 4 */
+               tester(5,
                        "Happy-5",
                        input(
                                
"http://host:port","/context","/resource","/path";,
@@ -108,7 +108,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "foobar"
                        )
                ),
-               tester( /* 5 */
+               tester(6,
                        "Happy-6",
                        input(
                                
"http://host:port","/context","/resource","/path";,
@@ -123,7 +123,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                ""
                        )
                ),
-               tester( /* 6 */
+               tester(7,
                        "Happy-7",
                        input(
                                
"http://host:port","/context","/resource","/path";,
@@ -138,7 +138,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/context/foo"
                        )
                ),
-               tester( /* 7 */
+               tester(8,
                        "Happy-8",
                        input(
                                
"http://host:port","/context","/resource","/path";,
@@ -153,7 +153,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/context"
                        )
                ),
-               tester( /* 8 */
+               tester(9,
                        "Happy-9",
                        input(
                                
"http://host:port","/context","/resource","/path";,
@@ -168,7 +168,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/context/resource/foo"
                        )
                ),
-               tester( /* 9 */
+               tester(10,
                        "Happy-10",
                        input(
                                
"http://host:port","/context","/resource","/path";,
@@ -185,7 +185,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                ),
 
                // Multiple context and resource parts
-               tester( /* 10 */
+               tester(11,
                        "MultiContextResource-1",
                        input(
                                "http://host:port","/c1/c2","/r1/r2","/p1/p2";,
@@ -200,7 +200,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123/foobar";
                        )
                ),
-               tester( /* 11 */
+               tester(12,
                        "MultiContextResource-2",
                        input(
                                "http://host:port","/c1/c2","/r1/r2","/p1/p2";,
@@ -215,7 +215,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123";
                        )
                ),
-               tester( /* 12 */
+               tester(13,
                        "MultiContextResource-3",
                        input(
                                "http://host:port","/c1/c2","/r1/r2","/p1/p2";,
@@ -230,7 +230,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/foobar"
                        )
                ),
-               tester( /* 13 */
+               tester(14,
                        "MultiContextResource-4",
                        input(
                                "http://host:port","/c1/c2","/r1/r2","/p1/p2";,
@@ -245,7 +245,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/"
                        )
                ),
-               tester( /* 14 */
+               tester(15,
                        "MultiContextResource-5",
                        input(
                                "http://host:port","/c1/c2","/r1/r2","/p1/p2";,
@@ -260,7 +260,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "foobar"
                        )
                ),
-               tester( /* 15 */
+               tester(16,
                        "MultiContextResource-6",
                        input(
                                "http://host:port","/c1/c2","/r1/r2","/p1/p2";,
@@ -275,7 +275,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                ""
                        )
                ),
-               tester( /* 16 */
+               tester(17,
                        "MultiContextResource-7",
                        input(
                                "http://host:port","/c1/c2","/r1/r2","/p1/p2";,
@@ -290,7 +290,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/c1/c2/foo"
                        )
                ),
-               tester( /* 17 */
+               tester(18,
                        "MultiContextResource-8",
                        input(
                                "http://host:port","/c1/c2","/r1/r2","/p1/p2";,
@@ -305,7 +305,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/c1/c2"
                        )
                ),
-               tester( /* 18 */
+               tester(19,
                        "MultiContextResource-9",
                        input(
                                "http://host:port","/c1/c2","/r1/r2","/p1/p2";,
@@ -320,7 +320,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/c1/c2/r1/r2/foo"
                        )
                ),
-               tester( /* 19 */
+               tester(20,
                        "MultiContextResource-10",
                        input(
                                "http://host:port","/c1/c2","/r1/r2","/p1/p2";,
@@ -337,7 +337,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                ),
 
                // No authority given
-               tester( /* 20 */
+               tester(21,
                        "NoAuthority-1",
                        input(
                                "","/context","/resource","/path",
@@ -352,7 +352,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123/foobar";
                        )
                ),
-               tester( /* 21 */
+               tester(22,
                        "NoAuthority-2",
                        input(
                                "","/context","/resource","/path",
@@ -367,7 +367,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123";
                        )
                ),
-               tester( /* 22 */
+               tester(23,
                        "NoAuthority-3",
                        input(
                                "","/context","/resource","/path",
@@ -382,7 +382,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/foobar"
                        )
                ),
-               tester( /* 23 */
+               tester(24,
                        "NoAuthority-4",
                        input(
                                "","/context","/resource","/path",
@@ -397,7 +397,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/"
                        )
                ),
-               tester( /* 24 */
+               tester(25,
                        "NoAuthority-5",
                        input(
                                "","/context","/resource","/path",
@@ -412,7 +412,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "foobar"
                        )
                ),
-               tester( /* 25 */
+               tester(26,
                        "NoAuthority-6",
                        input(
                                "","/context","/resource","/path",
@@ -427,7 +427,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                ""
                        )
                ),
-               tester( /* 26 */
+               tester(27,
                        "NoAuthority-7",
                        input(
                                "","/context","/resource","/path",
@@ -442,7 +442,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/context/foo"
                        )
                ),
-               tester( /* 27 */
+               tester(28,
                        "NoAuthority-8",
                        input(
                                "","/context","/resource","/path",
@@ -457,7 +457,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/context"
                        )
                ),
-               tester( /* 28 */
+               tester(29,
                        "NoAuthority-9",
                        input(
                                "","/context","/resource","/path",
@@ -472,7 +472,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/context/resource/foo"
                        )
                ),
-               tester( /* 29 */
+               tester(30,
                        "NoAuthority-10",
                        input(
                                "","/context","/resource","/path",
@@ -489,7 +489,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                ),
 
                // No authority or context given
-               tester( /* 30 */
+               tester(31,
                        "NoAuthorityOrContext-1",
                        input(
                                "","","/resource","/path",
@@ -504,7 +504,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123/foobar";
                        )
                ),
-               tester( /* 31 */
+               tester(32,
                        "NoAuthorityOrContext-2",
                        input(
                                "","","/resource","/path",
@@ -519,7 +519,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123";
                        )
                ),
-               tester( /* 32 */
+               tester(33,
                        "NoAuthorityOrContext-3",
                        input(
                                "","","/resource","/path",
@@ -534,7 +534,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/foobar"
                        )
                ),
-               tester( /* 33 */
+               tester(34,
                        "NoAuthorityOrContext-4",
                        input(
                                "","","/resource","/path",
@@ -549,7 +549,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/"
                        )
                ),
-               tester( /* 34 */
+               tester(35,
                        "NoAuthorityOrContext-5",
                        input(
                                "","","/resource","/path",
@@ -564,7 +564,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "foobar"
                        )
                ),
-               tester( /* 35 */
+               tester(36,
                        "NoAuthorityOrContext-6",
                        input(
                                "","","/resource","/path",
@@ -579,7 +579,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                ""
                        )
                ),
-               tester( /* 36 */
+               tester(37,
                        "NoAuthorityOrContext-7",
                        input(
                                "","","/resource","/path",
@@ -594,7 +594,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/foo"
                        )
                ),
-               tester( /* 37 */
+               tester(38,
                        "NoAuthorityOrContext-8",
                        input(
                                "","","/resource","/path",
@@ -609,7 +609,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/"
                        )
                ),
-               tester( /* 38 */
+               tester(39,
                        "NoAuthorityOrContext-9",
                        input(
                                "","","/resource","/path",
@@ -624,7 +624,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/resource/foo"
                        )
                ),
-               tester( /* 39 */
+               tester(40,
                        "NoAuthorityOrContext-10",
                        input(
                                "","","/resource","/path",
@@ -641,7 +641,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                ),
 
                // No authority or context or resource given
-               tester( /* 40 */
+               tester(41,
                        "NoAuthorityOrContextOrResource-1",
                        input(
                                "","","","/path",
@@ -656,7 +656,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123/foobar";
                        )
                ),
-               tester( /* 41 */
+               tester(42,
                        "NoAuthorityOrContextOrResource-2",
                        input(
                                "","","","/path",
@@ -671,7 +671,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123";
                        )
                ),
-               tester( /* 42 */
+               tester(43,
                        "NoAuthorityOrContextOrResource-3",
                        input(
                                "","","","/path",
@@ -686,7 +686,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/foobar"
                        )
                ),
-               tester( /* 43 */
+               tester(44,
                        "NoAuthorityOrContextOrResource-4",
                        input(
                                "","","","/path",
@@ -701,7 +701,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/"
                        )
                ),
-               tester( /* 44 */
+               tester(45,
                        "NoAuthorityOrContextOrResource-5",
                        input(
                                "","","","/path",
@@ -716,7 +716,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "foobar"
                        )
                ),
-               tester( /* 45 */
+               tester(46,
                        "NoAuthorityOrContextOrResource-6",
                        input(
                                "","","","/path",
@@ -731,7 +731,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                ""
                        )
                ),
-               tester( /* 46 */
+               tester(47,
                        "NoAuthorityOrContextOrResource-7",
                        input(
                                "","","","/path",
@@ -746,7 +746,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/foo"
                        )
                ),
-               tester( /* 47 */
+               tester(48,
                        "NoAuthorityOrContextOrResource-8",
                        input(
                                "","","","/path",
@@ -761,7 +761,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/"
                        )
                ),
-               tester( /* 48 */
+               tester(49,
                        "NoAuthorityOrContextOrResource-9",
                        input(
                                "","","","/path",
@@ -776,7 +776,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/foo"
                        )
                ),
-               tester( /* 49 */
+               tester(50,
                        "NoAuthorityOrContextOrResource-10",
                        input(
                                "","","","/path",
@@ -793,7 +793,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                ),
 
                // No context or resource given.
-               tester( /* 50 */
+               tester(51,
                        "NoContextOrResource-1",
                        input(
                                "http://host:port","","","/path";,
@@ -808,7 +808,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123/foobar";
                        )
                ),
-               tester( /* 51 */
+               tester(52,
                        "NoContextOrResource-2",
                        input(
                                "http://host:port","","","/path";,
@@ -823,7 +823,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "http://foo.com:123";
                        )
                ),
-               tester( /* 52 */
+               tester(53,
                        "NoContextOrResource-3",
                        input(
                                "http://host:port","","","/path";,
@@ -838,7 +838,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/foobar"
                        )
                ),
-               tester( /* 53 */
+               tester(54,
                        "NoContextOrResource-4",
                        input(
                                "http://host:port","","","/path";,
@@ -853,7 +853,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/"
                        )
                ),
-               tester( /* 54 */
+               tester(55,
                        "NoContextOrResource-5",
                        input(
                                "http://host:port","","","/path";,
@@ -868,7 +868,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "foobar"
                        )
                ),
-               tester( /* 55 */
+               tester(56,
                        "NoContextOrResource-6",
                        input(
                                "http://host:port","","","/path";,
@@ -883,7 +883,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                ""
                        )
                ),
-               tester( /* 56 */
+               tester(57,
                        "NoContextOrResource-7",
                        input(
                                "http://host:port","","","/path";,
@@ -898,7 +898,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/foo"
                        )
                ),
-               tester( /* 57 */
+               tester(58,
                        "NoContextOrResource-8",
                        input(
                                "http://host:port","","","/path";,
@@ -913,7 +913,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/"
                        )
                ),
-               tester( /* 58 */
+               tester(59,
                        "NoContextOrResource-9",
                        input(
                                "http://host:port","","","/path";,
@@ -928,7 +928,7 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/foo"
                        )
                ),
-               tester( /* 59 */
+               tester(60,
                        "NoContextOrResource-10",
                        input(
                                "http://host:port","","","/path";,
@@ -942,6 +942,98 @@ class UriContextResolutionCombo_Test extends TestBase {
                                "/",
                                "/"
                        )
+               ),
+
+               // Test query string support (JUNEAU-117)
+               tester(61,
+                       "request:?query",
+                       input(
+                               
"http://host:port","/context","/resource","/path";,
+                               "request:?foo=bar"
+                       ),
+                       results(
+                               
"http://host:port/context/resource/path?foo=bar";,
+                               
"http://host:port/context/resource/path?foo=bar";,
+                               "/context/resource/path?foo=bar",
+                               "/context/resource/path?foo=bar",
+                               "/context/resource/path?foo=bar",
+                               "/context/resource/path?foo=bar"
+                       )
+               ),
+               tester(62,
+                       "servlet:?query",
+                       input(
+                               
"http://host:port","/context","/resource","/path";,
+                               "servlet:?foo=bar"
+                       ),
+                       results(
+                               "http://host:port/context/resource?foo=bar";,
+                               "http://host:port/context/resource?foo=bar";,
+                               "/context/resource?foo=bar",
+                               "/context/resource?foo=bar",
+                               "/context/resource?foo=bar",
+                               "/context/resource?foo=bar"
+                       )
+               ),
+               tester(63,
+                       "context:?query",
+                       input(
+                               
"http://host:port","/context","/resource","/path";,
+                               "context:?foo=bar"
+                       ),
+                       results(
+                               "http://host:port/context?foo=bar";,
+                               "http://host:port/context?foo=bar";,
+                               "/context?foo=bar",
+                               "/context?foo=bar",
+                               "/context?foo=bar",
+                               "/context?foo=bar"
+                       )
+               ),
+               tester(64,
+                       "request:#hash",
+                       input(
+                               
"http://host:port","/context","/resource","/path";,
+                               "request:#section"
+                       ),
+                       results(
+                               
"http://host:port/context/resource/path#section";,
+                               
"http://host:port/context/resource/path#section";,
+                               "/context/resource/path#section",
+                               "/context/resource/path#section",
+                               "/context/resource/path#section",
+                               "/context/resource/path#section"
+                       )
+               ),
+               tester(65,
+                       "request:pathOnly",
+                       input(
+                               
"http://host:port","/context","/resource","/path";,
+                               "request:foo"
+                       ),
+                       results(
+                               "http://host:port/context/resource/path/foo";,
+                               "http://host:port/context/resource/path/foo";,
+                               "/context/resource/path/foo",
+                               "/context/resource/path/foo",
+                               "/context/resource/path/foo",
+                               "/context/resource/path/foo"
+                       )
+               ),
+               tester(66,
+                       "request:empty",
+                       input(
+                               
"http://host:port","/context","/resource","/path";,
+                               "request:"
+                       ),
+                       results(
+                               "http://host:port/context/resource/path";,
+                               "http://host:port/context/resource/path";,
+                               "/context/resource/path",
+                               "/context/resource/path",
+                               "/context/resource/path",
+                               "/context/resource/path"
+                       )
                )
        };
 
@@ -950,8 +1042,8 @@ class UriContextResolutionCombo_Test extends TestBase {
                final Input input;
                final Results results;
 
-               Tester(String label, Input input, Results results) {
-                       this.label = label;
+               Tester(int index, String label, Input input, Results results) {
+                       this.label = "[" + index + "] " + label;
                        this.input = input;
                        this.results = results;
                }
@@ -983,8 +1075,8 @@ class UriContextResolutionCombo_Test extends TestBase {
                }
        }
 
-       public static Tester tester(String label, Input input, Results results) 
{
-               return new Tester(label, input, results);
+       public static Tester tester(int index, String label, Input input, 
Results results) {
+               return new Tester(index, label, input, results);
        }
 
        public static Input input(String authority, String context, String 
resource, String path, String uri) {
diff --git a/scripts/cleanup-whitespace.py b/scripts/cleanup-whitespace.py
index fa0ddf0bae..9a7fa9945b 100755
--- a/scripts/cleanup-whitespace.py
+++ b/scripts/cleanup-whitespace.py
@@ -17,6 +17,7 @@
 
 """
 Cleans up whitespace inconsistencies in Java files:
+- Converts leading 4-spaces to tabs
 - Removes consecutive blank lines (max 1 blank line allowed)
 - Removes trailing whitespace from lines
 - Removes blank lines before the final closing brace
@@ -41,10 +42,26 @@ def clean_java_file(file_path):
         original_content = content
         lines = content.splitlines(keepends=True)
         
-        # Step 1: Remove trailing whitespace from each line
+        # Step 1: Convert leading 4-spaces to tabs
+        converted_lines = []
+        for line in lines:
+            if line.strip():  # Only process non-empty lines
+                # Count leading spaces
+                leading_spaces = len(line) - len(line.lstrip(' '))
+                if leading_spaces > 0:
+                    # Calculate number of tabs (groups of 4 spaces)
+                    num_tabs = leading_spaces // 4
+                    remaining_spaces = leading_spaces % 4
+                    # Reconstruct line with tabs
+                    rest_of_line = line[leading_spaces:]
+                    line = '\t' * num_tabs + ' ' * remaining_spaces + 
rest_of_line
+            converted_lines.append(line)
+        lines = converted_lines
+        
+        # Step 2: Remove trailing whitespace from each line
         lines = [line.rstrip() + ('\n' if line.endswith('\n') else '') for 
line in lines]
         
-        # Step 2: Remove consecutive blank lines (keep max 1)
+        # Step 3: Remove consecutive blank lines (keep max 1)
         cleaned_lines = []
         prev_blank = False
         for line in lines:
@@ -55,7 +72,7 @@ def clean_java_file(file_path):
             cleaned_lines.append(line)
             prev_blank = is_blank
         
-        # Step 3: Remove blank lines before final closing brace
+        # Step 4: Remove blank lines before final closing brace
         # Find the last non-empty line
         while cleaned_lines and cleaned_lines[-1].strip() == '':
             cleaned_lines.pop()
@@ -72,7 +89,7 @@ def clean_java_file(file_path):
                     cleaned_lines.pop(idx)
                     idx -= 1
         
-        # Step 4: Remove trailing newline after final }
+        # Step 5: Remove trailing newline after final }
         new_content = ''.join(cleaned_lines)
         # Remove any trailing newlines
         new_content = new_content.rstrip('\n')

Reply via email to