Merge branch 'JAL-972-dasobert-to-jdas' into JAL-972-jdas
authorjprocter <jprocter@compbio.dundee.ac.uk>
Fri, 30 Mar 2012 12:29:04 +0000 (13:29 +0100)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Fri, 30 Mar 2012 12:29:04 +0000 (13:29 +0100)
Conflicts:
.classpath
src/jalview/ws/dbsources/DasSequenceSource.java
src/jalview/ws/dbsources/das/DasSequenceSourceListener.java

merged jdas switchover into v2.8 development branch

1  2 
.classpath
src/jalview/bin/Cache.java
src/jalview/gui/DasSourceBrowser.java
src/jalview/gui/FeatureSettings.java
src/jalview/gui/SequenceFetcher.java
src/jalview/ws/DBRefFetcher.java
src/jalview/ws/DasSequenceFeatureFetcher.java
src/jalview/ws/SequenceFetcher.java
src/jalview/ws/seqfetcher/DbSourceProxy.java

diff --combined .classpath
@@@ -1,7 -1,6 +1,7 @@@
  <?xml version="1.0" encoding="UTF-8"?>
  <classpath>
        <classpathentry kind="src" path="src"/>
 +      <classpathentry kind="src" path="utils"/>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
        <classpathentry kind="lib" path="lib/activation.jar"/>
        <classpathentry kind="lib" path="lib/axis.jar" sourcepath="D:/axis-1_2RC2-src/axis-1_2RC2"/>
        </classpathentry>
        <classpathentry kind="lib" path="lib/miglayout-4.0-swing.jar"/>
        <classpathentry kind="lib" path="lib/jswingreader-0.3.jar" sourcepath="/jswingreader"/>
 -      <classpathentry kind="lib" path="lib/min-jaba-client.jar"/>
        <classpathentry kind="lib" path="lib/commons-codec-1.3.jar"/>
 +      <classpathentry kind="lib" path="lib/min-jaba-client-2.0.jar" sourcepath="/clustengine2"/>
        <classpathentry kind="lib" path="lib/Jmol-12.2.4.jar"/>
        <classpathentry kind="lib" path="appletlib/JmolApplet-12.2.4.jar"/>
+       <classpathentry kind="lib" path="lib/jdas-1.0.4.jar"/>
+       <classpathentry kind="lib" path="lib/spring-core-3.0.5.RELEASE.jar"/>
+       <classpathentry kind="lib" path="lib/spring-web-3.0.5.RELEASE.jar"/>
        <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin.jar"/>
 -      <classpathentry exported="true" kind="con" path="GROOVY_DSL_SUPPORT"/>
 +      <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin.java"/>
 +      <classpathentry kind="lib" path="/Users/jimp/git/jalview_clean/lib/VARNAv3-9-dev.jar"/>
        <classpathentry kind="output" path="classes"/>
  </classpath>
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
   * 
   * This file is part of Jalview.
   * 
@@@ -17,6 -17,9 +17,9 @@@
   */
  package jalview.bin;
  
+ import jalview.ws.dbsources.das.api.DasSourceRegistryI;
+ import jalview.ws.dbsources.das.datamodel.DasSourceRegistry;
  import java.awt.Color;
  import java.io.*;
  import java.text.DateFormat;
@@@ -24,7 -27,6 +27,6 @@@ import java.text.SimpleDateFormat
  import java.util.*;
  
  import org.apache.log4j.*;
- import org.biojava.dasobert.dasregistry.Das1Source;
  
  /**
   * Stores and retrieves Jalview Application Properties Lists and fields within
   * histogram.</li>
   * <li>SHOW_CONSENSUS_LOGO (false) Show consensus annotation row's sequence
   * logo.</li>
 + * <li>NORMALISE_CONSENSUS_LOGO (false) Show consensus annotation row's sequence
 + * logo normalised to row height rather than histogram height.</li>
   * <li>FOLLOW_SELECTIONS (true) Controls whether a new alignment view should
   * respond to selections made in other alignments containing the same sequences.
   * </li>
@@@ -282,26 -282,6 +284,26 @@@ public class Cach
        System.setProperty("http.proxyPort", getDefault("PROXY_PORT", null));
      }
  
 +    // LOAD THE AUTHORS FROM THE authors.props file
 +    try
 +    {
 +      String authorDetails = "jar:".concat(Cache.class.getProtectionDomain()
 +              .getCodeSource().getLocation().toString()
 +              .concat("!/authors.props"));
 +
 +      java.net.URL localJarFileURL = new java.net.URL(authorDetails);
 +
 +      InputStream in = localJarFileURL.openStream();
 +      applicationProperties.load(in);
 +      in.close();
 +    } catch (Exception ex)
 +    {
 +      System.out.println("Error reading author details: " + ex);
 +      applicationProperties.remove("AUTHORS");
 +      applicationProperties.remove("AUTHORFNAMES");
 +      applicationProperties.remove("YEAR");
 +    }
 +
      // FIND THE VERSION NUMBER AND BUILD DATE FROM jalview.jar
      // MUST FOLLOW READING OF LOCAL PROPERTIES FILE AS THE
      // VERSION MAY HAVE CHANGED SINCE LAST USING JALVIEW
    }
  
    /**
-    * generate Das1Sources from the local das source list
-    * 
-    * @return Vector of Das1Sources
-    */
-   public static Vector getLocalDasSources()
-   {
-     Vector localSources = new Vector();
-     String local = jalview.bin.Cache.getProperty("DAS_LOCAL_SOURCE");
-     if (local != null)
-     {
-       StringTokenizer st = new StringTokenizer(local, "\t");
-       while (st.hasMoreTokens())
-       {
-         String token = st.nextToken();
-         int bar = token.indexOf("|");
-         Das1Source source = new Das1Source();
-         source.setUrl(token.substring(bar + 1));
-         if (source.getUrl().startsWith("sequence:"))
-         {
-           source.setUrl(source.getUrl().substring(9));
-           // this source also serves sequences as well as features
-           source.setCapabilities(new String[]
-           { "sequence", "features" });
-         }
-         else
-         {
-           // default is that all user added sources serve features
-           source.setCapabilities(new String[]
-           { "features" });
-         }
-         source.setNickname(token.substring(0, bar));
-         localSources.addElement(source);
-       }
-     }
-     return localSources;
-   }
-   /**
     * GA tracker object - actually JGoogleAnalyticsTracker null if tracking not
     * enabled.
     */
      }
      return null;
    }
+   private static DasSourceRegistryI sourceRegistry=null;
+   /**
+    * initialise and ..
+    * @return instance of the das source registry
+    */
+   public static DasSourceRegistryI getDasSourceRegistry()
+   {
+     if (sourceRegistry==null)
+     {
+       sourceRegistry = new DasSourceRegistry();
+     }
+     return sourceRegistry;
+   }
  }
@@@ -1,6 -1,6 +1,6 @@@
  /*\r
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)\r
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle\r
   * \r
   * This file is part of Jalview.\r
   * \r
   */\r
  package jalview.gui;\r
  \r
- import java.util.*;\r
\r
- import java.awt.*;\r
- import java.awt.event.*;\r
- import javax.swing.*;\r
- import javax.swing.event.*;\r
- import javax.swing.table.*;\r
\r
- import org.biojava.dasobert.dasregistry.*;\r
- import jalview.jbgui.*;\r
- import jalview.util.*;\r
+ import jalview.jbgui.GDasSourceBrowser;\r
+ import jalview.util.TableSorter;\r
+ import jalview.ws.dbsources.das.api.DasSourceRegistryI;\r
+ import jalview.ws.dbsources.das.api.jalviewSourceI;\r
\r
+ import java.awt.BorderLayout;\r
+ import java.awt.event.ActionEvent;\r
+ import java.awt.event.MouseAdapter;\r
+ import java.awt.event.MouseEvent;\r
+ import java.util.ArrayList;\r
+ import java.util.List;\r
+ import java.util.Properties;\r
+ import java.util.StringTokenizer;\r
+ import java.util.Vector;\r
\r
+ import javax.swing.JCheckBox;\r
+ import javax.swing.JLabel;\r
+ import javax.swing.JOptionPane;\r
+ import javax.swing.JPanel;\r
+ import javax.swing.JTextField;\r
+ import javax.swing.ListSelectionModel;\r
+ import javax.swing.SwingUtilities;\r
+ import javax.swing.event.ListSelectionEvent;\r
+ import javax.swing.event.ListSelectionListener;\r
+ import javax.swing.table.AbstractTableModel;\r
\r
+ import org.biodas.jdas.schema.sources.CAPABILITY;\r
+ import org.biodas.jdas.schema.sources.COORDINATES;\r
+ import org.biodas.jdas.schema.sources.PROP;\r
+ import org.biodas.jdas.schema.sources.VERSION;\r
  \r
  public class DasSourceBrowser extends GDasSourceBrowser implements\r
          Runnable, ListSelectionListener\r
  {\r
-   static DasSource[] dasSources = null;\r
\r
-   Hashtable localSources = null;\r
\r
-   Vector selectedSources;\r
\r
-   public static String DEFAULT_REGISTRY = "http://www.dasregistry.org/das1/sources/";\r
\r
-   /**\r
-    * true if thread is running and we are talking to DAS registry service\r
-    */\r
-   public boolean loadingDasSources = false;\r
+   DasSourceRegistryI sourceRegistry = null;\r
  \r
-   protected static String getDasRegistryURL()\r
-   {\r
-     String registry = jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",\r
-             DEFAULT_REGISTRY);\r
\r
-     if (registry.indexOf("/registry/das1/sources/") > -1)\r
-     {\r
-       jalview.bin.Cache.setProperty(jalview.bin.Cache.DAS_REGISTRY_URL,\r
-               DEFAULT_REGISTRY);\r
-       registry = DEFAULT_REGISTRY;\r
-     }\r
-     return registry;\r
-   }\r
+   Vector<String> selectedSources;\r
  \r
    public DasSourceBrowser(FeatureSettings featureSettings)\r
    {\r
      fs = featureSettings;\r
-     String registry = getDasRegistryURL();\r
+     // TODO DasSourceRegistryProvider API\r
+     sourceRegistry = jalview.bin.Cache.getDasSourceRegistry();\r
+     String registry = sourceRegistry.getDasRegistryURL();\r
  \r
      registryURL.setText(registry);\r
  \r
        }\r
      });\r
  \r
