X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fws%2Fseqfetcher%2FASequenceFetcher.java;h=05d541f95e6449a18569ab059b829b58ee0e7e57;hb=d1b697c33b69a6dfe55df789eec5ac9881013681;hp=0785ea2c044be3aeff136c4930d611cd8a6db9d9;hpb=2de36153a84ca246643cd28b2ce05e9f4159dd89;p=jalview.git diff --git a/src/jalview/ws/seqfetcher/ASequenceFetcher.java b/src/jalview/ws/seqfetcher/ASequenceFetcher.java index 0785ea2..05d541f 100644 --- a/src/jalview/ws/seqfetcher/ASequenceFetcher.java +++ b/src/jalview/ws/seqfetcher/ASequenceFetcher.java @@ -1,10 +1,36 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7) + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle + * + * 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 . + */ package jalview.ws.seqfetcher; import jalview.datamodel.AlignmentI; +import jalview.datamodel.DBRefEntry; import jalview.datamodel.SequenceI; +import jalview.util.DBRefUtils; +import java.util.ArrayList; +import java.util.Collection; import java.util.Enumeration; +import java.util.HashSet; import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Stack; import java.util.Vector; public class ASequenceFetcher @@ -13,7 +39,7 @@ public class ASequenceFetcher /** * set of databases we can retrieve entries from */ - protected Hashtable FETCHABLEDBS; + protected Hashtable> FETCHABLEDBS; public ASequenceFetcher() { @@ -58,125 +84,143 @@ public class ASequenceFetcher public SequenceI[] getSequences(jalview.datamodel.DBRefEntry[] refs) { SequenceI[] ret = null; - Vector rseqs = new Vector(); - Hashtable queries = new Hashtable(); + Vector rseqs = new Vector(); + Hashtable> queries = new Hashtable(); for (int r = 0; r < refs.length; r++) { if (!queries.containsKey(refs[r].getSource())) { - queries.put(refs[r].getSource(), new Vector()); + queries.put(refs[r].getSource(), new ArrayList()); } - Vector qset = (Vector) queries.get(refs[r].getSource()); + List qset = queries.get(refs[r].getSource()); if (!qset.contains(refs[r].getAccessionId())) { - qset.addElement(refs[r].getAccessionId()); + qset.add(refs[r].getAccessionId()); } } - Enumeration e = queries.keys(); + Enumeration e = queries.keys(); while (e.hasMoreElements()) { - Vector query = null; + List query = null; String db = null; - try + db = e.nextElement(); + query = queries.get(db); + if (!isFetchable(db)) { - db = (String) e.nextElement(); - query = (Vector) queries.get(db); - if (!isFetchable(db)) - throw new Exception( - "Don't know how to fetch from this database :" + db); - DbSourceProxy fetcher = getSourceProxy(db); - boolean doMultiple = fetcher.getAccessionSeparator() != null; // No - // separator - // - no - // Multiple - // Queries - Enumeration qs = query.elements(); - while (qs.hasMoreElements()) + reportStdError(db, query, new Exception( + "Don't know how to fetch from this database :" + db)); + continue; + } + Iterator fetchers = getSourceProxy(db).iterator(); + Stack queriesLeft = new Stack(); + // List queriesFailed = new ArrayList(); + queriesLeft.addAll(query); + while (fetchers.hasNext()) + { + List queriesMade = new ArrayList(); + HashSet queriesFound = new HashSet(); + try { - StringBuffer qsb = new StringBuffer(); - do - { - qsb.append((String) qs.nextElement()); - if (qs.hasMoreElements() && doMultiple) // and not reached limit for - // multiple queries at one - // time for this source - { - qsb.append(fetcher.getAccessionSeparator()); - } - } while (doMultiple && qs.hasMoreElements()); - - AlignmentI seqset=null; - try { - // create a fetcher and go to it - seqset = fetcher.getSequenceRecords(qsb.toString()); - } catch (Exception ex) + DbSourceProxy fetcher = fetchers.next(); + boolean doMultiple = fetcher.getAccessionSeparator() != null; // No + // separator + // - no + // Multiple + // Queries + while (!queriesLeft.isEmpty()) { - System.err.println("Failed to retrieve the following from "+db); - System.err.println(qsb); - ex.printStackTrace(System.err); - } - // TODO: Merge alignment together - perhaps - if (seqset != null) - { - SequenceI seqs[] = seqset.getSequencesArray(); - if (seqs != null) + StringBuffer qsb = new StringBuffer(); + do { - for (int is = 0; is < seqs.length; is++) + if (qsb.length() > 0) { - rseqs.addElement(seqs[is]); - seqs[is] = null; + qsb.append(fetcher.getAccessionSeparator()); } + String q = queriesLeft.pop(); + queriesMade.add(q); + qsb.append(q); + } while (doMultiple && !queriesLeft.isEmpty()); + + AlignmentI seqset = null; + try + { + // create a fetcher and go to it + seqset = fetcher.getSequenceRecords(qsb.toString()); // , + // queriesFailed); + } catch (Exception ex) + { + System.err.println("Failed to retrieve the following from " + + db); + System.err.println(qsb); + ex.printStackTrace(System.err); } - else + // TODO: Merge alignment together - perhaps + if (seqset != null) { - if (fetcher.getRawRecords() != null) + SequenceI seqs[] = seqset.getSequencesArray(); + if (seqs != null) { - System.out.println("# Retrieved from " + db + ":" - + qs.toString()); - StringBuffer rrb = fetcher.getRawRecords(); - /* - * for (int rr = 0; rr 0) { - System.err.print(" " + qv.nextElement() + ";"); - if (n++ > 10) - { - System.err.println(); - n = 0; - } + System.out.println("# Adding " + queriesMade.size() + + " ids back to queries list for searching again (" + db + + "."); + queriesLeft.addAll(queriesMade); } - System.err.println(); - ex.printStackTrace(); } } if (rseqs.size() > 0) { ret = new SequenceI[rseqs.size()]; Enumeration sqs = rseqs.elements(); - int si=0; + int si = 0; while (sqs.hasMoreElements()) { SequenceI s = (SequenceI) sqs.nextElement(); @@ -187,6 +231,26 @@ public class ASequenceFetcher return ret; } + public void reportStdError(String db, List queriesMade, + Exception ex) + { + + System.err.println("Failed to retrieve the following references from " + + db); + int n = 0; + for (String qv : queriesMade) + { + System.err.print(" " + qv + ";"); + if (n++ > 10) + { + System.err.println(); + n = 0; + } + } + System.err.println(); + ex.printStackTrace(); + } + /** * Retrieve an instance of the proxy for the given source * @@ -195,9 +259,35 @@ public class ASequenceFetcher * retrieval of specific DB source/version combinations. * @return an instance of DbSourceProxy for that db. */ - public DbSourceProxy getSourceProxy(String db) + public List getSourceProxy(String db) { - DbSourceProxy dbs = (DbSourceProxy) FETCHABLEDBS.get(db); + List dbs; + Map dblist = FETCHABLEDBS.get(db); + if (dblist == null) + { + return new ArrayList(); + } + ; + if (dblist.size() > 1) + { + DbSourceProxy[] l = dblist.values().toArray(new DbSourceProxy[0]); + int i = 0; + String[] nm = new String[l.length]; + for (DbSourceProxy s : l) + { + nm[i++] = s.getDbName().toLowerCase(); + } + jalview.util.QuickSort.sort(nm, l); + dbs = new ArrayList(); + for (i = l.length - 1; i >= 0; i--) + { + dbs.add(l[i]); + } + } + else + { + dbs = new ArrayList(dblist.values()); + } return dbs; } @@ -206,20 +296,19 @@ public class ASequenceFetcher * dbrefsource * * @param dbSourceProxy - * reference for class implementing - * jalview.ws.seqfetcher.DbSourceProxy + * reference for class implementing + * jalview.ws.seqfetcher.DbSourceProxy * @throws java.lang.IllegalArgumentException - * if class does not implement - * jalview.ws.seqfetcher.DbSourceProxy + * if class does not implement jalview.ws.seqfetcher.DbSourceProxy */ protected void addDBRefSourceImpl(Class dbSourceProxy) throws java.lang.IllegalArgumentException { - DbSourceProxy proxy = null; + DbSourceProxy proxy = null; try { - Object proxyObj = dbSourceProxy.getConstructor( - null).newInstance(null); + Object proxyObj = dbSourceProxy.getConstructor(null) + .newInstance(null); if (!DbSourceProxy.class.isInstance(proxyObj)) { throw new IllegalArgumentException( @@ -227,20 +316,21 @@ public class ASequenceFetcher + " does not implement the jalview.ws.seqfetcher.DbSourceProxy"); } proxy = (DbSourceProxy) proxyObj; - } - catch (IllegalArgumentException e) + } catch (IllegalArgumentException e) { throw e; - } - catch (Exception e) + } catch (Exception e) { // Serious problems if this happens. throw new Error("DBRefSource Implementation Exception", e); } addDbRefSourceImpl(proxy); } + /** - * add the properly initialised DbSourceProxy object 'proxy' to the list of sequence fetchers + * add the properly initialised DbSourceProxy object 'proxy' to the list of + * sequence fetchers + * * @param proxy */ protected void addDbRefSourceImpl(DbSourceProxy proxy) @@ -249,14 +339,25 @@ public class ASequenceFetcher { if (FETCHABLEDBS == null) { - FETCHABLEDBS = new Hashtable(); + FETCHABLEDBS = new Hashtable>(); + } + Map slist = FETCHABLEDBS.get(proxy + .getDbSource()); + if (slist == null) + { + FETCHABLEDBS.put(proxy.getDbSource(), + slist = new Hashtable()); } - FETCHABLEDBS.put(proxy.getDbSource(), proxy); + slist.put(proxy.getDbName(), proxy); } } /** - * test if the database handler for dbName contains the given dbProperty + * test if the database handler for dbName contains the given dbProperty when + * a dbName resolves to a set of proxies - this method will return the result + * of the test for the first instance. TODO implement additional method to + * query all sources for a db to find one with a particular property + * * @param dbName * @param dbProperty * @return true if proxy has the given property @@ -264,15 +365,76 @@ public class ASequenceFetcher public boolean hasDbSourceProperty(String dbName, String dbProperty) { // TODO: decide if invalidDbName exception is thrown here. - DbSourceProxy proxy = getSourceProxy(dbName); - if (proxy!=null) + + List proxies = getSourceProxy(dbName); + if (proxies != null) { - if (proxy.getDbSourceProperties()!=null) + for (DbSourceProxy proxy : proxies) { - return proxy.getDbSourceProperties().containsKey(dbProperty); + if (proxy.getDbSourceProperties() != null) + { + return proxy.getDbSourceProperties().containsKey(dbProperty); + } } } return false; } -} \ No newline at end of file + /** + * select sources which are implemented by instances of the given class + * + * @param class that implements DbSourceProxy + * @return null or vector of source names for fetchers + */ + public String[] getDbInstances(Class class1) + { + if (!jalview.ws.seqfetcher.DbSourceProxy.class.isAssignableFrom(class1)) + { + throw new Error( + "Implmentation Error - getDbInstances must be given a class that implements jalview.ws.seqfetcher.DbSourceProxy (was given '" + + class1 + "')"); + } + if (FETCHABLEDBS == null) + { + return null; + } + String[] sources = null; + Vector src = new Vector(); + Enumeration dbs = FETCHABLEDBS.keys(); + while (dbs.hasMoreElements()) + { + String dbn = (String) dbs.nextElement(); + for (DbSourceProxy dbp : FETCHABLEDBS.get(dbn).values()) + { + if (class1.isAssignableFrom(dbp.getClass())) + { + src.addElement(dbn); + } + } + } + if (src.size() > 0) + { + src.copyInto(sources = new String[src.size()]); + } + return sources; + } + + public DbSourceProxy[] getDbSourceProxyInstances(Class class1) + { + ArrayList prlist = new ArrayList(); + for (String fetchable : getSupportedDb()) + for (DbSourceProxy pr : getSourceProxy(fetchable)) + { + if (class1.isInstance(pr)) + { + prlist.add(pr); + } + } + if (prlist.size() == 0) + { + return null; + } + return prlist.toArray(new DbSourceProxy[0]); + } + +}