JAL-1645 Version-Rel Version 2.9 Year-Rel 2015 Licensing glob
[jalview.git] / src / jalview / ws / dbsources / das / datamodel / JalviewSource.java
index 1ec9ef9..8cb3fba 100644 (file)
@@ -1,13 +1,39 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9)
+ * Copyright (C) 2015 The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.ws.dbsources.das.datamodel;
 
+import jalview.util.MessageManager;
+import jalview.ws.dbsources.das.api.jalviewSourceI;
+import jalview.ws.seqfetcher.DbSourceProxy;
+
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
 
+import org.biodas.jdas.client.threads.MultipleConnectionPropertyProviderI;
 import org.biodas.jdas.dassources.Capabilities;
 import org.biodas.jdas.dassources.utils.DasTimeFormat;
-import org.biodas.jdas.dassources.utils.RegistrySourceAdapter;
 import org.biodas.jdas.schema.sources.CAPABILITY;
 import org.biodas.jdas.schema.sources.COORDINATES;
 import org.biodas.jdas.schema.sources.MAINTAINER;
@@ -15,15 +41,16 @@ import org.biodas.jdas.schema.sources.PROP;
 import org.biodas.jdas.schema.sources.SOURCE;
 import org.biodas.jdas.schema.sources.VERSION;
 
-import jalview.ws.dbsources.das.api.jalviewSourceI;
-import jalview.ws.seqfetcher.DbSourceProxy;
-
 public class JalviewSource implements jalviewSourceI
 {
   SOURCE source;
 
-  public JalviewSource(SOURCE local2, boolean local)
+  MultipleConnectionPropertyProviderI connprov;
+
+  public JalviewSource(SOURCE local2,
+          MultipleConnectionPropertyProviderI connprov, boolean local)
   {
+    this.connprov = connprov;
     this.local = local;
     source = local2;
   }
@@ -37,7 +64,7 @@ public class JalviewSource implements jalviewSourceI
   @Override
   public VERSION getVersion()
   {
-    
+
     return getVersionFor(source);
   }
 
@@ -68,7 +95,7 @@ public class JalviewSource implements jalviewSourceI
   @Override
   public String getEmail()
   {
-    return (local) ? null: source.getMAINTAINER().getEmail();
+    return (local) ? null : source.getMAINTAINER().getEmail();
   }
 
   boolean local = false;
@@ -93,6 +120,7 @@ public class JalviewSource implements jalviewSourceI
     }
     return false;
   }
+
   @Override
   public boolean isFeatureSource()
   {
@@ -125,23 +153,34 @@ public class JalviewSource implements jalviewSourceI
     return latest;
   }
 