-     if (dasSources != null)\r
+     if (sourceRegistry.getSources() != null)\r
      {\r
        init();\r
      }\r
  \r
    FeatureSettings fs = null;\r
  \r
+   private boolean loadingDasSources;\r
\r
    public DasSourceBrowser()\r
    {\r
      this(null);\r
  \r
    public void paintComponent(java.awt.Graphics g)\r
    {\r
-     if (dasSources == null && !loadingDasSources)\r
+     if (sourceRegistry == null)\r
      {\r
        Thread worker = new Thread(this);\r
        worker.start();\r
  \r
    void init()\r
    {\r
-     int dSize = dasSources.length;\r
+     List<jalviewSourceI> sources = sourceRegistry.getSources();\r
+     int dSize = sources.size();\r
      Object[][] data = new Object[dSize][2];\r
      for (int i = 0; i < dSize; i++)\r
      {\r
-       data[i][0] = dasSources[i].getNickname();\r
-       data[i][1] = new Boolean(selectedSources.contains(dasSources[i]\r
-               .getNickname()));\r
+       data[i][0] = sources.get(i).getTitle(); // what's equivalent of nickname\r
+       data[i][1] = new Boolean(selectedSources.contains(sources.get(i).getTitle()));\r
      }\r
  \r
      refreshTableData(data);\r
-     setCapabilities(dasSources);\r
+     setCapabilities(sourceRegistry);\r
  \r
      javax.swing.SwingUtilities.invokeLater(new Runnable()\r
      {\r
        return;\r
      }\r
  \r
-     int dSize = dasSources.length;\r
-     for (int i = 0; i < dSize; i++)\r
+     int dSize = sourceRegistry.getSources().size();\r
+     for (jalviewSourceI ds : sourceRegistry.getSources())\r
      {\r
-       if (!dasSources[i].getNickname().equals(nickName))\r
+       if (!ds.getTitle().equals(nickName))\r
        {\r
          continue;\r
        }\r
  \r
-       DasSource ds = dasSources[i];\r
\r
-       text.append("<font color=\"#0000FF\">Id:</font> "\r
-               + dasSources[i].getId() + "<br>");\r
+       VERSION latest = ds.getVersion();\r
+       text.append("<font color=\"#0000FF\">Id:</font> " + ds.getUri()\r
+               + "<br>");\r
        text.append("<font color=\"#0000FF\">Nickname:</font> "\r
-               + dasSources[i].getNickname() + "<br>");\r
-       text.append("<font color=\"#0000FF\">URL:</font> "\r
-               + dasSources[i].getUrl() + "<br>");\r
\r
+               + ds.getTitle() + "<br>");\r
+       \r
+       if (!ds.isLocal())\r
+       {\r
+       // TODO: IMMEDIATE verify that URI + ds.URI point to latest version for non-local sources.\r
+       if (ds.getDocHref()!=null) {\r
+         text.append("<font color=\"#0000FF\">URL:</font> " + ds.getDocHref()\r
+               + "<br>");\r
+       }\r
+       \r
        text.append("<font color=\"#0000FF\">Admin Email:</font> <a href=\"mailto:"\r
-               + dasSources[i].getAdminemail()\r
-               + "\">"\r
-               + dasSources[i].getAdminemail() + "</a>" + "<br>");\r
+               + ds.getEmail() + "\">" + ds.getEmail() + "</a>" + "<br>");\r
  \r
        text.append("<font color=\"#0000FF\">Registered at:</font> "\r
-               + dasSources[i].getRegisterDate() + "<br>");\r
\r
-       text.append("<font color=\"#0000FF\">Last successful test:</font> "\r
-               + dasSources[i].getLeaseDate() + "<br>");\r
+               + latest.getCreated() + "<br>");\r
  \r
+       // TODO: Identify last successful test date\r
+       // text.append("<font color=\"#0000FF\">Last successful test:</font> "\r
+       // + latest.dasSources[i].getLeaseDate() + "<br>");\r
+       } else {\r
+         text.append("Source was added manually.<br/>");\r
+       }\r
        text.append("<font color=\"#0000FF\">Labels:</font> ");\r
-       for (int s = 0; s < dasSources[i].getLabels().length; s++)\r
+       boolean b = false;\r
+       for (PROP labl : latest.getPROP())\r
        {\r
-         text.append(dasSources[i].getLabels()[s]);\r
-         if (s < dasSources[i].getLabels().length - 1)\r
+         if (labl.getName().equalsIgnoreCase("LABEL"))\r
          {\r
-           text.append(",");\r
+           if (!b)\r
+           {\r
+             text.append(",");\r
+           }\r
+           text.append(" ");\r
\r
+           text.append(labl.getValue());\r
+           b = true;\r
          }\r
-         text.append(" ");\r
+         ;\r
        }\r
        text.append("<br>");\r
  \r
        text.append("<font color=\"#0000FF\">Capabilities:</font> ");\r
-       String[] scap = dasSources[i].getCapabilities();\r
+       CAPABILITY[] scap = latest.getCAPABILITY().toArray(new CAPABILITY[0]);\r
        for (int j = 0; j < scap.length; j++)\r
        {\r
-         text.append(scap[j]);\r
+         text.append(scap[j].getType());\r
          if (j < scap.length - 1)\r
          {\r
            text.append(", ");\r
        text.append("<br>");\r
  \r
        text.append("<font color=\"#0000FF\">Coordinates:</font> ");\r
-       DasCoordinateSystem[] dcs = ds.getCoordinateSystem();\r
-       for (int j = 0; j < dcs.length; j++)\r
+       for (COORDINATES dcs : latest.getCOORDINATES())\r
        {\r
-         text.append("(" + dcs[j].getUniqueId() + ") "\r
-                 + dcs[j].getCategory() + ", " + dcs[j].getName());\r
-         if (dcs[j].getNCBITaxId() != 0)\r
+         text.append("(" + dcs.getUri() + ") "\r
\r
+         + dcs.getSource() + ", " + dcs.getAuthority());\r
+         if (dcs.getTaxid() != null && dcs.getTaxid().trim().length() > 0)\r
          {\r
-           text.append(", " + dcs[j].getNCBITaxId());\r
+           text.append(", " + dcs.getTaxid());\r
          }\r
-         if (dcs[j].getOrganismName().length() > 0)\r
+         if (dcs.getVersion()!=null && dcs.getVersion().trim().length() > 0)\r
          {\r
-           text.append(", " + dcs[j].getOrganismName());\r
-         }\r
+           {\r
+             text.append(", " + dcs.getVersion());\r
+           }\r
  \r
-         text.append("<br>");\r
-       }\r
+           text.append("<br>");\r
+         }\r
  \r
-       text.append("<font color=\"#0000FF\">Description:</font> "\r
-               + dasSources[i].getDescription() + "<br>");\r
+         text.append("<font color=\"#0000FF\">Description:</font> "\r
+                 + ds.getDescription() + "<br>");\r
  \r
-       if (dasSources[i].getHelperurl() != null\r
-               && dasSources[i].getHelperurl().length() > 0)\r
-       {\r
-         text.append("<font color=\"#0000FF\"><a href=\""\r
-                 + dasSources[i].getHelperurl()\r
-                 + "\">Go to site</a></font<br>");\r
-       }\r
+         if (ds.getDocHref() != null && ds.getDocHref().length() > 0)\r
+         {\r
+           text.append("<font color=\"#0000FF\"><a href=\""\r
+                   + ds.getDocHref() + "\">Go to site</a></font<br>");\r
+         }\r
  \r
-       text.append("</font></html>");\r
+         text.append("</font></html>");\r
  \r
-       break;\r
+         break;\r
+       }\r
      }\r
\r
      fullDetails.setText(text.toString());\r
      javax.swing.SwingUtilities.invokeLater(new Runnable()\r
      {\r
      progressBar.setIndeterminate(true);\r
      setParentGuiEnabled(false);\r
      // Refresh the source list.\r
-     dasSources = null;\r
-     getDASSource();\r
+     sourceRegistry.refreshSources();\r
  \r
      init();\r
  \r
      }\r
    }\r
  \r
-   public Vector getSelectedSources()\r
+   public Vector<jalviewSourceI> getSelectedSources()\r
    {\r
      // wait around if we're still loading.\r
-     while (dasSources == null)\r
+     while (sourceRegistry == null)\r
      {\r
        if (!loadingDasSources)\r
        {\r
        }\r
      }\r
  \r
-     Vector selected = new Vector();\r
-     for (int r = 0; r < selectedSources.size(); r++)\r
+     Vector<jalviewSourceI> selected = new Vector<jalviewSourceI>();\r
+     for (String source : selectedSources)\r
      {\r
-       for (int i = 0; i < dasSources.length; i++)\r
+       jalviewSourceI srce = sourceRegistry.getSource(source);\r
+       if (srce != null)\r
        {\r
-         if (dasSources[i].getNickname()\r
-                 .equals(selectedSources.elementAt(r)))\r
-         {\r
-           selected.addElement(dasSources[i]);\r
-           break;\r
-         }\r
+         selected.addElement(srce);\r
        }\r
      }\r
      return selected;\r
    }\r
  \r
-   /**\r
-    * retrieve das sources from registry and add local source list\r
-    * \r
-    * @return\r
-    */\r
-   public DasSource[] getDASSource()\r
-   {\r
-     if (dasSources == null)\r
-     {\r
-       dasSources = jalview.ws.DasSequenceFeatureFetcher.getDASSources();\r
-       appendLocalSources();\r
-     }\r
\r
-     return dasSources;\r
-   }\r
\r
    public void refresh_actionPerformed(ActionEvent e)\r
    {\r
      saveProperties(jalview.bin.Cache.applicationProperties);\r
      worker.start();\r
    }\r
  \r
-   private void setCapabilities(DasSource[] sources)\r
+   private void setCapabilities(DasSourceRegistryI sourceRegistry2)\r
    {\r
-     Vector authority = new Vector();\r
-     Vector type = new Vector();\r
-     Vector label = new Vector();\r
\r
-     authority.addElement("Any");\r
-     type.addElement("Any");\r
-     label.addElement("Any");\r
+     Vector<String> authority = new Vector<String>();\r
+     Vector<String> type = new Vector<String>();\r
+     Vector<String> label = new Vector<String>();\r
+     Vector<String> taxIds = new Vector<String>();\r
+     authority.add("Any");\r
+     type.add("Any");\r
+     label.add("Any");\r
  \r
-     for (int i = 0; i < sources.length; i++)\r
+     for (jalviewSourceI ds : sourceRegistry2.getSources())\r
      {\r
-       DasSource ds = sources[i];\r
+       VERSION latest = ds.getVersion();\r
  \r
-       DasCoordinateSystem[] dcs = ds.getCoordinateSystem();\r
\r
-       for (int j = 0; j < dcs.length; j++)\r
+       for (COORDINATES cs : latest.getCOORDINATES())\r
        {\r
-         if (!type.contains(dcs[j].getCategory()))\r
+         if (!type.contains(cs.getSource()))\r
          {\r
-           type.addElement(dcs[j].getCategory());\r
+           type.add(cs.getSource()); // source==category\r
          }\r
  \r
-         if (!authority.contains(dcs[j].getName()))\r
+         if (!authority.contains(cs.getAuthority()))\r
          {\r
-           authority.addElement(dcs[j].getName());\r
+           authority.add(cs.getAuthority());\r
          }\r
        }\r
  \r
-       String[] slabels = ds.getLabels();\r
-       for (int s = 0; s < slabels.length; s++)\r
+       for (PROP slabel : latest.getPROP())\r
        {\r
-         if (!label.contains(slabels[s]))\r
+         if (slabel.getName().equalsIgnoreCase("LABEL")\r
+                 && !label.contains(slabel.getValue()))\r
          {\r
-           label.addElement(slabels[s]);\r
+           label.add(slabel.getValue());\r
          }\r
        }\r
  \r
      filter1.setListData(authority);\r
      filter2.setListData(type);\r
      filter3.setListData(label);\r
+     // filter4 taxIds\r
  \r
      javax.swing.SwingUtilities.invokeLater(new Runnable()\r
      {\r
      {\r
        int selectedRow = table.getSelectionModel().getMinSelectionIndex();\r
        nickname = table.getValueAt(selectedRow, 0).toString();\r
-       url = ((DasSource) localSources.get(nickname)).getUrl();\r
-       seqsrc = ((DasSource) localSources.get(nickname))\r
-               .hasCapability("sequence");\r
+       jalviewSourceI source = sourceRegistry.getSource(nickname);\r
+       url = source.getUri();\r
+       seqsrc = source.isSequenceSource();\r
      }\r
  \r
      JTextField nametf = new JTextField(nickname, 40);\r
        urltf.setText(urltf.getText() + "/");\r
      }\r
  \r
-     Das1Source local = new Das1Source();\r
+     jalviewSourceI local = sourceRegistry.createLocalSource(\r
+             urltf.getText(), nametf.getText(), seqs.isSelected(), true);\r
+     List sources = sourceRegistry.getSources();\r
+     int osize = sources.size();\r
+     int size = osize + (newSource ? 1 : 0);\r
  \r
-     local.setUrl(urltf.getText());\r
-     local.setNickname(nametf.getText());\r
-     if (seqs.isSelected())\r
+     Object[][] data = new Object[size][2];\r
+     DASTableModel dtm = (table != null) ? (DASTableModel)((TableSorter) table.getModel()).getTableModel()\r
+             : null;\r
+     for (int i = 0; i < osize; i++)\r
      {\r
-       local.setCapabilities(new String[]\r
-       { "features", "sequence" });\r
-     }\r
-     if (localSources == null)\r
-     {\r
-       localSources = new Hashtable();\r
-     }\r
\r
-     localSources.put(local.getNickname(), local);\r
\r
-     if (!newSource && !nickname.equals(nametf.getText()))\r
-     {\r
-       localSources.remove(nickname);\r
-     }\r
\r
-     int size = dasSources.length;\r
-     int adjust = newSource ? 1 : 0;\r
\r
-     Object[][] data = new Object[size + adjust][2];\r
-     for (int i = 0; i < size; i++)\r
-     {\r
-       if (!newSource && dasSources[i].getNickname().equals(nickname))\r
+       String osrc = (dtm == null || i >= osize) ? null : (String) dtm\r
+               .getValueAt(i, 0);\r
+       if (!newSource && osrc != null\r
+               && dtm.getValueAt(i, 0).equals(nickname))\r
        {\r
-         ((DasSource) dasSources[i]).setNickname(local.getNickname());\r
-         ((DasSource) dasSources[i]).setUrl(local.getUrl());\r
-         data[i][0] = local.getNickname();\r
+         data[i][0] = local.getTitle();\r
          data[i][1] = new Boolean(true);\r
        }\r
        else\r
        {\r
-         data[i][0] = dasSources[i].getNickname();\r
-         data[i][1] = new Boolean(selectedSources.contains(dasSources[i]\r
-                 .getNickname()));\r
+         data[i][0] = osrc;\r
+         data[i][1] = new Boolean(selectedSources.contains(osrc));\r
        }\r
      }\r
\r
+     // Always add a new source at the end\r
      if (newSource)\r
      {\r
-       data[size][0] = local.getNickname();\r
-       data[size][1] = new Boolean(true);\r
-       selectedSources.add(local.getNickname());\r
+       data[osize][0] = local.getTitle();\r
+       data[osize][1] = new Boolean(true);\r
+       selectedSources.add(local.getTitle());\r
      }\r
  \r
-     DasSource[] tmp = new DasSource[size + adjust];\r
\r
-     System.arraycopy(dasSources, 0, tmp, 0, size);\r
\r
-     if (newSource)\r
-     {\r
-       tmp[size] = local;\r
-     }\r
\r
-     dasSources = tmp;\r
\r
      refreshTableData(data);\r
  \r
      SwingUtilities.invokeLater(new Runnable()\r
        }\r
      });\r
  \r
-     displayFullDetails(local.getNickname());\r
+     displayFullDetails(local.getTitle());\r
    }\r
  \r
    public void editRemoveLocalSource(MouseEvent evt)\r
  \r
      String nickname = table.getValueAt(selectedRow, 0).toString();\r
  \r
-     if (!localSources.containsKey(nickname))\r
+     if (!sourceRegistry.getSource(nickname).isLocal())\r
      {\r
        JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
                "You can only edit or remove local DAS Sources!",\r
        amendLocal(false);\r
        break;\r
      case 1:\r
-       localSources.remove(nickname);\r
+       sourceRegistry.removeLocalSource(sourceRegistry.getSource(nickname));\r
        selectedSources.remove(nickname);\r
-       Object[][] data = new Object[dasSources.length - 1][2];\r
-       DasSource[] tmp = new DasSource[dasSources.length - 1];\r
-       int index = 0;\r
-       for (int i = 0; i < dasSources.length; i++)\r
+       Object[][] data = new Object[sourceRegistry.getSources().size()][2];\r
+       int index = 0,\r
+       l = table.getRowCount();\r
\r
+       for (int i = 0; i < l; i++)\r
        {\r
-         if (dasSources[i].getNickname().equals(nickname))\r
+         String nm;\r
+         if ((nm = (String) table.getValueAt(i, 0)).equals(nickname))\r
          {\r
            continue;\r
          }\r
          else\r
          {\r
-           tmp[index] = dasSources[i];\r
-           data[index][0] = dasSources[i].getNickname();\r
-           data[index][1] = new Boolean(\r
-                   selectedSources.contains(dasSources[i].getNickname()));\r
+           data[index][0] = nm;\r
+           data[index][1] = new Boolean(selectedSources.contains(nm));\r
            index++;\r
          }\r
        }\r
-       dasSources = tmp;\r
        refreshTableData(data);\r
        SwingUtilities.invokeLater(new Runnable()\r
        {\r
      }\r
    }\r
  \r
-   void appendLocalSources()\r
-   {\r
-     if (localSources == null)\r
-     {\r
-       return;\r
-     }\r
-     // note - we add all das sources to list so they can be filtered for the\r
-     // standard fetchDbRefs function\r
-     int size = dasSources != null ? dasSources.length : 0;\r
-     int lsize = localSources.size();\r
\r
-     Object[][] data = new Object[size + lsize][2];\r
-     for (int i = 0; i < size; i++)\r
-     {\r
-       data[i][0] = dasSources[i].getNickname();\r
-       data[i][1] = new Boolean(selectedSources.contains(dasSources[i]\r
-               .getNickname()));\r
-     }\r
\r
-     DasSource[] tmp = new DasSource[size + lsize];\r
-     if (dasSources != null)\r
-     {\r
-       System.arraycopy(dasSources, 0, tmp, 0, size);\r
-     }\r
\r
-     Enumeration en = localSources.keys();\r
-     int index = size;\r
-     while (en.hasMoreElements())\r
-     {\r
-       String key = en.nextElement().toString();\r
-       data[index][0] = key;\r
-       data[index][1] = new Boolean(false);\r
-       tmp[index] = new Das1Source();\r
-       tmp[index].setNickname(key);\r
-       tmp[index].setUrl(((DasSource) localSources.get(key)).getUrl());\r
\r
-       index++;\r
-     }\r
\r
-     dasSources = tmp;\r
\r
-     refreshTableData(data);\r
-   }\r
\r
    public void valueChanged(ListSelectionEvent evt)\r
    {\r
      // Called when the MainTable selection changes\r
      displayFullDetails(null);\r
  \r
      // Filter the displayed data sources\r
  \r
      ArrayList names = new ArrayList();\r
      ArrayList selected = new ArrayList();\r
-     DasSource ds;\r
  \r
      // The features filter is not visible, but we must still\r
      // filter the das source list here.\r
      // July 2006 - only 6 sources fo not serve features\r
      Object[] dummyFeatureList = new Object[]\r
      { "features" };\r
\r
-     for (int i = 0; i < dSize; i++)\r
+     List<jalviewSourceI> srcs=sourceRegistry.getSources();\r
+     for (jalviewSourceI ds : srcs)\r
      {\r
-       ds = dasSources[i];\r
-       DasCoordinateSystem[] dcs = ds.getCoordinateSystem();\r
  \r
-       if (dcs.length == 0 && ds.getCapabilities().length == 0\r
+       VERSION v = ds.getVersion();\r
+       List<COORDINATES> coords = v.getCOORDINATES();\r
+       if (ds.isLocal() || ((coords == null || coords.size() == 0)\r
                && filter1.getSelectedIndex() == 0\r
                && filter2.getSelectedIndex() == 0\r
-               && filter3.getSelectedIndex() == 0)\r
+               && filter3.getSelectedIndex() == 0))\r
        {\r
          // THIS IS A FIX FOR LOCAL SOURCES WHICH DO NOT\r
          // HAVE COORDINATE SYSTEMS, INFO WHICH AT PRESENT\r
          // IS ADDED FROM THE REGISTRY\r
-         names.add(ds.getNickname());\r
-         selected.add(new Boolean(selectedSources.contains(ds.getNickname())));\r
+         names.add(ds.getTitle());\r
+         selected.add(new Boolean(selectedSources.contains(ds.getTitle())));\r
          continue;\r
        }\r
  \r
-       if (!selectedInList(dummyFeatureList, ds.getCapabilities())\r
+       if (!selectedInList(dummyFeatureList, ds.getCapabilityList(v))\r
                || !selectedInList(filter3.getSelectedValues(),\r
-                       ds.getLabels()))\r
+                       ds.getLabelsFor(v)))\r
        {\r
          continue;\r
        }\r
  \r
-       for (int j = 0; j < dcs.length; j++)\r
+       for (int j = 0; j < coords.size(); j++)\r
        {\r
          if (selectedInList(filter1.getSelectedValues(), new String[]\r
-         { dcs[j].getName() })\r
+         { coords.get(j).getAuthority() })\r
                  && selectedInList(filter2.getSelectedValues(), new String[]\r
-                 { dcs[j].getCategory() }))\r
+                 { coords.get(j).getSource() }))\r
          {\r
-           names.add(ds.getNickname());\r
-           selected.add(new Boolean(selectedSources.contains(ds\r
-                   .getNickname())));\r
+           names.add(ds.getTitle());\r
+           selected.add(new Boolean(selectedSources.contains(ds.getTitle())));\r
            break;\r
          }\r
        }\r
      }\r
  \r
-     dSize = names.size();\r
+     int dSize = names.size();\r
      Object[][] data = new Object[dSize][2];\r
      for (int d = 0; d < dSize; d++)\r
      {\r
      refreshTableData(data);\r
    }\r
  \r
-   boolean selectedInList(Object[] selection, String[] items)\r
+   private boolean selectedInList(Object[] selection, String[] items)\r
    {\r
      for (int i = 0; i < selection.length; i++)\r
      {\r
        {\r
          return true;\r
        }\r
\r
+       if (items==null || items.length==0)\r
+       {\r
+         return false;\r
+       }\r
+       String sel=(items[0].startsWith("das1:") ? "das1:":"")+selection[i];\r
        for (int j = 0; j < items.length; j++)\r
        {\r
-         if (selection[i].equals(items[j]))\r
+         if (sel.equals(items[j]))\r
          {\r
            return true;\r
          }\r
      {\r
        selectedSources.addElement(st.nextToken());\r
      }\r
\r
-     Vector _localSources = jalview.bin.Cache.getLocalDasSources();\r
-     if (_localSources != null)\r
-     {\r
-       if (localSources == null)\r
-       {\r
-         localSources = new Hashtable();\r
-       }\r
-       Enumeration sources = _localSources.elements();\r
-       while (sources.hasMoreElements())\r
-       {\r
-         Das1Source source = (Das1Source) sources.nextElement();\r
-         localSources.put(source.getNickname(), source);\r
-       }\r
-     }\r
    }\r
  \r
    public void reset_actionPerformed(ActionEvent e)\r
    {\r
-     registryURL.setText(DEFAULT_REGISTRY);\r
+     registryURL.setText(sourceRegistry.getDasRegistryURL());\r
    }\r
  \r
    /**\r
      properties.setProperty(jalview.bin.Cache.DAS_ACTIVE_SOURCE,\r
              sb.toString());\r
  \r
-     if (localSources != null)\r
-     {\r
-       sb = new StringBuffer();\r
-       Enumeration en = localSources.keys();\r
-       while (en.hasMoreElements())\r
-       {\r
-         String token = en.nextElement().toString();\r
-         sb.append(token\r
-                 + "|"\r
-                 + (((DasSource) localSources.get(token))\r
-                         .hasCapability("sequence") ? "sequence:" : "")\r
-                 + ((DasSource) localSources.get(token)).getUrl() + "\t");\r
-       }\r
\r
-       properties.setProperty(jalview.bin.Cache.DAS_LOCAL_SOURCE,\r
-               sb.toString());\r
-     }\r
\r
+     String sourceprop = sourceRegistry.getLocalSourceString();\r
+     properties.setProperty(jalview.bin.Cache.DAS_LOCAL_SOURCE, sourceprop);\r
    }\r
  \r
    class DASTableModel extends AbstractTableModel\r
        }\r
      });\r
      thr.start();\r
-     while (loadingDasSources || dasSources == null)\r
+     while (loadingDasSources || sourceRegistry == null)\r
      {\r
        try\r
        {\r
      }\r
    }\r
  \r
-   public Vector resolveSourceNicknames(Vector sources)\r
-   {\r
\r
-     Vector resolved = new Vector();\r
-     if (sources != null)\r
-     {\r
-       for (int i = 0; i < dasSources.length; i++)\r
-       {\r
-         if (sources.contains(dasSources[i].getNickname()))\r
-         {\r
-           if (!resolved.contains(dasSources[i]))\r
-           {\r
-             resolved.addElement(dasSources[i]);\r
-           }\r
-         }\r
-       }\r
-     }\r
-     return resolved;\r
-   }\r
\r
    /**\r
     * disable or enable the buttons on the source browser\r
     * \r
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
   * 
   * This file is part of Jalview.
   * 
@@@ -19,11 -19,10 +19,10 @@@ package jalview.gui
  
  import java.io.*;
  import java.util.*;
+ import java.util.List;
  
  import java.awt.*;
  import java.awt.event.*;
- import java.awt.geom.AffineTransform;
- import java.awt.image.BufferedImage;
  import java.beans.PropertyChangeEvent;
  import java.beans.PropertyChangeListener;
  
@@@ -38,6 -37,7 +37,7 @@@ import jalview.datamodel.*
  import jalview.io.*;
  import jalview.schemes.AnnotationColourGradient;
  import jalview.schemes.GraduatedColor;
+ import jalview.ws.dbsources.das.api.jalviewSourceI;
  
  public class FeatureSettings extends JPanel
  {
      Vector allGroups = new Vector();
      SequenceFeature[] tmpfeatures;
      String group;
 -    for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
 +    for (int i = 0; i < af.getViewport().getAlignment().getHeight(); i++)
      {
 -      if (af.getViewport().alignment.getSequenceAt(i).getDatasetSequence()
 +      if (af.getViewport().getAlignment().getSequenceAt(i).getDatasetSequence()
                .getSequenceFeatures() == null)
        {
          continue;
        }
  
 -      tmpfeatures = af.getViewport().alignment.getSequenceAt(i)
 +      tmpfeatures = af.getViewport().getAlignment().getSequenceAt(i)
                .getDatasetSequence().getSequenceFeatures();
  
        int index = 0;
      // Find out which features should be visible depending on which groups
      // are selected / deselected
      // and recompute average width ordering
 -    for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
 +    for (int i = 0; i < af.getViewport().getAlignment().getHeight(); i++)
      {
  
 -      tmpfeatures = af.getViewport().alignment.getSequenceAt(i)
 +      tmpfeatures = af.getViewport().getAlignment().getSequenceAt(i)
                .getDatasetSequence().getSequenceFeatures();
        if (tmpfeatures == null)
        {
     * @param checkDbRefs
     * @param promptFetchDbRefs
     */
-   private void doDasFeatureFetch(Vector selectedSources,
+   private void doDasFeatureFetch(List<jalviewSourceI> selectedSources,
            boolean checkDbRefs, boolean promptFetchDbRefs)
    {
      SequenceI[] dataset, seqs;
     *          Vector of Strings to resolve to DAS source nicknames.
     * @return sources that are present in source list.
     */
-   public Vector resolveSourceNicknames(Vector sources)
+   public List<jalviewSourceI> resolveSourceNicknames(Vector sources)
    {
-     return dassourceBrowser.resolveSourceNicknames(sources);
+     return dassourceBrowser.sourceRegistry.resolveSourceNicknames(sources);
    }
  
    /**
    public void fetchDasFeatures(Vector sources, boolean block)
    {
      initDasSources();
-     Vector resolved = resolveSourceNicknames(sources);
+     List<jalviewSourceI> resolved = dassourceBrowser.sourceRegistry.resolveSourceNicknames(sources);
      if (resolved.size() == 0)
      {
        resolved = dassourceBrowser.getSelectedSources();
      }
      if (resolved.size() > 0)
      {
-       final Vector dassources = resolved;
+       final List<jalviewSourceI> dassources = resolved;
        fetchDAS.setEnabled(false);
        // cancelDAS.setEnabled(true); doDasFetch does this.
        Runnable fetcher = new Runnable()
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
   * 
   * This file is part of Jalview.
   * 
@@@ -17,7 -17,6 +17,6 @@@
   */
  package jalview.gui;
  
- import java.io.*;
  import java.util.*;
  
  import java.awt.*;
@@@ -25,19 -24,12 +24,12 @@@ import java.awt.event.*
  
  import javax.swing.*;
  
- import MCview.*;
  import jalview.datamodel.*;
- import jalview.datamodel.xdb.embl.*;
- import java.io.File;
  import jalview.io.*;
- import jalview.ws.DBRefFetcher;
- import jalview.ws.ebi.EBIFetchClient;
- import jalview.ws.seqfetcher.ASequenceFetcher;
+ import jalview.ws.dbsources.das.api.DasSourceRegistryI;
  import jalview.ws.seqfetcher.DbSourceProxy;
  
- import java.awt.Rectangle;
  import java.awt.BorderLayout;
- import java.awt.Dimension;
  
  public class SequenceFetcher extends JPanel implements Runnable
  {
@@@ -56,7 -48,7 +48,7 @@@
  
    private static jalview.ws.SequenceFetcher sfetch = null;
  
-   private static String dasRegistry = null;
+   private static DasSourceRegistryI dasRegistry = null;
  
    private static boolean _initingFetcher = false;
  
        }
      }
      if (sfetch == null
-             || dasRegistry != DasSourceBrowser.getDasRegistryURL())
+             || dasRegistry != jalview.bin.Cache.getDasSourceRegistry())
      {
        _initingFetcher = true;
        initingThread = Thread.currentThread();
          guiWindow.setProgressBar("Initialising Sequence Database Fetchers",
                  Thread.currentThread().hashCode());
        }
-       dasRegistry = DasSourceBrowser.getDasRegistryURL();
+       dasRegistry = jalview.bin.Cache.getDasSourceRegistry();
+       dasRegistry.refreshSources();
+       
        jalview.ws.SequenceFetcher sf = new jalview.ws.SequenceFetcher();
        if (guiWindow != null)
        {
        {
          for (int i = 0; i < al.getHeight(); i++)
          {
 -          alignFrame.viewport.alignment.addSequence(al.getSequenceAt(i)); // this
 +          alignFrame.viewport.getAlignment().addSequence(al.getSequenceAt(i)); // this
            // also
            // creates
            // dataset
            // sequence
            // entries
          }
 -        alignFrame.viewport.setEndSeq(alignFrame.viewport.alignment
 +        alignFrame.viewport.setEndSeq(alignFrame.viewport.getAlignment()
                  .getHeight());
 -        alignFrame.viewport.alignment.getWidth();
 +        alignFrame.viewport.getAlignment().getWidth();
          alignFrame.viewport.firePropertyChange("alignment", null,
                  alignFrame.viewport.getAlignment().getSequences());
        }
@@@ -1,6 -1,6 +1,6 @@@
  /*\r
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)\r
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle\r
   * \r
   * This file is part of Jalview.\r
   * \r
@@@ -30,6 -30,7 +30,7 @@@ import jalview.gui.CutAndPasteTransfer
  import jalview.gui.Desktop;\r
  import jalview.gui.IProgressIndicator;\r
  import jalview.gui.OOMWarning;\r
+ import jalview.ws.dbsources.das.api.jalviewSourceI;\r
  \r
  import java.lang.reflect.Array;\r
  import java.util.Enumeration;\r
@@@ -37,8 -38,6 +38,6 @@@ import java.util.Hashtable
  import java.util.StringTokenizer;\r
  import java.util.Vector;\r
  \r
- import org.biojava.dasobert.dasregistry.DasSource;\r
\r
  import uk.ac.ebi.picr.model.UPEntry;\r
  \r
  /**\r
@@@ -124,15 -123,15 +123,15 @@@ public class DBRefFetcher implements Ru
      {\r
        // af.featureSettings_actionPerformed(null);\r
        String[] defdb = null, otherdb = sfetcher\r
-               .getDbInstances(jalview.ws.dbsources.DasSequenceSource.class);\r
+               .getDbInstances(jalview.ws.dbsources.das.datamodel.DasSequenceSource.class);\r
        Vector selsources = new Vector(), dasselsrc = (af.featureSettings != null) ? af.featureSettings\r
                .getSelectedSources() : new jalview.gui.DasSourceBrowser()\r
                .getSelectedSources();\r
        Enumeration en = dasselsrc.elements();\r
        while (en.hasMoreElements())\r
        {\r
-         DasSource src = (DasSource) en.nextElement();\r
-         selsources.addElement(src.getNickname());\r
+         jalviewSourceI src = (jalviewSourceI) en.nextElement();\r
+         selsources.addElement(src.getTitle());\r
        }\r
        int osel = 0;\r
        for (int o = 0; otherdb != null && o < otherdb.length; o++)\r
      }\r
      // append additional sources\r
      String[] otherdb = sfetcher\r
-             .getDbInstances(jalview.ws.dbsources.DasSequenceSource.class);\r
+             .getDbInstances(jalview.ws.dbsources.das.datamodel.DasSequenceSource.class);\r
      if (otherdb != null && otherdb.length > 0)\r
      {\r
        String[] newsrc = new String[dbSources.length + otherdb.length];\r
@@@ -1,6 -1,6 +1,6 @@@
  /*\r
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)\r
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle\r
   * \r
   * This file is part of Jalview.\r
   * \r
   */\r
  package jalview.ws;\r
  \r
- import java.net.*;\r
- import java.util.*;\r
\r
- import javax.swing.*;\r
\r
- import org.biojava.dasobert.das.*;\r
- import org.biojava.dasobert.das2.*;\r
- import org.biojava.dasobert.das2.io.*;\r
- import org.biojava.dasobert.dasregistry.*;\r
- import org.biojava.dasobert.eventmodel.*;\r
  import jalview.bin.Cache;\r
- import jalview.datamodel.*;\r
- import jalview.gui.*;\r
+ import jalview.datamodel.DBRefEntry;\r
+ import jalview.datamodel.SequenceFeature;\r
+ import jalview.datamodel.SequenceI;\r
+ import jalview.gui.AlignFrame;\r
+ import jalview.gui.Desktop;\r
+ import jalview.gui.FeatureSettings;\r
  import jalview.util.UrlLink;\r
+ import jalview.ws.dbsources.das.api.DasSourceRegistryI;\r
+ import jalview.ws.dbsources.das.api.jalviewSourceI;\r
\r
+ import java.util.ArrayList;\r
+ import java.util.Enumeration;\r
+ import java.util.HashMap;\r
+ import java.util.HashSet;\r
+ import java.util.Iterator;\r
+ import java.util.List;\r
+ import java.util.Map;\r
+ import java.util.Set;\r
+ import java.util.StringTokenizer;\r
+ import java.util.Vector;\r
\r
+ import javax.swing.JOptionPane;\r
\r
+ import org.biodas.jdas.client.adapters.features.DasGFFAdapter;\r
+ import org.biodas.jdas.client.adapters.features.DasGFFAdapter.GFFAdapter;\r
+ import org.biodas.jdas.client.threads.FeaturesClientMultipleSources;\r
+ import org.biodas.jdas.schema.features.ERRORSEGMENT;\r
+ import org.biodas.jdas.schema.features.FEATURE;\r
+ import org.biodas.jdas.schema.features.LINK;\r
+ import org.biodas.jdas.schema.features.SEGMENT;\r
+ import org.biodas.jdas.schema.features.TYPE;\r
+ import org.biodas.jdas.schema.features.UNKNOWNFEATURE;\r
+ import org.biodas.jdas.schema.features.UNKNOWNSEGMENT;\r
+ import org.biodas.jdas.schema.sources.COORDINATES;\r
  \r
  /**\r
   * DOCUMENT ME!\r
@@@ -48,7 -69,7 +69,7 @@@ public class DasSequenceFeatureFetche
  \r
    StringBuffer sbuffer = new StringBuffer();\r
  \r
-   Vector selectedSources;\r
+   List<jalviewSourceI> selectedSources;\r
  \r
    boolean cancelled = false;\r
  \r
@@@ -75,6 -96,8 +96,8 @@@
  \r
    long startTime;\r
  \r
+   private DasSourceRegistryI sourceRegistry;\r
\r
    /**\r
     * Creates a new SequenceFeatureFetcher object. Uses default\r
     * \r
    }\r
  \r
    public DasSequenceFeatureFetcher(SequenceI[] oursequences,\r
-           FeatureSettings fsettings, Vector ourselectedSources,\r
+           FeatureSettings fsettings, List<jalviewSourceI> selectedSources2,\r
            boolean checkDbrefs, boolean promptFetchDbrefs)\r
    {\r
-     this.selectedSources = new Vector();\r
-     Enumeration sources = ourselectedSources.elements();\r
+     this.selectedSources = new ArrayList<jalviewSourceI>();\r
      // filter both sequences and sources to eliminate duplicates\r
-     while (sources.hasMoreElements())\r
+     for (jalviewSourceI src : selectedSources2)\r
      {\r
-       Object src = sources.nextElement();\r
        if (!selectedSources.contains(src))\r
        {\r
-         selectedSources.addElement(src);\r
+         selectedSources.add(src);\r
        }\r
        ;\r
      }\r
        af.setShowSeqFeatures(true);\r
      }\r
      int uniprotCount = 0;\r
-     for (int i = 0; i < selectedSources.size(); i++)\r
+     for (jalviewSourceI source : selectedSources)\r
      {\r
-       DasSource source = (DasSource) selectedSources.elementAt(i);\r
-       DasCoordinateSystem[] coords = source.getCoordinateSystem();\r
-       for (int c = 0; c < coords.length; c++)\r
+       for (COORDINATES coords : source.getVersion().getCOORDINATES())\r
        {\r
          // TODO: match UniProt coord system canonically (?) - does\r
          // UniProt==uniprot==UNIPROT ?\r
-         if (coords[c].getName().indexOf("UniProt") > -1)\r
+         if (coords.getAuthority().toLowerCase().equals("uniprot"))\r
          {\r
            uniprotCount++;\r
            break;\r
        }\r
        else\r
        {\r
-         startFetching();\r
+         _startFetching();\r
        }\r
      }\r
      else\r
      {\r
-       startFetching();\r
+       _startFetching();\r
      }\r
  \r
    }\r
\r
+   private void _startFetching()\r
+   {\r
+     new Thread(new FetchSeqFeatures()).start();\r
+   }\r
+   class FetchSeqFeatures implements Runnable\r
+   {\r
+     public void run()\r
+     {\r
+       startFetching();\r
+       setGuiFetchComplete();\r
+     }\r
+   }\r
    class FetchDBRefs implements Runnable\r
    {\r
      public void run()\r
      {\r
        new DBRefFetcher(sequences, af).fetchDBRefs(true);\r
        startFetching();\r
+       setGuiFetchComplete();\r
      }\r
    }\r
  \r
    /**\r
-    * Spawns a number of dasobert Fetcher threads to add features to sequences in\r
-    * the dataset\r
+    * Spawns Fetcher threads to add features to sequences in the dataset\r
     */\r
    void startFetching()\r
    {\r
      {\r
        af.setProgressBar("Fetching DAS Sequence Features", startTime);\r
      }\r
\r
+     if (sourceRegistry == null)\r
+     {\r
+       sourceRegistry = Cache.getDasSourceRegistry();\r
+     }\r
      if (selectedSources == null || selectedSources.size() == 0)\r
      {\r
        try\r
        {\r
-         DasSource[] sources = new jalview.gui.DasSourceBrowser()\r
-                 .getDASSource();\r
\r
+         jalviewSourceI[] sources = sourceRegistry.getSources().toArray(\r
+                 new jalviewSourceI[0]);\r
          String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE",\r
                  "uniprot");\r
          StringTokenizer st = new StringTokenizer(active, "\t");\r
            token = st.nextToken();\r
            for (int i = 0; i < sources.length; i++)\r
            {\r
-             if (sources[i].getNickname().equals(token))\r
+             if (sources[i].getTitle().equals(token))\r
              {\r
-               selectedSources.addElement(sources[i]);\r
+               selectedSources.add(sources[i]);\r
                break;\r
              }\r
            }\r
      }\r
  \r
      sourcesRemaining = selectedSources.size();\r
+     FeaturesClientMultipleSources fc = new FeaturesClientMultipleSources();\r
+     fc.setConnProps(sourceRegistry.getSessionHandler());\r
      // Now sending requests one at a time to each server\r
-     for (int sourceIndex = 0; sourceIndex < selectedSources.size()\r
-             && !cancelled; sourceIndex++)\r
+     ArrayList<jalviewSourceI> srcobj = new ArrayList<jalviewSourceI>();\r
+     ArrayList<String> src = new ArrayList<String>();\r
+     List<List<String>> ids = new ArrayList<List<String>>();\r
+     List<List<DBRefEntry>> idobj = new ArrayList<List<DBRefEntry>>();\r
+     List<Map<String, SequenceI>> sqset = new ArrayList<Map<String, SequenceI>>();\r
+     for (jalviewSourceI _sr : selectedSources)\r
+     {\r
\r
+       Map<String, SequenceI> slist = new HashMap<String, SequenceI>();\r
+       List<DBRefEntry> idob = new ArrayList<DBRefEntry>();\r
+       List<String> qset = new ArrayList<String>();\r
\r
+       for (SequenceI seq : sequences)\r
+       {\r
+         Object[] idset = nextSequence(_sr, seq);\r
+         if (idset != null)\r
+         {\r
+           List<DBRefEntry> _idob = (List<DBRefEntry>) idset[0];\r
+           List<String> _qset = (List<String>) idset[1];\r
+           if (_idob.size() > 0)\r
+           {\r
+             // add sequence's ref for each id derived from it\r
+             // (space inefficient, but most unambiguous)\r
+             // could replace with hash with _qset values as keys.\r
+             Iterator<DBRefEntry> dbobj = _idob.iterator();\r
+             for (String q : _qset)\r
+             {\r
+               SequenceI osq = slist.get(q);\r
+               DBRefEntry dr = dbobj.next();\r
+               if (osq != null && osq != seq)\r
+               {\r
+                 // skip - non-canonical query\r
+               }\r
+               else\r
+               {\r
+                 idob.add(dr);\r
+                 qset.add(q);\r
+                 slist.put(q, seq);\r
+               }\r
+             }\r
+           }\r
+         }\r
+       }\r
+       if (idob.size() > 0)\r
+       {\r
+         srcobj.add(_sr);\r
+         src.add(_sr.getSourceURL());\r
+         ids.add(qset);\r
+         idobj.add(idob);\r
+         sqset.add(slist);\r
+       }\r
+     }\r
+     Map<String, Map<List<String>, Exception>> errors = new HashMap<String, Map<List<String>, Exception>>();\r
+     Map<String, Map<List<String>, DasGFFAdapter>> results = new HashMap<String, Map<List<String>, DasGFFAdapter>>();\r
+     fc.fetchData(src, ids, false, results, errors);\r
+     fc.shutDown();\r
+     while (!fc.isTerminated())\r
+     {\r
+       try\r
+       {\r
+         Thread.sleep(200);\r
+       } catch (InterruptedException x)\r
+       {\r
\r
+       }\r
+     }\r
+     Iterator<List<String>> idset = ids.iterator();\r
+     Iterator<List<DBRefEntry>> idobjset = idobj.iterator();\r
+     Iterator<Map<String, SequenceI>> seqset = sqset.iterator();\r
+     for (jalviewSourceI source : srcobj)\r
+     {\r
+       processResponse(seqset.next(), source, idset.next(), idobjset.next(),\r
+               results.get(source.getSourceURL()),\r
+               errors.get(source.getSourceURL()));\r
+     }\r
+   }\r
\r
+   private void processResponse(Map<String, SequenceI> sequencemap,\r
+           jalviewSourceI jvsource, List<String> ids,\r
+           List<DBRefEntry> idobj, Map<List<String>, DasGFFAdapter> results,\r
+           Map<List<String>, Exception> errors)\r
+   {\r
+     Set<SequenceI> sequences = new HashSet<SequenceI>();\r
+     String source = jvsource.getSourceURL();\r
+     // process features\r
+     DasGFFAdapter result = (results == null) ? null : results.get(ids);\r
+     Exception error = (errors == null) ? null : errors.get(ids);\r
+     if (result == null)\r
+     {\r
+       debug("das source " + source + " could not be contacted. "\r
+               + (error == null ? "" : error.toString()));\r
+     }\r
+     else\r
      {\r
-       DasSource dasSource = (DasSource) selectedSources\r
-               .elementAt(sourceIndex);\r
  \r
-       nextSequence(dasSource, sequences[0]);\r
+       GFFAdapter gff = result.getGFF();\r
+       List<SEGMENT> segments = gff.getSegments();\r
+       List<ERRORSEGMENT> errorsegs = gff.getErrorSegments();\r
+       List<UNKNOWNFEATURE> unkfeats = gff.getUnknownFeatures();\r
+       List<UNKNOWNSEGMENT> unksegs = gff.getUnknownSegments();\r
+       debug("das source " + source + " returned " + gff.getTotal()\r
+               + " responses. " + (errorsegs != null ? errorsegs.size() : 0)\r
+               + " were incorrect segment queries, "\r
+               + (unkfeats != null ? unkfeats.size() : 0)\r
+               + " were unknown features "\r
+               + (unksegs != null ? unksegs.size() : 0)\r
+               + " were unknown segments and "\r
+               + (segments != null ? segments.size() : 0)\r
+               + " were segment responses.");\r
+       Iterator<DBRefEntry> dbr = idobj.iterator();\r
+       if (segments != null)\r
+       {\r
+         for (SEGMENT seg : segments)\r
+         {\r
+           String id = seg.getId();\r
+           DBRefEntry dbref = idobj.get(ids.indexOf(id));\r
+           SequenceI sequence = sequencemap.get(id);\r
+           boolean added = false;\r
+           sequences.add(sequence);\r
\r
+           for (FEATURE feat : seg.getFEATURE())\r
+           {\r
+             // standard DAS feature-> jalview sequence feature transformation\r
+             SequenceFeature f = newSequenceFeature(feat, jvsource.getTitle());\r
+             if (!parseSeqFeature(sequence, f, feat, jvsource))\r
+             {\r
+               if (dbref.getMap() != null && f.getBegin() > 0\r
+                       && f.getEnd() > 0)\r
+               {\r
+                 debug("mapping from " + f.getBegin() + " - " + f.getEnd());\r
+                 SequenceFeature vf[] = null;\r
\r
+                 try\r
+                 {\r
+                   vf = dbref.getMap().locateFeature(f);\r
+                 } catch (Exception ex)\r
+                 {\r
+                   Cache.log\r
+                           .info("Error in 'experimental' mapping of features. Please try to reproduce and then report info to jalview-discuss@jalview.org.");\r
+                   Cache.log.info("Mapping feature from " + f.getBegin()\r
+                           + " to " + f.getEnd() + " in dbref "\r
+                           + dbref.getAccessionId() + " in "\r
+                           + dbref.getSource());\r
+                   Cache.log.info("using das Source " + source);\r
+                   Cache.log.info("Exception", ex);\r
+                 }\r
\r
+                 if (vf != null)\r
+                 {\r
+                   for (int v = 0; v < vf.length; v++)\r
+                   {\r
+                     debug("mapping to " + v + ": " + vf[v].getBegin()\r
+                             + " - " + vf[v].getEnd());\r
+                     sequence.addSequenceFeature(vf[v]);\r
+                   }\r
+                 }\r
+               }\r
+               else\r
+               {\r
+                 sequence.addSequenceFeature(f);\r
+               }\r
+             }\r
+           }\r
+         }\r
+         featuresAdded(sequences);\r
+       }\r
+       else\r
+       {\r
+         // System.out.println("No features found for " + seq.getName()\r
+         // + " from: " + e.getDasSource().getNickname());\r
+       }\r
      }\r
    }\r
  \r
  \r
    int sourcesRemaining = 0;\r
  \r
-   void responseComplete(DasSource dasSource, SequenceI seq)\r
-   {\r
-     if (seq != null)\r
-     {\r
-       for (int seqIndex = 0; seqIndex < sequences.length - 1 && !cancelled; seqIndex++)\r
-       {\r
-         if (sequences[seqIndex] == seq)\r
-         {\r
-           nextSequence(dasSource, sequences[++seqIndex]);\r
-           return;\r
-         }\r
-       }\r
-     }\r
\r
-     sourcesRemaining--;\r
\r
-     if (sourcesRemaining == 0)\r
-     {\r
-       System.err.println("Fetching Complete.");\r
-       setGuiFetchComplete();\r
-     }\r
\r
-   }\r
\r
    private void setGuiFetchComplete()\r
    {\r
  \r
      }\r
    }\r
  \r
-   void featuresAdded(SequenceI seq)\r
+   void featuresAdded(Set<SequenceI> seqs)\r
    {\r
      if (af == null)\r
      {\r
      int index;\r
      for (index = start; index < end; index++)\r
      {\r
-       if (seq == af.getViewport().getAlignment().getSequenceAt(index)\r
-               .getDatasetSequence())\r
+       for (SequenceI seq : seqs)\r
        {\r
-         af.alignPanel.paintAlignment(true);\r
-         break;\r
+         if (seq == af.getViewport().getAlignment().getSequenceAt(index)\r
+                 .getDatasetSequence())\r
+         {\r
+           af.alignPanel.paintAlignment(true);\r
+           index = end;\r
+           break;\r
+         }\r
        }\r
      }\r
    }\r
  \r
-   void nextSequence(DasSource dasSource, SequenceI seq)\r
+   Object[] nextSequence(jalviewSourceI dasSource, SequenceI seq)\r
    {\r
      if (cancelled)\r
-       return;\r
+       return null;\r
      DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs(\r
              seq.getDBRef(), new String[]\r
              {\r
      // TODO: minimal list of DAS queries to make by querying with untyped ID if\r
      // distinct from any typed IDs\r
  \r
+     List<DBRefEntry> ids = new ArrayList<DBRefEntry>();\r
+     List<String> qstring = new ArrayList<String>();\r
      boolean dasCoordSysFound = false;\r
  \r
      if (uprefs != null)\r
        // do any of these ids match the source's coordinate system ?\r
        for (int j = 0; !dasCoordSysFound && j < uprefs.length; j++)\r
        {\r
-         DasCoordinateSystem cs[] = dasSource.getCoordinateSystem();\r
  \r
-         for (int csIndex = 0; csIndex < cs.length && !dasCoordSysFound; csIndex++)\r
+         for (COORDINATES csys : dasSource.getVersion().getCOORDINATES())\r
          {\r
-           if (cs.length > 0\r
-                   && jalview.util.DBRefUtils.isDasCoordinateSystem(\r
-                           cs[csIndex].getName(), uprefs[j]))\r
+           if (jalview.util.DBRefUtils.isDasCoordinateSystem(\r
+                   csys.getAuthority(), uprefs[j]))\r
            {\r
              debug("Launched fetcher for coordinate system "\r
-                     + cs[0].getName());\r
+                     + csys.getAuthority());\r
              // Will have to pass any mapping information to the fetcher\r
              // - the start/end for the DBRefEntry may not be the same as the\r
              // sequence's start/end\r
  \r
              System.out.println(seq.getName() + " "\r
                      + (seq.getDatasetSequence() == null) + " "\r
-                     + dasSource.getUrl());\r
+                     + csys.getUri());\r
  \r
              dasCoordSysFound = true; // break's out of the loop\r
-             createFeatureFetcher(seq, dasSource, uprefs[j]);\r
+             ids.add(uprefs[j]);\r
+             qstring.add(uprefs[j].getAccessionId());\r
            }\r
            else\r
-             System.out.println("IGNORE " + cs[csIndex].getName());\r
+             System.out.println("IGNORE " + csys.getAuthority());\r
          }\r
        }\r
      }\r
        }\r
        if (id != null)\r
        {\r
+         DBRefEntry dbre = new DBRefEntry();\r
+         dbre.setAccessionId(id);\r
          // Should try to call a general feature fetcher that\r
          // queries many sources with name to discover applicable ID references\r
-         createFeatureFetcher(seq, dasSource, id);\r
-       }\r
-     }\r
\r
-   }\r
\r
-   /**\r
-    * fetch and add das features to a sequence using the given source URL and\r
-    * compatible DbRef id. new features are mapped using the DbRef mapping to the\r
-    * local coordinate system.\r
-    * \r
-    * @param seq\r
-    * @param SourceUrl\r
-    * @param dbref\r
-    */\r
-   protected void createFeatureFetcher(final SequenceI seq,\r
-           final DasSource dasSource, final DBRefEntry dbref)\r
-   {\r
\r
-     // ////////////\r
-     // / fetch DAS features\r
-     final Das1Source source = new Das1Source();\r
-     source.setUrl(dasSource.getUrl());\r
-     source.setNickname(dasSource.getNickname());\r
-     if (dbref == null || dbref.getAccessionId() == null\r
-             || dbref.getAccessionId().length() < 1)\r
-     {\r
-       responseComplete(dasSource, seq); // reduce thread count anyhow\r
-       return;\r
-     }\r
-     debug("new Das Feature Fetcher for " + dbref.getSource() + ":"\r
-             + dbref.getAccessionId() + " querying " + dasSource.getUrl());\r
-     FeatureThread fetcher = new FeatureThread(dbref.getAccessionId()\r
-     // + ":" + start + "," + end,\r
-             , source);\r
\r
-     fetcher.addFeatureListener(new FeatureListener()\r
-     {\r
-       public void comeBackLater(FeatureEvent e)\r
-       {\r
-         responseComplete(dasSource, seq);\r
-         debug("das source " + e.getSource().getNickname()\r
-                 + " asked us to come back in " + e.getComeBackLater()\r
-                 + " secs.");\r
-       }\r
\r
-       public void newFeatures(FeatureEvent e)\r
-       {\r
\r
-         Das1Source ds = e.getSource();\r
\r
-         Map[] features = e.getFeatures();\r
-         // add features to sequence\r
-         debug("das source " + ds.getUrl() + " returned " + features.length\r
-                 + " features");\r
\r
-         if (features.length > 0)\r
-         {\r
-           for (int i = 0; i < features.length; i++)\r
-           {\r
-             // standard DAS feature-> jalview sequence feature transformation\r
-             SequenceFeature f = newSequenceFeature(features[i],\r
-                     source.getNickname());\r
-             if (!parseSeqFeature(seq, f, features[i], source))\r
-             {\r
-               if (dbref.getMap() != null && f.getBegin() > 0\r
-                       && f.getEnd() > 0)\r
-               {\r
-                 debug("mapping from " + f.getBegin() + " - " + f.getEnd());\r
-                 SequenceFeature vf[] = null;\r
\r
-                 try\r
-                 {\r
-                   vf = dbref.getMap().locateFeature(f);\r
-                 } catch (Exception ex)\r
-                 {\r
-                   Cache.log\r
-                           .info("Error in 'experimental' mapping of features. Please try to reproduce and then report info to jalview-discuss@jalview.org.");\r
-                   Cache.log.info("Mapping feature from " + f.getBegin()\r
-                           + " to " + f.getEnd() + " in dbref "\r
-                           + dbref.getAccessionId() + " in "\r
-                           + dbref.getSource());\r
-                   Cache.log.info("using das Source " + ds.getUrl());\r
-                   Cache.log.info("Exception", ex);\r
-                 }\r
\r
-                 if (vf != null)\r
-                 {\r
-                   for (int v = 0; v < vf.length; v++)\r
-                   {\r
-                     debug("mapping to " + v + ": " + vf[v].getBegin()\r
-                             + " - " + vf[v].getEnd());\r
-                     seq.addSequenceFeature(vf[v]);\r
-                   }\r
-                 }\r
-               }\r
-               else\r
-               {\r
-                 seq.addSequenceFeature(f);\r
-               }\r
-             }\r
-           }\r
-           featuresAdded(seq);\r
-         }\r
-         else\r
-         {\r
-           // System.out.println("No features found for " + seq.getName()\r
-           // + " from: " + e.getDasSource().getNickname());\r
-         }\r
-         responseComplete(dasSource, seq);\r
\r
+         ids.add(dbre);\r
+         qstring.add(dbre.getAccessionId());\r
        }\r
      }\r
  \r
-     );\r
\r
-     fetcher.start();\r
-   }\r
\r
-   protected void createFeatureFetcher(final SequenceI seq,\r
-           final DasSource dasSource, String id)\r
-   {\r
-     // ////////////\r
-     // / fetch DAS features\r
-     final Das1Source source = new Das1Source();\r
-     source.setUrl(dasSource.getUrl());\r
-     source.setNickname(dasSource.getNickname());\r
\r
-     if (id != null)\r
-     {\r
-       id = id.trim();\r
-     }\r
-     if (id != null && id.length() > 0)\r
-     {\r
-       debug("new Das Feature Fetcher for " + id + " querying "\r
-               + dasSource.getUrl());\r
-       FeatureThread fetcher = new FeatureThread(id\r
-       // + ":" + start + "," + end,\r
-               , source);\r
\r
-       fetcher.addFeatureListener(new FeatureListener()\r
-       {\r
-         public void comeBackLater(FeatureEvent e)\r
-         {\r
-           responseComplete(dasSource, seq);\r
-           debug("das source " + e.getSource().getNickname()\r
-                   + " asked us to come back in " + e.getComeBackLater()\r
-                   + " secs.");\r
-         }\r
\r
-         public void newFeatures(FeatureEvent e)\r
-         {\r
\r
-           Das1Source ds = e.getSource();\r
\r
-           Map[] features = e.getFeatures();\r
-           // add features to sequence\r
-           debug("das source " + ds.getUrl() + " returned "\r
-                   + features.length + " features");\r
\r
-           if (features.length > 0)\r
-           {\r
-             for (int i = 0; i < features.length; i++)\r
-             {\r
-               // standard DAS feature-> jalview sequence feature transformation\r
-               SequenceFeature f = newSequenceFeature(features[i],\r
-                       source.getNickname());\r
-               if (!parseSeqFeature(seq, f, features[i], source))\r
-               {\r
-                 // just add as a simple sequence feature\r
-                 seq.addSequenceFeature(f);\r
-               }\r
-             }\r
\r
-             featuresAdded(seq);\r
-           }\r
-           else\r
-           {\r
-             // System.out.println("No features found for " + seq.getName()\r
-             // + " from: " + e.getDasSource().getNickname());\r
-           }\r
-           responseComplete(dasSource, seq);\r
\r
-         }\r
-       }\r
\r
-       );\r
\r
-       fetcher.start();\r
-     }\r
-     else\r
-     {\r
-       // invalid fetch - indicate it is finished.\r
-       debug("Skipping empty ID for querying " + dasSource.getUrl());\r
-       responseComplete(dasSource, seq);\r
-     }\r
+     return new Object[]\r
+     { ids, qstring };\r
    }\r
  \r
    /**\r
     * @return true if feature was consumed as another kind of annotation.\r
     */\r
    protected boolean parseSeqFeature(SequenceI seq, SequenceFeature f,\r
-           Map map, Das1Source source)\r
+           FEATURE feature, jalviewSourceI source)\r
    {\r
      SequenceI mseq = seq;\r
      while (seq.getDatasetSequence() != null)\r
          // try to parse the accession out\r
  \r
          DBRefEntry dbr = new DBRefEntry();\r
-         dbr.setVersion(source.getNickname());\r
+         dbr.setVersion(source.getTitle());\r
          StringTokenizer st = new StringTokenizer(f.getDescription(), ":");\r
          if (st.hasMoreTokens())\r
          {\r
    /**\r
     * creates a jalview sequence feature from a das feature document\r
     * \r
-    * @param dasfeature\r
+    * @param feat\r
     * @return sequence feature object created using dasfeature information\r
     */\r
-   SequenceFeature newSequenceFeature(Map dasfeature, String nickname)\r
+   SequenceFeature newSequenceFeature(FEATURE feat, String nickname)\r
    {\r
-     if (dasfeature == null)\r
+     if (feat == null)\r
      {\r
        return null;\r
      }\r
         * qName.equals("SCORE")\r
         */\r
        String desc = new String();\r
-       if (dasfeature.containsKey("NOTE"))\r
+       if (feat.getNOTE() != null)\r
        {\r
-         desc += (String) dasfeature.get("NOTE");\r
+         for (String note : feat.getNOTE())\r
+         {\r
+           desc += (String) note;\r
+         }\r
        }\r
  \r
        int start = 0, end = 0;\r
  \r
        try\r
        {\r
-         start = Integer.parseInt(dasfeature.get("START").toString());\r
+         start = Integer.parseInt(feat.getSTART().toString());\r
        } catch (Exception ex)\r
        {\r
        }\r
        try\r
        {\r
-         end = Integer.parseInt(dasfeature.get("END").toString());\r
+         end = Integer.parseInt(feat.getEND().toString());\r
        } catch (Exception ex)\r
        {\r
        }\r
        try\r
        {\r
-         Object scr = dasfeature.get("SCORE");\r
+         Object scr = feat.getSCORE();\r
          if (scr != null)\r
          {\r
            score = (float) Double.parseDouble(scr.toString());\r
        }\r
  \r
        SequenceFeature f = new SequenceFeature(\r
-               (String) dasfeature.get("TYPE"), desc, start, end, score,\r
+               getTypeString(feat.getTYPE()), desc, start, end, score,\r
                nickname);\r
  \r
-       if (dasfeature.containsKey("LINK"))\r
+       if (feat.getLINK() != null)\r
        {\r
-         // Do not put feature extent in link text for non-positional features\r
-         if (f.begin == 0 && f.end == 0)\r
-         {\r
-           f.addLink(f.getType() + "|" + dasfeature.get("LINK"));\r
-         }\r
-         else\r
+         for (LINK link : feat.getLINK())\r
          {\r
-           f.addLink(f.getType() + " " + f.begin + "_" + f.end + "|"\r
-                   + dasfeature.get("LINK"));\r
+           // Do not put feature extent in link text for non-positional features\r
+           if (f.begin == 0 && f.end == 0)\r
+           {\r
+             f.addLink(f.getType() + " " + link.getContent() + "|"\r
+                     + link.getHref());\r
+           }\r
+           else\r
+           {\r
+             f.addLink(f.getType() + " " + f.begin + "_" + f.end + " "\r
+                     + link.getContent() + "|" + link.getHref());\r
+           }\r
          }\r
        }\r
  \r
        System.out.println("ERRR " + e);\r
        e.printStackTrace();\r
        System.out.println("############");\r
-       debug("Failed to parse " + dasfeature.toString(), e);\r
+       debug("Failed to parse " + feat.toString(), e);\r
        return null;\r
      }\r
    }\r
  \r
-   /**\r
-    * query the default DAS Source Registry for sources. Uses value of jalview\r
-    * property DAS_REGISTRY_URL and the DasSourceBrowser.DEFAULT_REGISTRY if that\r
-    * doesn't exist.\r
-    * \r
-    * @return list of sources\r
-    */\r
-   public static DasSource[] getDASSources()\r
-   {\r
\r
-     String registryURL = jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",\r
-             DasSourceBrowser.DEFAULT_REGISTRY);\r
-     return getDASSources(registryURL);\r
-   }\r
\r
-   /**\r
-    * query the given URL for DasSources.\r
-    * \r
-    * @param registryURL\r
-    *          return sources from registryURL\r
-    */\r
-   public static DasSource[] getDASSources(String registryURL)\r
+   private String getTypeString(TYPE type)\r
    {\r
-     DasSourceReaderImpl reader = new DasSourceReaderImpl();\r
\r
-     try\r
-     {\r
-       URL url = new URL(registryURL);\r
\r
-       DasSource[] sources = reader.readDasSource(url);\r
\r
-       List das1sources = new ArrayList();\r
-       for (int i = 0; i < sources.length; i++)\r
-       {\r
-         DasSource ds = sources[i];\r
-         if (ds instanceof Das2Source)\r
-         {\r
-           Das2Source d2s = (Das2Source) ds;\r
-           if (d2s.hasDas1Capabilities())\r
-           {\r
-             Das1Source d1s = DasSourceConverter.toDas1Source(d2s);\r
-             das1sources.add(d1s);\r
-           }\r
\r
-         }\r
-         else if (ds instanceof Das1Source)\r
-         {\r
-           das1sources.add((Das1Source) ds);\r
-         }\r
-       }\r
\r
-       return (Das1Source[]) das1sources.toArray(new Das1Source[das1sources\r
-               .size()]);\r
-     } catch (Exception ex)\r
-     {\r
-       System.err.println("Failed to contact DAS1 registry at "\r
-               + registryURL);\r
-       ex.printStackTrace();\r
-       return null;\r
-     }\r
+     return type.getContent();\r
    }\r
  \r
  }\r
@@@ -1,6 -1,6 +1,6 @@@
  /*\r
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)\r
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle\r
   * \r
   * This file is part of Jalview.\r
   * \r
   */\r
  package jalview.ws;\r
  \r
- import java.util.ArrayList;\r
- import java.util.Enumeration;\r
- import java.util.Vector;\r
\r
- import org.biojava.dasobert.das2.Das2Source;\r
- import org.biojava.dasobert.dasregistry.Das1Source;\r
- import org.biojava.dasobert.dasregistry.DasCoordinateSystem;\r
- import org.biojava.dasobert.dasregistry.DasSource;\r
\r
  import jalview.datamodel.Alignment;\r
  import jalview.datamodel.AlignmentI;\r
  import jalview.datamodel.DBRefSource;\r
  import jalview.datamodel.SequenceI;\r
- import jalview.ws.dbsources.DasSequenceSource;\r
+ import jalview.ws.dbsources.das.api.jalviewSourceI;\r
  import jalview.ws.seqfetcher.ASequenceFetcher;\r
  import jalview.ws.seqfetcher.DbSourceProxy;\r
  \r
+ import java.util.ArrayList;\r
+ import java.util.Enumeration;\r
+ import java.util.List;\r
+ import java.util.Vector;\r
\r
  /**\r
   * This is the the concrete implementation of the sequence retrieval interface\r
   * and abstract class in jalview.ws.seqfetcher. This implements the run-time\r
@@@ -61,8 -57,6 +57,8 @@@ public class SequenceFetcher extends AS
      // alignment is\r
      // 'default' for\r
      // PFAM\r
 +    addDBRefSourceImpl(jalview.ws.dbsources.RfamFull.class);\r
 +    addDBRefSourceImpl(jalview.ws.dbsources.RfamSeed.class);\r
      registerDasSequenceSources();\r
    }\r
  \r
@@@ -77,7 -71,7 +73,7 @@@
      for (int i = 0; i < srcs.length; i++)\r
      {\r
        String nm = getSourceProxy(srcs[i]).getDbName();\r
-       if (getSourceProxy(srcs[i]) instanceof jalview.ws.dbsources.DasSequenceSource)\r
+       if (getSourceProxy(srcs[i]) instanceof jalview.ws.dbsources.das.datamodel.DasSequenceSource)\r
        {\r
          if (nm.startsWith("das:"))\r
          {\r
     */\r
    public void registerDasSequenceSources()\r
    {\r
-     DasSource[] sources = jalview.ws.DasSequenceFeatureFetcher\r
-             .getDASSources();\r
-     if (sources != null)\r
-     {\r
-       for (int s = 0; sources != null && s < sources.length; s++)\r
-       {\r
-         addDasSequenceSource(sources[s]);\r
-       }\r
-     }\r
\r
-     Vector localsources = jalview.bin.Cache.getLocalDasSources();\r
-     if (localsources != null)\r
-     {\r
-       for (Enumeration ls = localsources.elements(); ls.hasMoreElements();)\r
-       {\r
-         addDasSequenceSource((DasSource) ls.nextElement());\r
-       }\r
-     }\r
-   }\r
\r
-   /**\r
-    * Try to create and add a DasSequenceSource to the list of sources.\r
-    * \r
-    * @param source\r
-    * @return null if no source was added, or the new DasSequenceSource created\r
-    */\r
-   DasSequenceSource addDasSequenceSource(DasSource source)\r
-   {\r
-     DasSequenceSource ds = null;\r
-     Das1Source d1s = null;\r
-     if (source.hasCapability("sequence"))\r
-     {\r
-       if (source instanceof Das2Source)\r
-       {\r
-         if (((Das2Source) source).hasDas1Capabilities())\r
-         {\r
-           try\r
-           {\r
-             d1s = org.biojava.dasobert.das2.DasSourceConverter\r
-                     .toDas1Source((Das2Source) source);\r
-           } catch (Exception e)\r
-           {\r
-             System.err.println("Ignoring DAS2 sequence source "\r
-                     + source.getNickname()\r
-                     + " - couldn't map to Das1Source.\n");\r
-             e.printStackTrace();\r
-           }\r
-         }\r
-       }\r
-       else\r
-       {\r
-         if (source instanceof Das1Source)\r
-         {\r
-           d1s = (Das1Source) source;\r
-         }\r
-       }\r
-     }\r
-     if (d1s != null)\r
+     // TODO: define a context as a registry provider (either desktop,\r
+     // jalview.bin.cache, or something else).\r
+     for (jalviewSourceI source : jalview.bin.Cache.getDasSourceRegistry().getSources())\r
      {\r
-       DasCoordinateSystem[] css = d1s.getCoordinateSystem();\r
-       if (css == null || css.length == 0)\r
+       if (source.isSequenceSource())\r
        {\r
-         // TODO: query das source directly to identify coordinate system... or\r
-         // have to make up a coordinate system\r
-         css = new DasCoordinateSystem[]\r
-         { new DasCoordinateSystem() };\r
-         css[0].setName(d1s.getNickname());\r
-         css[0].setUniqueId(d1s.getNickname());\r
-       }\r
-       for (int c = 0; c < css.length; c++)\r
-       {\r
-         try\r
+         List<DbSourceProxy> dassources = source.getSequenceSourceProxies();\r
+         for (DbSourceProxy seqsrc : dassources)\r
          {\r
-           addDbRefSourceImpl(ds = new DasSequenceSource("das:"\r
-                   + d1s.getNickname() + " (" + css[c].getName() + ")",\r
-                   css[c].getName(), d1s, css[c]));\r
-         } catch (Exception e)\r
-         {\r
-           System.err.println("Ignoring sequence coord system " + c + " ("\r
-                   + css[c].getName() + ") for source " + d1s.getNickname()\r
-                   + "- threw exception when constructing fetcher.\n");\r
-           e.printStackTrace();\r
+           addDbRefSourceImpl(seqsrc);\r
          }\r
        }\r
      }\r
-     return ds;\r
    }\r
  }\r
@@@ -1,6 -1,6 +1,6 @@@
  /*\r
   * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)\r
 - * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
 + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle\r
   * \r
   * This file is part of Jalview.\r
   * \r
@@@ -31,7 -31,7 +31,7 @@@ import com.stevesoft.pat.Regex
   * database (unify with io)\r
   * \r
   * @author JimP\r
-  * \r
+  * TODO: promote to API\r
   */\r
  public interface DbSourceProxy\r
  {\r