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 java.util.HashSet; 016import java.util.Set; 017 018import org.biojava.bio.SimpleAnnotation; 019import org.biojava.bio.seq.StrandedFeature; 020import org.biojava.bio.seq.io.ParseException; 021import org.biojava.bio.seq.io.game.ElementRecognizer; 022import org.biojava.bio.symbol.RangeLocation; 023import org.biojava.utils.ChangeVetoException; 024import org.biojava.utils.stax.StAXContentHandler; 025import org.biojava.utils.stax.StringElementHandlerBase; 026import org.xml.sax.Attributes; 027import org.xml.sax.SAXException; 028 029/** 030 * Handles the GAME <annotation> element 031 * 032 * @author David Huen 033 * @since 1.2 034 */ 035public class GAMEAnnotationHandler 036 extends StAXFeatureHandler { 037 // <annotation> is a container for all features of a "gene". 038 // the only important property of this container is its id 039 // which I need to capture and supply nested classes. 040 041 private Set knownTypes; 042 043 // database columns 044 String annotationName; 045 String annotationType; 046 047 // there can be multiple transcripts (aka feature_sets) in a 048 // <annotation>. We must get the full extent of all transcripts 049 // to use as the limits. 050 int annotationLocMin = Integer.MAX_VALUE; 051 int annotationLocMax = Integer.MIN_VALUE; 052 053 StrandedFeature.Template annotationTemplate; 054 055 // subclass GAMEFeatureSetHandler to retrieve transcript info 056 private class FeatureSetHandler extends GAMEFeatureSetHandler 057 { 058 private FeatureSetHandler(StAXFeatureHandler staxenv) 059 { 060 super(staxenv); 061// System.out.println("entering FeatureSetHandler"); 062 } 063 064 public void endElementHandler( 065 String nsURI, 066 String localName, 067 String qName, 068 StAXContentHandler contentHandler) 069 throws SAXException 070 { 071 // validate 072 super.endElementHandler(nsURI, localName, qName, contentHandler); 073 074 // fill in the template with location and strand info 075 annotationTemplate.strand = transcriptStrand; 076 077 annotationLocMin = Math.min(annotationLocMin, transcript.getMin()); 078 annotationLocMax = Math.max(annotationLocMax, transcript.getMax()); 079 080 if (annotationTemplate.strand == null) 081 annotationTemplate.strand = transcriptStrand; 082 else if (annotationTemplate.strand != transcriptStrand) { 083 // conflicting info 084 System.err.println("inconsistent strand info from transcripts."); 085 } 086 } 087 } 088 089 // subclass <dbxref> to write a feature property here 090 private class DbxrefHandler extends GAMEDbxrefHandler 091 { 092 private DbxrefHandler(StAXFeatureHandler staxenv) 093 { 094 super(staxenv); 095 } 096 097 public void endElementHandler( 098 String nsURI, 099 String localName, 100 String qName, 101 StAXContentHandler contentHandler) 102 throws SAXException 103 { 104 // validate before going further 105 super.endElementHandler(nsURI, localName, qName, contentHandler); 106 107 try { 108 listener.addFeatureProperty("dbxref", "dbxref:" + db_xref_db + "//" + db_xref_id); 109 } 110 catch (ParseException pe) { 111 pe.printStackTrace(); 112 throw new SAXException("unexpected exception while add <dbxref> as a feature property."); 113 } 114 } 115 } 116 117 // set up factory method 118 /** 119 * Description of the Field 120 */ 121 public final static StAXHandlerFactory GAME_ANNOTATION_HANDLER_FACTORY 122 = 123 new StAXHandlerFactory() { 124 public StAXContentHandler getHandler(StAXFeatureHandler staxenv) { 125 return new GAMEAnnotationHandler(staxenv); 126 } 127 }; 128 129 /** 130 * Constructor for the GAMEAnnotationHandler object 131 * 132 *@param staxenv Description of the Parameter 133 *@param parentID Description of the Parameter 134 */ 135 GAMEAnnotationHandler(StAXFeatureHandler staxenv) { 136 // setup environment 137 super(staxenv); 138 139 // initialise known types 140 knownTypesInitialiser(); 141 142 // setup handlers 143 // <name> 144 super.addHandler(new ElementRecognizer.ByLocalName("name"), 145 new StAXHandlerFactory() { 146 public StAXContentHandler getHandler(StAXFeatureHandler staxenv) { 147 return new NameHandler(); 148 } 149 } 150 ); 151 152 // <type> 153 super.addHandler(new ElementRecognizer.ByLocalName("type"), 154 new StAXHandlerFactory() { 155 public StAXContentHandler getHandler(StAXFeatureHandler staxenv) { 156 return new TypeHandler(); 157 } 158 } 159 ); 160 161 // <seq>: never seen it used yet. 162// super.addHandler(new ElementRecognizer.ByLocalName("seq"), 163// GAMESeqPropHandler.GAME_SEQ_PROP_HANDLER_FACTORY); 164 // <gene> 165 super.addHandler(new ElementRecognizer.ByLocalName("gene"), 166 GAMEGeneHandler.GAME_GENE_HANDLER_FACTORY); 167 // <feature_set> 168 super.addHandler(new ElementRecognizer.ByLocalName("feature_set"), 169 new StAXHandlerFactory() { 170 public StAXContentHandler getHandler(StAXFeatureHandler staxenv) { 171 return new FeatureSetHandler(staxenv); 172 } 173 } 174 ); 175 // <dbxref> 176 super.addHandler(new ElementRecognizer.ByLocalName("dbxref"), 177 new StAXHandlerFactory() { 178 public StAXContentHandler getHandler(StAXFeatureHandler staxenv) { 179 return new DbxrefHandler(staxenv); 180 } 181 } 182 ); 183 // <Aspect> 184 super.addHandler(new ElementRecognizer.ByLocalName("aspect"), 185 GAMEAspectHandler.GAME_ASPECT_HANDLER_FACTORY); 186 // <property> 187 super.addHandler(new ElementRecognizer.ByLocalName("property"), 188 GAMEPropertyHandler.GAME_PROPERTY_HANDLER_FACTORY); 189 } 190 191 192 /** 193 * Description of the Class 194 * 195 *@author david 196 *@created 19 January 2002 197 */ 198 private class NameHandler extends StringElementHandlerBase { 199 /** 200 * Sets the stringValue attribute of the NameHandler object 201 * 202 *@param s The new stringValue value 203 */ 204 protected void setStringValue(String s) { 205 annotationName = s.trim(); 206 } 207 } 208 209 /** 210 * Description of the Class 211 * 212 *@author david 213 *@created 19 January 2002 214 */ 215 private class TypeHandler extends StringElementHandlerBase { 216 /** 217 * Sets the stringValue attribute of the TypeHandler object 218 * 219 *@param s The new stringValue value 220 */ 221 protected void setStringValue(String s) { 222 annotationType = s.trim(); 223 } 224 } 225 226 private void knownTypesInitialiser() 227 { 228 // initialise a String array 229 String [] types = {"gene", "tRNA", "snRNA", "pseudogene", "transposon", "snoRNA", "misc. non-coding RNA", 230 "transposable_element", "miscellaneous curator's observation"}; 231 232 // now initialise the knownTypes Set 233 knownTypes = new HashSet(); 234 235 for (int i=0; i < types.length; i++) { 236 knownTypes.add(types[i]); 237 } 238 } 239 240 public void startElementHandler( 241 String nsURI, 242 String localName, 243 String qName, 244 Attributes attrs) 245 throws SAXException 246 { 247 // indicate start of sequence 248 try { 249// System.out.println("local name is " + localName); 250 annotationTemplate = new StrandedFeature.Template(); 251 annotationTemplate.annotation = new SimpleAnnotation(); 252 253 // there should be an id in the attributes, get it 254 String id = attrs.getValue("id"); 255 256 try { 257 if (id != null) annotationTemplate.annotation.setProperty("id", id); 258 } 259 catch (ChangeVetoException cve) { 260 cve.printStackTrace(); 261 throw new SAXException("unexpected ChangeVetoException when setting id!"); 262 } 263 264 listener.startFeature(annotationTemplate); 265 } 266 catch (ParseException pe) { 267 pe.printStackTrace(); 268 throw new SAXException("error in GAMEAnnotationHandler."); 269 } 270 } 271 272 273 public void endElementHandler( 274 String nsURI, 275 String localName, 276 String qName, 277 StAXContentHandler contentHandler) 278 throws SAXException 279 { 280 // fill in the template as best can 281 // confirm that it is something I expect 282 if (!knownTypes.contains(annotationType)) { 283 System.err.println("<annotation> of type " + annotationType + " encountered when gene expected"); 284 } 285 286 // ganbatte! 287 annotationTemplate.type = annotationType; 288 annotationTemplate.source = ""; 289 annotationTemplate.location = new RangeLocation(annotationLocMin, annotationLocMax); 290 291 // bear in mind we are completely dependent on the SeqIOListener 292 // to set the location and strand!!!! 293 294 // indicate end of sequence 295 try { 296 listener.endFeature(); 297 } 298 catch (ParseException pe) { 299 pe.printStackTrace(); 300 throw new SAXException("error in GAMEAnnotationHandler."); 301 } 302 } 303} 304