(JAL-1016) noted position where race condition occurs
[jalview.git] / src / org / biojava / dasobert / das / DAS_Feature_Handler.java
1 /*
2  *                    BioJava development code
3  *
4  * This code may be freely distributed and modified under the
5  * terms of the GNU Lesser General Public Licence.  This should
6  * be distributed with the code.  If you do not have a copy,
7  * see:
8  *
9  *      http://www.gnu.org/copyleft/lesser.html
10  *
11  * Copyright for this code is held jointly by the individual
12  * authors.  These should be listed in @author doc comments.
13  *
14  * For more information on the BioJava project and its aims,
15  * or to join the biojava-l mailing list, visit the home page
16  * at:
17  *
18  *      http://www.biojava.org/
19  *
20  * Created on 19.03.2004
21  * @author Andreas Prlic
22  *
23  */
24 package org.biojava.dasobert.das;
25
26 import java.util.*;
27
28 import org.xml.sax.*;
29 import org.xml.sax.helpers.*;
30
31 /**
32  * a class to parse the response of a DAS - Feature request
33  * 
34  * @author Andreas Prlic Adapted for jalview use.
35  * @author Andrew Waterhouse Updated to Das 1.53e feature spec.
36  * @author Jim Procter
37  * 
38  */
39 public class DAS_Feature_Handler extends DefaultHandler
40 {
41
42   /**
43    * 
44    */
45   List features;
46
47   boolean first_flag;
48
49   HashMap feature;
50
51   String featurefield;
52
53   StringBuffer characterdata;
54
55   String dasCommand;
56
57   int comeBackLater;
58
59   int maxFeatures;
60
61   String segmentId;
62
63   String version;
64
65   String type_id;
66
67   String type_category;
68
69   public DAS_Feature_Handler()
70   {
71     super();
72
73     features = new ArrayList();
74     first_flag = true;
75     featurefield = "";
76     characterdata = new StringBuffer();
77     dasCommand = "";
78     comeBackLater = -1;
79     maxFeatures = -1;
80     segmentId = "";
81     version = "";
82     type_id = "";
83     type_category = "";
84   }
85
86   /**
87    * get the id information specified int the SEGMENT field of the DAS response
88    * 
89    * @return the segmentId or an emtpy string if not available
90    */
91   public String getSegmentId()
92   {
93     return segmentId;
94   }
95
96   /**
97    * get the version informationspecified in the SEGMENT field of the DAS
98    * response
99    * 
100    * @return the version information of an empty string if not available
101    */
102   public String getVersion()
103   {
104     return version;
105   }
106
107   public boolean isMD5Checksum()
108   {
109
110     if ((version != null) && (version.length() == 32))
111       return true;
112     return false;
113   }
114
115   /**
116    * specifies a maximum number of features to be downloaded. if a server
117    * returns more, they will be ignored. default is to load all features
118    * 
119    * @param max
120    *                the maximium number of features to be downloaded
121    */
122
123   public void setMaxFeatures(int max)
124   {
125     maxFeatures = max;
126   }
127
128   public int getMaxFeatures()
129   {
130     return maxFeatures;
131   }
132
133   public void setDASCommand(String cmd)
134   {
135     dasCommand = cmd;
136   }
137
138   public String getDASCommand()
139   {
140     return dasCommand;
141   }
142
143   public List get_features()
144   {
145     return features;
146   }
147
148   public int getComBackLater()
149   {
150     return comeBackLater;
151   }
152
153   void start_feature(String uri, String name, String qName, Attributes atts)
154   {
155
156     if ((maxFeatures > 0) && (features.size() > maxFeatures))
157     {
158       characterdata = new StringBuffer();
159       return;
160     }
161     feature = new HashMap();
162     String id = atts.getValue("id");
163     feature.put("id", id);
164     feature.put("dassource", dasCommand);
165     characterdata = new StringBuffer();
166   }
167
168   void add_featuredata(String uri, String name, String qName)
169   {
170     // System.out.println("featurefield "+featurefield+ " data "+characterdata);
171     // NOTE can have multiple lines ..
172
173     if ((maxFeatures > 0) && (features.size() > maxFeatures))
174     {
175       return;
176     }
177
178     String data = (String) feature.get(featurefield);
179     String featureText = characterdata.toString();
180     if (data != null)
181     {
182       featureText = data + " " + featureText;
183     }
184
185     if (qName.equals("TYPE"))
186     {
187       if (featureText.length() < 1)
188         featureText = type_id;
189
190       feature.put("TYPE_ID", type_id);
191       feature.put("TYPE_CATEGORY", type_category);
192       type_id = "";
193       type_category = "";
194     }
195
196     feature.put(featurefield, featureText);
197     featurefield = "";
198     characterdata = new StringBuffer();
199   }
200
201   private void addLink(String uri, String name, String qName,
202           Attributes atts)
203   {
204     String href = atts.getValue("href");
205     feature.put("LINK", href);
206     characterdata = new StringBuffer();
207     featurefield = "LINK-TEXT";
208
209   }
210
211   private void addGroup(String uri, String name, String qName,
212           Attributes atts)
213   {
214     String id = atts.getValue("id");
215     feature.put("GROUP", id);
216     characterdata = new StringBuffer();
217     featurefield = "GROUP";
218   }
219
220   public void startElement(String uri, String name, String qName,
221           Attributes atts)
222   {
223     // System.out.println("new element "+qName);
224
225     if (qName.equals("FEATURE"))
226     {
227       start_feature(uri, name, qName, atts);
228     }
229     else if (qName.equals("LINK"))
230     {
231       addLink(uri, name, qName, atts);
232     }
233     else if (qName.equals("GROUP"))
234     {
235       addGroup(uri, name, qName, atts);
236     }
237     else if (qName.equals("METHOD") || qName.equals("TYPE")
238             || qName.equals("START") || qName.equals("END")
239             || qName.equals("NOTE") || qName.equals("SCORE")
240             || qName.equals("ORIENTATION"))
241     {
242       characterdata = new StringBuffer();
243       featurefield = qName;
244     }
245     else if (qName.equals("SEGMENT"))
246     {
247       String id = atts.getValue("id");
248       if (id != null)
249         segmentId = id;
250       String v = atts.getValue("version");
251       if (v != null)
252         version = v;
253
254     }
255     if (qName.equals("TYPE"))
256     {
257       type_id = atts.getValue("id");
258       type_category = atts.getValue("category");
259     }
260
261   }
262
263   public void startDocument()
264   {
265   }
266
267   public void endDocument()
268   {
269   }
270
271   public void endElement(String uri, String name, String qName)
272   {
273
274     if (qName.equals("METHOD") || qName.equals("TYPE")
275             || qName.equals("START") || qName.equals("END")
276             || qName.equals("NOTE") || qName.equals("LINK")
277             || qName.equals("SCORE") || qName.equals("ORIENTATION")
278             || qName.equals("GROUP"))
279     {
280       add_featuredata(uri, name, qName);
281     }
282     else if (qName.equals("FEATURE"))
283     {
284
285       if (maxFeatures > 0)
286       {
287         if (features.size() < maxFeatures)
288         {
289           features.add(feature);
290         }
291       }
292       else
293       {
294         // no restriction
295         features.add(feature);
296       }
297     }
298   }
299
300   public void characters(char ch[], int start, int length)
301   {
302     if (maxFeatures > 0)
303       if (features.size() > maxFeatures)
304         return;
305
306     for (int i = start; i < start + length; i++)
307     {
308
309       characterdata.append(ch[i]);
310     }
311
312   }
313
314 }