JAL-3181 refactor: extracted buildLinkMenu() for testability feature/JAL-3181linkOrdering
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 4 Jan 2019 10:32:21 +0000 (10:32 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 4 Jan 2019 10:32:21 +0000 (10:32 +0000)
src/jalview/gui/PopupMenu.java
test/jalview/gui/PopupMenuTest.java

index 473ac3a..4e02d21 100644 (file)
@@ -75,10 +75,8 @@ import javax.swing.JMenuItem;
 import javax.swing.JPopupMenu;
 
 /**
- * DOCUMENT ME!
- * 
- * @author $author$
- * @version $Revision: 1.118 $
+ * The popup menu that is displayed on right-click on a sequence id, or in the
+ * sequence alignment.
  */
 public class PopupMenu extends JPopupMenu implements ColourChangeListener
 {
@@ -173,6 +171,187 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
   JMenuItem hideInsertions = new JMenuItem();
 
   /**
+   * Constructs a menu with sub-menu items for any hyperlinks for the sequence
+   * and/or features provided. Hyperlinks may include a lookup by sequence id,
+   * or database cross-references, depending on which links are enabled in user
+   * preferences.
+   * 
+   * @param seq
+   * @param features
+   * @return
+   */
+  static JMenu buildLinkMenu(final SequenceI seq,
+          List<SequenceFeature> features)
+  {
+    JMenu linkMenu = new JMenu(MessageManager.getString("action.link"));
+
+    List<String> nlinks = null;
+    if (seq != null)
+    {
+      nlinks = Preferences.sequenceUrlLinks.getLinksForMenu();
+      UrlLink.sort(nlinks);
+    }
+    else
+    {
+      nlinks = new ArrayList<>();
+    }
+
+    if (features != null)
+    {
+      for (SequenceFeature sf : features)
+      {
+        if (sf.links != null)
+        {
+          for (String link : sf.links)
+          {
+            nlinks.add(link);
+          }
+        }
+      }
+    }
+
+    /*
+     * instantiate the hyperlinklink templates from sequence data;
+     * note the order of the templates is preserved in the map
+     */
+    Map<String, List<String>> linkset = new LinkedHashMap<>();
+    for (String link : nlinks)
+    {
+      UrlLink urlLink = null;
+      try
+      {
+        urlLink = new UrlLink(link);
+      } catch (Exception foo)
+      {
+        Cache.log.error("Exception for URLLink '" + link + "'", foo);
+        continue;
+      }
+
+      if (!urlLink.isValid())
+      {
+        Cache.log.error(urlLink.getInvalidMessage());
+        continue;
+      }
+
+      urlLink.createLinksFromSeq(seq, linkset);
+    }
+
+    /*
+     * construct menu items for the hyperlinks (still preserving
+     * the order of the sorted templates)
+     */
+    addUrlLinks(linkMenu, linkset.values());
+
+    return linkMenu;
+  }
+
+  /**
+   * A helper method that builds menu items from the given links, with action
+   * handlers to open the link URL, and adds them to the linkMenu. Each provided
+   * link should be a list whose second item is the menu text, and whose fourth
+   * item is the URL to open when the menu item is selected.
+   * 
+   * @param linkMenu
+   * @param linkset
+   */
+  static private void addUrlLinks(JMenu linkMenu,
+          Collection<List<String>> linkset)
+  {
+    for (List<String> linkstrset : linkset)
+    {
+      final String url = linkstrset.get(3);
+      JMenuItem item = new JMenuItem(linkstrset.get(1));
+      item.setToolTipText(MessageManager
+              .formatMessage("label.open_url_param", new Object[]
+              { url }));
+      item.addActionListener(new ActionListener()
+      {
+        @Override
+        public void actionPerformed(ActionEvent e)
+        {
+          new Thread(new Runnable()
+          {
+            @Override
+            public void run()
+            {
+              showLink(url);
+            }
+          }).start();
+        }
+      });
+      linkMenu.add(item);
+    }
+  }
+
+  /**
+   * Opens the provided url in the default web browser, or shows an error
+   * message if this fails
+   * 
+   * @param url
+   */
+  static void showLink(String url)
+  {
+    try
+    {
+      jalview.util.BrowserLauncher.openURL(url);
+    } catch (Exception ex)
+    {
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+              MessageManager.getString("label.web_browser_not_found_unix"),
+              MessageManager.getString("label.web_browser_not_found"),
+              JvOptionPane.WARNING_MESSAGE);
+
+      ex.printStackTrace();
+    }
+  }
+
+  /**
+   * add a late bound groupURL item to the given linkMenu
+   * 
+   * @param linkMenu
+   * @param label
+   *          - menu label string
+   * @param urlgenerator
+   *          GroupURLLink used to generate URL
+   * @param urlstub
+   *          Object array returned from the makeUrlStubs function.
+   */
+  static void addshowLink(JMenu linkMenu, String label,
+          final GroupUrlLink urlgenerator, final Object[] urlstub)
+  {
+    JMenuItem item = new JMenuItem(label);
+    item.setToolTipText(MessageManager
+            .formatMessage("label.open_url_seqs_param", new Object[]
+            { urlgenerator.getUrl_prefix(),
+                urlgenerator.getNumberInvolved(urlstub) }));
+    // TODO: put in info about what is being sent.
+    item.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        new Thread(new Runnable()
+        {
+
+          @Override
+          public void run()
+          {
+            try
+            {
+              showLink(urlgenerator.constructFrom(urlstub));
+            } catch (UrlStringTooLongException e2)
+            {
+            }
+          }
+
+        }).start();
+      }
+    });
+
+    linkMenu.add(item);
+  }
+
+  /**
    * Creates a new PopupMenu object.
    * 
    * @param ap
@@ -605,64 +784,14 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
    * When seq is not null, these are links for the sequence id, which may be to
    * external web sites for the sequence accession, and/or links embedded in
    * non-positional features. When seq is null, only links embedded in the
-   * provided features are added.
+   * provided features are added. If no links are found, the menu is not added.
    * 
    * @param seq
    * @param features
    */
   void addLinks(final SequenceI seq, List<SequenceFeature> features)
   {
-    JMenu linkMenu = new JMenu(MessageManager.getString("action.link"));
-
-    List<String> nlinks = null;
-    if (seq != null)
-    {
-      nlinks = Preferences.sequenceUrlLinks.getLinksForMenu();
-      UrlLink.sort(nlinks);
-    }
-    else
-    {
-      nlinks = new ArrayList<>();
-    }
-
-    if (features != null)
-    {
-      for (SequenceFeature sf : features)
-      {
-        if (sf.links != null)
-        {
-          for (String link : sf.links)
-          {
-            nlinks.add(link);
-          }
-        }
-      }
-    }
-
-    Map<String, List<String>> linkset = new LinkedHashMap<>();
-
-    for (String link : nlinks)
-    {
-      UrlLink urlLink = null;
-      try
-      {
-        urlLink = new UrlLink(link);
-      } catch (Exception foo)
-      {
-        Cache.log.error("Exception for URLLink '" + link + "'", foo);
-        continue;
-      }
-
-      if (!urlLink.isValid())
-      {
-        Cache.log.error(urlLink.getInvalidMessage());
-        continue;
-      }
-
-      urlLink.createLinksFromSeq(seq, linkset);
-    }
-
-    addshowLinks(linkMenu, linkset.values());
+    JMenu linkMenu = buildLinkMenu(seq, features);
 
     // only add link menu if it has entries
     if (linkMenu.getItemCount() > 0)
@@ -955,98 +1084,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
     }
   }
 