+  /**
+   * compare date strings. null or unparseable dates are assumed to be oldest
+   * 
+   * @param ref
+   * @param newer
+   * @return true iff ref comes before newer
+   */
   private boolean isLaterThan(String ref, String newer)
   {
     Date refdate = null, newdate = null;
-    try
+    if (ref != null && ref.trim().length() > 0)
     {
-      refdate = DasTimeFormat.fromDASString(ref);
+      try
+      {
+        refdate = DasTimeFormat.fromDASString(ref.trim());
 
-    } catch (ParseException x)
-    {
-      return false;
+      } catch (ParseException x)
+      {
+      }
     }
-    try
-    {
-      newdate = DasTimeFormat.fromDASString(newer);
-    } catch (ParseException e)
+    if (newer != null && newer.trim().length() > 0)
     {
-      // TODO: handle exception
+      try
+      {
+        newdate = DasTimeFormat.fromDASString(newer);
+      } catch (ParseException e)
+      {
+      }
     }
     if (refdate != null)
     {
@@ -173,15 +212,20 @@ public class JalviewSource implements jalviewSourceI
     return labels.toArray(new String[0]);
   }
 
-  private CAPABILITY getCapability(Capabilities capability) {
-    for (CAPABILITY p: getVersion().getCAPABILITY()) {
-      if (p.getType().equalsIgnoreCase(capability.getName()) || p.getType().equalsIgnoreCase("das1:"+capability.getName()))
+  private CAPABILITY getCapability(Capabilities capability)
+  {
+    for (CAPABILITY p : getVersion().getCAPABILITY())
+    {
+      if (p.getType().equalsIgnoreCase(capability.getName())
+              || p.getType().equalsIgnoreCase(
+                      "das1:" + capability.getName()))
       {
         return p;
       }
     }
     return null;
   }
+
   public String[] getCapabilityList(VERSION v)
   {
 
@@ -209,55 +253,131 @@ public class JalviewSource implements jalviewSourceI
     ArrayList<DbSourceProxy> seqsources = new ArrayList<DbSourceProxy>();
     if (!local)
     {
-    VERSION v = getVersion();
-    for (COORDINATES cs : v.getCOORDINATES())
-    {
-
-      /*
-       * if (css == null || css.length == 0) { // TODO: query das source
-       * directly to identify coordinate system... or // have to make up a
-       * coordinate system css = new DasCoordinateSystem[] { new
-       * DasCoordinateSystem() }; css[0].setName(d1s.getNickname());
-       * css[0].setUniqueId(d1s.getNickname()); } for (int c = 0; c <
-       * css.length; c++) {
-       */
-      try
+      VERSION v = getVersion();
+      Map<String, COORDINATES> latestc = new Hashtable<String, COORDINATES>();
+      for (COORDINATES cs : v.getCOORDINATES())
       {
-        seqsources.add(new DasSequenceSource("das:" + getTitle() + " ("
-                + cs.getContent() + ")", cs.getContent(), source, v, cs));
-      } catch (Exception e)
+        COORDINATES ltst = latestc.get(cs.getUri());
+        if (ltst == null
+                || ltst.getVersion() == null
+                || (ltst.getVersion() != null && cs.getVersion() != null && isLaterThan(
+                        ltst.getVersion(), cs.getVersion())))
+        {
+          latestc.put(cs.getUri(), cs);
+        }
+      }
+      for (COORDINATES cs : latestc.values())
       {
-        System.err.println("Ignoring sequence coord system " + cs + " ("
-                + cs.getContent() + ") for source " + getTitle()
-                + "- threw exception when constructing fetcher.\n");
-        e.printStackTrace();
+        DasSequenceSource ds;
+        /*
+         * if (css == null || css.length == 0) { // TODO: query das source
+         * directly to identify coordinate system... or // have to make up a
+         * coordinate system css = new DasCoordinateSystem[] { new
+         * DasCoordinateSystem() }; css[0].setName(d1s.getNickname());
+         * css[0].setUniqueId(d1s.getNickname()); } for (int c = 0; c <
+         * css.length; c++) {
+         */
+        try
+        {
+          seqsources.add(ds = new DasSequenceSource(getTitle() + " ("
+                  + cs.getAuthority() + " " + cs.getSource()
+                  + (cs.getVersion() != null ? " " + cs.getVersion() : "")
+                  + ")", cs.getAuthority(), source, v, cs, connprov));
+          if (seqsources.size() > 1)
+          {
+            System.err.println("Added another sequence DB source for "
+                    + getTitle() + " (" + ds.getDbName() + ")");
+          }
+        } catch (Exception e)
+        {
+          System.err.println("Ignoring sequence coord system " + cs + " ("
+                  + cs.getContent() + ") for source " + getTitle()
+                  + "- threw exception when constructing fetcher.\n");
+          e.printStackTrace();
+        }
       }
     }
-    } else {
+    else
+    {
       try
       {
-        seqsources.add(new DasSequenceSource("das:"+getTitle(), getTitle(), source, getVersion(), null));
+        seqsources.add(new DasSequenceSource(getTitle(), getTitle(),
+                source, getVersion(), null, connprov));
       } catch (Exception e)
       {
         // TODO Auto-generated catch block
         e.printStackTrace();
       }
-      
+
+    }
+    if (seqsources.size() > 1)
+    {
+      // sort by name
+      DbSourceProxy[] tsort = seqsources.toArray(new DasSequenceSource[0]);
+      String[] nm = new String[tsort.length];
+      for (int i = 0; i < nm.length; i++)
+      {
+        nm[i] = tsort[i].getDbName().toLowerCase();
+      }
+      jalview.util.QuickSort.sort(nm, tsort);
+      seqsources.clear();
+      for (DbSourceProxy ssrc : tsort)
+      {
+        seqsources.add(ssrc);
+      }
     }
     return seqsources;
   }
+
   @Override
   public String getSourceURL()
   {
-    try {
-    String url = new RegistrySourceAdapter(source).getOriginalDataSourceUri();
-    return url;
-    }
-    catch (Exception x)
+    try
     {
-      System.err.println("Serious: Couldn't get the URL for source "+source.getTitle());
+      // kind of dumb, since
+      // org.biodas.jdas.dassources.utils.VersionAdapter.getSourceUriFromQueryUri()
+      // does this,
+      // 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)
+
+      for (CAPABILITY cap : getVersion().getCAPABILITY())
+      {
+        String capname = cap.getType().substring(
+                cap.getType().indexOf(":") + 1);
+        int p = cap.getQueryUri().lastIndexOf(capname);
+        if (p < -1)
+        {
+          throw new Exception(MessageManager.formatMessage(
+                  "exception.invalid_das_source",
+                  new String[] { source.getUri() }));
+        }
+        if (cap.getQueryUri().charAt(p) == '/')
+        {
+          p--;
+        }
+        return cap.getQueryUri().substring(0, p);
+      }
+    } catch (Exception x)
+    {
+      System.err.println("Serious: Couldn't get the URL for source "
+              + source.getTitle());
       x.printStackTrace();
     }
     return null;
   }
+
+  @Override
+  public boolean isNewerThan(jalviewSourceI other)
+  {
+    return isLaterThan(getVersion().getCreated(), other.getVersion()
+            .getCreated());
+  }
+
+  @Override
+  public boolean isReferenceSource()
+  {
+    // TODO check source object for indication that we are the primary for a DAS
+    // coordinate system
+    return false;
+  }
 }