/* * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * */ package org.biojava.bio.program.sax; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.DTDHandler; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; /** * An abstract convenience baseclass implementing the * org.xml.sax.XMLReader interface (i.e. SAX2) that application * writers can inherit from when writing SAX2 compliant * parsers that take non-XML input, and send SAX2 messages * to XML ContentHandlers. *

* Note to application writers - support for namespaces may be flaky * in some instances. Namespace support is expected to work properly * for generating events according to DTDs that use explicit namespaces * for all elements. This is because start/end of Prefix Mapping * events are currently not handled properly (at all!). *

* The class provides the following: *

*

* The implementation of the org.xml.sax.XMLReader. interface * provides working implementation of the following method(s) *

* and default, do-nothing implementations of other methods * in the interface. *

* Non-interface methods are functional utility methods to help * application writers. For example, see the source of * org.biojava.bio.program.sax.BlastLikeSAXParser * for an example of how these utility methods can be used. *

* Copyright © 2000 Cambridge Antibody Technology Group plc. *

* Primary author -

* Other authors - * * This code was first released to the biojava.org project, July 2000. * * @author Cambridge Antibody Technology Group plc (CAT) * @version 1.1 * * @see BlastLikeSAXParser */ abstract class AbstractNativeAppSAXParser implements org.xml.sax.XMLReader, NamespaceConfigurationIF { private HashMap oPrefixMap = new HashMap(); protected ContentHandler oHandler = null; protected boolean tNamespaces = true; protected boolean tNamespacePrefixes = false; protected String oNamespacePrefix = ""; protected String oFullNamespacePrefix = ""; protected int iState; /** * Allow an application to register a content event handler. * If the application does not register a content handler, all content * events reported by the SAX parser will be silently ignored. *

* Applications may register a new or different handler in the * middle of a parse, and the SAX parser must begin using the * new handler immediately. * * @param poHandler a ContentHandler The XML content handler * * @throws java.lang.NullPointerException If the handler argument is null */ public void setContentHandler(ContentHandler poHandler) { if (poHandler == null) { throw new java.lang.NullPointerException("ContentHandler is null"); } oHandler = poHandler; } /** * Return the content handler. * * @return a ContentHandler The current content handler, * or null if none has been registered. */ public ContentHandler getContentHandler() { return oHandler; } /** * Do-nothing implementation of interface method * */ public void parse(InputSource input) throws java.io.IOException, SAXException { } /** * Full implementation of interface method. */ public void parse(java.lang.String poSystemId) throws java.io.IOException, SAXException { this.parse(new InputSource(poSystemId)); } /** * Do-nothing implementation of interface method * */ public boolean getFeature(String poName) throws SAXNotRecognizedException,SAXNotSupportedException { //if get here, throw exception throw (new SAXNotSupportedException("The feature \"" + poName + "\" is not supported "+ "in the biojava native SAX2 parsing framework.")); } /** * Handles support for ReasoningDomain and Namespace-prefixes * */ public void setFeature(java.lang.String poName, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { //handle namespaces if (poName.equals("http://xml.org/sax/features/namespaces")) { this.setNamespaces(value); //check if features combination is supported if ((!this.getNamespaces()) && (!this.getNamespacePrefixes())) { throw (new SAXNotSupportedException( "Illegal feature combination")); } return; } if (poName.equals("http://xml.org/sax/features/namespace-prefixes")) { this.setNamespacePrefixes(value); if ((!this.getNamespaces()) && (!this.getNamespacePrefixes())) { throw (new SAXNotSupportedException( "Illegal feature combination")); } return; } //if get here, throw exception throw (new SAXNotSupportedException("The feature \"" + poName + "\" is not supported "+ "in the biojava native SAX2 parsing framework.")); } /** * Do-nothing implementation of interface method * */ public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { throw (new SAXNotSupportedException("This method is not supported" + "in the biojava native SAX2 parser.")); } /** * Do-nothing implementation of interface method * */ public void setProperty(java.lang.String name, java.lang.Object value) throws SAXNotRecognizedException, SAXNotSupportedException { throw (new SAXNotSupportedException("This method is not supported"+ "in the biojava native SAX2 parser.")); } /** * Do-nothing implementation of interface method * */ public void setEntityResolver(EntityResolver resolver) { } /** * Do-nothing implementation of interface method * */ public EntityResolver getEntityResolver() { return null; } /** * Do-nothing implementation of interface method * */ public void setDTDHandler(DTDHandler handler) { } /** * Do-nothing implementation of interface method * */ public DTDHandler getDTDHandler() { return null; } /** * Do-nothing implementation of interface method * */ public void setErrorHandler(ErrorHandler handler) { } /** * Do-nothing implementation of interface method * */ public ErrorHandler getErrorHandler() { return null; } //---------------------------------------- /** * Utility method to centralize sending of a SAX * startElement message to document handler * * @param poQName a QName value * @param atts an Attributes value * @exception SAXException if an error occurs */ protected void startElement(QName poQName, Attributes atts) throws SAXException{ oHandler.startElement(poQName.getURI(), poQName.getLocalName(), poQName.getQName(),atts); } /** * Utility method to centralize the sending of a SAX endElement * message a document handler. * * @param poQName - * @exception SAXException thrown if * @exception thrown if */ protected void endElement(QName poQName) throws SAXException { oHandler.endElement(poQName.getURI(), poQName.getLocalName(), poQName.getQName()); } /** * Utility method to centralize the sending of a SAX characters * message a document handler. * * @param ch - * @param start - * @param length - * @exception SAXException thrown if * @exception thrown if */ protected void characters(char []ch, int start, int length) throws SAXException { oHandler.characters(ch,start,length); } /** * Support SAX2 configuration of namespace support of parser. */ private void setNamespaces(boolean ptNamespaces) { tNamespaces = ptNamespaces; } /** * Support SAX2 configuration of namespace support of parser. */ public boolean getNamespaces() { return tNamespaces; } /** * Support SAX2 configuration of namespace support of parser. */ private void setNamespacePrefixes(boolean ptNamespacePrefixes) { tNamespacePrefixes = ptNamespacePrefixes; } /** * Support SAX2 configuration of namespace support of parser. */ public boolean getNamespacePrefixes() { return tNamespacePrefixes; } /** * Adds a namespace prefix to URI mapping as (key,value) pairs. * This mapping can be looked up later to get URIs on request * using the getURIFromPrefix method. * * @param poPrefix a String representation of the * namespace prefix * @param poURI a String representation of the URI * for the namespace prefix. * */ public void addPrefixMapping(String poPrefix, String poURI) { oPrefixMap.put(poPrefix,poURI); } /** * Gets the URI for a namespace prefix, given that prefix, * or null if the prefix is not recognised. * * @param poPrefix a String The namespace prefix. */ public String getURIFromPrefix(String poPrefix) { if (oPrefixMap.containsKey(poPrefix)) { return (String)oPrefixMap.get(poPrefix); } else { //return an empty string, null makes XSLT processors unhappy return ""; } } /** * * @param poPrefix a String value */ public void setNamespacePrefix(String poPrefix) { oNamespacePrefix = poPrefix; oFullNamespacePrefix = oNamespacePrefix.concat(":"); } /** * Describe getNamespacePrefix method here. * * @return a String value */ public String getNamespacePrefix() { return oNamespacePrefix; } /** * Given an unprefixed element name, returns * a new element name with a namespace prefix * * @return a String value */ public String prefix(String poElementName) { return oFullNamespacePrefix.concat(poElementName); } /** * Create a stream from an an InputSource, picking the * correct stream according to order of precedance. * * @param poSource an InputSource value * @return a BufferedReader value */ protected BufferedReader getContentStream(InputSource poSource) { InputSource oSource; BufferedReader oContents; int iBuffSize = 8192; oSource = poSource; //Check contents InputSource in order of precedence //Highest - Character stream if (oSource.getCharacterStream() != null) { oContents = new BufferedReader(oSource.getCharacterStream(), iBuffSize); return oContents; } //Next to lowest - Byte stream if ( (oSource.getByteStream() != null) ) { oContents = new BufferedReader( new InputStreamReader(oSource.getByteStream()), iBuffSize); return oContents; } //Lowest precedence - System URI if ( (oSource.getSystemId() != null) ) { try { //URL handles file URI's and URL's, which might be sent in //by an XSLT processor. Handles things like file:\C:\file.txt URL IORUrl = new java.net.URL(oSource.getSystemId()); BufferedInputStream inStr = new BufferedInputStream(IORUrl.openStream()); // Create input stream oContents = new BufferedReader(new InputStreamReader(inStr), iBuffSize); return oContents; //catch Malfromed URL and IOException } catch (MalformedURLException x) { System.out.println(x.getMessage()); System.out.println("Couldn't open file"); System.exit(0); } catch (IOException x) { System.out.println(x.getMessage()); System.out.println("Couldn't open file"); System.exit(0); } } //should throw an exception to say couldn't get stream return null; } /** * Centralise chaining of iState field to help * with debugging. E.g. printing out value etc. * All changes to iState should be made through this method. * * @param piState an int value */ protected void changeState(int piState) { iState = piState; } }