FileDocCategorySizeDatePackage
XMLCatalogResolver.javaAPI DocApache Xerces 3.0.123090Fri Sep 14 20:33:54 BST 2007org.apache.xerces.util

XMLCatalogResolver

public class XMLCatalogResolver extends Object implements LSResourceResolver, org.apache.xerces.xni.parser.XMLEntityResolver, EntityResolver2

The catalog resolver handles the resolution of external identifiers and URI references through XML catalogs. This component supports XML catalogs defined by the OASIS XML Catalogs Specification. It encapsulates the XML Commons resolver. An instance of this class may be registered on the parser as a SAX entity resolver, as a DOM LSResourceResolver or as an XNI entity resolver by setting the property (http://apache.org/xml/properties/internal/entity-resolver).

It is intended that this class may be used standalone to perform catalog resolution outside of a parsing context. It may be shared between several parsers and the application.

author
Michael Glavassevich, IBM
version
$Id: XMLCatalogResolver.java 570138 2007-08-27 14:21:51Z mrglavas $

Fields Summary
private org.apache.xml.resolver.CatalogManager
fResolverCatalogManager
Internal catalog manager for Apache catalogs.
private org.apache.xml.resolver.Catalog
fCatalog
Internal catalog structure.
private String[]
fCatalogsList
An array of catalog URIs.
private boolean
fCatalogsChanged
Indicates whether the list of catalogs has changed since it was processed.
private boolean
fPreferPublic
Application specified prefer public setting.
private boolean
fUseLiteralSystemId
Indicates whether the application desires that the parser or some other component performing catalog resolution should use the literal system identifier instead of the expanded system identifier.
Constructors Summary
public XMLCatalogResolver()

Constructs a catalog resolver with a default configuration.

    
                 
       
    	this(null, true);
    
public XMLCatalogResolver(String[] catalogs)

Constructs a catalog resolver with the given list of entry files.

param
catalogs an ordered array list of absolute URIs

    	this(catalogs, true);
    
public XMLCatalogResolver(String[] catalogs, boolean preferPublic)

Constructs a catalog resolver with the given list of entry files and the preference for whether system or public matches are preferred.

param
catalogs an ordered array list of absolute URIs
param
preferPublic the prefer public setting

        init(catalogs, preferPublic);
    
Methods Summary
private voidattachReaderToCatalog(org.apache.xml.resolver.Catalog catalog)
Attaches the reader to the catalog.


        SAXParserFactory spf = new SAXParserFactoryImpl();
        spf.setNamespaceAware(true);
        spf.setValidating(false);

        SAXCatalogReader saxReader = new SAXCatalogReader(spf);
        saxReader.setCatalogParser(OASISXMLCatalogReader.namespaceName, "catalog", 
            "org.apache.xml.resolver.readers.OASISXMLCatalogReader");
        catalog.addReader("application/xml", saxReader);
    
public final synchronized voidclear()

Forces the cache of catalog mappings to be cleared.

        fCatalog = null;
    
public final synchronized java.lang.String[]getCatalogList()

Returns the initial list of catalog entry files.

return
the initial list of catalog entry files

        return (fCatalogsList != null) 
            ? (String[]) fCatalogsList.clone() : null;
    
public org.xml.sax.InputSourcegetExternalSubset(java.lang.String name, java.lang.String baseURI)

Locates an external subset for documents which do not explicitly provide one. This method always returns null. It should be overrided if other behaviour is required.

param
name the identifier of the document root element
param
baseURI the document's base URI
throws
SAXException any SAX exception, possibly wrapping another exception
throws
IOException thrown if some i/o error occurs

         return null;
     
public final booleangetPreferPublic()

Returns the preference for whether system or public matches are preferred. This is used in the absence of any occurrence of the prefer attribute on the catalog entry of a catalog. If this property has not yet been explicitly set its value is true.

return
the prefer public setting

        return fPreferPublic;
    
public final booleangetUseLiteralSystemId()

Returns the preference for whether the literal system identifier should be used when resolving system identifiers when both it and the expanded system identifier are available. If this property has not yet been explicitly set its value is true.

return
the preference for using literal system identifiers for catalog resolution
see
#setUseLiteralSystemId

        return fUseLiteralSystemId;
    
private voidinit(java.lang.String[] catalogs, boolean preferPublic)
Initialization. Create a CatalogManager and set all the properties upfront. This prevents JVM wide system properties or a property file somewhere in the environment from affecting the behaviour of this catalog resolver.

        fCatalogsList = (catalogs != null) ? (String[]) catalogs.clone() : null;
        fPreferPublic = preferPublic;
        fResolverCatalogManager = new CatalogManager();
        fResolverCatalogManager.setAllowOasisXMLCatalogPI(false);
        fResolverCatalogManager.setCatalogClassName("org.apache.xml.resolver.Catalog");
        fResolverCatalogManager.setCatalogFiles("");
        fResolverCatalogManager.setIgnoreMissingProperties(true);
        fResolverCatalogManager.setPreferPublic(fPreferPublic);
        fResolverCatalogManager.setRelativeCatalogs(false);
        fResolverCatalogManager.setUseStaticCatalog(false);
        fResolverCatalogManager.setVerbosity(0);
    
private voidparseCatalogs()
Instruct the Catalog to parse each of the catalogs in the list. Only the first catalog will actually be parsed immediately. The others will be queued and read if they are needed later.

        if (fCatalogsList != null) {
            fCatalog = new Catalog(fResolverCatalogManager);
            attachReaderToCatalog(fCatalog);
            for (int i = 0; i < fCatalogsList.length; ++i) {
                String catalog = fCatalogsList[i];
                if (catalog != null && catalog.length() > 0) {
                    fCatalog.parseCatalog(catalog);
                }
            }
        }
        else {
            fCatalog = null;
        }
    
public org.xml.sax.InputSourceresolveEntity(java.lang.String publicId, java.lang.String systemId)

Resolves an external entity. If the entity cannot be resolved, this method should return null. This method returns an input source if an entry was found in the catalog for the given external identifier. It should be overridden if other behaviour is required.

param
publicId the public identifier, or null if none was supplied
param
systemId the system identifier
throws
SAXException any SAX exception, possibly wrapping another exception
throws
IOException thrown if some i/o error occurs

        
        String resolvedId = null;
        if (publicId != null && systemId != null) {
            resolvedId = resolvePublic(publicId, systemId);
        }
        else if (systemId != null) {
            resolvedId = resolveSystem(systemId);
        }
        
        if (resolvedId != null) {
            InputSource source = new InputSource(resolvedId);
            source.setPublicId(publicId);
            return source;
        }  
        return null;
    
public org.xml.sax.InputSourceresolveEntity(java.lang.String name, java.lang.String publicId, java.lang.String baseURI, java.lang.String systemId)

Resolves an external entity. If the entity cannot be resolved, this method should return null. This method returns an input source if an entry was found in the catalog for the given external identifier. It should be overridden if other behaviour is required.

param
name the identifier of the external entity
param
publicId the public identifier, or null if none was supplied
param
baseURI the URI with respect to which relative systemIDs are interpreted.
param
systemId the system identifier
throws
SAXException any SAX exception, possibly wrapping another exception
throws
IOException thrown if some i/o error occurs

 
        
         String resolvedId = null;
         
         if (!getUseLiteralSystemId() && baseURI != null) {
             // Attempt to resolve the system identifier against the base URI.
             try {
                 URI uri = new URI(new URI(baseURI), systemId);
                 systemId = uri.toString();
             }
             // Ignore the exception. Fallback to the literal system identifier.
             catch (URI.MalformedURIException ex) {}
         }
         
         if (publicId != null && systemId != null) {
             resolvedId = resolvePublic(publicId, systemId);
         }
         else if (systemId != null) {
             resolvedId = resolveSystem(systemId);
         }
        
         if (resolvedId != null) {
             InputSource source = new InputSource(resolvedId);
             source.setPublicId(publicId);
             return source;
         }  
         return null;
    
public org.apache.xerces.xni.parser.XMLInputSourceresolveEntity(org.apache.xerces.xni.XMLResourceIdentifier resourceIdentifier)

Resolves an external entity. If the entity cannot be resolved, this method should return null. This method only calls resolveIdentifier and returns an input source if an entry was found in the catalog. It should be overridden if other behaviour is required.

param
resourceIdentifier location of the XML resource to resolve
throws
XNIException thrown on general error
throws
IOException thrown if some i/o error occurs


        String resolvedId = resolveIdentifier(resourceIdentifier);
        if (resolvedId != null) {
            return new XMLInputSource(resourceIdentifier.getPublicId(), 
                                      resolvedId, 
                                      resourceIdentifier.getBaseSystemId());
        }
        return null;
    
public java.lang.StringresolveIdentifier(org.apache.xerces.xni.XMLResourceIdentifier resourceIdentifier)

Resolves an identifier using the catalog. This method interprets that the namespace of the identifier corresponds to uri entries in the catalog. Where both a namespace and an external identifier exist, the namespace takes precedence.

param
resourceIdentifier the identifier to resolve
throws
XNIException thrown on general error
throws
IOException thrown if some i/o error occurs

        
        String resolvedId = null;

        // The namespace is useful for resolving namespace aware
        // grammars such as XML schema. Let it take precedence over
        // the external identifier if one exists.
        String namespace = resourceIdentifier.getNamespace();
        if (namespace != null) {
            resolvedId = resolveURI(namespace);
        }
        
        // Resolve against an external identifier if one exists. This
        // is useful for resolving DTD external subsets and other 
        // external entities. For XML schemas if there was no namespace 
        // mapping we might be able to resolve a system identifier 
        // specified as a location hint.
        if (resolvedId == null) {
            String publicId = resourceIdentifier.getPublicId();
            String systemId = getUseLiteralSystemId() 
                ? resourceIdentifier.getLiteralSystemId()
                : resourceIdentifier.getExpandedSystemId();
            if (publicId != null && systemId != null) {
                resolvedId = resolvePublic(publicId, systemId);
            }
            else if (systemId != null) {
                resolvedId = resolveSystem(systemId);
            }
        }
        return resolvedId;
    
public final synchronized java.lang.StringresolvePublic(java.lang.String publicId, java.lang.String systemId)

Returns the URI mapping in the catalog for the given external identifier or null if no mapping exists. Public identifiers are normalized before comparison.

param
publicId the public identifier to locate in the catalog
param
systemId the system identifier to locate in the catalog
return
the mapped URI or null if no mapping was found in the catalog
throws
IOException if an i/o error occurred while reading the catalog


        if (fCatalogsChanged) {
            parseCatalogs();
            fCatalogsChanged = false;
        }
        return (fCatalog != null) 
            ? fCatalog.resolvePublic(publicId, systemId) : null;
    
public org.w3c.dom.ls.LSInputresolveResource(java.lang.String type, java.lang.String namespaceURI, java.lang.String publicId, java.lang.String systemId, java.lang.String baseURI)

Resolves a resource using the catalog. This method interprets that the namespace URI corresponds to uri entries in the catalog. Where both a namespace and an external identifier exist, the namespace takes precedence.

param
type the type of the resource being resolved
param
namespaceURI the namespace of the resource being resolved, or null if none was supplied
param
publicId the public identifier of the resource being resolved, or null if none was supplied
param
systemId the system identifier of the resource being resolved, or null if none was supplied
param
baseURI the absolute base URI of the resource being parsed, or null if there is no base URI


        String resolvedId = null;
        
        try {
            // The namespace is useful for resolving namespace aware
            // grammars such as XML schema. Let it take precedence over
            // the external identifier if one exists.
            if (namespaceURI != null) {
                resolvedId = resolveURI(namespaceURI);
            }
            
            if (!getUseLiteralSystemId() && baseURI != null) {
                // Attempt to resolve the system identifier against the base URI.
                try {
                    URI uri = new URI(new URI(baseURI), systemId);
                    systemId = uri.toString();
                }
                // Ignore the exception. Fallback to the literal system identifier.
                catch (URI.MalformedURIException ex) {}
            }
        
            // Resolve against an external identifier if one exists. This
            // is useful for resolving DTD external subsets and other 
            // external entities. For XML schemas if there was no namespace 
            // mapping we might be able to resolve a system identifier 
            // specified as a location hint.
            if (resolvedId == null) {
                if (publicId != null && systemId != null) {
                    resolvedId = resolvePublic(publicId, systemId);
                }
                else if (systemId != null) {
                    resolvedId = resolveSystem(systemId);
                }
            }
        }
        // Ignore IOException. It cannot be thrown from this method.
        catch (IOException ex) {}
        
        if (resolvedId != null) {
            return new DOMInputImpl(publicId, resolvedId, baseURI);
        }  
        return null;
    
public final synchronized java.lang.StringresolveSystem(java.lang.String systemId)

Returns the URI mapping in the catalog for the given external identifier or null if no mapping exists. If the system identifier is an URN in the publicid namespace it is converted into a public identifier by URN "unwrapping" as specified in the XML Catalogs specification.

param
systemId the system identifier to locate in the catalog
return
the mapped URI or null if no mapping was found in the catalog
throws
IOException if an i/o error occurred while reading the catalog


        if (fCatalogsChanged) {
            parseCatalogs();
            fCatalogsChanged = false;
        }
        return (fCatalog != null) 
            ? fCatalog.resolveSystem(systemId) : null;
    
public final synchronized java.lang.StringresolveURI(java.lang.String uri)

Returns the URI mapping in the catalog for the given URI reference or null if no mapping exists. URI comparison is case sensitive. If the URI reference is an URN in the publicid namespace it is converted into a public identifier by URN "unwrapping" as specified in the XML Catalogs specification and then resolution is performed following the semantics of external identifier resolution.

param
uri the URI to locate in the catalog
return
the mapped URI or null if no mapping was found in the catalog
throws
IOException if an i/o error occurred while reading the catalog


        if (fCatalogsChanged) {
            parseCatalogs();
            fCatalogsChanged = false;
        }
        return (fCatalog != null)
            ? fCatalog.resolveURI(uri) : null;
    
public final synchronized voidsetCatalogList(java.lang.String[] catalogs)

Sets the initial list of catalog entry files. If there were any catalog mappings cached from the previous list they will be replaced by catalog mappings from the new list the next time the catalog is queried.

param
catalogs an ordered array list of absolute URIs

        fCatalogsChanged = true;
        fCatalogsList = (catalogs != null)
            ? (String[]) catalogs.clone() : null;
    
public final voidsetPreferPublic(boolean preferPublic)

Sets the preference for whether system or public matches are preferred. This is used in the absence of any occurrence of the prefer attribute on the catalog entry of a catalog.

param
preferPublic the prefer public setting

        fPreferPublic = preferPublic;
        fResolverCatalogManager.setPreferPublic(preferPublic);
    
public final voidsetUseLiteralSystemId(boolean useLiteralSystemId)

Sets the preference for whether the literal system identifier should be used when resolving system identifiers when both it and the expanded system identifier are available.

The literal system identifier is the URI as it was provided before absolutization. It may be embedded within an entity. It may be provided externally or it may be the result of redirection. For example, redirection may have come from the protocol level through HTTP or from an application's entity resolver.

The expanded system identifier is an absolute URI which is the result of resolving the literal system identifier against a base URI.

param
useLiteralSystemId the preference for using literal system identifiers for catalog resolution

        fUseLiteralSystemId = useLiteralSystemId;