FileDocCategorySizeDatePackage
Resolver.javaAPI DocJava SE 6 API21873Tue Jun 10 00:22:58 BST 2008com.sun.org.apache.xml.internal.resolver

Resolver

public class Resolver extends Catalog
An extension to OASIS Open Catalog files, this class supports suffix-based matching and an external RFC2483 resolver.
see
Catalog
author
Norman Walsh Norman.Walsh@Sun.COM
version
1.0

Fields Summary
public static final int
URISUFFIX
The URISUFFIX Catalog Entry type.

URI suffix entries match URIs that end in a specified suffix.

public static final int
SYSTEMSUFFIX
The SYSTEMSUFFIX Catalog Entry type.

System suffix entries match system identifiers that end in a specified suffix.

public static final int
RESOLVER
The RESOLVER Catalog Entry type.

A hook for providing support for web-based backup resolvers.

public static final int
SYSTEMREVERSE
The SYSTEMREVERSE Catalog Entry type.

This is a bit of a hack. There's no actual SYSTEMREVERSE entry, but this entry type is used to indicate that a reverse lookup is being performed. (This allows the Resolver to implement RFC2483 I2N and I2NS.)

Constructors Summary
Methods Summary
public voidaddEntry(com.sun.org.apache.xml.internal.resolver.CatalogEntry entry)
Cleanup and process a Catalog entry.

This method processes each Catalog entry, changing mapped relative system identifiers into absolute ones (based on the current base URI), and maintaining other information about the current catalog.

param
entry The CatalogEntry to process.

    int type = entry.getEntryType();

    if (type == URISUFFIX) {
      String suffix = normalizeURI(entry.getEntryArg(0));
      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));

      entry.setEntryArg(1, fsi);

      catalogManager.debug.message(4, "URISUFFIX", suffix, fsi);
    } else if (type == SYSTEMSUFFIX) {
      String suffix = normalizeURI(entry.getEntryArg(0));
      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));

      entry.setEntryArg(1, fsi);

      catalogManager.debug.message(4, "SYSTEMSUFFIX", suffix, fsi);
    }

    super.addEntry(entry);
  
private java.util.VectorappendVector(java.util.Vector vec, java.util.Vector appvec)
Append two vectors, returning the result.

param
vec The first vector
param
appvec The vector to be appended
return
The vector vec, with appvec's elements appended to it

	if (appvec != null) {
	    for (int count = 0; count < appvec.size(); count++) {
		vec.addElement(appvec.elementAt(count));
	    }
	}
	return vec;
    
protected com.sun.org.apache.xml.internal.resolver.ResolverqueryResolver(java.lang.String resolver, java.lang.String command, java.lang.String arg1, java.lang.String arg2)
Query an external RFC2483 resolver.

param
resolver The URL of the RFC2483 resolver.
param
command The command to send the resolver.
param
arg1 The first argument to the resolver.
param
arg2 The second argument to the resolver, usually null.
return
The Resolver constructed.

	InputStream iStream = null;
	String RFC2483 = resolver + "?command=" + command 
	    + "&format=tr9401&uri=" + arg1 
	    + "&uri2=" + arg2;
	String line = null;

	try {
	    URL url = new URL(RFC2483);

	    URLConnection urlCon = url.openConnection();

	    urlCon.setUseCaches(false);

	    Resolver r = (Resolver) newCatalog();

	    String cType = urlCon.getContentType();

	    // I don't care about the character set or subtype
	    if (cType.indexOf(";") > 0) {
		cType = cType.substring(0, cType.indexOf(";"));
	    }

	    r.parseCatalog(cType, urlCon.getInputStream());

	    return r;
	} catch (CatalogException cex) {
	  if (cex.getExceptionType() == CatalogException.UNPARSEABLE) {
	    catalogManager.debug.message(1, "Unparseable catalog: " + RFC2483);
	  } else if (cex.getExceptionType()
		     == CatalogException.UNKNOWN_FORMAT) {
	    catalogManager.debug.message(1, "Unknown catalog format: " + RFC2483);
	  }
	  return null;
	} catch (MalformedURLException mue) {
	    catalogManager.debug.message(1, "Malformed resolver URL: " + RFC2483);
	    return null;
	} catch (IOException ie) {
	    catalogManager.debug.message(1, "I/O Exception opening resolver: " + RFC2483);
	    return null;
	}
    
private java.util.VectorresolveAllLocalSystem(java.lang.String systemId)
Return all applicable SYSTEM system identifiers in this catalog.

If one or more SYSTEM entries exists in the catalog file for the system ID specified, return the mapped values.

