2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
\r
3 * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
\r
5 * This file is part of Jalview.
\r
7 * Jalview is free software: you can redistribute it and/or
\r
8 * modify it under the terms of the GNU General Public License
\r
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
\r
11 * Jalview is distributed in the hope that it will be useful, but
\r
12 * WITHOUT ANY WARRANTY; without even the implied warranty
\r
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
\r
14 * PURPOSE. See the GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
\r
18 package jalview.ws.dbsources.das.datamodel;
\r
20 import java.util.ArrayList;
\r
21 import java.util.Arrays;
\r
22 import java.util.HashMap;
\r
23 import java.util.List;
\r
24 import java.util.Map;
\r
25 import java.util.StringTokenizer;
\r
26 import java.util.Vector;
\r
28 import org.biodas.jdas.client.ConnectionPropertyProviderI;
\r
29 import org.biodas.jdas.client.SequenceClient;
\r
30 import org.biodas.jdas.client.adapters.sequence.DasSequenceAdapter;
\r
31 import org.biodas.jdas.client.threads.MultipleConnectionPropertyProviderI;
\r
32 import org.biodas.jdas.client.threads.SequenceClientMultipleSources;
\r
33 import org.biodas.jdas.schema.sequence.SEQUENCE;
\r
34 import org.biodas.jdas.schema.sources.COORDINATES;
\r
35 import org.biodas.jdas.schema.sources.SOURCE;
\r
36 import org.biodas.jdas.schema.sources.VERSION;
\r
38 import com.stevesoft.pat.Regex;
\r
40 import jalview.ws.dbsources.das.api.jalviewSourceI;
\r
41 import jalview.ws.seqfetcher.*;
\r
42 import jalview.bin.Cache;
\r
43 import jalview.datamodel.Alignment;
\r
44 import jalview.datamodel.AlignmentI;
\r
45 import jalview.datamodel.DBRefEntry;
\r
46 import jalview.datamodel.Sequence;
\r
47 import jalview.datamodel.SequenceI;
\r
50 * an instance of this class is created for each unique DAS Sequence source (ie
\r
51 * one capable of handling the 'sequence' for a particular MapMaster)
\r
56 public class DasSequenceSource extends DbSourceProxyImpl implements
\r
59 private jalviewSourceI jsrc;
\r
61 protected SOURCE source = null;
\r
63 protected VERSION version = null;
\r
65 protected COORDINATES coordsys = null;
\r
67 protected String dbname = "DASCS";
\r
69 protected String dbrefname = "das:source";
\r
71 protected MultipleConnectionPropertyProviderI connprops = null;
\r
74 * create a new DbSource proxy for a DAS 1 source
\r
77 * Human Readable Name to use when fetching from this source
\r
79 * DbRefName for DbRefs attached to sequences retrieved from this
\r
84 * specific coordinate system to use for this source
\r
86 * if source is not capable of the 'sequence' command
\r
88 public DasSequenceSource(String dbname, String dbrefname, SOURCE source,
\r
89 VERSION version, COORDINATES coordsys,
\r
90 MultipleConnectionPropertyProviderI connprops) throws Exception
\r
92 if (!(jsrc = new JalviewSource(source, connprops, false))
\r
93 .isSequenceSource())
\r
95 throw new Exception("Source " + source.getTitle()
\r
96 + " does not support the sequence command.");
\r
98 this.source = source;
\r
99 this.dbname = dbname;
\r
100 this.dbrefname = dbrefname.toUpperCase();
\r
101 if (coordsys != null)
\r
103 this.coordsys = coordsys;
\r
105 this.connprops = connprops;
\r
108 public String getAccessionSeparator()
\r
113 public Regex getAccessionValidator()
\r
116 return Regex.perlCode("m/([^:]+)(:\\d+,\\d+)?/");
\r
119 public String getDbName()
\r
122 return dbname + " (DAS)";
\r
125 public String getDbSource()
\r
130 public String getDbVersion()
\r
132 return coordsys != null ? coordsys.getVersion() : "";
\r
135 public AlignmentI getSequenceRecords(String queries) throws Exception
\r
137 StringTokenizer st = new StringTokenizer(queries, "\t");
\r
138 List<String> toks = new ArrayList<String>(), src = new ArrayList<String>(), acIds = new ArrayList<String>();
\r
139 while (st.hasMoreTokens())
\r
142 toks.add(t = st.nextToken());
\r
143 acIds.add(t.replaceAll(":[0-9,]+", ""));
\r
145 src.add(jsrc.getSourceURL());
\r
146 Map<String, Map<List<String>, DasSequenceAdapter>> resultset = new HashMap<String, Map<List<String>, DasSequenceAdapter>>();
\r
147 Map<String, Map<List<String>, Exception>> errors = new HashMap<String, Map<List<String>, Exception>>();
\r
149 // First try multiple sources
\r
150 boolean multiple = true, retry = false;
\r
156 // slow, fetch one at a time.
\r
157 for (String sr : src)
\r
160 .println("Retrieving IDs individually from das source: "
\r
162 org.biodas.jdas.client.SequenceClient sq = new SequenceClient(
\r
163 connprops.getConnectionPropertyProviderFor(sr));
\r
164 for (String q : toks)
\r
166 List<String> qset = Arrays.asList(new String[]
\r
170 DasSequenceAdapter s = sq.fetchData(sr, qset);
\r
171 Map<List<String>, DasSequenceAdapter> dss = resultset.get(sr);
\r
176 dss = new HashMap<List<String>, DasSequenceAdapter>());
\r
179 } catch (Exception x)
\r
181 Map<List<String>, Exception> ers = errors.get(sr);
\r
184 errors.put(sr, ers = new HashMap<List<String>, Exception>());
\r
193 SequenceClientMultipleSources sclient;
\r
194 sclient = new SequenceClientMultipleSources();
\r
195 sclient.fetchData(src, toks, resultset, errors);
\r
196 sclient.shutDown();
\r
197 while (!sclient.isTerminated())
\r
203 } catch (InterruptedException x)
\r
207 if (resultset.isEmpty() && !errors.isEmpty())
\r
215 if (resultset.isEmpty())
\r
217 System.err.println("Sequence Query to " + jsrc.getTitle() + " with '"
\r
218 + queries + "' returned no sequences.");
\r
223 Vector<SequenceI> seqs = null;
\r
224 for (Map.Entry<String, Map<List<String>, DasSequenceAdapter>> resset : resultset
\r
227 for (Map.Entry<List<String>, DasSequenceAdapter> result : resset
\r
228 .getValue().entrySet())
\r
230 DasSequenceAdapter dasseqresp = result.getValue();
\r
231 List<String> accessions = result.getKey();
\r
232 for (SEQUENCE e : dasseqresp.getSequence())
\r
234 String lbl = e.getId();
\r
236 if (acIds.indexOf(lbl) == -1)
\r
239 .println("Warning - received sequence event for strange accession code ("
\r
246 if (e.getContent().length() == 0)
\r
249 .println("Empty sequence returned for accession code ("
\r
253 + " (source is " + getDbName());
\r
257 seqs = new java.util.Vector<SequenceI>();
\r
258 // JDAS returns a sequence complete with any newlines and spaces
\r
260 Sequence sq = new Sequence(lbl, e.getContent().replaceAll(
\r
262 sq.setStart(e.getStart().intValue());
\r
263 sq.addDBRef(new DBRefEntry(getDbSource(), getDbVersion()
\r
264 + ":" + e.getVersion(), lbl));
\r
265 seqs.addElement(sq);
\r
271 if (seqs == null || seqs.size() == 0)
\r
273 SequenceI[] sqs = new SequenceI[seqs.size()];
\r
274 for (int i = 0, iSize = seqs.size(); i < iSize; i++)
\r
276 sqs[i] = (SequenceI) seqs.elementAt(i);
\r
278 Alignment al = new Alignment(sqs);
\r
279 if (jsrc.isFeatureSource())
\r
281 java.util.Vector<jalviewSourceI> srcs = new java.util.Vector<jalviewSourceI>();
\r
282 srcs.addElement(jsrc);
\r
285 jalview.ws.DasSequenceFeatureFetcher dssf = new jalview.ws.DasSequenceFeatureFetcher(
\r
286 sqs, null, srcs, false, false, multiple);
\r
287 while (dssf.isRunning())
\r
292 } catch (InterruptedException x)
\r
298 } catch (Exception x)
\r
301 .error("Couldn't retrieve features for sequence from its source.",
\r
310 public String getTestQuery()
\r
312 return coordsys == null ? "" : coordsys.getTestRange();
\r
315 public boolean isValidReference(String accession)
\r
317 // TODO try to validate an accession against source
\r
318 // We don't really know how to do this without querying source
\r
324 * @return the source
\r
326 public SOURCE getSource()
\r
332 * @return the coordsys
\r
334 public COORDINATES getCoordsys()
\r