001 /*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021package org.biojava.bio.seq.io.agave;
022import java.util.ArrayList;
023import java.util.List;
024
025import org.xml.sax.Attributes;
026import org.xml.sax.ContentHandler;
027import org.xml.sax.Locator;
028import org.xml.sax.SAXException;
029/**
030 * Lightweight adaptor which translates SAX content events into
031 * StAX form, and provides delegation services.
032 *
033 * @author Thomas Down
034 * @author modified by Hanning Ni
035 */
036public class SAX2StAXAdaptor implements ContentHandler {
037    private List stack;
038    private HandlerBinding current;
039    private boolean isRecursive ;
040
041    {
042        stack = new ArrayList();
043        isRecursive = true ;
044    }
045
046    /**
047     * Construct a new SAX Content handler which wraps a StAX
048     * handler.
049     */
050
051    public SAX2StAXAdaptor(StAXContentHandler rootHandler) {
052        current = new HandlerBinding(rootHandler);
053        stack.add(current);
054    }
055
056    public void startDocument() throws SAXException {
057        current.handler.startTree();
058    }
059
060    public void endDocument() throws SAXException {
061        current.handler.endTree();
062    }
063
064    public void characters(char[] ch,
065                           int start,
066                           int end)
067        throws SAXException
068    {
069        current.handler.characters(ch, start, end);
070    }
071
072    public void ignorableWhitespace(char[] ch,
073                                    int start,
074                                    int end)
075        throws SAXException
076    {
077        current.handler.ignorableWhitespace(ch, start, end);
078    }
079
080    public void startPrefixMapping(String prefix, String uri)
081        throws SAXException
082    {
083        current.handler.startPrefixMapping(prefix, uri);
084    }
085
086    public void endPrefixMapping(String prefix)
087        throws SAXException
088    {
089        current.handler.endPrefixMapping(prefix);
090    }
091
092    public void processingInstruction(String target, String data)
093        throws SAXException
094    {
095        current.handler.processingInstruction(target, data);
096    }
097
098    public void setDocumentLocator(Locator locator) {
099        current.handler.setDocumentLocator(locator);
100    }
101
102    public void skippedEntity(String name)
103        throws SAXException
104    {
105        current.handler.skippedEntity(name);
106    }
107
108    public void startElement(final String nsURI,
109                             final String localName,
110                             final String qName,
111                             final Attributes attrs)
112        throws SAXException
113    {
114        S2SDelegationManager dm = new S2SDelegationManager();
115        dm.setRecursive( isRecursive ) ;
116        current.handler.startElement(nsURI,
117                                     localName,
118                                     qName,
119                                     attrs,
120                                     dm);
121
122        if (dm.getDelegate() != null) {
123            current = new HandlerBinding(dm.getDelegate());
124            stack.add(current);
125            isRecursive = false ;
126            current.handler.startTree();
127            startElement(nsURI, localName, qName, attrs); // Recurse until someone
128        } else {
129            current.count++;
130            isRecursive = true ;
131        }
132    }
133
134    private static class S2SDelegationManager implements DelegationManager {
135        private StAXContentHandler delegate;
136        private boolean recursive = true ;
137
138        public void delegate(StAXContentHandler handler)
139            throws SAXException
140        {
141            if (this.delegate != null) {
142                throw new SAXException("Tried to multiply delegate a single StAX element");
143            }
144
145            this.delegate = handler;
146        }
147
148        public void setRecursive(boolean recursive )
149        {
150            this.recursive = recursive ;
151        }
152
153        public boolean getRecursive()
154        {
155            return recursive ;
156        }
157
158        private StAXContentHandler getDelegate() {
159            return delegate;
160        }
161    }
162
163    public void endElement(String nsURI, String localName, String qName)
164        throws SAXException
165    {
166        current.handler.endElement(nsURI, localName, qName, null);
167        current.count--;
168        while (current.count == 0 && stack.size() > 1) {
169            current.handler.endTree();
170            stack.remove(stack.size() - 1);
171            current = (HandlerBinding) stack.get(stack.size() - 1);
172         //   current.handler.endElement(nsURI, localName, qName, oldHandler);
173        }
174    }
175
176    private class HandlerBinding {
177        public StAXContentHandler handler;
178        public int count;
179
180        private HandlerBinding(StAXContentHandler handler) {
181            this.handler = handler;
182            this.count = 0;
183        }
184    }
185}