Our code addresses compatibility:
/** Fixes windows file URI string by converting back slashes to forward
* slashes and inserting a forward slash before the drive letter if
it is
* missing. No normalisation or modification of case is performed.
* @param uri String representation of URI
* @return fixed URI String
*/
public static String fixWindowsURI(String uri) {
if (uri == null) return null;
if (File.separatorChar != '\\') return uri;
if ( uri.startsWith("file:") || uri.startsWith("FILE:")){
char [] u = uri.toCharArray();
int l = u.length;
StringBuilder sb = new StringBuilder(uri.length()+1);
for (int i=0; i<l; i++){
// Ensure we use forward slashes
if (u[i] == File.separatorChar) {
sb.append('/');
continue;
}
if (i == 5 && uri.startsWith(":", 6 )) {
// Windows drive letter without leading slashes
doesn't comply
// with URI spec, fix it here
sb.append("/");
}
sb.append(u[i]);
}
return sb.toString();
}
return uri;
}
<SNIP>
public static Uri filePathToUri(String path) throws URISyntaxException{
String forwardSlash = "/";
if (path == null || path.length() == 0) {
// codebase is "file:"
path = "*";
}
// Ensure compatibility with URLClassLoader, when directory
// character is dropped by File.
boolean directory = false;
if (path.endsWith(forwardSlash)) directory = true;
path = new File(path).getAbsolutePath();
if (directory) {
if (!(path.endsWith(File.separator))){
path = path + File.separator;
}
}
if (File.separatorChar == '\\') {
path = path.replace(File.separatorChar, '/');
}
path = fixWindowsURI("file:" + path);
return Uri.escapeAndCreate(path); //$NON-NLS-1$
}
--
Regards,
Peter
On 10/11/2024 5:05 pm, Peter Firmstone wrote:
So we have an RFC3986 compliant URI implementation, that's not
compatible with Java's RFC2396 URI and now we use deprecated URL
public constructors...
But I guess they're only deprecated, not going to be removed, we can't
change our code to use RFC2396 URI without unintended
consequences... Having said that, I would discourage developers from
writing any new code that uses RFC2396 URI.
My understanding is Java's RFC2396 cannot be changed for backward
compatibility reasons, it's not strictly compliant with RFC2396 and
varies from the spec with a larger allowed character set (unescaped)...
Perhaps a new RFC3986 URI implementation could utilise a provider
mechanism, with some static methods that allow the developer to select
which RFC compliant URI version they want to use?
We haven't used Java's URI class for a long time, as there are
significant performance benefits to using RFC3986 et al, such as not
relying on DNS lookup for identity.
Javadoc from our RFC3986 Uri implementation (AL2.0):
/**
* This class represents an immutable instance of a URI as defined by
RFC 3986.
* <p>
* This class replaces java.net.URI functionality.
* <p>
* Unlike java.net.URI this class is not Serializable and hashCode and
* equality is governed by strict RFC3986 normalisation. In addition
"other"
* characters allowed in java.net.URI as specified by javadoc, not
specifically
* allowed by RFC3986 are illegal and must be escaped. This strict
adherence
* is essential to eliminate false negative or positive matches.
* <p>
* In addition to RFC3896 normalisation, on OS platforms with a \ file
separator
* the path is converted to UPPER CASE for comparison for file:
schema, during
* equals and hashCode calls.
* <p>
* IPv6 and IPvFuture host addresses must be enclosed in square
brackets as per
* RFC3986. A zone delimiter %, if present, must be represented in
escaped %25
* form as per RFC6874.
* <p>
* In addition to RFC3986 normalization, IPv6 host addresses will be
normalized
* to comply with RFC 5952 A Recommendation for IPv6 Address Text
Representation.
* This is to ensure consistent equality between identical IPv6
addresses.
*
* @since 3.0.0
*/
public final class Uri implements Comparable<Uri> {