/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
+ * 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.
+ * 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 <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
package jalview.ws.seqfetcher;
+import jalview.api.FeatureSettingsModelI;
+import jalview.bin.Cache;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.SequenceI;
import jalview.util.DBRefUtils;
+import jalview.util.MessageManager;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
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;
public class ASequenceFetcher
{
- /**
+ /*
* set of databases we can retrieve entries from
*/
- protected Hashtable<String, Map<String, DbSourceProxy>> FETCHABLEDBS;
+ protected Hashtable<String, Map<String, DbSourceProxy>> fetchableDbs;
+
+ /*
+ * comparator to sort by tier (0/1/2) and name
+ */
+ private Comparator<DbSourceProxy> proxyComparator;
- public ASequenceFetcher()
+ /**
+ * Constructor
+ */
+ protected ASequenceFetcher()
{
super();
+
+ /*
+ * comparator to sort proxies by tier and name
+ */
+ proxyComparator = new Comparator<DbSourceProxy>()
+ {
+ @Override
+ public int compare(DbSourceProxy o1, DbSourceProxy o2)
+ {
+ /*
+ * Tier 0 precedes 1 precedes 2
+ */
+ int compared = Integer.compare(o1.getTier(), o2.getTier());
+ if (compared == 0)
+ {
+ // defend against NullPointer - should never happen
+ String o1Name = o1.getDbName();
+ String o2Name = o2.getDbName();
+ if (o1Name != null && o2Name != null)
+ {
+ compared = o1Name.compareToIgnoreCase(o2Name);
+ }
+ }
+ return compared;
+ }
+ };
}
/**
- * get list of supported Databases
+ * get array 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())
+ if (fetchableDbs == null)
{
- sf[i++] = (String) e.nextElement();
+ return null;
}
- ;
+ String[] sf = fetchableDbs.keySet()
+ .toArray(new String[fetchableDbs.size()]);
return sf;
}
public boolean isFetchable(String source)
{
- Enumeration e = FETCHABLEDBS.keys();
- while (e.hasMoreElements())
+ for (String db : fetchableDbs.keySet())
{
- String db = (String) e.nextElement();
- if (source.compareToIgnoreCase(db) == 0)
+ if (source.equalsIgnoreCase(db))
+ {
return true;
+ }
}
- jalview.bin.Cache.log.warn("isFetchable doesn't know about '" + source
- + "'");
+ Cache.log.warn("isFetchable doesn't know about '" + source + "'");
return false;
}
- public SequenceI[] getSequences(jalview.datamodel.DBRefEntry[] refs)
+ /**
+ * Fetch sequences for the given cross-references
+ *
+ * @param refs
+ * @param dna
+ * if true, only fetch from nucleotide data sources, else peptide
+ * @return
+ */
+ public SequenceI[] getSequences(List<DBRefEntry> refs, boolean dna)
{
- SequenceI[] ret = null;
- Vector<SequenceI> rseqs = new Vector();
- Hashtable<String, List<String>> queries = new Hashtable();
- for (int r = 0; r < refs.length; r++)
+ Vector<SequenceI> rseqs = new Vector<>();
+ Hashtable<String, List<String>> queries = new Hashtable<>();
+ for (DBRefEntry ref : refs)
{
- if (!queries.containsKey(refs[r].getSource()))
+ String canonical = DBRefUtils.getCanonicalName(ref.getSource());
+ if (!queries.containsKey(canonical))
{
- queries.put(refs[r].getSource(), new ArrayList<String>());
+ queries.put(canonical, new ArrayList<String>());
}
- List<String> qset = queries.get(refs[r].getSource());
- if (!qset.contains(refs[r].getAccessionId()))
+ List<String> qset = queries.get(canonical);
+ if (!qset.contains(ref.getAccessionId()))
{
- qset.add(refs[r].getAccessionId());
+ qset.add(ref.getAccessionId());
}
}
Enumeration<String> e = queries.keys();
"Don't know how to fetch from this database :" + db));
continue;
}
- Iterator<DbSourceProxy> fetchers = getSourceProxy(db).iterator();
- Stack<String> queriesLeft = new Stack<String>();
- // List<String> queriesFailed = new ArrayList<String>();
+
+ Stack<String> queriesLeft = new Stack<>();
queriesLeft.addAll(query);
- while (fetchers.hasNext())
+
+ List<DbSourceProxy> proxies = getSourceProxy(db);
+ for (DbSourceProxy fetcher : proxies)
{
- List<String> queriesMade = new ArrayList<String>();
- HashSet queriesFound = new HashSet<String>();
+ List<String> queriesMade = new ArrayList<>();
+ HashSet<String> queriesFound = new HashSet<>();
try
{
- DbSourceProxy fetcher = fetchers.next();
- boolean doMultiple = fetcher.getAccessionSeparator() != null; // No
- // separator
- // - no
- // Multiple
- // Queries
+ if (fetcher.isDnaCoding() != dna)
+ {
+ continue; // wrong sort of data
+ }
+ boolean doMultiple = fetcher.getMaximumQueryCount() > 1;
while (!queriesLeft.isEmpty())
{
StringBuffer qsb = new StringBuffer();
try
{
// create a fetcher and go to it
- seqset = fetcher.getSequenceRecords(qsb.toString()); // ,
- // queriesFailed);
+ seqset = fetcher.getSequenceRecords(qsb.toString());
} catch (Exception ex)
{
- System.err.println("Failed to retrieve the following from "
- + db);
+ System.err.println(
+ "Failed to retrieve the following from " + db);
System.err.println(qsb);
ex.printStackTrace(System.err);
}
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)
+ List<DBRefEntry> frefs = DBRefUtils.searchRefs(
+ seqs[is].getDBRefs(),
+ new DBRefEntry(db, null, null));
+ for (DBRefEntry dbr : frefs)
{
- for (DBRefEntry dbr : frefs)
- {
- queriesFound.add(dbr.getAccessionId());
- queriesMade.remove(dbr.getAccessionId());
- }
+ queriesFound.add(dbr.getAccessionId());
+ queriesMade.remove(dbr.getAccessionId());
}
seqs[is] = null;
}
{
if (fetcher.getRawRecords() != null)
{
- System.out.println("# Retrieved from " + db + ":"
- + qsb.toString());
+ System.out.println(
+ "# Retrieved from " + db + ":" + qsb.toString());
StringBuffer rrb = fetcher.getRawRecords();
/*
* for (int rr = 0; rr<rrb.length; rr++) {
*/
System.out.println(hdr);
if (rrb != null)
+ {
System.out.println(rrb);
+ }
System.out.println("# end of " + hdr);
}
{
System.out.println("# Adding " + queriesMade.size()
+ " ids back to queries list for searching again (" + db
- + ".");
+ + ")");
queriesLeft.addAll(queriesMade);
}
}
}
+
+ SequenceI[] result = null;
if (rseqs.size() > 0)
{
- ret = new SequenceI[rseqs.size()];
- Enumeration sqs = rseqs.elements();
+ result = new SequenceI[rseqs.size()];
int si = 0;
- while (sqs.hasMoreElements())
+ for (SequenceI s : rseqs)
{
- SequenceI s = (SequenceI) sqs.nextElement();
- ret[si++] = s;
+ result[si++] = s;
s.updatePDBIds();
}
}
- return ret;
+ return result;
}
public void reportStdError(String db, List<String> queriesMade,
Exception ex)
{
- System.err.println("Failed to retrieve the following references from "
- + db);
+ System.err.println(
+ "Failed to retrieve the following references from " + db);
int n = 0;
for (String qv : queriesMade)
{
}
/**
- * Retrieve an instance of the proxy for the given source
+ * Returns a list of proxies 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.
+ * @return a list of DbSourceProxy for the db
*/
public List<DbSourceProxy> getSourceProxy(String db)
{
- List<DbSourceProxy> dbs;
- Map<String, DbSourceProxy> dblist = FETCHABLEDBS.get(db);
+ db = DBRefUtils.getCanonicalName(db);
+ Map<String, DbSourceProxy> dblist = fetchableDbs.get(db);
if (dblist == null)
{
- return new ArrayList<DbSourceProxy>();
- }
- ;
- 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<DbSourceProxy>();
- for (i = l.length - 1; i >= 0; i--)
- {
- dbs.add(l[i]);
- }
- }
- else
- {
- dbs = new ArrayList<DbSourceProxy>(dblist.values());
+ return new ArrayList<>();
}
+
+ /*
+ * sort so that primary sources precede secondary
+ */
+ List<DbSourceProxy> dbs = new ArrayList<>(dblist.values());
+ Collections.sort(dbs, proxyComparator);
return dbs;
}
/**
- * constructs and instance of the proxy and registers it as a valid
- * dbrefsource
+ * constructs an 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
+ protected void addDBRefSourceImpl(
+ Class<? extends DbSourceProxy> dbSourceProxy)
+ throws 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;
+ DbSourceProxy proxyObj = dbSourceProxy.getConstructor().newInstance();
+ proxy = proxyObj;
} catch (IllegalArgumentException e)
{
throw e;
} catch (Exception e)
{
// Serious problems if this happens.
- throw new Error("DBRefSource Implementation Exception", e);
+ throw new Error(MessageManager
+ .getString("error.dbrefsource_implementation_exception"), e);
}
addDbRefSourceImpl(proxy);
}
{
if (proxy != null)
{
- if (FETCHABLEDBS == null)
+ if (fetchableDbs == null)
{
- FETCHABLEDBS = new Hashtable<String, Map<String, DbSourceProxy>>();
+ fetchableDbs = new Hashtable<>();
}
- Map<String, DbSourceProxy> slist = FETCHABLEDBS.get(proxy
- .getDbSource());
+ Map<String, DbSourceProxy> slist = fetchableDbs
+ .get(proxy.getDbSource());
if (slist == null)
{
- FETCHABLEDBS.put(proxy.getDbSource(),
- slist = new Hashtable<String, DbSourceProxy>());
+ 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<DbSourceProxy> 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
+ * @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))
+ if (!DbSourceProxy.class.isAssignableFrom(class1))
{
- throw new Error(
- "Implmentation Error - getDbInstances must be given a class that implements jalview.ws.seqfetcher.DbSourceProxy (was given '"
- + class1 + "')");
+ throw new Error(MessageManager.formatMessage(
+ "error.implementation_error_dbinstance_must_implement_interface",
+ new String[]
+ { class1.toString() }));
}
- if (FETCHABLEDBS == null)
+ if (fetchableDbs == null)
{
return null;
}
String[] sources = null;
- Vector src = new Vector();
- Enumeration dbs = FETCHABLEDBS.keys();
+ Vector<String> src = new Vector<>();
+ Enumeration<String> dbs = fetchableDbs.keys();
while (dbs.hasMoreElements())
{
- String dbn = (String) dbs.nextElement();
- for (DbSourceProxy dbp : FETCHABLEDBS.get(dbn).values())
+ String dbn = dbs.nextElement();
+ for (DbSourceProxy dbp : fetchableDbs.get(dbn).values())
{
if (class1.isAssignableFrom(dbp.getClass()))
{
public DbSourceProxy[] getDbSourceProxyInstances(Class class1)
{
- ArrayList<DbSourceProxy> prlist = new ArrayList<DbSourceProxy>();
+ List<DbSourceProxy> 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]);
}
+ /**
+ * Returns a preferred feature colouring scheme for the given source, or null
+ * if none is defined.
+ *
+ * @param source
+ * @return
+ */
+ public FeatureSettingsModelI getFeatureColourScheme(String source)
+ {
+ /*
+ * return the first non-null colour scheme for any proxy for
+ * this database source
+ */
+ for (DbSourceProxy proxy : getSourceProxy(source))
+ {
+ FeatureSettingsModelI preferredColours = proxy
+ .getFeatureColourScheme();
+ if (preferredColours != null)
+ {
+ return preferredColours;
+ }
+ }
+ return null;
+ }
}