diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
index d02d208e9..e20b4a5d3 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
@@ -65,7 +65,7 @@ import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
-import org.apache.tools.ant.types.DTDLocation;
+import org.apache.tools.ant.types.ResourceLocation;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
@@ -248,8 +248,8 @@ public class XMLValidateTask extends Task {
* This stores the location of a DTD. The DTD is identified
* by its public Id.
*/
- public DTDLocation createDTD() {
- DTDLocation dtdLocation = new DTDLocation();
+ public ResourceLocation createDTD() {
+ ResourceLocation dtdLocation = new ResourceLocation();
xmlCatalog.addDTD(dtdLocation);
return dtdLocation;
}
diff --git a/src/main/org/apache/tools/ant/types/DTDLocation.java b/src/main/org/apache/tools/ant/types/DTDLocation.java
index 977fa3c51..a81a1f1c6 100644
--- a/src/main/org/apache/tools/ant/types/DTDLocation.java
+++ b/src/main/org/apache/tools/ant/types/DTDLocation.java
@@ -70,9 +70,4 @@ package org.apache.tools.ant.types;
* @version $Id$
*/
public class DTDLocation extends ResourceLocation {
-
- public DTDLocation() {
- super("PUBLIC");
- }
-
}
diff --git a/src/main/org/apache/tools/ant/types/EntityLocation.java b/src/main/org/apache/tools/ant/types/EntityLocation.java
index c5351f989..80ec037a3 100644
--- a/src/main/org/apache/tools/ant/types/EntityLocation.java
+++ b/src/main/org/apache/tools/ant/types/EntityLocation.java
@@ -69,9 +69,4 @@ package org.apache.tools.ant.types;
* @author Craeg Strong
*/
public class EntityLocation extends ResourceLocation {
-
- public EntityLocation() {
- super("URI");
- }
-
}
diff --git a/src/main/org/apache/tools/ant/types/ResourceLocation.java b/src/main/org/apache/tools/ant/types/ResourceLocation.java
index c23eeaf39..c52cba8f0 100644
--- a/src/main/org/apache/tools/ant/types/ResourceLocation.java
+++ b/src/main/org/apache/tools/ant/types/ResourceLocation.java
@@ -76,6 +76,9 @@ import java.net.URL;
* @author Craeg Strong
* @version $Id$
*/
+
+import java.net.URL;
+
public class ResourceLocation {
//-- Fields ----------------------------------------------------------------
@@ -98,14 +101,10 @@ public class ResourceLocation {
* for an external catalog file is the directory in which it is
* located.
*/
- private String base = null;
+ private URL base = null;
//-- Methods ---------------------------------------------------------------
- protected ResourceLocation(String name) {
- this.name = name;
- }
-
/**
* @param publicId uniquely identifies the resource.
*/
@@ -127,7 +126,7 @@ public class ResourceLocation {
* it is resolved using the base. The default base for an
* external catalog file is the directory in which it is located.
*/
- public void setBase(String base) {
+ public void setBase(URL base) {
this.base = base;
}
@@ -148,18 +147,8 @@ public class ResourceLocation {
/**
* @return the base of the resource identified by the publicId.
*/
- public String getBase() {
+ public URL getBase() {
return base;
}
- /**
- * @return the name of the catalog entry type. Currently this is
- * one of PUBLIC
or URI
.
- *
- * @see org.apache.xml.resolver.Catalog
- */
- public String getName() {
- return name;
- }
-
} //-- ResourceLocation
diff --git a/src/main/org/apache/tools/ant/types/XMLCatalog.java b/src/main/org/apache/tools/ant/types/XMLCatalog.java
index 223dd1d9c..b403a80d0 100644
--- a/src/main/org/apache/tools/ant/types/XMLCatalog.java
+++ b/src/main/org/apache/tools/ant/types/XMLCatalog.java
@@ -76,7 +76,7 @@ import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
-import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JAXPUtils;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@@ -95,6 +95,19 @@ import org.xml.sax.XMLReader;
* in the Java API for XML
* Processing Specification.
Resource locations can be specified either in-line or in
+ * external catalog file(s), or both. In order to use an external
+ * catalog file, the xml-commons resolver library ("resolver.jar")
+ * must be in your classpath. External catalog files may be either
+ * plain text format or
+ * XML format. If the xml-commons resolver library is not found
+ * in the classpath, external catalog files, specified in
+ * <catalogfiles>
filesets, will be ignored and a
+ * warning will be logged. In this case, however, processing of
+ * inline entries will proceed normally.
Currently, only <dtd>
and
* <entity>
elements may be specified inline; these
* correspond to OASIS catalog entry types PUBLIC
and
@@ -108,6 +121,8 @@ import org.xml.sax.XMLReader;
* <dtd publicId="" location="/path/to/file2.jar" />
* <entity publicId="" location="/path/to/file3.jar" />
* <entity publicId="" location="/path/to/file4.jar" />
+ * <catalogfiles dir="${basedir}" includes="**\catalog" />
+ * <catalogfiles dir="/opt/catalogs/" includes="**\catalog.xml" />
* </xmlcatalog>
*
*
@@ -123,6 +138,7 @@ import org.xml.sax.XMLReader; *
Possible future extension could provide for additional OASIS - * entry types to be specified inline, and external catalog files - * using the xml-commons resolver library
+ * entry types to be specified inline. * * @author dIon Gillard * @author Erik Hatcher @@ -143,8 +158,6 @@ import org.xml.sax.XMLReader; */ public class XMLCatalog extends DataType implements Cloneable, EntityResolver, URIResolver { - /** File utilities instance */ - private FileUtils fileUtils = FileUtils.newFileUtils(); //-- Fields ---------------------------------------------------------------- @@ -171,10 +184,10 @@ public class XMLCatalog extends DataType } /** - * Returns the elements of the catalog - ResolverLocation and FileSet + * Returns the elements of the catalog - ResourceLocation and FileSet * objects. * - * @return the elements of the catalog - ResolverLocation and FileSet + * @return the elements of the catalog - ResourceLocation and FileSet * objects */ private Vector getElements() { @@ -255,10 +268,11 @@ public class XMLCatalog extends DataType setChecked( false ); } - /** Creates the nested<catalogfiles>
element. Not
- * allowed if this catalog is itself a reference to another catalog -- that
- * is, a catalog cannot both refer to another and contain elements
- * or other attributes.
+ /**
+ * Creates the nested <catalogfiles>
element.
+ * Not allowed if this catalog is itself a reference to another
+ * catalog -- that is, a catalog cannot both refer to another
+ * and contain elements or other attributes.
*
* @param fs the fileset of external catalogs.
* @exception BuildException
@@ -290,9 +304,6 @@ public class XMLCatalog extends DataType
getElements().addElement(dtd);
setChecked( false );
}
- public void addDTD(DTDLocation dtd) throws BuildException {
- addDTD((ResourceLocation)dtd);
- }
/**
* Creates the nested <entity>
element. Not
@@ -300,34 +311,13 @@ public class XMLCatalog extends DataType
* catalog -- that is, a catalog cannot both refer to another
* and contain elements or other attributes.
*
- * @param entity the information about the URI resource mapping to
- * be added to the catalog.
+ * @param entity the information about the URI resource mapping to be
+ * added to the catalog.
* @exception BuildException if this is a reference and no nested
* elements are allowed.
*/
- public void addEntity(EntityLocation entity) throws BuildException {
- if (isReference()) {
- throw noChildrenAllowed();
- }
- getElements().addElement(entity);
- }
-
- /**
- * Creates the nested <entity>
element. Not
- * allowed if this catalog is itself a reference to another
- * catalog -- that is, a catalog cannot both refer to another
- * and contain elements or other attributes.
- *
- * @param entity the information about the URI resource mapping to
- * be added to the catalog.
- * @exception BuildException if this is a reference and no nested
- * elements are allowed.
- */
- public void addEntity(DTDLocation entity) throws BuildException {
- if (isReference()) {
- throw noChildrenAllowed();
- }
- getElements().addElement(entity);
+ public void addEntity(ResourceLocation entity) throws BuildException {
+ addDTD(entity);
}
/**
@@ -432,12 +422,12 @@ public class XMLCatalog extends DataType
}
SAXSource source = null;
-
+
String uri = removeFragment(href);
log("resolve: '" + uri + "' with base: '" + base + "'", Project.MSG_DEBUG);
- source = resolveImpl(uri, base);
+ source = (SAXSource)getCatalogResolver().resolve(uri, base);
if (source == null) {
log("No matching catalog entry found, parser will use: '" +
@@ -447,12 +437,17 @@ public class XMLCatalog extends DataType
// setEntityResolver (see setEntityResolver javadoc comment)
//
source = new SAXSource();
- try
- {
- URL baseURL = new URL(base);
- URL url = (uri.length() == 0 ? baseURL : new URL(baseURL, uri));
- source.setInputSource(new InputSource(url.toString()));
+ URL baseURL = null;
+ try {
+ if (base == null) {
+ baseURL = getProject().getBaseDir().toURL();
+ }
+ else {
+ baseURL = new URL(base);
}
+ URL url = (uri.length() == 0 ? baseURL : new URL(baseURL, uri));
+ source.setInputSource(new InputSource(url.toString()));
+ }
catch (MalformedURLException ex) {
// At this point we are probably in failure mode, but
// try to use the bare URI as a last gasp
@@ -467,7 +462,7 @@ public class XMLCatalog extends DataType
/**
* The instance of the CatalogResolver strategy to use.
*/
- private static CatalogResolver catalogResolver = null;
+ private CatalogResolver catalogResolver = null;
/**
* Factory method for creating the appropriate CatalogResolver
@@ -478,11 +473,6 @@ public class XMLCatalog extends DataType
* appropriate implementation of CatalogResolver based on the answer.
* This is an application of the Gang of Four Strategy Pattern * combined with Template Method.
- * - * @param publicId the publicId of the Resource for which local information - * is required - * @return a ResourceLocation instance with information on the local location - * of the Resource or null if no such information is available */ private CatalogResolver getCatalogResolver() { @@ -490,7 +480,7 @@ public class XMLCatalog extends DataType AntClassLoader loader = null; - loader = new AntClassLoader(project, Path.systemClasspath); + loader = new AntClassLoader(getProject(), Path.systemClasspath); try { Class clazz = loader.forceLoadSystemClass(APACHE_RESOLVER); @@ -525,7 +515,6 @@ public class XMLCatalog extends DataType return catalogResolver; } - /** *This is called from the URIResolver to set an EntityResolver
* on the SAX parser to be used for new XML documents that are
@@ -568,8 +557,8 @@ public class XMLCatalog extends DataType
/**
* Find a ResourceLocation instance for the given publicId.
*
- * @param publicId the publicId of the Resource for which local information is
- * required.
+ * @param publicId the publicId of the Resource for which local information
+ * is required.
* @return a ResourceLocation instance with information on the local location
* of the Resource or null if no such information is available.
*/
@@ -616,32 +605,54 @@ public class XMLCatalog extends DataType
private InputSource filesystemLookup(ResourceLocation matchingEntry) {
String uri = matchingEntry.getLocation();
+ URL baseURL = null;
//
// The ResourceLocation may specify a relative path for its
// location attribute. This is resolved using the appropriate
// base.
//
- File resFile = getProject().resolveFile(uri);
- InputSource source = null;
-
- if (resFile.exists() && resFile.canRead()) {
+ if (matchingEntry.getBase() != null) {
+ baseURL = matchingEntry.getBase();
+ } else {
try {
- source = new InputSource(new FileInputStream(resFile));
- URL resFileURL = fileUtils.getFileURL(resFile);
- String sysid = resFileURL.toExternalForm();
- source.setSystemId(sysid);
- log("catalog entry matched a readable file: '" +
- sysid + "'", Project.MSG_DEBUG);
- } catch(FileNotFoundException ex) {
- // ignore
- } catch(MalformedURLException ex) {
- // ignore
- } catch(IOException ex) {
- // ignore
+ baseURL = getProject().getBaseDir().toURL();
+ }
+ catch (MalformedURLException ex) {
+ throw new BuildException("Project basedir cannot be converted to a URL");
+ }
+ }
+
+ InputSource source = null;
+ URL url = null;
+
+ try {
+ url = new URL(baseURL, uri);
+ }
+ catch (MalformedURLException ex) {
+ // ignore
+ }
+
+ if (url != null) {
+ String fileName = url.getFile();
+ if (fileName != null) {
+ log("fileName"+fileName, Project.MSG_DEBUG);
+ File resFile = new File(fileName);
+ if (resFile.exists() && resFile.canRead()) {
+ try {
+ source = new InputSource(new FileInputStream(resFile));
+ String sysid = JAXPUtils.getSystemId(resFile);
+ source.setSystemId(sysid);
+ log("catalog entry matched a readable file: '" +
+ sysid + "'", Project.MSG_DEBUG);
+ } catch(FileNotFoundException ex) {
+ // ignore
+ } catch(IOException ex) {
+ // ignore
+ }
+ }
}
}
-
return source;
}
@@ -686,19 +697,32 @@ public class XMLCatalog extends DataType
* @return An InputSource for reading the resource, or null
* if the resource does not identify a valid URL or is not readable.
*/
- private InputSource urlLookup(String uri, String base) {
+ private InputSource urlLookup(ResourceLocation matchingEntry) {
+
+ String uri = matchingEntry.getLocation();
+ URL baseURL = null;
+
+ //
+ // The ResourceLocation may specify a relative url for its
+ // location attribute. This is resolved using the appropriate
+ // base.
+ //
+ if (matchingEntry.getBase() != null) {
+ baseURL = matchingEntry.getBase();
+ } else {
+ try {
+ baseURL = getProject().getBaseDir().toURL();
+ }
+ catch (MalformedURLException ex) {
+ throw new BuildException("Project basedir cannot be converted to a URL");
+ }
+ }
InputSource source = null;
URL url = null;
try {
- if (base == null) {
- url = new URL(uri);
- }
- else {
- URL baseURL = new URL(base);
- url = (uri.length() == 0 ? baseURL : new URL(baseURL, uri));
- }
+ url = new URL(baseURL, uri);
}
catch (MalformedURLException ex) {
// ignore
@@ -723,71 +747,6 @@ public class XMLCatalog extends DataType
}
- /**
- * Implements the guts of the resolveEntity() lookup strategy.
- */
- /*
- private InputSource resolveEntityImpl(String publicId) {
-
- InputSource result = null;
-
- ResourceLocation matchingEntry = findMatchingEntry(publicId);
-
- if (matchingEntry != null) {
-
- log("Matching catalog entry found for publicId: '" +
- matchingEntry.getPublicId() + "' location: '" +
- matchingEntry.getLocation() + "'",
- Project.MSG_DEBUG);
-
- result = filesystemLookup(matchingEntry);
-
- if (result == null) {
- result = classpathLookup(matchingEntry);
- }
-
- if (result == null) {
- result = urlLookup(matchingEntry.getLocation(), null);
- }
- }
- return result;
- }
- */
-
- /**
- * Implements the guts of the resolve() lookup strategy.
- */
- private SAXSource resolveImpl(String href, String base) {
-
- SAXSource result = null;
- InputSource source = null;
-
- ResourceLocation matchingEntry = findMatchingEntry(href);
-
- if (matchingEntry != null) {
-
- log("Matching catalog entry found for uri: '" +
- matchingEntry.getPublicId() + "' location: '" +
- matchingEntry.getLocation() + "'",
- Project.MSG_DEBUG);
-
- source = filesystemLookup(matchingEntry);
-
- if (source == null) {
- source = classpathLookup(matchingEntry);
- }
-
- if (source == null) {
- source = urlLookup(matchingEntry.getLocation(), base);
- }
-
- if (source != null) {
- result = new SAXSource(source);
- }
- }
- return result;
- }
-
/**
* Interface implemented by both the InternalResolver strategy and
* the ApacheResolver strategy.
@@ -815,9 +774,7 @@ public class XMLCatalog extends DataType
public InputSource resolveEntity(String publicId,
String systemId) {
-
InputSource result = null;
-
ResourceLocation matchingEntry = findMatchingEntry(publicId);
if (matchingEntry != null) {
@@ -834,14 +791,12 @@ public class XMLCatalog extends DataType
}
if (result == null) {
- result = urlLookup(matchingEntry.getLocation(), null);
+ result = urlLookup(matchingEntry);
}
}
return result;
}
-
-
public Source resolve(String href, String base)
throws TransformerException {
@@ -857,14 +812,38 @@ public class XMLCatalog extends DataType
matchingEntry.getLocation() + "'",
Project.MSG_DEBUG);
- source = filesystemLookup(matchingEntry);
+ //
+ // Use the passed in base in preference to the base
+ // from matchingEntry, which is either null or the
+ // directory in which the external catalog file from
+ // which it was obtained is located. We make a copy
+ // so matchingEntry's original base is untouched.
+ //
+ // This is the standard behavior as per my reading of
+ // the JAXP and XML Catalog specs. CKS 11/7/2002
+ //
+ ResourceLocation entryCopy = matchingEntry;
+ if (base != null) {
+ try {
+ URL baseURL = new URL(base);
+ entryCopy = new ResourceLocation();
+ entryCopy.setBase(baseURL);
+ }
+ catch (MalformedURLException ex) {
+ // ignore
+ }
+ }
+ entryCopy.setPublicId(matchingEntry.getPublicId());
+ entryCopy.setLocation(matchingEntry.getLocation());
+
+ source = filesystemLookup(entryCopy);
if (source == null) {
- source = classpathLookup(matchingEntry);
+ source = classpathLookup(entryCopy);
}
if (source == null) {
- source = urlLookup(matchingEntry.getLocation(), base);
+ source = urlLookup(entryCopy);
}
if (source != null) {
@@ -971,11 +950,11 @@ public class XMLCatalog extends DataType
else {
//
// We didn't match a ResourceLocation, but since we
- // only support PUBLIC and URI entry types, it is
- // still possible that there is another entry in an
- // external catalog that will match. We call Apache
- // resolver's resolveEntity method to cover this
- // possibility.
+ // only support PUBLIC and URI entry types internally,
+ // it is still possible that there is another entry in
+ // an external catalog that will match. We call
+ // Apache resolver's resolveEntity method to cover
+ // this possibility.
//
try {
result =
@@ -1008,10 +987,36 @@ public class XMLCatalog extends DataType
matchingEntry.getLocation() + "'",
Project.MSG_DEBUG);
- source = filesystemLookup(matchingEntry);
+ //
+ // Use the passed in base in preference to the base
+ // from matchingEntry, which is either null or the
+ // directory in which the external catalog file from
+ // which it was obtained is located. We make a copy
+ // so matchingEntry's original base is untouched. Of
+ // course, if there is no base, no need to make a
+ // copy...
+ //
+ // This is the standard behavior as per my reading of
+ // the JAXP and XML Catalog specs. CKS 11/7/2002
+ //
+ ResourceLocation entryCopy = matchingEntry;
+ if (base != null) {
+ try {
+ URL baseURL = new URL(base);
+ entryCopy = new ResourceLocation();
+ entryCopy.setBase(baseURL);
+ }
+ catch (MalformedURLException ex) {
+ // ignore
+ }
+ }
+ entryCopy.setPublicId(matchingEntry.getPublicId());
+ entryCopy.setLocation(matchingEntry.getLocation());
+
+ source = filesystemLookup(entryCopy);
if (source == null) {
- source = classpathLookup(matchingEntry);
+ source = classpathLookup(entryCopy);
}
if (source != null) {
@@ -1031,11 +1036,11 @@ public class XMLCatalog extends DataType
else {
//
// We didn't match a ResourceLocation, but since we
- // only support PUBLIC and URI entry types, it is
- // still possible that there is another entry in an
- // external catalog that will match. We call Apache
- // resolver's resolveEntity method to cover this
- // possibility.
+ // only support PUBLIC and URI entry types internally,
+ // it is still possible that there is another entry in
+ // an external catalog that will match. We call
+ // Apache resolver's resolveEntity method to cover
+ // this possibility.
//
try {
result =
@@ -1095,4 +1100,5 @@ public class XMLCatalog extends DataType
externalCatalogsProcessed = true;
}
}
-}
+
+} //-- XMLCatalog
diff --git a/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java b/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java
index 32dadc4ba..fd5abf7fa 100644
--- a/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java
+++ b/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java
@@ -132,7 +132,7 @@ public class ApacheCatalog extends Catalog {
Debug.message(1, "Internal Error: null ApacheCatalogResolver");
}
else {
- resolver.addPublicEntry(publicid, systemid, base.toExternalForm());
+ resolver.addPublicEntry(publicid, systemid, base);
}
} else if (type == URI) {
@@ -144,7 +144,7 @@ public class ApacheCatalog extends Catalog {
Debug.message(1, "Internal Error: null ApacheCatalogResolver");
}
else {
- resolver.addURIEntry(uri, altURI, base.toExternalForm());
+ resolver.addURIEntry(uri, altURI, base);
}
}
diff --git a/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java b/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java
index 18efb7c57..65277bcc4 100644
--- a/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java
+++ b/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java
@@ -57,12 +57,12 @@ package org.apache.tools.ant.types.resolver;
import java.io.IOException;
import java.net.MalformedURLException;
+import java.net.URL;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.XMLCatalog;
-import org.apache.tools.ant.types.DTDLocation;
-import org.apache.tools.ant.types.EntityLocation;
+import org.apache.tools.ant.types.ResourceLocation;
import org.apache.xml.resolver.Catalog;
import org.apache.xml.resolver.CatalogManager;
@@ -168,9 +168,9 @@ public class ApacheCatalogResolver extends CatalogResolver {
*/
public void addPublicEntry(String publicid,
String systemid,
- String base) {
+ URL base) {
- DTDLocation dtd = new DTDLocation();
+ ResourceLocation dtd = new ResourceLocation();
dtd.setBase(base);
dtd.setPublicId(publicid);
dtd.setLocation(systemid);
@@ -194,9 +194,9 @@ public class ApacheCatalogResolver extends CatalogResolver {
*/
public void addURIEntry(String uri,
String altURI,
- String base) {
+ URL base) {
- EntityLocation entity = new EntityLocation();
+ ResourceLocation entity = new ResourceLocation();
entity.setBase(base);
entity.setPublicId(uri);
entity.setLocation(altURI);
diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/XsltTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/XsltTest.java
index 8819f0dfa..7c05b5329 100644
--- a/src/testcases/org/apache/tools/ant/taskdefs/optional/XsltTest.java
+++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/XsltTest.java
@@ -98,12 +98,12 @@ public class XsltTest extends BuildFileTest {
/**
* A unit test for JUnit
+ */
public void testCatchNoDtd() throws Exception {
expectBuildExceptionContaining("testCatchNoDtd",
- "expected failure",
- "Fatal error during transformation");
+ "expected failure",
+ "Fatal error during transformation");
}
- */
/**
* A unit test for JUnit