X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fws%2Fseqfetcher%2FASequenceFetcher.java;h=cf60b630282b0224f54f4326cb176b9dafdd849b;hb=865a855a4ca87eadb3e5ff284ed32ed307d9c34b;hp=013fb1593d77db8ccfe6acb1c4bab7e1d2e11fe5;hpb=729da71b3927879d79062fe4770ed024068bbd17;p=jalview.git diff --git a/src/jalview/ws/seqfetcher/ASequenceFetcher.java b/src/jalview/ws/seqfetcher/ASequenceFetcher.java index 013fb15..cf60b63 100644 --- a/src/jalview/ws/seqfetcher/ASequenceFetcher.java +++ b/src/jalview/ws/seqfetcher/ASequenceFetcher.java @@ -1,333 +1,441 @@ -/* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4) - * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle - * - * This program 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 2 - * of the License, or (at your option) any later version. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ -package jalview.ws.seqfetcher; - -import jalview.datamodel.AlignmentI; -import jalview.datamodel.SequenceI; - -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -public class ASequenceFetcher -{ - - /** - * set of databases we can retrieve entries from - */ - protected Hashtable FETCHABLEDBS; - - public ASequenceFetcher() - { - super(); - } - - /** - * get list of supported Databases - * - * @return database source string for each database - only the latest version - * of a source db is bound to each source. - */ - public String[] getSupportedDb() - { - if (FETCHABLEDBS == null) - return null; - String[] sf = new String[FETCHABLEDBS.size()]; - Enumeration e = FETCHABLEDBS.keys(); - int i = 0; - while (e.hasMoreElements()) - { - sf[i++] = (String) e.nextElement(); - } - ; - return sf; - } - - public boolean isFetchable(String source) - { - Enumeration e = FETCHABLEDBS.keys(); - while (e.hasMoreElements()) - { - String db = (String) e.nextElement(); - if (source.compareToIgnoreCase(db) == 0) - return true; - } - jalview.bin.Cache.log.warn("isFetchable doesn't know about '" + source - + "'"); - return false; - } - - public SequenceI[] getSequences(jalview.datamodel.DBRefEntry[] refs) - { - SequenceI[] ret = null; - 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()); - } - Vector qset = (Vector) queries.get(refs[r].getSource()); - if (!qset.contains(refs[r].getAccessionId())) - { - qset.addElement(refs[r].getAccessionId()); - } - } - Enumeration e = queries.keys(); - while (e.hasMoreElements()) - { - Vector query = null; - String db = null; - try - { - 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()) - { - 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) - { - 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) - { - for (int is = 0; is < seqs.length; is++) - { - rseqs.addElement(seqs[is]); - seqs[is] = null; - } - } - else - { - if (fetcher.getRawRecords() != null) - { - System.out.println("# Retrieved from " + db + ":" - + qs.toString()); - StringBuffer rrb = fetcher.getRawRecords(); - /* - * for (int rr = 0; rr 10) - { - System.err.println(); - n = 0; - } - } - System.err.println(); - ex.printStackTrace(); - } - } - if (rseqs.size() > 0) - { - ret = new SequenceI[rseqs.size()]; - Enumeration sqs = rseqs.elements(); - int si = 0; - while (sqs.hasMoreElements()) - { - SequenceI s = (SequenceI) sqs.nextElement(); - ret[si++] = s; - s.updatePDBIds(); - } - } - return ret; - } - - /** - * Retrieve an instance of the proxy for the given source - * - * @param db - * database source string TODO: add version string/wildcard for - * retrieval of specific DB source/version combinations. - * @return an instance of DbSourceProxy for that db. - */ - public DbSourceProxy getSourceProxy(String db) - { - DbSourceProxy dbs = (DbSourceProxy) FETCHABLEDBS.get(db); - return dbs; - } - - /** - * constructs and instance of the proxy and registers it as a valid - * dbrefsource - * - * @param dbSourceProxy - * reference for class implementing - * jalview.ws.seqfetcher.DbSourceProxy - * @throws java.lang.IllegalArgumentException - * if class does not implement - * jalview.ws.seqfetcher.DbSourceProxy - */ - protected void addDBRefSourceImpl(Class dbSourceProxy) - throws java.lang.IllegalArgumentException - { - DbSourceProxy proxy = null; - try - { - Object proxyObj = dbSourceProxy.getConstructor(null) - .newInstance(null); - if (!DbSourceProxy.class.isInstance(proxyObj)) - { - throw new IllegalArgumentException( - dbSourceProxy.toString() - + " does not implement the jalview.ws.seqfetcher.DbSourceProxy"); - } - proxy = (DbSourceProxy) proxyObj; - } catch (IllegalArgumentException e) - { - throw 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 - * - * @param proxy - */ - protected void addDbRefSourceImpl(DbSourceProxy proxy) - { - if (proxy != null) - { - if (FETCHABLEDBS == null) - { - FETCHABLEDBS = new Hashtable(); - } - FETCHABLEDBS.put(proxy.getDbSource(), proxy); - } - } - - /** - * test if the database handler for dbName contains the given dbProperty - * - * @param dbName - * @param dbProperty - * @return true if proxy has the given property - */ - public boolean hasDbSourceProperty(String dbName, String dbProperty) - { - // TODO: decide if invalidDbName exception is thrown here. - DbSourceProxy proxy = getSourceProxy(dbName); - if (proxy != null) - { - if (proxy.getDbSourceProperties() != null) - { - return proxy.getDbSourceProperties().containsKey(dbProperty); - } - } - return false; - } - - /** - * 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(); - DbSourceProxy dbp = (DbSourceProxy) FETCHABLEDBS.get(dbn); - if (class1.isAssignableFrom(dbp.getClass())) - { - src.addElement(dbn); - } - } - if (src.size()>0) - { - src.copyInto(sources = new String[src.size()]); - } - return sources; - } -} +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.0b1) + * Copyright (C) 2014 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.seqfetcher; + +import jalview.datamodel.AlignmentI; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.SequenceI; +import jalview.util.DBRefUtils; + +import java.util.ArrayList; +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 +{ + + /** + * set of databases we can retrieve entries from + */ + protected Hashtable> FETCHABLEDBS; + + public ASequenceFetcher() + { + super(); + } + + /** + * get list of supported Databases + * + * @return database source string for each database - only the latest version + * of a source db is bound to each source. + */ + public String[] getSupportedDb() + { + if (FETCHABLEDBS == null) + return null; + String[] sf = new String[FETCHABLEDBS.size()]; + Enumeration e = FETCHABLEDBS.keys(); + int i = 0; + while (e.hasMoreElements()) + { + sf[i++] = (String) e.nextElement(); + } + ; + return sf; + } + + public boolean isFetchable(String source) + { + Enumeration e = FETCHABLEDBS.keys(); + while (e.hasMoreElements()) + { + String db = (String) e.nextElement(); + if (source.compareToIgnoreCase(db) == 0) + return true; + } + jalview.bin.Cache.log.warn("isFetchable doesn't know about '" + source + + "'"); + return false; + } + + public SequenceI[] getSequences(jalview.datamodel.DBRefEntry[] refs) + { + SequenceI[] ret = null; + 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 ArrayList()); + } + List qset = queries.get(refs[r].getSource()); + if (!qset.contains(refs[r].getAccessionId())) + { + qset.add(refs[r].getAccessionId()); + } + } + Enumeration e = queries.keys(); + while (e.hasMoreElements()) + { + List query = null; + String db = null; + db = e.nextElement(); + query = queries.get(db); + if (!isFetchable(db)) + { + 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 + { + DbSourceProxy fetcher = fetchers.next(); + boolean doMultiple = fetcher.getAccessionSeparator() != null; // No + // separator + // - no + // Multiple + // Queries + while (!queriesLeft.isEmpty()) + { + StringBuffer qsb = new StringBuffer(); + do + { + if (qsb.length() > 0) + { + 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); + } + // TODO: Merge alignment together - perhaps + if (seqset != null) + { + SequenceI seqs[] = seqset.getSequencesArray(); + if (seqs != null) + { + for (int is = 0; is < seqs.length; is++) + { + rseqs.addElement(seqs[is]); + DBRefEntry[] frefs = DBRefUtils.searchRefs(seqs[is] + .getDBRef(), new DBRefEntry(db, null, null)); + if (frefs != null) + { + for (DBRefEntry dbr : frefs) + { + queriesFound.add(dbr.getAccessionId()); + queriesMade.remove(dbr.getAccessionId()); + } + } + seqs[is] = null; + } + } + else + { + if (fetcher.getRawRecords() != null) + { + System.out.println("# Retrieved from " + db + ":" + + qsb.toString()); + StringBuffer rrb = fetcher.getRawRecords(); + /* + * for (int rr = 0; rr 0) + { + System.out.println("# Adding " + queriesMade.size() + + " ids back to queries list for searching again (" + db + + "."); + queriesLeft.addAll(queriesMade); + } + } + } + if (rseqs.size() > 0) + { + ret = new SequenceI[rseqs.size()]; + Enumeration sqs = rseqs.elements(); + int si = 0; + while (sqs.hasMoreElements()) + { + SequenceI s = (SequenceI) sqs.nextElement(); + ret[si++] = s; + s.updatePDBIds(); + } + } + 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 + * + * @param db + * database source string TODO: add version string/wildcard for + * retrieval of specific DB source/version combinations. + * @return an instance of DbSourceProxy for that db. + */ + public List getSourceProxy(String 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]; + // make sure standard dbs appear first, followed by reference das sources, followed by anything else. + for (DbSourceProxy s : l) + { + nm[i++] = ""+s.getTier()+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; + } + + /** + * constructs and instance of the proxy and registers it as a valid + * dbrefsource + * + * @param dbSourceProxy + * reference for class implementing + * jalview.ws.seqfetcher.DbSourceProxy + * @throws java.lang.IllegalArgumentException + * if class does not implement jalview.ws.seqfetcher.DbSourceProxy + */ + protected void addDBRefSourceImpl(Class dbSourceProxy) + throws java.lang.IllegalArgumentException + { + DbSourceProxy proxy = null; + try + { + Object proxyObj = dbSourceProxy.getConstructor(null) + .newInstance(null); + if (!DbSourceProxy.class.isInstance(proxyObj)) + { + throw new IllegalArgumentException( + dbSourceProxy.toString() + + " does not implement the jalview.ws.seqfetcher.DbSourceProxy"); + } + proxy = (DbSourceProxy) proxyObj; + } catch (IllegalArgumentException e) + { + throw 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 + * + * @param proxy + */ + protected void addDbRefSourceImpl(DbSourceProxy proxy) + { + if (proxy != null) + { + if (FETCHABLEDBS == null) + { + FETCHABLEDBS = new Hashtable>(); + } + Map slist = FETCHABLEDBS.get(proxy + .getDbSource()); + if (slist == null) + { + FETCHABLEDBS.put(proxy.getDbSource(), + slist = new Hashtable()); + } + slist.put(proxy.getDbName(), proxy); + } + } + + /** + * 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 + */ + public boolean hasDbSourceProperty(String dbName, String dbProperty) + { + // TODO: decide if invalidDbName exception is thrown here. + + List proxies = getSourceProxy(dbName); + if (proxies != null) + { + for (DbSourceProxy proxy : proxies) + { + if (proxy.getDbSourceProperties() != null) + { + return proxy.getDbSourceProperties().containsKey(dbProperty); + } + } + } + return false; + } + + /** + * 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]); + } + +}