/* * 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.xff; import java.util.ArrayList; import java.util.List; import org.biojava.bio.Annotation; import org.biojava.bio.seq.io.SeqIOListener; import org.biojava.utils.stax.DelegationManager; import org.biojava.utils.stax.StAXContentHandler; import org.biojava.utils.stax.StAXContentHandlerBase; import org.xml.sax.Attributes; import org.xml.sax.SAXException; /** * StAX handler which converts and stream of parse events for an XFF * featureSet element into BioJava SeqIO events. * * NOTE This class is not thread-safe -- it * must only be used for one parse at any time. * * @author Thomas Down * @since 1.2 */ public class XFFFeatureSetHandler extends StAXContentHandlerBase { public final static String PROPERTY_XFF_ID = "org.biojava.bio.program.xff.id"; private List featureHandlers; private List detailHandlers; private SeqIOListener featureListener; private Annotation mergeAnnotation; { featureHandlers = new ArrayList(); detailHandlers = new ArrayList(); mergeAnnotation = Annotation.EMPTY_ANNOTATION; } // // Current parse status // /** * Construct a new XFFFeatureSetHandler with the default set of handlers. */ public XFFFeatureSetHandler() { addFeatureHandler(ElementRecognizer.ALL, FeatureHandler.FEATURE_HANDLER_FACTORY); addFeatureHandler(new ElementRecognizer.HasAttribute("strand"), StrandedFeatureHandler.STRANDEDFEATURE_HANDLER_FACTORY); addDetailHandler(new ElementRecognizer.ByLocalName("prop"), PropDetailHandler.PROPDETAIL_HANDLER_FACTORY); } /** * Set the object which receives startFeature/endFeature notifications. */ public void setFeatureListener(SeqIOListener siol) { featureListener = siol; } /** * Return the object which receives startFeature/endFeature notifications. */ public SeqIOListener getFeatureListener() { return featureListener; } public void setMergeAnnotation(Annotation ann) { this.mergeAnnotation = ann; } public Annotation getMergeAnnotation() { return this.mergeAnnotation; } /** * Extend this FeatureSetHandler to delegate certain feature elements * to the specified handler type. * * @param rec A selector for some sub-set of feature elements. * @param handler A factory which returns StAX handlers for matching elements. */ public void addFeatureHandler(ElementRecognizer rec, XFFPartHandlerFactory handler) { featureHandlers.add(new Binding(rec, handler)); } /** * Extend this FeatureSetHandler to delegate certain detail elements * to the specified handler type. * * @param rec A selector for some sub-set of detail elements. * @param handler A factory which returns StAX handlers for matching elements. */ public void addDetailHandler(ElementRecognizer rec, XFFPartHandlerFactory handler) { detailHandlers.add(new Binding(rec, handler)); } class Binding { final ElementRecognizer recognizer; final XFFPartHandlerFactory handlerFactory; Binding(ElementRecognizer er, XFFPartHandlerFactory hf) { recognizer = er; handlerFactory = hf; } public String toString() { return "Binding[rec=" + recognizer + " fact=" + handlerFactory + "]"; } } public void startElement(String nsURI, String localName, String qName, Attributes attrs, DelegationManager dm) throws SAXException { //System.err.println("Processing startElement(" + nsURI + ", " + localName + ", " + qName + ", " + pretify(attrs)); if (localName.equals("featureSet")) { return; } for (int i = featureHandlers.size() - 1; i >= 0; --i) { Binding b = (Binding) featureHandlers.get(i); //System.err.println("Binding: " + b); if (b.recognizer.filterStartElement(nsURI, localName, qName, attrs)) { //System.err.println("Accepting binding"); dm.delegate(b.handlerFactory.getPartHandler(this)); return; } } throw new SAXException("Couldn't handle element " + localName + " in namespace " + nsURI); } public void endElement(String nsURI, String localName, String qName, StAXContentHandler handler) { if (localName.equals("featureSet")) { } } /** * Return a handler for the XFF details element. * This handler will, in turn, delegate to the specific detail * handlers provided with addDetailHandler */ public StAXContentHandlerBase getDetailsHandler() { return new XFFDetailsHandler(); } private class XFFDetailsHandler extends StAXContentHandlerBase { public void startElement(String nsURI, String localName, String qName, Attributes attrs, DelegationManager dm) throws SAXException { if (localName.equals("details")) { return; } for (int i = detailHandlers.size() - 1; i >= 0; --i) { Binding b = (Binding) detailHandlers.get(i); if (b.recognizer.filterStartElement(nsURI, localName, qName, attrs)) { dm.delegate(b.handlerFactory.getPartHandler(XFFFeatureSetHandler.this)); return; } } // Unknown detail types get silently ignored. } public void endElement(String nsURI, String localName, String qName) { if (localName.equals("details")) { } } } }