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> {

Reply via email to