langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java
changeset 17569 ef80738645e2
parent 17560 9f6771abbd1a
child 17570 78512b2899db
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java	Tue May 14 10:14:55 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java	Tue May 14 10:14:55 2013 -0700
@@ -78,8 +78,8 @@
      */
     public void addAttr(HtmlAttr attrName, String attrValue) {
         if (attrs.isEmpty())
-            attrs = new LinkedHashMap<HtmlAttr,String>();
-        attrs.put(nullCheck(attrName), nullCheck(attrValue));
+            attrs = new LinkedHashMap<HtmlAttr,String>(3);
+        attrs.put(nullCheck(attrName), escapeHtmlChars(attrValue));
     }
 
     /**
@@ -131,6 +131,35 @@
     }
 
     /**
+     * Given a string, escape all special html characters and
+     * return the result.
+     *
+     * @param s The string to check.
+     * @return the original string with all of the HTML characters escaped.
+     */
+    private static String escapeHtmlChars(String s) {
+        for (int i = 0; i < s.length(); i++) {
+            char ch = s.charAt(i);
+            switch (ch) {
+                // only start building a new string if we need to
+                case '<': case '>': case '&':
+                    StringBuilder sb = new StringBuilder(s.substring(0, i));
+                    for ( ; i < s.length(); i++) {
+                        ch = s.charAt(i);
+                        switch (ch) {
+                            case '<': sb.append("&lt;");  break;
+                            case '>': sb.append("&gt;");  break;
+                            case '&': sb.append("&amp;"); break;
+                            default:  sb.append(ch);      break;
+                        }
+                    }
+                    return sb.toString();
+            }
+        }
+        return s;
+    }
+
+    /**
      * Generates an HTML anchor tag.
      *
      * @param ref reference url for the anchor tag
@@ -139,7 +168,7 @@
      */
     public static HtmlTree A(String ref, Content body) {
         HtmlTree htmltree = new HtmlTree(HtmlTag.A, nullCheck(body));
-        htmltree.addAttr(HtmlAttr.HREF, Util.escapeHtmlChars(nullCheck(ref)));
+        htmltree.addAttr(HtmlAttr.HREF, ref);
         return htmltree;
     }
 
@@ -324,7 +353,7 @@
             HtmlStyle styleClass, Content body) {
         HtmlTree htmltree = new HtmlTree(headingTag, nullCheck(body));
         if (printTitle)
-            htmltree.addAttr(HtmlAttr.TITLE, Util.stripHtml(body.toString()));
+            htmltree.addAttr(HtmlAttr.TITLE, stripHtml(body));
         if (styleClass != null)
             htmltree.addStyle(styleClass);
         return htmltree;
@@ -837,4 +866,22 @@
             return false;
         }
     }
+
+    /**
+     * Given a Content node, strips all html characters and
+     * return the result.
+     *
+     * @param body The content node to check.
+     * @return the plain text from the content node
+     *
+     */
+    private static String stripHtml(Content body) {
+        String rawString = body.toString();
+        // remove HTML tags
+        rawString = rawString.replaceAll("\\<.*?>", " ");
+        // consolidate multiple spaces between a word to a single space
+        rawString = rawString.replaceAll("\\b\\s{2,}\\b", " ");
+        // remove extra whitespaces
+        return rawString.trim();
+    }
 }