param
systemId The system ID to locate in the catalog
return
A vector of the mapped system identifiers or null

	Vector map = new Vector();
	String osname = System.getProperty("os.name");
	boolean windows = (osname.indexOf("Windows") >= 0);
	Enumeration en = catalogEntries.elements();
	while (en.hasMoreElements()) {
	    CatalogEntry e = (CatalogEntry) en.nextElement();
	    if (e.getEntryType() == SYSTEM
		&& (e.getEntryArg(0).equals(systemId)
		    || (windows
			&& e.getEntryArg(0).equalsIgnoreCase(systemId)))) {
		map.addElement(e.getEntryArg(1));
	    }
	}
	if (map.size() == 0) {
	    return null;
	} else {
	    return map;
	}
    
private synchronized java.util.VectorresolveAllSubordinateCatalogs(int entityType, java.lang.String entityName, java.lang.String publicId, java.lang.String systemId)
Search the subordinate catalogs, in order, looking for all match.

This method searches the Catalog and returns all of the system identifiers specified for the given entity type with the given name, public, and system identifiers. In some contexts, these may be null.

param
entityType The CatalogEntry type for which this query is being conducted. This is necessary in order to do the approprate query on a subordinate catalog.
param
entityName The name of the entity being searched for, if appropriate.
param
publicId The public identifier of the entity in question (as provided in the source document).
param
systemId The nominal system identifier for the entity in question (as provided in the source document).
throws
MalformedURLException The formal system identifier of a delegated catalog cannot be turned into a valid URL.
throws
IOException Error reading delegated catalog file.
return
The system identifier to use. Note that the nominal system identifier is not returned if a match is not found in the catalog, instead null is returned to indicate that no match was found.


	Vector resolutions = new Vector();

	for (int catPos = 0; catPos < catalogs.size(); catPos++) {
	    Resolver c = null;

	    try {
		c = (Resolver) catalogs.elementAt(catPos);
	    } catch (ClassCastException e) {
		String catfile = (String) catalogs.elementAt(catPos);
		c = (Resolver) newCatalog();

		try {
		    c.parseCatalog(catfile);
		} catch (MalformedURLException mue) {
		    catalogManager.debug.message(1, "Malformed Catalog URL", catfile);
		} catch (FileNotFoundException fnfe) {
		    catalogManager.debug.message(1, "Failed to load catalog, file not found",
			  catfile);
		} catch (IOException ioe) {
		    catalogManager.debug.message(1, "Failed to load catalog, I/O error", catfile);
		}

		catalogs.setElementAt(c, catPos);
	    }

	    String resolved = null;

	    // Ok, now what are we supposed to call here?
	    if (entityType == DOCTYPE) {
		resolved = c.resolveDoctype(entityName,
					    publicId,
					    systemId);
		if (resolved != null) {
		    // Only find one DOCTYPE resolution
		    resolutions.addElement(resolved);
		    return resolutions;
		}
	    } else if (entityType == DOCUMENT) {
		resolved = c.resolveDocument();
		if (resolved != null) {
		    // Only find one DOCUMENT resolution
		    resolutions.addElement(resolved);
		    return resolutions;
		}
	    } else if (entityType == ENTITY) {
		resolved = c.resolveEntity(entityName,
					   publicId,
					   systemId);
		if (resolved != null) {
		    // Only find one ENTITY resolution
		    resolutions.addElement(resolved);
		    return resolutions;
		}
	    } else if (entityType == NOTATION) {
		resolved = c.resolveNotation(entityName,
					     publicId,
					     systemId);
		if (resolved != null) {
		    // Only find one NOTATION resolution
		    resolutions.addElement(resolved);
		    return resolutions;
		}
	    } else if (entityType == PUBLIC) {
		resolved = c.resolvePublic(publicId, systemId);
		if (resolved != null) {
		    // Only find one PUBLIC resolution
		    resolutions.addElement(resolved);
		    return resolutions;
		}
	    } else if (entityType == SYSTEM) {
		Vector localResolutions = c.resolveAllSystem(systemId);
		resolutions = appendVector(resolutions, localResolutions);
		break;
	    } else if (entityType == SYSTEMREVERSE) {
		Vector localResolutions = c.resolveAllSystemReverse(systemId);
		resolutions = appendVector(resolutions, localResolutions);
	    }
	}

	if (resolutions != null) {
	    return resolutions;
	} else {
	    return null;
	}
    
public java.util.VectorresolveAllSystem(java.lang.String systemId)
Return the applicable SYSTEM system identifiers.

If one or more SYSTEM entries exists in the Catalog for the system ID specified, return the mapped values.

The caller is responsible for doing any necessary normalization of the system identifier before calling this method. For example, a relative system identifier in a document might be converted to an absolute system identifier before attempting to resolve it.

Note that this function will force all subordinate catalogs to be loaded.

