2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.ws.dbsources.das.datamodel;
23 import jalview.bin.Cache;
24 import jalview.ws.dbsources.das.api.DasSourceRegistryI;
25 import jalview.ws.dbsources.das.api.jalviewSourceI;
27 import java.net.HttpURLConnection;
28 import java.net.MalformedURLException;
30 import java.util.ArrayList;
31 import java.util.Enumeration;
32 import java.util.HashMap;
33 import java.util.Hashtable;
34 import java.util.List;
35 import java.util.StringTokenizer;
37 import org.biodas.jdas.client.ConnectionPropertyProviderI;
38 import org.biodas.jdas.client.SourcesClient;
39 import org.biodas.jdas.client.threads.MultipleConnectionPropertyProviderI;
40 import org.biodas.jdas.dassources.Capabilities;
41 import org.biodas.jdas.schema.sources.CAPABILITY;
42 import org.biodas.jdas.schema.sources.SOURCE;
43 import org.biodas.jdas.schema.sources.SOURCES;
44 import org.biodas.jdas.schema.sources.VERSION;
49 public class DasSourceRegistry
50 implements DasSourceRegistryI, MultipleConnectionPropertyProviderI
52 // private org.biodas.jdas.schema.sources.SOURCE[] dasSources = null;
53 private List<jalviewSourceI> dasSources = null;
55 private Hashtable<String, jalviewSourceI> sourceNames = null;
57 private Hashtable<String, jalviewSourceI> localSources = null;
59 // public static String DEFAULT_REGISTRY = "http://www.dasregistry.org/das/";
60 public static String DEFAULT_REGISTRY = "http://www.ebi.ac.uk/das-srv/registry/das/";
63 * true if thread is running and we are talking to DAS registry service
65 private boolean loadingDasSources = false;
67 public boolean isLoadingDasSources()
69 return loadingDasSources;
73 public String getDasRegistryURL()
75 String registry = jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",
78 if (registry.indexOf("/registry/das1/sources/") > -1)
80 jalview.bin.Cache.setProperty(jalview.bin.Cache.DAS_REGISTRY_URL,
82 registry = DEFAULT_REGISTRY;
84 if (registry.lastIndexOf("sources.xml") == registry.length() - 11)
86 // no trailing sources.xml document for registry in JDAS
87 jalview.bin.Cache.setProperty(jalview.bin.Cache.DAS_REGISTRY_URL,
88 registry = registry.substring(0,
89 registry.lastIndexOf("sources.xml")));
95 * query the default DAS Source Registry for sources. Uses value of jalview
96 * property DAS_REGISTRY_URL and the DasSourceBrowser.DEFAULT_REGISTRY if that
99 * @return list of sources
101 private List<jalviewSourceI> getDASSources()
104 return getDASSources(getDasRegistryURL(), this);
108 * query the given URL for DasSources.
111 * return sources from registryURL
113 private static List<jalviewSourceI> getDASSources(String registryURL,
114 MultipleConnectionPropertyProviderI registry)
118 URL url = new URL(registryURL);
119 org.biodas.jdas.client.SourcesClientInterface client = new SourcesClient();
121 SOURCES sources = client.fetchDataRegistry(registryURL, null, null,
122 null, null, null, null);
124 List<SOURCE> dassources = sources.getSOURCE();
125 ArrayList<jalviewSourceI> dsrc = new ArrayList<jalviewSourceI>();
126 HashMap<String, Integer> latests = new HashMap<String, Integer>();
128 for (SOURCE src : dassources)
130 JalviewSource jsrc = new JalviewSource(src, registry, false);
131 latest = latests.get(jsrc.getSourceURL());
134 if (jsrc.isNewerThan(dsrc.get(latest.intValue())))
136 dsrc.set(latest.intValue(), jsrc);
141 "Debug: Ignored older source " + jsrc.getTitle());
146 latests.put(jsrc.getSourceURL(), Integer.valueOf(dsrc.size()));
151 } catch (Exception ex)
154 "DAS1 registry at " + registryURL + " no longer exists");
155 return new ArrayList<jalviewSourceI>();
165 public List<jalviewSourceI> getSources()
167 if (dasSources == null)
169 dasSources = getDASSources();
171 return appendLocalSources();
175 * generate Sources from the local das source list
178 private void addLocalDasSources()
180 if (localSources == null)
182 // get local sources from properties and initialise the local source list
183 String local = jalview.bin.Cache.getProperty("DAS_LOCAL_SOURCE");
188 StringTokenizer st = new StringTokenizer(local, "\t");
189 while (st.hasMoreTokens())
191 String token = st.nextToken();
192 int bar = token.indexOf("|");
196 "Warning: DAS user local source appears to have no nickname (expected a '|' followed by nickname)\nOffending definition: '"
199 String url = token.substring(bar + 1);
200 boolean features = true, sequence = false;
201 if (url.startsWith("sequence:"))
203 url = url.substring(9);
204 // this source also serves sequences as well as features
211 createLocalSource(url, token.substring(0, bar), sequence,
216 createLocalSource(url, "User Source" + n, sequence, features);
218 } catch (Exception q)
221 "Unexpected exception when creating local source from '"
231 private List<jalviewSourceI> appendLocalSources()
233 List<jalviewSourceI> srclist = new ArrayList<jalviewSourceI>();
234 addLocalDasSources();
235 sourceNames = new Hashtable<String, jalviewSourceI>();
236 if (dasSources != null)
238 for (jalviewSourceI src : dasSources)
240 sourceNames.put(src.getTitle(), src);
245 if (localSources == null)
249 Enumeration en = localSources.keys();
250 while (en.hasMoreElements())
252 String key = en.nextElement().toString();
253 jalviewSourceI jvsrc = localSources.get(key);
254 sourceNames.put(key, jvsrc);
265 public jalviewSourceI createLocalSource(String url, String name,
266 boolean sequence, boolean features)
268 SOURCE local = _createLocalSource(url, name, sequence, features);
270 if (localSources == null)
272 localSources = new Hashtable<String, jalviewSourceI>();
274 jalviewSourceI src = new JalviewSource(local, this, true);
275 localSources.put(local.getTitle(), src);
279 private SOURCE _createLocalSource(String url, String name,
280 boolean sequence, boolean features)
282 SOURCE local = new SOURCE();
285 local.setTitle(name);
286 local.setVERSION(new ArrayList<VERSION>());
287 VERSION v = new VERSION();
288 List<CAPABILITY> cp = new ArrayList<CAPABILITY>();
292 * Could try and synthesize a coordinate system for the source if needbe
293 * COORDINATES coord = new COORDINATES(); coord.setAuthority("NCBI");
294 * coord.setSource("Chromosome"); coord.setTaxid("9606");
295 * coord.setVersion("35"); version.getCOORDINATES().add(coord);
297 CAPABILITY cap = new CAPABILITY();
298 cap.setType("das1:" + Capabilities.SEQUENCE.getName());
299 cap.setQueryUri(url + "/sequence");
304 CAPABILITY cap = new CAPABILITY();
305 cap.setType("das1:" + Capabilities.FEATURES.getName());
306 cap.setQueryUri(url + "/features");
310 v.getCAPABILITY().addAll(cp);
311 local.getVERSION().add(v);
317 public jalviewSourceI getSource(String nickname)
319 return sourceNames.get(nickname);
323 public boolean removeLocalSource(jalviewSourceI source)
325 if (localSources.containsValue(source))
327 localSources.remove(source.getTitle());
328 sourceNames.remove(source.getTitle());
329 dasSources.remove(source);
330 jalview.bin.Cache.setProperty("DAS_LOCAL_SOURCE",
331 getLocalSourceString());
339 public void refreshSources()
347 public List<jalviewSourceI> resolveSourceNicknames(List<String> sources)
349 ArrayList<jalviewSourceI> resolved = new ArrayList<jalviewSourceI>();
350 if (sourceNames != null)
352 for (String src : sources)
354 jalviewSourceI dsrc = sourceNames.get(src);
365 public String getLocalSourceString()
367 if (localSources != null)
369 StringBuffer sb = new StringBuffer();
370 Enumeration en = localSources.keys();
371 while (en.hasMoreElements())
373 String token = en.nextElement().toString();
374 jalviewSourceI srco = localSources.get(token);
375 sb.append(token + "|" + (srco.isSequenceSource() ? "sequence:" : "")
376 + srco.getUri() + "\t");
378 return sb.toString();
383 private static final Hashtable<URL, String> authStash;
386 authStash = new Hashtable<URL, String>();
390 // TODO: allow same credentials for https and http
392 new URL("http://www.compbio.dundee.ac.uk/geneweb/das/myseq/"),
393 "Basic SmltOm1pSg==");
394 } catch (MalformedURLException e)
396 // TODO Auto-generated catch block
402 public MultipleConnectionPropertyProviderI getSessionHandler()
408 public ConnectionPropertyProviderI getConnectionPropertyProviderFor(
412 final ConnectionPropertyProviderI conprov = new ConnectionPropertyProviderI()
414 boolean authed = false;
417 public void setConnectionProperties(HttpURLConnection connection)
419 String auth = authStash.get(connection.getURL());
420 if (auth != null && auth.length() > 0)
422 connection.setRequestProperty("Authorisation", auth);
432 public boolean getResponseProperties(HttpURLConnection connection)
434 String auth = authStash.get(connection.getURL());
435 if (auth != null && auth.length() == 0)
437 // don't attempt to check if we authed or not - user entered empty
445 // try and pass credentials.
448 // see if we should try and create a new auth record.
449 String ameth = connection.getHeaderField("X-DAS-AuthMethods");
450 Cache.log.debug("Could authenticate to " + connection.getURL()
451 + " with : " + ameth);
452 // TODO: search auth string and raise login box - return if auth was
458 // check to see if auth was successful
459 String asuc = connection
460 .getHeaderField("X-DAS_AuthenticatedUser");
461 if (asuc != null && asuc.trim().length() > 0)
463 // authentication was successful
464 Cache.log.debug("Authenticated successfully to "
465 + connection.getURL().toString());
468 // it wasn't - so we should tell the user it failed and ask if they
469 // want to attempt authentication again.
470 authStash.remove(connection.getURL());
471 // open a new login/password dialog with cancel button
472 // set new authStash content with password and return true
474 // User cancelled auth - so put empty string in stash to indicate we
475 // don't want to auth with this server.
476 // authStash.put(connection.getURL(), "");