org.biojava.bio.program.sax.AbstractNativeAppSAXParser Maven / Gradle / Ivy
/*
* 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:
*
* - An implmentation of the org.xml.sax.XMLReader interface.
*
- Utilty methods for generating SAX messages.
*
*
* The implementation of the org.xml.sax.XMLReader. interface
* provides working implementation of the following method(s)
*
* - setContentHandler(ContentHandler handler)
*
- setFeature
*
- getFeature
*
* 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 -
* - Simon Brocklehurst (CAT)
*
* Other authors -
* - Tim Dilks (CAT)
*
- Colin Hardman (CAT)
*
- Stuart Johnston (CAT)
*
- Mathieu Wiepert (Mayo Foundation)
*
*
* 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;
}
}