On Windows-based operating systems, the comparison between the system identifier provided and the SYSTEM entries in the Catalog is case-insensitive.

param
systemId The system ID to locate in the catalog.
return
The system identifier to use for the notation.
throws
MalformedURLException The formal system identifier of a subordinate catalog cannot be turned into a valid URL.
throws
IOException Error reading subordinate catalog file.

	Vector resolutions = new Vector();

	// If there are SYSTEM entries in this catalog, start with them
	if (systemId != null) {
	    Vector localResolutions = resolveAllLocalSystem(systemId);
	    resolutions = appendVector(resolutions, localResolutions);
	}

	// Then look in the subordinate catalogs
	Vector subResolutions = resolveAllSubordinateCatalogs(SYSTEM,
							      null,
							      null,
							      systemId);
	resolutions = appendVector(resolutions, subResolutions);

	if (resolutions.size() > 0) {
	    return resolutions;
	} else {
	    return null;
	}
    
public java.util.VectorresolveAllSystemReverse(java.lang.String systemId)
Find the URNs for a given system identifier in all catalogs.

param
systemId The system ID to locate.
return
A vector of URNs that map to the systemId.

	Vector resolved = new Vector();

	// If there's a SYSTEM entry in this catalog, use it
	if (systemId != null) {
	    Vector localResolved = resolveLocalSystemReverse(systemId);
	    resolved = appendVector(resolved, localResolved);
	}

	// Otherwise, look in the subordinate catalogs
	Vector subResolved = resolveAllSubordinateCatalogs(SYSTEMREVERSE,
							   null,
							   null,
							   systemId);

	return appendVector(resolved, subResolved);
    
protected java.lang.StringresolveExternalPublic(java.lang.String publicId, java.lang.String resolver)
Query an external RFC2483 resolver for a public identifier.

param
publicId The system ID to locate.
param
resolver The name of the resolver to use.
return
The system identifier to use for the systemId.

	Resolver r = queryResolver(resolver, "fpi2l", publicId, null);
	if (r != null) {
	    return r.resolvePublic(publicId, null);
	} else {
	    return null;
	}
    
protected java.lang.StringresolveExternalSystem(java.lang.String systemId, java.lang.String resolver)
Query an external RFC2483 resolver for a system identifier.

param
systemId The system ID to locate.
param
resolver The name of the resolver to use.
return
The system identifier to use for the systemId.

	Resolver r = queryResolver(resolver, "i2l", systemId, null);
	if (r != null) {
	    return r.resolveSystem(systemId);
	} else {
	    return null;
	}
    
private java.util.VectorresolveLocalSystemReverse(java.lang.String systemId)
Find the URNs for a given system identifier in the current catalog.

param
systemId The system ID to locate.
return
A vector of URNs that map to the systemId.

	Vector map = new Vector();
	String osname = System.getProperty("os.name");
	boolean windows = (osname.indexOf("Windows") >= 0);
	Enumeration en = catalogEntries.elements();
	while (en.hasMoreElements()) {
	    CatalogEntry e = (CatalogEntry) en.nextElement();
	    if (e.getEntryType() == SYSTEM
		&& (e.getEntryArg(1).equals(systemId)
		    || (windows
			&& e.getEntryArg(1).equalsIgnoreCase(systemId)))) {
		map.addElement(e.getEntryArg(0));
	    }
	}
	if (map.size() == 0) {
	    return null;
	} else {
	    return map;
	}
    
public java.lang.StringresolvePublic(java.lang.String publicId, java.lang.String systemId)
Return the applicable PUBLIC or SYSTEM identifier, resorting to external resolvers if necessary.

This method searches the Catalog and returns the system identifier specified for the given system or public identifiers. If no appropriate PUBLIC or SYSTEM entry is found in the Catalog, null is returned.

Note that a system or public identifier in the current catalog (or subordinate catalogs) will be used in preference to an external resolver. Further, if a systemId is present, the external resolver(s) will be queried for that before the publicId.

param
publicId The public identifier to locate in the catalog. Public identifiers are normalized before comparison.
param
systemId The nominal system identifier for the entity in question (as provided in the source document).
throws
MalformedURLException The formal system identifier of a subordinate catalog cannot be turned into a valid URL.
throws
IOException Error reading subordinate catalog file.
return
The system identifier to use. Note that the nominal system identifier is not returned if a match is not found in the catalog, instead null is returned to indicate that no match was found.


    String resolved = super.resolvePublic(publicId, systemId);
    if (resolved != null) {
      return resolved;
    }

    Enumeration en = catalogEntries.elements();
    while (en.hasMoreElements()) {
      CatalogEntry e = (CatalogEntry) en.nextElement();
      if (e.getEntryType() == RESOLVER) {
	if (systemId != null) {
	  resolved = resolveExternalSystem(systemId,
					   e.getEntryArg(0));
	  if (resolved != null) {
	    return resolved;
	  }
	}
	resolved = resolveExternalPublic(publicId, e.getEntryArg(0));
	if (resolved != null) {
	  return resolved;
	}
      }
    }

    return resolveSubordinateCatalogs(Catalog.PUBLIC,
				      null,
				      publicId,
				      systemId);
  
