diff --git a/make/sun/awt/Makefile b/make/sun/awt/Makefile
index c7961dc556a19e8fe2e5e74891ea60a6eb7a08b0..87fd56b6dad73a6ff853031bf4f9da94a3fcfb59 100644
--- a/make/sun/awt/Makefile
+++ b/make/sun/awt/Makefile
@@ -175,6 +175,10 @@ endif
include $(BUILDDIR)/common/Mapfile-vers.gmk
include $(BUILDDIR)/common/Library.gmk
+COMPILEFONTCONFIG_FLAGS =
+ifdef ALT_COMPILEFONTCONFIG_FLAGS
+ COMPILEFONTCONFIG_FLAGS += $(ALT_COMPILEFONTCONFIG_FLAGS)
+endif
build: fontconfigs
@@ -406,7 +410,7 @@ COMPILEFONTCONFIG_JARFILE = $(BUILDTOOLJARDIR)/compilefontconfig.jar
$(LIBDIR)/%.bfc: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%.properties \
$(COMPILEFONTCONFIG_JARFILE)
$(prep-target)
- $(BOOT_JAVA_CMD) -jar $(COMPILEFONTCONFIG_JARFILE) $< $@
+ $(BOOT_JAVA_CMD) -jar $(COMPILEFONTCONFIG_JARFILE) $(COMPILEFONTCONFIG_FLAGS) $< $@
$(install-module-file)
$(call chmod-file, 444)
@$(java-vm-cleanup)
diff --git a/make/tools/src/build/tools/javazic/Zoneinfo.java b/make/tools/src/build/tools/javazic/Zoneinfo.java
index 143c687d51b9357faf0a95419b6790f7578c686a..872cc1144c8568239e8f195dc9d24a70cef5060b 100644
--- a/make/tools/src/build/tools/javazic/Zoneinfo.java
+++ b/make/tools/src/build/tools/javazic/Zoneinfo.java
@@ -222,6 +222,7 @@ class Zoneinfo {
boolean continued = false;
Zone zone = null;
String l;
+ lineNum = 0;
try {
while ((line = in.readLine()) != null) {
diff --git a/src/share/classes/java/awt/font/NumericShaper.java b/src/share/classes/java/awt/font/NumericShaper.java
index 0c57c299fb61ca770ce039cdd0ad00597ab153f9..c8100bfb0dea20c53dcce409127cca63ca884bf8 100644
--- a/src/share/classes/java/awt/font/NumericShaper.java
+++ b/src/share/classes/java/awt/font/NumericShaper.java
@@ -58,20 +58,20 @@ import java.util.Set;
* It is also possible to perform numeric shaping explicitly using instances
* of NumericShaper
, as this code snippet demonstrates:
*
* *- * char[] text = ...; - * // shape all EUROPEAN digits (except zero) to ARABIC digits - * NumericShaper shaper = NumericShaper.getShaper(NumericShaper.ARABIC); - * shaper.shape(text, start, count); + * char[] text = ...; + * // shape all EUROPEAN digits (except zero) to ARABIC digits + * NumericShaper shaper = NumericShaper.getShaper(NumericShaper.ARABIC); + * shaper.shape(text, start, count); * - * // shape European digits to ARABIC digits if preceding text is Arabic, or - * // shape European digits to TAMIL digits if preceding text is Tamil, or - * // leave European digits alone if there is no preceding text, or - * // preceding text is neither Arabic nor Tamil - * NumericShaper shaper = - * NumericShaper.getContextualShaper(NumericShaper.ARABIC | - * NumericShaper.TAMIL, - * NumericShaper.EUROPEAN); - * shaper.shape(text, start, count); + * // shape European digits to ARABIC digits if preceding text is Arabic, or + * // shape European digits to TAMIL digits if preceding text is Tamil, or + * // leave European digits alone if there is no preceding text, or + * // preceding text is neither Arabic nor Tamil + * NumericShaper shaper = + * NumericShaper.getContextualShaper(NumericShaper.ARABIC | + * NumericShaper.TAMIL, + * NumericShaper.EUROPEAN); + * shaper.shape(text, start, count); *
Bit mask- and enum-based Unicode ranges
@@ -99,6 +99,37 @@ import java.util.Set; * values are specified, such as {@code NumericShaper.Range.BALINESE}, * those ranges are ignored. * + *Decimal Digits Precedence
+ * + *A Unicode range may have more than one set of decimal digits. If + * multiple decimal digits sets are specified for the same Unicode + * range, one of the sets will take precedence as follows. + * + *
Unicode Range | + *NumericShaper Constants |
+ * Precedence | + *
---|---|---|
Arabic | + *{@link NumericShaper#ARABIC NumericShaper.ARABIC} + * {@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC} |
+ * {@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC} | + *
{@link NumericShaper.Range#ARABIC} + * {@link NumericShaper.Range#EASTERN_ARABIC} |
+ * {@link NumericShaper.Range#EASTERN_ARABIC} | + *|
Tai Tham | + *{@link NumericShaper.Range#TAI_THAM_HORA} + * {@link NumericShaper.Range#TAI_THAM_THAM} |
+ * {@link NumericShaper.Range#TAI_THAM_THAM} | + *
Within a String, a pair of single quotes can be used to
+ * quote any arbitrary characters except single quotes. For example,
+ * pattern string "'{0}'"
represents string
+ * "{0}"
, not a FormatElement. A single quote itself
+ * must be represented by doubled single quotes {@code ''} throughout a
+ * String. For example, pattern string "'{''}'"
is
+ * interpreted as a sequence of '{
(start of quoting and a
+ * left curly brace), ''
(a single quote), and
+ * }'
(a right curly brace and end of quoting),
+ * not '{'
and '}'
(quoted left and
+ * right curly braces): representing string "{'}"
,
+ * not "{}"
.
*
- * StringPart:
- * ''
- * ' QuotedString '
- * UnquotedString
+ *
A SubformatPattern is interpreted by its corresponding
+ * subformat, and subformat-dependent pattern rules apply. For example,
+ * pattern string "{1,number,$'#',##}"
+ * (SubformatPattern with underline) will produce a number format
+ * with the pound-sign quoted, with a result such as: {@code
+ * "$#31,45"}. Refer to each {@code Format} subclass documentation for
+ * details.
*
- * SubformatPattern:
- * SubformatPatternPartopt
- * SubformatPattern SubformatPatternPart
+ *
Any unmatched quote is treated as closed at the end of the given + * pattern. For example, pattern string {@code "'{0}"} is treated as + * pattern {@code "'{0}'"}. * - * SubFormatPatternPart: - * ' QuotedPattern ' - * UnquotedPattern - * + *
Any curly braces within an unquoted pattern must be balanced. For
+ * example, "ab {0} de"
and "ab '}' de"
are
+ * valid patterns, but "ab {0'}' de"
, "ab } de"
+ * and "''{''"
are not.
*
*
- * Within a String, "''"
represents a single
- * quote. A QuotedString can contain arbitrary characters
- * except single quotes; the surrounding single quotes are removed.
- * An UnquotedString can contain arbitrary characters
- * except single quotes and left curly brackets. Thus, a string that
- * should result in the formatted message "'{0}'" can be written as
- * "'''{'0}''"
or "'''{0}'''"
.
- *
- * Within a SubformatPattern, different rules apply.
- * A QuotedPattern can contain arbitrary characters
- * except single quotes; but the surrounding single quotes are
- * not removed, so they may be interpreted by the
- * subformat. For example, "{1,number,$'#',##}"
will
- * produce a number format with the pound-sign quoted, with a result
- * such as: "$#31,45".
- * An UnquotedPattern can contain arbitrary characters
- * except single quotes, but curly braces within it must be balanced.
- * For example, "ab {0} de"
and "ab '}' de"
- * are valid subformat patterns, but "ab {0'}' de"
and
- * "ab } de"
are not.
- *
*
* The ArgumentIndex value is a non-negative integer written
- * using the digits '0' through '9', and represents an index into the
- * arguments
array passed to the format
methods
- * or the result array returned by the parse
methods.
+ * using the digits {@code '0'} through {@code '9'}, and represents an index into the
+ * {@code arguments} array passed to the {@code format} methods
+ * or the result array returned by the {@code parse} methods.
*
* The FormatType and FormatStyle values are used to create
- * a Format
instance for the format element. The following
- * table shows how the values map to Format instances. Combinations not
+ * a {@code Format} instance for the format element. The following
+ * table shows how the values map to {@code Format} instances. Combinations not
* shown in the table are illegal. A SubformatPattern must
- * be a valid pattern string for the Format subclass used.
+ * be a valid pattern string for the {@code Format} subclass used.
*
*
Format Type - * | Format Style - * | Subformat Created + * | FormatType + * | FormatStyle + * | Subformat Created * |
---|---|---|---|---|---|
(none) * | (none) @@ -167,61 +159,61 @@ import java.util.Locale; * | ||||
number
* | (none) - * | NumberFormat.getInstance(getLocale())
+ * | {@link NumberFormat#getInstance(Locale) NumberFormat.getInstance}{@code (getLocale())} * | ||
integer
- * | NumberFormat.getIntegerInstance(getLocale())
+ * | {@link NumberFormat#getIntegerInstance(Locale) NumberFormat.getIntegerInstance}{@code (getLocale())} * | |||
currency
- * | NumberFormat.getCurrencyInstance(getLocale())
+ * | {@link NumberFormat#getCurrencyInstance(Locale) NumberFormat.getCurrencyInstance}{@code (getLocale())} * | |||
percent
- * | NumberFormat.getPercentInstance(getLocale())
+ * | {@link NumberFormat#getPercentInstance(Locale) NumberFormat.getPercentInstance}{@code (getLocale())} * | |||
SubformatPattern - * | new DecimalFormat(subformatPattern, DecimalFormatSymbols.getInstance(getLocale()))
+ * | {@code new} {@link DecimalFormat#DecimalFormat(String,DecimalFormatSymbols) DecimalFormat}{@code (subformatPattern,} {@link DecimalFormatSymbols#getInstance(Locale) DecimalFormatSymbols.getInstance}{@code (getLocale()))} * | |||
date
* | (none) - * | DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
+ * | {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * | ||
short
- * | DateFormat.getDateInstance(DateFormat.SHORT, getLocale())
+ * | {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} * | |||
medium
- * | DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
+ * | {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * | |||
long
- * | DateFormat.getDateInstance(DateFormat.LONG, getLocale())
+ * | {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} * | |||
full
- * | DateFormat.getDateInstance(DateFormat.FULL, getLocale())
+ * | {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} * | |||
SubformatPattern - * | new SimpleDateFormat(subformatPattern, getLocale())
+ * | {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} * | |||
time
* | (none) - * | DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
+ * | {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * | ||
short
- * | DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())
+ * | {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} * | |||
medium
- * | DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
+ * | {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * | |||
long
- * | DateFormat.getTimeInstance(DateFormat.LONG, getLocale())
+ * | {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} * | |||
full
- * | DateFormat.getTimeInstance(DateFormat.FULL, getLocale())
+ * | {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} * | |||
SubformatPattern - * | new SimpleDateFormat(subformatPattern, getLocale())
+ * | {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} * | |||
choice
* | SubformatPattern - * | new ChoiceFormat(subformatPattern)
+ * | {@code new} {@link ChoiceFormat#ChoiceFormat(String) ChoiceFormat}{@code (subformatPattern)} * |
* @@ -321,7 +313,7 @@ import java.util.Locale; * * *
- * Likewise, parsing with a MessageFormat object using patterns containing + * Likewise, parsing with a {@code MessageFormat} object using patterns containing * multiple occurrences of the same argument would return the last match. For * example, *
@@ -343,7 +335,11 @@ import java.util.Locale; * @see Format * @see NumberFormat * @see DecimalFormat + * @see DecimalFormatSymbols * @see ChoiceFormat + * @see DateFormat + * @see SimpleDateFormat + * * @author Mark Davis */ @@ -427,18 +423,19 @@ public class MessageFormat extends Format { * @exception IllegalArgumentException if the pattern is invalid */ public void applyPattern(String pattern) { - StringBuffer[] segments = new StringBuffer[4]; - for (int i = 0; i < segments.length; ++i) { - segments[i] = new StringBuffer(); - } - int part = 0; + StringBuilder[] segments = new StringBuilder[4]; + // Allocate only segments[SEG_RAW] here. The rest are + // allocated on demand. + segments[SEG_RAW] = new StringBuilder(); + + int part = SEG_RAW; int formatNumber = 0; boolean inQuote = false; int braceStack = 0; maxOffset = -1; for (int i = 0; i < pattern.length(); ++i) { char ch = pattern.charAt(i); - if (part == 0) { + if (part == SEG_RAW) { if (ch == '\'') { if (i + 1 < pattern.length() && pattern.charAt(i+1) == '\'') { @@ -448,43 +445,61 @@ public class MessageFormat extends Format { inQuote = !inQuote; } } else if (ch == '{' && !inQuote) { - part = 1; + part = SEG_INDEX; + if (segments[SEG_INDEX] == null) { + segments[SEG_INDEX] = new StringBuilder(); + } } else { segments[part].append(ch); } - } else if (inQuote) { // just copy quotes in parts - segments[part].append(ch); - if (ch == '\'') { - inQuote = false; - } - } else { - switch (ch) { - case ',': - if (part < 3) - part += 1; - else - segments[part].append(ch); - break; - case '{': - ++braceStack; + } else { + if (inQuote) { // just copy quotes in parts segments[part].append(ch); - break; - case '}': - if (braceStack == 0) { - part = 0; - makeFormat(i, formatNumber, segments); - formatNumber++; - } else { - --braceStack; + if (ch == '\'') { + inQuote = false; + } + } else { + switch (ch) { + case ',': + if (part < SEG_MODIFIER) { + if (segments[++part] == null) { + segments[part] = new StringBuilder(); + } + } else { + segments[part].append(ch); + } + break; + case '{': + ++braceStack; segments[part].append(ch); + break; + case '}': + if (braceStack == 0) { + part = SEG_RAW; + makeFormat(i, formatNumber, segments); + formatNumber++; + // throw away other segments + segments[SEG_INDEX] = null; + segments[SEG_TYPE] = null; + segments[SEG_MODIFIER] = null; + } else { + --braceStack; + segments[part].append(ch); + } + break; + case ' ': + // Skip any leading space chars for SEG_TYPE. + if (part != SEG_TYPE || segments[SEG_TYPE].length() > 0) { + segments[part].append(ch); + } + break; + case '\'': + inQuote = true; + // fall through, so we keep quotes in other parts + default: + segments[part].append(ch); + break; } - break; - case '\'': - inQuote = true; - // fall through, so we keep quotes in other parts - default: - segments[part].append(ch); - break; } } } @@ -506,65 +521,57 @@ public class MessageFormat extends Format { public String toPattern() { // later, make this more extensible int lastOffset = 0; - StringBuffer result = new StringBuffer(); + StringBuilder result = new StringBuilder(); for (int i = 0; i <= maxOffset; ++i) { - copyAndFixQuotes(pattern, lastOffset, offsets[i],result); + copyAndFixQuotes(pattern, lastOffset, offsets[i], result); lastOffset = offsets[i]; - result.append('{'); - result.append(argumentNumbers[i]); - if (formats[i] == null) { + result.append('{').append(argumentNumbers[i]); + Format fmt = formats[i]; + if (fmt == null) { // do nothing, string format - } else if (formats[i] instanceof DecimalFormat) { - if (formats[i].equals(NumberFormat.getInstance(locale))) { + } else if (fmt instanceof NumberFormat) { + if (fmt.equals(NumberFormat.getInstance(locale))) { result.append(",number"); - } else if (formats[i].equals(NumberFormat.getCurrencyInstance(locale))) { + } else if (fmt.equals(NumberFormat.getCurrencyInstance(locale))) { result.append(",number,currency"); - } else if (formats[i].equals(NumberFormat.getPercentInstance(locale))) { + } else if (fmt.equals(NumberFormat.getPercentInstance(locale))) { result.append(",number,percent"); - } else if (formats[i].equals(NumberFormat.getIntegerInstance(locale))) { + } else if (fmt.equals(NumberFormat.getIntegerInstance(locale))) { result.append(",number,integer"); } else { - result.append(",number," + - ((DecimalFormat)formats[i]).toPattern()); + if (fmt instanceof DecimalFormat) { + result.append(",number,").append(((DecimalFormat)fmt).toPattern()); + } else if (fmt instanceof ChoiceFormat) { + result.append(",choice,").append(((ChoiceFormat)fmt).toPattern()); + } else { + // UNKNOWN + } } - } else if (formats[i] instanceof SimpleDateFormat) { - if (formats[i].equals(DateFormat.getDateInstance( - DateFormat.DEFAULT,locale))) { - result.append(",date"); - } else if (formats[i].equals(DateFormat.getDateInstance( - DateFormat.SHORT,locale))) { - result.append(",date,short"); - } else if (formats[i].equals(DateFormat.getDateInstance( - DateFormat.DEFAULT,locale))) { - result.append(",date,medium"); - } else if (formats[i].equals(DateFormat.getDateInstance( - DateFormat.LONG,locale))) { - result.append(",date,long"); - } else if (formats[i].equals(DateFormat.getDateInstance( - DateFormat.FULL,locale))) { - result.append(",date,full"); - } else if (formats[i].equals(DateFormat.getTimeInstance( - DateFormat.DEFAULT,locale))) { - result.append(",time"); - } else if (formats[i].equals(DateFormat.getTimeInstance( - DateFormat.SHORT,locale))) { - result.append(",time,short"); - } else if (formats[i].equals(DateFormat.getTimeInstance( - DateFormat.DEFAULT,locale))) { - result.append(",time,medium"); - } else if (formats[i].equals(DateFormat.getTimeInstance( - DateFormat.LONG,locale))) { - result.append(",time,long"); - } else if (formats[i].equals(DateFormat.getTimeInstance( - DateFormat.FULL,locale))) { - result.append(",time,full"); - } else { - result.append(",date," - + ((SimpleDateFormat)formats[i]).toPattern()); + } else if (fmt instanceof DateFormat) { + int index; + for (index = MODIFIER_DEFAULT; index < DATE_TIME_MODIFIERS.length; index++) { + DateFormat df = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[index], + locale); + if (fmt.equals(df)) { + result.append(",date"); + break; + } + df = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[index], + locale); + if (fmt.equals(df)) { + result.append(",time"); + break; + } + } + if (index >= DATE_TIME_MODIFIERS.length) { + if (fmt instanceof SimpleDateFormat) { + result.append(",date,").append(((SimpleDateFormat)fmt).toPattern()); + } else { + // UNKNOWN + } + } else if (index != MODIFIER_DEFAULT) { + result.append(',').append(DATE_TIME_MODIFIER_KEYWORDS[index]); } - } else if (formats[i] instanceof ChoiceFormat) { - result.append(",choice," - + ((ChoiceFormat)formats[i]).toPattern()); } else { //result.append(", unknown"); } @@ -678,7 +685,7 @@ public class MessageFormat extends Format { * * @param formatElementIndex the index of a format element within the pattern * @param newFormat the format to use for the specified format element - * @exception ArrayIndexOutOfBoundsException if formatElementIndex is equal to or + * @exception ArrayIndexOutOfBoundsException if {@code formatElementIndex} is equal to or * larger than the number of format elements in the pattern string */ public void setFormat(int formatElementIndex, Format newFormat) { @@ -972,7 +979,8 @@ public class MessageFormat extends Format { if (patternOffset >= tempLength) { next = source.length(); }else{ - next = source.indexOf( pattern.substring(patternOffset,tempLength), sourceOffset); + next = source.indexOf(pattern.substring(patternOffset, tempLength), + sourceOffset); } if (next < 0) { @@ -1226,7 +1234,7 @@ public class MessageFormat extends Format { lastOffset = offsets[i]; int argumentNumber = argumentNumbers[i]; if (arguments == null || argumentNumber >= arguments.length) { - result.append("{" + argumentNumber + "}"); + result.append('{').append(argumentNumber).append('}'); continue; } // int argRecursion = ((recursionProtection >> (argumentNumber*2)) & 0x3); @@ -1338,25 +1346,83 @@ public class MessageFormat extends Format { } } - private static final String[] typeList = - {"", "", "number", "", "date", "", "time", "", "choice"}; - private static final String[] modifierList = - {"", "", "currency", "", "percent", "", "integer"}; - private static final String[] dateModifierList = - {"", "", "short", "", "medium", "", "long", "", "full"}; + // Indices for segments + private static final int SEG_RAW = 0; + private static final int SEG_INDEX = 1; + private static final int SEG_TYPE = 2; + private static final int SEG_MODIFIER = 3; // modifier or subformat + + // Indices for type keywords + private static final int TYPE_NULL = 0; + private static final int TYPE_NUMBER = 1; + private static final int TYPE_DATE = 2; + private static final int TYPE_TIME = 3; + private static final int TYPE_CHOICE = 4; + + private static final String[] TYPE_KEYWORDS = { + "", + "number", + "date", + "time", + "choice" + }; + + // Indices for number modifiers + private static final int MODIFIER_DEFAULT = 0; // common in number and date-time + private static final int MODIFIER_CURRENCY = 1; + private static final int MODIFIER_PERCENT = 2; + private static final int MODIFIER_INTEGER = 3; + + private static final String[] NUMBER_MODIFIER_KEYWORDS = { + "", + "currency", + "percent", + "integer" + }; + + // Indices for date-time modifiers + private static final int MODIFIER_SHORT = 1; + private static final int MODIFIER_MEDIUM = 2; + private static final int MODIFIER_LONG = 3; + private static final int MODIFIER_FULL = 4; + + private static final String[] DATE_TIME_MODIFIER_KEYWORDS = { + "", + "short", + "medium", + "long", + "full" + }; + + // Date-time style values corresponding to the date-time modifiers. + private static final int[] DATE_TIME_MODIFIERS = { + DateFormat.DEFAULT, + DateFormat.SHORT, + DateFormat.MEDIUM, + DateFormat.LONG, + DateFormat.FULL, + }; private void makeFormat(int position, int offsetNumber, - StringBuffer[] segments) + StringBuilder[] textSegments) { + String[] segments = new String[textSegments.length]; + for (int i = 0; i < textSegments.length; i++) { + StringBuilder oneseg = textSegments[i]; + segments[i] = (oneseg != null) ? oneseg.toString() : ""; + } + // get the argument number int argumentNumber; try { - argumentNumber = Integer.parseInt(segments[1].toString()); // always unlocalized! + argumentNumber = Integer.parseInt(segments[SEG_INDEX]); // always unlocalized! } catch (NumberFormatException e) { - throw new IllegalArgumentException("can't parse argument number: " + segments[1]); + throw new IllegalArgumentException("can't parse argument number: " + + segments[SEG_INDEX], e); } if (argumentNumber < 0) { - throw new IllegalArgumentException("negative argument number: " + argumentNumber); + throw new IllegalArgumentException("negative argument number: " + + argumentNumber); } // resize format information arrays if necessary @@ -1374,120 +1440,129 @@ public class MessageFormat extends Format { } int oldMaxOffset = maxOffset; maxOffset = offsetNumber; - offsets[offsetNumber] = segments[0].length(); + offsets[offsetNumber] = segments[SEG_RAW].length(); argumentNumbers[offsetNumber] = argumentNumber; // now get the format Format newFormat = null; - switch (findKeyword(segments[2].toString(), typeList)) { - case 0: - break; - case 1: case 2:// number - switch (findKeyword(segments[3].toString(), modifierList)) { - case 0: // default; - newFormat = NumberFormat.getInstance(locale); - break; - case 1: case 2:// currency - newFormat = NumberFormat.getCurrencyInstance(locale); - break; - case 3: case 4:// percent - newFormat = NumberFormat.getPercentInstance(locale); - break; - case 5: case 6:// integer - newFormat = NumberFormat.getIntegerInstance(locale); - break; - default: // pattern - newFormat = new DecimalFormat(segments[3].toString(), DecimalFormatSymbols.getInstance(locale)); + if (segments[SEG_TYPE].length() != 0) { + int type = findKeyword(segments[SEG_TYPE], TYPE_KEYWORDS); + switch (type) { + case TYPE_NULL: + // Type "" is allowed. e.g., "{0,}", "{0,,}", and "{0,,#}" + // are treated as "{0}". break; - } - break; - case 3: case 4: // date - switch (findKeyword(segments[3].toString(), dateModifierList)) { - case 0: // default - newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale); - break; - case 1: case 2: // short - newFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale); - break; - case 3: case 4: // medium - newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale); - break; - case 5: case 6: // long - newFormat = DateFormat.getDateInstance(DateFormat.LONG, locale); - break; - case 7: case 8: // full - newFormat = DateFormat.getDateInstance(DateFormat.FULL, locale); - break; - default: - newFormat = new SimpleDateFormat(segments[3].toString(), locale); - break; - } - break; - case 5: case 6:// time - switch (findKeyword(segments[3].toString(), dateModifierList)) { - case 0: // default - newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale); - break; - case 1: case 2: // short - newFormat = DateFormat.getTimeInstance(DateFormat.SHORT, locale); - break; - case 3: case 4: // medium - newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale); + + case TYPE_NUMBER: + switch (findKeyword(segments[SEG_MODIFIER], NUMBER_MODIFIER_KEYWORDS)) { + case MODIFIER_DEFAULT: + newFormat = NumberFormat.getInstance(locale); + break; + case MODIFIER_CURRENCY: + newFormat = NumberFormat.getCurrencyInstance(locale); + break; + case MODIFIER_PERCENT: + newFormat = NumberFormat.getPercentInstance(locale); + break; + case MODIFIER_INTEGER: + newFormat = NumberFormat.getIntegerInstance(locale); + break; + default: // DecimalFormat pattern + try { + newFormat = new DecimalFormat(segments[SEG_MODIFIER], + DecimalFormatSymbols.getInstance(locale)); + } catch (IllegalArgumentException e) { + maxOffset = oldMaxOffset; + throw e; + } + break; + } break; - case 5: case 6: // long - newFormat = DateFormat.getTimeInstance(DateFormat.LONG, locale); + + case TYPE_DATE: + case TYPE_TIME: + int mod = findKeyword(segments[SEG_MODIFIER], DATE_TIME_MODIFIER_KEYWORDS); + if (mod >= 0 && mod < DATE_TIME_MODIFIER_KEYWORDS.length) { + if (type == TYPE_DATE) { + newFormat = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[mod], + locale); + } else { + newFormat = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[mod], + locale); + } + } else { + // SimpleDateFormat pattern + try { + newFormat = new SimpleDateFormat(segments[SEG_MODIFIER], locale); + } catch (IllegalArgumentException e) { + maxOffset = oldMaxOffset; + throw e; + } + } break; - case 7: case 8: // full - newFormat = DateFormat.getTimeInstance(DateFormat.FULL, locale); + + case TYPE_CHOICE: + try { + // ChoiceFormat pattern + newFormat = new ChoiceFormat(segments[SEG_MODIFIER]); + } catch (Exception e) { + maxOffset = oldMaxOffset; + throw new IllegalArgumentException("Choice Pattern incorrect: " + + segments[SEG_MODIFIER], e); + } break; + default: - newFormat = new SimpleDateFormat(segments[3].toString(), locale); - break; - } - break; - case 7: case 8:// choice - try { - newFormat = new ChoiceFormat(segments[3].toString()); - } catch (Exception e) { maxOffset = oldMaxOffset; - throw new IllegalArgumentException( - "Choice Pattern incorrect"); + throw new IllegalArgumentException("unknown format type: " + + segments[SEG_TYPE]); } - break; - default: - maxOffset = oldMaxOffset; - throw new IllegalArgumentException("unknown format type: " + - segments[2].toString()); } formats[offsetNumber] = newFormat; - segments[1].setLength(0); // throw away other segments - segments[2].setLength(0); - segments[3].setLength(0); } private static final int findKeyword(String s, String[] list) { - s = s.trim().toLowerCase(); for (int i = 0; i < list.length; ++i) { if (s.equals(list[i])) return i; } + + // Try trimmed lowercase. + String ls = s.trim().toLowerCase(Locale.ROOT); + if (ls != s) { + for (int i = 0; i < list.length; ++i) { + if (ls.equals(list[i])) + return i; + } + } return -1; } - private static final void copyAndFixQuotes( - String source, int start, int end, StringBuffer target) { + private static final void copyAndFixQuotes(String source, int start, int end, + StringBuilder target) { + boolean quoted = false; + for (int i = start; i < end; ++i) { char ch = source.charAt(i); if (ch == '{') { - target.append("'{'"); - } else if (ch == '}') { - target.append("'}'"); + if (!quoted) { + target.append('\''); + quoted = true; + } + target.append(ch); } else if (ch == '\'') { target.append("''"); } else { + if (quoted) { + target.append('\''); + quoted = false; + } target.append(ch); } } + if (quoted) { + target.append('\''); + } } /** diff --git a/src/share/classes/java/text/SimpleDateFormat.java b/src/share/classes/java/text/SimpleDateFormat.java index 9ae84f828d08bca6a3e43fd20b5e86ef2ef2eae8..fd2876aca056bc2bdf13279c613ff8aa4e961524 100644 --- a/src/share/classes/java/text/SimpleDateFormat.java +++ b/src/share/classes/java/text/SimpleDateFormat.java @@ -1662,6 +1662,81 @@ public class SimpleDateFormat extends DateFormat { return 0; } + /** + * Parses numeric forms of time zone offset, such as "hh:mm", and + * sets calb to the parsed value. + * + * @param text the text to be parsed + * @param start the character position to start parsing + * @param sign 1: positive; -1: negative + * @param count 0: 'Z' or "GMT+hh:mm" parsing; 1 - 3: the number of 'X's + * @param colon true - colon required between hh and mm; false - no colon required + * @param calb a CalendarBuilder in which the parsed value is stored + * @return updated parsed position, or its negative value to indicate a parsing error + */ + private int subParseNumericZone(String text, int start, int sign, int count, + boolean colon, CalendarBuilder calb) { + int index = start; + + parse: + try { + char c = text.charAt(index++); + // Parse hh + int hours; + if (!isDigit(c)) { + break parse; + } + hours = c - '0'; + c = text.charAt(index++); + if (isDigit(c)) { + hours = hours * 10 + (c - '0'); + } else { + // If no colon in RFC 822 or 'X' (ISO), two digits are + // required. + if (count > 0 || !colon) { + break parse; + } + --index; + } + if (hours > 23) { + break parse; + } + int minutes = 0; + if (count != 1) { + // Proceed with parsing mm + c = text.charAt(index++); + if (colon) { + if (c != ':') { + break parse; + } + c = text.charAt(index++); + } + if (!isDigit(c)) { + break parse; + } + minutes = c - '0'; + c = text.charAt(index++); + if (!isDigit(c)) { + break parse; + } + minutes = minutes * 10 + (c - '0'); + if (minutes > 59) { + break parse; + } + } + minutes += hours * 60; + calb.set(Calendar.ZONE_OFFSET, minutes * MILLIS_PER_MINUTE * sign) + .set(Calendar.DST_OFFSET, 0); + return index; + } catch (IndexOutOfBoundsException e) { + } + return 1 - index; // -(index - 1) + } + + private boolean isDigit(char c) { + return c >= '0' && c <= '9'; + } + /** * Private member function that converts the parsed date strings into * timeFields. Returns -start (for ParsePosition) if failed. @@ -1907,248 +1982,95 @@ public class SimpleDateFormat extends DateFormat { case PATTERN_ZONE_NAME: // 'z' case PATTERN_ZONE_VALUE: // 'Z' - // First try to parse generic forms such as GMT-07:00. Do this first - // in case localized TimeZoneNames contains the string "GMT" - // for a zone; in that case, we don't want to match the first three - // characters of GMT+/-hh:mm etc. { int sign = 0; - int offset; - - // For time zones that have no known names, look for strings - // of the form: - // GMT[+-]hours:minutes or - // GMT. - if ((text.length() - start) >= GMT.length() && - text.regionMatches(true, start, GMT, 0, GMT.length())) { - int num; - calb.set(Calendar.DST_OFFSET, 0); - pos.index = start + GMT.length(); - - try { // try-catch for "GMT" only time zone string - char c = text.charAt(pos.index); - if (c == '+') { - sign = 1; - } else if (c == '-') { - sign = -1; - } - } - catch(StringIndexOutOfBoundsException e) {} - - if (sign == 0) { /* "GMT" without offset */ - calb.set(Calendar.ZONE_OFFSET, 0); - return pos.index; + try { + char c = text.charAt(pos.index); + if (c == '+') { + sign = 1; + } else if (c == '-') { + sign = -1; } - - // Look for hours. - try { - char c = text.charAt(++pos.index); - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; - } - num = c - '0'; - - if (text.charAt(++pos.index) != ':') { - c = text.charAt(pos.index); - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; + if (sign == 0) { + // Try parsing a custom time zone "GMT+hh:mm" or "GMT". + if ((c == 'G' || c == 'g') + && (text.length() - start) >= GMT.length() + && text.regionMatches(true, start, GMT, 0, GMT.length())) { + pos.index = start + GMT.length(); + + if ((text.length() - pos.index) > 0) { + c = text.charAt(pos.index); + if (c == '+') { + sign = 1; + } else if (c == '-') { + sign = -1; + } } - num *= 10; - num += c - '0'; - pos.index++; - } - if (num > 23) { - --pos.index; - break parsing; - } - if (text.charAt(pos.index) != ':') { - break parsing; - } - // Look for minutes. - offset = num * 60; - c = text.charAt(++pos.index); - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; - } - num = c - '0'; - c = text.charAt(++pos.index); - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; - } - num *= 10; - num += c - '0'; + if (sign == 0) { /* "GMT" without offset */ + calb.set(Calendar.ZONE_OFFSET, 0) + .set(Calendar.DST_OFFSET, 0); + return pos.index; + } - if (num > 59) { - break parsing; - } - } catch (StringIndexOutOfBoundsException e) { - break parsing; - } - offset += num; - // Fall through for final processing below of 'offset' and 'sign'. - } else { - // If the first character is a sign, look for numeric timezones of - // the form [+-]hhmm as specified by RFC 822. Otherwise, check - // for named time zones by looking through the locale data from - // the TimeZoneNames strings. - try { - char c = text.charAt(pos.index); - if (c == '+') { - sign = 1; - } else if (c == '-') { - sign = -1; + // Parse the rest as "hh:mm" + int i = subParseNumericZone(text, ++pos.index, + sign, 0, true, calb); + if (i > 0) { + return i; + } + pos.index = -i; } else { - // Try parsing the text as a time zone name (abbr). + // Try parsing the text as a time zone + // name or abbreviation. int i = subParseZoneString(text, pos.index, calb); - if (i != 0) { + if (i > 0) { return i; } - break parsing; - } - - // Parse the text as an RFC 822 time zone string. This code is - // actually a little more permissive than RFC 822. It will - // try to do its best with numbers that aren't strictly 4 - // digits long. - - // Look for hh. - int hours = 0; - c = text.charAt(++pos.index); - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; + pos.index = -i; } - hours = c - '0'; - c = text.charAt(++pos.index); - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; - } - hours *= 10; - hours += c - '0'; - - if (hours > 23) { - break parsing; - } - - // Look for mm. - int minutes = 0; - c = text.charAt(++pos.index); - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; - } - minutes = c - '0'; - c = text.charAt(++pos.index); - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; - } - minutes *= 10; - minutes += c - '0'; - - if (minutes > 59) { - break parsing; + } else { + // Parse the rest as "hhmm" (RFC 822) + int i = subParseNumericZone(text, ++pos.index, + sign, 0, false, calb); + if (i > 0) { + return i; } - - offset = hours * 60 + minutes; - } catch (StringIndexOutOfBoundsException e) { - break parsing; + pos.index = -i; } - } - - // Do the final processing for both of the above cases. We only - // arrive here if the form GMT+/-... or an RFC 822 form was seen. - if (sign != 0) { - offset *= MILLIS_PER_MINUTE * sign; - calb.set(Calendar.ZONE_OFFSET, offset).set(Calendar.DST_OFFSET, 0); - return ++pos.index; + } catch (IndexOutOfBoundsException e) { } } break parsing; case PATTERN_ISO_ZONE: // 'X' { - int sign = 0; - int offset = 0; - - iso8601: { - try { - char c = text.charAt(pos.index); - if (c == 'Z') { - calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0); - return ++pos.index; - } - - // parse text as "+/-hh[[:]mm]" based on count - if (c == '+') { - sign = 1; - } else if (c == '-') { - sign = -1; - } - // Look for hh. - int hours = 0; - c = text.charAt(++pos.index); - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; - } - hours = c - '0'; - c = text.charAt(++pos.index); - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; - } - hours *= 10; - hours += c - '0'; - if (hours > 23) { - break parsing; - } - - if (count == 1) { // "X" - offset = hours * 60; - break iso8601; - } - - c = text.charAt(++pos.index); - // Skip ':' if "XXX" - if (c == ':') { - if (count == 2) { - break parsing; - } - c = text.charAt(++pos.index); - } else { - if (count == 3) { - // missing ':' - break parsing; - } - } - - // Look for mm. - int minutes = 0; - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; - } - minutes = c - '0'; - c = text.charAt(++pos.index); - if (c < '0' || c > '9') { /* must be from '0' to '9'. */ - break parsing; - } - minutes *= 10; - minutes += c - '0'; - - if (minutes > 59) { - break parsing; - } - - offset = hours * 60 + minutes; - } catch (StringIndexOutOfBoundsException e) { - break parsing; - } + if ((text.length() - pos.index) <= 0) { + break parsing; } - // Do the final processing for both of the above cases. We only - // arrive here if the form GMT+/-... or an RFC 822 form was seen. - if (sign != 0) { - offset *= MILLIS_PER_MINUTE * sign; - calb.set(Calendar.ZONE_OFFSET, offset).set(Calendar.DST_OFFSET, 0); + int sign = 0; + char c = text.charAt(pos.index); + if (c == 'Z') { + calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0); return ++pos.index; } + + // parse text as "+/-hh[[:]mm]" based on count + if (c == '+') { + sign = 1; + } else if (c == '-') { + sign = -1; + } else { + ++pos.index; + break parsing; + } + int i = subParseNumericZone(text, ++pos.index, sign, count, + count == 3, calb); + if (i > 0) { + return i; + } + pos.index = -i; } break parsing; diff --git a/src/share/classes/java/util/Locale.java b/src/share/classes/java/util/Locale.java index ecaa9cca68a4a35feeb266d6f06194e2a4949e53..1f0fbba1eaea8214b94ade566cddc02b94b0830b 100644 --- a/src/share/classes/java/util/Locale.java +++ b/src/share/classes/java/util/Locale.java @@ -1449,10 +1449,15 @@ public final class Locale implements Cloneable, Serializable { * three-letter language abbreviation is not available for this locale. */ public String getISO3Language() throws MissingResourceException { - String language3 = getISO3Code(_baseLocale.getLanguage(), LocaleISOData.isoLanguageTable); + String lang = _baseLocale.getLanguage(); + if (lang.length() == 3) { + return lang; + } + + String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable); if (language3 == null) { throw new MissingResourceException("Couldn't find 3-letter language code for " - + _baseLocale.getLanguage(), "FormatData_" + toString(), "ShortLanguage"); + + lang, "FormatData_" + toString(), "ShortLanguage"); } return language3; } diff --git a/src/share/classes/javax/sound/midi/MidiSystem.java b/src/share/classes/javax/sound/midi/MidiSystem.java index d3ce81e22939160461f62e9f22014999d35bb259..b2a47dc96540cbf76878015be43f5a941706e9f5 100644 --- a/src/share/classes/javax/sound/midi/MidiSystem.java +++ b/src/share/classes/javax/sound/midi/MidiSystem.java @@ -310,7 +310,7 @@ public class MidiSystem { } else { transmitter = device.getTransmitter(); } - if (!(transmitter instanceof MidiDeviceReceiver)) { + if (!(transmitter instanceof MidiDeviceTransmitter)) { transmitter = new MidiDeviceTransmitterEnvelope(device, transmitter); } return transmitter; diff --git a/src/share/classes/javax/swing/JSlider.java b/src/share/classes/javax/swing/JSlider.java index 156b9e4fb99ed32700204703856a0af14d236e91..8d188b95bf8d2a42b639d9aef2daeff0d1b179c4 100644 --- a/src/share/classes/javax/swing/JSlider.java +++ b/src/share/classes/javax/swing/JSlider.java @@ -40,7 +40,8 @@ import java.beans.*; /** * A component that lets the user graphically select a value by sliding - * a knob within a bounded interval. + * a knob within a bounded interval. The knob is always positioned + * at the points that match integer values within the specified interval. ** The slider can show both * major tick marks, and minor tick marks between the major ones. The number of diff --git a/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java b/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java index b26f226c043a32df235121c29515219f36c76ea6..a57638e39ebb5c01121b679aac07017351c91a32 100644 --- a/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java +++ b/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java @@ -908,6 +908,14 @@ public class BasicSpinnerUI extends SpinnerUI int height = parent.getHeight(); Insets insets = parent.getInsets(); + + if (nextButton == null && previousButton == null) { + setBounds(editor, insets.left, insets.top, width - insets.left - insets.right, + height - insets.top - insets.bottom); + + return; + } + Dimension nextD = preferredSize(nextButton); Dimension previousD = preferredSize(previousButton); int buttonsWidth = Math.max(nextD.width, previousD.width); diff --git a/src/share/classes/sun/awt/FontConfiguration.java b/src/share/classes/sun/awt/FontConfiguration.java index a2593cc2ff5ea98ebcfdc4e96b92ff5c8ab9736c..ba8f6e56a014f0b9a254cf917361293e572541de 100644 --- a/src/share/classes/sun/awt/FontConfiguration.java +++ b/src/share/classes/sun/awt/FontConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, 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 @@ -37,10 +37,10 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; -import java.util.Iterator; import java.util.Locale; import java.util.Map.Entry; import java.util.Properties; @@ -329,6 +329,8 @@ public abstract class FontConfiguration { * tables. */ public static void saveBinary(OutputStream out) throws IOException { + sanityCheck(); + DataOutputStream dataOut = new DataOutputStream(out); writeShortTable(dataOut, head); writeShortTable(dataOut, table_scriptIDs); @@ -350,7 +352,6 @@ public abstract class FontConfiguration { if (verbose) { dump(); } - sanityCheck(); } //private static boolean loadingProperties; @@ -1343,6 +1344,11 @@ public abstract class FontConfiguration { private static short[] table_stringIDs; private static char[] table_stringTable; + /** + * Checks consistencies of complied fontconfig data. This method + * is called only at the build-time from + * build.tools.compilefontconfig.CompileFontConfig. + */ private static void sanityCheck() { int errors = 0; @@ -1358,12 +1364,20 @@ public abstract class FontConfiguration { //componentFontNameID starts from "1" for (int ii = 1; ii < table_filenames.length; ii++) { if (table_filenames[ii] == -1) { - System.out.println("\n Warning: " - + "
entry is missing!!!"); - if (!osName.contains("Linux")) { + // The corresponding finename entry for a component + // font name is mandatory on Windows, but it's + // optional on Solaris and Linux. + if (osName.contains("Windows")) { + System.err.println("\n Error: entry is missing!!!"); errors++; + } else { + if (verbose && !isEmpty(table_filenames)) { + System.err.println("\n Note: 'filename' entry is undefined for \"" + + getString(table_componentFontNameIDs[ii]) + + "\""); + } } } } @@ -1382,7 +1396,7 @@ public abstract class FontConfiguration { int jj = iii * NUM_STYLES + iij; short ffid = table_scriptFonts[fid + jj]; if (ffid == 0) { - System.out.println("\n Error: <" + System.err.println("\n Error: <" + getFontName(iii) + "." + getStyleName(iij) + "." + getString(table_scriptIDs[ii]) @@ -1402,7 +1416,7 @@ public abstract class FontConfiguration { script.contains("symbol")) { continue; } - System.out.println("\nError: " + System.err.println("\nError: " + " entry is missing!!!"); @@ -1411,11 +1425,19 @@ public abstract class FontConfiguration { } } if (errors != 0) { - System.out.println("!!THERE ARE " + errors + " ERROR(S) IN " + System.err.println("!!THERE ARE " + errors + " ERROR(S) IN " + "THE FONTCONFIG FILE, PLEASE CHECK ITS CONTENT!!\n"); System.exit(1); + } + } + private static boolean isEmpty(short[] a) { + for (short s : a) { + if (s != -1) { + return false; + } } + return true; } //dump the fontconfig data tables @@ -1652,20 +1674,16 @@ public abstract class FontConfiguration { private static void writeShortTable(DataOutputStream out, short[] data) throws IOException { - for (int i = 0; i < data.length; i++) { - out.writeShort(data[i]); + for (short val : data) { + out.writeShort(val); } } - private static short[] toList(HashMap map) { + private static short[] toList(HashMap map) { short[] list = new short[map.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = -1; - } - Iterator iterator = map.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - list[entry.getValue().shortValue()] = getStringID(entry.getKey()); + Arrays.fill(list, (short) -1); + for (Entry entry : map.entrySet()) { + list[entry.getValue()] = getStringID(entry.getKey()); } return list; } @@ -1763,25 +1781,19 @@ public abstract class FontConfiguration { int len = table_scriptIDs.length + scriptFonts.size() * 20; table_scriptFonts = new short[len]; - Iterator iterator = scriptAllfonts.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - table_scriptFonts[entry.getKey().intValue()] = (short)entry.getValue().shortValue(); + for (Entry entry : scriptAllfonts.entrySet()) { + table_scriptFonts[entry.getKey().intValue()] = entry.getValue(); } int off = table_scriptIDs.length; - iterator = scriptFonts.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); + for (Entry entry : scriptFonts.entrySet()) { table_scriptFonts[entry.getKey().intValue()] = (short)-off; Short[] v = entry.getValue(); - int i = 0; - while (i < 20) { + for (int i = 0; i < 20; i++) { if (v[i] != null) { - table_scriptFonts[off++] = v[i].shortValue(); + table_scriptFonts[off++] = v[i]; } else { table_scriptFonts[off++] = 0; } - i++; } } @@ -1792,9 +1804,7 @@ public abstract class FontConfiguration { //(3) sequences elcID -> XXXX[1|5] -> scriptID[] head[INDEX_sequences] = (short)(head[INDEX_elcIDs] + table_elcIDs.length); table_sequences = new short[elcIDs.size() * NUM_FONTS]; - iterator = sequences.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); + for (Entry entry : sequences.entrySet()) { //table_sequences[entry.getKey().intValue()] = (short)-off; int k = entry.getKey().intValue(); short[] v = entry.getValue(); @@ -1827,31 +1837,24 @@ public abstract class FontConfiguration { //(6)componentFontNameID -> filenameID head[INDEX_filenames] = (short)(head[INDEX_componentFontNameIDs] + table_componentFontNameIDs.length); table_filenames = new short[table_componentFontNameIDs.length]; - for (int i = 0; i < table_filenames.length; i++) { - table_filenames[i] = -1; - } - iterator = filenames.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - table_filenames[entry.getKey().shortValue()] = entry.getValue().shortValue(); + Arrays.fill(table_filenames, (short) -1); + + for (Entry entry : filenames.entrySet()) { + table_filenames[entry.getKey()] = entry.getValue(); } //(7)scriptID-> awtfontpath //the paths are stored as scriptID -> stringID in awtfontpahts head[INDEX_awtfontpaths] = (short)(head[INDEX_filenames] + table_filenames.length); table_awtfontpaths = new short[table_scriptIDs.length]; - iterator = awtfontpaths.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - table_awtfontpaths[entry.getKey().shortValue()] = entry.getValue().shortValue(); + for (Entry entry : awtfontpaths.entrySet()) { + table_awtfontpaths[entry.getKey()] = entry.getValue(); } //(8)exclusions head[INDEX_exclusions] = (short)(head[INDEX_awtfontpaths] + table_awtfontpaths.length); table_exclusions = new short[scriptIDs.size()]; - iterator = exclusions.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); + for (Entry entry : exclusions.entrySet()) { int[] exI = entry.getValue(); char[] exC = new char[exI.length * 2]; int j = 0; @@ -1859,17 +1862,15 @@ public abstract class FontConfiguration { exC[j++] = (char) (exI[i] >> 16); exC[j++] = (char) (exI[i] & 0xffff); } - table_exclusions[entry.getKey().shortValue()] = getStringID(new String (exC)); + table_exclusions[entry.getKey()] = getStringID(new String (exC)); } //(9)proportionals head[INDEX_proportionals] = (short)(head[INDEX_exclusions] + table_exclusions.length); table_proportionals = new short[proportionals.size() * 2]; - iterator = proportionals.entrySet().iterator(); int j = 0; - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - table_proportionals[j++] = entry.getKey().shortValue(); - table_proportionals[j++] = entry.getValue().shortValue(); + for (Entry entry : proportionals.entrySet()) { + table_proportionals[j++] = entry.getKey(); + table_proportionals[j++] = entry.getValue(); } //(10) see (1) for info, the only difference is "xxx.motif" @@ -1878,22 +1879,18 @@ public abstract class FontConfiguration { len = table_scriptIDs.length + scriptFontsMotif.size() * 20; table_scriptFontsMotif = new short[len]; - iterator = scriptAllfontsMotif.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); + for (Entry entry : scriptAllfontsMotif.entrySet()) { table_scriptFontsMotif[entry.getKey().intValue()] = - (short)entry.getValue().shortValue(); + (short)entry.getValue(); } off = table_scriptIDs.length; - iterator = scriptFontsMotif.entrySet().iterator(); - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); + for (Entry entry : scriptFontsMotif.entrySet()) { table_scriptFontsMotif[entry.getKey().intValue()] = (short)-off; Short[] v = entry.getValue(); int i = 0; while (i < 20) { if (v[i] != null) { - table_scriptFontsMotif[off++] = v[i].shortValue(); + table_scriptFontsMotif[off++] = v[i]; } else { table_scriptFontsMotif[off++] = 0; } @@ -1907,12 +1904,10 @@ public abstract class FontConfiguration { //(11)short[] alphabeticSuffix head[INDEX_alphabeticSuffix] = (short)(head[INDEX_scriptFontsMotif] + table_scriptFontsMotif.length); table_alphabeticSuffix = new short[alphabeticSuffix.size() * 2]; - iterator = alphabeticSuffix.entrySet().iterator(); j = 0; - while (iterator.hasNext()) { - Entry entry = (Entry )iterator.next(); - table_alphabeticSuffix[j++] = entry.getKey().shortValue(); - table_alphabeticSuffix[j++] = entry.getValue().shortValue(); + for (Entry entry : alphabeticSuffix.entrySet()) { + table_alphabeticSuffix[j++] = entry.getKey(); + table_alphabeticSuffix[j++] = entry.getValue(); } //(15)short[] fallbackScriptIDs; just put the ID in head diff --git a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c index 3128efe252e120789feaadfcfe75dd2a5a9082a8..73ec25671d1e39bfc18f1a5e000eed14123c751a 100644 --- a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c +++ b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c @@ -137,41 +137,43 @@ void getALSAVersion(char* buffer, int len) { file = fopen(ALSA_VERSION_PROC_FILE, "r"); ALSAVersionString[0] = 0; if (file) { - fgets(ALSAVersionString, ALSAVersionString_LENGTH, file); - // parse for version number - totalLen = strlen(ALSAVersionString); - inVersionString = FALSE; - len = 0; - curr = 0; - while (curr < totalLen) { - if (!inVersionString) { - // is this char the beginning of a version string ? - if (ALSAVersionString[curr] >= '0' - && ALSAVersionString[curr] <= '9') { - inVersionString = TRUE; + if (NULL != fgets(ALSAVersionString, ALSAVersionString_LENGTH, file)) { + // parse for version number + totalLen = strlen(ALSAVersionString); + inVersionString = FALSE; + len = 0; + curr = 0; + while (curr < totalLen) { + if (!inVersionString) { + // is this char the beginning of a version string ? + if (ALSAVersionString[curr] >= '0' + && ALSAVersionString[curr] <= '9') { + inVersionString = TRUE; + } } - } - if (inVersionString) { - // the version string ends with white space - if (ALSAVersionString[curr] <= 32) { - break; - } - if (curr != len) { - // copy this char to the beginning of the string - ALSAVersionString[len] = ALSAVersionString[curr]; + if (inVersionString) { + // the version string ends with white space + if (ALSAVersionString[curr] <= 32) { + break; + } + if (curr != len) { + // copy this char to the beginning of the string + ALSAVersionString[len] = ALSAVersionString[curr]; + } + len++; } - len++; + curr++; } - curr++; - } - // remove trailing dots - while ((len > 0) && (ALSAVersionString[len - 1] == '.')) { - len--; + // remove trailing dots + while ((len > 0) && (ALSAVersionString[len - 1] == '.')) { + len--; + } + // null terminate + ALSAVersionString[len] = 0; } - // null terminate - ALSAVersionString[len] = 0; + fclose(file); + hasGottenALSAVersion = TRUE; } - hasGottenALSAVersion = TRUE; } strncpy(buffer, ALSAVersionString, len); } diff --git a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c index a2277bdb6a0b3535b3e18bc4d13693b9c48fd2b1..db4a30ca330a0a9114b85c6ce69fbfbab2a75b0a 100644 --- a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c +++ b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c @@ -32,6 +32,9 @@ #include #include "PlatformMidi.h" #include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h" +#if defined(i586) +#include +#endif /* * Helper methods @@ -73,9 +76,38 @@ char* MIDI_IN_GetErrorStr(INT32 err) { return (char*) getErrorStr(err); } - INT32 MIDI_IN_GetNumDevices() { +/* Workaround for 6842956: 32bit app on 64bit linux + * gets assertion failure trying to open midiIn ports. + * Untill the issue is fixed in ALSA + * (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4807) + * report no midi in devices in the configuration. + */ +#if defined(i586) + static int jre32onlinux64 = -1; + if (jre32onlinux64 < 0) { + jre32onlinux64 = 0; + /* The workaround may be disabled setting "JAVASOUND_ENABLE_MIDIIN" + * environment variable. + */ + if (getenv("JAVASOUND_ENABLE_MIDIIN") == NULL) { + struct utsname u; + jre32onlinux64 = 0; + if (uname(&u) == 0) { + if (strstr(u.machine, "64") != NULL) { + TRACE0("jre32 on linux64 detected - report no midiIn devices\n"); + jre32onlinux64 = 1; + } + } + } + } + if (jre32onlinux64) { + return 0; + } +#endif + TRACE0("MIDI_IN_GetNumDevices()\n"); + return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT); } diff --git a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c index 74af23ef0420f86c025d0ee9df0e90067834feb3..7d2ac11923442835a582038a4fd7e45de2a1893d 100644 --- a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c +++ b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, 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 @@ -372,7 +372,7 @@ INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex, snd_rawmidi_t* native_handle; snd_midi_event_t* event_parser = NULL; int err; - UINT32 deviceID; + UINT32 deviceID = 0; char devicename[100]; #ifdef ALSA_MIDI_USE_PLUGHW int usePlugHw = 1; diff --git a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c index 58ca8abfcc2980a01998e3d2551d1cccc3fd2974..fb2ba3c5da36a940d8d7a7e741bdfac65b44cf85 100644 --- a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c +++ b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, 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 @@ -127,7 +127,7 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre int ret; int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc; int origSampleSizeInBytes, origSignificantBits; - int channels, minChannels, maxChannels; + unsigned int channels, minChannels, maxChannels; int rate, bitIndex; for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE; @@ -152,7 +152,6 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre } } snd_pcm_hw_params_get_format_mask(hwParams, formatMask); -#ifdef ALSA_PCM_NEW_HW_PARAMS_API if (ret == 0) { ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels); if (ret != 0) { @@ -165,13 +164,6 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret); } } -#else - minChannels = snd_pcm_hw_params_get_channels_min(hwParams); - maxChannels = snd_pcm_hw_params_get_channels_max(hwParams); - if (minChannels > maxChannels) { - ERROR2("MinChannels=%d, maxChannels=%d\n", minChannels, maxChannels); - } -#endif // since we queried the hw: device, for many soundcards, it will only // report the maximum number of channels (which is the only way to talk @@ -222,7 +214,7 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre } else { for (channels = minChannels; channels <= maxChannels; channels++) { DAUDIO_AddAudioFormat(creator, significantBits, - (channels < 0)?-1:(sampleSizeInBytes * channels), + sampleSizeInBytes * channels, channels, rate, enc, isSigned, isBigEndian); } @@ -254,7 +246,7 @@ typedef struct tag_AlsaPcmInfo { snd_pcm_sw_params_t* swParams; int bufferSizeInBytes; int frameSize; // storage size in Bytes - int periods; + unsigned int periods; snd_pcm_uframes_t periodSize; #ifdef GET_POSITION_METHOD2 // to be used exclusively by getBytePosition! @@ -305,8 +297,8 @@ int setHWParams(AlsaPcmInfo* info, int channels, int bufferSizeInFrames, snd_pcm_format_t format) { - unsigned int rrate; - int ret, dir, periods, periodTime; + unsigned int rrate, periodTime, periods; + int ret, dir; snd_pcm_uframes_t alsaBufferSizeInFrames = (snd_pcm_uframes_t) bufferSizeInFrames; /* choose all parameters */ @@ -335,12 +327,8 @@ int setHWParams(AlsaPcmInfo* info, } /* set the stream rate */ rrate = (int) (sampleRate + 0.5f); -#ifdef ALSA_PCM_NEW_HW_PARAMS_API dir = 0; ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, &rrate, &dir); -#else - ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, rrate, 0); -#endif if (ret < 0) { ERROR2("Rate %dHz not available for playback: %s\n", (int) (sampleRate+0.5f), snd_strerror(ret)); return FALSE; @@ -350,12 +338,7 @@ int setHWParams(AlsaPcmInfo* info, return FALSE; } /* set the buffer time */ -#ifdef ALSA_PCM_NEW_HW_PARAMS_API - ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, &alsaBufferSizeInFrames); -#else - ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, alsaBufferSizeInFrames); -#endif if (ret < 0) { ERROR2("Unable to set buffer size to %d frames: %s\n", (int) alsaBufferSizeInFrames, snd_strerror(ret)); @@ -366,12 +349,7 @@ int setHWParams(AlsaPcmInfo* info, if (bufferSizeInFrames > 1024) { dir = 0; periodTime = DEFAULT_PERIOD_TIME; -#ifdef ALSA_PCM_NEW_HW_PARAMS_API ret = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, &periodTime, &dir); -#else - periodTime = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, periodTime, &dir); - ret = periodTime; -#endif if (ret < 0) { ERROR2("Unable to set period time to %d: %s\n", DEFAULT_PERIOD_TIME, snd_strerror(ret)); return FALSE; @@ -380,12 +358,7 @@ int setHWParams(AlsaPcmInfo* info, /* set the period count for very small buffer sizes to 2 */ dir = 0; periods = 2; -#ifdef ALSA_PCM_NEW_HW_PARAMS_API ret = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, &periods, &dir); -#else - periods = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, periods, &dir); - ret = periods; -#endif if (ret < 0) { ERROR2("Unable to set period count to %d: %s\n", /*periods*/ 2, snd_strerror(ret)); return FALSE; @@ -421,12 +394,6 @@ int setSWParams(AlsaPcmInfo* info) { ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret)); return FALSE; } - /* align all transfers to 1 sample */ - ret = snd_pcm_sw_params_set_xfer_align(info->handle, info->swParams, 1); - if (ret < 0) { - ERROR1("Unable to set transfer align: %s\n", snd_strerror(ret)); - return FALSE; - } /* write the parameters to the playback device */ ret = snd_pcm_sw_params(info->handle, info->swParams); if (ret < 0) { @@ -448,7 +415,6 @@ void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource, int ret = 0; AlsaPcmInfo* info = NULL; /* snd_pcm_uframes_t is 64 bit on 64-bit systems */ - snd_pcm_uframes_t alsaPeriodSize = 0; snd_pcm_uframes_t alsaBufferSizeInFrames = 0; @@ -484,21 +450,13 @@ void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource, bufferSizeInBytes / frameSize, format)) { info->frameSize = frameSize; -#ifdef ALSA_PCM_NEW_HW_PARAMS_API - ret = snd_pcm_hw_params_get_period_size(info->hwParams, &alsaPeriodSize, &dir); - info->periodSize = (int) alsaPeriodSize; + ret = snd_pcm_hw_params_get_period_size(info->hwParams, &info->periodSize, &dir); if (ret < 0) { ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret)); } snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir); snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames); info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize; -#else - info->periodSize = snd_pcm_hw_params_get_period_size(info->hwParams, &dir); - info->periods = snd_pcm_hw_params_get_periods(info->hwParams, &dir); - info->bufferSizeInBytes = snd_pcm_hw_params_get_buffer_size(info->hwParams) * frameSize; - ret = 0; -#endif TRACE3(" DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n", (int) info->periodSize, info->periods, info->bufferSizeInBytes); } diff --git a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h index c8d920f8de6b61a115a7faefa6c18e3230d390bb..ca911d2f486d918cd983eef7ea06690cbdd82383 100644 --- a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h +++ b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, 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 @@ -24,6 +24,7 @@ */ // define this with a later version of ALSA than 0.9.0rc3 +// (starting from 1.0.0 it became default behaviour) #define ALSA_PCM_NEW_HW_PARAMS_API #include #include "Utilities.h" diff --git a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_Ports.c b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_Ports.c index 465ecadf0f92b1de9052189706d9db49be0d62f6..0db0e6c4b53ae1f994a8c9a96d10e9d3595312f5 100644 --- a/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_Ports.c +++ b/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_Ports.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, 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 @@ -380,7 +380,7 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) { void* controls[10]; int numControls; char* portName; - int isPlayback; + int isPlayback = 0; int isMono; int isStereo; char* type; diff --git a/src/windows/lib/tzmappings b/src/windows/lib/tzmappings index bbc3ca09ce23c0baebc929c26bbd0ddc05a628ee..7f6f0d36052fc4ab7f514482cb944c1205a1d391 100644 --- a/src/windows/lib/tzmappings +++ b/src/windows/lib/tzmappings @@ -188,5 +188,6 @@ UTC-02:920,920::GMT-0200: UTC-11:921,921::GMT-1100: Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar: Venezuela Standard Time:923,923::America/Caracas: -Western Brazilian Standard Time:924,924:BR:America/Rio_Branco: -Armenian Standard Time:925,925:AM:Asia/Yerevan: +Magadan Standard Time:924,924::Asia/Magadan: +Western Brazilian Standard Time:925,925:BR:America/Rio_Branco: +Armenian Standard Time:926,926:AM:Asia/Yerevan: diff --git a/test/java/text/Format/DateFormat/ISO8601ZoneTest.java b/test/java/text/Format/DateFormat/ISO8601ZoneTest.java index 2179948a849c2c0373d89163a9a1c060546a75d9..2a5c24125855398be4c64ae3c052ebbcc33bac19 100644 --- a/test/java/text/Format/DateFormat/ISO8601ZoneTest.java +++ b/test/java/text/Format/DateFormat/ISO8601ZoneTest.java @@ -60,48 +60,51 @@ public class ISO8601ZoneTest { "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", }; + // badData[][0] - format + // badData[][1] - (bad) text to be parsed + // badData[][2] - subtext at the end of which a parse error is detected static final String[][] badData = { - { "X", "1" }, - { "X", "+1" }, - { "X", "-2" }, - { "X", "-24" }, - { "X", "+24" }, - - { "XX", "9" }, - { "XX", "23" }, - { "XX", "234" }, - { "XX", "3456" }, - { "XX", "23456" }, - { "XX", "+1" }, - { "XX", "-12" }, - { "XX", "+123" }, - { "XX", "-12:34" }, - { "XX", "+12:34" }, - { "XX", "-2423" }, - { "XX", "+2423" }, - { "XX", "-1260" }, - { "XX", "+1260" }, - - { "XXX", "9" }, - { "XXX", "23" }, - { "XXX", "234" }, - { "XXX", "3456" }, - { "XXX", "23456" }, - { "XXX", "2:34" }, - { "XXX", "12:4" }, - { "XXX", "12:34" }, - { "XXX", "-1" }, - { "XXX", "+1" }, - { "XXX", "-12" }, - { "XXX", "+12" }, - { "XXX", "-123" }, - { "XXX", "+123" }, - { "XXX", "-1234" }, - { "XXX", "+1234" }, - { "XXX", "+24:23" }, - { "XXX", "+12:60" }, - { "XXX", "+1:23" }, - { "XXX", "+12:3" }, + { "X", "1", "1" }, + { "X", "+1", "+1" }, + { "X", "-2", "-2" }, + { "X", "-24", "-2" }, + { "X", "+24", "+2" }, + + { "XX", "9", "9" }, + { "XX", "23", "2" }, + { "XX", "234", "2" }, + { "XX", "3456", "3" }, + { "XX", "23456", "2" }, + { "XX", "+1", "+1" }, + { "XX", "-12", "-12" }, + { "XX", "+123", "+123" }, + { "XX", "-12:34", "-12" }, + { "XX", "+12:34", "+12" }, + { "XX", "-2423", "-2" }, + { "XX", "+2423", "+2" }, + { "XX", "-1260", "-126" }, + { "XX", "+1260", "+126" }, + + { "XXX", "9", "9" }, + { "XXX", "23", "2" }, + { "XXX", "234", "2" }, + { "XXX", "3456", "3" }, + { "XXX", "23456", "2" }, + { "XXX", "2:34", "2" }, + { "XXX", "12:4", "1" }, + { "XXX", "12:34", "1" }, + { "XXX", "-1", "-1" }, + { "XXX", "+1", "+1" }, + { "XXX", "-12", "-12" }, + { "XXX", "+12", "+12" }, + { "XXX", "-123", "-12" }, + { "XXX", "+123", "+12" }, + { "XXX", "-1234", "-12" }, + { "XXX", "+1234", "+12" }, + { "XXX", "+24:23", "+2" }, + { "XXX", "+12:60", "+12:6" }, + { "XXX", "+1:23", "+1" }, + { "XXX", "+12:3", "+12:3" }, }; static String[] badFormats = { @@ -110,6 +113,8 @@ public class ISO8601ZoneTest { public static void main(String[] args) throws Exception { TimeZone tz = TimeZone.getDefault(); + Locale loc = Locale.getDefault(); + Locale.setDefault(Locale.US); try { for (int i = 0; i < formatData.length; i++) { @@ -128,7 +133,7 @@ public class ISO8601ZoneTest { } for (String[] d : badData) { - badDataParsing(d[0], d[1]); + badDataParsing(d[0], d[1], d[2].length()); } for (String fmt : badFormats) { @@ -136,6 +141,7 @@ public class ISO8601ZoneTest { } } finally { TimeZone.setDefault(tz); + Locale.setDefault(loc); } } @@ -188,15 +194,24 @@ public class ISO8601ZoneTest { } - static void badDataParsing(String fmt, String text) { + static void badDataParsing(String fmt, String text, int expectedErrorIndex) { + SimpleDateFormat sdf = new SimpleDateFormat(fmt); try { - SimpleDateFormat sdf = new SimpleDateFormat(fmt); sdf.parse(text); throw new RuntimeException("didn't throw an exception: fmt=" + fmt + ", text=" + text); } catch (ParseException e) { // OK } + + ParsePosition pos = new ParsePosition(0); + Date d = sdf.parse(text, pos); + int errorIndex = pos.getErrorIndex(); + if (d != null || errorIndex != expectedErrorIndex) { + throw new RuntimeException("Bad error index=" + errorIndex + + ", expected=" + expectedErrorIndex + + ", fmt=" + fmt + ", text=" + text); + } } static void badFormat(String fmt) { diff --git a/test/java/text/Format/MessageFormat/Bug7003643.java b/test/java/text/Format/MessageFormat/Bug7003643.java new file mode 100644 index 0000000000000000000000000000000000000000..aeb722cac17203193811133c8b0ece4dc7d19528 --- /dev/null +++ b/test/java/text/Format/MessageFormat/Bug7003643.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2010, 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 7003643 + * @summary Make sure MessageFormat.toPattern produces correct quoting. (SPI part is tested in PluggableLocale tests.) + */ + +import java.text.*; +import java.util.*; + +public class Bug7003643 { + private static final int N = 5; + + private static final String[] elements = { + "'{'", "'{", "{", "''", "}", "a", "'", + }; + + public static void main(String[] args) { + Random rand = new Random(); + int count = 0; + int max = (int) (Math.pow((double)elements.length, (double)N)/0.52); + while (count < max) { + // Create a random pattern. If the produced pattern is + // valid, then proceed with the round-trip testing. + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < N; i++) { + sb.append(elements[rand.nextInt(elements.length)]); + } + String pattern = sb.toString(); + MessageFormat mf = null; + try { + mf = new MessageFormat(pattern); + } catch (IllegalArgumentException e) { + // bad pattern data + } + if (mf == null) { + continue; + } + count++; + String res1 = MessageFormat.format(pattern, 123); + String toPattern = mf.toPattern(); + String res2 = MessageFormat.format(toPattern, 123); + if (!res1.equals(res2)) { + String s = String.format("Failed%n pattern=\"%s\" => result=\"%s\"%n" + + " toPattern()=\"%s\" => result=\"%s\"%n", + pattern, res1, toPattern, res2); + throw new RuntimeException(s); + } + } + } +} diff --git a/test/java/util/Locale/LocaleTest.java b/test/java/util/Locale/LocaleTest.java index af00c6bba6cd83df197aca1a7cd62a77fb3252be..0c21a8ef3544b870269a16349a482425dafb5e80 100644 --- a/test/java/util/Locale/LocaleTest.java +++ b/test/java/util/Locale/LocaleTest.java @@ -24,7 +24,8 @@ * @test * @bug 4052404 4052440 4084688 4092475 4101316 4105828 4107014 4107953 4110613 * 4118587 4118595 4122371 4126371 4126880 4135316 4135752 4139504 4139940 4143951 - * 4147315 4147317 4147552 4335196 4778440 5010672 6475525 6544471 6627549 6786276 + * 4147315 4147317 4147552 4335196 4778440 4940539 5010672 6475525 6544471 6627549 + * 6786276 * @summary test Locales */ /* @@ -895,17 +896,28 @@ test commented out pending API-change approval } /** - * @bug 4147317 - * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes. - * Should throw an exception for unknown locales + * @bug 4147317 4940539 + * java.util.Locale.getISO3Language() works wrong for non ISO-639 codes. + * Should throw an exception for unknown locales, except they have three + * letter language codes. */ public void Test4147317() { - // Try with codes that are the wrong length but happen to match text - // at a valid offset in the mapping table + // Try a three letter language code, and check whether it is + // returned as is. Locale locale = new Locale("aaa", "CCC"); + String result = locale.getISO3Language(); + if (!result.equals("aaa")) { + errln("ERROR: getISO3Language() returns: " + result + + " for locale '" + locale + "' rather than returning it as is" ); + } + + // Try an invalid two letter language code, and check whether it + // throws a MissingResourceException. + locale = new Locale("zz", "CCC"); + try { - String result = locale.getISO3Language(); + result = locale.getISO3Language(); errln("ERROR: getISO3Language() returns: " + result + " for locale '" + locale + "' rather than exception" ); diff --git a/test/java/util/PluggableLocale/DateFormatProviderTest.java b/test/java/util/PluggableLocale/DateFormatProviderTest.java index 6112b6836a437472d97d0f8844631730315e8479..6d5ecd23f3a2e340e48bfa8b4812f30e69a5e02f 100644 --- a/test/java/util/PluggableLocale/DateFormatProviderTest.java +++ b/test/java/util/PluggableLocale/DateFormatProviderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, 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 @@ -44,6 +44,7 @@ public class DateFormatProviderTest extends ProviderTest { availableLocalesTest(); objectValidityTest(); extendedVariantTest(); + messageFormatTest(); } void availableLocalesTest() { @@ -118,4 +119,48 @@ public class DateFormatProviderTest extends ProviderTest { } } } + + + private static final String[] TYPES = { + "date", + "time" + }; + private static final String[] MODIFIERS = { + "", + "short", + "medium", // Same as DEFAULT + "long", + "full" + }; + + void messageFormatTest() { + for (Locale target : providerloc) { + for (String type : TYPES) { + for (String modifier : MODIFIERS) { + String pattern, expected; + if (modifier.equals("")) { + pattern = String.format("%s={0,%s}", type, type); + } else { + pattern = String.format("%s={0,%s,%s}", type, type, modifier); + } + if (modifier.equals("medium")) { + // medium is default. + expected = String.format("%s={0,%s}", type, type); + } else { + expected = pattern; + } + MessageFormat mf = new MessageFormat(pattern, target); + Format[] fmts = mf.getFormats(); + if (fmts[0] instanceof SimpleDateFormat) { + continue; + } + String toPattern = mf.toPattern(); + if (!toPattern.equals(expected)) { + throw new RuntimeException("messageFormatTest: got '" + toPattern + + "', expected '" + expected + "'"); + } + } + } + } + } } diff --git a/test/java/util/PluggableLocale/DateFormatProviderTest.sh b/test/java/util/PluggableLocale/DateFormatProviderTest.sh index 0d7ad953fe209af41be14765e50cf35a94cf5954..228a2484a100b09bd22da771dad20e0add0f10d9 100644 --- a/test/java/util/PluggableLocale/DateFormatProviderTest.sh +++ b/test/java/util/PluggableLocale/DateFormatProviderTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2010, 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,6 +23,6 @@ #!/bin/sh # # @test -# @bug 4052440 +# @bug 4052440 7003643 # @summary DateFormatProvider tests # @run shell ExecTest.sh foo DateFormatProviderTest true diff --git a/test/java/util/PluggableLocale/NumberFormatProviderTest.java b/test/java/util/PluggableLocale/NumberFormatProviderTest.java index 93540bf1764da7281305d1b3702098b2181200b4..a7ebfb794975b15b3e95d350911244e9ebde2be0 100644 --- a/test/java/util/PluggableLocale/NumberFormatProviderTest.java +++ b/test/java/util/PluggableLocale/NumberFormatProviderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, 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 @@ -29,6 +29,8 @@ import java.util.*; import sun.util.*; import sun.util.resources.*; +import com.foo.FooNumberFormat; + public class NumberFormatProviderTest extends ProviderTest { com.foo.NumberFormatProviderImpl nfp = new com.foo.NumberFormatProviderImpl(); @@ -43,6 +45,7 @@ public class NumberFormatProviderTest extends ProviderTest { NumberFormatProviderTest() { availableLocalesTest(); objectValidityTest(); + messageFormatTest(); } void availableLocalesTest() { @@ -72,14 +75,10 @@ public class NumberFormatProviderTest extends ProviderTest { } // result object - String resultCur = - ((DecimalFormat)NumberFormat.getCurrencyInstance(target)).toPattern(); - String resultInt = - ((DecimalFormat)NumberFormat.getIntegerInstance(target)).toPattern(); - String resultNum = - ((DecimalFormat)NumberFormat.getNumberInstance(target)).toPattern(); - String resultPer = - ((DecimalFormat)NumberFormat.getPercentInstance(target)).toPattern(); + String resultCur = getPattern(NumberFormat.getCurrencyInstance(target)); + String resultInt = getPattern(NumberFormat.getIntegerInstance(target)); + String resultNum = getPattern(NumberFormat.getNumberInstance(target)); + String resultPer = getPattern(NumberFormat.getPercentInstance(target)); // provider's object (if any) String providersCur = null; @@ -87,21 +86,21 @@ public class NumberFormatProviderTest extends ProviderTest { String providersNum = null; String providersPer = null; if (providerloc.contains(target)) { - DecimalFormat dfCur = (DecimalFormat)nfp.getCurrencyInstance(target); + NumberFormat dfCur = nfp.getCurrencyInstance(target); if (dfCur != null) { - providersCur = dfCur.toPattern(); + providersCur = getPattern(dfCur); } - DecimalFormat dfInt = (DecimalFormat)nfp.getIntegerInstance(target); + NumberFormat dfInt = nfp.getIntegerInstance(target); if (dfInt != null) { - providersInt = dfInt.toPattern(); + providersInt = getPattern(dfInt); } - DecimalFormat dfNum = (DecimalFormat)nfp.getNumberInstance(target); + NumberFormat dfNum = nfp.getNumberInstance(target); if (dfNum != null) { - providersNum = dfNum.toPattern(); + providersNum = getPattern(dfNum); } - DecimalFormat dfPer = (DecimalFormat)nfp.getPercentInstance(target); + NumberFormat dfPer = nfp.getPercentInstance(target); if (dfPer != null) { - providersPer = dfPer.toPattern(); + providersPer = getPattern(dfPer); } } @@ -174,4 +173,35 @@ public class NumberFormatProviderTest extends ProviderTest { } } } + + private static String getPattern(NumberFormat nf) { + if (nf instanceof DecimalFormat) { + return ((DecimalFormat)nf).toPattern(); + } + if (nf instanceof FooNumberFormat) { + return ((FooNumberFormat)nf).toPattern(); + } + return null; + } + + private static final String[] NUMBER_PATTERNS = { + "num={0,number}", + "num={0,number,currency}", + "num={0,number,percent}", + "num={0,number,integer}" + }; + + void messageFormatTest() { + for (Locale target : providerloc) { + for (String pattern : NUMBER_PATTERNS) { + MessageFormat mf = new MessageFormat(pattern, target); + String toPattern = mf.toPattern(); + if (!pattern.equals(toPattern)) { + throw new RuntimeException("MessageFormat.toPattern: got '" + + toPattern + + "', expected '" + pattern + "'"); + } + } + } + } } diff --git a/test/java/util/PluggableLocale/NumberFormatProviderTest.sh b/test/java/util/PluggableLocale/NumberFormatProviderTest.sh index 7967da9f070d1f4a9bd66a7bee05e8cc983a7c4f..7f4e902a91451bb0bf5daca113600d355109f14b 100644 --- a/test/java/util/PluggableLocale/NumberFormatProviderTest.sh +++ b/test/java/util/PluggableLocale/NumberFormatProviderTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2010, 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,6 +23,6 @@ #!/bin/sh # # @test -# @bug 4052440 +# @bug 4052440 7003643 # @summary NumberFormatProvider tests # @run shell ExecTest.sh foo NumberFormatProviderTest true diff --git a/test/java/util/PluggableLocale/fooprovider.jar b/test/java/util/PluggableLocale/fooprovider.jar index 29ea53fcca62228087b1f864009aa21447af46c2..c1b5723f9b95dad064ed0393dd878cd7d82f3c51 100644 Binary files a/test/java/util/PluggableLocale/fooprovider.jar and b/test/java/util/PluggableLocale/fooprovider.jar differ diff --git a/test/java/util/PluggableLocale/providersrc/DateFormatProviderImpl.java b/test/java/util/PluggableLocale/providersrc/DateFormatProviderImpl.java index 25e7b1769462d8df3c650854e588339e94797bb5..55bc8d5ae73f3d1c8cb9a7b40b7acc078c71ef51 100644 --- a/test/java/util/PluggableLocale/providersrc/DateFormatProviderImpl.java +++ b/test/java/util/PluggableLocale/providersrc/DateFormatProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, 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,7 +42,7 @@ public class DateFormatProviderImpl extends DateFormatProvider { static String[] datePattern = { "yyyy'\u5e74'M'\u6708'd'\u65e5'", // full date pattern - "yyyy/MM/dd", // long date pattern + "yyyy/MMM/dd", // long date pattern "yyyy/MM/dd", // medium date pattern "yy/MM/dd" // short date pattern }; @@ -68,7 +68,7 @@ public class DateFormatProviderImpl extends DateFormatProvider { public DateFormat getDateInstance(int style, Locale locale) { for (int i = 0; i < avail.length; i ++) { if (Utils.supportsLocale(avail[i], locale)) { - return new SimpleDateFormat(datePattern[style]+dialect[i], locale); + return new FooDateFormat(datePattern[style]+dialect[i], locale); } } throw new IllegalArgumentException("locale is not supported: "+locale); @@ -77,7 +77,7 @@ public class DateFormatProviderImpl extends DateFormatProvider { public DateFormat getTimeInstance(int style, Locale locale) { for (int i = 0; i < avail.length; i ++) { if (Utils.supportsLocale(avail[i], locale)) { - return new SimpleDateFormat(timePattern[style]+dialect[i], locale); + return new FooDateFormat(timePattern[style]+dialect[i], locale); } } throw new IllegalArgumentException("locale is not supported: "+locale); @@ -86,7 +86,7 @@ public class DateFormatProviderImpl extends DateFormatProvider { public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) { for (int i = 0; i < avail.length; i ++) { if (Utils.supportsLocale(avail[i], locale)) { - return new SimpleDateFormat( + return new FooDateFormat( datePattern[dateStyle]+" "+timePattern[timeStyle]+dialect[i], locale); } } diff --git a/test/java/util/PluggableLocale/providersrc/FooDateFormat.java b/test/java/util/PluggableLocale/providersrc/FooDateFormat.java new file mode 100644 index 0000000000000000000000000000000000000000..80d4ce2010fb6555b8ea6042f3a7b0dcd094d11f --- /dev/null +++ b/test/java/util/PluggableLocale/providersrc/FooDateFormat.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2010, 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. + */ + +package com.foo; + +import java.text.*; +import java.util.*; + +/** + * FooDateFormat provides SimpleDateFormat methods required for the SPI testing. + */ +public class FooDateFormat extends DateFormat { + private SimpleDateFormat sdf; + + public FooDateFormat(String pattern, Locale loc) { + sdf = new SimpleDateFormat(pattern, loc); + } + + @Override + public StringBuffer format(Date date, + StringBuffer toAppendTo, + FieldPosition fieldPosition) { + return sdf.format(date, toAppendTo, fieldPosition); + } + + @Override + public Date parse(String source, ParsePosition pos) { + return sdf.parse(source, pos); + } + + @Override + public boolean equals(Object other) { + return other instanceof FooDateFormat + && sdf.equals(((FooDateFormat)other).sdf); + } + + @Override + public int hashCode() { + return sdf.hashCode(); + } +} diff --git a/test/java/util/PluggableLocale/providersrc/FooNumberFormat.java b/test/java/util/PluggableLocale/providersrc/FooNumberFormat.java new file mode 100644 index 0000000000000000000000000000000000000000..d13bd7362fed3bb046ae3053479d971d1ec3f076 --- /dev/null +++ b/test/java/util/PluggableLocale/providersrc/FooNumberFormat.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2010, 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. + */ + +package com.foo; + +import java.text.*; + +/** + * FooNumberFormat provides DecimalFormat methods required for the SPI testing. + */ +public class FooNumberFormat extends NumberFormat { + private DecimalFormat df; + + public FooNumberFormat(String pattern, DecimalFormatSymbols dfs) { + df = new DecimalFormat(pattern, dfs); + } + + @Override + public StringBuffer format(double number, + StringBuffer toAppendTo, + FieldPosition pos) { + return df.format(number, toAppendTo, pos); + } + + @Override + public StringBuffer format(long number, + StringBuffer toAppendTo, + FieldPosition pos) { + return df.format(number, toAppendTo, pos); + } + + @Override + public Number parse(String source, ParsePosition parsePosition) { + return df.parse(source, parsePosition); + } + + @Override + public boolean equals(Object other) { + return other instanceof FooNumberFormat + && df.equals(((FooNumberFormat)other).df); + } + + @Override + public int hashCode() { + return df.hashCode(); + } + + // DecimalFormat specific methods required for testing + + public String toPattern() { + return df.toPattern(); + } + + public DecimalFormatSymbols getDecimalFormatSymbols() { + return df.getDecimalFormatSymbols(); + } + + public void setDecimalSeparatorAlwaysShown(boolean newValue) { + df.setDecimalSeparatorAlwaysShown(newValue); + } +} diff --git a/test/java/util/PluggableLocale/providersrc/Makefile b/test/java/util/PluggableLocale/providersrc/Makefile index a85ea065e981950aa2e5b8a3f872657f4f23beaa..8d2fa9cab808568a238929fef8847c7bc926c73b 100644 --- a/test/java/util/PluggableLocale/providersrc/Makefile +++ b/test/java/util/PluggableLocale/providersrc/Makefile @@ -28,6 +28,8 @@ FOOFILES_JAVA = \ DateFormatSymbolsProviderImpl.java \ DecimalFormatSymbolsProviderImpl.java \ NumberFormatProviderImpl.java \ + FooDateFormat.java \ + FooNumberFormat.java \ Utils.java BARFILES_JAVA = \ diff --git a/test/java/util/PluggableLocale/providersrc/NumberFormatProviderImpl.java b/test/java/util/PluggableLocale/providersrc/NumberFormatProviderImpl.java index 164de5e1db634982482a24c2e1f9697e4fd49d73..9aa677cf89bcaf004b3c1fd9c4a12c536a4d3d9a 100644 --- a/test/java/util/PluggableLocale/providersrc/NumberFormatProviderImpl.java +++ b/test/java/util/PluggableLocale/providersrc/NumberFormatProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, 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 @@ -49,13 +49,15 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { static String[] patterns = { "#,##0.###{0};-#,##0.###{1}", // decimal pattern + "#{0};(#){1}", // integer pattern "\u00A4#,##0{0};-\u00A4#,##0{1}", // currency pattern "#,##0%{0}" // percent pattern }; // Constants used by factory methods to specify a style of format. static final int NUMBERSTYLE = 0; - static final int CURRENCYSTYLE = 1; - static final int PERCENTSTYLE = 2; + static final int INTEGERSTYLE = 1; + static final int CURRENCYSTYLE = 2; + static final int PERCENTSTYLE = 3; public Locale[] getAvailableLocales() { return avail; @@ -68,10 +70,10 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { MessageFormat.format(patterns[CURRENCYSTYLE], dialect[i], dialect[i]); - DecimalFormat df = new DecimalFormat(pattern, + FooNumberFormat nf = new FooNumberFormat(pattern, DecimalFormatSymbols.getInstance(locale)); - adjustForCurrencyDefaultFractionDigits(df); - return df; + adjustForCurrencyDefaultFractionDigits(nf); + return nf; } } throw new IllegalArgumentException("locale is not supported: "+locale); @@ -81,15 +83,15 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { for (int i = 0; i < avail.length; i ++) { if (Utils.supportsLocale(avail[i], locale)) { String pattern = - MessageFormat.format(patterns[NUMBERSTYLE], + MessageFormat.format(patterns[INTEGERSTYLE], dialect[i], dialect[i]); - DecimalFormat df = new DecimalFormat(pattern, + FooNumberFormat nf = new FooNumberFormat(pattern, DecimalFormatSymbols.getInstance(locale)); - df.setMaximumFractionDigits(0); - df.setDecimalSeparatorAlwaysShown(false); - df.setParseIntegerOnly(true); - return df; + nf.setMaximumFractionDigits(0); + nf.setDecimalSeparatorAlwaysShown(false); + nf.setParseIntegerOnly(true); + return nf; } } throw new IllegalArgumentException("locale is not supported: "+locale); @@ -102,7 +104,7 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { MessageFormat.format(patterns[NUMBERSTYLE], dialect[i], dialect[i]); - return new DecimalFormat(pattern, + return new FooNumberFormat(pattern, DecimalFormatSymbols.getInstance(locale)); } } @@ -115,7 +117,7 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { String pattern = MessageFormat.format(patterns[PERCENTSTYLE], dialect[i]); - return new DecimalFormat(pattern, + return new FooNumberFormat(pattern, DecimalFormatSymbols.getInstance(locale)); } } @@ -126,8 +128,8 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { * Adjusts the minimum and maximum fraction digits to values that * are reasonable for the currency's default fraction digits. */ - void adjustForCurrencyDefaultFractionDigits(DecimalFormat df) { - DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); + void adjustForCurrencyDefaultFractionDigits(FooNumberFormat nf) { + DecimalFormatSymbols dfs = nf.getDecimalFormatSymbols(); Currency currency = dfs.getCurrency(); if (currency == null) { try { @@ -138,15 +140,15 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { if (currency != null) { int digits = currency.getDefaultFractionDigits(); if (digits != -1) { - int oldMinDigits = df.getMinimumFractionDigits(); + int oldMinDigits = nf.getMinimumFractionDigits(); // Common patterns are "#.##", "#.00", "#". // Try to adjust all of them in a reasonable way. - if (oldMinDigits == df.getMaximumFractionDigits()) { - df.setMinimumFractionDigits(digits); - df.setMaximumFractionDigits(digits); + if (oldMinDigits == nf.getMaximumFractionDigits()) { + nf.setMinimumFractionDigits(digits); + nf.setMaximumFractionDigits(digits); } else { - df.setMinimumFractionDigits(Math.min(digits, oldMinDigits)); - df.setMaximumFractionDigits(digits); + nf.setMinimumFractionDigits(Math.min(digits, oldMinDigits)); + nf.setMaximumFractionDigits(digits); } } } diff --git a/test/javax/swing/JFileChooser/4847375/bug4847375.java b/test/javax/swing/JFileChooser/4847375/bug4847375.java new file mode 100644 index 0000000000000000000000000000000000000000..8a9af80b672fe93699ba40034e4febee42cbf8c6 --- /dev/null +++ b/test/javax/swing/JFileChooser/4847375/bug4847375.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2010, 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 4847375 + * @summary JFileChooser Create New Folder button is disabled incorrectly + * @author Pavel Porvatov + */ + +import sun.awt.OSInfo; +import sun.awt.shell.ShellFolder; + +import javax.swing.*; +import java.awt.*; +import java.lang.reflect.Method; + +public class bug4847375 { + private final String newFolderToolTipText; + + private final String lookAndFeel; + + public static void main(String[] args) throws Exception { + if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) { + System.out.println("The test is suitable only for Windows OS. Skipped."); + + return; + } + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + new bug4847375("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + + new bug4847375("javax.swing.plaf.metal.MetalLookAndFeel"); + } + }); + } + + private static Object[][] DIRECTORIES = new Object[][]{ + {"getDesktop", Boolean.TRUE}, + {"getDrives", Boolean.FALSE}, // My computer + {"getRecent", Boolean.TRUE}, + {"getNetwork", Boolean.FALSE}, + {"getPersonal", Boolean.TRUE}, + }; + + private bug4847375(String lookAndFeel) { + this.lookAndFeel = lookAndFeel; + + try { + UIManager.setLookAndFeel(lookAndFeel); + } catch (Exception e) { + fail("Cannot set LookAndFeel", e); + } + + JFileChooser fileChooser = new JFileChooser(); + + // Find button NewFolder + newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText", fileChooser.getLocale()); + + if (newFolderToolTipText == null || newFolderToolTipText.length() == 0) { + fail("Cannot find NewFolderButton in FileChooser (tooltip doesn't exist)"); + + return; + } + + JButton newFolderButton = findNewFolderButton(fileChooser); + + if (newFolderButton == null) { + fail("Cannot find NewFolderButton in FileChooser"); + + return; + } + + for (Object[] objects : DIRECTORIES) { + String getterName = (String) objects[0]; + Boolean enabledNewFolder = (Boolean) objects[1]; + + fileChooser.setCurrentDirectory(getWin32Folder(getterName)); + + if (newFolderButton.isEnabled() != enabledNewFolder) { + fail("Enabled state of NewFolderButton should be " + enabledNewFolder + + " for Win32ShellFolderManager2." + getterName + "()"); + } + } + } + + private JButton findNewFolderButton(Container container) { + JButton result = null; + + for (int i = 0; i < container.getComponentCount(); i++) { + Component c = container.getComponent(i); + + if (c instanceof JButton && newFolderToolTipText.equals(((JButton) c).getToolTipText())) { + if (result != null) { + fail("Two or more NewFolderButton found in FileChooser"); + } + + result = (JButton) c; + } + + if (c instanceof Container) { + JButton button = findNewFolderButton((Container) c); + + if (result == null) { + result = button; + } else { + if (button != null) { + fail("Two or more NewFolderButton found in FileChooser"); + } + } + } + } + + return result; + } + + private ShellFolder getWin32Folder(String getterName) { + try { + Class win32ShellFolderManager2 = Class.forName("sun.awt.shell.Win32ShellFolderManager2"); + + Method method = win32ShellFolderManager2.getDeclaredMethod(getterName); + method.setAccessible(true); + + return (ShellFolder) method.invoke(null); + } catch (Exception e) { + fail("Cannot call '" + getterName + "' in the Win32ShellFolderManager2 class", e); + + return null; + } + } + + private void fail(String s) { + throw new RuntimeException("Test failed: " + s); + } + + private void fail(String s, Throwable e) { + throw new RuntimeException("Test failed for LookAndFeel " + lookAndFeel + ": " + s, e); + } +} diff --git a/test/javax/swing/JScrollBar/6542335/bug6542335.java b/test/javax/swing/JScrollBar/6542335/bug6542335.java index 33e95d8ecac74a6c9c3963b5fc6f1566ef8e5c9b..d4ed4736e346a2f440632d5be534d37169619d3e 100644 --- a/test/javax/swing/JScrollBar/6542335/bug6542335.java +++ b/test/javax/swing/JScrollBar/6542335/bug6542335.java @@ -40,11 +40,13 @@ public class bug6542335 { private static MyScrollBarUI ui; public static void main(String[] args) throws Exception { - Robot robot = new Robot(); + final Robot robot = new Robot(); robot.setAutoDelay(10); SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + final Rectangle[] thumbBounds = new Rectangle[1]; + SwingUtilities.invokeAndWait(new Runnable() { public void run() { final JFrame frame = new JFrame("bug6542335"); @@ -63,25 +65,39 @@ public class bug6542335 { rangeModel.setValue(50); sb.setModel(rangeModel); - frame.add(sb); + frame.add(sb, BorderLayout.NORTH); frame.setSize(200, 100); frame.setVisible(true); + + thumbBounds[0] = new Rectangle(ui.getThumbBounds()); } }); - Rectangle thumbBounds = new Rectangle(ui.getThumbBounds()); - toolkit.realSync(); - Point l = sb.getLocationOnScreen(); - robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2); - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + Point l = sb.getLocationOnScreen(); + + robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight() / 2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + } + }); + toolkit.realSync(); - if (!thumbBounds.equals(ui.getThumbBounds())) { - throw new RuntimeException("Test failed"); - } + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + Rectangle newThumbBounds = ui.getThumbBounds(); + + if (!thumbBounds[0].equals(newThumbBounds)) { + throw new RuntimeException("Test failed.\nOld bounds: " + thumbBounds[0] + + "\nNew bounds: " + newThumbBounds); + } + } + }); } static class MyScrollBarUI extends BasicScrollBarUI { diff --git a/test/javax/swing/JSpinner/6532833/bug6532833.java b/test/javax/swing/JSpinner/6532833/bug6532833.java new file mode 100644 index 0000000000000000000000000000000000000000..184fe69d96d345d557e91137aa7ca63207317db5 --- /dev/null +++ b/test/javax/swing/JSpinner/6532833/bug6532833.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2010, 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 6532833 + @summary PIT: Metal LAF - The right side border is not shown for the Spinner after the removing the buttons + @author Pavel Porvatov +*/ + +import javax.swing.*; +import java.awt.*; + +public class bug6532833 { + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + JSpinner[] spinners = new JSpinner[2]; + + for (int i = 0; i < spinners.length; i++) { + JSpinner spinner = new JSpinner(); + + spinner.setValue(2010); + + Component arrowUp = spinner.getComponent(0); + Component arrowDown = spinner.getComponent(1); + + LayoutManager layout = spinner.getLayout(); + + layout.removeLayoutComponent(arrowUp); + layout.removeLayoutComponent(arrowDown); + + if (i == 1) { + spinner.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); + } + + spinners[i] = spinner; + } + + // Do layout of spinners components + JFrame frame = new JFrame(); + + for (JSpinner spinner : spinners) { + frame.getContentPane().add(spinner); + } + + frame.pack(); + + for (JSpinner spinner : spinners) { + Insets insets = spinner.getInsets(); + + if (spinner.getWidth() != insets.left + insets.right + spinner.getEditor().getWidth()) { + throw new RuntimeException("Spinner editor width is invalid"); + } + } + + frame.dispose(); + } + }); + } +}