-  private void addshowLinks(JMenu linkMenu,
-          Collection<List<String>> linkset)
-  {
-    for (List<String> linkstrset : linkset)
-    {
-      // split linkstr into label and url
-      addshowLink(linkMenu, linkstrset.get(1), linkstrset.get(3));
-    }
-  }
-
-  /**
-   * add a show URL menu item to the given linkMenu
-   * 
-   * @param linkMenu
-   * @param label
-   *          - menu label string
-   * @param url
-   *          - url to open
-   */
-  private void addshowLink(JMenu linkMenu, String label, final String url)
-  {
-    JMenuItem item = new JMenuItem(label);
-    item.setToolTipText(MessageManager.formatMessage("label.open_url_param",
-            new Object[]
-            { url }));
-    item.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        new Thread(new Runnable()
-        {
-
-          @Override
-          public void run()
-          {
-            showLink(url);
-          }
-
-        }).start();
-      }
-    });
-
-    linkMenu.add(item);
-  }
-
-  /**
-   * add a late bound groupURL item to the given linkMenu
-   * 
-   * @param linkMenu
-   * @param label
-   *          - menu label string
-   * @param urlgenerator
-   *          GroupURLLink used to generate URL
-   * @param urlstub
-   *          Object array returned from the makeUrlStubs function.
-   */
-  private void addshowLink(JMenu linkMenu, String label,
-          final GroupUrlLink urlgenerator, final Object[] urlstub)
-  {
-    JMenuItem item = new JMenuItem(label);
-    item.setToolTipText(MessageManager
-            .formatMessage("label.open_url_seqs_param", new Object[]
-            { urlgenerator.getUrl_prefix(),
-                urlgenerator.getNumberInvolved(urlstub) }));
-    // TODO: put in info about what is being sent.
-    item.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        new Thread(new Runnable()
-        {
-
-          @Override
-          public void run()
-          {
-            try
-            {
-              showLink(urlgenerator.constructFrom(urlstub));
-            } catch (UrlStringTooLongException e2)
-            {
-            }
-          }
-
-        }).start();
-      }
-    });
-
-    linkMenu.add(item);
-  }
-
   /**
    * DOCUMENT ME!
    * 
@@ -1916,22 +1953,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
     refresh();
   }
 
-  public void showLink(String url)
-  {
-    try
-    {
-      jalview.util.BrowserLauncher.openURL(url);
-    } catch (Exception ex)
-    {
-      JvOptionPane.showInternalMessageDialog(Desktop.desktop,
-              MessageManager.getString("label.web_browser_not_found_unix"),
-              MessageManager.getString("label.web_browser_not_found"),
-              JvOptionPane.WARNING_MESSAGE);
-
-      ex.printStackTrace();
-    }
-  }
-
   void hideSequences(boolean representGroup)
   {
     ap.av.hideSequences(sequence, representGroup);
index e04be68..df30935 100644 (file)
@@ -492,7 +492,7 @@ public class PopupMenuTest
    * Test for adding sequence id, dbref and feature links
    */
   @Test(groups = { "Functional" })
