Hello Justin,
thanks a lot for your effort, you point crucial issues.
You help fixing a bug with the computing of the relative part. The
StackOverflowError was thrown when the base reference was not defined.
However, as said in chapter "5.1. Establishing a Base URI", of the Uri
reference (http://www.ietf.org/rfc/rfc3986.txt), a relative part cannot
be used in a context where the base reference is not defined. The fix
consists of throwing an IllegalArgumentException.
The "getRemainingPart()" method needs 2 prerequities as written in the
javadocs: the reference must be absolute and the reference identifier
must start with the resource baseRef. The warning trace was intended to
give us some feed-back about some errors experienced with the Restlet
website (served by a Restlet application). We think this is the time to
remove this trace that may be confusing.
And the last but not the least. The Reference class was intended to wrap
an URI and to leave the user free to choose the way he builds
references, and to memorize as much as possible these primary choices.
That's why some behaviours are disturbing; The safer way to get the
final complete URI is to call the "getTargetRef" method, which needed
some correction, as you point very judiciously.
I send an attached file, the list of all actualized tests and their results.
Finally, I must say that I did not see wrong URIs. I have the feeling
that you think about such cases:
Reference fulldir = new Reference("http://host.com/dir");
Reference fulldirsub = new Reference(fulldir, "sub");
fulldirsub.getTargetRef() => http://host.com/sub
In my opinion, the result is correct, because it is conform to what you
can notice with the relative URLs in HTML pages.
Can you tell me more about this point?
Please feel free to give your feeling, ideas.
Best regards,
Thierry Boileau
Actually, Reference seems to have some odd behavior in general when constructed
with baseRef. Depending on the construction one may end up with null values, odd
values, wrong URIs, NullPointerExceptions, and infinite loops resulting in
StackOverflowErrors.
Here are my test cases:
Reference host = new Reference("http://host.com")
scheme: http
authority: host.com
path: null
baseRef: null
rel-part: java.lang.StackOverflowError
rem-part: http://host.com
toString: http://host.com
targetRef: http://host.com
Reference slashdir = new Reference(host, "/dir")
scheme: null
authority: null
path: /dir
baseRef: http://host.com
rel-part: /dir
Apr 10, 2007 4:45:55 PM org.restlet.data.Reference getRemainingPart
WARNING: Cannot get the remaining part. [baseRef,internalRef]=[http://host.com,
/dir]
java.lang.StringIndexOutOfBoundsException: String index out of range: -11
at java.lang.String.substring(String.java:1768)
at java.lang.String.substring(String.java:1735)
at org.restlet.data.Reference.getRemainingPart(Reference.java:781)
at xex.webdb.Main.display(Main.java:69)
at xex.webdb.Main.main(Main.java:44)
rem-part: null
toString: /dir
targetRef: http://host.com/dir
Reference dir = new Reference(host, "dir")
scheme: null
authority: null
path: dir
baseRef: http://host.com
rel-part: dir
Apr 10, 2007 4:45:55 PM org.restlet.data.Reference getRemainingPart
WARNING: Cannot get the remaining part. [baseRef,internalRef]=[http://host.com,
dir]
java.lang.StringIndexOutOfBoundsException: String index out of range: -12
at java.lang.String.substring(String.java:1768)
at java.lang.String.substring(String.java:1735)
at org.restlet.data.Reference.getRemainingPart(Reference.java:781)
at xex.webdb.Main.display(Main.java:69)
at xex.webdb.Main.main(Main.java:45)
rem-part: null
toString: dir
targetRef: http://host.com/dir
Reference dirslash = new Reference(host, "dir/")
scheme: null
authority: null
path: dir/
baseRef: http://host.com
rel-part: dir/
Apr 10, 2007 4:45:55 PM org.restlet.data.Reference getRemainingPart
WARNING: Cannot get the remaining part. [baseRef,internalRef]=[http://host.com,
dir/]
java.lang.StringIndexOutOfBoundsException: String index out of range: -11
at java.lang.String.substring(String.java:1768)
at java.lang.String.substring(String.java:1735)
at org.restlet.data.Reference.getRemainingPart(Reference.java:781)
at xex.webdb.Main.display(Main.java:69)
at xex.webdb.Main.main(Main.java:46)
rem-part: null
toString: dir/
targetRef: http://host.com/dir/
Reference fulldir = new Reference("http://host.com/dir")
scheme: http
authority: host.com
path: /dir
baseRef: null
rel-part: java.lang.StackOverflowError
rem-part: http://host.com/dir
toString: http://host.com/dir
targetRef: http://host.com/dir
Reference fulldirsub = new Reference(fulldir, "sub")
scheme: null
authority: null
path: sub
baseRef: http://host.com/dir
rel-part: sub
Apr 10, 2007 4:45:55 PM org.restlet.data.Reference getRemainingPart
WARNING: Cannot get the remaining part.
[baseRef,internalRef]=[http://host.com/dir, sub]
java.lang.StringIndexOutOfBoundsException: String index out of range: -16
at java.lang.String.substring(String.java:1768)
at java.lang.String.substring(String.java:1735)
at org.restlet.data.Reference.getRemainingPart(Reference.java:781)
at xex.webdb.Main.display(Main.java:69)
at xex.webdb.Main.main(Main.java:49)
rem-part: null
toString: sub
targetRef: http://host.com/sub
Reference fulldirslashsub = new Reference(fulldir, "/sub")
scheme: null
authority: null
path: /sub
baseRef: http://host.com/dir
rel-part: /sub
Apr 10, 2007 4:45:55 PM org.restlet.data.Reference getRemainingPart
WARNING: Cannot get the remaining part.
[baseRef,internalRef]=[http://host.com/dir, /sub]
java.lang.StringIndexOutOfBoundsException: String index out of range: -15
at java.lang.String.substring(String.java:1768)
at java.lang.String.substring(String.java:1735)
at org.restlet.data.Reference.getRemainingPart(Reference.java:781)
at xex.webdb.Main.display(Main.java:69)
at xex.webdb.Main.main(Main.java:50)
rem-part: null
toString: /sub
targetRef: http://host.com/sub
Reference slashdirsub = new Reference(slashdir, "sub")
scheme: null
authority: null
path: sub
baseRef: /dir
rel-part: sub
Apr 10, 2007 4:45:55 PM org.restlet.data.Reference getRemainingPart
WARNING: Cannot get the remaining part. [baseRef,internalRef]=[/dir, sub]
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1768)
at java.lang.String.substring(String.java:1735)
at org.restlet.data.Reference.getRemainingPart(Reference.java:781)
at xex.webdb.Main.display(Main.java:69)
at xex.webdb.Main.main(Main.java:52)
rem-part: null
toString: sub
targetRef: java.lang.NullPointerException
Reference slashdirslashsub = new Reference(slashdir, "/sub")
scheme: null
authority: null
path: /sub
baseRef: /dir
rel-part: /sub
rem-part:
toString: /sub
targetRef: java.lang.NullPointerException
Reference dirslashsub = new Reference(dirslash, "sub");
scheme: null
authority: null
path: sub
baseRef: dir/
rel-part: sub
Apr 10, 2007 4:45:55 PM org.restlet.data.Reference getRemainingPart
WARNING: Cannot get the remaining part. [baseRef,internalRef]=[dir/, sub]
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1768)
at java.lang.String.substring(String.java:1735)
at org.restlet.data.Reference.getRemainingPart(Reference.java:781)
at xex.webdb.Main.display(Main.java:69)
at xex.webdb.Main.main(Main.java:55)
rem-part: null
toString: sub
targetRef: java.lang.NullPointerException
Reference fullsub = new Reference("http://host.com/dir/sub")
scheme: http
authority: host.com
path: /dir/sub
baseRef: null
rel-part: java.lang.StackOverflowError
rem-part: http://host.com/dir/sub
toString: http://host.com/dir/sub
targetRef: http://host.com/dir/sub
**************** host = new Reference("http://host.com")
Scheme http
Authority host.com
Path null
RemainingPart http://host.com
toString http://host.com
TargetRef http://host.com
RelativePart IllegalArgumentException
**************** slashdir = new Reference(host, "/dir")
Scheme null
Authority null
Path /dir
RemainingPart null
toString /dir
TargetRef http://host.com/dir
RelativePart /dir
**************** dir = new Reference(host, "dir")
Scheme null
Authority null
Path dir
RemainingPart null
toString dir
TargetRef http://host.com/dir
RelativePart dir
**************** dirslash
Scheme null
Authority null
Path dir/
RemainingPart null
toString dir/
TargetRef http://host.com/dir/
RelativePart dir/
**************** fulldir = new Reference("http://host.com/dir"
Scheme http
Authority host.com
Path /dir
RemainingPart http://host.com/dir
toString http://host.com/dir
TargetRef http://host.com/dir
RelativePart IllegalArgumentException
**************** fulldirslashsub = new Reference(fulldir, "/sub")
Scheme null
Authority null
Path sub
RemainingPart null
toString sub
TargetRef http://host.com/sub
RelativePart sub
**************** slashdirslashsub = new Reference(slashdir, "/sub")
Scheme null
Authority null
Path /sub
RemainingPart null
toString /sub
TargetRef http://host.com/sub
RelativePart /sub
**************** slashdirsub = new Reference(slashdir, "sub")
Scheme null
Authority null
Path sub
RemainingPart null
toString sub
TargetRef http://host.com/sub
RelativePart sub
**************** slashdirslashsub = new Reference(slashdir, "/sub")
Scheme null
Authority null
Path /sub
RemainingPart
toString /sub
TargetRef http://host.com/sub
RelativePart /sub
**************** dirslashsub = new Reference(dirslash, "sub")
Scheme null
Authority null
Path sub
RemainingPart null
toString sub
TargetRef http://host.com/dir/sub
RelativePart sub
**************** fullsub = new Reference("http://host.com/dir/sub")
Scheme http
Authority host.com
Path /dir/sub
RemainingPart http://host.com/dir/sub
toString http://host.com/dir/sub
TargetRef http://host.com/dir/sub
RelativePart IllegalArgumentException