2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.ws.dbsources.das.datamodel;
23 import jalview.bin.Cache;
24 import jalview.datamodel.Alignment;
25 import jalview.datamodel.AlignmentI;
26 import jalview.datamodel.DBRefEntry;
27 import jalview.datamodel.Sequence;
28 import jalview.datamodel.SequenceI;
29 import jalview.util.MessageManager;
30 import jalview.ws.dbsources.das.api.jalviewSourceI;
31 import jalview.ws.seqfetcher.DbSourceProxy;
32 import jalview.ws.seqfetcher.DbSourceProxyImpl;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.HashMap;
37 import java.util.List;
39 import java.util.StringTokenizer;
40 import java.util.Vector;
42 import org.biodas.jdas.client.SequenceClient;
43 import org.biodas.jdas.client.adapters.sequence.DasSequenceAdapter;
44 import org.biodas.jdas.client.threads.MultipleConnectionPropertyProviderI;
45 import org.biodas.jdas.client.threads.SequenceClientMultipleSources;
46 import org.biodas.jdas.schema.sequence.SEQUENCE;
47 import org.biodas.jdas.schema.sources.COORDINATES;
48 import org.biodas.jdas.schema.sources.SOURCE;
49 import org.biodas.jdas.schema.sources.VERSION;
51 import com.stevesoft.pat.Regex;
54 * an instance of this class is created for each unique DAS Sequence source (ie
55 * one capable of handling the 'sequence' for a particular MapMaster)
60 public class DasSequenceSource extends DbSourceProxyImpl
61 implements DbSourceProxy
63 private jalviewSourceI jsrc;
65 protected SOURCE source = null;
67 protected VERSION version = null;
69 protected COORDINATES coordsys = null;
71 protected String dbname = "DASCS";
73 protected String dbrefname = "das:source";
75 protected MultipleConnectionPropertyProviderI connprops = null;
78 * DAS sources are tier 1 - if we have a direct DB connection then we should
84 * create a new DbSource proxy for a DAS 1 source
87 * Human Readable Name to use when fetching from this source
89 * DbRefName for DbRefs attached to sequences retrieved from this
94 * specific coordinate system to use for this source
96 * if source is not capable of the 'sequence' command
98 public DasSequenceSource(String dbname, String dbrefname, SOURCE source,
99 VERSION version, COORDINATES coordsys,
100 MultipleConnectionPropertyProviderI connprops) throws Exception
102 if (!(jsrc = new JalviewSource(source, connprops, false))
105 throw new Exception(MessageManager.formatMessage(
106 "exception.das_source_doesnt_support_sequence_command",
108 { source.getTitle() }));
110 this.tier = 1 + ((jsrc.isLocal() || jsrc.isReferenceSource()) ? 0 : 1);
111 this.source = source;
112 this.dbname = dbname;
113 this.dbrefname = dbrefname.toUpperCase();
114 if (coordsys != null)
116 this.coordsys = coordsys;
118 this.connprops = connprops;
121 public String getAccessionSeparator()
126 public Regex getAccessionValidator()
129 return Regex.perlCode("m/([^:]+)(:\\d+,\\d+)?/");
132 public String getDbName()
135 return dbname + " (DAS)";
138 public String getDbSource()
143 public String getDbVersion()
145 return coordsys != null ? coordsys.getVersion() : "";
148 public AlignmentI getSequenceRecords(String queries) throws Exception
150 StringTokenizer st = new StringTokenizer(queries, "\t");
151 List<String> toks = new ArrayList<String>(),
152 src = new ArrayList<String>(), acIds = new ArrayList<String>();
153 while (st.hasMoreTokens())
156 toks.add(t = st.nextToken());
157 acIds.add(t.replaceAll(":[0-9,]+", ""));
159 src.add(jsrc.getSourceURL());
160 Map<String, Map<List<String>, DasSequenceAdapter>> resultset = new HashMap<String, Map<List<String>, DasSequenceAdapter>>();
161 Map<String, Map<List<String>, Exception>> errors = new HashMap<String, Map<List<String>, Exception>>();
163 // First try multiple sources
164 boolean multiple = true, retry = false;
170 // slow, fetch one at a time.
171 for (String sr : src)
174 "Retrieving IDs individually from das source: " + sr);
175 org.biodas.jdas.client.SequenceClient sq = new SequenceClient(
176 connprops.getConnectionPropertyProviderFor(sr));
177 for (String q : toks)
179 List<String> qset = Arrays.asList(new String[] { q });
182 DasSequenceAdapter s = sq.fetchData(sr, qset);
183 Map<List<String>, DasSequenceAdapter> dss = resultset.get(sr);
187 dss = new HashMap<List<String>, DasSequenceAdapter>());
190 } catch (Exception x)
192 Map<List<String>, Exception> ers = errors.get(sr);
196 ers = new HashMap<List<String>, Exception>());
205 SequenceClientMultipleSources sclient;
206 sclient = new SequenceClientMultipleSources();
207 sclient.fetchData(src, toks, resultset, errors);
209 while (!sclient.isTerminated())
215 } catch (InterruptedException x)
219 if (resultset.isEmpty() && !errors.isEmpty())
227 if (resultset.isEmpty())
229 System.err.println("Sequence Query to " + jsrc.getTitle() + " with '"
230 + queries + "' returned no sequences.");
235 Vector<SequenceI> seqs = null;
236 for (Map.Entry<String, Map<List<String>, DasSequenceAdapter>> resset : resultset
239 for (Map.Entry<List<String>, DasSequenceAdapter> result : resset
240 .getValue().entrySet())
242 DasSequenceAdapter dasseqresp = result.getValue();
243 List<String> accessions = result.getKey();
244 for (SEQUENCE e : dasseqresp.getSequence())
246 String lbl = e.getId();
248 if (acIds.indexOf(lbl) == -1)
251 "Warning - received sequence event for strange accession code ("
258 if (e.getContent().length() == 0)
261 "Empty sequence returned for accession code ("
262 + lbl + ") from " + resset.getKey()
263 + " (source is " + getDbName());
267 seqs = new java.util.Vector<SequenceI>();
268 // JDAS returns a sequence complete with any newlines and spaces
270 Sequence sq = new Sequence(lbl,
271 e.getContent().replaceAll("\\s+", ""));
272 sq.setStart(e.getStart().intValue());
273 sq.addDBRef(new DBRefEntry(getDbSource(),
274 getDbVersion() + ":" + e.getVersion(), lbl));
281 if (seqs == null || seqs.size() == 0)
283 SequenceI[] sqs = new SequenceI[seqs.size()];
284 for (int i = 0, iSize = seqs.size(); i < iSize; i++)
286 sqs[i] = (SequenceI) seqs.elementAt(i);
288 Alignment al = new Alignment(sqs);
289 if (jsrc.isFeatureSource())
291 java.util.Vector<jalviewSourceI> srcs = new java.util.Vector<jalviewSourceI>();
292 srcs.addElement(jsrc);
295 jalview.ws.DasSequenceFeatureFetcher dssf = new jalview.ws.DasSequenceFeatureFetcher(
296 sqs, null, srcs, false, false, multiple);
297 while (dssf.isRunning())
302 } catch (InterruptedException x)
308 } catch (Exception x)
311 "Couldn't retrieve features for sequence from its source.",
320 public String getTestQuery()
322 return coordsys == null ? "" : coordsys.getTestRange();
325 public boolean isValidReference(String accession)
327 // TODO try to validate an accession against source
328 // We don't really know how to do this without querying source
336 public SOURCE getSource()
342 * @return the coordsys
344 public COORDINATES getCoordsys()