X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Futil%2FUrlLink.java;h=0141a6ac2b35eae4446a973982cca6fd25f17625;hb=dc5a5883cfe90255079e41538e56bc433bd1e4a5;hp=34070dda34b758e4c2fc58afd0f7245f41d8202d;hpb=e63a4d52c27252dfb83efeeee1bda6c89b6dddec;p=jalview.git diff --git a/src/jalview/util/UrlLink.java b/src/jalview/util/UrlLink.java index 34070dd..0141a6a 100644 --- a/src/jalview/util/UrlLink.java +++ b/src/jalview/util/UrlLink.java @@ -29,21 +29,61 @@ import jalview.datamodel.DBRefEntry; import jalview.datamodel.SequenceI; import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Vector; +/** + * A helper class to parse URL Link strings taken from applet parameters or + * jalview properties file using the com.stevesoft.pat.Regex implementation. + * Jalview 2.4 extension allows regular expressions to be used to parse ID + * strings and replace the result in the URL. Regex's operate on the whole ID + * string given to the matchURL method, if no regex is supplied, then only text + * following the first pipe symbol will be substituted. Usage documentation + * todo. + */ public class UrlLink { + private static final String SEQUENCEID_PLACEHOLDER = DELIM + SEQUENCE_ID + + DELIM; + + private static final String ACCESSION_PLACEHOLDER = DELIM + DB_ACCESSION + + DELIM; + /** - * helper class to parse URL Link strings taken from applet parameters or - * jalview properties file using the com.stevesoft.pat.Regex implementation. - * Jalview 2.4 extension allows regular expressions to be used to parse ID - * strings and replace the result in the URL. Regex's operate on the whole ID - * string given to the matchURL method, if no regex is supplied, then only - * text following the first pipe symbol will be substituted. Usage - * documentation todo. + * A comparator that puts SEQUENCE_ID template links before DB_ACCESSION + * links, and otherwise orders by link name + url (not case sensitive). It + * expects to compare strings formatted as "Name|URLTemplate" where the + * template may include $SEQUENCE_ID$ or $DB_ACCESSION$ or neither. */ + public static final Comparator LINK_COMPARATOR = new Comparator() + { + @Override + public int compare(String link1, String link2) + { + if (link1 == null || link2 == null) + { + return 0; // for failsafe only + } + if (link1.contains(SEQUENCEID_PLACEHOLDER) + && link2.contains(ACCESSION_PLACEHOLDER)) + { + return -1; + } + if (link2.contains(SEQUENCEID_PLACEHOLDER) + && link1.contains(ACCESSION_PLACEHOLDER)) + { + return 1; + } + return String.CASE_INSENSITIVE_ORDER.compare(link1, link2); + } + }; + + private static final String EQUALS = "="; + + private static final String SPACE = " "; private String urlSuffix; @@ -53,6 +93,8 @@ public class UrlLink private String label; + private String dbname; + private String regexReplace; private boolean dynamic = false; @@ -78,23 +120,38 @@ public class UrlLink dynamic = true; usesDBaccession = true; - sep = parseTargetAndLabel(sep, psqid, link); + sep = parseLabel(sep, psqid, link); - parseUrl(link, DB_ACCESSION, psqid, sep); + int endOfRegex = parseUrl(link, DB_ACCESSION, psqid, sep); + parseTarget(link, sep, endOfRegex); } else if (nsqid > -1) { dynamic = true; - sep = parseTargetAndLabel(sep, nsqid, link); + sep = parseLabel(sep, nsqid, link); + + int endOfRegex = parseUrl(link, SEQUENCE_ID, nsqid, sep); - parseUrl(link, SEQUENCE_ID, nsqid, sep); + parseTarget(link, sep, endOfRegex); } else { - target = link.substring(0, sep); - sep = link.lastIndexOf(SEP); - label = link.substring(0, sep); - urlPrefix = link.substring(sep + 1).trim(); + label = link.substring(0, sep).trim(); + + // if there's a third element in the url link string + // it is the target name, otherwise target=label + int lastsep = link.lastIndexOf(SEP); + if (lastsep != sep) + { + urlPrefix = link.substring(sep + 1, lastsep).trim(); + target = link.substring(lastsep + 1).trim(); + } + else + { + urlPrefix = link.substring(sep + 1).trim(); + target = label; + } + regexReplace = null; // implies we trim any prefix if necessary // urlSuffix = null; } @@ -104,9 +161,24 @@ public class UrlLink } /** + * Alternative constructor for separate name, link and description + * + * @param name + * The string used to match the link to a DB reference id + * @param url + * The url to link to + * @param desc + * The description of the associated target DB + */ + public UrlLink(String name, String url, String desc) + { + this(name + SEP + url + SEP + desc); + } + + /** * @return the url_suffix */ - public String getUrl_suffix() + public String getUrlSuffix() { return urlSuffix; } @@ -114,7 +186,7 @@ public class UrlLink /** * @return the url_prefix */ - public String getUrl_prefix() + public String getUrlPrefix() { return urlPrefix; } @@ -140,8 +212,12 @@ public class UrlLink String var = (usesDBaccession ? DB_ACCESSION : SEQUENCE_ID); return urlPrefix - + (dynamic ? (DELIM + var + ((regexReplace != null) ? "=" - + regexReplace + "=" + DELIM : DELIM)) : "") + + (dynamic + ? (DELIM + var + + ((regexReplace != null) + ? EQUALS + regexReplace + EQUALS + DELIM + : DELIM)) + : "") + ((urlSuffix == null) ? "" : urlSuffix); } @@ -201,6 +277,16 @@ public class UrlLink } /** + * Set the target + * + * @param desc + */ + public void setTarget(String desc) + { + target = desc; + } + + /** * return one or more URL strings by applying regex to the given idstring * * @param idstring @@ -216,8 +302,8 @@ public class UrlLink { if (regexReplace != null) { - com.stevesoft.pat.Regex rg = com.stevesoft.pat.Regex.perlCode("/" - + regexReplace + "/"); + com.stevesoft.pat.Regex rg = com.stevesoft.pat.Regex + .perlCode("/" + regexReplace + "/"); if (rg.search(idstring)) { int ns = rg.numSubs(); @@ -241,7 +327,7 @@ public class UrlLink + rg.stringMatched(s) + "'"); } // try to collate subgroup matches - Vector subs = new Vector(); + Vector subs = new Vector<>(); // have to loop through submatches, collating them at top level // match int s = 0; // 1; @@ -275,8 +361,8 @@ public class UrlLink if (rg.matchedFrom(s) > -1) { subs.addElement(rg.stringMatched(s)); - subs.addElement(urlPrefix + rg.stringMatched(s) - + urlSuffix); + subs.addElement( + urlPrefix + rg.stringMatched(s) + urlSuffix); } s++; } @@ -285,7 +371,7 @@ public class UrlLink String[] res = new String[subs.size()]; for (int r = 0, rs = subs.size(); r < rs; r++) { - res[r] = (String) subs.elementAt(r); + res[r] = subs.elementAt(r); } subs.removeAllElements(); return res; @@ -318,6 +404,15 @@ public class UrlLink } /** + * @return delimited string containing label, url and target + */ + public String toStringWithTarget() + { + return label + SEP + getUrlWithToken() + SEP + target; + } + + /** + * Parse the label from the link string * * @param firstSep * Location of first occurrence of separator in link string @@ -327,7 +422,7 @@ public class UrlLink * Link string containing database name and url * @return Position of last separator symbol prior to any regex symbols */ - protected int parseTargetAndLabel(int firstSep, int psqid, String link) + protected int parseLabel(int firstSep, int psqid, String link) { int p = firstSep; int sep = firstSep; @@ -339,21 +434,44 @@ public class UrlLink // Assuming that the URL itself does not contain any SEP symbols // sep now contains last pipe symbol position prior to any regex symbols label = link.substring(0, sep); - if (label.indexOf(SEP) > -1) - { - // SEP terminated database name / www target at start of Label - target = label.substring(0, label.indexOf(SEP)); - } - else if (label.indexOf(" ") > 2) + + return sep; + } + + /** + * Parse the target from the link string + * + * @param link + * Link string containing database name and url + * @param sep + * Location of first separator symbol + * @param endOfRegex + * Location of end of any regular expression in link string + */ + protected void parseTarget(String link, int sep, int endOfRegex) + { + int lastsep = link.lastIndexOf(SEP); + + if ((lastsep != sep) && (lastsep > endOfRegex)) { - // space separated Label - matches database name - target = label.substring(0, label.indexOf(" ")); + // final element in link string is the target + target = link.substring(lastsep + 1).trim(); } else { target = label; } - return sep; + + if (target.indexOf(SEP) > -1) + { + // SEP terminated database name / www target at start of Label + target = target.substring(0, target.indexOf(SEP)); + } + else if (target.indexOf(SPACE) > 2) + { + // space separated label - first word matches database name + target = target.substring(0, target.indexOf(SPACE)); + } } /** @@ -367,8 +485,9 @@ public class UrlLink * Position of id or name in link string * @param sep * Position of separator in link string + * @return Location of end of any regex in link string */ - protected void parseUrl(String link, String varName, int sqidPos, int sep) + protected int parseUrl(String link, String varName, int sqidPos, int sep) { urlPrefix = link.substring(sep + 1, sqidPos).trim(); @@ -391,8 +510,8 @@ public class UrlLink regexReplace = link.substring(sqidPos + startLength, p); try { - com.stevesoft.pat.Regex rg = com.stevesoft.pat.Regex.perlCode("/" - + regexReplace + "/"); + com.stevesoft.pat.Regex rg = com.stevesoft.pat.Regex + .perlCode("/" + regexReplace + "/"); if (rg == null) { invalidMessage = "Invalid Regular Expression : '" + regexReplace @@ -411,7 +530,14 @@ public class UrlLink // verify format is really correct. if (link.indexOf(DELIM + varName + DELIM) == sqidPos) { - urlSuffix = link.substring(sqidPos + startLength - 1); + int lastsep = link.lastIndexOf(SEP); + if (lastsep < sqidPos + startLength - 1) + { + // the last SEP character was before the regex, ignore + lastsep = link.length(); + } + urlSuffix = link.substring(sqidPos + startLength - 1, lastsep) + .trim(); regexReplace = null; } else @@ -420,6 +546,8 @@ public class UrlLink + link; } } + + return p; } /** @@ -453,11 +581,11 @@ public class UrlLink */ protected void createStaticLink(Map> linkset) { - if (!linkset.containsKey(label + SEP + getUrl_prefix())) + if (!linkset.containsKey(label + SEP + getUrlPrefix())) { // Add a non-dynamic link - linkset.put(label + SEP + getUrl_prefix(), - Arrays.asList(target, label, null, getUrl_prefix())); + linkset.put(label + SEP + getUrlPrefix(), + Arrays.asList(target, label, null, getUrlPrefix())); } } @@ -484,16 +612,17 @@ public class UrlLink if (usesDBAccession()) // link is ID { // collect matching db-refs - DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(), - new String[] { target }); + List dbr = DBRefUtils.selectRefs(seq.getDBRefs(), + new String[] + { target }); // if there are any dbrefs which match up with the link if (dbr != null) { - for (int r = 0; r < dbr.length; r++) + for (int r = 0, nd = dbr.size(); r < nd; r++) { // create Bare ID link for this URL - createBareURLLink(dbr[r].getAccessionId(), true, linkset); + createBareURLLink(dbr.get(r).getAccessionId(), true, linkset); } } } @@ -540,81 +669,19 @@ public class UrlLink } } - private static void testUrls(UrlLink ul, String idstring, String[] urls) - { - - if (urls == null) - { - System.out.println("Created NO urls."); - } - else - { - System.out.println("Created " + (urls.length / 2) + " Urls."); - for (int uls = 0; uls < urls.length; uls += 2) - { - System.out.println("URL Replacement text : " + urls[uls] - + " : URL : " + urls[uls + 1]); - } - } - } - - public static void main(String argv[]) + /** + * Sorts links (formatted as LinkName|LinkPattern) suitable for display in a + * menu + *
    + *
  • SEQUENCE_ID links precede DB_ACCESSION links (i.e. canonical lookup + * before cross-references)
  • + *
  • otherwise by Link name (case insensitive)
  • + *
+ * + * @param nlinks + */ + public static void sort(List nlinks) { - String[] links = new String[] { - /* - * "AlinkT|Target|http://foo.foo.soo/", - * "myUrl1|http://$SEQUENCE_ID=/[0-9]+/=$.someserver.org/foo", - * "myUrl2|http://$SEQUENCE_ID=/(([0-9]+).+([A-Za-z]+))/=$.someserver.org/foo" - * , - * "myUrl3|http://$SEQUENCE_ID=/([0-9]+).+([A-Za-z]+)/=$.someserver.org/foo" - * , "myUrl4|target|http://$SEQUENCE_ID$.someserver.org/foo|too", - * "PF1|http://us.expasy.org/cgi-bin/niceprot.pl?$SEQUENCE_ID=/(?:PFAM:)?(.+)/=$" - * , - * "PF2|http://us.expasy.org/cgi-bin/niceprot.pl?$SEQUENCE_ID=/(PFAM:)?(.+)/=$" - * , - * "PF3|http://us.expasy.org/cgi-bin/niceprot.pl?$SEQUENCE_ID=/PFAM:(.+)/=$" - * , "NOTFER|http://notfer.org/$SEQUENCE_ID=/(?