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