Suggested patches for resolver: Windows driver-letter paths and resolveSystem() and <uri>
"Earl Hood" <[email protected]>
| Newsgroups | gmane.text.xml.commons.devel |
|---|---|
| Message-ID | <[email protected]> |
While working with xml-commons-resolver, I discovered that the code does not handle pathnames that utilize window's driver letters. The code appears to lose the "absoluteness" of the path, causing resolution of other entities/files to fail that have it for a base. Also, and probably a little more controversal, is the resolution of system IDs. I noticed that resolverSystem() does not do a resolveURI() if no system mapping exists. This is a problem when using the <schemavalidate> task in Ant. I'm working with catalogs that contain numerous <uri> entries to remap http URLs to local file URLs. Unfortunately, Ant/Xerces fails to resolve to the local URLs because resolveSytem() is used (because the URLs appears in SYSTEM idenitifiers in the documents). The XML resolution spec is not clear if the resolver should also check <uri> entries or if the XML parser should do a URI lookup if a SYSTEM lookup fails (it appears Saxon may actually do this since it does not have the problem that Ant/Xerces does). To address the immediate problem, I checked resolveSystem() to call resolveURI() if it fails to find anything, and the change is in the Catalog.java.patch attached (but the patch also includes the Windows pathname fix also). Are any of these changes worth including in the resolver code base? --ewh
Catalog.java.patch
(application/octet-stream, 2.8 KB)
--- src/org/apache/xml/resolver/Catalog.java.org 2008-04-08 13:58:50.828125000 -0500
+++ src/org/apache/xml/resolver/Catalog.java 2008-04-09 09:39:49.125000000 -0500
@@ -807,6 +807,7 @@
protected synchronized void parseCatalogFile(String fileName)
throws MalformedURLException, IOException, CatalogException {
+ URL newBase = null;
CatalogEntry entry;
// The base-base is the cwd. If the catalog file is specified
@@ -821,19 +822,39 @@
catalogManager.debug.message(1, "Malformed URL on cwd", userdir);
catalogCwd = null;
}
+ catalogManager.debug.message(4, "catalog cwd", catalogCwd.toString());
// The initial base URI is the location of the catalog file
- try {
- base = new URL(catalogCwd, fixSlashes(fileName));
- } catch (MalformedURLException e) {
+
+ // We handle case if on windows and filename is denoted by
+ // a drive letter. If so, treat as absolute.
+ String fixedFileName = fixSlashes(fileName);
+ String osname = System.getProperty("os.name");
+ boolean windows = (osname.indexOf("Windows") >= 0);
+ catalogManager.debug.message(4, "fixed filename", fixedFileName);
+ if (windows && (fixedFileName.charAt(1) == ':')) {
try {
- base = new URL("file:" + fixSlashes(fileName));
- } catch (MalformedURLException e2) {
- catalogManager.debug.message(1, "Malformed URL on catalog filename",
- fixSlashes(fileName));
- base = null;
+ newBase = new URL("file:/" + fixedFileName);
+ } catch (MalformedURLException mue) {
+ catalogManager.debug.message(4, "Windows path failed", fixedFileName);
}
}
+ if (newBase == null) {
+ try {
+ newBase = new URL(catalogCwd, fixedFileName);
+ } catch (MalformedURLException e) {
+ catalogManager.debug.message(4, "context URL failed", fixedFileName);
+ try {
+ newBase = new URL("file:" + fixedFileName);
+ } catch (MalformedURLException e2) {
+ catalogManager.debug.message(1, "Malformed URL on catalog filename",
+ fixedFileName);
+ // No reason to continue since base needs to be non-null
+ return;
+ }
+ }
+ }
+ base = newBase;
catalogManager.debug.message(2, "Loading catalog", fileName);
catalogManager.debug.message(4, "Default BASE", base.toString());
@@ -1692,10 +1713,16 @@
}
// Otherwise, look in the subordinate catalogs
- return resolveSubordinateCatalogs(SYSTEM,
+ String resolved = resolveSubordinateCatalogs(SYSTEM,
null,
null,
systemId);
+ if (resolved != null) {
+ return resolved;
+ }
+
+ // There could be a URI entry that maps systemId to another URI.
+ return resolveURI(systemId);
}
/**
FileURL.java.patch
(application/octet-stream, 696 B)
--- src/org/apache/xml/resolver/helpers/FileURL.java.org 2008-04-08 13:33:46.687500000 -0500
+++ src/org/apache/xml/resolver/helpers/FileURL.java 2008-04-09 09:29:26.218750000 -0500
@@ -73,6 +73,14 @@
return new URL("file://" + pathname);
}
+ // For Windows, see if pathname starts with a drive letter. If so,
+ // treat it as an absolute pathname.
+ String osname = System.getProperty("os.name");
+ boolean windows = (osname.indexOf("Windows") >= 0);
+ if (windows && (pathname.charAt(1) == ':')) {
+ return new URL("file:/" + pathname);
+ }
+
String userdir = System.getProperty("user.dir");
userdir = userdir.replace('\\', '/');