-  public void testConstructor_links()
+  public void testBuildLinkMenu()
   {
     List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
     final SequenceI seq0 = seqs.get(0);
@@ -509,11 +509,9 @@ public class PopupMenuTest
     seq1.addDBRef(new DBRefEntry("GENE3D", "1", "3.10.20.30"));
     
     /*
-     * check the Popup Menu for the first sequence
+     * check the Link Menu for the first sequence
      */
-    testee = new PopupMenu(parentPanel, seq0, noFeatures);
-    Component[] seqItems = testee.sequenceMenu.getMenuComponents();
-    JMenu linkMenu = (JMenu) seqItems[6];
+    JMenu linkMenu = PopupMenu.buildLinkMenu(seq0, noFeatures);
     assertEquals(linkText, linkMenu.getText());
     Component[] linkItems = linkMenu.getMenuComponents();
     
@@ -532,12 +530,10 @@ public class PopupMenuTest
     assertEquals("UNIPROT|P83527", ((JMenuItem) linkItems[4]).getText());
 
     /*
-     * check the Popup Menu for second sequence
+     * check the Link Menu for the second sequence
      * note dbref GENE3D is matched to link Gene3D, the latter is displayed
      */
-    testee = new PopupMenu(parentPanel, seq1, noFeatures);
-    seqItems = testee.sequenceMenu.getMenuComponents();
-    linkMenu = (JMenu) seqItems[6];
+    linkMenu = PopupMenu.buildLinkMenu(seq1, noFeatures);
     assertEquals(linkText, linkMenu.getText());
     linkItems = linkMenu.getMenuComponents();
     assertEquals(3, linkItems.length);
@@ -556,9 +552,7 @@ public class PopupMenuTest
             unmatched, "");
     Preferences.sequenceUrlLinks = factory.createUrlProvider();
 
-    testee = new PopupMenu(parentPanel, seq1, noFeatures);
-    seqItems = testee.sequenceMenu.getMenuComponents();
-    linkMenu = (JMenu) seqItems[6];
+    linkMenu = PopupMenu.buildLinkMenu(seq1, noFeatures);
     assertEquals(linkText, linkMenu.getText());
     linkItems = linkMenu.getMenuComponents();
     assertEquals(1, linkItems.length);