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; 023 024import java.io.Serializable; 025import java.util.ArrayList; 026import java.util.List; 027import java.util.Vector; 028 029import org.biojava.bio.BioException; 030import org.biojava.utils.ParseErrorEvent; 031import org.biojava.utils.ParseErrorListener; 032import org.biojava.utils.ParseErrorSource; 033 034/** 035 * Simple filter which handles attribute lines from a Genbank file 036 * 037 * @author Greg Cox 038 * @deprecated Use org.biojavax.bio.seq.io framework instead 039 */ 040 041public class GenbankProcessor extends SequenceBuilderFilter 042implements ParseErrorSource 043{ 044 public static final String PROPERTY_GENBANK_ACCESSIONS = "genbank_accessions"; 045 private boolean mBadFeature = false; 046 private Vector mListeners = new Vector(); 047 048 /** 049 * Factory which wraps sequence builders in a GenbankProcessor 050 * 051 * @author Greg Cox 052 */ 053 public static class Factory implements SequenceBuilderFactory, Serializable 054 { 055 private SequenceBuilderFactory delegateFactory; 056 057 public Factory(SequenceBuilderFactory theDelegate) 058 { 059 delegateFactory = theDelegate; 060 } 061 062 public SequenceBuilder makeSequenceBuilder() 063 { 064 return new GenbankProcessor(delegateFactory.makeSequenceBuilder()); 065 } 066 067 public SequenceBuilder makeSequenceBuilder(String theSource) 068 { 069 return new GenbankProcessor(delegateFactory.makeSequenceBuilder(), theSource); 070 } 071 } 072 073 protected FeatureTableParser features; 074 private List accessions; 075 076 { 077 accessions = new ArrayList(); 078 } 079 080 public GenbankProcessor(SequenceBuilder theDelegate, String theSource) 081 { 082 super(theDelegate); 083 features = new FeatureTableParser(this, theSource); 084 } 085 086 public GenbankProcessor(SequenceBuilder theDelegate) 087 { 088 super(theDelegate); 089 features = new FeatureTableParser(this, "GenBank"); 090 } 091 092 public void endSequence() throws ParseException 093 { 094 // Avoids leaving a null name and null URI if there is no 095 // accession number. If accession number is vital, failure of 096 // test of accessions.size() > 0 should throw a 097 // ParseException. 098 String uri = ""; 099 if (accessions.size() > 0) { 100 uri = "urn:sequence/genbank:" + (String) accessions.get(0); 101 getDelegate().addSequenceProperty(PROPERTY_GENBANK_ACCESSIONS, accessions); 102 } 103 104 getDelegate().setURI(uri); 105 getDelegate().endSequence(); 106 } 107 108 public void addSequenceProperty(Object key, Object value) throws ParseException 109 { 110 try 111 { 112 if(mBadFeature) 113 { 114 // If this feature is bad in some way, ignore it. 115 String featureLine = value.toString(); 116 if((key.equals(GenbankFormat.FEATURE_FLAG)) && (featureLine.charAt(0) != ' ')) 117 { 118 // If the offending feature is past, start reading data again 119 mBadFeature = false; 120 features.startFeature(featureLine.substring(0, 16).trim()); 121 features.featureData(featureLine.substring(16)); 122 } 123 } 124 else 125 { 126 if (features.inFeature() && !(key.equals(GenbankFormat.FEATURE_FLAG))) 127 { 128 features.endFeature(); 129 } 130 131 if(key.equals(GenbankFormat.FEATURE_FLAG)) 132 { 133 String featureLine = value.toString(); 134 if (featureLine.charAt(0) != ' ') 135 { 136 // This is a featuretype field 137 if (features.inFeature()) 138 { 139 features.endFeature(); 140 } 141 features.startFeature(featureLine.substring(0, 16).trim()); 142 } 143 features.featureData(featureLine.substring(16)); 144 } 145 else 146 { 147 getDelegate().addSequenceProperty(key, value); 148 if (key.equals(GenbankFormat.ACCESSION_TAG)) 149 { 150 accessions.add(value); 151 } 152 else if (key.equals(GenbankFormat.LOCUS_TAG)) { 153 getDelegate().setName((String) value); 154 features.setSeqID((String) value); 155 } 156 } 157 } 158 } 159 catch (BioException ex) 160 { 161 // If an exception is thrown, notify the listeners and read past 162 // the offending feature 163 mBadFeature = true; 164 ParseErrorEvent offendingLineEvent = new ParseErrorEvent(this, "This line could not be parsed: " + value.toString()); 165 this.notifyParseErrorEvent(offendingLineEvent); 166 } 167 catch (IndexOutOfBoundsException ex) 168 { 169 // This occurs when for some line min > max 170 mBadFeature = true; 171 ParseErrorEvent offendingLineEvent = new ParseErrorEvent(this, "From must be less than To: " + value.toString()); 172 this.notifyParseErrorEvent(offendingLineEvent); 173 } 174 } 175 176 /** 177 * Adds a parse error listener to the list of listeners if it isn't already 178 * included. 179 * 180 * @param theListener Listener to be added. 181 */ 182 public synchronized void addParseErrorListener( 183 ParseErrorListener theListener) 184 { 185 if(mListeners.contains(theListener) == false) 186 { 187 mListeners.addElement(theListener); 188 } 189 } 190 191 /** 192 * Removes a parse error listener from the list of listeners if it is 193 * included. 194 * 195 * @param theListener Listener to be removed. 196 */ 197 public synchronized void removeParseErrorListener( 198 ParseErrorListener theListener) 199 { 200 if(mListeners.contains(theListener) == true) 201 { 202 mListeners.removeElement(theListener); 203 } 204 } 205 206 // Protected methods 207 /** 208 * Passes the event on to all the listeners registered for ParseErrorEvents. 209 * 210 * @param theEvent The event to be handed to the listeners. 211 */ 212 protected void notifyParseErrorEvent(ParseErrorEvent theEvent) 213 { 214 Vector listeners; 215 synchronized(this) 216 { 217 listeners = (Vector)mListeners.clone(); 218 } 219 220 for (int index = 0; index < listeners.size(); index++) 221 { 222 ParseErrorListener client = (ParseErrorListener)listeners.elementAt(index); 223 client.BadLineParsed(theEvent); 224 } 225 } 226}