/* * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.ws.dbsources.das.datamodel; import jalview.bin.Cache; import jalview.ws.dbsources.das.api.DasSourceRegistryI; import jalview.ws.dbsources.das.api.jalviewSourceI; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.StringTokenizer; import org.biodas.jdas.client.ConnectionPropertyProviderI; import org.biodas.jdas.client.SourcesClient; import org.biodas.jdas.client.threads.MultipleConnectionPropertyProviderI; import org.biodas.jdas.dassources.Capabilities; import org.biodas.jdas.schema.sources.CAPABILITY; import org.biodas.jdas.schema.sources.SOURCE; import org.biodas.jdas.schema.sources.SOURCES; import org.biodas.jdas.schema.sources.VERSION; /** * */ public class DasSourceRegistry implements DasSourceRegistryI, MultipleConnectionPropertyProviderI { // private org.biodas.jdas.schema.sources.SOURCE[] dasSources = null; private List dasSources = null; private Hashtable sourceNames = null; private Hashtable localSources = null; // public static String DEFAULT_REGISTRY = "http://www.dasregistry.org/das/"; public static String DEFAULT_REGISTRY = "http://www.ebi.ac.uk/das-srv/registry/das/"; /** * true if thread is running and we are talking to DAS registry service */ private boolean loadingDasSources = false; public boolean isLoadingDasSources() { return loadingDasSources; } public String getDasRegistryURL() { String registry = jalview.bin.Cache.getDefault("DAS_REGISTRY_URL", DEFAULT_REGISTRY); if (registry.indexOf("/registry/das1/sources/") > -1) { jalview.bin.Cache.setProperty(jalview.bin.Cache.DAS_REGISTRY_URL, DEFAULT_REGISTRY); registry = DEFAULT_REGISTRY; } if (registry.lastIndexOf("sources.xml") == registry.length() - 11) { // no trailing sources.xml document for registry in JDAS jalview.bin.Cache.setProperty( jalview.bin.Cache.DAS_REGISTRY_URL, registry = registry.substring(0, registry.lastIndexOf("sources.xml"))); } return registry; } /** * query the default DAS Source Registry for sources. Uses value of jalview * property DAS_REGISTRY_URL and the DasSourceBrowser.DEFAULT_REGISTRY if that * doesn't exist. * * @return list of sources */ private List getDASSources() { return getDASSources(getDasRegistryURL(), this); } /** * query the given URL for DasSources. * * @param registryURL * return sources from registryURL */ private static List getDASSources(String registryURL, MultipleConnectionPropertyProviderI registry) { try { URL url = new URL(registryURL); org.biodas.jdas.client.SourcesClientInterface client = new SourcesClient(); SOURCES sources = client.fetchDataRegistry(registryURL, null, null, null, null, null, null); List dassources = sources.getSOURCE(); ArrayList dsrc = new ArrayList(); HashMap latests = new HashMap(); Integer latest; for (SOURCE src : dassources) { JalviewSource jsrc = new JalviewSource(src, registry, false); latest = latests.get(jsrc.getSourceURL()); if (latest != null) { if (jsrc.isNewerThan(dsrc.get(latest.intValue()))) { dsrc.set(latest.intValue(), jsrc); } else { System.out.println("Debug: Ignored older source " + jsrc.getTitle()); } } else { latests.put(jsrc.getSourceURL(), Integer.valueOf(dsrc.size())); dsrc.add(jsrc); } } return dsrc; } catch (Exception ex) { System.err.println("Failed to contact DAS1 registry at " + registryURL); ex.printStackTrace(); return new ArrayList(); } } public void run() { getSources(); } @Override public List getSources() { if (dasSources == null) { dasSources = getDASSources(); } return appendLocalSources(); } /** * generate Sources from the local das source list * */ private void addLocalDasSources() { if (localSources == null) { // get local sources from properties and initialise the local source list String local = jalview.bin.Cache.getProperty("DAS_LOCAL_SOURCE"); if (local != null) { int n = 1; StringTokenizer st = new StringTokenizer(local, "\t"); while (st.hasMoreTokens()) { String token = st.nextToken(); int bar = token.indexOf("|"); if (bar == -1) { System.err .println("Warning: DAS user local source appears to have no nickname (expected a '|' followed by nickname)\nOffending definition: '" + token + "'"); } String url = token.substring(bar + 1); boolean features = true, sequence = false; if (url.startsWith("sequence:")) { url = url.substring(9); // this source also serves sequences as well as features sequence = true; } try { if (bar > -1) { createLocalSource(url, token.substring(0, bar), sequence, features); } else { createLocalSource(url, "User Source" + n, sequence, features); } } catch (Exception q) { System.err .println("Unexpected exception when creating local source from '" + token + "'"); q.printStackTrace(); } n++; } } } } private List appendLocalSources() { List srclist = new ArrayList(); addLocalDasSources(); sourceNames = new Hashtable(); if (dasSources != null) { for (jalviewSourceI src : dasSources) { sourceNames.put(src.getTitle(), src); srclist.add(src); } } if (localSources == null) { return srclist; } Enumeration en = localSources.keys(); while (en.hasMoreElements()) { String key = en.nextElement().toString(); jalviewSourceI jvsrc = localSources.get(key); sourceNames.put(key, jvsrc); srclist.add(jvsrc); } return srclist; } /* * */ @Override public jalviewSourceI createLocalSource(String url, String name, boolean sequence, boolean features) { SOURCE local = _createLocalSource(url, name, sequence, features); if (localSources == null) { localSources = new Hashtable(); } jalviewSourceI src = new JalviewSource(local, this, true); localSources.put(local.getTitle(), src); return src; } private SOURCE _createLocalSource(String url, String name, boolean sequence, boolean features) { SOURCE local = new SOURCE(); local.setUri(url); local.setTitle(name); local.setVERSION(new ArrayList()); VERSION v = new VERSION(); List cp = new ArrayList(); if (sequence) { /* * Could try and synthesize a coordinate system for the source if needbe * COORDINATES coord = new COORDINATES(); coord.setAuthority("NCBI"); * coord.setSource("Chromosome"); coord.setTaxid("9606"); * coord.setVersion("35"); version.getCOORDINATES().add(coord); */ CAPABILITY cap = new CAPABILITY(); cap.setType("das1:" + Capabilities.SEQUENCE.getName()); cap.setQueryUri(url + "/sequence"); cp.add(cap); } if (features) { CAPABILITY cap = new CAPABILITY(); cap.setType("das1:" + Capabilities.FEATURES.getName()); cap.setQueryUri(url + "/features"); cp.add(cap); } v.getCAPABILITY().addAll(cp); local.getVERSION().add(v); return local; } @Override public jalviewSourceI getSource(String nickname) { return sourceNames.get(nickname); } @Override public boolean removeLocalSource(jalviewSourceI source) { if (localSources.containsValue(source)) { localSources.remove(source.getTitle()); sourceNames.remove(source.getTitle()); dasSources.remove(source); jalview.bin.Cache.setProperty("DAS_LOCAL_SOURCE", getLocalSourceString()); return true; } return false; } @Override public void refreshSources() { dasSources = null; sourceNames = null; run(); } @Override public List resolveSourceNicknames(List sources) { ArrayList resolved = new ArrayList(); if (sourceNames != null) { for (String src : sources) { jalviewSourceI dsrc = sourceNames.get(src); if (dsrc != null) { resolved.add(dsrc); } } } return resolved; } @Override public String getLocalSourceString() { if (localSources != null) { StringBuffer sb = new StringBuffer(); Enumeration en = localSources.keys(); while (en.hasMoreElements()) { String token = en.nextElement().toString(); jalviewSourceI srco = localSources.get(token); sb.append(token + "|" + (srco.isSequenceSource() ? "sequence:" : "") + srco.getUri() + "\t"); } return sb.toString(); } return ""; } private static final Hashtable authStash; static { authStash = new Hashtable(); try { // TODO: allow same credentials for https and http authStash.put(new URL( "http://www.compbio.dundee.ac.uk/geneweb/das/myseq/"), "Basic SmltOm1pSg=="); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public MultipleConnectionPropertyProviderI getSessionHandler() { return this; } @Override public ConnectionPropertyProviderI getConnectionPropertyProviderFor( String arg0) { final ConnectionPropertyProviderI conprov = new ConnectionPropertyProviderI() { boolean authed = false; @Override public void setConnectionProperties(HttpURLConnection connection) { String auth = authStash.get(connection.getURL()); if (auth != null && auth.length() > 0) { connection.setRequestProperty("Authorisation", auth); authed = true; } else { authed = false; } } @Override public boolean getResponseProperties(HttpURLConnection connection) { String auth = authStash.get(connection.getURL()); if (auth != null && auth.length() == 0) { // don't attempt to check if we authed or not - user entered empty // password return false; } if (!authed) { if (auth != null) { // try and pass credentials. return true; } // see if we should try and create a new auth record. String ameth = connection.getHeaderField("X-DAS-AuthMethods"); Cache.log.debug("Could authenticate to " + connection.getURL() + " with : " + ameth); // TODO: search auth string and raise login box - return if auth was // provided return false; } else { // check to see if auth was successful String asuc = connection .getHeaderField("X-DAS_AuthenticatedUser"); if (asuc != null && asuc.trim().length() > 0) { // authentication was successful Cache.log.debug("Authenticated successfully to " + connection.getURL().toString()); return false; } // it wasn't - so we should tell the user it failed and ask if they // want to attempt authentication again. authStash.remove(connection.getURL()); // open a new login/password dialog with cancel button // set new authStash content with password and return true return true; // // User cancelled auth - so put empty string in stash to indicate we // don't want to auth with this server. // authStash.put(connection.getURL(), ""); // return false; } } }; return conprov; } }