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.seq.io.game;
023
024import java.util.ListIterator;
025
026import org.biojava.bio.SmallAnnotation;
027import org.biojava.bio.seq.Feature;
028import org.biojava.bio.seq.StrandedFeature;
029import org.biojava.bio.symbol.RangeLocation;
030import org.biojava.utils.ChangeVetoException;
031import org.biojava.utils.stax.StAXContentHandler;
032import org.xml.sax.Attributes;
033
034/**
035 * Handles the <feature_span> element
036 *
037 * @author David Huen
038 * @since 1.8
039 */
040public class GAMEFeatureSpanHandler extends StAXFeatureHandler {
041  // <feature_span> is one of the worst elements in GAME.  The type of element
042  // is only known from reading the nested <type> element.  The bloody
043  // strand and coordinates are nested 4-deep within the element.
044  // this element could be a start codon feature or an exon.
045  // Also, the lower value coordinate is one less than than the equivalent
046  // EMBL coordinate but the higher value is the same.
047  private StAXFeatureHandler staxenv;
048
049  public static final StAXHandlerFactory GAME_FEATURESPAN_HANDLER_FACTORY
050    = new StAXHandlerFactory() {
051    public StAXContentHandler getHandler(StAXFeatureHandler staxenv) {
052      return new GAMEFeatureSpanHandler(staxenv);
053    }
054  };
055
056  GAMEFeatureSpanHandler(StAXFeatureHandler staxenv) {
057    // setup up environment stuff
058    this.staxenv = staxenv;
059    featureListener = staxenv.featureListener;
060    setHandlerCharacteristics("feature_span", false);
061
062    // setup handlers
063       // <type>
064       super.addHandler(new ElementRecognizer.ByLocalName("type"),
065         GAMETypePropHandler.GAME_TYPE_PROP_HANDLER_FACTORY);
066       // <seq_relationship>
067       super.addHandler(new ElementRecognizer.ByLocalName("seq_relationship"),
068         GAMESeqRelPropHandler.GAME_SEQREL_PROP_HANDLER_FACTORY);
069  }
070
071  protected Feature.Template createTemplate() {
072    // create Gene Template for this
073    StrandedFeature.Template ft = new StrandedFeature.Template();
074
075    // set up annotation bundle
076    ft.annotation = new SmallAnnotation();
077    ft.strand = StrandedFeature.UNKNOWN;
078
079    return ft;
080  }
081
082
083  public void startElementHandler(
084                String nsURI,
085                String localName,
086                String qName,
087                Attributes attrs)
088  {
089//    System.out.println("GAMEFeatureSpanHandler.startElementHandler entered.");
090
091      // pick up id and save it in annotation bundle
092      String featureId = attrs.getValue("id");
093
094      try {
095        if (featureId != null)
096          featureTemplate.annotation.setProperty("id", featureId);
097      }
098      catch (ChangeVetoException cve) {
099        System.err.println("GAMEFeatureSpanHandler. Change blocked.");
100      }
101  }
102
103  public void endElementHandler(
104                String nsURI,
105                String localName,
106                String qName,
107                StAXContentHandler handler)
108  {
109    // we only do this for exons
110    if (!( ((String) featureTemplate.type).equals("exon") )) return;
111
112    // update transcript limits
113    // get iterator to callbackStack of PREVIOUS FeatureHandler
114    int currLevel = staxenv.getLevel();
115 
116    if (currLevel >=1) {
117      // search down stack for callback handler
118      ListIterator li = staxenv.getHandlerStackIterator(currLevel);
119
120      while (li.hasPrevious()) {
121        Object ob = li.previous();
122        if (ob instanceof GAMETranscriptCallbackItf) {
123          // we have a nesting handler, use it
124          ((GAMETranscriptCallbackItf) ob).reportExon(
125              (RangeLocation) ((StrandedFeature.Template) featureTemplate).location,
126              ((StrandedFeature.Template) featureTemplate).strand);
127          return;
128        }
129      }
130    }
131    
132  }
133
134}
135