package jalview.ws.seqfetcher;\r
\r
import jalview.datamodel.AlignmentI;\r
+import jalview.datamodel.DBRefEntry;\r
import jalview.datamodel.SequenceI;\r
+import jalview.util.DBRefUtils;\r
\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
import java.util.Enumeration;\r
+import java.util.HashSet;\r
import java.util.Hashtable;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Stack;\r
import java.util.Vector;\r
\r
public class ASequenceFetcher\r
/**\r
* set of databases we can retrieve entries from\r
*/\r
- protected Hashtable FETCHABLEDBS;\r
+ protected Hashtable<String, Map<String, DbSourceProxy>> FETCHABLEDBS;\r
\r
public ASequenceFetcher()\r
{\r
public SequenceI[] getSequences(jalview.datamodel.DBRefEntry[] refs)\r
{\r
SequenceI[] ret = null;\r
- Vector rseqs = new Vector();\r
- Hashtable queries = new Hashtable();\r
+ Vector<SequenceI> rseqs = new Vector();\r
+ Hashtable<String, List<String>> queries = new Hashtable();\r
for (int r = 0; r < refs.length; r++)\r
{\r
if (!queries.containsKey(refs[r].getSource()))\r
{\r
- queries.put(refs[r].getSource(), new Vector());\r
+ queries.put(refs[r].getSource(), new ArrayList<String>());\r
}\r
- Vector qset = (Vector) queries.get(refs[r].getSource());\r
+ List<String> qset = queries.get(refs[r].getSource());\r
if (!qset.contains(refs[r].getAccessionId()))\r
{\r
- qset.addElement(refs[r].getAccessionId());\r
+ qset.add(refs[r].getAccessionId());\r
}\r
}\r
- Enumeration e = queries.keys();\r
+ Enumeration<String> e = queries.keys();\r
while (e.hasMoreElements())\r
{\r
- Vector query = null;\r
+ List<String> query = null;\r
String db = null;\r
- try\r
+ db = e.nextElement();\r
+ query = queries.get(db);\r
+ if (!isFetchable(db))\r
{\r
- db = (String) e.nextElement();\r
- query = (Vector) queries.get(db);\r
- if (!isFetchable(db))\r
- throw new Exception(\r
- "Don't know how to fetch from this database :" + db);\r
- DbSourceProxy fetcher = getSourceProxy(db);\r
- boolean doMultiple = fetcher.getAccessionSeparator() != null; // No\r
- // separator\r
- // - no\r
- // Multiple\r
- // Queries\r
- Enumeration qs = query.elements();\r
- while (qs.hasMoreElements())\r
+ reportStdError(db, query, new Exception(\r
+ "Don't know how to fetch from this database :" + db));\r
+ continue;\r
+ }\r
+ Iterator<DbSourceProxy> fetchers = getSourceProxy(db).iterator();\r
+ Stack<String> queriesLeft = new Stack<String>();\r
+// List<String> queriesFailed = new ArrayList<String>();\r
+ queriesLeft.addAll(query);\r
+ while (fetchers.hasNext())\r
+ {\r
+ List<String> queriesMade = new ArrayList<String>();\r
+ HashSet queriesFound = new HashSet<String>();\r
+ try\r
{\r
- StringBuffer qsb = new StringBuffer();\r
- do\r
+ DbSourceProxy fetcher = fetchers.next();\r
+ boolean doMultiple = fetcher.getAccessionSeparator() != null; // No\r
+ // separator\r
+ // - no\r
+ // Multiple\r
+ // Queries\r
+ while (!queriesLeft.isEmpty())\r
{\r
- qsb.append((String) qs.nextElement());\r
- if (qs.hasMoreElements() && doMultiple) // and not reached limit for\r
- // multiple queries at one\r
- // time for this source\r
+ StringBuffer qsb = new StringBuffer();\r
+ do\r
{\r
- qsb.append(fetcher.getAccessionSeparator());\r
- }\r
- } while (doMultiple && qs.hasMoreElements());\r
-\r
- AlignmentI seqset = null;\r
- try\r
- {\r
- // create a fetcher and go to it\r
- seqset = fetcher.getSequenceRecords(qsb.toString());\r
- } catch (Exception ex)\r
- {\r
- System.err.println("Failed to retrieve the following from "\r
- + db);\r
- System.err.println(qsb);\r
- ex.printStackTrace(System.err);\r
- }\r
- // TODO: Merge alignment together - perhaps\r
- if (seqset != null)\r
- {\r
- SequenceI seqs[] = seqset.getSequencesArray();\r
- if (seqs != null)\r
- {\r
- for (int is = 0; is < seqs.length; is++)\r
+ if (qsb.length() > 0)\r
{\r
- rseqs.addElement(seqs[is]);\r
- seqs[is] = null;\r
+ qsb.append(fetcher.getAccessionSeparator());\r
}\r
+ String q = queriesLeft.pop();\r
+ queriesMade.add(q);\r
+ qsb.append(q);\r
+ } while (doMultiple && !queriesLeft.isEmpty());\r
+\r
+ AlignmentI seqset = null;\r
+ try\r
+ {\r
+ // create a fetcher and go to it\r
+ seqset = fetcher.getSequenceRecords(qsb.toString()); // ,\r
+ // queriesFailed);\r
+ } catch (Exception ex)\r
+ {\r
+ System.err.println("Failed to retrieve the following from "\r
+ + db);\r
+ System.err.println(qsb);\r
+ ex.printStackTrace(System.err);\r
}\r
- else\r
+ // TODO: Merge alignment together - perhaps\r
+ if (seqset != null)\r
{\r
- if (fetcher.getRawRecords() != null)\r
+ SequenceI seqs[] = seqset.getSequencesArray();\r
+ if (seqs != null)\r
+ {\r
+ for (int is = 0; is < seqs.length; is++)\r
+ {\r
+ rseqs.addElement(seqs[is]);\r
+ DBRefEntry[] frefs = DBRefUtils.searchRefs(seqs[is]\r
+ .getDBRef(), new DBRefEntry(db, null, null));\r
+ if (frefs != null)\r
+ {\r
+ for (DBRefEntry dbr : frefs)\r
+ {\r
+ queriesFound.add(dbr.getAccessionId());\r
+ queriesMade.remove(dbr.getAccessionId());\r
+ }\r
+ }\r
+ seqs[is] = null;\r
+ }\r
+ }\r
+ else\r
{\r
- System.out.println("# Retrieved from " + db + ":"\r
- + qs.toString());\r
- StringBuffer rrb = fetcher.getRawRecords();\r
- /*\r
- * for (int rr = 0; rr<rrb.length; rr++) {\r
- */\r
- String hdr;\r
- // if (rr<qs.length)\r
- // {\r
- hdr = "# " + db + ":" + qsb.toString();\r
- /*\r
- * } else { hdr = "# part "+rr; }\r
- */\r
- System.out.println(hdr);\r
- if (rrb != null)\r
- System.out.println(rrb);\r
- System.out.println("# end of " + hdr);\r
+ if (fetcher.getRawRecords() != null)\r
+ {\r
+ System.out.println("# Retrieved from " + db + ":"\r
+ + qsb.toString());\r
+ StringBuffer rrb = fetcher.getRawRecords();\r
+ /*\r
+ * for (int rr = 0; rr<rrb.length; rr++) {\r
+ */\r
+ String hdr;\r
+ // if (rr<qs.length)\r
+ // {\r
+ hdr = "# " + db + ":" + qsb.toString();\r
+ /*\r
+ * } else { hdr = "# part "+rr; }\r
+ */\r
+ System.out.println(hdr);\r
+ if (rrb != null)\r
+ System.out.println(rrb);\r
+ System.out.println("# end of " + hdr);\r
+ }\r
+\r
}\r
}\r
+\r
}\r
+ } catch (Exception ex)\r
+ {\r
+ reportStdError(db, queriesMade, ex);\r
}\r
- } catch (Exception ex)\r
- {\r
- System.err\r
- .println("Failed to retrieve the following references from "\r
- + db);\r
- Enumeration qv = query.elements();\r
- int n = 0;\r
- while (qv.hasMoreElements())\r
+ if (queriesMade.size() > 0)\r
{\r
- System.err.print(" " + qv.nextElement() + ";");\r
- if (n++ > 10)\r
- {\r
- System.err.println();\r
- n = 0;\r
- }\r
+ System.out.println("# Adding " + queriesMade.size()\r
+ + " ids back to queries list for searching again (" + db\r
+ + ".");\r
+ queriesLeft.addAll(queriesMade);\r
}\r
- System.err.println();\r
- ex.printStackTrace();\r
}\r
}\r
if (rseqs.size() > 0)\r
return ret;\r
}\r
\r
+ public void reportStdError(String db, List<String> queriesMade,\r
+ Exception ex)\r
+ {\r
+\r
+ System.err.println("Failed to retrieve the following references from "\r
+ + db);\r
+ int n = 0;\r
+ for (String qv : queriesMade)\r
+ {\r
+ System.err.print(" " + qv + ";");\r
+ if (n++ > 10)\r
+ {\r
+ System.err.println();\r
+ n = 0;\r
+ }\r
+ }\r
+ System.err.println();\r
+ ex.printStackTrace();\r
+ }\r
+\r
/**\r
* Retrieve an instance of the proxy for the given source\r
* \r
* retrieval of specific DB source/version combinations.\r
* @return an instance of DbSourceProxy for that db.\r
*/\r
- public DbSourceProxy getSourceProxy(String db)\r
+ public List<DbSourceProxy> getSourceProxy(String db)\r
{\r
- DbSourceProxy dbs = (DbSourceProxy) FETCHABLEDBS.get(db);\r
+ List<DbSourceProxy> dbs;\r
+ Map<String,DbSourceProxy> dblist = FETCHABLEDBS.get(db);\r
+ if (dblist==null) {return new ArrayList<DbSourceProxy>();};\r
+ if (dblist.size()>1) {\r
+ DbSourceProxy[] l=dblist.values().toArray(new DbSourceProxy[0]);\r
+ int i=0;\r
+ String[] nm=new String[l.length];\r
+ for (DbSourceProxy s:l)\r
+ {\r
+ nm[i++]=s.getDbName().toLowerCase();\r
+ }\r
+ jalview.util.QuickSort.sort(nm,l);\r
+ dbs = new ArrayList<DbSourceProxy>();\r
+ for (i=l.length-1;i>=0; i--)\r
+ {\r
+ dbs.add(l[i]);\r
+ }\r
+ } else {\r
+ dbs = new ArrayList<DbSourceProxy>(dblist.values());\r
+ }\r
return dbs;\r
}\r
\r
{\r
if (FETCHABLEDBS == null)\r
{\r
- FETCHABLEDBS = new Hashtable();\r
+ FETCHABLEDBS = new Hashtable<String, Map<String,DbSourceProxy>>();\r
+ }\r
+ Map<String,DbSourceProxy> slist = FETCHABLEDBS.get(proxy.getDbSource());\r
+ if (slist == null)\r
+ {\r
+ FETCHABLEDBS.put(proxy.getDbSource(),\r
+ slist = new Hashtable<String,DbSourceProxy>());\r
}\r
- FETCHABLEDBS.put(proxy.getDbSource(), proxy);\r
+ slist.put(proxy.getDbName(),proxy);\r
}\r
}\r
\r
/**\r
* test if the database handler for dbName contains the given dbProperty\r
- * \r
+ * when a dbName resolves to a set of proxies - this method will return the result of the test for the first instance.\r
+ * TODO implement additional method to query all sources for a db to find one with a particular property\r
* @param dbName\r
* @param dbProperty\r
* @return true if proxy has the given property\r
public boolean hasDbSourceProperty(String dbName, String dbProperty)\r
{\r
// TODO: decide if invalidDbName exception is thrown here.\r
- DbSourceProxy proxy = getSourceProxy(dbName);\r
- if (proxy != null)\r
+\r
+ List<DbSourceProxy> proxies = getSourceProxy(dbName);\r
+ if (proxies != null)\r
{\r
- if (proxy.getDbSourceProperties() != null)\r
+ for (DbSourceProxy proxy : proxies)\r
{\r
- return proxy.getDbSourceProperties().containsKey(dbProperty);\r
+ if (proxy.getDbSourceProperties() != null)\r
+ {\r
+ return proxy.getDbSourceProperties().containsKey(dbProperty);\r
+ }\r
}\r
}\r
return false;\r
while (dbs.hasMoreElements())\r
{\r
String dbn = (String) dbs.nextElement();\r
- DbSourceProxy dbp = (DbSourceProxy) FETCHABLEDBS.get(dbn);\r
- if (class1.isAssignableFrom(dbp.getClass()))\r
+ for (DbSourceProxy dbp : FETCHABLEDBS.get(dbn).values())\r
{\r
- src.addElement(dbn);\r
+ if (class1.isAssignableFrom(dbp.getClass()))\r
+ {\r
+ src.addElement(dbn);\r
+ }\r
}\r
}\r
if (src.size() > 0)\r
}\r
return sources;\r
}\r
+ public DbSourceProxy[] getDbSourceProxyInstances(\r
+ Class class1)\r
+ {\r
+ ArrayList<DbSourceProxy> prlist=new ArrayList<DbSourceProxy>();\r
+ for (String fetchable:getSupportedDb())\r
+ for (DbSourceProxy pr:getSourceProxy(fetchable))\r
+ {\r
+ if (class1.isInstance(pr)) {prlist.add(pr);}\r
+ }\r
+ if (prlist.size()==0)\r
+ {\r
+ return null;\r
+ }\r
+ return prlist.toArray(new DbSourceProxy[0]);\r
+ }\r
+\r
}\r