From d3cabbfdd38d554bb8a8b17d3e2c4b113c102545 Mon Sep 17 00:00:00 2001 From: kiramt Date: Tue, 15 Nov 2016 14:20:12 +0000 Subject: [PATCH 1/1] JAL-2316 Refactoring of functionality to provide urls to gui --- resources/lang/Messages.properties | 2 + resources/lang/Messages_es.properties | 4 +- src/jalview/appletgui/IdPanel.java | 126 ++++++++---------- src/jalview/gui/Desktop.java | 8 +- src/jalview/gui/IdPanel.java | 53 +------- src/jalview/gui/Preferences.java | 133 ++++++++---------- src/jalview/util/CustomUrlProvider.java | 185 ++++++++++++++++++++------ src/jalview/util/IdentifiersUrlProvider.java | 39 +++--- src/jalview/util/UrlConstants.java | 8 +- src/jalview/util/UrlLink.java | 7 +- src/jalview/util/UrlProvider.java | 159 ++++++++++++++-------- src/jalview/util/UrlProviderI.java | 63 ++++++--- src/jalview/util/UrlProviderImpl.java | 94 +++++++++++++ 13 files changed, 541 insertions(+), 340 deletions(-) create mode 100644 src/jalview/util/UrlProviderImpl.java diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 49a0456..7582568 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -1272,3 +1272,5 @@ label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ is no longer used for DB access label.SEQUENCE_ID_for_DB_ACCESSION1 = Please review your URL links in the 'Connections' tab of the Preferences window: label.SEQUENCE_ID_for_DB_ACCESSION2 = URL links using '$SEQUENCE_ID$' for DB accessions now use '$DB_ACCESSION$'. label.do_not_display_again = Do not display this message again +exception.url_cannot_have_miriam_id = {0} is a MIRIAM id and cannot be used as a custom url name +exception.url_cannot_have_duplicate_id = {0} cannot be used as a label for more than one link \ No newline at end of file diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index 96c8ef2..f3d782c 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -1272,4 +1272,6 @@ label.operation_failed = Operaci label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ no se utiliza más para accesiones DB label.SEQUENCE_ID_for_DB_ACCESSION1 = Por favor, revise sus URLs en la pestaña 'Conexiones' de la ventana de Preferencias: label.SEQUENCE_ID_for_DB_ACCESSION2 = URL enlaza usando '$SEQUENCE_ID$' para accesiones DB ahora usar '$DB_ACCESSION$'. -label.do_not_display_again = No mostrar este mensaje de nuevo \ No newline at end of file +label.do_not_display_again = No mostrar este mensaje de nuevo +exception.url_cannot_have_miriam_id = {0} is a MIRIAM id and cannot be used as a custom url name +exception.url_cannot_have_duplicate_id = {0} cannot be used as a label for more than one link \ No newline at end of file diff --git a/src/jalview/appletgui/IdPanel.java b/src/jalview/appletgui/IdPanel.java index 182f20e..f8ea522 100755 --- a/src/jalview/appletgui/IdPanel.java +++ b/src/jalview/appletgui/IdPanel.java @@ -20,14 +20,12 @@ */ package jalview.appletgui; -import static jalview.util.UrlConstants.EMBLEBI_STRING; -import static jalview.util.UrlConstants.SRS_STRING; - import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; -import jalview.util.UrlLink; +import jalview.util.UrlProvider; +import jalview.util.UrlProviderI; import jalview.viewmodel.AlignmentViewport; import java.awt.BorderLayout; @@ -36,6 +34,7 @@ import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; +import java.util.HashMap; import java.util.List; import java.util.Vector; @@ -55,7 +54,7 @@ public class IdPanel extends Panel implements MouseListener, boolean mouseDragging = false; - java.util.Vector links = new java.util.Vector(); + UrlProviderI urlProvider = null; public IdPanel(AlignViewport av, AlignmentPanel parent) { @@ -69,6 +68,9 @@ public class IdPanel extends Panel implements MouseListener, String label, url; // TODO: add in group link parameter + + // make a list of label,url pairs + HashMap urlList = new HashMap(); if (av.applet != null) { for (int i = 1; i < 10; i++) @@ -76,26 +78,16 @@ public class IdPanel extends Panel implements MouseListener, label = av.applet.getParameter("linkLabel_" + i); url = av.applet.getParameter("linkURL_" + i); - if (label != null && url != null) - { - links.addElement(label + "|" + url); - } - + urlList.put(label, url); } - } - { - // upgrade old SRS link - int srsPos = links.indexOf(SRS_STRING); - if (srsPos > -1) + + if (!urlList.isEmpty()) { - links.setElementAt(EMBLEBI_STRING, srsPos); + // set default as first entry in list + String defaultUrl = av.applet.getParameter("linkLabel_1"); + urlProvider = new UrlProvider(defaultUrl, urlList); } } - if (links.size() < 1) - { - links = new java.util.Vector(); - links.addElement(EMBLEBI_STRING); - } } Tooltip tooltip; @@ -225,54 +217,55 @@ public class IdPanel extends Panel implements MouseListener, return; } String id = sq.getName(); + String url = urlProvider.getDefaultUrl(id); + String target = urlProvider.getDefaultTarget(id); - String target = null; - String url = null; - int i = 0; - while (url == null && i < links.size()) - { - // DEFAULT LINK IS FIRST IN THE LINK LIST - // BUT IF ITS A REGEX AND DOES NOT MATCH THE NEXT ONE WILL BE TRIED - url = links.elementAt(i++).toString(); - jalview.util.UrlLink urlLink = null; - try - { - urlLink = new UrlLink(url); - target = urlLink.getTarget(); - } catch (Exception foo) - { - System.err.println("Exception for URLLink '" + url + "'"); - foo.printStackTrace(); - url = null; - continue; - } + /* String target = null; + String url = null; + int i = 0; + while (url == null && i < links.size()) + { + // DEFAULT LINK IS FIRST IN THE LINK LIST + // BUT IF ITS A REGEX AND DOES NOT MATCH THE NEXT ONE WILL BE TRIED + url = links.elementAt(i++).toString(); + jalview.util.UrlLink urlLink = null; + try + { + urlLink = new UrlLink(url); + target = urlLink.getTarget(); + } catch (Exception foo) + { + System.err.println("Exception for URLLink '" + url + "'"); + foo.printStackTrace(); + url = null; + continue; + } - if (urlLink.usesDBAccession()) - { - // this URL requires an accession id, not the name of a sequence - url = null; - continue; - } + if (urlLink.usesDBAccession()) + { + // this URL requires an accession id, not the name of a sequence + url = null; + continue; + } - if (!urlLink.isValid()) - { - System.err.println(urlLink.getInvalidMessage()); - url = null; - continue; - } + if (!urlLink.isValid()) + { + System.err.println(urlLink.getInvalidMessage()); + url = null; + continue; + } - String urls[] = urlLink.makeUrls(id, true); - if (urls == null || urls[0] == null || urls[0].length() < 1) - { - url = null; - continue; - } - // just take first URL made from regex - url = urls[1]; - } + String urls[] = urlLink.makeUrls(id, true); + if (urls == null || urls[0] == null || urls[0].length() < 1) + { + url = null; + continue; + } + // just take first URL made from regex + url = urls[1]; + }*/ try { - alignPanel.alignFrame.showURL(url, target); } catch (Exception ex) { @@ -331,11 +324,8 @@ public class IdPanel extends Panel implements MouseListener, // build a new links menu based on the current links + any non-positional // features - Vector nlinks = new Vector(); - for (int l = 0, lSize = links.size(); l < lSize; l++) - { - nlinks.addElement(links.elementAt(l)); - } + Vector nlinks = urlProvider.getLinksForDisplay(); + SequenceFeature sf[] = sq == null ? null : sq.getSequenceFeatures(); for (int sl = 0; sf != null && sl < sf.length; sl++) { diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 28606f1..63f797d 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -20,7 +20,6 @@ */ package jalview.gui; -import static jalview.util.UrlConstants.EMBLEBI_STRING; import static jalview.util.UrlConstants.SEQUENCE_ID; import jalview.api.AlignViewportI; @@ -38,6 +37,7 @@ import jalview.structure.StructureSelectionManager; import jalview.util.ImageMaker; import jalview.util.MessageManager; import jalview.util.Platform; +import jalview.util.UrlProviderI; import jalview.viewmodel.AlignmentViewport; import jalview.ws.params.ParamManager; @@ -2277,7 +2277,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements { // check what the actual links are - if it's just the default don't // bother with the warning - Vector links = Preferences.sequenceURLLinks; + Vector links = Preferences.sequenceUrlLinks + .getLinksForDisplay(); // only need to check links if there is one with a // SEQUENCE_ID which is not the default EMBL_EBI link @@ -2287,7 +2288,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements while (li.hasNext()) { String link = li.next(); - if (link.contains(SEQUENCE_ID) && !link.equals(EMBLEBI_STRING)) + if (link.contains(SEQUENCE_ID) + && !link.equals(UrlProviderI.DEFAULT_STRING)) { check = true; int barPos = link.indexOf("|"); diff --git a/src/jalview/gui/IdPanel.java b/src/jalview/gui/IdPanel.java index e321a74..7170d04 100755 --- a/src/jalview/gui/IdPanel.java +++ b/src/jalview/gui/IdPanel.java @@ -27,7 +27,6 @@ import jalview.datamodel.SequenceI; import jalview.io.SequenceAnnotationReport; import jalview.util.MessageManager; import jalview.util.Platform; -import jalview.util.UrlLink; import jalview.viewmodel.AlignmentViewport; import java.awt.BorderLayout; @@ -199,56 +198,10 @@ public class IdPanel extends JPanel implements MouseListener, return; } - Vector links = Preferences.sequenceURLLinks; - if (links == null || links.size() < 1) - { - return; - } - int seq = alignPanel.getSeqPanel().findSeq(e); - String url = null; - int i = 0; String id = av.getAlignment().getSequenceAt(seq).getName(); - while (url == null && i < links.size()) - { - // DEFAULT LINK IS FIRST IN THE LINK LIST - // BUT IF ITS A REGEX AND DOES NOT MATCH THE NEXT ONE WILL BE TRIED - url = links.elementAt(i++).toString(); - jalview.util.UrlLink urlLink = null; - try - { - urlLink = new UrlLink(url); - } catch (Exception foo) - { - jalview.bin.Cache.log.error("Exception for URLLink '" + url + "'", - foo); - url = null; - continue; - } + String url = Preferences.sequenceUrlLinks.getDefaultUrl(id); - if (urlLink.usesDBAccession()) - { - // this URL requires an accession id, not the name of a sequence - url = null; - continue; - } - - if (!urlLink.isValid()) - { - jalview.bin.Cache.log.error(urlLink.getInvalidMessage()); - url = null; - continue; - } - - String urls[] = urlLink.makeUrls(id, true); - if (urls == null || urls[0] == null || urls[0].length() < 4) - { - url = null; - continue; - } - // just take first URL made from regex - url = urls[1]; - } try { jalview.util.BrowserLauncher.openURL(url); @@ -375,7 +328,9 @@ public class IdPanel extends JPanel implements MouseListener, Sequence sq = (Sequence) av.getAlignment().getSequenceAt(seq2); // build a new links menu based on the current links + any non-positional // features - Vector nlinks = new Vector(Preferences.sequenceURLLinks); + Vector nlinks = Preferences.sequenceUrlLinks + .getLinksForDisplay(); // new + // Vector(Preferences.sequenceURLLinks); SequenceFeature sfs[] = sq == null ? null : sq.getSequenceFeatures(); if (sfs != null) { diff --git a/src/jalview/gui/Preferences.java b/src/jalview/gui/Preferences.java index 718e14f..69dc9fe 100755 --- a/src/jalview/gui/Preferences.java +++ b/src/jalview/gui/Preferences.java @@ -20,8 +20,6 @@ */ package jalview.gui; -import static jalview.util.UrlConstants.EMBLEBI_STRING; - import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.bin.Cache; import jalview.gui.Help.HelpId; @@ -100,7 +98,6 @@ public class Preferences extends GPreferences * Holds name and link separated with | character. Sequence ID must be * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$ */ - // public static Vector sequenceURLLinks; public static UrlProviderI sequenceUrlLinks; /** @@ -114,43 +111,10 @@ public class Preferences extends GPreferences public static List groupURLLinks; static { - String string = Cache.getDefault("SEQUENCE_LINKS", EMBLEBI_STRING); - sequenceUrlLinks = new UrlProvider(EMBLEBI_STRING.split("\\|")[0], - string); // TODO sort out the default string - // sequenceURLLinks = new Vector(); + String string = Cache.getDefault("SEQUENCE_LINKS", + UrlProviderI.DEFAULT_STRING); + sequenceUrlLinks = new UrlProvider(UrlProviderI.DEFAULT_LABEL, string); - /* try - { - StringTokenizer st = new StringTokenizer(string, "|"); - while (st.hasMoreElements()) - { - String name = st.nextToken(); - String url = st.nextToken(); - // check for '|' within a regex - int rxstart = url.indexOf("$" + DB_ACCESSION + "$"); - if (rxstart == -1) - { - rxstart = url.indexOf("$" + SEQUENCE_ID + "$"); - } - while (rxstart == -1 && url.indexOf("/=$") == -1) - { - url = url + "|" + st.nextToken(); - } - sequenceURLLinks.addElement(name + "|" + url); - } - } catch (Exception ex) - { - System.out.println(ex + "\nError parsing sequence links"); - } - { - // upgrade old SRS link - int srsPos = sequenceURLLinks.indexOf(SRS_STRING); - if (srsPos > -1) - { - sequenceURLLinks.setElementAt(EMBLEBI_STRING, srsPos); - } - } - */ /** * TODO: reformulate groupURL encoding so two or more can be stored in the * .properties file as '|' separated strings @@ -346,14 +310,8 @@ public class Preferences extends GPreferences */ nameLinks = new Vector(); urlLinks = new Vector(); - sequenceUrlLinks.getLinksForDisplay(nameLinks, urlLinks); - /* for (HashMap.Entry entry: sequenceUrlLinks.getUrlLinks()) - { - String link = sequenceURLLinks.elementAt(i).toString(); - nameLinks.addElement(link.substring(0, link.indexOf("|"))); - urlLinks.addElement(link.substring(link.indexOf("|") + 1)); - } - */ + + resetStoredLinks(); updateLinkData(); useProxy.setSelected(Cache.getDefault("USE_PROXY", false)); @@ -550,6 +508,7 @@ public class Preferences extends GPreferences jalview.util.BrowserLauncher.resetBrowser(); + // save user-defined and selected links String links = sequenceUrlLinks.writeUrlsAsString(); if (links.isEmpty()) { @@ -561,28 +520,6 @@ public class Preferences extends GPreferences links.toString()); } - /* if (nameLinks.size() > 0) - { - StringBuffer links = new StringBuffer(); - sequenceURLLinks = new Vector(); - for (int i = 0; i < nameLinks.size(); i++) - { - sequenceURLLinks.addElement(nameLinks.elementAt(i) + "|" - + urlLinks.elementAt(i)); - links.append(sequenceURLLinks.elementAt(i).toString()); - links.append("|"); - } - // remove last "|" - links.setLength(links.length() - 1); - Cache.applicationProperties.setProperty("SEQUENCE_LINKS", - links.toString()); - } - else - { - Cache.applicationProperties.remove("SEQUENCE_LINKS"); - sequenceURLLinks.clear(); - }*/ - Cache.applicationProperties.setProperty("USE_PROXY", Boolean.toString(useProxy.isSelected())); @@ -775,8 +712,14 @@ public class Preferences extends GPreferences { nameLinks.addElement(link.getName()); urlLinks.addElement(link.getURL()); - updateLinkData(); - valid = true; + if (updateLinkData()) + { + valid = true; + } + else + { + break; + } } } else @@ -816,8 +759,14 @@ public class Preferences extends GPreferences { nameLinks.setElementAt(link.getName(), index); urlLinks.setElementAt(link.getURL(), index); - updateLinkData(); - valid = true; + if (updateLinkData()) + { + valid = true; + } + else + { + break; + } } } @@ -845,10 +794,42 @@ public class Preferences extends GPreferences updateLinkData(); } - void updateLinkData() + private boolean updateLinkData() + { + try + { + sequenceUrlLinks.setUrlLinks(nameLinks, urlLinks); + linkNameList.setListData(nameLinks); + linkURLList.setListData(urlLinks); + } catch (IllegalArgumentException e) + { + + // put back the old links + resetStoredLinks(); + + linkNameList.setListData(nameLinks); + linkURLList.setListData(urlLinks); + + JOptionPane.showInternalMessageDialog(Desktop.desktop, + e.getMessage(), MessageManager.getString("label.link_name"), + JOptionPane.WARNING_MESSAGE); + + return false; + } + return true; + } + + private void resetStoredLinks() { - linkNameList.setListData(nameLinks); - linkURLList.setListData(urlLinks); + Vector nlinks = sequenceUrlLinks.getLinksForDisplay(); + + nameLinks.clear(); + urlLinks.clear(); + for (String entry : nlinks) + { + nameLinks.addElement(entry.split("\\|")[0]); + urlLinks.addElement(entry.split("\\|")[1]); + } } @Override diff --git a/src/jalview/util/CustomUrlProvider.java b/src/jalview/util/CustomUrlProvider.java index f679e36..e6f19fb 100644 --- a/src/jalview/util/CustomUrlProvider.java +++ b/src/jalview/util/CustomUrlProvider.java @@ -22,9 +22,12 @@ package jalview.util; import static jalview.util.UrlConstants.DB_ACCESSION; -import static jalview.util.UrlConstants.EMBLEBI_STRING; +import static jalview.util.UrlConstants.DELIM; +//import static jalview.util.UrlConstants.EMBLEBI_LABEL; +//import static jalview.util.UrlConstants.EMBLEBI_STRING; +import static jalview.util.UrlConstants.SEP; import static jalview.util.UrlConstants.SEQUENCE_ID; -import static jalview.util.UrlConstants.SRS_STRING; +//import static jalview.util.UrlConstants.SRS_LABEL; import java.util.HashMap; import java.util.Iterator; @@ -40,81 +43,118 @@ import java.util.Vector; * @author $author$ * @version $Revision$ */ -public class CustomUrlProvider implements UrlProviderI +public class CustomUrlProvider extends UrlProviderImpl { + // minimum length of substitution in url link string + private static final int MIN_SUBST_LENGTH = 4; + + // Default sequence URL link label for SRS + private static final String SRS_LABEL = "SRS"; + + // map of string ids to urlLinks private HashMap urls; + /** + * Construct UrlProvider for custom (user-entered) URLs + * + * @param cachedUrlList + * list of URLs in form stored in Cache. i.e. SEP delimited string + */ public CustomUrlProvider(String cachedUrlList) { try { - StringTokenizer st = new StringTokenizer(cachedUrlList, "|"); + urls = new HashMap(); + + // cachedUrlList is in form