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