JAL-1807 explicit imports (jalview.ws.*)
[jalview.git] / src / jalview / ws / dbsources / das / datamodel / JalviewSource.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
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.
11  *  
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.
16  * 
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.
20  */
21 package jalview.ws.dbsources.das.datamodel;
22
23 import jalview.util.MessageManager;
24 import jalview.util.QuickSort;
25 import jalview.ws.dbsources.das.api.jalviewSourceI;
26 import jalview.ws.seqfetcher.DbSourceProxy;
27
28 import java.text.ParseException;
29 import java.util.ArrayList;
30 import java.util.Date;
31 import java.util.Hashtable;
32 import java.util.List;
33 import java.util.Map;
34
35 import org.biodas.jdas.client.threads.MultipleConnectionPropertyProviderI;
36 import org.biodas.jdas.dassources.Capabilities;
37 import org.biodas.jdas.dassources.utils.DasTimeFormat;
38 import org.biodas.jdas.schema.sources.CAPABILITY;
39 import org.biodas.jdas.schema.sources.COORDINATES;
40 import org.biodas.jdas.schema.sources.MAINTAINER;
41 import org.biodas.jdas.schema.sources.PROP;
42 import org.biodas.jdas.schema.sources.SOURCE;
43 import org.biodas.jdas.schema.sources.VERSION;
44
45 public class JalviewSource implements jalviewSourceI
46 {
47   SOURCE source;
48
49   MultipleConnectionPropertyProviderI connprov;
50
51   public JalviewSource(SOURCE local2,
52           MultipleConnectionPropertyProviderI connprov, boolean local)
53   {
54     this.connprov = connprov;
55     this.local = local;
56     source = local2;
57   }
58
59   @Override
60   public String getTitle()
61   {
62     return source.getTitle();
63   }
64
65   @Override
66   public VERSION getVersion()
67   {
68
69     return getVersionFor(source);
70   }
71
72   @Override
73   public String getDocHref()
74   {
75     return source.getDocHref();
76   }
77
78   @Override
79   public String getDescription()
80   {
81     return source.getDescription();
82   }
83
84   @Override
85   public String getUri()
86   {
87     return source.getUri();
88   }
89
90   @Override
91   public MAINTAINER getMAINTAINER()
92   {
93     return source.getMAINTAINER();
94   }
95
96   @Override
97   public String getEmail()
98   {
99     return (local) ? null : source.getMAINTAINER().getEmail();
100   }
101
102   boolean local = false;
103
104   @Override
105   public boolean isLocal()
106   {
107     return local;
108   }
109
110   @Override
111   public boolean isSequenceSource()
112   {
113     String seqcap = "das1:" + Capabilities.SEQUENCE.getName();
114     for (String cp : getCapabilityList(getVersionFor(source)))
115     {
116       if (cp.equals(seqcap))
117       {
118         return true;
119
120       }
121     }
122     return false;
123   }
124
125   @Override
126   public boolean isFeatureSource()
127   {
128     String seqcap = "das1:" + Capabilities.FEATURES.getName();
129     for (String cp : getCapabilityList(getVersionFor(source)))
130     {
131       if (cp.equals(seqcap))
132       {
133         return true;
134
135       }
136     }
137     return false;
138   }
139
140   private VERSION getVersionFor(SOURCE ds)
141   {
142     VERSION latest = null;
143     for (VERSION v : ds.getVERSION())
144     {
145       if (latest == null
146               || isLaterThan(latest.getCreated(), v.getCreated()))
147       {
148         // TODO: das 1.6 - should just get the first version - ignore other
149         // versions since not specified how to construct URL from version's URI
150         // + source URI
151         latest = v;
152       }
153     }
154     return latest;
155   }
156
157   /**
158    * compare date strings. null or unparseable dates are assumed to be oldest
159    * 
160    * @param ref
161    * @param newer
162    * @return true iff ref comes before newer
163    */
164   private boolean isLaterThan(String ref, String newer)
165   {
166     Date refdate = null, newdate = null;
167     if (ref != null && ref.trim().length() > 0)
168     {
169       try
170       {
171         refdate = DasTimeFormat.fromDASString(ref.trim());
172
173       } catch (ParseException x)
174       {
175       }
176     }
177     if (newer != null && newer.trim().length() > 0)
178     {
179       try
180       {
181         newdate = DasTimeFormat.fromDASString(newer);
182       } catch (ParseException e)
183       {
184       }
185     }
186     if (refdate != null)
187     {
188       if (newdate != null)
189       {
190         return refdate.before(newdate);
191       }
192       return false;
193     }
194     if (newdate != null)
195     {
196       return true;
197     }
198     // assume first instance of source is newest in list. - TODO: check if
199     // natural ordering of source versions is newest first or oldest first
200     return false;
201   }
202
203   public String[] getLabelsFor(VERSION v)
204   {
205     ArrayList<String> labels = new ArrayList<String>();
206     for (PROP p : v.getPROP())
207     {
208       if (p.getName().equalsIgnoreCase("LABEL"))
209       {
210         labels.add(p.getValue());
211       }
212     }
213     return labels.toArray(new String[0]);
214   }
215
216   private CAPABILITY getCapability(Capabilities capability)
217   {
218     for (CAPABILITY p : getVersion().getCAPABILITY())
219     {
220       if (p.getType().equalsIgnoreCase(capability.getName())
221               || p.getType().equalsIgnoreCase(
222                       "das1:" + capability.getName()))
223       {
224         return p;
225       }
226     }
227     return null;
228   }
229
230   public String[] getCapabilityList(VERSION v)
231   {
232
233     ArrayList<String> labels = new ArrayList<String>();
234     for (CAPABILITY p : v.getCAPABILITY())
235     {
236       // TODO: work out what to do with namespace prefix
237       // does SEQUENCE == das1:SEQUENCE and das2:SEQUENCE ?
238       // for moment, just show all capabilities...
239       if (p.getType().startsWith("das1:"))
240       {
241         labels.add(p.getType());
242       }
243     }
244     return labels.toArray(new String[0]);
245   }
246
247   @Override
248   public List<DbSourceProxy> getSequenceSourceProxies()
249   {
250     if (!isSequenceSource())
251     {
252       return null;
253     }
254     ArrayList<DbSourceProxy> seqsources = new ArrayList<DbSourceProxy>();
255     if (!local)
256     {
257       VERSION v = getVersion();
258       Map<String, COORDINATES> latestc = new Hashtable<String, COORDINATES>();
259       for (COORDINATES cs : v.getCOORDINATES())
260       {
261         COORDINATES ltst = latestc.get(cs.getUri());
262         if (ltst == null
263                 || ltst.getVersion() == null
264                 || (ltst.getVersion() != null && cs.getVersion() != null && isLaterThan(
265                         ltst.getVersion(), cs.getVersion())))
266         {
267           latestc.put(cs.getUri(), cs);
268         }
269       }
270       for (COORDINATES cs : latestc.values())
271       {
272         DasSequenceSource ds;
273         /*
274          * if (css == null || css.length == 0) { // TODO: query das source
275          * directly to identify coordinate system... or // have to make up a
276          * coordinate system css = new DasCoordinateSystem[] { new
277          * DasCoordinateSystem() }; css[0].setName(d1s.getNickname());
278          * css[0].setUniqueId(d1s.getNickname()); } for (int c = 0; c <
279          * css.length; c++) {
280          */
281         try
282         {
283           seqsources.add(ds = new DasSequenceSource(getTitle() + " ("
284                   + cs.getAuthority() + " " + cs.getSource()
285                   + (cs.getVersion() != null ? " " + cs.getVersion() : "")
286                   + ")", cs.getAuthority(), source, v, cs, connprov));
287           if (seqsources.size() > 1)
288           {
289             System.err.println("Added another sequence DB source for "
290                     + getTitle() + " (" + ds.getDbName() + ")");
291           }
292         } catch (Exception e)
293         {
294           System.err.println("Ignoring sequence coord system " + cs + " ("
295                   + cs.getContent() + ") for source " + getTitle()
296                   + "- threw exception when constructing fetcher.\n");
297           e.printStackTrace();
298         }
299       }
300     }
301     else
302     {
303       try
304       {
305         seqsources.add(new DasSequenceSource(getTitle(), getTitle(),
306                 source, getVersion(), null, connprov));
307       } catch (Exception e)
308       {
309         // TODO Auto-generated catch block
310         e.printStackTrace();
311       }
312
313     }
314     if (seqsources.size() > 1)
315     {
316       // sort by name
317       DbSourceProxy[] tsort = seqsources.toArray(new DasSequenceSource[0]);
318       String[] nm = new String[tsort.length];
319       for (int i = 0; i < nm.length; i++)
320       {
321         nm[i] = tsort[i].getDbName().toLowerCase();
322       }
323       QuickSort.sort(nm, tsort);
324       seqsources.clear();
325       for (DbSourceProxy ssrc : tsort)
326       {
327         seqsources.add(ssrc);
328       }
329     }
330     return seqsources;
331   }
332
333   @Override
334   public String getSourceURL()
335   {
336     try
337     {
338       // kind of dumb, since
339       // org.biodas.jdas.dassources.utils.VersionAdapter.getSourceUriFromQueryUri()
340       // does this,
341       // but this way, we can access non DAS 1.6 compliant sources (which have
342       // to have a URL like <sourcename>/das/ and cause a validation exception)
343
344       for (CAPABILITY cap : getVersion().getCAPABILITY())
345       {
346         String capname = cap.getType().substring(
347                 cap.getType().indexOf(":") + 1);
348         int p = cap.getQueryUri().lastIndexOf(capname);
349         if (p < -1)
350         {
351           throw new Exception(MessageManager.formatMessage("exception.invalid_das_source", new String[]{source.getUri()}));
352         }
353         if (cap.getQueryUri().charAt(p) == '/')
354         {
355           p--;
356         }
357         return cap.getQueryUri().substring(0, p);
358       }
359     } catch (Exception x)
360     {
361       System.err.println("Serious: Couldn't get the URL for source "
362               + source.getTitle());
363       x.printStackTrace();
364     }
365     return null;
366   }
367
368   @Override
369   public boolean isNewerThan(jalviewSourceI other)
370   {
371     return isLaterThan(getVersion().getCreated(), other.getVersion()
372             .getCreated());
373   }
374
375   @Override
376   public boolean isReferenceSource()
377   {
378     // TODO check source object for indication that we are the primary for a DAS
379     // coordinate system
380     return false;
381   }
382 }