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 jalview.biojava.dasobert.das ;
29 import java.util.logging.* ;
30 import jalview.biojava.dasobert.eventmodel.FeatureListener;
31 import jalview.biojava.dasobert.eventmodel.FeatureEvent;
32 import jalview.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);
96 logger.info("requesting features from " + cmd);
97 DAS_FeatureRetrieve ftmp = new DAS_FeatureRetrieve(cmd);
100 int comeBackLater = ftmp.getComeBackLater();
101 int securityCounter = 0;
102 while ( (thread == me) && ( comeBackLater > 0 )) {
104 if ( securityCounter >= MAX_COME_BACK_ITERATIONS){
109 notifyComeBackLater(comeBackLater);
110 // server is still calculating - asks us to come back later
112 wait (comeBackLater);
113 } catch (InterruptedException e){
119 comeBackLater = ftmp.getComeBackLater();
122 if ( ! (thread == me ) ) {
126 List features = ftmp.get_features();
128 // a fallback mechanism to prevent DAS sources from bringing down spice
129 if ( features.size() > MAX_NR_FEATURES){
130 logger.warning("DAS source returned more than " + MAX_NR_FEATURES + "features. " +
131 " throwing away excess features at " +cmd);
132 features = features.subList(0,MAX_NR_FEATURES);
136 // notify FeatureListeners
137 Map[] feats = (Map[])features.toArray(new Map[features.size()]);
138 notifyFeatureListeners(feats);
148 public void start() {
149 thread = new Thread(this);
153 private void notifyFeatureListeners(Map[] feats){
154 logger.finest("FeatureThread found " + feats.length + " features");
155 FeatureEvent fevent = new FeatureEvent(feats,dasSource);
156 Iterator fiter = featureListeners.iterator();
157 while (fiter.hasNext()){
158 FeatureListener fi = (FeatureListener)fiter.next();
159 fi.newFeatures(fevent);
163 /** the Annotation server requested to be queried again in a while
165 * @param comeBackLater
167 private void notifyComeBackLater(int comeBackLater){
168 FeatureEvent event = new FeatureEvent(new HashMap[0],dasSource);
169 event.setComeBackLater(comeBackLater);
170 Iterator fiter = featureListeners.iterator();
171 while (fiter.hasNext()){
172 FeatureListener fi = (FeatureListener)fiter.next();
173 fi.comeBackLater(event);