public java.lang.StringresolveSystem(java.lang.String systemId)
Return the applicable SYSTEM system identifier, resorting to external RESOLVERs if necessary.

If a SYSTEM entry exists in the Catalog for the system ID specified, return the mapped value.

In the Resolver (as opposed to the Catalog) class, if the URI isn't found by the usual algorithm, SYSTEMSUFFIX entries are considered.

On Windows-based operating systems, the comparison between the system identifier provided and the SYSTEM entries in the Catalog is case-insensitive.

param
systemId The system ID to locate in the catalog.
return
The system identifier to use for systemId.
throws
MalformedURLException The formal system identifier of a subordinate catalog cannot be turned into a valid URL.
throws
IOException Error reading subordinate catalog file.


    String resolved = super.resolveSystem(systemId);
    if (resolved != null) {
      return resolved;
    }

    Enumeration en = catalogEntries.elements();
    while (en.hasMoreElements()) {
      CatalogEntry e = (CatalogEntry) en.nextElement();
      if (e.getEntryType() == RESOLVER) {
	resolved = resolveExternalSystem(systemId, e.getEntryArg(0));
	if (resolved != null) {
	  return resolved;
	}
      } else if (e.getEntryType() == SYSTEMSUFFIX) {
	String suffix = e.getEntryArg(0);
	String result = e.getEntryArg(1);

	if (suffix.length() <= systemId.length()
	    && systemId.substring(systemId.length()-suffix.length()).equals(suffix)) {
	  return result;
	}
      }
    }

    return resolveSubordinateCatalogs(Catalog.SYSTEM,
				      null,
				      null,
				      systemId);
  
public java.lang.StringresolveSystemReverse(java.lang.String systemId)
Find the URN for a given system identifier.

param
systemId The system ID to locate.
return
A (single) URN that maps to the systemId.

	Vector resolved = resolveAllSystemReverse(systemId);
	if (resolved != null && resolved.size() > 0) {
	    return (String) resolved.elementAt(0);
	} else {
	    return null;
	}
    
public java.lang.StringresolveURI(java.lang.String uri)
Return the applicable URI.

If a URI entry exists in the Catalog for the URI specified, return the mapped value.

In the Resolver (as opposed to the Catalog) class, if the URI isn't found by the usual algorithm, URISUFFIX entries are considered.

URI comparison is case sensitive.

param
uri The URI to locate in the catalog.
return
The resolved URI.
throws
MalformedURLException The system identifier of a subordinate catalog cannot be turned into a valid URL.
throws
IOException Error reading subordinate catalog file.


    String resolved = super.resolveURI(uri);
    if (resolved != null) {
      return resolved;
    }

    Enumeration en = catalogEntries.elements();
    while (en.hasMoreElements()) {
      CatalogEntry e = (CatalogEntry) en.nextElement();
      if (e.getEntryType() == RESOLVER) {
	resolved = resolveExternalSystem(uri, e.getEntryArg(0));
	if (resolved != null) {
	  return resolved;
	}
      } else if (e.getEntryType() == URISUFFIX) {
	String suffix = e.getEntryArg(0);
	String result = e.getEntryArg(1);

	if (suffix.length() <= uri.length()
	    && uri.substring(uri.length()-suffix.length()).equals(suffix)) {
	  return result;
	}
      }
    }

    // Otherwise, look in the subordinate catalogs
    return resolveSubordinateCatalogs(Catalog.URI,
				      null,
				      null,
				      uri);
  
public voidsetupReaders()
Setup readers.


       
     
    SAXParserFactory spf = SAXParserFactory.newInstance();
    spf.setNamespaceAware(true);
    spf.setValidating(false);

    SAXCatalogReader saxReader = new SAXCatalogReader(spf);

    saxReader.setCatalogParser(null, "XMLCatalog",
			       "com.sun.org.apache.xml.internal.resolver.readers.XCatalogReader");

    saxReader.setCatalogParser(OASISXMLCatalogReader.namespaceName,
			       "catalog",
			       "com.sun.org.apache.xml.internal.resolver.readers.ExtendedXMLCatalogReader");

    addReader("application/xml", saxReader);

    TR9401CatalogReader textReader = new TR9401CatalogReader();
    addReader("text/plain", textReader);