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 */
021
022package org.biojava.bio.program.xff;
023
024import org.biojava.bio.symbol.Location;
025import org.biojava.bio.symbol.RangeLocation;
026import org.biojava.utils.stax.DelegationManager;
027import org.biojava.utils.stax.StAXContentHandler;
028import org.biojava.utils.stax.StAXContentHandlerBase;
029import org.xml.sax.Attributes;
030import org.xml.sax.SAXException;
031
032/**
033 * Handler to the XFF location type.  To use this, write a simple
034 * subclass which takes the location and stores it somewhere sensible.
035 *
036 * @author Thomas Down
037 * @since 1.2
038 */
039
040public abstract class LocationHandlerBase extends StAXContentHandlerBase {
041    private int level = 0;
042    private Location location = Location.empty;
043
044    public void startElement(String nsURI,
045                             String localName,
046                             String qName,
047                             Attributes attrs,
048                             DelegationManager dm)
049         throws SAXException
050    {
051        level++;
052        if (level == 0) {
053            // Top-level.  Ignore
054        } else {
055            if (localName.equals("span")) {
056                try {
057                    String starts = attrs.getValue("start");
058                    String stops = attrs.getValue("stop");
059                    
060                    if (starts == null || stops == null) {
061                        throw new SAXException("Missing start/stop attribute in location span");
062                    }
063                    
064                    Location span = new RangeLocation(Integer.parseInt(starts),
065                                                      Integer.parseInt(stops));
066                    location = location.union(span);
067                } catch (NumberFormatException ex) {
068                    throw new SAXException("Error parsing location", ex);
069                }
070            }
071        }
072    }
073
074    public void endElement(String nsURI,
075                           String localName,
076                           String qName,
077                           StAXContentHandler handler)
078        throws SAXException
079    {
080        level--;
081        if (level == 0) {
082            setLocationValue(location);
083        }
084    }
085
086    /**
087     * Override this method to do something useful with the
088     * location we collect.  Maybe we should do this by delegation
089     * rather than extension.
090     */
091
092    protected abstract void setLocationValue(Location l) throws SAXException;
093}