JAL-1905 parse url including & correctly
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 24 Sep 2015 15:25:24 +0000 (16:25 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 24 Sep 2015 15:25:24 +0000 (16:25 +0100)
src/jalview/util/ParseHtmlBodyAndLinks.java
test/jalview/util/ParseHtmlBodyAndLinksTest.java [new file with mode: 0644]

index 5263454..f1b83b8 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.util;
 
 import java.util.ArrayList;
+import java.util.List;
 import java.util.StringTokenizer;
 import java.util.regex.Pattern;
 
@@ -52,9 +53,9 @@ public class ParseHtmlBodyAndLinks
     return htmlContent;
   }
 
-  ArrayList<String> links = new ArrayList<String>();
+  List<String> links = new ArrayList<String>();
 
-  StringBuffer sb = new StringBuffer();
+  String content;
 
   /**
    * result of parsing description - with or without HTML tags
@@ -64,7 +65,7 @@ public class ParseHtmlBodyAndLinks
   public String getContent()
   {
 
-    return sb.toString();
+    return content;
   }
 
   /**
@@ -72,12 +73,19 @@ public class ParseHtmlBodyAndLinks
    * 
    * @return
    */
-  public ArrayList<String> getLinks()
+  public List<String> getLinks()
   {
     return links;
   }
 
   /**
+   * Parses the given html and
+   * <ul>
+   * <li>extracts any 'href' links to a list of "displayName|url" strings,
+   * retrievable by #getLinks</li>
+   * <li>extracts the remaining text (with %LINK% placeholders replacing hrefs),
+   * retrievable by #getContent</li>
+   * </ul>
    * 
    * @param description
    *          - html or text content to be parsed
@@ -89,6 +97,7 @@ public class ParseHtmlBodyAndLinks
   public ParseHtmlBodyAndLinks(String description, boolean removeHTML,
           String newline)
   {
+    StringBuilder sb = new StringBuilder(description.length());
     if (description == null || description.length() == 0)
     {
       htmlContent = false;
@@ -105,7 +114,7 @@ public class ParseHtmlBodyAndLinks
     String tag = null;
     while (st.hasMoreElements())
     {
-      token = st.nextToken("&>");
+      token = st.nextToken(">");
       if (token.equalsIgnoreCase("html") || token.startsWith("/"))
       {
         continue;
@@ -135,18 +144,6 @@ public class ParseHtmlBodyAndLinks
       {
         sb.append(newline);
       }
-      else if (token.startsWith("lt;"))
-      {
-        sb.append("<" + token.substring(3));
-      }
-      else if (token.startsWith("gt;"))
-      {
-        sb.append(">" + token.substring(3));
-      }
-      else if (token.startsWith("amp;"))
-      {
-        sb.append("&" + token.substring(4));
-      }
       else
       {
         sb.append(token);
@@ -156,11 +153,18 @@ public class ParseHtmlBodyAndLinks
     {
       // instead of parsing the html into plaintext
       // clean the description ready for embedding in html
-      sb = new StringBuffer(LEFT_ANGLE_BRACKET_PATTERN.matcher(description)
-              .replaceAll("&lt;"));
-
+      sb = new StringBuilder(LEFT_ANGLE_BRACKET_PATTERN
+              .matcher(description).replaceAll("&lt;"));
     }
+    content = translateEntities(sb.toString());
+  }
 
+  private String translateEntities(String s)
+  {
+    s = s.replaceAll("&amp;", "&");
+    s = s.replaceAll("&lt;", "<");
+    s = s.replaceAll("&gt;", ">");
+    return s;
   }
 
   /**
@@ -171,7 +175,7 @@ public class ParseHtmlBodyAndLinks
    */
   public String getNonHtmlContent()
   {
-    return isHtmlContent() ? sb.toString() : orig;
+    return isHtmlContent() ? content : orig;
   }
 
 }
diff --git a/test/jalview/util/ParseHtmlBodyAndLinksTest.java b/test/jalview/util/ParseHtmlBodyAndLinksTest.java
new file mode 100644 (file)
index 0000000..5e8cd8c
--- /dev/null
@@ -0,0 +1,74 @@
+package jalview.util;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import org.testng.annotations.Test;
+
+public class ParseHtmlBodyAndLinksTest
+{
+  @Test(groups = { "Functional" })
+  public void testParseHtml_noLinks()
+  {
+    ParseHtmlBodyAndLinks testee = new ParseHtmlBodyAndLinks(
+            "<html>something here</html>", false, "\n");
+    assertEquals("something here", testee.getContent());
+    assertEquals("something here", testee.getNonHtmlContent());
+
+    // second argument makes no difference??
+    testee = new ParseHtmlBodyAndLinks("<html>something here</html>", true,
+            "\n");
+    assertEquals("something here", testee.getContent());
+    assertEquals("something here", testee.getNonHtmlContent());
+  }
+
+  @Test(groups = { "Functional" })
+  public void testParseHtml_withLinks()
+  {
+    ParseHtmlBodyAndLinks testee = new ParseHtmlBodyAndLinks(
+            "<html>Please click <a href=\"http://www.nowhere.com\">on this</a> to learn more about <a href=\"http://www.somewhere.com/here\">this</a></html>",
+            false, "\n");
+    assertEquals(
+            "Please click on this%LINK% to learn more about this%LINK%",
+            testee.getContent());
+    assertEquals(
+            "Please click on this%LINK% to learn more about this%LINK%",
+            testee.getNonHtmlContent());
+    assertEquals(2, testee.getLinks().size());
+    assertEquals("on this|http://www.nowhere.com", testee.getLinks().get(0));
+    assertEquals("this|http://www.somewhere.com/here", testee.getLinks()
+            .get(1));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testParseHtml_withLinksWithParameters()
+  {
+    ParseHtmlBodyAndLinks testee = new ParseHtmlBodyAndLinks(
+            "<html>Please click <a href=\"http://www.nowhere.com?id=234&taxon=human\">on this</a> to learn more</html>",
+            false, "\n");
+    assertEquals("Please click on this%LINK% to learn more",
+            testee.getContent());
+    assertEquals("Please click on this%LINK% to learn more",
+            testee.getNonHtmlContent());
+    assertEquals(1, testee.getLinks().size());
+    assertEquals("on this|http://www.nowhere.com?id=234&taxon=human",
+            testee.getLinks().get(0));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testParseHtml_withLinksWithEncoding()
+  {
+    ParseHtmlBodyAndLinks testee = new ParseHtmlBodyAndLinks(
+            "<html>Please click <a href=\"http://www.nowhere.com?id=234&amp;taxon=human&amp;id&gt;3&amp;id&lt;10\">on this</a> to learn &amp;&lt;&gt;more</html>",
+            false, "\n");
+    // html encoding in the text body is translated
+    assertEquals("Please click on this%LINK% to learn &<>more",
+            testee.getContent());
+    assertEquals("Please click on this%LINK% to learn &<>more",
+            testee.getNonHtmlContent());
+    assertEquals(1, testee.getLinks().size());
+    // html encoding in the url links is not translated
+    assertEquals(
+            "on this|http://www.nowhere.com?id=234&amp;taxon=human&amp;id&gt;3&amp;id&lt;10",
+            testee.getLinks().get(0));
+  }
+}