# HG changeset patch # User jlahoda # Date 1387274159 -3600 # Node ID f9f06fcca59deae934d266a2c7af142b45bd7fb3 # Parent aec1999bb1fa984786a658f5ed54f9f97fd8ee90 8029800: Flags.java uses String.toLowerCase without specifying Locale Summary: Introducing StringUtils.toLowerCase/toUpperCase independent on the default locale, converting almost all usages of String.toLowerCase/toUpperCase to use the new methods. Reviewed-by: jjg, bpatel diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/classfile/Instruction.java --- a/langtools/src/share/classes/com/sun/tools/classfile/Instruction.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/classfile/Instruction.java Tue Dec 17 10:55:59 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, 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 @@ -25,6 +25,8 @@ package com.sun.tools.classfile; +import java.util.Locale; + /** * See JVMS, chapter 6. * @@ -211,7 +213,7 @@ if (opcode == null) return "bytecode " + getUnsignedByte(0); else - return opcode.toString().toLowerCase(); + return opcode.toString().toLowerCase(Locale.US); } /** Get the length, in bytes, of this instruction, including the opcode diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Tue Dec 17 10:55:59 2013 +0100 @@ -37,6 +37,7 @@ import com.sun.tools.doclint.DocLint; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.StringUtils; import com.sun.tools.javadoc.RootDocImpl; /** @@ -237,7 +238,7 @@ public void setSpecificDocletOptions(String[][] options) { for (int oi = 0; oi < options.length; ++oi) { String[] os = options[oi]; - String opt = os[0].toLowerCase(); + String opt = StringUtils.toLowerCase(os[0]); if (opt.equals("-footer")) { footer = os[1]; } else if (opt.equals("-header")) { @@ -325,7 +326,7 @@ return result; } // otherwise look for the options we have added - option = option.toLowerCase(); + option = StringUtils.toLowerCase(option); if (option.equals("-nodeprecatedlist") || option.equals("-noindex") || option.equals("-notree") || @@ -389,7 +390,7 @@ // otherwise look at our options for (int oi = 0; oi < options.length; ++oi) { String[] os = options[oi]; - String opt = os[0].toLowerCase(); + String opt = StringUtils.toLowerCase(os[0]); if (opt.equals("-helpfile")) { if (nohelp == true) { reporter.printError(getText("doclet.Option_conflict", diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Tue Dec 17 10:55:59 2013 +0100 @@ -34,6 +34,7 @@ import com.sun.tools.doclets.internal.toolkit.*; import com.sun.tools.doclets.internal.toolkit.taglets.*; import com.sun.tools.doclets.internal.toolkit.util.*; +import com.sun.tools.javac.util.StringUtils; /** * Class for the Html Format Code Generation specific to JavaDoc. @@ -138,17 +139,17 @@ if (index < 0) { return htmlstr; } - String lowerHtml = htmlstr.toLowerCase(); + 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); + index = lowerHtml.indexOf(docroot, index); if (index < 0) { return htmlstr; } StringBuilder buf = new StringBuilder(); int previndex = 0; while (true) { - final String docroot = "{@docroot}"; // Search for lowercase version of {@docRoot} index = lowerHtml.indexOf(docroot, previndex); // If next {@docRoot} tag not found, append rest of htmlstr and exit loop @@ -1689,13 +1690,13 @@ } //Redirect all relative links. - int end, begin = text.toLowerCase().indexOf("= 0){ StringBuilder textBuff = new StringBuilder(text); while(begin >=0){ if (textBuff.length() > begin + 2 && ! Character.isWhitespace(textBuff.charAt(begin+2))) { - begin = textBuff.toString().toLowerCase().indexOf("' && blockTags.contains(text.substring(tagPos, currPos).toLowerCase())) { + if (ch == '>' && blockTags.contains(StringUtils.toLowerCase(text.substring(tagPos, currPos)))) { result.append(text, startPos, lessThanPos); startPos = currPos + 1; } diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java Tue Dec 17 10:55:59 2013 +0100 @@ -31,6 +31,7 @@ import com.sun.tools.doclets.formats.html.markup.*; import com.sun.tools.doclets.internal.toolkit.*; import com.sun.tools.doclets.internal.toolkit.util.*; +import com.sun.tools.javac.util.StringUtils; /** * Writes method documentation in HTML format. @@ -338,7 +339,7 @@ return ""; } - String lc = tag.toLowerCase(); + String lc = StringUtils.toLowerCase(tag); int begin = lc.indexOf(""); int end = lc.indexOf(""); if(begin == -1 || end == -1 || end <= begin){ diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlAttr.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlAttr.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlAttr.java Tue Dec 17 10:55:59 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -25,6 +25,8 @@ package com.sun.tools.doclets.formats.html.markup; +import com.sun.tools.javac.util.StringUtils; + /** * Enum representing HTML tag attributes. * @@ -64,7 +66,7 @@ private final String value; HtmlAttr() { - this.value = name().toLowerCase(); + this.value = StringUtils.toLowerCase(name()); } HtmlAttr(String name) { diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java Tue Dec 17 10:55:59 2013 +0100 @@ -25,7 +25,7 @@ package com.sun.tools.doclets.formats.html.markup; -import java.util.Locale; +import com.sun.tools.javac.util.StringUtils; /** * Enum representing HTML tags. @@ -117,7 +117,7 @@ HtmlTag(BlockType blockType, EndTag endTag ) { this.blockType = blockType; this.endTag = endTag; - this.value = name().toLowerCase(Locale.US); + this.value = StringUtils.toLowerCase(name()); } /** diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Tue Dec 17 10:55:59 2013 +0100 @@ -29,6 +29,7 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.tools.JavaFileManager; import com.sun.javadoc.*; import com.sun.tools.javac.sym.Profiles; @@ -36,7 +37,7 @@ import com.sun.tools.doclets.internal.toolkit.builders.BuilderFactory; import com.sun.tools.doclets.internal.toolkit.taglets.*; import com.sun.tools.doclets.internal.toolkit.util.*; -import javax.tools.JavaFileManager; +import com.sun.tools.javac.util.StringUtils; /** * Configure the output based on the options. Doclets should sub-class @@ -337,7 +338,7 @@ * Negative value means error occurred. */ public int optionLength(String option) { - option = option.toLowerCase(); + option = StringUtils.toLowerCase(option); if (option.equals("-author") || option.equals("-docfilessubdirs") || option.equals("-javafx") || @@ -454,7 +455,7 @@ // the output directory has already been created: so do that first. for (int oi = 0; oi < options.length; ++oi) { String[] os = options[oi]; - String opt = os[0].toLowerCase(); + String opt = StringUtils.toLowerCase(os[0]); if (opt.equals("-d")) { destDirName = addTrailingFileSep(os[1]); docFileDestDirName = destDirName; @@ -465,7 +466,7 @@ for (int oi = 0; oi < options.length; ++oi) { String[] os = options[oi]; - String opt = os[0].toLowerCase(); + String opt = StringUtils.toLowerCase(os[0]); if (opt.equals("-docfilessubdirs")) { copydocfilesubdirs = true; } else if (opt.equals("-docencoding")) { @@ -708,7 +709,7 @@ String encoding = ""; for (int oi = 0; oi < options.length; oi++) { String[] os = options[oi]; - String opt = os[0].toLowerCase(); + String opt = StringUtils.toLowerCase(os[0]); if (opt.equals("-docencoding")) { docencodingfound = true; if (!checkOutputFileEncoding(os[1], reporter)) { diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java Tue Dec 17 10:55:59 2013 +0100 @@ -384,13 +384,13 @@ commentTextBuilder.append( MessageFormat.format( configuration.getText("doclet.PropertySetterWithName"), - Util.propertyNameFromMethodName(member.name()))); + Util.propertyNameFromMethodName(configuration, member.name()))); } if (isGetter) { commentTextBuilder.append( MessageFormat.format( configuration.getText("doclet.PropertyGetterWithName"), - Util.propertyNameFromMethodName(member.name()))); + Util.propertyNameFromMethodName(configuration, member.name()))); } if (propertyDoc.commentText() != null && !propertyDoc.commentText().isEmpty()) { diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java Tue Dec 17 10:55:59 2013 +0100 @@ -31,6 +31,7 @@ import com.sun.javadoc.*; import com.sun.tools.doclets.internal.toolkit.*; import com.sun.tools.doclets.internal.toolkit.util.*; +import com.sun.tools.javac.util.StringUtils; /** * Builds the serialized form. @@ -567,7 +568,7 @@ } Tag[] serial = doc.tags("serial"); if (serial.length > 0) { - String serialtext = serial[0].text().toLowerCase(); + String serialtext = StringUtils.toLowerCase(serial[0].text()); if (serialtext.indexOf("exclude") >= 0) { return false; } else if (serialtext.indexOf("include") >= 0) { diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java Tue Dec 17 10:55:59 2013 +0100 @@ -28,6 +28,7 @@ import com.sun.javadoc.*; import com.sun.tools.doclets.internal.toolkit.Content; import com.sun.tools.doclets.internal.toolkit.util.DocFinder; +import com.sun.tools.javac.util.StringUtils; /** * A simple single argument custom tag. @@ -110,7 +111,7 @@ public SimpleTaglet(String tagName, String header, String locations) { this.tagName = tagName; this.header = header; - locations = locations.toLowerCase(); + locations = StringUtils.toLowerCase(locations); if (locations.indexOf(ALL) != -1 && locations.indexOf(EXCLUDED) == -1) { this.locations = PACKAGE + TYPE + FIELD + METHOD + CONSTRUCTOR + OVERVIEW; } else { diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java Tue Dec 17 10:55:59 2013 +0100 @@ -35,6 +35,7 @@ import com.sun.javadoc.*; import com.sun.tools.doclets.internal.toolkit.util.*; +import com.sun.tools.javac.util.StringUtils; /** * Manages theTaglets used by doclets. @@ -304,7 +305,7 @@ return; } Taglet tag = customTags.get(tagName); - locations = locations.toLowerCase(); + locations = StringUtils.toLowerCase(locations); if (tag == null || header != null) { customTags.remove(tagName); customTags.put(tagName, new SimpleTaglet(tagName, header, locations)); @@ -375,7 +376,7 @@ name = name.substring(1, name.length()); } if (! (standardTags.contains(name) || customTags.containsKey(name))) { - if (standardTagsLowercase.contains(name.toLowerCase())) { + if (standardTagsLowercase.contains(StringUtils.toLowerCase(name))) { message.warning(tags[i].position(), "doclet.UnknownTagLowercase", tags[i].name()); continue; } else { @@ -708,7 +709,7 @@ private void initStandardTagsLowercase() { Iterator it = standardTags.iterator(); while (it.hasNext()) { - standardTagsLowercase.add(it.next().toLowerCase()); + standardTagsLowercase.add(StringUtils.toLowerCase(it.next())); } } diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Tue Dec 17 10:55:59 2013 +0100 @@ -28,11 +28,12 @@ import java.io.*; import java.lang.annotation.ElementType; import java.util.*; +import javax.tools.StandardLocation; import com.sun.javadoc.*; import com.sun.javadoc.AnnotationDesc.ElementValuePair; import com.sun.tools.doclets.internal.toolkit.*; -import javax.tools.StandardLocation; +import com.sun.tools.javac.util.StringUtils; /** * Utilities Class for Doclets. @@ -253,8 +254,8 @@ */ private static class TypeComparator implements Comparator { public int compare(Type type1, Type type2) { - return type1.qualifiedTypeName().toLowerCase().compareTo( - type2.qualifiedTypeName().toLowerCase()); + return type1.qualifiedTypeName().compareToIgnoreCase( + type2.qualifiedTypeName()); } } @@ -589,7 +590,7 @@ typeName = "doclet.Enum"; } return config.getText( - lowerCaseOnly ? typeName.toLowerCase() : typeName); + lowerCaseOnly ? StringUtils.toLowerCase(typeName) : typeName); } /** @@ -724,7 +725,7 @@ * @param name name of the getter or setter method. * @return the name of the property of the given setter of getter. */ - public static String propertyNameFromMethodName(String name) { + public static String propertyNameFromMethodName(Configuration configuration, String name) { String propertyName = null; if (name.startsWith("get") || name.startsWith("set")) { propertyName = name.substring(3); @@ -734,7 +735,7 @@ if ((propertyName == null) || propertyName.isEmpty()){ return ""; } - return propertyName.substring(0, 1).toLowerCase() + return propertyName.substring(0, 1).toLowerCase(configuration.getLocale()) + propertyName.substring(1); } diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java Tue Dec 17 10:55:59 2013 +0100 @@ -702,7 +702,7 @@ private boolean isPropertyGetterOrSetter(MethodDoc[] members, MethodDoc methodDoc) { boolean found = false; - String propertyName = Util.propertyNameFromMethodName(methodDoc.name()); + String propertyName = Util.propertyNameFromMethodName(configuration, methodDoc.name()); if (!propertyName.isEmpty()) { String propertyMethodName = propertyName + "Property"; for (MethodDoc member: members) { diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclint/Checker.java --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Tue Dec 17 10:55:59 2013 +0100 @@ -80,6 +80,7 @@ import com.sun.source.util.TreePath; import com.sun.tools.doclint.HtmlTag.AttrKind; import com.sun.tools.javac.tree.DocPretty; +import com.sun.tools.javac.util.StringUtils; import static com.sun.tools.doclint.Messages.Group.*; @@ -243,7 +244,7 @@ markEnclosingTag(Flag.HAS_TEXT); String name = tree.getName().toString(); if (name.startsWith("#")) { - int v = name.toLowerCase().startsWith("#x") + int v = StringUtils.toLowerCase(name).startsWith("#x") ? Integer.parseInt(name.substring(2), 16) : Integer.parseInt(name.substring(1), 10); if (!Entity.isValid(v)) { diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclint/Env.java --- a/langtools/src/share/classes/com/sun/tools/doclint/Env.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclint/Env.java Tue Dec 17 10:55:59 2013 +0100 @@ -44,6 +44,7 @@ import com.sun.source.util.TreePath; import com.sun.tools.javac.model.JavacTypes; import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.util.StringUtils; /** * Utility container for current execution environment, @@ -66,7 +67,7 @@ static boolean accepts(String opt) { for (AccessKind g: values()) - if (opt.equals(g.name().toLowerCase())) return true; + if (opt.equals(StringUtils.toLowerCase(g.name()))) return true; return false; } diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java --- a/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java Tue Dec 17 10:55:59 2013 +0100 @@ -36,6 +36,7 @@ import javax.lang.model.element.Name; import static com.sun.tools.doclint.HtmlTag.Attr.*; +import com.sun.tools.javac.util.StringUtils; /** * Enum representing HTML tags. @@ -352,7 +353,7 @@ WIDTH; public String getText() { - return toLowerCase(name()); + return StringUtils.toLowerCase(name()); } static final Map index = new HashMap(); @@ -431,11 +432,11 @@ } public String getText() { - return toLowerCase(name()); + return StringUtils.toLowerCase(name()); } public Attr getAttr(Name attrName) { - return Attr.index.get(toLowerCase(attrName.toString())); + return Attr.index.get(StringUtils.toLowerCase(attrName.toString())); } public AttrKind getAttrKind(Name attrName) { @@ -457,10 +458,7 @@ } static HtmlTag get(Name tagName) { - return index.get(toLowerCase(tagName.toString())); + return index.get(StringUtils.toLowerCase(tagName.toString())); } - private static String toLowerCase(String s) { - return s.toLowerCase(Locale.US); - } } diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/doclint/Messages.java --- a/langtools/src/share/classes/com/sun/tools/doclint/Messages.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/doclint/Messages.java Tue Dec 17 10:55:59 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -42,6 +42,7 @@ import com.sun.source.doctree.DocTree; import com.sun.source.tree.Tree; import com.sun.tools.doclint.Env.AccessKind; +import com.sun.tools.javac.util.StringUtils; /** * Message reporting for DocLint. @@ -67,7 +68,7 @@ SYNTAX, REFERENCE; - String optName() { return name().toLowerCase(); } + String optName() { return StringUtils.toLowerCase(name()); } String notOptName() { return "-" + optName(); } static boolean accepts(String opt) { @@ -158,7 +159,7 @@ static boolean isValidOptions(String opts) { for (String opt: opts.split(",")) { - if (!isValidOption(opt.trim().toLowerCase())) + if (!isValidOption(StringUtils.toLowerCase(opt.trim()))) return false; } return true; @@ -203,7 +204,7 @@ setOption(ALL, Env.AccessKind.PRIVATE); else { for (String opt: opts.split(",")) - setOption(opt.trim().toLowerCase()); + setOption(StringUtils.toLowerCase(opt.trim())); } } @@ -215,7 +216,7 @@ int sep = arg.indexOf("/"); if (sep > 0) { - Env.AccessKind ak = Env.AccessKind.valueOf(arg.substring(sep + 1).toUpperCase()); + Env.AccessKind ak = Env.AccessKind.valueOf(StringUtils.toUpperCase(arg.substring(sep + 1))); setOption(arg.substring(0, sep), ak); } else { setOption(arg, null); @@ -290,7 +291,7 @@ out.println("By diagnostic kind..."); Table dkindTable = new Table(); for (Diagnostic.Kind k : Diagnostic.Kind.values()) { - dkindTable.put(k.toString().toLowerCase(), dkindCounts[k.ordinal()]); + dkindTable.put(StringUtils.toLowerCase(k.toString()), dkindCounts[k.ordinal()]); } dkindTable.print(out); out.println(); diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/javac/code/Flags.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Tue Dec 17 10:55:59 2013 +0100 @@ -33,6 +33,7 @@ import javax.lang.model.element.Modifier; import com.sun.tools.javac.util.Assert; +import com.sun.tools.javac.util.StringUtils; /** Access flags and other modifiers for Java classes and members. * @@ -388,7 +389,7 @@ Flag(long flag) { this.value = flag; - this.lowercaseName = name().toLowerCase(); + this.lowercaseName = StringUtils.toLowerCase(name()); } @Override diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/javac/file/Locations.java --- a/langtools/src/share/classes/com/sun/tools/javac/file/Locations.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/file/Locations.java Tue Dec 17 10:55:59 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -51,6 +51,7 @@ import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Options; +import com.sun.tools.javac.util.StringUtils; import javax.tools.JavaFileManager; import javax.tools.StandardJavaFileManager; @@ -717,7 +718,7 @@ /** Is this the name of an archive file? */ private boolean isArchive(File file) { - String n = file.getName().toLowerCase(); + String n = StringUtils.toLowerCase(file.getName()); return fsInfo.isFile(file) && (n.endsWith(".jar") || n.endsWith(".zip")); } diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/javac/main/Option.java --- a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java Tue Dec 17 10:55:59 2013 +0100 @@ -47,6 +47,7 @@ import com.sun.tools.javac.util.Log.PrefixKind; import com.sun.tools.javac.util.Log.WriterKind; import com.sun.tools.javac.util.Options; +import com.sun.tools.javac.util.StringUtils; import static com.sun.tools.javac.main.Option.ChoiceKind.*; import static com.sun.tools.javac.main.Option.OptionGroup.*; import static com.sun.tools.javac.main.Option.OptionKind.*; @@ -713,7 +714,7 @@ String v = options.get(XPKGINFO); return (v == null ? PkgInfo.LEGACY - : PkgInfo.valueOf(v.toUpperCase())); + : PkgInfo.valueOf(StringUtils.toUpperCase(v))); } } diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Tue Dec 17 10:55:59 2013 +0100 @@ -57,6 +57,7 @@ import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Options; import com.sun.tools.javac.util.Position; +import com.sun.tools.javac.util.StringUtils; import static com.sun.tools.javac.util.LayoutCharacters.*; /** @@ -993,7 +994,7 @@ "h1", "h2", "h3", "h4", "h5", "h6", "p", "pre")); protected boolean isSentenceBreak(Name n) { - return htmlBlockTags.contains(n.toString().toLowerCase()); + return htmlBlockTags.contains(StringUtils.toLowerCase(n.toString())); } protected boolean isSentenceBreak(DCTree t) { diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java --- a/langtools/src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java Tue Dec 17 10:55:59 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -36,6 +36,7 @@ import java.io.PrintWriter; import java.io.Writer; import java.util.*; +import com.sun.tools.javac.util.StringUtils; /** * A processor which prints out elements. Used to implement the @@ -202,7 +203,7 @@ writer.print("@interface"); break; default: - writer.print(kind.toString().toLowerCase()); + writer.print(StringUtils.toLowerCase(kind.toString())); } writer.print(" "); writer.print(e.getSimpleName()); diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java Tue Dec 17 10:55:59 2013 +0100 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javac.util; + +import java.util.Locale; + +/** A collection of utilities for String manipulation. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class StringUtils { + + /**Converts the given String to lower case using the {@link Locale#US US Locale}. The result + * is independent of the default Locale in the current JVM instance. + */ + public static String toLowerCase(String source) { + return source.toLowerCase(Locale.US); + } + + /**Converts the given String to upper case using the {@link Locale#US US Locale}. The result + * is independent of the default Locale in the current JVM instance. + */ + public static String toUpperCase(String source) { + return source.toUpperCase(Locale.US); + } + +} diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java --- a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java Tue Dec 17 10:55:59 2013 +0100 @@ -62,6 +62,7 @@ import com.sun.tools.classfile.Synthetic_attribute; import static com.sun.tools.classfile.AccessFlags.*; +import com.sun.tools.javac.util.StringUtils; /* * A writer for writing Attributes as text. @@ -717,14 +718,14 @@ } static String toHex(int i) { - return Integer.toString(i, 16).toUpperCase(); + return StringUtils.toUpperCase(Integer.toString(i, 16)); } static String toHex(int i, int w) { - String s = Integer.toHexString(i).toUpperCase(); + String s = StringUtils.toUpperCase(Integer.toHexString(i)); while (s.length() < w) s = "0" + s; - return s.toUpperCase(); + return StringUtils.toUpperCase(s); } private AnnotationWriter annotationWriter; diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java --- a/langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java Tue Dec 17 10:55:59 2013 +0100 @@ -37,6 +37,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import com.sun.tools.javac.util.StringUtils; /** * Annotate instructions with details about type annotations. @@ -115,7 +116,7 @@ print("@"); annotationWriter.write(n.anno, false, true); print(", "); - println(n.kind.toString().toLowerCase()); + println(StringUtils.toLowerCase(n.kind.toString())); } } } diff -r aec1999bb1fa -r f9f06fcca59d langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerThread.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerThread.java Tue Dec 17 10:55:58 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerThread.java Tue Dec 17 10:55:59 2013 +0100 @@ -49,6 +49,7 @@ import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.BaseFileManager; +import com.sun.tools.javac.util.StringUtils; import com.sun.tools.sjavac.comp.Dependencies; import com.sun.tools.sjavac.comp.JavaCompilerWithDeps; import com.sun.tools.sjavac.comp.SmartFileManager; @@ -256,7 +257,7 @@ // Load visible sources Set visibleSources = new HashSet(); boolean fix_drive_letter_case = - System.getProperty("os.name").toLowerCase().startsWith("windows"); + StringUtils.toLowerCase(System.getProperty("os.name")).startsWith("windows"); for (;;) { String l = in.readLine(); if (l == null) diff -r aec1999bb1fa -r f9f06fcca59d langtools/test/tools/javac/NoStringToLower.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/NoStringToLower.java Tue Dec 17 10:55:59 2013 +0100 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8029800 + * @summary String.toLowerCase()/toUpperCase is generally dangerous, check it is not used in langtools + */ + +import java.io.*; +import java.util.*; +import javax.tools.*; +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info; + +public class NoStringToLower { + public static void main(String... args) throws Exception { + NoStringToLower c = new NoStringToLower(); + if (c.run(args)) + return; + + if (is_jtreg()) + throw new Exception(c.errors + " errors occurred"); + else + System.exit(1); + } + + static boolean is_jtreg() { + return (System.getProperty("test.src") != null); + } + + /** + * Main entry point. + */ + boolean run(String... args) throws Exception { + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + JavaFileManager fm = c.getStandardFileManager(null, null, null); + JavaFileManager.Location javacLoc = findJavacLocation(fm); + String[] pkgs = { + "javax.annotation.processing", + "javax.lang.model", + "javax.tools", + "com.sun.source", + "com.sun.tools" + }; + for (String pkg: pkgs) { + for (JavaFileObject fo: fm.list(javacLoc, + pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) { + scan(fo); + } + } + + return (errors == 0); + } + + // depending on how the test is run, javac may be on bootclasspath or classpath + JavaFileManager.Location findJavacLocation(JavaFileManager fm) { + JavaFileManager.Location[] locns = + { StandardLocation.PLATFORM_CLASS_PATH, StandardLocation.CLASS_PATH }; + try { + for (JavaFileManager.Location l: locns) { + JavaFileObject fo = fm.getJavaFileForInput(l, + "com.sun.tools.javac.Main", JavaFileObject.Kind.CLASS); + if (fo != null) + return l; + } + } catch (IOException e) { + throw new Error(e); + } + throw new IllegalStateException("Cannot find javac"); + } + + /** + * Verify there are no references to String.toLowerCase() in a class file. + */ + void scan(JavaFileObject fo) throws IOException { + InputStream in = fo.openInputStream(); + try { + ClassFile cf = ClassFile.read(in); + for (ConstantPool.CPInfo cpinfo: cf.constant_pool.entries()) { + if (cpinfo.getTag() == ConstantPool.CONSTANT_Methodref) { + CONSTANT_Methodref_info ref = (CONSTANT_Methodref_info) cpinfo; + String methodDesc = ref.getClassInfo().getName() + "." + ref.getNameAndTypeInfo().getName() + ":" + ref.getNameAndTypeInfo().getType(); + + if ("java/lang/String.toLowerCase:()Ljava/lang/String;".equals(methodDesc)) { + error("found reference to String.toLowerCase() in: " + fo.getName()); + } + if ("java/lang/String.toUpperCase:()Ljava/lang/String;".equals(methodDesc)) { + error("found reference to String.toLowerCase() in: " + fo.getName()); + } + } + } + } catch (ConstantPoolException ignore) { + } finally { + in.close(); + } + } + + /** + * Report an error. + */ + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; +} diff -r aec1999bb1fa -r f9f06fcca59d langtools/test/tools/javac/util/StringUtilsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/util/StringUtilsTest.java Tue Dec 17 10:55:59 2013 +0100 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8029800 + * @summary Unit test StringUtils + * @run main StringUtilsTest + */ + +import java.util.Locale; +import java.util.Objects; +import com.sun.tools.javac.util.StringUtils; + +public class StringUtilsTest { + public static void main(String... args) throws Exception { + new StringUtilsTest().run(); + } + + void run() throws Exception { + Locale.setDefault(new Locale("tr", "TR")); + + //verify the properties of the default locale: + assertEquals("\u0131", "I".toLowerCase()); + assertEquals("\u0130", "i".toUpperCase()); + + //verify the StringUtils does what it 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")); + } + + void assertEquals(String expected, String actual) { + if (!Objects.equals(expected, actual)) { + throw new IllegalStateException("expected=" + expected + "; actual=" + actual); + } + } + + void assertEquals(int expected, int actual) { + if (expected != actual) { + throw new IllegalStateException("expected=" + expected + "; actual=" + actual); + } + } +}