2 * BioJava development code
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,
9 * http://www.gnu.org/copyleft/lesser.html
11 * Copyright for this code is held jointly by the individual
12 * authors. These should be listed in @author doc comments.
14 * For more information on the BioJava project and its aims,
15 * or to join the biojava-l mailing list, visit the home page
18 * http://www.biojava.org/
20 * Created on 21.09.2004
21 * @author Andreas Prlic
25 package org.biojava.dasobert.das ;
29 import java.util.logging.* ;
30 import org.biojava.dasobert.eventmodel.FeatureListener;
31 import org.biojava.dasobert.eventmodel.FeatureEvent;
32 import org.biojava.dasobert.dasregistry.Das1Source;
34 /** a thread that connects to a DAS - Feature service and gets the features
36 * @author Andreas Prlic
41 public class FeatureThread
45 /** number of times the client tries to reconnect to the server if a "come back later" is returned.
46 * the server should provide a reasonable estimation how long it will take him to create results.
47 * if this number of requests is still not successfull, give up.
49 public static int MAX_COME_BACK_ITERATIONS = 5;
51 public static int MAX_NR_FEATURES = 300;
53 static Logger logger = Logger.getLogger("org.biojava.spice");
57 List featureListeners;
60 public FeatureThread (String accessionCode, Das1Source dasSource) {
61 this.dasSource = dasSource;
62 this.ac = accessionCode;
63 featureListeners = new ArrayList();
66 public void addFeatureListener(FeatureListener li) {
67 featureListeners.add(li);
70 public void clearFeatureListeners() {
71 featureListeners.clear();
74 public synchronized void stop(){
83 Thread me = Thread.currentThread();
84 while ( thread == me) {
85 String url = dasSource.getUrl();
86 String queryString = url + "features?segment="+ ac ;
89 cmd = new URL(queryString);
90 } catch (MalformedURLException e ) {
91 logger.warning("got MalformedURL from das source " +dasSource);
95 logger.info("requesting features from " + cmd);
96 DAS_FeatureRetrieve ftmp = new DAS_FeatureRetrieve(cmd);
99 int comeBackLater = ftmp.getComeBackLater();
100 int securityCounter = 0;
101 while ( (thread == me) && ( comeBackLater > 0 )) {
103 if ( securityCounter >= MAX_COME_BACK_ITERATIONS){
108 notifyComeBackLater(comeBackLater);
109 // server is still calculating - asks us to come back later
111 wait (comeBackLater);
112 } catch (InterruptedException e){
118 comeBackLater = ftmp.getComeBackLater();
121 if ( ! (thread == me ) ) {
125 List features = ftmp.get_features();
127 // a fallback mechanism to prevent DAS sources from bringing down spice
128 if ( features.size() > MAX_NR_FEATURES){
129 logger.warning("DAS source returned more than " + MAX_NR_FEATURES + "features. " +
130 " throwing away excess features at " +cmd);
131 features = features.subList(0,MAX_NR_FEATURES);
135 // notify FeatureListeners
136 Map[] feats = (Map[])features.toArray(new Map[features.size()]);
137 notifyFeatureListeners(feats);
147 public void start() {
148 thread = new Thread(this);
152 private void notifyFeatureListeners(Map[] feats){
153 logger.finest("FeatureThread found " + feats.length + " features");
154 FeatureEvent fevent = new FeatureEvent(feats,dasSource);
155 Iterator fiter = featureListeners.iterator();
156 while (fiter.hasNext()){
157 FeatureListener fi = (FeatureListener)fiter.next();
158 fi.newFeatures(fevent);
162 /** the Annotation server requested to be queried again in a while
164 * @param comeBackLater
166 private void notifyComeBackLater(int comeBackLater){
167 FeatureEvent event = new FeatureEvent(new HashMap[0],dasSource);
168 event.setComeBackLater(comeBackLater);
169 Iterator fiter = featureListeners.iterator();
170 while (fiter.hasNext()){
171 FeatureListener fi = (FeatureListener)fiter.next();
172 fi.comeBackLater(event);