saxcatalogreader.java

来自「JAVA 所有包」· Java 代码 · 共 504 行

JAVA
504
字号
// SAXCatalogReader.java - Read XML Catalog files/* * Copyright 2001-2004 The Apache Software Foundation or its licensors, * as applicable. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.sun.org.apache.xml.internal.resolver.readers;import java.util.Hashtable;import java.io.IOException;import java.io.FileNotFoundException;import java.io.InputStream;import java.net.URL;import java.net.URLConnection;import java.net.MalformedURLException;import java.net.UnknownHostException;import javax.xml.parsers.ParserConfigurationException;import javax.xml.parsers.SAXParserFactory;import javax.xml.parsers.SAXParser;import org.xml.sax.AttributeList;import org.xml.sax.Attributes;import org.xml.sax.ContentHandler;import org.xml.sax.DocumentHandler;import org.xml.sax.EntityResolver;import org.xml.sax.InputSource;import org.xml.sax.Locator;import org.xml.sax.Parser;import org.xml.sax.SAXException;import com.sun.org.apache.xml.internal.resolver.Catalog;import com.sun.org.apache.xml.internal.resolver.CatalogManager;import com.sun.org.apache.xml.internal.resolver.CatalogException;import com.sun.org.apache.xml.internal.resolver.readers.CatalogReader;import com.sun.org.apache.xml.internal.resolver.helpers.Debug;/** * A SAX-based CatalogReader. * * <p>This class is used to read XML Catalogs using the SAX. This reader * has an advantage over the DOM-based reader in that it functions on * the stream of SAX events. It has the disadvantage * that it cannot look around in the tree.</p> * * <p>Since the choice of CatalogReaders (in the InputStream case) can only * be made on the basis of MIME type, the following problem occurs: only * one CatalogReader can exist for all XML mime types. In order to get * around this problem, the SAXCatalogReader relies on a set of external * CatalogParsers to actually build the catalog.</p> * * <p>The selection of CatalogParsers is made on the basis of the QName * of the root element of the document.</p> * * @see Catalog * @see CatalogReader * @see SAXCatalogReader * @see TextCatalogReader * @see DOMCatalogParser * * @author Norman Walsh * <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a> * * @version 1.0 */public class SAXCatalogReader implements CatalogReader, ContentHandler, DocumentHandler {  /** The SAX Parser Factory */  protected SAXParserFactory parserFactory = null;  /** The SAX Parser Class */  protected String parserClass = null;  /**     * Mapping table from QNames to CatalogParser classes.     *     * <p>Each key in this hash table has the form "elementname"     * or "{namespaceuri}elementname". The former is used if the     * namespace URI is null.</p>     */  protected Hashtable namespaceMap = new Hashtable();  /** The parser in use for the current catalog. */  private SAXCatalogParser saxParser = null;  /** Set if something goes horribly wrong. It allows the class to     * ignore the rest of the events that are received.     */  private boolean abandonHope = false;  /** The Catalog that we're working for. */  private Catalog catalog;  /** Set the XML SAX Parser Factory.   */  public void setParserFactory(SAXParserFactory parserFactory) {    this.parserFactory = parserFactory;  }  /** Set the XML SAX Parser Class   */  public void setParserClass(String parserClass) {    this.parserClass = parserClass;  }  /** Get the parser factory currently in use. */  public SAXParserFactory getParserFactory() {    return parserFactory;  }  /** Get the parser class currently in use. */  public String getParserClass() {    return parserClass;  }  /** The debug class to use for this reader.   *   * This is a bit of a hack. Anyway, whenever we read for a catalog,   * we extract the debug object   * from the catalog's manager so that we can use it to print messages.   *   * In production, we don't really expect any messages so it doesn't   * really matter. But it's still a bit of a hack.   */  protected Debug debug = CatalogManager.getStaticManager().debug;  /** The constructor */  public SAXCatalogReader() {    parserFactory = null;    parserClass = null;  }  /** The constructor */  public SAXCatalogReader(SAXParserFactory parserFactory) {    this.parserFactory = parserFactory;  }  /** The constructor */  public SAXCatalogReader(String parserClass) {    this.parserClass = parserClass;  }  /** Set the SAXCatalogParser class for the given namespace/root     * element type.     */  public void setCatalogParser(String namespaceURI,			       String rootElement,			       String parserClass) {    if (namespaceURI == null) {      namespaceMap.put(rootElement, parserClass);    } else {      namespaceMap.put("{"+namespaceURI+"}"+rootElement, parserClass);    }  }  /** Get the SAXCatalogParser class for the given namespace/root     * element type.     */  public String getCatalogParser(String namespaceURI,				 String rootElement) {    if (namespaceURI == null) {      return (String) namespaceMap.get(rootElement);    } else {      return (String) namespaceMap.get("{"+namespaceURI+"}"+rootElement);    }  }  /**   * Parse an XML Catalog file.   *   * @param catalog The catalog to which this catalog file belongs   * @param fileUrl The URL or filename of the catalog file to process   *   * @throws MalformedURLException Improper fileUrl   * @throws IOException Error reading catalog file   */  public void readCatalog(Catalog catalog, String fileUrl)    throws MalformedURLException, IOException,	   CatalogException {    URL url = null;    try {      url = new URL(fileUrl);    } catch (MalformedURLException e) {      url = new URL("file:///" + fileUrl);    }    debug = catalog.getCatalogManager().debug;    try {      URLConnection urlCon = url.openConnection();      readCatalog(catalog, urlCon.getInputStream());    } catch (FileNotFoundException e) {      catalog.getCatalogManager().debug.message(1, "Failed to load catalog, file not found",		    url.toString());    }  }  /**   * Parse an XML Catalog stream.   *   * @param catalog The catalog to which this catalog file belongs   * @param is The input stream from which the catalog will be read   *   * @throws MalformedURLException Improper fileUrl   * @throws IOException Error reading catalog file   * @throws CatalogException A Catalog exception   */  public void readCatalog(Catalog catalog, InputStream is)     throws IOException, CatalogException {    // Create an instance of the parser    if (parserFactory == null && parserClass == null) {      debug.message(1, "Cannot read SAX catalog without a parser");      throw new CatalogException(CatalogException.UNPARSEABLE);    }    debug = catalog.getCatalogManager().debug;    EntityResolver bResolver = catalog.getCatalogManager().getBootstrapResolver();    this.catalog = catalog;    try {      if (parserFactory != null) {	SAXParser parser = parserFactory.newSAXParser();	SAXParserHandler spHandler = new SAXParserHandler();	spHandler.setContentHandler(this);	if (bResolver != null) {	  spHandler.setEntityResolver(bResolver);	}	parser.parse(new InputSource(is), spHandler);      } else {	Parser parser = (Parser) Class.forName(parserClass).newInstance();	parser.setDocumentHandler(this);	if (bResolver != null) {	  parser.setEntityResolver(bResolver);	}	parser.parse(new InputSource(is));      }    } catch (ClassNotFoundException cnfe) {      throw new CatalogException(CatalogException.UNPARSEABLE);    } catch (IllegalAccessException iae) {      throw new CatalogException(CatalogException.UNPARSEABLE);    } catch (InstantiationException ie) {      throw new CatalogException(CatalogException.UNPARSEABLE);    } catch (ParserConfigurationException pce) {      throw new CatalogException(CatalogException.UNKNOWN_FORMAT);    } catch (SAXException se) {      Exception e = se.getException();      // FIXME: there must be a better way      UnknownHostException uhe = new UnknownHostException();      FileNotFoundException fnfe = new FileNotFoundException();      if (e != null) {	if (e.getClass() == uhe.getClass()) {	  throw new CatalogException(CatalogException.PARSE_FAILED,				     e.toString());	} else if (e.getClass() == fnfe.getClass()) {	  throw new CatalogException(CatalogException.PARSE_FAILED,				     e.toString());	}      }      throw new CatalogException(se);    }  }  // ----------------------------------------------------------------------  // Implement the SAX ContentHandler interface  /** The SAX <code>setDocumentLocator</code> method. Does nothing. */  public void setDocumentLocator (Locator locator) {    if (saxParser != null) {      saxParser.setDocumentLocator(locator);    }  }  /** The SAX <code>startDocument</code> method. Does nothing. */  public void startDocument () throws SAXException {    saxParser = null;    abandonHope = false;    return;  }  /** The SAX <code>endDocument</code> method. Does nothing. */  public void endDocument ()throws SAXException {    if (saxParser != null) {      saxParser.endDocument();    }  }  /**   * The SAX <code>startElement</code> method.   *   * <p>The catalog parser is selected based on the namespace of the   * first element encountered in the catalog.</p>   */  public void startElement (String name,			    AttributeList atts)    throws SAXException {    if (abandonHope) {      return;    }    if (saxParser == null) {      String prefix = "";      if (name.indexOf(':') > 0) {	prefix = name.substring(0, name.indexOf(':'));      }      String localName = name;      if (localName.indexOf(':') > 0) {	localName = localName.substring(localName.indexOf(':')+1);      }      String namespaceURI = null;      if (prefix.equals("")) {	namespaceURI = atts.getValue("xmlns");      } else {	namespaceURI = atts.getValue("xmlns:" + prefix);      }      String saxParserClass = getCatalogParser(namespaceURI,					       localName);      if (saxParserClass == null) {	abandonHope = true;	if (namespaceURI == null) {	  debug.message(2, "No Catalog parser for " + name);	} else {	  debug.message(2, "No Catalog parser for "			+ "{" + namespaceURI + "}"			+ name);	}	return;      }      try {	saxParser = (SAXCatalogParser)	  Class.forName(saxParserClass).newInstance();	saxParser.setCatalog(catalog);	saxParser.startDocument();	saxParser.startElement(name, atts);      } catch (ClassNotFoundException cnfe) {	saxParser = null;	abandonHope = true;	debug.message(2, cnfe.toString());      } catch (InstantiationException ie) {	saxParser = null;	abandonHope = true;	debug.message(2, ie.toString());      } catch (IllegalAccessException iae) {	saxParser = null;	abandonHope = true;	debug.message(2, iae.toString());      } catch (ClassCastException cce ) {	saxParser = null;	abandonHope = true;	debug.message(2, cce.toString());      }    } else {      saxParser.startElement(name, atts);    }  }  /**   * The SAX2 <code>startElement</code> method.   *   * <p>The catalog parser is selected based on the namespace of the   * first element encountered in the catalog.</p>   */  public void startElement (String namespaceURI,			    String localName,			    String qName,			    Attributes atts)    throws SAXException {    if (abandonHope) {      return;    }    if (saxParser == null) {      String saxParserClass = getCatalogParser(namespaceURI,					       localName);      if (saxParserClass == null) {	abandonHope = true;	if (namespaceURI == null) {	  debug.message(2, "No Catalog parser for " + localName);	} else {	  debug.message(2, "No Catalog parser for "			+ "{" + namespaceURI + "}"			+ localName);	}	return;      }      try {	saxParser = (SAXCatalogParser)	  Class.forName(saxParserClass).newInstance();	saxParser.setCatalog(catalog);	saxParser.startDocument();	saxParser.startElement(namespaceURI, localName, qName, atts);      } catch (ClassNotFoundException cnfe) {	saxParser = null;	abandonHope = true;	debug.message(2, cnfe.toString());      } catch (InstantiationException ie) {	saxParser = null;	abandonHope = true;	debug.message(2, ie.toString());      } catch (IllegalAccessException iae) {	saxParser = null;	abandonHope = true;	debug.message(2, iae.toString());      } catch (ClassCastException cce ) {	saxParser = null;	abandonHope = true;	debug.message(2, cce.toString());      }    } else {      saxParser.startElement(namespaceURI, localName, qName, atts);    }  }  /** The SAX <code>endElement</code> method. Does nothing. */  public void endElement (String name) throws SAXException {    if (saxParser != null) {      saxParser.endElement(name);    }  }  /** The SAX2 <code>endElement</code> method. Does nothing. */  public void endElement (String namespaceURI,			  String localName,			  String qName) throws SAXException {    if (saxParser != null) {      saxParser.endElement(namespaceURI, localName, qName);    }  }  /** The SAX <code>characters</code> method. Does nothing. */  public void characters (char ch[], int start, int length)    throws SAXException {    if (saxParser != null) {      saxParser.characters(ch, start, length);    }  }  /** The SAX <code>ignorableWhitespace</code> method. Does nothing. */  public void ignorableWhitespace (char ch[], int start, int length)    throws SAXException {    if (saxParser != null) {      saxParser.ignorableWhitespace(ch, start, length);    }  }  /** The SAX <code>processingInstruction</code> method. Does nothing. */  public void processingInstruction (String target, String data)    throws SAXException {    if (saxParser != null) {      saxParser.processingInstruction(target, data);    }  }  /** The SAX <code>startPrefixMapping</code> method. Does nothing. */  public void startPrefixMapping (String prefix, String uri)    throws SAXException {    if (saxParser != null) {      saxParser.startPrefixMapping (prefix, uri);    }  }  /** The SAX <code>endPrefixMapping</code> method. Does nothing. */  public void endPrefixMapping (String prefix)    throws SAXException {    if (saxParser != null) {      saxParser.endPrefixMapping (prefix);    }  }  /** The SAX <code>skippedentity</code> method. Does nothing. */  public void skippedEntity (String name)    throws SAXException {    if (saxParser != null) {      saxParser.skippedEntity(name);    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?