001/**
002 *  BioJava development code This code may be freely distributed and modified
003 *  under the terms of the GNU Lesser General Public Licence. This should be
004 *  distributed with the code. If you do not have a copy, see:
005 *  http://www.gnu.org/copyleft/lesser.html Copyright for this code is held
006 *  jointly by the individual authors. These should be listed in
007 *
008 *@author    doc comments. For more information on the BioJava project and its
009 *      aims, or to join the biojava-l mailing list, visit the home page at:
010 *      http://www.biojava.org/
011 */
012
013package org.biojava.bio.seq.io.game12;
014
015import org.biojava.bio.SimpleAnnotation;
016import org.biojava.bio.seq.StrandedFeature;
017import org.biojava.bio.seq.io.ParseException;
018import org.biojava.bio.seq.io.game.ElementRecognizer;
019import org.biojava.bio.symbol.Location;
020import org.biojava.utils.ChangeVetoException;
021import org.biojava.utils.stax.StAXContentHandler;
022import org.biojava.utils.stax.StringElementHandlerBase;
023import org.xml.sax.Attributes;
024import org.xml.sax.SAXException;
025
026/**
027 *  Handles the GAME <feature_span> element
028 *
029 *@author     David Huen
030 *@since      1.2
031 */
032public class GAMEFeatureSpanHandler
033         extends StAXFeatureHandler {
034    // <annotation> is a container for all features of a "gene".
035    // the only important property of this container is its id
036    // which I need to capture and supply nested classes.
037
038    // database columns
039    private String featureSpanId;
040    String featureSpanType;
041    Location featureSpanLoc;
042    StrandedFeature.Strand featureSpanStrand;
043
044    private StrandedFeature.Template template;
045
046//    private GAMESeqRelHandler.SeqRelTemplate seqRelTmpl = null;
047
048    public class SeqRelHandler extends GAMESeqRelHandler
049    {
050        private SeqRelHandler(StAXFeatureHandler staxenv)
051        {
052            super(staxenv);
053//            System.out.println("entering SeqRelHandler");
054        }
055
056        public void endElementHandler(
057                String nsURI,
058                String localName,
059                String qName,
060                StAXContentHandler contentHandler)
061            throws SAXException
062        {
063            // validate
064            super.endElementHandler(nsURI, localName, qName, contentHandler);
065
066            featureSpanLoc = seqRelLoc;
067            featureSpanStrand = seqRelStrand;
068        }
069    }
070
071    // set up factory method
072    /**
073     *  Description of the Field
074     */
075    public final static StAXHandlerFactory GAME_FEATURE_SPAN_HANDLER_FACTORY
076             =
077        new StAXHandlerFactory() {
078            public StAXContentHandler getHandler(StAXFeatureHandler staxenv) {
079                return new GAMEFeatureSpanHandler(staxenv);
080            }
081        };
082
083    GAMEFeatureSpanHandler(StAXFeatureHandler staxenv) {
084        // setup environment
085        super(staxenv);
086
087        // setup handlers
088        // <name>
089        super.addHandler(new ElementRecognizer.ByLocalName("name"),
090            new StAXHandlerFactory() {
091                public StAXContentHandler getHandler(StAXFeatureHandler staxenv) {
092                    return new NameHandler();
093                }
094            }
095                );
096
097        // <type>
098        super.addHandler(new ElementRecognizer.ByLocalName("type"),
099            new StAXHandlerFactory() {
100                public StAXContentHandler getHandler(StAXFeatureHandler staxenv) {
101                    return new TypeHandler();
102                }
103            }
104                );
105        // <seq_relationship> external handler type
106        super.addHandler(new ElementRecognizer.ByLocalName("seq_relationship"),
107            new StAXHandlerFactory() {
108                public StAXContentHandler getHandler(StAXFeatureHandler staxenv) {
109                    return new SeqRelHandler(staxenv);
110                }
111            }
112        );
113    }
114
115
116    private class NameHandler extends StringElementHandlerBase {
117        /**
118         *  Sets the stringValue attribute of the NameHandler object
119         *
120         *@param  s  The new stringValue value
121         */
122        protected void setStringValue(String s) {
123        }
124    }
125
126    private class TypeHandler extends StringElementHandlerBase {
127        /**
128         *  Sets the stringValue attribute of the TypeHandler object
129         *
130         *@param  s  The new stringValue value
131         */
132        protected void setStringValue(String s) {
133            featureSpanType = s.trim();
134        }
135    }
136
137    public void startElementHandler(
138            String nsURI,
139            String localName,
140            String qName,
141            Attributes attrs) 
142        throws SAXException
143    {
144        featureSpanId = attrs.getValue("id");
145
146        try {
147            template = new StrandedFeature.Template();
148            template.annotation = new SimpleAnnotation();
149            template.source = null;
150
151            try {
152                if (featureSpanId != null) template.annotation.setProperty("id", featureSpanId);
153            }
154            catch (ChangeVetoException cve) {
155                throw new SAXException("unexpected ChangeVetoException when setting id!");
156            }
157
158            listener.startFeature(template);
159        }
160        catch (ParseException pe) {
161        }
162    }
163
164    public void endElementHandler(
165            String nsURI,
166            String localName,
167            String qName,
168            StAXContentHandler contentHandler)
169        throws SAXException 
170    {
171        // issue warning if it is not a translate offset or exon
172        if ( !( (featureSpanType.equals("exon")) || (featureSpanType.equals("translate offset")) ) ) {
173             System.err.println("<feature_span> of unexpected type " + featureSpanType);
174        }
175
176        // fill in template
177        // i would like to avoid returning something for translate offsets
178        // but I can't because the start feature has already allocated a template
179        template.type = featureSpanType;
180        template.source = "";
181        template.location = featureSpanLoc;
182        template.strand = featureSpanStrand;
183
184        // indicate end of sequence
185        try {
186            listener.endFeature();
187        }
188        catch (ParseException pe) {
189            pe.printStackTrace();
190            throw new SAXException("error in GAMEFeatureSetHandler.");
191        }
192    }
193}
194