8043186: javac test langtools/tools/javac/util/StringUtilsTest.java fails
Summary: The result of String.toLowerCase.indexOf does not always point at the start of the given string in the non-lowercased text.
Reviewed-by: jjg, bpatel
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Mon May 12 17:09:26 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Fri May 16 10:52:07 2014 +0200
@@ -28,6 +28,8 @@
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import com.sun.javadoc.*;
import com.sun.tools.doclets.formats.html.markup.*;
@@ -139,42 +141,37 @@
if (index < 0) {
return htmlstr;
}
- String lowerHtml = StringUtils.toLowerCase(htmlstr);
- final String docroot = "{@docroot}";
- // Return index of first occurrence of {@docroot}
- // Note: {@docRoot} is not case sensitive when passed in w/command line option
- index = lowerHtml.indexOf(docroot, index);
- if (index < 0) {
+ Matcher docrootMatcher = docrootPattern.matcher(htmlstr);
+ if (!docrootMatcher.find()) {
return htmlstr;
}
StringBuilder buf = new StringBuilder();
- int previndex = 0;
- while (true) {
- // Search for lowercase version of {@docRoot}
- index = lowerHtml.indexOf(docroot, previndex);
- // If next {@docRoot} tag not found, append rest of htmlstr and exit loop
- if (index < 0) {
- buf.append(htmlstr.substring(previndex));
- break;
- }
- // If next {@docroot} tag found, append htmlstr up to start of tag
- buf.append(htmlstr.substring(previndex, index));
- previndex = index + docroot.length();
- if (configuration.docrootparent.length() > 0 && htmlstr.startsWith("/..", previndex)) {
+ int prevEnd = 0;
+ do {
+ int match = docrootMatcher.start();
+ // append htmlstr up to start of next {@docroot}
+ buf.append(htmlstr.substring(prevEnd, match));
+ prevEnd = docrootMatcher.end();
+ if (configuration.docrootparent.length() > 0 && htmlstr.startsWith("/..", prevEnd)) {
// Insert the absolute link if {@docRoot} is followed by "/..".
buf.append(configuration.docrootparent);
- previndex += 3;
+ prevEnd += 3;
} else {
// Insert relative path where {@docRoot} was located
buf.append(pathToRoot.isEmpty() ? "." : pathToRoot.getPath());
}
// Append slash if next character is not a slash
- if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') {
+ if (prevEnd < htmlstr.length() && htmlstr.charAt(prevEnd) != '/') {
buf.append('/');
}
- }
+ } while (docrootMatcher.find());
+ buf.append(htmlstr.substring(prevEnd));
return buf.toString();
}
+ //where:
+ // Note: {@docRoot} is not case sensitive when passed in w/command line option:
+ private static final Pattern docrootPattern =
+ Pattern.compile(Pattern.quote("{@docroot}"), Pattern.CASE_INSENSITIVE);
/**
* Get the script to show or hide the All classes link.
@@ -1690,13 +1687,13 @@
}
//Redirect all relative links.
- int end, begin = StringUtils.toLowerCase(text).indexOf("<a");
+ int end, begin = StringUtils.indexOfIgnoreCase(text, "<a");
if(begin >= 0){
StringBuilder textBuff = new StringBuilder(text);
while(begin >=0){
if (textBuff.length() > begin + 2 && ! Character.isWhitespace(textBuff.charAt(begin+2))) {
- begin = StringUtils.toLowerCase(textBuff.toString()).indexOf("<a", begin + 1);
+ begin = StringUtils.indexOfIgnoreCase(textBuff.toString(), "<a", begin + 1);
continue;
}
@@ -1736,7 +1733,7 @@
+ redirectPathFromRoot.resolve(relativeLink).getPath();
textBuff.replace(begin, end, relativeLink);
}
- begin = StringUtils.toLowerCase(textBuff.toString()).indexOf("<a", begin + 1);
+ begin = StringUtils.indexOfIgnoreCase(textBuff.toString(), "<a", begin + 1);
}
return textBuff.toString();
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java Mon May 12 17:09:26 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java Fri May 16 10:52:07 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -332,24 +332,6 @@
}
/**
- * Parse the <Code> tag and return the text.
- */
- protected String parseCodeTag(String tag){
- if(tag == null){
- return "";
- }
-
- String lc = StringUtils.toLowerCase(tag);
- int begin = lc.indexOf("<code>");
- int end = lc.indexOf("</code>");
- if(begin == -1 || end == -1 || end <= begin){
- return tag;
- } else {
- return tag.substring(begin + 6, end);
- }
- }
-
- /**
* {@inheritDoc}
*/
protected static void addImplementsInfo(HtmlDocletWriter writer,
--- a/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java Mon May 12 17:09:26 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java Fri May 16 10:52:07 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
package com.sun.tools.javac.util;
import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/** A collection of utilities for String manipulation.
*
@@ -50,4 +52,19 @@
return source.toUpperCase(Locale.US);
}
+ /**Case insensitive version of {@link String#indexOf(java.lang.String)}. Equivalent to
+ * {@code text.indexOf(str)}, except the matching is case insensitive.
+ */
+ public static int indexOfIgnoreCase(String text, String str) {
+ return indexOfIgnoreCase(text, str, 0);
+ }
+
+ /**Case insensitive version of {@link String#indexOf(java.lang.String, int)}. Equivalent to
+ * {@code text.indexOf(str, startIndex)}, except the matching is case insensitive.
+ */
+ public static int indexOfIgnoreCase(String text, String str, int startIndex) {
+ Matcher m = Pattern.compile(Pattern.quote(str), Pattern.CASE_INSENSITIVE).matcher(text);
+ return m.find(startIndex) ? m.start() : -1;
+ }
+
}
--- a/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java Mon May 12 17:09:26 2014 +0100
+++ b/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java Fri May 16 10:52:07 2014 +0200
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4460354 8014636
+ * @bug 4460354 8014636 8043186
* @summary Test to make sure that relative paths are redirected in the
* output so that they are not broken.
* @author jamieh
--- a/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java Mon May 12 17:09:26 2014 +0100
+++ b/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java Fri May 16 10:52:07 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
public class C {
/**
- * Here is a relative link in a field:
+ * Here is a relative link in a field:\u0130
* <a href="relative-field-link.html">relative field link</a>.
*/
public C field = null;
--- a/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java Mon May 12 17:09:26 2014 +0100
+++ b/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java Fri May 16 10:52:07 2014 +0200
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6227616
+ * @bug 6227616 8043186
* @summary Test the new -top option.
* @author jamieh
* @library ../lib
@@ -43,7 +43,30 @@
javadoc("-overview", testSrc("overview.html"),
"-use",
"-top", "TOP TEXT",
- "-d", "out",
+ "-d", "out-1",
+ "-sourcepath", testSrc,
+ "pkg");
+ checkExit(Exit.OK);
+
+ checkTopText(
+ "pkg/AnnotationType.html",
+ "pkg/class-use/AnnotationType.html",
+ "pkg/Cl.html",
+ "pkg/class-use/Cl.html",
+ "pkg/package-summary.html",
+ "pkg/package-use.html",
+ "overview-summary.html",
+ "overview-tree.html",
+ "constant-values.html",
+ "help-doc.html");
+ }
+
+ @Test
+ void testDocRootRewrite() {
+ javadoc("-overview", testSrc("overview.html"),
+ "-use",
+ "-top", "\u0130{@docroot}TOP TEXT",
+ "-d", "out-2",
"-sourcepath", testSrc,
"pkg");
checkExit(Exit.OK);
--- a/langtools/test/tools/javac/util/StringUtilsTest.java Mon May 12 17:09:26 2014 +0100
+++ b/langtools/test/tools/javac/util/StringUtilsTest.java Fri May 16 10:52:07 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8029800
+ * @bug 8029800 8043186
* @summary Unit test StringUtils
* @run main StringUtilsTest
*/
@@ -44,12 +44,14 @@
assertEquals("\u0131", "I".toLowerCase());
assertEquals("\u0130", "i".toUpperCase());
- //verify the StringUtils does what it should
+ //verify the StringUtils.toLowerCase/toUpperCase do what they should:
assertEquals("i", StringUtils.toLowerCase("I"));
assertEquals("I", StringUtils.toUpperCase("i"));
- //verify we can use index from indexOf of toLowerCase String in the original:
- assertEquals(2, StringUtils.toLowerCase("\u0130\u0130lookFor").indexOf("lookfor"));
+ //verify StringUtils.caseInsensitiveIndexOf works:
+ assertEquals(2, StringUtils.indexOfIgnoreCase(" lookFor", "lookfor"));
+ assertEquals(11, StringUtils.indexOfIgnoreCase(" lookFor LOOKfor", "lookfor", 11));
+ assertEquals(2, StringUtils.indexOfIgnoreCase("\u0130\u0130lookFor", "lookfor"));
}
void assertEquals(String expected, String actual) {