package org.spaceroots.rkcheck;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.EntityResolver;
import org.xml.sax.SAXException;
import org.xml.sax.InputSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* This class implements a resolver for external entities that are
* cached locally in the same jar file as the application.
* @version $Id: EmbeddedCatalogResolver.java,v 1.1 2004/05/23 13:30:17 luc Exp $
* @author L. Maisonobe
*/
public class EmbeddedCatalogResolver
implements EntityResolver {
/** Simple constructor.
* Build an empty resolver.
* @param catalog catalog path (inside the jar)
* @param builder document builder (as a side effect, the builder
* will use the instance as its entity resolver)
*/
public EmbeddedCatalogResolver(String catalog, DocumentBuilder builder) {
int index = catalog.lastIndexOf('/');
if (index < 0) {
base = "";
catalogName = catalog;
} else {
base = catalog.substring(0, index + 1);
catalogName = catalog.substring(index + 1);
}
map = new HashMap();
this.builder = builder;
builder.setEntityResolver(this);
}
/** Get the resource associated with a public identifier
* @param publicId public identifier
* @return the resource name or null if the identifier is unknown
* @exception IOException if parsing the catalog throws one
* @exception SAXException if parsing the catalog throws one
*/
public String getResourceName(String publicId)
throws IOException, SAXException {
if (publicId.equals("-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN")) {
// special case, this should be handled BEFORE trying to
// parse the catalog, because it is needed during this parsing
// (this is a chicken and egg problem)
return base + "catalog.dtd";
}
if (map.isEmpty()) {
// read the catalog containing the entities mapping
parseCatalog();
}
// return the mapping we have for this entity, or null
return (String) map.get(publicId);
}
/** Parse the resources catalog.
* @exception SAXException if a parse error is encountered during
* catalog analysis
* @exception IOException if the catalog cannot be read
*/
private void parseCatalog()
throws SAXException, IOException {
// parse the catalog
InputStream is = getClass().getResourceAsStream(base + catalogName);
if (is == null) {
return;
}
Document document = builder.parse(is);
// build the map
for (Node child = document.getDocumentElement().getFirstChild();
child != null;
child = child.getNextSibling()) {
if ((child.getNodeType() == Node.ELEMENT_NODE)
&& (child.getNodeName().equals("public"))) {
String publicId = ((Element) child).getAttribute("publicId");
String uri = ((Element) child).getAttribute("uri");
if ((publicId != null) && (uri != null)) {
// store the publicId/uri mapping
// (adding the base prefix if uri is relative)
map.put(publicId, uri.startsWith("/") ? uri : (base + uri));
}
}
}
}
public InputSource resolveEntity (String publicId, String systemId)
throws SAXException {
try {
String resourceName = getResourceName(publicId);
if (resourceName != null) {
// the resource is cached locally in the jar
InputStream is = getClass().getResourceAsStream(resourceName);
return (is != null) ? new InputSource(is) : null;
} else {
// we did not find the resource,
// we let the parser use the default behaviour
return null;
}
} catch (IOException ioe) {
throw new SAXException(ioe);
}
}
/** Base directory (inside the jar file). */
String base;
/** Catalog name (in the base directory). */
String catalogName;
/** Document builder. */
DocumentBuilder builder;
/** Map for public identifiers. */
HashMap map;
}
Ads help maintain this website.