Return-Path:
+
resolver.jar
+ xmlcatalog datatype only if support for external catalog files is desired
+ http://xml.apache.org/dist/commons
+
1.3 +60 -4 jakarta-ant/docs/manual/CoreTypes/xmlcatalog.html
Index: xmlcatalog.html
===================================================================
RCS file: /home/cvs/jakarta-ant/docs/manual/CoreTypes/xmlcatalog.html,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- xmlcatalog.html 1 Jun 2002 12:26:35 -0000 1.2
+++ xmlcatalog.html 5 Nov 2002 16:33:28 -0000 1.3
@@ -19,6 +19,10 @@
to efficiently allow a local substitution for a resource available on the
web.
Note: This task uses, but does not depend on external +libraries not included in the Ant distribution. See Library Dependencies for more +information.
This data type provides a catalog of resource locations based
on the
@@ -59,17 +63,34 @@
XMLCatalogs are specified as either a reference to another XMLCatalog,
defined
previously in a build file, or as a list of XMLCatalogs can also be nested inside other XMLCatalogs. For
example, a "superset" XMLCatalog could be made by including several
nested XMLCatalogs that referred to other, previously defined
XMLCatalogs. 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 path. 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 Currently, only dtd
or
-entity
locations. A separate classpath for entity resolution
+entity
locations. In addition, external catalog files
+may be specified in catalogfiles
filesets, but they will
+be ignored unless the resolver library from xml-commons is available
+in the system classpath. A separate classpath for entity resolution
may be specified inline via nested classpath
elements;
otherwise the system classpath is used for this as well.catalogfiles
+filesets, will be ignored and a warning will be logged. In this case, however,
+processing of inline entries will proceed normally.<dtd>
and
<entity>
elements may be specified inline; these
roughly correspond to OASIS catalog entry types PUBLIC
and
-URI
respectively.URI
respectively. By contrast, external catalog files
+may use any of the entry types defined in the
+
++OASIS specification.
blat.dtd
.
+What happens next depends on whether the resolver library from +xml-commons is available on the classpath. If so, we defer all +further attempts at resolving to it. The resolver library supports +extremely sophisticated functionality like URL rewriting and so on, +which can be accessed by making the appropriate entries in external +catalog files (XMLCatalog does not yet provide inline support for all +of the entries defined in the OASIS +standard).
+Finally, we attempt to make a URL out of the location
.
@@ -171,6 +204,22 @@
The classpath to use for entity
resolution. The nested <classpath>
is a
path-like structure.
+The nested catalogfiles
element specifies a FileSet. All files included in
+this fileset are assumed to be OASIS catalog files, in either
+
+plain text format or
+XML format. Multiple catalogfiles
filesets may be
+specified. Of course, if you use wildcards in your fileset, you will
+want to use some sort of naming convention to ensure that you don't
+accidentally match non-catalog files. If the resolver library from
+xml-commons is not available in the classpath, all
+catalogfiles
will be ignored and a warning will be
+logged.
+
Set up an XMLCatalog with a single dtd referenced locally in a user's home @@ -197,7 +246,8 @@
Set up an XMLCatalog with a combination of DTDs and entities as -well as a nested XMLCatalog:
+well as a nested XMLCatalog and external catalog files in both +formats:<xmlcatalog id="allcatalogs"> @@ -207,7 +257,13 @@ <entity publicId="LargeLogo" location="com/arielpartners/images/ariel-logo-large.gif"/> - <xmlcatalog refid="commonDTDs"/> + <xmlcatalog refid="commonDTDs"/> + <catalogfiles + dir="/anetwork/drive" + includes="**/catalog"/> + <catalogfiles + dir="/my/catalogs" + includes="**/catalog.xml"/> </xmlcatalog>
To reference the above XMLCatalog in an xslt
task:
1.7 +11 -1 jakarta-ant/src/etc/testcases/taskdefs/optional/xmlvalidate.xml
Index: xmlvalidate.xml
===================================================================
RCS file: /home/cvs/jakarta-ant/src/etc/testcases/taskdefs/optional/xmlvalidate.xml,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- xmlvalidate.xml 23 Sep 2002 14:59:42 -0000 1.6
+++ xmlvalidate.xml 5 Nov 2002 16:33:28 -0000 1.7
@@ -38,8 +38,18 @@
+
+ Helper class to handle the DTD nested element. Instances of
+ * this class correspond to the Possible Future Enhancement: Bring the Ant element name into
+ * conformance with the OASIS standard. Until we query the classpath, we don't know whether the Apache
+ * resolver (Norm Walsh's library from xml-commons) is available or not.
+ * This method determines whether the library is available and creates the
+ * appropriate implementation of CatalogResolver based on the answer. This is an application of the Gang of Four Strategy Pattern
+ * combined with Template Method. This is called from the URIResolver to set an EntityResolver
* on the SAX parser to be used for new XML documents that are
@@ -465,6 +566,29 @@
}
/**
+ * Find a ResourceLocation instance for the given publicId.
+ *
+ * @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 ResourceLocation findMatchingEntry(String publicId) {
+ Enumeration enum = getElements().elements();
+ ResourceLocation element = null;
+ while (enum.hasMoreElements()) {
+ Object o = enum.nextElement();
+ if (o instanceof ResourceLocation) {
+ element = (ResourceLocation)o;
+ if (element.getPublicId().equals(publicId)) {
+ return element;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
* Utility method to remove trailing fragment from a URI.
* For example,
* Possible Future Enhancement: Bring the Ant element name into
* conformance with the OASIS standard. Helper class to handle the Possible Future Enhancements:
* PUBLIC
catalog entry type
+ * of the
+ * OASIS "Open Catalog" standard.<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
+ * if this is a reference and no nested elements are allowed.
+ */
+ public void addCatalogfiles(FileSet fs) throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ getElements().addElement(fs);
+ }
+
/**
* Creates the nested <dtd>
element. Not
* allowed if this catalog is itself a reference to another
@@ -248,7 +282,7 @@
* @exception BuildException if this is a reference and no nested
* elements are allowed.
*/
- public void addDTD(DTDLocation dtd) throws BuildException {
+ public void addDTD(ResourceLocation dtd) throws BuildException {
if (isReference()) {
throw noChildrenAllowed();
}
@@ -256,6 +290,9 @@
getElements().addElement(dtd);
setChecked( false );
}
+ public void addDTD(DTDLocation dtd) throws BuildException {
+ addDTD((ResourceLocation)dtd);
+ }
/**
* Creates the nested <entity>
element. Not
@@ -263,13 +300,34 @@
* catalog -- that is, a catalog cannot both refer to another
* and contain elements or other attributes.
*
- * @param dtd 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(DTDLocation dtd) throws BuildException {
- addDTD(dtd);
+ 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);
}
/**
@@ -337,17 +395,18 @@
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
- if (!isChecked()) {
- // make sure we don't have a circular reference here
- Stack stk = new Stack();
- stk.push(this);
- dieOnCircularReference(stk, getProject());
- }
+ if (!isChecked()) {
+ // make sure we don't have a circular reference here
+ Stack stk = new Stack();
+ stk.push(this);
+ dieOnCircularReference(stk, getProject());
+ }
log("resolveEntity: '" + publicId + "': '" + systemId + "'",
Project.MSG_DEBUG);
- InputSource inputSource = resolveEntityImpl(publicId );
+ InputSource inputSource =
+ getCatalogResolver().resolveEntity(publicId, systemId);
if (inputSource == null) {
log("No matching catalog entry found, parser will use: '" +
@@ -365,12 +424,12 @@
public Source resolve(String href, String base)
throws TransformerException {
- if (!isChecked()) {
- // make sure we don't have a circular reference here
- Stack stk = new Stack();
- stk.push(this);
- dieOnCircularReference(stk, getProject());
- }
+ if (!isChecked()) {
+ // make sure we don't have a circular reference here
+ Stack stk = new Stack();
+ stk.push(this);
+ dieOnCircularReference(stk, getProject());
+ }
SAXSource source = null;
@@ -389,11 +448,11 @@
//
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 = 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
@@ -406,25 +465,67 @@
}
/**
- * Find a DTDLocation instance for the given publicId.
+ * The instance of the CatalogResolver strategy to use.
+ */
+ private static CatalogResolver catalogResolver = null;
+
+ /**
+ * Factory method for creating the appropriate CatalogResolver
+ * strategy implementation.
+ * http://java.sun.com/index.html#chapter1
@@ -484,17 +608,17 @@
}
/**
- * Utility method to lookup a DTDLocation in the filesystem.
+ * Utility method to lookup a ResourceLocation in the filesystem.
*
* @return An InputSource for reading the file, or null
* if the file does not exist or is not readable.
*/
- private InputSource filesystemLookup(DTDLocation matchingEntry) {
+ private InputSource filesystemLookup(ResourceLocation matchingEntry) {
String uri = matchingEntry.getLocation();
//
- // The DTDLocation may specify a relative path for its
+ // The ResourceLocation may specify a relative path for its
// location attribute. This is resolved using the appropriate
// base.
//
@@ -522,12 +646,12 @@
}
/**
- * Utility method to lookup a DTDLocation in the classpath.
+ * Utility method to lookup a ResourceLocation in the classpath.
*
* @return An InputSource for reading the resource, or null
* if the resource does not exist in the classpath or is not readable.
*/
- private InputSource classpathLookup(DTDLocation matchingEntry) {
+ private InputSource classpathLookup(ResourceLocation matchingEntry) {
InputSource source = null;
@@ -557,7 +681,7 @@
}
/**
- * Utility method to lookup a DTDLocation in URL-space.
+ * Utility method to lookup a ResourceLocation in URL-space.
*
* @return An InputSource for reading the resource, or null
* if the resource does not identify a valid URL or is not readable.
@@ -602,31 +726,33 @@
/**
* Implements the guts of the resolveEntity() lookup strategy.
*/
- private InputSource resolveEntityImpl(String publicId) {
+ /*
+ private InputSource resolveEntityImpl(String publicId) {
- InputSource result = null;
+ InputSource result = null;
- DTDLocation matchingEntry = findMatchingEntry(publicId);
+ ResourceLocation matchingEntry = findMatchingEntry(publicId);
- if (matchingEntry != null) {
+ if (matchingEntry != null) {
- log("Matching catalog entry found for publicId: '" +
- matchingEntry.getPublicId() + "' location: '" +
- matchingEntry.getLocation() + "'",
- Project.MSG_DEBUG);
+ log("Matching catalog entry found for publicId: '" +
+ matchingEntry.getPublicId() + "' location: '" +
+ matchingEntry.getLocation() + "'",
+ Project.MSG_DEBUG);
- result = filesystemLookup(matchingEntry);
+ result = filesystemLookup(matchingEntry);
- if (result == null) {
- result = classpathLookup(matchingEntry);
- }
+ if (result == null) {
+ result = classpathLookup(matchingEntry);
+ }
- if (result == null) {
- result = urlLookup(matchingEntry.getLocation(), null);
- }
- }
- return result;
- }
+ if (result == null) {
+ result = urlLookup(matchingEntry.getLocation(), null);
+ }
+ }
+ return result;
+ }
+ */
/**
* Implements the guts of the resolve() lookup strategy.
@@ -636,7 +762,7 @@
SAXSource result = null;
InputSource source = null;
- DTDLocation matchingEntry = findMatchingEntry(href);
+ ResourceLocation matchingEntry = findMatchingEntry(href);
if (matchingEntry != null) {
@@ -660,5 +786,313 @@
}
}
return result;
+ }
+
+ /**
+ * Interface implemented by both the InternalResolver strategy and
+ * the ApacheResolver strategy.
+ */
+ private interface CatalogResolver extends URIResolver, EntityResolver {
+
+ InputSource resolveEntity(String publicId, String systemId);
+
+ Source resolve(String href, String base) throws TransformerException;
+ }
+
+ /**
+ * The InternalResolver strategy is used if the Apache resolver
+ * library (Norm Walsh's library from xml-commons) is not
+ * available. In this case, external catalog files will be
+ * ignored.
+ *
+ */
+ private class InternalResolver implements CatalogResolver {
+
+ public InternalResolver() {
+ log("Apache resolver library not found, internal resolver will be used",
+ Project.MSG_INFO);
+ }
+
+ public InputSource resolveEntity(String publicId,
+ String systemId) {
+
+ 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;
+ }
+
+
+
+ public Source resolve(String href, String base)
+ throws TransformerException {
+
+ 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;
+ }
+ }
+
+ /**
+ * The ApacheResolver strategy is used if the Apache resolver
+ * library (Norm Walsh's library from xml-commons) is available in
+ * the classpath. The ApacheResolver is a essentially a superset
+ * of the InternalResolver.
+ *
+ */
+ private class ApacheResolver implements CatalogResolver {
+
+ private Method setXMLCatalog = null;
+ private Method parseCatalog = null;
+ private Method resolveEntity = null;
+ private Method resolve = null;
+
+ /** The instance of the ApacheCatalogResolver bridge class */
+ private Object resolverImpl = null;
+
+ private boolean externalCatalogsProcessed = false;
+
+ public ApacheResolver(Class resolverImplClass,
+ Object resolverImpl) {
+
+ this.resolverImpl = resolverImpl;
+
+ //
+ // Get Method instances for each of the methods we need to
+ // call on the resolverImpl using reflection. We can't
+ // call them directly, because they require on the
+ // xml-commons resolver library which may not be available
+ // in the classpath.
+ //
+ try {
+ setXMLCatalog =
+ resolverImplClass.getMethod("setXMLCatalog",
+ new Class[]
+ { XMLCatalog.class });
+
+ parseCatalog =
+ resolverImplClass.getMethod("parseCatalog",
+ new Class[]
+ { String.class });
+
+ resolveEntity =
+ resolverImplClass.getMethod("resolveEntity",
+ new Class[]
+ { String.class, String.class });
+
+ resolve =
+ resolverImplClass.getMethod("resolve",
+ new Class[]
+ { String.class, String.class });
+ }
+ catch (NoSuchMethodException ex) {
+ throw new BuildException(ex);
+ }
+
+ log("Apache resolver library found, xml-commons resolver will be used",
+ Project.MSG_INFO);
+ }
+
+ public InputSource resolveEntity(String publicId,
+ String systemId) {
+ InputSource result = null;
+
+ processExternalCatalogs();
+
+ 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) {
+ try {
+ result =
+ (InputSource)resolveEntity.invoke(resolverImpl,
+ new Object[]
+ { publicId, systemId });
+ }
+ catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+ }
+ 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.
+ //
+ try {
+ result =
+ (InputSource)resolveEntity.invoke(resolverImpl,
+ new Object[]
+ { publicId, systemId });
+ }
+ catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+
+ return result;
+ }
+
+ public Source resolve(String href, String base)
+ throws TransformerException {
+
+ SAXSource result = null;
+ InputSource source = null;
+
+ processExternalCatalogs();
+
+ 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) {
+ result = new SAXSource(source);
+ } else {
+ try {
+ result =
+ (SAXSource)resolve.invoke(resolverImpl,
+ new Object[]
+ { href, base });
+ }
+ catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+ }
+ 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.
+ //
+ try {
+ result =
+ (SAXSource)resolve.invoke(resolverImpl,
+ new Object[]
+ { href, base });
+ }
+ catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Process each external catalog file specified in a
+ * <catalogfiles>
FileSet. It will be
+ * parsed by the resolver library, and the individual elements
+ * will be added back to us (that is, the controlling
+ * XMLCatalog instance) via a callback mechanism.
+ */
+ private void processExternalCatalogs() {
+
+ if (externalCatalogsProcessed == false) {
+
+ try {
+ setXMLCatalog.invoke(resolverImpl,
+ new Object[]
+ { XMLCatalog.this });
+ }
+ catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+
+ Enumeration enum = getElements().elements();
+ while (enum.hasMoreElements()) {
+ Object o = enum.nextElement();
+ if (o instanceof FileSet) {
+ FileSet fs = (FileSet)o;
+ DirectoryScanner ds =
+ fs.getDirectoryScanner(getProject());
+ String[] files = ds.getIncludedFiles();
+ for (int i = 0; i < files.length; i++) {
+ File catFile = new File(ds.getBasedir(), files[i]);
+ try {
+ parseCatalog.invoke(resolverImpl,
+ new Object[]
+ { catFile.getPath() });
+ }
+ catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+ }
+ }
+ }
+ externalCatalogsProcessed = true;
+ }
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/types/EntityLocation.java
Index: EntityLocation.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* URI
catalog entry type of
* the
* OASIS "Open Catalog" standard.<dtd>
and
* <entity>
nested elements. These correspond to
* the PUBLIC
and URI
catalog entry types,
* respectively, as defined in the
* OASIS "Open Catalog" standard.
*
*
PUBLIC
or URI
.
*
* @see org.apache.xml.resolver.Catalog
*/
public String getName() {
return name;
}
} //-- ResourceLocation
1.1 jakarta-ant/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java
Index: ApacheCatalog.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <dtd>
* and <entity>
) are not added to ApacheCatalog.
* See XMLCatalog.java for the details of the entity and URI
* resolution algorithms.
*
* @see org.apache.tools.ant.types.XMLCatalog.CatalogResolver
* @author Craeg Strong
* @version $Id: ApacheCatalog.java,v 1.1 2002/11/05 16:33:29 bodewig Exp $
*/
public class ApacheCatalog extends Catalog {
/** The resolver object to callback. */
private ApacheCatalogResolver resolver = null;
/**
* Create a new ApacheCatalog instance.
* *This method overrides the superclass method of the same name * in order to set the resolver object for callbacks. The reason * we have to do this is that internally Catalog creates a new * instance of itself for each external catalog file processed. * That is, if two external catalog files are processed, there * will be a total of two ApacheCatalog instances, and so on.
*/ protected Catalog newCatalog() { ApacheCatalog cat = (ApacheCatalog)super.newCatalog(); cat.setResolver(resolver); return cat; } /** Set the resolver object to callback. */ public void setResolver(ApacheCatalogResolver resolver) { this.resolver = resolver; } /** *This method overrides the superclass method of the same name * in order to add catalog entries back to the controlling * XMLCatalog instance. In this way, we can add classpath lookup * for these entries.
* *When we add an external catalog file, the entries inside it * get parsed by this method. Therefore, we override it to add * each of them back to the controlling XMLCatalog instance. This * is done by performing a callback to the ApacheCatalogResolver, * which in turn calls the XMLCatalog.
* *XMLCatalog currently only understands PUBLIC
* and URI
entry types, so we ignore the other types.
This class extends the CatalogResolver class provided by Norman * Walsh's resolver library in xml-commons. It provides the bridge * between the Ant XMLCatalog datatype and the xml-commons Catalog * class. XMLCatalog calls methods in this class using Reflection in * order to avoid requiring the xml-commons resolver library in the * path.
* *The {@link org.apache.tools.ant.types.resolver.ApacheCatalog * ApacheCatalog} class is used to parse external catalog files, which * can be in either * plain text format or * XML format.
* *For each entry found in an external catalog file, if any, an * instance of {@link org.apache.tools.ant.types.ResourceLocation * ResourceLocation} is created and added to the controlling * XMLCatalog datatype. In this way, these entries will be included * in XMLCatalog's lookup algorithm. See XMLCatalog.java for more * details.
* * @see org.apache.tools.ant.types.XMLCatalog.CatalogResolver * @see org.apache.xml.resolver.CatalogManager * @author Craeg Strong * @version $Id: ApacheCatalogResolver.java,v 1.1 2002/11/05 16:33:29 bodewig Exp $ */ public class ApacheCatalogResolver extends CatalogResolver { /** The XMLCatalog object to callback. */ private XMLCatalog xmlCatalog = null; static { // // If you don't do this, you get all sorts of annoying // warnings about a missing properties file. However, it // seems to work just fine with default values. Ultimately, // we should probably include a "CatalogManager.properties" // file in the ant jarfile with some default property // settings. See CatalogManager.java for more details. // CatalogManager.ignoreMissingProperties(true); // // Make sure CatalogResolver instantiates ApacheCatalog, // rather than a plain Catalog // System.setProperty("xml.catalog.className", ApacheCatalog.class.getName()); // debug // System.setProperty("xml.catalog.verbosity", "4"); } /** Set the XMLCatalog object to callback. */ public void setXMLCatalog(XMLCatalog xmlCatalog) { this.xmlCatalog = xmlCatalog; } /** * XMLCatalog calls this to add an external catalog file for each * file within a<catalogfiles>
fileset.
*/
public void parseCatalog(String file) {
ApacheCatalog catalog = (ApacheCatalog)getCatalog();
// Pass in reference to ourselves so we can be called back.
catalog.setResolver(this);
try {
catalog.parseCatalog(file);
}
catch(MalformedURLException ex) {
throw new BuildException(ex);
}
catch(IOException ex) {
throw new BuildException(ex);
}
}
/**
* Add a PUBLIC catalog entry to the controlling XMLCatalog instance. * ApacheCatalog calls this for each PUBLIC entry found in an external * catalog file.
* * @param publicid The public ID of the resource * @param systemid The system ID (aka location) of the resource * @param base The base URL of the resource. If the systemid * specifies a relative URL/pathname, it is resolved using the * base. The default base for an external catalog file is the * directory in which the catalog is located. * */ public void addPublicEntry(String publicid, String systemid, String base) { DTDLocation dtd = new DTDLocation(); dtd.setBase(base); dtd.setPublicId(publicid); dtd.setLocation(systemid); xmlCatalog.addDTD(dtd); } /** *Add a URI catalog entry to the controlling XMLCatalog instance. * ApacheCatalog calls this for each URI entry found in an external * catalog file.
* * @param URI The URI of the resource * @param altURI The URI to which the resource should be mapped * (aka the location) * @param base The base URL of the resource. If the altURI * specifies a relative URL/pathname, it is resolved using the * base. The default base for an external catalog file is the * directory in which the catalog is located. * */ public void addURIEntry(String uri, String altURI, String base) { EntityLocation entity = new EntityLocation(); entity.setBase(base); entity.setPublicId(uri); entity.setLocation(altURI); xmlCatalog.addEntity(entity); } } //-- ApacheCatalogResolver 1.1 jakarta-ant/src/main/org/apache/tools/ant/types/resolver/package.html Index: package.html =================================================================== Ant integration with xml-commons resolver.These classes enhance the <xmlcatalog>
datatype
to support external catalog files using the xml-commons resolver, in
accordance with the
OASIS "Open Catalog" standard. They will be used if and only if
the xml-commons resolver library is available on the classpath.
Copyright © 2002 Apache Software Foundation. All rights Reserved.
1.6 +11 -0 jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java Index: XmlValidateTest.java =================================================================== RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- XmlValidateTest.java 30 Sep 2002 09:40:39 -0000 1.5 +++ XmlValidateTest.java 5 Nov 2002 16:33:29 -0000 1.6 @@ -122,6 +122,17 @@ } /** + * catalogfiles fileset should be ignored + * if resolver.jar is not present, but will + * be used if it is. either way, test should + * work b/c we have a nested dtd with the same + * entity + */ + public void testXmlCatalogFiles() { + executeTarget("xmlcatalogfiles"); + } + + /** * Test nested xmlcatalog definitions */ public void testXmlCatalogNested() { -- To unsubscribe, e-mail: