update author list in license for (JAL-826)
[jalview.git] / src / jalview / gui / SequenceFetcher.java
index 84e0e91..3fa00f5 100755 (executable)
-package jalview.gui;\r
-\r
-import javax.swing.*;\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-import jalview.io.EBIFetchClient;\r
-import MCview.*;\r
-import jalview.datamodel.*;\r
-import jalview.analysis.AlignSeq;\r
-import java.io.File;\r
-import jalview.io.*;\r
-import java.util.*;\r
-\r
-\r
-public class SequenceFetcher\r
-    extends JPanel implements Runnable\r
-{\r
-  JInternalFrame frame;\r
-  AlignFrame alignFrame;\r
-  StringBuffer result;\r
-  public SequenceFetcher(AlignFrame af)\r
-  {\r
-    alignFrame = af;\r
-    database.addItem("-- Select Database --");\r
-    database.addItem("Uniprot");\r
-    database.addItem("EMBL");\r
-    database.addItem("EMBLCDS");\r
-    database.addItem("PDB");\r
-\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
-    }\r
-\r
-    frame = new JInternalFrame();\r
-    frame.setContentPane(this);\r
-    if(System.getProperty("os.name").startsWith("Mac"))\r
-      Desktop.addInternalFrame(frame, "Sequence Fetcher (WSDBfetch@EBI)", 400, 140);\r
-    else\r
-      Desktop.addInternalFrame(frame, "Sequence Fetcher (WSDBfetch@EBI)", 400, 125);\r
-  }\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    this.setLayout(gridBagLayout1);\r
-\r
-    database.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    database.setMinimumSize(new Dimension(160, 21));\r
-    database.setPreferredSize(new Dimension(160, 21));\r
-    jLabel1.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));\r
-    jLabel1.setText(\r
-        "Separate multiple accession ids with semi colon \";\"");\r
-    ok.setText("OK");\r
-    ok.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        ok_actionPerformed(e);\r
-      }\r
-    });\r
-    cancel.setText("Cancel");\r
-    cancel.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        cancel_actionPerformed(e);\r
-      }\r
-    });\r
-    textfield.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
-    textfield.addActionListener(new ActionListener()\r
-    {\r
-      public void actionPerformed(ActionEvent e)\r
-      {\r
-        ok_actionPerformed(e);\r
-      }\r
-    });\r
-    jPanel1.add(ok);\r
-    jPanel1.add(cancel);\r
-    this.add(jLabel1, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0\r
-                                             , GridBagConstraints.WEST,\r
-                                             GridBagConstraints.NONE,\r
-                                             new Insets(7, 4, 0, 6), 77, 6));\r
-    this.add(jPanel1, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0\r
-                                             , GridBagConstraints.WEST,\r
-                                             GridBagConstraints.BOTH,\r
-                                             new Insets(7, -2, 7, 12), 241, -2));\r
-    this.add(database, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0\r
-                                              , GridBagConstraints.WEST,\r
-                                              GridBagConstraints.NONE,\r
-                                              new Insets(0, 4, 0, 0), 1, 0));\r
-    this.add(textfield, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0\r
-                                               , GridBagConstraints.CENTER,\r
-                                               GridBagConstraints.HORIZONTAL,\r
-                                               new Insets(0, 0, 0, 6), 200, 1));\r
-  }\r
-\r
-  JComboBox database = new JComboBox();\r
-  JLabel jLabel1 = new JLabel();\r
-  JButton ok = new JButton();\r
-  JButton cancel = new JButton();\r
-  JPanel jPanel1 = new JPanel();\r
-  JTextField textfield = new JTextField();\r
-  GridBagLayout gridBagLayout1 = new GridBagLayout();\r
-  public void cancel_actionPerformed(ActionEvent e)\r
-  {\r
-    try\r
-    {\r
-      frame.setClosed(true);\r
-    }\r
-    catch (Exception ex)\r
-    {}\r
-  }\r
-\r
-  public void ok_actionPerformed(ActionEvent e)\r
-  {\r
-    frame.setTitle("Sequence Fetcher (WSDBfetch@EBI) - Fetching Sequence...");\r
-    database.setEnabled(false);\r
-    textfield.setEnabled(false);\r
-    ok.setEnabled(false);\r
-    cancel.setEnabled(false);\r
-\r
-    Thread worker = new Thread(this);\r
-    worker.start();\r
-  }\r
-\r
-  public void run()\r
-  {\r
-   result = new StringBuffer();\r
-    if (database.getSelectedItem().equals("Uniprot"))\r
-    {\r
-      getUniprotFile(textfield.getText());\r
-    }\r
-    else if (database.getSelectedItem().equals("EMBL")\r
-        || database.getSelectedItem().equals("EMBLCDS"))\r
-    {\r
-      EBIFetchClient dbFetch = new EBIFetchClient();\r
-      String[] reply = dbFetch.fetchData(\r
-          database.getSelectedItem().toString().toLowerCase(\r
-          ) + ":" + textfield.getText(),\r
-          "fasta", "raw");\r
-\r
-      for (int i = 0; i < reply.length; i++)\r
-        result.append(reply[i] + "\n");\r
-\r
-      parseResult(result.toString());\r
-    }\r
-    else if (database.getSelectedItem().equals("PDB"))\r
-    {\r
-      result = getPDBFile(textfield.getText().toUpperCase());\r
-      parseResult(result.toString());\r
-    }\r
-\r
-\r
-    if (result == null || result.length() == 0)\r
-      showErrorMessage("Error retrieving " + textfield.getText()\r
-                       + " from " + database.getSelectedItem());\r
-\r
-\r
-      database.setEnabled(true);\r
-      textfield.setEnabled(true);\r
-      ok.setEnabled(true);\r
-      cancel.setEnabled(true);\r
-      frame.setTitle("Sequence Fetcher (WSDBfetch@EBI)");\r
-  }\r
-\r
-  void getUniprotFile(String id)\r
-  {\r
-    EBIFetchClient ebi = new EBIFetchClient();\r
-    File file = ebi.fetchDataAsFile("uniprot:"+id,"xml", null);\r
-    SequenceFeatureFetcher sff = new SequenceFeatureFetcher();\r
-    Vector entries = sff.getUniprotEntries(file);\r
-\r
-    if(entries!=null)\r
-    {\r
-      //First, make the new sequences\r
-      Enumeration en = entries.elements();\r
-      while (en.hasMoreElements())\r
-      {\r
-        UniprotEntry entry = (UniprotEntry) en.nextElement();\r
-        StringBuffer name = new StringBuffer( ">Uniprot/Swiss-Prot" );\r
-        Enumeration en2 = entry.getAccession().elements();\r
-        while(en2.hasMoreElements())\r
-        {\r
-          name.append("|");\r
-          name.append(en2.nextElement());\r
-        }\r
-        en2 = entry.getName().elements();\r
-        while(en2.hasMoreElements())\r
-        {\r
-          name.append("|");\r
-          name.append(en2.nextElement());\r
-        }\r
-\r
-        if(entry.getProteinName()!=null)\r
-          name.append(" "+entry.getProteinName().elementAt(0));\r
-\r
-        result.append(name +"\n"+entry.getUniprotSequence().getContent());\r
-\r
-      }\r
-\r
-      //Then read in the features and apply them to the dataset\r
-      SequenceI [] sequence = parseResult(result.toString());\r
-      for(int i=0; i<entries.size(); i++)\r
-      {\r
-        UniprotEntry entry = (UniprotEntry) entries.elementAt(i);\r
-        Enumeration e = entry.getDbReference().elements();\r
-        Vector onlyPdbEntries = new Vector();\r
-        while (e.hasMoreElements())\r
-        {\r
-          PDBEntry pdb = (PDBEntry) e.nextElement();\r
-          if (!pdb.getType().equals("PDB"))\r
-            continue;\r
-\r
-          onlyPdbEntries.addElement(pdb);\r
-        }\r
-\r
-        sequence[i].getDatasetSequence().setPDBId(onlyPdbEntries);\r
-        sequence[i].getDatasetSequence().setSequenceFeatures(entry.getFeature());\r
-\r
-      }\r
-    }\r
-  }\r
-\r
-    StringBuffer getPDBFile(String id)\r
-    {\r
-      StringBuffer result = new StringBuffer();\r
-      String chain = null;\r
-      if (id.indexOf(":") > -1)\r
-      {\r
-        chain = id.substring(id.indexOf(":") + 1);\r
-        id = id.substring(0, id.indexOf(":"));\r
-      }\r
-\r
-      EBIFetchClient ebi = new EBIFetchClient();\r
-      String[] reply = ebi.fetchData("pdb:" + id, "pdb", "raw");\r
-      try\r
-      {\r
-        PDBfile pdbfile = new PDBfile(reply);\r
-        for (int i = 0; i < pdbfile.chains.size(); i++)\r
-        {\r
-          if (chain == null ||\r
-              ( (PDBChain) pdbfile.chains.elementAt(i)).id.\r
-              toUpperCase().equals(chain))\r
-            result.append("\n>PDB|" + id + "|" +\r
-                          ( (PDBChain) pdbfile.chains.elementAt(i)).sequence.\r
-                          getName() +\r
-                          "\n"\r
-                          +\r
-                          ( (PDBChain) pdbfile.chains.elementAt(i)).sequence.\r
-                          getSequence());\r
-        }\r
-      }\r
-      catch (Exception ex) // Problem parsing PDB file\r
-      {\r
-        showErrorMessage("Error retrieving " + textfield.getText() + " from " +\r
-            database.getSelectedItem());\r
-        return null;\r
-      }\r
-\r
-      return result;\r
-    }\r
-\r
-    SequenceI[] parseResult(String result)\r
-    {\r
-      String format = IdentifyFile.Identify(result, "Paste");\r
-      SequenceI[] sequences = null;\r
-\r
-      if (FormatAdapter.formats.contains(format))\r
-      {\r
-        sequences = new FormatAdapter().readFile(result.toString(), "Paste", format);\r
-        if (sequences != null && sequences.length>0)\r
-        {\r
-          if(alignFrame==null)\r
-          {\r
-            AlignFrame af = new AlignFrame(new Alignment(sequences));\r
-            af.currentFileFormat = format;\r
-            Desktop.addInternalFrame(af, "Retrieved from "+database.getSelectedItem(),\r
-                                     AlignFrame.NEW_WINDOW_WIDTH,\r
-                                     AlignFrame.NEW_WINDOW_HEIGHT);\r
-            af.statusBar.setText("Successfully pasted alignment file");\r
-            try\r
-            {\r
-              af.setMaximum(jalview.bin.Cache.getDefault("SHOW_FULLSCREEN", false));\r
-            }\r
-            catch (Exception ex)\r
-            {}\r
-          }\r
-          else\r
-          {\r
-            for (int i = 0; i < sequences.length; i++)\r
-            {\r
-              alignFrame.viewport.alignment.addSequence(sequences[i]);\r
-\r
-              ////////////////////////////\r
-              //Datset needs extension;\r
-              /////////////////////////////\r
-              Sequence ds = new Sequence(sequences[i].getName(),\r
-                                         AlignSeq.extractGaps("-. ",\r
-                  sequences[i].getSequence()),\r
-                                         sequences[i].getStart(),\r
-                                         sequences[i].getEnd());\r
-              sequences[i].setDatasetSequence(ds);\r
-              alignFrame.viewport.alignment.getDataset().addSequence(ds);\r
-            }\r
-            alignFrame.viewport.setEndSeq(alignFrame.viewport.alignment.\r
-                                          getHeight());\r
-            alignFrame.viewport.alignment.getWidth();\r
-            alignFrame.viewport.firePropertyChange("alignment", null,\r
-            alignFrame.viewport.getAlignment().getSequences());\r
-\r
-          }\r
-\r
-          if (database.getSelectedItem().equals("PDB"))\r
-          {\r
-            for (int i = 0; i < sequences.length; i++)\r
-            {\r
-              PDBEntry entry = new PDBEntry();\r
-              entry.setId(textfield.getText());\r
-              sequences[i].getDatasetSequence().addPDBId(entry);\r
-            }\r
-          }\r
-\r
-        }\r
-        else\r
-          showErrorMessage( "Error retrieving "+textfield.getText()\r
-                            +" from "+database.getSelectedItem());\r
-      }\r
-\r
-      return sequences;\r
-\r
-  }\r
-\r
-  void showErrorMessage(String error)\r
-  {\r
-    JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
-         error, "Error Retrieving Data", JOptionPane.WARNING_MESSAGE);\r
-  }\r
-}\r
-\r
-\r
-\r
-\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
+ * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
+ * 
+ * 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/>.
+ */
+package jalview.gui;
+
+import java.io.*;
+import java.util.*;
+
+import java.awt.*;
+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.seqfetcher.DbSourceProxy;
+
+import java.awt.Rectangle;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+
+public class SequenceFetcher extends JPanel implements Runnable
+{
+  // ASequenceFetcher sfetch;
+  JInternalFrame frame;
+
+  IProgressIndicator guiWindow;
+
+  AlignFrame alignFrame;
+
+  StringBuffer result;
+
+  final String noDbSelected = "-- Select Database --";
+
+  Hashtable sources = new Hashtable();
+
+  private static jalview.ws.SequenceFetcher sfetch = null;
+
+  private static String dasRegistry = null;
+
+  private static boolean _initingFetcher = false;
+
+  private static Thread initingThread = null;
+
+  /**
+   * Blocking method that initialises and returns the shared instance of the
+   * SequenceFetcher client
+   * 
+   * @param guiWindow
+   *          - where the initialisation delay message should be shown
+   * @return the singleton instance of the sequence fetcher client
+   */
+  public static jalview.ws.SequenceFetcher getSequenceFetcherSingleton(
+          final IProgressIndicator guiWindow)
+  {
+    if (_initingFetcher && initingThread != null && initingThread.isAlive())
+    {
+      if (guiWindow != null)
+      {
+        guiWindow.setProgressBar(
+                "Waiting for Sequence Database Fetchers to initialise",
+                Thread.currentThread().hashCode());
+      }
+      // initting happening on another thread - so wait around to see if it
+      // finishes.
+      while (_initingFetcher && initingThread != null
+              && initingThread.isAlive())
+      {
+        try
+        {
+          Thread.sleep(10);
+        } catch (Exception e)
+        {
+        }
+        ;
+      }
+      if (guiWindow != null)
+      {
+        guiWindow.setProgressBar(
+                "Waiting for Sequence Database Fetchers to initialise",
+                Thread.currentThread().hashCode());
+      }
+    }
+    if (sfetch == null
+            || dasRegistry != DasSourceBrowser.getDasRegistryURL())
+    {
+      _initingFetcher = true;
+      initingThread = Thread.currentThread();
+      /**
+       * give a visual indication that sequence fetcher construction is occuring
+       */
+      if (guiWindow != null)
+      {
+        guiWindow.setProgressBar("Initialising Sequence Database Fetchers",
+                Thread.currentThread().hashCode());
+      }
+      dasRegistry = DasSourceBrowser.getDasRegistryURL();
+      jalview.ws.SequenceFetcher sf = new jalview.ws.SequenceFetcher();
+      if (guiWindow != null)
+      {
+        guiWindow.setProgressBar("Initialising Sequence Database Fetchers",
+                Thread.currentThread().hashCode());
+      }
+      sfetch = sf;
+      _initingFetcher = false;
+      initingThread = null;
+    }
+    return sfetch;
+  }
+
+  public SequenceFetcher(IProgressIndicator guiIndic)
+  {
+    final IProgressIndicator guiWindow = guiIndic;
+    final SequenceFetcher us = this;
+    // launch initialiser thread
+    Thread sf = new Thread(new Runnable()
+    {
+
+      public void run()
+      {
+        if (getSequenceFetcherSingleton(guiWindow) != null)
+        {
+          us.initGui(guiWindow);
+        }
+        else
+        {
+          javax.swing.SwingUtilities.invokeLater(new Runnable()
+          {
+            public void run()
+            {
+              JOptionPane
+                      .showInternalMessageDialog(
+                              Desktop.desktop,
+                              "Could not create the sequence fetcher client. Check error logs for details.",
+                              "Couldn't create SequenceFetcher",
+                              JOptionPane.ERROR_MESSAGE);
+            }
+          });
+
+          // raise warning dialog
+        }
+      }
+    });
+    sf.start();
+  }
+
+  /**
+   * called by thread spawned by constructor
+   * 
+   * @param guiWindow
+   */
+  private void initGui(IProgressIndicator guiWindow)
+  {
+    this.guiWindow = guiWindow;
+    if (guiWindow instanceof AlignFrame)
+    {
+      alignFrame = (AlignFrame) guiWindow;
+    }
+
+    database.addItem(noDbSelected);
+    /*
+     * Dynamically generated database list will need a translation function from
+     * internal source to externally distinct names. UNIPROT and UP_NAME are
+     * identical DB sources, and should be collapsed.
+     */
+
+    String dbs[] = sfetch.getOrderedSupportedSources();
+    for (int i = 0; i < dbs.length; i++)
+    {
+      if (!sources.containsValue(dbs[i]))
+      {
+        String name = sfetch.getSourceProxy(dbs[i]).getDbName();
+        // duplicate source names are thrown away, here.
+        if (!sources.containsKey(name))
+        {
+          database.addItem(name);
+        }
+        // overwrite with latest version of the retriever for this source
+        sources.put(name, dbs[i]);
+      }
+    }
+    try
+    {
+      jbInit();
+    } catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+
+    frame = new JInternalFrame();
+    frame.setContentPane(this);
+    if (new jalview.util.Platform().isAMac())
+    {
+      Desktop.addInternalFrame(frame, getFrameTitle(), 400, 240);
+    }
+    else
+    {
+      Desktop.addInternalFrame(frame, getFrameTitle(), 400, 180);
+    }
+  }
+
+  private String getFrameTitle()
+  {
+    return ((alignFrame == null) ? "New " : "Additional ")
+            + "Sequence Fetcher";
+  }
+
+  private void jbInit() throws Exception
+  {
+    this.setLayout(borderLayout2);
+
+    database.setFont(JvSwingUtils.getLabelFont());
+    dbeg.setFont(new java.awt.Font("Verdana", Font.BOLD, 11));
+    jLabel1.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
+    jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
+    jLabel1.setText("Separate multiple accession ids with semi colon \";\"");
+
+    replacePunctuation.setHorizontalAlignment(SwingConstants.CENTER);
+    replacePunctuation
+            .setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
+    replacePunctuation.setText("Replace commas with semi-colons");
+    ok.setText("OK");
+    ok.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        ok_actionPerformed();
+      }
+    });
+    clear.setText("Clear");
+    clear.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        clear_actionPerformed();
+      }
+    });
+
+    example.setText("Example");
+    example.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        example_actionPerformed();
+      }
+    });
+    close.setText("Close");
+    close.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        close_actionPerformed(e);
+      }
+    });
+    textArea.setFont(JvSwingUtils.getLabelFont());
+    textArea.setLineWrap(true);
+    textArea.addKeyListener(new KeyAdapter()
+    {
+      public void keyPressed(KeyEvent e)
+      {
+        if (e.getKeyCode() == KeyEvent.VK_ENTER)
+          ok_actionPerformed();
+      }
+    });
+    jPanel3.setLayout(borderLayout1);
+    borderLayout1.setVgap(5);
+    jPanel1.add(ok);
+    jPanel1.add(example);
+    jPanel1.add(clear);
+    jPanel1.add(close);
+    jPanel3.add(jPanel2, java.awt.BorderLayout.CENTER);
+    jPanel2.setLayout(borderLayout3);
+
+    database.addActionListener(new ActionListener()
+    {
+
+      public void actionPerformed(ActionEvent e)
+      {
+        DbSourceProxy db = null;
+        try
+        {
+          db = sfetch.getSourceProxy((String) sources.get(database
+                  .getSelectedItem()));
+          String eq = db.getTestQuery();
+          dbeg.setText("Example query: " + eq);
+          replacePunctuation.setEnabled(!(eq != null && eq.indexOf(",") > -1));
+        } catch (Exception ex)
+        {
+          dbeg.setText("");
+          replacePunctuation.setEnabled(true);
+        }
+        jPanel2.repaint();
+      }
+    });
+    dbeg.setText("");
+    jPanel2.add(database, java.awt.BorderLayout.NORTH);
+    jPanel2.add(dbeg, java.awt.BorderLayout.CENTER);
+    JPanel jPanel2a = new JPanel(new BorderLayout());
+    jPanel2a.add(jLabel1, java.awt.BorderLayout.NORTH);
+    jPanel2a.add(replacePunctuation, java.awt.BorderLayout.SOUTH);
+    jPanel2.add(jPanel2a, java.awt.BorderLayout.SOUTH);
+    // jPanel2.setPreferredSize(new Dimension())
+    jPanel3.add(jScrollPane1, java.awt.BorderLayout.CENTER);
+    this.add(jPanel1, java.awt.BorderLayout.SOUTH);
+    this.add(jPanel3, java.awt.BorderLayout.CENTER);
+    this.add(jPanel2, java.awt.BorderLayout.NORTH);
+    jScrollPane1.getViewport().add(textArea);
+
+  }
+
+  protected void example_actionPerformed()
+  {
+    DbSourceProxy db = null;
+    try
+    {
+      db = sfetch.getSourceProxy((String) sources.get(database
+              .getSelectedItem()));
+      textArea.setText(db.getTestQuery());
+    } catch (Exception ex)
+    {
+    }
+    jPanel3.repaint();
+  }
+
+  protected void clear_actionPerformed()
+  {
+    textArea.setText("");
+    jPanel3.repaint();
+  }
+
+  JLabel dbeg = new JLabel();
+
+  JComboBox database = new JComboBox();
+
+  JLabel jLabel1 = new JLabel();
+
+  JCheckBox replacePunctuation = new JCheckBox();
+
+  JButton ok = new JButton();
+
+  JButton clear = new JButton();
+
+  JButton example = new JButton();
+
+  JButton close = new JButton();
+
+  JPanel jPanel1 = new JPanel();
+
+  JTextArea textArea = new JTextArea();
+
+  JScrollPane jScrollPane1 = new JScrollPane();
+
+  JPanel jPanel2 = new JPanel();
+
+  JPanel jPanel3 = new JPanel();
+
+  JPanel jPanel4 = new JPanel();
+
+  BorderLayout borderLayout1 = new BorderLayout();
+
+  BorderLayout borderLayout2 = new BorderLayout();
+
+  BorderLayout borderLayout3 = new BorderLayout();
+
+  public void close_actionPerformed(ActionEvent e)
+  {
+    try
+    {
+      frame.setClosed(true);
+    } catch (Exception ex)
+    {
+    }
+  }
+
+  public void ok_actionPerformed()
+  {
+    database.setEnabled(false);
+    textArea.setEnabled(false);
+    ok.setEnabled(false);
+    close.setEnabled(false);
+
+    Thread worker = new Thread(this);
+    worker.start();
+  }
+
+  private void resetDialog()
+  {
+    database.setEnabled(true);
+    textArea.setEnabled(true);
+    ok.setEnabled(true);
+    close.setEnabled(true);
+  }
+
+  public void run()
+  {
+    String error = "";
+    if (database.getSelectedItem().equals(noDbSelected))
+    {
+      error += "Please select the source database\n";
+    }
+    // TODO: make this transformation more configurable
+    com.stevesoft.pat.Regex empty;
+    if (replacePunctuation.isEnabled() && replacePunctuation.isSelected())
+    {
+      empty = new com.stevesoft.pat.Regex(
+      // replace commas and spaces with a semicolon
+              "(\\s|[,; ])+", ";");
+    }
+    else
+    {
+      // just turn spaces and semicolons into single semicolons
+      empty = new com.stevesoft.pat.Regex("(\\s|[; ])+", ";");
+    }
+    textArea.setText(empty.replaceAll(textArea.getText()));
+    // see if there's anthing to search with
+    if (!new com.stevesoft.pat.Regex("[A-Za-z0-9_.]").search(textArea
+            .getText()))
+    {
+      error += "Please enter a (semi-colon separated list of) database id(s)";
+    }
+    if (error.length() > 0)
+    {
+      showErrorMessage(error);
+      resetDialog();
+      return;
+    }
+    ArrayList<String> aresultq=new ArrayList<String>();
+    ArrayList<AlignmentI> aresult = new ArrayList<AlignmentI>();
+    Object source = database.getSelectedItem();
+    Enumeration en = new StringTokenizer(textArea.getText(), ";");
+    boolean isAliSource=false;
+    try
+    {
+      guiWindow.setProgressBar(
+              "Fetching Sequences from " + database.getSelectedItem(),
+              Thread.currentThread().hashCode());
+      DbSourceProxy proxy = sfetch.getSourceProxy((String) sources
+              .get(source));
+      isAliSource = proxy.isA(DBRefSource.ALIGNMENTDB);
+      if (proxy.getAccessionSeparator() == null)
+      {
+        while (en.hasMoreElements())
+        {
+          String item = (String) en.nextElement();
+          try
+          {
+            if (aresult != null)
+            {
+              try
+              {
+                // give the server a chance to breathe
+                Thread.sleep(5);
+              } catch (Exception e)
+              {
+                //
+              }
+
+            }
+
+            AlignmentI indres = null;
+            try
+            {
+              indres = proxy.getSequenceRecords(item);
+            } catch (OutOfMemoryError oome)
+            {
+              new OOMWarning("fetching " + item + " from "
+                      + database.getSelectedItem(), oome, this);
+            }
+            if (indres != null)
+            {
+              aresultq.add(item);
+              aresult.add(indres);
+            }
+          } catch (Exception e)
+          {
+            jalview.bin.Cache.log.info("Error retrieving " + item
+                    + " from " + source, e);
+          }
+        }
+      }
+      else
+      {
+        StringBuffer multiacc = new StringBuffer();
+        while (en.hasMoreElements())
+        {
+          multiacc.append(en.nextElement());
+          if (en.hasMoreElements())
+          {
+            multiacc.append(proxy.getAccessionSeparator());
+          }
+        }
+        try
+        {
+          aresultq.add(multiacc.toString());
+          aresult.add(proxy.getSequenceRecords(multiacc.toString()));
+        } catch (OutOfMemoryError oome)
+        {
+          new OOMWarning("fetching " + multiacc + " from "
+                  + database.getSelectedItem(), oome, this);
+        }
+
+      }
+
+    } catch (Exception e)
+    {
+      showErrorMessage("Error retrieving " + textArea.getText() + " from "
+              + database.getSelectedItem());
+      // error +="Couldn't retrieve sequences from "+database.getSelectedItem();
+      System.err.println("Retrieval failed for source ='"
+              + database.getSelectedItem() + "' and query\n'"
+              + textArea.getText() + "'\n");
+      e.printStackTrace();
+    } catch (OutOfMemoryError e)
+    {
+      // resets dialog box - so we don't use OOMwarning here.
+      showErrorMessage("Out of Memory when retrieving "
+              + textArea.getText()
+              + " from "
+              + database.getSelectedItem()
+              + "\nPlease see the Jalview FAQ for instructions for increasing the memory available to Jalview.\n");
+      e.printStackTrace();
+    } catch (Error e)
+    {
+      showErrorMessage("Serious Error retrieving " + textArea.getText()
+              + " from " + database.getSelectedItem());
+      e.printStackTrace();
+    }
+    if (aresult != null && aresult.size()>0)
+    {
+      AlignmentI ar=null;
+      if (isAliSource) {
+        // new window for each result
+        while (aresult.size()>0)
+        {
+          parseResult(aresult.remove(0), aresultq.remove(0)+" "+getDefaultRetrievalTitle(), null);
+        }
+      } else {
+        // concatenate all results in one window
+        while (aresult.size()>0)
+        {
+          if (ar==null) { ar = aresult.remove(0);}
+          else { ar.append(aresult.remove(0)); };
+        }
+        parseResult(ar, null, null);
+      } 
+    }
+    // only remove visual delay after we finished parsing.
+    guiWindow.setProgressBar(null, Thread.currentThread().hashCode());
+    resetDialog();
+  }
+
+  /*
+   * result = new StringBuffer(); if
+   * (database.getSelectedItem().equals("Uniprot")) {
+   * getUniprotFile(textArea.getText()); } else if
+   * (database.getSelectedItem().equals("EMBL") ||
+   * database.getSelectedItem().equals("EMBLCDS")) { String DBRefSource =
+   * database.getSelectedItem().equals("EMBLCDS") ?
+   * jalview.datamodel.DBRefSource.EMBLCDS : jalview.datamodel.DBRefSource.EMBL;
+   * 
+   * StringTokenizer st = new StringTokenizer(textArea.getText(), ";");
+   * SequenceI[] seqs = null; while(st.hasMoreTokens()) { EBIFetchClient dbFetch
+   * = new EBIFetchClient(); String qry =
+   * database.getSelectedItem().toString().toLowerCase( ) + ":" +
+   * st.nextToken(); File reply = dbFetch.fetchDataAsFile( qry, "emblxml",null);
+   * 
+   * jalview.datamodel.xdb.embl.EmblFile efile=null; if (reply != null &&
+   * reply.exists()) { efile =
+   * jalview.datamodel.xdb.embl.EmblFile.getEmblFile(reply); } if (efile!=null)
+   * { for (Iterator i=efile.getEntries().iterator(); i.hasNext(); ) { EmblEntry
+   * entry = (EmblEntry) i.next(); SequenceI[] seqparts =
+   * entry.getSequences(false,true, DBRefSource); if (seqparts!=null) {
+   * SequenceI[] newseqs = null; int si=0; if (seqs==null) { newseqs = new
+   * SequenceI[seqparts.length]; } else { newseqs = new
+   * SequenceI[seqs.length+seqparts.length];
+   * 
+   * for (;si<seqs.length; si++) { newseqs[si] = seqs[si]; seqs[si] = null; } }
+   * for (int j=0;j<seqparts.length; si++, j++) { newseqs[si] =
+   * seqparts[j].deriveSequence(); // place DBReferences on dataset and refer }
+   * seqs=newseqs; } } } else { result.append("# no response for "+qry); } } if
+   * (seqs!=null && seqs.length>0) { if (parseResult(new Alignment(seqs), null,
+   * null)!=null) { result.append("# Successfully parsed the
+   * "+database.getSelectedItem()+" Queries into an Alignment"); } } } else if
+   * (database.getSelectedItem().equals("PDB")) { StringTokenizer qset = new
+   * StringTokenizer(textArea.getText(), ";"); String query; SequenceI[] seqs =
+   * null; while (qset.hasMoreTokens() && ((query = qset.nextToken())!=null)) {
+   * SequenceI[] seqparts = getPDBFile(query.toUpperCase()); if (seqparts !=
+   * null) { if (seqs == null) { seqs = seqparts; } else { SequenceI[] newseqs =
+   * new SequenceI[seqs.length+seqparts.length]; int i=0; for (; i <
+   * seqs.length; i++) { newseqs[i] = seqs[i]; seqs[i] = null; } for (int
+   * j=0;j<seqparts.length; i++, j++) { newseqs[i] = seqparts[j]; }
+   * seqs=newseqs; } result.append("# Success for "+query.toUpperCase()+"\n"); }
+   * } if (seqs != null && seqs.length > 0) { if (parseResult(new
+   * Alignment(seqs), null, null)!=null) { result.append( "# Successfully parsed
+   * the PDB File Queries into an
+   * Alignment"); } } } else if( database.getSelectedItem().equals("PFAM")) {
+   * try { result.append(new FastaFile(
+   * "http://www.sanger.ac.uk/cgi-bin/Pfam/getalignment.pl?format=fal&acc=" +
+   * textArea.getText().toUpperCase(), "URL").print() );
+   * 
+   * if(result.length()>0) { parseResult( result.toString(),
+   * textArea.getText().toUpperCase() ); } } catch (java.io.IOException ex) {
+   * result = null; } }
+   * 
+   * if (result == null || result.length() == 0) { showErrorMessage("Error
+   * retrieving " + textArea.getText() + " from " + database.getSelectedItem());
+   * }
+   * 
+   * resetDialog(); return; }
+   * 
+   * void getUniprotFile(String id) { EBIFetchClient ebi = new EBIFetchClient();
+   * File file = ebi.fetchDataAsFile("uniprot:" + id, "xml", null);
+   * 
+   * DBRefFetcher dbref = new DBRefFetcher(); Vector entries =
+   * dbref.getUniprotEntries(file);
+   * 
+   * if (entries != null) { //First, make the new sequences Enumeration en =
+   * entries.elements(); while (en.hasMoreElements()) { UniprotEntry entry =
+   * (UniprotEntry) en.nextElement();
+   * 
+   * StringBuffer name = new StringBuffer(">UniProt/Swiss-Prot"); Enumeration
+   * en2 = entry.getAccession().elements(); while (en2.hasMoreElements()) {
+   * name.append("|"); name.append(en2.nextElement()); } en2 =
+   * entry.getName().elements(); while (en2.hasMoreElements()) {
+   * name.append("|"); name.append(en2.nextElement()); }
+   * 
+   * if (entry.getProtein() != null) { name.append(" " +
+   * entry.getProtein().getName().elementAt(0)); }
+   * 
+   * result.append(name + "\n" + entry.getUniprotSequence().getContent() +
+   * "\n"); }
+   * 
+   * //Then read in the features and apply them to the dataset Alignment al =
+   * parseResult(result.toString(), null); for (int i = 0; i < entries.size();
+   * i++) { UniprotEntry entry = (UniprotEntry) entries.elementAt(i);
+   * Enumeration e = entry.getDbReference().elements(); Vector onlyPdbEntries =
+   * new Vector(); while (e.hasMoreElements()) { PDBEntry pdb = (PDBEntry)
+   * e.nextElement(); if (!pdb.getType().equals("PDB")) { continue; }
+   * 
+   * onlyPdbEntries.addElement(pdb); }
+   * 
+   * Enumeration en2 = entry.getAccession().elements(); while
+   * (en2.hasMoreElements()) {
+   * al.getSequenceAt(i).getDatasetSequence().addDBRef(new DBRefEntry(
+   * DBRefSource.UNIPROT, "0", en2.nextElement().toString())); }
+   * 
+   * 
+   * 
+   * 
+   * al.getSequenceAt(i).getDatasetSequence().setPDBId(onlyPdbEntries); if
+   * (entry.getFeature() != null) { e = entry.getFeature().elements(); while
+   * (e.hasMoreElements()) { SequenceFeature sf = (SequenceFeature)
+   * e.nextElement(); sf.setFeatureGroup("Uniprot");
+   * al.getSequenceAt(i).getDatasetSequence().addSequenceFeature( sf ); } } } }
+   * }
+   * 
+   * SequenceI[] getPDBFile(String id) { Vector result = new Vector(); String
+   * chain = null; if (id.indexOf(":") > -1) { chain =
+   * id.substring(id.indexOf(":") + 1); id = id.substring(0, id.indexOf(":")); }
+   * 
+   * EBIFetchClient ebi = new EBIFetchClient(); String file =
+   * ebi.fetchDataAsFile("pdb:" + id, "pdb", "raw"). getAbsolutePath(); if (file
+   * == null) { return null; } try { PDBfile pdbfile = new PDBfile(file,
+   * jalview.io.AppletFormatAdapter.FILE); for (int i = 0; i <
+   * pdbfile.chains.size(); i++) { if (chain == null || ( (PDBChain)
+   * pdbfile.chains.elementAt(i)).id. toUpperCase().equals(chain)) { PDBChain
+   * pdbchain = (PDBChain) pdbfile.chains.elementAt(i); // Get the Chain's
+   * Sequence - who's dataset includes any special features added from the PDB
+   * file SequenceI sq = pdbchain.sequence; // Specially formatted name for the
+   * PDB chain sequences retrieved from the PDB
+   * sq.setName("PDB|"+id+"|"+sq.getName()); // Might need to add more metadata
+   * to the PDBEntry object // like below /* PDBEntry entry = new PDBEntry(); //
+   * Construct the PDBEntry entry.setId(id); if (entry.getProperty() == null)
+   * entry.setProperty(new Hashtable()); entry.getProperty().put("chains",
+   * pdbchain.id + "=" + sq.getStart() + "-" + sq.getEnd());
+   * sq.getDatasetSequence().addPDBId(entry); // Add PDB DB Refs // We make a
+   * DBRefEtntry because we have obtained the PDB file from a verifiable source
+   * // JBPNote - PDB DBRefEntry should also carry the chain and mapping
+   * information DBRefEntry dbentry = new
+   * DBRefEntry(jalview.datamodel.DBRefSource.PDB, "0", id + pdbchain.id);
+   * sq.addDBRef(dbentry); // and add seuqence to the retrieved set
+   * result.addElement(sq.deriveSequence()); } }
+   * 
+   * if (result.size() < 1) { throw new Exception("WsDBFetch for PDB id resulted
+   * in zero result size"); } } catch (Exception ex) // Problem parsing PDB file
+   * { jalview.bin.Cache.log.warn("Exception when retrieving " +
+   * textArea.getText() + " from " + database.getSelectedItem(), ex); return
+   * null; }
+   * 
+   * 
+   * SequenceI[] results = new SequenceI[result.size()]; for (int i = 0, j =
+   * result.size(); i < j; i++) { results[i] = (SequenceI) result.elementAt(i);
+   * result.setElementAt(null,i); } return results; }
+   */
+  AlignmentI parseResult(String result, String title)
+  {
+    String format = new IdentifyFile().Identify(result, "Paste");
+    Alignment sequences = null;
+    if (FormatAdapter.isValidFormat(format))
+    {
+      sequences = null;
+      try
+      {
+        sequences = new FormatAdapter().readFile(result.toString(),
+                "Paste", format);
+      } catch (Exception ex)
+      {
+      }
+
+      if (sequences != null)
+      {
+        return parseResult(sequences, title, format);
+      }
+    }
+    else
+    {
+      showErrorMessage("Error retrieving " + textArea.getText() + " from "
+              + database.getSelectedItem());
+    }
+
+    return null;
+  }
+
+  /**
+   * 
+   * @return a standard title for any results retrieved using the currently selected source and settings
+   */
+  public String getDefaultRetrievalTitle() {
+    return "Retrieved from " + database.getSelectedItem();
+  }
+  AlignmentI parseResult(AlignmentI al, String title,
+          String currentFileFormat)
+  {
+
+    if (al != null && al.getHeight() > 0)
+    {
+      if (alignFrame == null)
+      {
+        AlignFrame af = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
+                AlignFrame.DEFAULT_HEIGHT);
+        if (currentFileFormat != null)
+        {
+          af.currentFileFormat = currentFileFormat; // WHAT IS THE DEFAULT
+          // FORMAT FOR
+          // NON-FormatAdapter Sourced
+          // Alignments?
+        }
+
+        if (title == null)
+        {
+          title = getDefaultRetrievalTitle();
+        }
+        SequenceFeature[] sfs = null;
+        for (Enumeration sq = al.getSequences().elements(); sq
+                .hasMoreElements();)
+        {
+          if ((sfs = ((SequenceI) sq.nextElement()).getDatasetSequence()
+                  .getSequenceFeatures()) != null)
+          {
+            if (sfs.length > 0)
+            {
+              af.setShowSeqFeatures(true);
+              break;
+            }
+          }
+
+        }
+        Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH,
+                AlignFrame.DEFAULT_HEIGHT);
+
+        af.statusBar.setText("Successfully pasted alignment file");
+
+        try
+        {
+          af.setMaximum(jalview.bin.Cache.getDefault("SHOW_FULLSCREEN",
+                  false));
+        } catch (Exception ex)
+        {
+        }
+      }
+      else
+      {
+        for (int i = 0; i < al.getHeight(); i++)
+        {
+          alignFrame.viewport.alignment.addSequence(al.getSequenceAt(i)); // this
+          // also
+          // creates
+          // dataset
+          // sequence
+          // entries
+        }
+        alignFrame.viewport.setEndSeq(alignFrame.viewport.alignment
+                .getHeight());
+        alignFrame.viewport.alignment.getWidth();
+        alignFrame.viewport.firePropertyChange("alignment", null,
+                alignFrame.viewport.getAlignment().getSequences());
+      }
+    }
+    return al;
+  }
+
+  void showErrorMessage(final String error)
+  {
+    resetDialog();
+    javax.swing.SwingUtilities.invokeLater(new Runnable()
+    {
+      public void run()
+      {
+        JOptionPane.showInternalMessageDialog(Desktop.desktop, error,
+                "Error Retrieving Data", JOptionPane.WARNING_MESSAGE);
+      }
+    });
+  }
+}