OpenJDK / portola / portola
changeset 4618:ff5d0801d4b7
Merge
author | yhuang |
---|---|
date | Mon, 11 Jan 2010 23:25:20 -0800 |
parents | 9406ecbcda79 a54861499f09 |
children | dd3bacb9f730 |
files | jdk/make/tools/CharsetMapping/DoubleByte-X.java jdk/make/tools/CharsetMapping/SingleByte-X.java jdk/src/share/classes/javax/swing/plaf/synth/DefaultMenuLayout.java jdk/src/share/classes/sun/awt/ComponentAccessor.java jdk/src/share/classes/sun/awt/WindowAccessor.java jdk/src/share/classes/sun/security/provider/IdentityDatabase.java jdk/src/share/classes/sun/security/provider/SystemIdentity.java jdk/src/share/classes/sun/security/provider/SystemSigner.java jdk/src/share/classes/sun/security/x509/X500Signer.java jdk/src/share/classes/sun/security/x509/X509Cert.java jdk/src/share/classes/sun/swing/plaf/synth/SynthUI.java jdk/src/share/classes/sun/tools/jar/JarVerifierStream.java jdk/src/share/classes/sun/util/CoreResourceBundleControl-XLocales.java jdk/src/share/classes/sun/util/LocaleDataMetaInfo-XLocales.java jdk/test/java/util/Formatter/Basic-X.java jdk/test/sun/tools/native2ascii/test2 jdk/test/tools/launcher/SolarisDataModel.sh jdk/test/tools/launcher/SolarisRunpath.sh jdk/test/tools/launcher/libraryCaller.c jdk/test/tools/launcher/libraryCaller.h jdk/test/tools/launcher/libraryCaller.java |
diffstat | 412 files changed, 12751 insertions(+), 9058 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Wed Jan 06 19:32:55 2010 -0800 +++ b/.hgignore Mon Jan 11 23:25:20 2010 -0800 @@ -1,3 +1,3 @@ ^build/ ^dist/ -^nbproject/private/ +/nbproject/private/
--- a/.hgtags Wed Jan 06 19:32:55 2010 -0800 +++ b/.hgtags Mon Jan 11 23:25:20 2010 -0800 @@ -51,3 +51,4 @@ 4e7661eaa211e186674f6cbefec4aef1144ac2a0 jdk7-b74 946518568340c4e511549318f19f47f06b7f5f9b jdk7-b75 09e0b33177af2b98a03c9ca19eedf61440bd1cf6 jdk7-b76 +1d0121b741f029dc4b828e4b36ba6fda92907dd7 jdk7-b77
--- a/.hgtags-top-repo Wed Jan 06 19:32:55 2010 -0800 +++ b/.hgtags-top-repo Mon Jan 11 23:25:20 2010 -0800 @@ -51,3 +51,4 @@ 2c88089b6e1c053597418099a14232182c387edc jdk7-b74 d1516b9f23954b29b8e76e6f4efc467c08c78133 jdk7-b75 c8b63075403d53a208104a8a6ea5072c1cb66aab jdk7-b76 +1f17ca8353babb13f4908c1f87d11508232518c8 jdk7-b77
--- a/Makefile Wed Jan 06 19:32:55 2010 -0800 +++ b/Makefile Mon Jan 11 23:25:20 2010 -0800 @@ -51,7 +51,7 @@ # For start and finish echo lines TITLE_TEXT = Control $(PLATFORM) $(ARCH) $(RELEASE) -DAYE_STAMP = `$(DATE) '+%y-%m-%d %H:%M'` +DATE_STAMP = `$(DATE) '+%y-%m-%d %H:%M'` START_ECHO = echo "$(TITLE_TEXT) $@ build started: $(DATE_STAMP)" FINISH_ECHO = echo "$(TITLE_TEXT) $@ build finished: $(DATE_STAMP)" @@ -188,7 +188,7 @@ create_fresh_product_bootdir: FRC @$(START_ECHO) $(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \ - NO_DOCS=true \ + GENERATE_DOCS=false \ BOOT_CYCLE_SETTINGS= \ build_product_image @$(FINISH_ECHO) @@ -196,7 +196,7 @@ create_fresh_debug_bootdir: FRC @$(START_ECHO) $(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \ - NO_DOCS=true \ + GENERATE_DOCS=false \ BOOT_CYCLE_DEBUG_SETTINGS= \ build_debug_image @$(FINISH_ECHO) @@ -204,7 +204,7 @@ create_fresh_fastdebug_bootdir: FRC @$(START_ECHO) $(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \ - NO_DOCS=true \ + GENERATE_DOCS=false \ BOOT_CYCLE_DEBUG_SETTINGS= \ build_fastdebug_image @$(FINISH_ECHO) @@ -253,7 +253,7 @@ $(MAKE) \ ALT_OUTPUTDIR=$(ABS_OUTPUTDIR)-$(DEBUG_NAME) \ DEBUG_NAME=$(DEBUG_NAME) \ - NO_DOCS=true \ + GENERATE_DOCS=false \ $(BOOT_CYCLE_DEBUG_SETTINGS) \ generic_build_repo_series @$(FINISH_ECHO) @@ -323,7 +323,7 @@ $(MKDIR) -p $(OPENJDK_OUTPUTDIR) ($(CD) $(OPENJDK_BUILDDIR) && $(MAKE) \ OPENJDK=true \ - NO_DOCS=true \ + GENERATE_DOCS=false \ ALT_JDK_DEVTOOLS_DIR=$(JDK_DEVTOOLS_DIR) \ ALT_OUTPUTDIR=$(OPENJDK_OUTPUTDIR) \ ALT_BINARY_PLUGS_PATH=$(OPENJDK_PLUGS) \
--- a/corba/.hgignore Wed Jan 06 19:32:55 2010 -0800 +++ b/corba/.hgignore Mon Jan 11 23:25:20 2010 -0800 @@ -1,3 +1,3 @@ ^build/ ^dist/ -^nbproject/private/ +/nbproject/private/
--- a/corba/.hgtags Wed Jan 06 19:32:55 2010 -0800 +++ b/corba/.hgtags Mon Jan 11 23:25:20 2010 -0800 @@ -51,3 +51,4 @@ 5d0cf59a3203b9f57aceebc33ae656b884987955 jdk7-b74 0fb137085952c8e47878e240d1cb40f14de463c4 jdk7-b75 937144222e2219939101b0129d26a872a7956b13 jdk7-b76 +6881f0383f623394b5ec73f27a5f329ff55d0467 jdk7-b77
--- a/hotspot/.hgignore Wed Jan 06 19:32:55 2010 -0800 +++ b/hotspot/.hgignore Mon Jan 11 23:25:20 2010 -0800 @@ -1,6 +1,6 @@ ^build/ ^dist/ -^nbproject/private/ +/nbproject/private/ ^src/share/tools/hsdis/build/ ^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/ ^src/share/tools/IdealGraphVisualizer/build/
--- a/hotspot/.hgtags Wed Jan 06 19:32:55 2010 -0800 +++ b/hotspot/.hgtags Mon Jan 11 23:25:20 2010 -0800 @@ -51,3 +51,4 @@ f4b900403d6e4b0af51447bd13bbe23fe3a1dac7 jdk7-b74 d8dd291a362acb656026a9c0a9da48501505a1e7 jdk7-b75 9174bb32e934965288121f75394874eeb1fcb649 jdk7-b76 +455105fc81d941482f8f8056afaa7aa0949c9300 jdk7-b77
--- a/jaxp/.hgignore Wed Jan 06 19:32:55 2010 -0800 +++ b/jaxp/.hgignore Mon Jan 11 23:25:20 2010 -0800 @@ -3,4 +3,4 @@ ^drop/ ^drop_included/ ^webrev/ -^nbproject/private/ +/nbproject/private/
--- a/jaxp/.hgtags Wed Jan 06 19:32:55 2010 -0800 +++ b/jaxp/.hgtags Mon Jan 11 23:25:20 2010 -0800 @@ -51,3 +51,4 @@ ea7b88c676dd8b269bc858a4a17c14dc96c8aed1 jdk7-b74 555fb78ee4cebed082ca7ddabff46d2e5b4c9026 jdk7-b75 233a4871d3364ec305efd4a58cfd676620a03a90 jdk7-b76 +bfadab8c7b1bf806a49d3e1bc19ec919717f057a jdk7-b77
--- a/jaxws/.hgignore Wed Jan 06 19:32:55 2010 -0800 +++ b/jaxws/.hgignore Mon Jan 11 23:25:20 2010 -0800 @@ -3,4 +3,4 @@ ^drop/ ^drop_included/ ^webrev/ -^nbproject/private/ +/nbproject/private/
--- a/jaxws/.hgtags Wed Jan 06 19:32:55 2010 -0800 +++ b/jaxws/.hgtags Mon Jan 11 23:25:20 2010 -0800 @@ -51,3 +51,4 @@ f4466e1b608088c90e11beaa4b600f102608c6a1 jdk7-b74 fcf2b8b5d606641659419f247fcee4b284c45e6e jdk7-b75 765d2077d1e652e234d27fe85ba58a986b488503 jdk7-b76 +5b4968c110476085225d3a71c4210fad2c1116c1 jdk7-b77
--- a/jdk/.hgignore Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/.hgignore Mon Jan 11 23:25:20 2010 -0800 @@ -1,6 +1,5 @@ ^build/ ^dist/ -^nbproject/private/ -^make/netbeans/.*/nbproject/private/ +/nbproject/private/ ^make/netbeans/.*/build/ ^make/netbeans/.*/dist/
--- a/jdk/.hgtags Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/.hgtags Mon Jan 11 23:25:20 2010 -0800 @@ -51,3 +51,5 @@ eacb36e30327e7ae33baa068e82ddccbd91eaae2 jdk7-b74 8885b22565077236a927e824ef450742e434a230 jdk7-b75 8fb602395be0f7d5af4e7e93b7df2d960faf9d17 jdk7-b76 +e6a5d095c356a547cf5b3c8885885aca5e91e09b jdk7-b77 +1143e498f813b8223b5e3a696d79da7ff7c25354 jdk7-b78
--- a/jdk/make/java/java/Makefile Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/java/java/Makefile Mon Jan 11 23:25:20 2010 -0800 @@ -390,7 +390,7 @@ LOCALES_GEN_SH = localelist.sh $(GENSRCDIR)/sun/util/CoreResourceBundleControl.java: \ - $(SHARE_SRC)/classes/sun/util/CoreResourceBundleControl-XLocales.java $(LOCALES_GEN_SH) + $(SHARE_SRC)/classes/sun/util/CoreResourceBundleControl-XLocales.java.template $(LOCALES_GEN_SH) @$(prep-target) NAWK="$(NAWK)" SED="$(SED)" $(SH) $(LOCALES_GEN_SH) "$(JRE_NONEXIST_LOCALES)" \ $< $@
--- a/jdk/make/java/java/genlocales.gmk Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/java/java/genlocales.gmk Mon Jan 11 23:25:20 2010 -0800 @@ -68,7 +68,7 @@ FILES_java := $(FILES_java_orig) FILES_compiled_properties := $(FILES_compiled_properties_orig) -LocaleDataMetaInfo_Src=$(SHARE_SRC)/classes/sun/util/LocaleDataMetaInfo-XLocales.java +LocaleDataMetaInfo_Src=$(SHARE_SRC)/classes/sun/util/LocaleDataMetaInfo-XLocales.java.template LocaleDataMetaInfo_Dest=$(GENSRCDIR)/sun/util/LocaleDataMetaInfo.java LOCALEGEN_SH=localegen.sh RESOURCE_NAMES="FormatData CollationData TimeZoneNames LocaleNames CurrencyNames CalendarData"
--- a/jdk/make/java/java/localegen.sh Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/java/java/localegen.sh Mon Jan 11 23:25:20 2010 -0800 @@ -27,7 +27,7 @@ # # This script is to generate the supported locale list string and replace the -# LocaleDataMetaInfo-XLocales.java in <ws>/src/share/classes/sun/util +# LocaleDataMetaInfo-XLocales.java.template in <ws>/src/share/classes/sun/util # # SORT, NAWK & SED is passed in as environment variables. #
--- a/jdk/make/java/jli/Makefile Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/java/jli/Makefile Mon Jan 11 23:25:20 2010 -0800 @@ -96,6 +96,7 @@ ifneq ($(PLATFORM), windows) # UNIX systems + LD_RUNPATH_EXTRAS += .. LIB_LOCATION = $(LIBDIR)/$(LIBARCH)/jli # Note: its important to keep this order meaning -lc is the # last library otherwise it could cause compatibility issues
--- a/jdk/make/java/main/java/Makefile Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/java/main/java/Makefile Mon Jan 11 23:25:20 2010 -0800 @@ -61,8 +61,5 @@ ifeq ($(PLATFORM), solaris) LDFLAGS += -R$(OPENWIN_LIB) -endif - -ifeq ($(PLATFORM), solaris) LDFLAGS += -M mapfile-$(ARCH) endif
--- a/jdk/make/java/nio/Makefile Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/java/nio/Makefile Mon Jan 11 23:25:20 2010 -0800 @@ -834,7 +834,7 @@ GENCSSRC = $(BUILDDIR)/tools/CharsetMapping CHARSETMAPPING_JARFILE = $(BUILDTOOLJARDIR)/charsetmapping.jar -$(FILES_gensbcs_out): $(GENCSSRC)/SingleByte-X.java $(GENCSSRC)/sbcs +$(FILES_gensbcs_out): $(GENCSSRC)/SingleByte-X.java.template $(GENCSSRC)/sbcs @$(prep-target) $(BOOT_JAVA_CMD) -jar $(CHARSETMAPPING_JARFILE) $(GENCSSRC) $(SCS_GEN) sbcs
--- a/jdk/make/java/redist/Makefile Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/java/redist/Makefile Mon Jan 11 23:25:20 2010 -0800 @@ -194,10 +194,8 @@ # For backwards compatability, make a link of the 32-bit client JVM to $(LIBDIR) IMPORT_LIST += $(LIB_LOCATION)/$(JVM_NAME) -# create a link from lib/libjvm.so to client/libjvm.so $(LIB_LOCATION)/$(JVM_NAME): $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_NAME) @$(prep-target) - $(LN) -s $(CLIENT_LOCATION)/$(JVM_NAME) $@ # solaris ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ solaris endif # 32bit solaris
--- a/jdk/make/javax/sound/Makefile Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/javax/sound/Makefile Mon Jan 11 23:25:20 2010 -0800 @@ -108,22 +108,14 @@ endif # PLATFORM linux ifeq ($(PLATFORM), solaris) - ifneq ($(ARCH), amd64) - # build with ports and direct audio - CPPFLAGS += -DUSE_PORTS=TRUE \ - -DUSE_DAUDIO=TRUE + # build with ports and direct audio + CPPFLAGS += -DUSE_PORTS=TRUE \ + -DUSE_DAUDIO=TRUE - INCLUDE_PORTS = TRUE - INCLUDE_DAUDIO = TRUE - INCLUDE_MIDI = TRUE - else - # build with empty MIDI i/o - INCLUDE_MIDI = TRUE - # build with empty ports - INCLUDE_PORTS = TRUE - # build with empty direct audio - INCLUDE_DAUDIO = TRUE - endif + INCLUDE_PORTS = TRUE + INCLUDE_DAUDIO = TRUE + # build with empty MIDI i/o + INCLUDE_MIDI = TRUE endif # PLATFORM solaris # for dynamic inclusion of extra sound libs: these
--- a/jdk/make/netbeans/README Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/netbeans/README Mon Jan 11 23:25:20 2010 -0800 @@ -411,7 +411,7 @@ java/util/regex/,\ java/util/spi/,\ java/util/zip/,\ - **/*-XLocales.java + **/*-XLocales.java.template jtreg.tests=\ java/util/**/*Collection/ \ java/util/**/*Map/ \
--- a/jdk/make/sun/nio/Makefile Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/sun/nio/Makefile Mon Jan 11 23:25:20 2010 -0800 @@ -82,7 +82,9 @@ $(FILES_MAP) $(FILES_DAT) sjis0213 -$(FILES_genout_extcs): $(GENCSDATASRC)/SingleByte-X.java $(GENCSDATASRC)/DoubleByte-X.java \ +$(FILES_genout_extcs): \ + $(GENCSDATASRC)/SingleByte-X.java.template \ + $(GENCSDATASRC)/DoubleByte-X.java.template \ $(GENCSDATASRC)/extsbcs $(GENCSDATASRC)/dbcs @$(prep-target) $(RM) -r $(GENCSEXT)
--- a/jdk/make/sun/xawt/mapfile-vers Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/sun/xawt/mapfile-vers Mon Jan 11 23:25:20 2010 -0800 @@ -126,6 +126,8 @@ Java_sun_awt_X11_XlibWrapper_ServerVendor; Java_sun_awt_X11_XlibWrapper_VendorRelease; Java_sun_awt_X11_XlibWrapper_IsXsunKPBehavior; + Java_sun_awt_X11_XlibWrapper_IsSunKeyboard; + Java_sun_awt_X11_XlibWrapper_IsKanaKeyboard; Java_sun_awt_X11_XlibWrapper_SetToolkitErrorHandler; Java_sun_awt_X11_XlibWrapper_XSetErrorHandler; Java_sun_awt_X11_XlibWrapper_CallErrorHandler; @@ -306,6 +308,7 @@ Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode; Java_sun_awt_X11_XlibWrapper_XGetModifierMapping; Java_sun_awt_X11_XlibWrapper_XFreeModifiermap; + Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping; Java_sun_awt_X11_XlibWrapper_XChangeActivePointerGrab; Java_sun_awt_X11_XlibWrapper_XNextSecondaryLoopEvent; Java_sun_awt_X11_XlibWrapper_ExitSecondaryLoop;
--- a/jdk/make/tools/CharsetMapping/DoubleByte-X.java Wed Jan 06 19:32:55 2010 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -/* - * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -// -- This file was mechanically generated: Do not edit! -- // - -package $PACKAGE$; - -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import java.util.Arrays; -import sun.nio.cs.HistoricallyNamedCharset; -import sun.nio.cs.ext.DoubleByte; - -public class $NAME_CLZ$ extends Charset - $IMPLEMENTS$ -{ - public $NAME_CLZ$() { - super("$NAME_CS$", $NAME_ALIASES$); - } - - $HISTORICALNAME$ - - public boolean contains(Charset cs) { - $CONTAINS$ - } - - public CharsetDecoder newDecoder() { - initb2c(); - return new DoubleByte.Decoder$DECTYPE$(this, b2c, b2cSB, $B2MIN$, $B2MAX$); - } - - public CharsetEncoder newEncoder() { - initc2b(); - return new DoubleByte.Encoder$ENCTYPE$(this, c2b, c2bIndex); - } - - $B2C$ - static char[][] b2c = new char[b2cStr.length][]; - static char[] b2cSB; - private static volatile boolean b2cInitialized = false; - - static void initb2c() { - if (b2cInitialized) - return; - synchronized (b2c) { - if (b2cInitialized) - return; - for (int i = 0; i < b2cStr.length; i++) { - if (b2cStr[i] == null) - b2c[i] = DoubleByte.B2C_UNMAPPABLE; - else - b2c[i] = b2cStr[i].toCharArray(); - } - b2cSB = b2cSBStr.toCharArray(); - b2cInitialized = true; - } - } - - static char[] c2b = new char[$C2BLENGTH$]; - static char[] c2bIndex = new char[0x100]; - private static volatile boolean c2bInitialized = false; - - static void initc2b() { - if (c2bInitialized) - return; - synchronized (c2b) { - if (c2bInitialized) - return; - $NONROUNDTRIP_B2C$ - $NONROUNDTRIP_C2B$ - DoubleByte.Encoder.initC2B(b2cStr, b2cSBStr, b2cNR, c2bNR, - $B2MIN$, $B2MAX$, - c2b, c2bIndex); - c2bInitialized = true; - } - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/tools/CharsetMapping/DoubleByte-X.java.template Mon Jan 11 23:25:20 2010 -0800 @@ -0,0 +1,100 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +// -- This file was mechanically generated: Do not edit! -- // + +package $PACKAGE$; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.util.Arrays; +import sun.nio.cs.HistoricallyNamedCharset; +import sun.nio.cs.ext.DoubleByte; + +public class $NAME_CLZ$ extends Charset + $IMPLEMENTS$ +{ + public $NAME_CLZ$() { + super("$NAME_CS$", $NAME_ALIASES$); + } + + $HISTORICALNAME$ + + public boolean contains(Charset cs) { + $CONTAINS$ + } + + public CharsetDecoder newDecoder() { + initb2c(); + return new DoubleByte.Decoder$DECTYPE$(this, b2c, b2cSB, $B2MIN$, $B2MAX$); + } + + public CharsetEncoder newEncoder() { + initc2b(); + return new DoubleByte.Encoder$ENCTYPE$(this, c2b, c2bIndex); + } + + $B2C$ + static char[][] b2c = new char[b2cStr.length][]; + static char[] b2cSB; + private static volatile boolean b2cInitialized = false; + + static void initb2c() { + if (b2cInitialized) + return; + synchronized (b2c) { + if (b2cInitialized) + return; + for (int i = 0; i < b2cStr.length; i++) { + if (b2cStr[i] == null) + b2c[i] = DoubleByte.B2C_UNMAPPABLE; + else + b2c[i] = b2cStr[i].toCharArray(); + } + b2cSB = b2cSBStr.toCharArray(); + b2cInitialized = true; + } + } + + static char[] c2b = new char[$C2BLENGTH$]; + static char[] c2bIndex = new char[0x100]; + private static volatile boolean c2bInitialized = false; + + static void initc2b() { + if (c2bInitialized) + return; + synchronized (c2b) { + if (c2bInitialized) + return; + $NONROUNDTRIP_B2C$ + $NONROUNDTRIP_C2B$ + DoubleByte.Encoder.initC2B(b2cStr, b2cSBStr, b2cNR, c2bNR, + $B2MIN$, $B2MAX$, + c2b, c2bIndex); + c2bInitialized = true; + } + } +}
--- a/jdk/make/tools/CharsetMapping/SingleByte-X.java Wed Jan 06 19:32:55 2010 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package $PACKAGE$; - -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import sun.nio.cs.StandardCharsets; -import sun.nio.cs.SingleByte; -import sun.nio.cs.HistoricallyNamedCharset; -import static sun.nio.cs.CharsetMapping.*; - -public class $NAME_CLZ$ extends Charset implements HistoricallyNamedCharset -{ - public $NAME_CLZ$() { - super("$NAME_CS$", $NAME_ALIASES$); - } - - public String historicalName() { - return "$NAME_HIS$"; - } - - public boolean contains(Charset cs) { - $CONTAINS$; - } - - public CharsetDecoder newDecoder() { - return new SingleByte.Decoder(this, b2c); - } - - public CharsetEncoder newEncoder() { - return new SingleByte.Encoder(this, c2b, c2bIndex); - } - - public String getDecoderSingleByteMappings() { - return b2cTable; - } - - public char[] getEncoderIndex2() { - return c2b; - } - - public char[] getEncoderIndex1() { - return c2bIndex; - } - - private final static String b2cTable = $B2CTABLE$ - - private final static char[] b2c = b2cTable.toCharArray(); - private final static char[] c2b = new char[$C2BLENGTH$]; - private final static char[] c2bIndex = new char[0x100]; - - static { - char[] b2cMap = b2c; - char[] c2bNR = null; - $NONROUNDTRIP_B2C$ - $NONROUNDTRIP_C2B$ - SingleByte.initC2B(b2cMap, c2bNR, c2b, c2bIndex); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/tools/CharsetMapping/SingleByte-X.java.template Mon Jan 11 23:25:20 2010 -0800 @@ -0,0 +1,83 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package $PACKAGE$; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import sun.nio.cs.StandardCharsets; +import sun.nio.cs.SingleByte; +import sun.nio.cs.HistoricallyNamedCharset; +import static sun.nio.cs.CharsetMapping.*; + +public class $NAME_CLZ$ extends Charset implements HistoricallyNamedCharset +{ + public $NAME_CLZ$() { + super("$NAME_CS$", $NAME_ALIASES$); + } + + public String historicalName() { + return "$NAME_HIS$"; + } + + public boolean contains(Charset cs) { + $CONTAINS$; + } + + public CharsetDecoder newDecoder() { + return new SingleByte.Decoder(this, b2c); + } + + public CharsetEncoder newEncoder() { + return new SingleByte.Encoder(this, c2b, c2bIndex); + } + + public String getDecoderSingleByteMappings() { + return b2cTable; + } + + public char[] getEncoderIndex2() { + return c2b; + } + + public char[] getEncoderIndex1() { + return c2bIndex; + } + + private final static String b2cTable = $B2CTABLE$ + + private final static char[] b2c = b2cTable.toCharArray(); + private final static char[] c2b = new char[$C2BLENGTH$]; + private final static char[] c2bIndex = new char[0x100]; + + static { + char[] b2cMap = b2c; + char[] c2bNR = null; + $NONROUNDTRIP_B2C$ + $NONROUNDTRIP_C2B$ + SingleByte.initC2B(b2cMap, c2bNR, c2b, c2bIndex); + } +}
--- a/jdk/make/tools/src/build/tools/charsetmapping/GenerateDBCS.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/tools/src/build/tools/charsetmapping/GenerateDBCS.java Mon Jan 11 23:25:20 2010 -0800 @@ -63,7 +63,7 @@ int b2Min = toInteger(fields[8]); int b2Max = toInteger(fields[9]); System.out.printf("%s,%s,%s,%b,%s%n", clzName, csName, hisName, isASCII, pkgName); - genClass(args[0], args[1], "DoubleByte-X.java", + genClass(args[0], args[1], "DoubleByte-X.java.template", clzName, csName, hisName, pkgName, isASCII, type, b1Min, b1Max, b2Min, b2Max);
--- a/jdk/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java Mon Jan 11 23:25:20 2010 -0800 @@ -55,7 +55,7 @@ String pkgName = fields[4]; System.out.printf("%s,%s,%s,%b,%s%n", clzName, csName, hisName, isASCII, pkgName); - genClass(args[0], args[1], "SingleByte-X.java", + genClass(args[0], args[1], "SingleByte-X.java.template", clzName, csName, hisName, pkgName, isASCII); } }
--- a/jdk/src/share/bin/java.c Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/bin/java.c Mon Jan 11 23:25:20 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2009 Sun Microsystems, Inc. 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 @@ -41,15 +41,13 @@ * options are turned into "-foo" options to the vm. This option * filtering is handled in a number of places in the launcher, some of * it in machine-dependent code. In this file, the function - * CheckJVMType removes vm style options and TranslateApplicationArgs - * removes "-J" prefixes. On unix platforms, the - * CreateExecutionEnvironment function from the unix java_md.c file - * processes and removes -d<n> options. However, in case - * CreateExecutionEnvironment does not need to exec because - * LD_LIBRARY_PATH is set acceptably and the data model does not need - * to be changed, ParseArguments will screen out the redundant -d<n> - * options and prevent them from being passed to the vm; this is done - * by RemovableOption. + * CheckJvmType removes vm style options and TranslateApplicationArgs + * removes "-J" prefixes. The CreateExecutionEnvironment function processes + * and removes -d<n> options. On unix, there is a possibility that the running + * data model may not match to the desired data model, in this case an exec is + * required to start the desired model. If the data models match, then + * ParseArguments will remove the -d<n> flags. If the data models do not match + * the CreateExecutionEnviroment will remove the -d<n> flags. */ @@ -1891,11 +1889,11 @@ * Return JNI_TRUE for an option string that has no effect but should * _not_ be passed on to the vm; return JNI_FALSE otherwise. On * Solaris SPARC, this screening needs to be done if: - * 1) LD_LIBRARY_PATH does _not_ need to be reset and - * 2) -d32 or -d64 is passed to a binary with a matching data model - * (the exec in SetLibraryPath removes -d<n> options and points the - * exec to the proper binary). When this exec is not done, these options - * would end up getting passed onto the vm. + * -d32 or -d64 is passed to a binary with an unmatched data model + * (the exec in CreateExecutionEnvironment removes -d<n> options and points the + * exec to the proper binary). In the case of when the data model and the + * requested version is matched, an exec would not occur, and these options + * were erroneously passed to the vm. */ jboolean RemovableOption(char * option)
--- a/jdk/src/share/classes/com/sun/beans/WeakCache.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/beans/WeakCache.java Mon Jan 11 23:25:20 2010 -0800 @@ -81,4 +81,11 @@ this.map.remove(key); } } + + /** + * Removes all of the mappings from this cache. + */ + public void clear() { + this.map.clear(); + } }
--- a/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java Mon Jan 11 23:25:20 2010 -0800 @@ -36,7 +36,7 @@ /** * This class constitutes the core of HMAC-<MD> algorithms, where - * <MD> can be SHA1 or MD5, etc. + * <MD> can be SHA1 or MD5, etc. See RFC 2104 for spec. * * It also contains the implementation classes for the SHA-256, * SHA-384, and SHA-512 HMACs. @@ -116,7 +116,7 @@ } byte[] secret = key.getEncoded(); - if (secret == null || secret.length == 0) { + if (secret == null) { throw new InvalidKeyException("Missing key data"); }
--- a/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java Mon Jan 11 23:25:20 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,21 +25,19 @@ package com.sun.crypto.provider; -import java.io.*; +import java.io.ObjectStreamException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.util.Arrays; import java.security.KeyRep; import java.security.GeneralSecurityException; -import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.spec.InvalidKeySpecException; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.PBEKeySpec; -import javax.crypto.spec.SecretKeySpec; /** * This class represents a PBE key derived using PBKDF2 defined @@ -123,7 +121,7 @@ this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength); } - private static byte[] deriveKey(Mac prf, byte[] password, byte[] salt, + private static byte[] deriveKey(final Mac prf, final byte[] password, byte[] salt, int iterCount, int keyLengthInBit) { int keyLength = keyLengthInBit/8; byte[] key = new byte[keyLength]; @@ -133,7 +131,34 @@ int intR = keyLength - (intL - 1)*hlen; // residue byte[] ui = new byte[hlen]; byte[] ti = new byte[hlen]; - SecretKey macKey = new SecretKeySpec(password, prf.getAlgorithm()); + // SecretKeySpec cannot be used, since password can be empty here. + SecretKey macKey = new SecretKey() { + @Override + public String getAlgorithm() { + return prf.getAlgorithm(); + } + @Override + public String getFormat() { + return "RAW"; + } + @Override + public byte[] getEncoded() { + return password; + } + @Override + public int hashCode() { + return Arrays.hashCode(password) * 41 + + prf.getAlgorithm().toLowerCase().hashCode(); + } + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (this.getClass() != obj.getClass()) return false; + SecretKey sk = (SecretKey)obj; + return prf.getAlgorithm().equalsIgnoreCase(sk.getAlgorithm()) && + Arrays.equals(password, sk.getEncoded()); + } + }; prf.init(macKey); byte[] ibytes = new byte[4]; @@ -230,7 +255,7 @@ * @throws ObjectStreamException if a new object representing * this PBE key could not be created */ - private Object writeReplace() throws java.io.ObjectStreamException { + private Object writeReplace() throws ObjectStreamException { return new KeyRep(KeyRep.Type.SECRET, getAlgorithm(), getFormat(), getEncoded()); }
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java Mon Jan 11 23:25:20 2010 -0800 @@ -24,7 +24,6 @@ */ package com.sun.java.swing.plaf.gtk; -import sun.swing.plaf.synth.SynthUI; import sun.awt.UNIXToolkit; import javax.swing.plaf.synth.*;
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java Mon Jan 11 23:25:20 2010 -0800 @@ -26,6 +26,7 @@ package com.sun.jmx.mbeanserver; import java.lang.annotation.Annotation; +import java.lang.ref.SoftReference; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -33,8 +34,13 @@ import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.List; +import java.util.LinkedList; +import java.util.Locale; import java.util.Map; +import java.util.WeakHashMap; import javax.management.Descriptor; import javax.management.DescriptorKey; @@ -506,11 +512,25 @@ } else { // Java Beans introspection // - BeanInfo bi = java.beans.Introspector.getBeanInfo(complex.getClass()); - PropertyDescriptor[] pds = bi.getPropertyDescriptors(); - for (PropertyDescriptor pd : pds) - if (pd.getName().equals(element)) - return pd.getReadMethod().invoke(complex); + Class<?> clazz = complex.getClass(); + Method readMethod = null; + if (BeansHelper.isAvailable()) { + Object bi = BeansHelper.getBeanInfo(clazz); + Object[] pds = BeansHelper.getPropertyDescriptors(bi); + for (Object pd: pds) { + if (BeansHelper.getPropertyName(pd).equals(element)) { + readMethod = BeansHelper.getReadMethod(pd); + break; + } + } + } else { + // Java Beans not available so use simple introspection + // to locate method + readMethod = SimpleIntrospector.getReadMethod(clazz, element); + } + if (readMethod != null) + return readMethod.invoke(complex); + throw new AttributeNotFoundException( "Could not find the getter method for the property " + element + " using the Java Beans introspector"); @@ -524,4 +544,235 @@ new AttributeNotFoundException(e.getMessage()), e); } } + + /** + * A simple introspector that uses reflection to analyze a class and + * identify its "getter" methods. This class is intended for use only when + * Java Beans is not present (which implies that there isn't explicit + * information about the bean available). + */ + private static class SimpleIntrospector { + private SimpleIntrospector() { } + + private static final String GET_METHOD_PREFIX = "get"; + private static final String IS_METHOD_PREFIX = "is"; + + // cache to avoid repeated lookups + private static final Map<Class<?>,SoftReference<List<Method>>> cache = + Collections.synchronizedMap( + new WeakHashMap<Class<?>,SoftReference<List<Method>>> ()); + + /** + * Returns the list of methods cached for the given class, or {@code null} + * if not cached. + */ + private static List<Method> getCachedMethods(Class<?> clazz) { + // return cached methods if possible + SoftReference<List<Method>> ref = cache.get(clazz); + if (ref != null) { + List<Method> cached = ref.get(); + if (cached != null) + return cached; + } + return null; + } + + /** + * Returns {@code true} if the given method is a "getter" method (where + * "getter" method is a public method of the form getXXX or "boolean + * isXXX") + */ + static boolean isReadMethod(Method method) { + // ignore static methods + int modifiers = method.getModifiers(); + if (Modifier.isStatic(modifiers)) + return false; + + String name = method.getName(); + Class<?>[] paramTypes = method.getParameterTypes(); + int paramCount = paramTypes.length; + + if (paramCount == 0 && name.length() > 2) { + // boolean isXXX() + if (name.startsWith(IS_METHOD_PREFIX)) + return (method.getReturnType() == boolean.class); + // getXXX() + if (name.length() > 3 && name.startsWith(GET_METHOD_PREFIX)) + return (method.getReturnType() != void.class); + } + return false; + } + + /** + * Returns the list of "getter" methods for the given class. The list + * is ordered so that isXXX methods appear before getXXX methods - this + * is for compatability with the JavaBeans Introspector. + */ + static List<Method> getReadMethods(Class<?> clazz) { + // return cached result if available + List<Method> cachedResult = getCachedMethods(clazz); + if (cachedResult != null) + return cachedResult; + + // get list of public methods, filtering out methods that have + // been overridden to return a more specific type. + List<Method> methods = + StandardMBeanIntrospector.getInstance().getMethods(clazz); + methods = MBeanAnalyzer.eliminateCovariantMethods(methods); + + // filter out the non-getter methods + List<Method> result = new LinkedList<Method>(); + for (Method m: methods) { + if (isReadMethod(m)) { + // favor isXXX over getXXX + if (m.getName().startsWith(IS_METHOD_PREFIX)) { + result.add(0, m); + } else { + result.add(m); + } + } + } + + // add result to cache + cache.put(clazz, new SoftReference<List<Method>>(result)); + + return result; + } + + /** + * Returns the "getter" to read the given property from the given class or + * {@code null} if no method is found. + */ + static Method getReadMethod(Class<?> clazz, String property) { + // first character in uppercase (compatability with JavaBeans) + property = property.substring(0, 1).toUpperCase(Locale.ENGLISH) + + property.substring(1); + String getMethod = GET_METHOD_PREFIX + property; + String isMethod = IS_METHOD_PREFIX + property; + for (Method m: getReadMethods(clazz)) { + String name = m.getName(); + if (name.equals(isMethod) || name.equals(getMethod)) { + return m; + } + } + return null; + } + } + + /** + * A class that provides access to the JavaBeans Introspector and + * PropertyDescriptors without creating a static dependency on java.beans. + */ + private static class BeansHelper { + private static final Class<?> introspectorClass = + getClass("java.beans.Introspector"); + private static final Class<?> beanInfoClass = + (introspectorClass == null) ? null : getClass("java.beans.BeanInfo"); + private static final Class<?> getPropertyDescriptorClass = + (beanInfoClass == null) ? null : getClass("java.beans.PropertyDescriptor"); + + private static final Method getBeanInfo = + getMethod(introspectorClass, "getBeanInfo", Class.class); + private static final Method getPropertyDescriptors = + getMethod(beanInfoClass, "getPropertyDescriptors"); + private static final Method getPropertyName = + getMethod(getPropertyDescriptorClass, "getName"); + private static final Method getReadMethod = + getMethod(getPropertyDescriptorClass, "getReadMethod"); + + private static Class<?> getClass(String name) { + try { + return Class.forName(name, true, null); + } catch (ClassNotFoundException e) { + return null; + } + } + private static Method getMethod(Class<?> clazz, + String name, + Class<?>... paramTypes) + { + if (clazz != null) { + try { + return clazz.getMethod(name, paramTypes); + } catch (NoSuchMethodException e) { + throw new AssertionError(e); + } + } else { + return null; + } + } + + private BeansHelper() { } + + /** + * Returns {@code true} if java.beans is available. + */ + static boolean isAvailable() { + return introspectorClass != null; + } + + /** + * Invokes java.beans.Introspector.getBeanInfo(Class) + */ + static Object getBeanInfo(Class<?> clazz) throws Exception { + try { + return getBeanInfo.invoke(null, clazz); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof Exception) + throw (Exception)cause; + throw new AssertionError(e); + } catch (IllegalAccessException iae) { + throw new AssertionError(iae); + } + } + + /** + * Invokes java.beans.BeanInfo.getPropertyDescriptors() + */ + static Object[] getPropertyDescriptors(Object bi) { + try { + return (Object[])getPropertyDescriptors.invoke(bi); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) + throw (RuntimeException)cause; + throw new AssertionError(e); + } catch (IllegalAccessException iae) { + throw new AssertionError(iae); + } + } + + /** + * Invokes java.beans.PropertyDescriptor.getName() + */ + static String getPropertyName(Object pd) { + try { + return (String)getPropertyName.invoke(pd); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) + throw (RuntimeException)cause; + throw new AssertionError(e); + } catch (IllegalAccessException iae) { + throw new AssertionError(iae); + } + } + + /** + * Invokes java.beans.PropertyDescriptor.getReadMethod() + */ + static Method getReadMethod(Object pd) { + try { + return (Method)getReadMethod.invoke(pd); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) + throw (RuntimeException)cause; + throw new AssertionError(e); + } catch (IllegalAccessException iae) { + throw new AssertionError(iae); + } + } + } }
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java Mon Jan 11 23:25:20 2010 -0800 @@ -175,7 +175,7 @@ /** * Get the methods to be analyzed to build the MBean interface. */ - List<Method> getMethods(final Class<?> mbeanType) throws Exception { + List<Method> getMethods(final Class<?> mbeanType) { return Arrays.asList(mbeanType.getMethods()); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiver.java Mon Jan 11 23:25:20 2010 -0800 @@ -0,0 +1,41 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.sun.media.sound; + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.Receiver; + +/** + * A Receiver with reference to it's MidiDevice object. + * + * @author Karl Helgason + */ +public interface MidiDeviceReceiver extends Receiver { + + /** Obtains the MidiDevice object associated with this Receiver. + */ + public MidiDevice getMidiDevice(); + +}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftAudioBuffer.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/media/sound/SoftAudioBuffer.java Mon Jan 11 23:25:20 2010 -0800 @@ -48,6 +48,30 @@ converter = AudioFloatConverter.getConverter(format); } + public void swap(SoftAudioBuffer swap) + { + int bak_size = size; + float[] bak_buffer = buffer; + boolean bak_empty = empty; + AudioFormat bak_format = format; + AudioFloatConverter bak_converter = converter; + byte[] bak_converter_buffer = converter_buffer; + + size = swap.size; + buffer = swap.buffer; + empty = swap.empty; + format = swap.format; + converter = swap.converter; + converter_buffer = swap.converter_buffer; + + swap.size = bak_size; + swap.buffer = bak_buffer; + swap.empty = bak_empty; + swap.format = bak_format; + swap.converter = bak_converter; + swap.converter_buffer = bak_converter_buffer; + } + public AudioFormat getFormat() { return format; }
--- a/jdk/src/share/classes/com/sun/media/sound/SoftChannel.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/media/sound/SoftChannel.java Mon Jan 11 23:25:20 2010 -0800 @@ -218,6 +218,15 @@ } private int findFreeVoice(int x) { + if(x == -1) + { + // x = -1 means that there where no available voice + // last time we called findFreeVoice + // and it hasn't changed because no audio has been + // rendered in the meantime. + // Therefore we have to return -1. + return -1; + } for (int i = x; i < voices.length; i++) if (!voices[i].active) return i; @@ -328,7 +337,7 @@ } protected void initVoice(SoftVoice voice, SoftPerformer p, int voiceID, - int noteNumber, int velocity, ModelConnectionBlock[] connectionBlocks, + int noteNumber, int velocity, int delay, ModelConnectionBlock[] connectionBlocks, ModelChannelMixer channelmixer, boolean releaseTriggered) { if (voice.active) { // Voice is active , we must steal the voice @@ -363,7 +372,7 @@ voice.objects.put("midi_cc", co_midi_cc); voice.objects.put("midi_rpn", co_midi_rpn); voice.objects.put("midi_nrpn", co_midi_nrpn); - voice.noteOn(noteNumber, velocity); + voice.noteOn(noteNumber, velocity, delay); voice.setMute(mute); voice.setSoloMute(solomute); if (releaseTriggered) @@ -399,14 +408,21 @@ } public void noteOn(int noteNumber, int velocity) { + noteOn(noteNumber, velocity, 0); + } + + /* A special noteOn with delay parameter, which is used to + * start note within control buffers. + */ + protected void noteOn(int noteNumber, int velocity, int delay) { noteNumber = restrict7Bit(noteNumber); velocity = restrict7Bit(velocity); - noteOn_internal(noteNumber, velocity); + noteOn_internal(noteNumber, velocity, delay); if (current_mixer != null) current_mixer.noteOn(noteNumber, velocity); } - private void noteOn_internal(int noteNumber, int velocity) { + private void noteOn_internal(int noteNumber, int velocity, int delay) { if (velocity == 0) { noteOff_internal(noteNumber, 64); @@ -490,6 +506,7 @@ int tunedKey = (int)(Math.round(tuning.getTuning()[noteNumber]/100.0)); play_noteNumber = noteNumber; play_velocity = velocity; + play_delay = delay; play_releasetriggered = false; lastVelocity[noteNumber] = velocity; current_director.noteOn(tunedKey, velocity); @@ -594,6 +611,7 @@ play_noteNumber = noteNumber; play_velocity = lastVelocity[noteNumber]; play_releasetriggered = true; + play_delay = 0; current_director.noteOff(tunedKey, velocity); } @@ -604,12 +622,14 @@ private int voiceNo = 0; private int play_noteNumber = 0; private int play_velocity = 0; + private int play_delay = 0; private boolean play_releasetriggered = false; public void play(int performerIndex, ModelConnectionBlock[] connectionBlocks) { int noteNumber = play_noteNumber; int velocity = play_velocity; + int delay = play_delay; boolean releasetriggered = play_releasetriggered; SoftPerformer p = current_instrument.getPerformers()[performerIndex]; @@ -633,7 +653,7 @@ if (voiceNo == -1) return; - initVoice(voices[voiceNo], p, prevVoiceID, noteNumber, velocity, + initVoice(voices[voiceNo], p, prevVoiceID, noteNumber, velocity, delay, connectionBlocks, current_mixer, releasetriggered); }
--- a/jdk/src/share/classes/com/sun/media/sound/SoftLimiter.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/media/sound/SoftLimiter.java Mon Jan 11 23:25:20 2010 -0800 @@ -79,7 +79,7 @@ if (silentcounter > 60) { if (!mix) { bufferLout.clear(); - bufferRout.clear(); + if (bufferRout != null) bufferRout.clear(); } return; }
--- a/jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java Mon Jan 11 23:25:20 2010 -0800 @@ -26,7 +26,6 @@ import java.io.IOException; import java.io.InputStream; -import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.Set; @@ -46,28 +45,37 @@ */ public class SoftMainMixer { + // A private class thats contains a ModelChannelMixer and it's private buffers. + // This becomes necessary when we want to have separate delay buffers for each channel mixer. + private class SoftChannelMixerContainer + { + ModelChannelMixer mixer; + SoftAudioBuffer[] buffers; + } + public final static int CHANNEL_LEFT = 0; public final static int CHANNEL_RIGHT = 1; public final static int CHANNEL_MONO = 2; - public final static int CHANNEL_EFFECT1 = 3; - public final static int CHANNEL_EFFECT2 = 4; - public final static int CHANNEL_EFFECT3 = 5; - public final static int CHANNEL_EFFECT4 = 6; + public final static int CHANNEL_DELAY_LEFT = 3; + public final static int CHANNEL_DELAY_RIGHT = 4; + public final static int CHANNEL_DELAY_MONO = 5; + public final static int CHANNEL_EFFECT1 = 6; + public final static int CHANNEL_EFFECT2 = 7; + public final static int CHANNEL_DELAY_EFFECT1 = 8; + public final static int CHANNEL_DELAY_EFFECT2 = 9; public final static int CHANNEL_LEFT_DRY = 10; public final static int CHANNEL_RIGHT_DRY = 11; public final static int CHANNEL_SCRATCH1 = 12; public final static int CHANNEL_SCRATCH2 = 13; - public final static int CHANNEL_CHANNELMIXER_LEFT = 14; - public final static int CHANNEL_CHANNELMIXER_RIGHT = 15; - public final static int CHANNEL_CHANNELMIXER_MONO = 16; protected boolean active_sensing_on = false; private long msec_last_activity = -1; private boolean pusher_silent = false; private int pusher_silent_count = 0; - private long msec_pos = 0; + private long sample_pos = 0; protected boolean readfully = true; private Object control_mutex; private SoftSynthesizer synth; + private float samplerate = 44100; private int nrofchannels = 2; private SoftVoice[] voicestatus = null; private SoftAudioBuffer[] buffers; @@ -75,7 +83,10 @@ private SoftAudioProcessor chorus; private SoftAudioProcessor agc; private long msec_buffer_len = 0; + private int buffer_len = 0; protected TreeMap<Long, Object> midimessages = new TreeMap<Long, Object>(); + private int delay_midievent = 0; + private int max_delay_midievent = 0; double last_volume_left = 1.0; double last_volume_right = 1.0; private double[] co_master_balance = new double[1]; @@ -83,9 +94,9 @@ private double[] co_master_coarse_tuning = new double[1]; private double[] co_master_fine_tuning = new double[1]; private AudioInputStream ais; - private Set<ModelChannelMixer> registeredMixers = null; + private Set<SoftChannelMixerContainer> registeredMixers = null; private Set<ModelChannelMixer> stoppedMixers = null; - private ModelChannelMixer[] cur_registeredMixers = null; + private SoftChannelMixerContainer[] cur_registeredMixers = null; protected SoftControl co_master = new SoftControl() { double[] balance = co_master_balance; @@ -413,26 +424,68 @@ Iterator<Entry<Long, Object>> iter = midimessages.entrySet().iterator(); while (iter.hasNext()) { Entry<Long, Object> entry = iter.next(); - if (entry.getKey() > (timeStamp + 100)) + if (entry.getKey() >= (timeStamp + msec_buffer_len)) return; + long msec_delay = entry.getKey() - timeStamp; + delay_midievent = (int)(msec_delay * (samplerate / 1000000.0) + 0.5); + if(delay_midievent > max_delay_midievent) + delay_midievent = max_delay_midievent; + if(delay_midievent < 0) + delay_midievent = 0; processMessage(entry.getValue()); iter.remove(); } + delay_midievent = 0; } protected void processAudioBuffers() { + + if(synth.weakstream != null && synth.weakstream.silent_samples != 0) + { + sample_pos += synth.weakstream.silent_samples; + synth.weakstream.silent_samples = 0; + } + for (int i = 0; i < buffers.length; i++) { - buffers[i].clear(); + if(i != CHANNEL_DELAY_LEFT && + i != CHANNEL_DELAY_RIGHT && + i != CHANNEL_DELAY_MONO && + i != CHANNEL_DELAY_EFFECT1 && + i != CHANNEL_DELAY_EFFECT2) + buffers[i].clear(); + } + + if(!buffers[CHANNEL_DELAY_LEFT].isSilent()) + { + buffers[CHANNEL_LEFT].swap(buffers[CHANNEL_DELAY_LEFT]); + } + if(!buffers[CHANNEL_DELAY_RIGHT].isSilent()) + { + buffers[CHANNEL_RIGHT].swap(buffers[CHANNEL_DELAY_RIGHT]); + } + if(!buffers[CHANNEL_DELAY_MONO].isSilent()) + { + buffers[CHANNEL_MONO].swap(buffers[CHANNEL_DELAY_MONO]); + } + if(!buffers[CHANNEL_DELAY_EFFECT1].isSilent()) + { + buffers[CHANNEL_EFFECT1].swap(buffers[CHANNEL_DELAY_EFFECT1]); + } + if(!buffers[CHANNEL_DELAY_EFFECT2].isSilent()) + { + buffers[CHANNEL_EFFECT2].swap(buffers[CHANNEL_DELAY_EFFECT2]); } double volume_left; double volume_right; - ModelChannelMixer[] act_registeredMixers; + SoftChannelMixerContainer[] act_registeredMixers; // perform control logic synchronized (control_mutex) { + long msec_pos = (long)(sample_pos * (1000000.0 / samplerate)); + processMessages(msec_pos); if (active_sensing_on) { @@ -450,7 +503,7 @@ for (int i = 0; i < voicestatus.length; i++) if (voicestatus[i].active) voicestatus[i].processControlLogic(); - msec_pos += msec_buffer_len; + sample_pos += buffer_len; double volume = co_master_volume[0]; volume_left = volume; @@ -469,7 +522,7 @@ if (cur_registeredMixers == null) { if (registeredMixers != null) { cur_registeredMixers = - new ModelChannelMixer[registeredMixers.size()]; + new SoftChannelMixerContainer[registeredMixers.size()]; registeredMixers.toArray(cur_registeredMixers); } } @@ -483,44 +536,61 @@ if (act_registeredMixers != null) { - // Reroute default left,right output - // to channelmixer left,right input/output + // Make backup of left,right,mono channels SoftAudioBuffer leftbak = buffers[CHANNEL_LEFT]; SoftAudioBuffer rightbak = buffers[CHANNEL_RIGHT]; SoftAudioBuffer monobak = buffers[CHANNEL_MONO]; - buffers[CHANNEL_LEFT] = buffers[CHANNEL_CHANNELMIXER_LEFT]; - buffers[CHANNEL_RIGHT] = buffers[CHANNEL_CHANNELMIXER_RIGHT]; - buffers[CHANNEL_MONO] = buffers[CHANNEL_CHANNELMIXER_MONO]; + SoftAudioBuffer delayleftbak = buffers[CHANNEL_DELAY_LEFT]; + SoftAudioBuffer delayrightbak = buffers[CHANNEL_DELAY_RIGHT]; + SoftAudioBuffer delaymonobak = buffers[CHANNEL_DELAY_MONO]; int bufferlen = buffers[CHANNEL_LEFT].getSize(); float[][] cbuffer = new float[nrofchannels][]; - cbuffer[0] = buffers[CHANNEL_LEFT].array(); - if (nrofchannels != 1) - cbuffer[1] = buffers[CHANNEL_RIGHT].array(); - float[][] obuffer = new float[nrofchannels][]; obuffer[0] = leftbak.array(); if (nrofchannels != 1) obuffer[1] = rightbak.array(); - for (ModelChannelMixer cmixer : act_registeredMixers) { - for (int i = 0; i < cbuffer.length; i++) - Arrays.fill(cbuffer[i], 0); + for (SoftChannelMixerContainer cmixer : act_registeredMixers) { + + // Reroute default left,right output + // to channelmixer left,right input/output + buffers[CHANNEL_LEFT] = cmixer.buffers[CHANNEL_LEFT]; + buffers[CHANNEL_RIGHT] = cmixer.buffers[CHANNEL_RIGHT]; + buffers[CHANNEL_MONO] = cmixer.buffers[CHANNEL_MONO]; + buffers[CHANNEL_DELAY_LEFT] = cmixer.buffers[CHANNEL_DELAY_LEFT]; + buffers[CHANNEL_DELAY_RIGHT] = cmixer.buffers[CHANNEL_DELAY_RIGHT]; + buffers[CHANNEL_DELAY_MONO] = cmixer.buffers[CHANNEL_DELAY_MONO]; + + buffers[CHANNEL_LEFT].clear(); + buffers[CHANNEL_RIGHT].clear(); buffers[CHANNEL_MONO].clear(); + + if(!buffers[CHANNEL_DELAY_LEFT].isSilent()) + { + buffers[CHANNEL_LEFT].swap(buffers[CHANNEL_DELAY_LEFT]); + } + if(!buffers[CHANNEL_DELAY_RIGHT].isSilent()) + { + buffers[CHANNEL_RIGHT].swap(buffers[CHANNEL_DELAY_RIGHT]); + } + if(!buffers[CHANNEL_DELAY_MONO].isSilent()) + { + buffers[CHANNEL_MONO].swap(buffers[CHANNEL_DELAY_MONO]); + } + + cbuffer[0] = buffers[CHANNEL_LEFT].array(); + if (nrofchannels != 1) + cbuffer[1] = buffers[CHANNEL_RIGHT].array(); + boolean hasactivevoices = false; for (int i = 0; i < voicestatus.length; i++) if (voicestatus[i].active) - if (voicestatus[i].channelmixer == cmixer) { + if (voicestatus[i].channelmixer == cmixer.mixer) { voicestatus[i].processAudioLogic(buffers); hasactivevoices = true; } - if (!cmixer.process(cbuffer, 0, bufferlen)) { - synchronized (control_mutex) { - registeredMixers.remove(cmixer); - cur_registeredMixers = null; - } - } if(!buffers[CHANNEL_MONO].isSilent()) { @@ -542,6 +612,13 @@ } } + if (!cmixer.mixer.process(cbuffer, 0, bufferlen)) { + synchronized (control_mutex) { + registeredMixers.remove(cmixer); + cur_registeredMixers = null; + } + } + for (int i = 0; i < cbuffer.length; i++) { float[] cbuff = cbuffer[i]; float[] obuff = obuffer[i]; @@ -554,7 +631,7 @@ if (stoppedMixers != null) { if (stoppedMixers.contains(cmixer)) { stoppedMixers.remove(cmixer); - cmixer.stop(); + cmixer.mixer.stop(); } } } @@ -565,6 +642,9 @@ buffers[CHANNEL_LEFT] = leftbak; buffers[CHANNEL_RIGHT] = rightbak; buffers[CHANNEL_MONO] = monobak; + buffers[CHANNEL_DELAY_LEFT] = delayleftbak; + buffers[CHANNEL_DELAY_RIGHT] = delayrightbak; + buffers[CHANNEL_DELAY_MONO] = delaymonobak; } @@ -650,14 +730,23 @@ if(buffers[CHANNEL_LEFT].isSilent() && buffers[CHANNEL_RIGHT].isSilent()) { - pusher_silent_count++; - if(pusher_silent_count > 5) + + int midimessages_size; + synchronized (control_mutex) { + midimessages_size = midimessages.size(); + } + + if(midimessages_size == 0) { - pusher_silent_count = 0; - synchronized (control_mutex) { - pusher_silent = true; - if(synth.weakstream != null) - synth.weakstream.setInputStream(null); + pusher_silent_count++; + if(pusher_silent_count > 5) + { + pusher_silent_count = 0; + synchronized (control_mutex) { + pusher_silent = true; + if(synth.weakstream != null) + synth.weakstream.setInputStream(null); + } } } } @@ -672,13 +761,18 @@ // Must only we called within control_mutex synchronization public void activity() { - msec_last_activity = msec_pos; + long silent_samples = 0; if(pusher_silent) { pusher_silent = false; if(synth.weakstream != null) + { synth.weakstream.setInputStream(ais); + silent_samples = synth.weakstream.silent_samples; + } } + msec_last_activity = (long)((sample_pos + silent_samples) + * (1000000.0 / samplerate)); } public void stopMixer(ModelChannelMixer mixer) { @@ -689,15 +783,22 @@ public void registerMixer(ModelChannelMixer mixer) { if (registeredMixers == null) - registeredMixers = new HashSet<ModelChannelMixer>(); - registeredMixers.add(mixer); + registeredMixers = new HashSet<SoftChannelMixerContainer>(); + SoftChannelMixerContainer mixercontainer = new SoftChannelMixerContainer(); + mixercontainer.buffers = new SoftAudioBuffer[6]; + for (int i = 0; i < mixercontainer.buffers.length; i++) { + mixercontainer.buffers[i] = + new SoftAudioBuffer(buffer_len, synth.getFormat()); + } + mixercontainer.mixer = mixer; + registeredMixers.add(mixercontainer); cur_registeredMixers = null; } public SoftMainMixer(SoftSynthesizer synth) { this.synth = synth; - msec_pos = 0; + sample_pos = 0; co_master_balance[0] = 0.5; co_master_volume[0] = 1; @@ -705,14 +806,18 @@ co_master_fine_tuning[0] = 0.5; msec_buffer_len = (long) (1000000.0 / synth.getControlRate()); - + samplerate = synth.getFormat().getSampleRate(); nrofchannels = synth.getFormat().getChannels(); int buffersize = (int) (synth.getFormat().getSampleRate() / synth.getControlRate()); + buffer_len = buffersize; + + max_delay_midievent = buffersize; + control_mutex = synth.control_mutex; - buffers = new SoftAudioBuffer[17]; + buffers = new SoftAudioBuffer[14]; for (int i = 0; i < buffers.length; i++) { buffers[i] = new SoftAudioBuffer(buffersize, synth.getFormat()); } @@ -994,7 +1099,10 @@ switch (cmd) { case ShortMessage.NOTE_ON: - softchannel.noteOn(data1, data2); + if(delay_midievent != 0) + softchannel.noteOn(data1, data2, delay_midievent); + else + softchannel.noteOn(data1, data2); break; case ShortMessage.NOTE_OFF: softchannel.noteOff(data1, data2); @@ -1021,7 +1129,15 @@ } public long getMicrosecondPosition() { - return msec_pos; + if(pusher_silent) + { + if(synth.weakstream != null) + { + return (long)((sample_pos + synth.weakstream.silent_samples) + * (1000000.0 / samplerate)); + } + } + return (long)(sample_pos * (1000000.0 / samplerate)); } public void close() {
--- a/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java Mon Jan 11 23:25:20 2010 -0800 @@ -26,8 +26,8 @@ import java.util.TreeMap; +import javax.sound.midi.MidiDevice; import javax.sound.midi.MidiMessage; -import javax.sound.midi.Receiver; import javax.sound.midi.ShortMessage; /** @@ -35,7 +35,7 @@ * * @author Karl Helgason */ -public class SoftReceiver implements Receiver { +public class SoftReceiver implements MidiDeviceReceiver { protected boolean open = true; private Object control_mutex; @@ -51,6 +51,10 @@ this.midimessages = mainmixer.midimessages; } + public MidiDevice getMidiDevice() { + return synth; + } + public void send(MidiMessage message, long timeStamp) { synchronized (control_mutex) { @@ -60,6 +64,7 @@ if (timeStamp != -1) { synchronized (control_mutex) { + mainmixer.activity(); while (midimessages.get(timeStamp) != null) timeStamp++; if (message instanceof ShortMessage
--- a/jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java Mon Jan 11 23:25:20 2010 -0800 @@ -66,6 +66,8 @@ public SoftAudioPusher pusher = null; public AudioInputStream jitter_stream = null; public SourceDataLine sourceDataLine = null; + public volatile long silent_samples = 0; + private int framesize = 0; private WeakReference<AudioInputStream> weak_stream_link; private AudioFloatConverter converter; private float[] silentbuffer = null; @@ -101,6 +103,8 @@ silentbuffer = new float[flen]; converter.toByteArray(silentbuffer, flen, b, off); + silent_samples += (long)((len / framesize)); + if(pusher != null) if(weak_stream_link.get() == null) { @@ -136,6 +140,7 @@ weak_stream_link = new WeakReference<AudioInputStream>(stream); converter = AudioFloatConverter.getConverter(stream.getFormat()); samplesize = stream.getFormat().getFrameSize() / stream.getFormat().getChannels(); + framesize = stream.getFormat().getFrameSize(); } public AudioInputStream getAudioInputStream()
--- a/jdk/src/share/classes/com/sun/media/sound/SoftVoice.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/media/sound/SoftVoice.java Mon Jan 11 23:25:20 2010 -0800 @@ -43,6 +43,7 @@ private int noteOn_noteNumber = 0; private int noteOn_velocity = 0; private int noteOff_velocity = 0; + private int delay = 0; protected ModelChannelMixer channelmixer = null; protected double tunedKey = 0; protected SoftTuning tuning = null; @@ -294,7 +295,7 @@ tunedKey = tuning.getTuning(noteNumber) / 100.0; } - protected void noteOn(int noteNumber, int velocity) { + protected void noteOn(int noteNumber, int velocity, int delay) { sustain = false; sostenuto = false; @@ -308,6 +309,7 @@ noteOn_noteNumber = noteNumber; noteOn_velocity = velocity; + this.delay = delay; lastMuteValue = 0; lastSoloMuteValue = 0; @@ -562,7 +564,7 @@ if (stealer_channel != null) { stealer_channel.initVoice(this, stealer_performer, - stealer_voiceID, stealer_noteNumber, stealer_velocity, + stealer_voiceID, stealer_noteNumber, stealer_velocity, 0, stealer_extendedConnectionBlocks, stealer_channelmixer, stealer_releaseTriggered); stealer_releaseTriggered = false; @@ -733,23 +735,55 @@ } protected void mixAudioStream(SoftAudioBuffer in, SoftAudioBuffer out, + SoftAudioBuffer dout, float amp_from, float amp_to) { int bufferlen = in.getSize(); if (amp_from < 0.000000001 && amp_to < 0.000000001) return; - if (amp_from == amp_to) { - float[] fout = out.array(); - float[] fin = in.array(); - for (int i = 0; i < bufferlen; i++) - fout[i] += fin[i] * amp_to; - } else { - float amp = amp_from; - float amp_delta = (amp_to - amp_from) / bufferlen; - float[] fout = out.array(); - float[] fin = in.array(); - for (int i = 0; i < bufferlen; i++) { - amp += amp_delta; - fout[i] += fin[i] * amp; + if(dout != null && delay != 0) + { + if (amp_from == amp_to) { + float[] fout = out.array(); + float[] fin = in.array(); + int j = 0; + for (int i = delay; i < bufferlen; i++) + fout[i] += fin[j++] * amp_to; + fout = dout.array(); + for (int i = 0; i < delay; i++) + fout[i] += fin[j++] * amp_to; + } else { + float amp = amp_from; + float amp_delta = (amp_to - amp_from) / bufferlen; + float[] fout = out.array(); + float[] fin = in.array(); + int j = 0; + for (int i = delay; i < bufferlen; i++) { + amp += amp_delta; + fout[i] += fin[j++] * amp; + } + fout = dout.array(); + for (int i = 0; i < delay; i++) { + amp += amp_delta; + fout[i] += fin[j++] * amp; + } + } + } + else + { + if (amp_from == amp_to) { + float[] fout = out.array(); + float[] fin = in.array(); + for (int i = 0; i < bufferlen; i++) + fout[i] += fin[i] * amp_to; + } else { + float amp = amp_from; + float amp_delta = (amp_to - amp_from) / bufferlen; + float[] fout = out.array(); + float[] fin = in.array(); + for (int i = 0; i < bufferlen; i++) { + amp += amp_delta; + fout[i] += fin[i] * amp; + } } } @@ -785,6 +819,13 @@ SoftAudioBuffer mono = buffer[SoftMainMixer.CHANNEL_MONO]; SoftAudioBuffer eff1 = buffer[SoftMainMixer.CHANNEL_EFFECT1]; SoftAudioBuffer eff2 = buffer[SoftMainMixer.CHANNEL_EFFECT2]; + + SoftAudioBuffer dleft = buffer[SoftMainMixer.CHANNEL_DELAY_LEFT]; + SoftAudioBuffer dright = buffer[SoftMainMixer.CHANNEL_DELAY_RIGHT]; + SoftAudioBuffer dmono = buffer[SoftMainMixer.CHANNEL_DELAY_MONO]; + SoftAudioBuffer deff1 = buffer[SoftMainMixer.CHANNEL_DELAY_EFFECT1]; + SoftAudioBuffer deff2 = buffer[SoftMainMixer.CHANNEL_DELAY_EFFECT2]; + SoftAudioBuffer leftdry = buffer[SoftMainMixer.CHANNEL_LEFT_DRY]; SoftAudioBuffer rightdry = buffer[SoftMainMixer.CHANNEL_RIGHT_DRY]; @@ -799,42 +840,42 @@ if (nrofchannels == 1) { out_mixer_left = (out_mixer_left + out_mixer_right) / 2; - mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left); + mixAudioStream(leftdry, left, dleft, last_out_mixer_left, out_mixer_left); if (rightdry != null) - mixAudioStream(rightdry, left, last_out_mixer_left, + mixAudioStream(rightdry, left, dleft, last_out_mixer_left, out_mixer_left); } else { if(rightdry == null && last_out_mixer_left == last_out_mixer_right && out_mixer_left == out_mixer_right) { - mixAudioStream(leftdry, mono, last_out_mixer_left, out_mixer_left); + mixAudioStream(leftdry, mono, dmono, last_out_mixer_left, out_mixer_left); } else { - mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left); + mixAudioStream(leftdry, left, dleft, last_out_mixer_left, out_mixer_left); if (rightdry != null) - mixAudioStream(rightdry, right, last_out_mixer_right, + mixAudioStream(rightdry, right, dright, last_out_mixer_right, out_mixer_right); else - mixAudioStream(leftdry, right, last_out_mixer_right, + mixAudioStream(leftdry, right, dright, last_out_mixer_right, out_mixer_right); } } if (rightdry == null) { - mixAudioStream(leftdry, eff1, last_out_mixer_effect1, + mixAudioStream(leftdry, eff1, deff1, last_out_mixer_effect1, out_mixer_effect1); - mixAudioStream(leftdry, eff2, last_out_mixer_effect2, + mixAudioStream(leftdry, eff2, deff2, last_out_mixer_effect2, out_mixer_effect2); } else { - mixAudioStream(leftdry, eff1, last_out_mixer_effect1 * 0.5f, + mixAudioStream(leftdry, eff1, deff1, last_out_mixer_effect1 * 0.5f, out_mixer_effect1 * 0.5f); - mixAudioStream(leftdry, eff2, last_out_mixer_effect2 * 0.5f, + mixAudioStream(leftdry, eff2, deff2, last_out_mixer_effect2 * 0.5f, out_mixer_effect2 * 0.5f); - mixAudioStream(rightdry, eff1, last_out_mixer_effect1 * 0.5f, + mixAudioStream(rightdry, eff1, deff1, last_out_mixer_effect1 * 0.5f, out_mixer_effect1 * 0.5f); - mixAudioStream(rightdry, eff2, last_out_mixer_effect2 * 0.5f, + mixAudioStream(rightdry, eff2, deff2, last_out_mixer_effect2 * 0.5f, out_mixer_effect2 * 0.5f); }
--- a/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java Mon Jan 11 23:25:20 2010 -0800 @@ -34,8 +34,6 @@ import java.security.AccessController; import java.security.CodeSource; -import java.security.Identity; -import java.security.IdentityScope; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.Permission; @@ -267,7 +265,7 @@ private boolean initialized = false; private boolean expandProperties = true; - private boolean ignoreIdentityScope = false; + private boolean ignoreIdentityScope = true; // for use with the reflection API @@ -459,9 +457,6 @@ } } - /** the scope to check */ - private static IdentityScope scope = null; - /** * Checks public key. If it is marked as trusted in * the identity database, add it to the policy
--- a/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java Mon Jan 11 23:25:20 2010 -0800 @@ -99,4 +99,58 @@ */ public Object inquireSecContext(InquireType type) throws GSSException; + + /** + * Requests that the delegation policy be respected. When a true value is + * requested, the underlying context would use the delegation policy + * defined by the environment as a hint to determine whether credentials + * delegation should be performed. This request can only be made on the + * context initiator's side and it has to be done prior to the first + * call to <code>initSecContext</code>. + * <p> + * When this flag is false, delegation will only be tried when the + * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} + * is true. + * <p> + * When this flag is true but the + * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} + * is false, delegation will be only tried if the delegation policy permits + * delegation. + * <p> + * When both this flag and the + * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} + * are true, delegation will be always tried. However, if the delegation + * policy does not permit delegation, the value of + * {@link #getDelegPolicyState} will be false, even + * if delegation is performed successfully. + * <p> + * In any case, if the delegation is not successful, the value returned + * by {@link GSSContext#getCredDelegState()} is false, and the value + * returned by {@link #getDelegPolicyState()} is also false. + * <p> + * Not all mechanisms support delegation policy. Therefore, the + * application should check to see if the request was honored with the + * {@link #getDelegPolicyState() getDelegPolicyState} method. When + * delegation policy is not supported, <code>requestDelegPolicy</code> + * should return silently without throwing an exception. + * <p> + * Note: for the Kerberos 5 mechanism, the delegation policy is expressed + * through the OK-AS-DELEGATE flag in the service ticket. When it's true, + * the KDC permits delegation to the target server. In a cross-realm + * environment, in order for delegation be permitted, all cross-realm TGTs + * on the authentication path must also have the OK-AS-DELAGATE flags set. + * @param state true if the policy should be respected + * @throws GSSException containing the following + * major error codes: + * {@link GSSException#FAILURE GSSException.FAILURE} + */ + public void requestDelegPolicy(boolean state) throws GSSException; + + /** + * Returns the delegation policy response. Called after a security context + * is established. This method can be only called on the initiator's side. + * See {@link ExtendedGSSContext#requestDelegPolicy}. + * @return the delegation policy response + */ + public boolean getDelegPolicyState(); }
--- a/jdk/src/share/classes/com/sun/tools/hat/internal/model/JavaStatic.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/model/JavaStatic.java Mon Jan 11 23:25:20 2010 -0800 @@ -57,7 +57,10 @@ id = ((JavaObjectRef)value).getId(); } value = value.dereference(snapshot, field); - if (value.isHeapAllocated()) { + if (value.isHeapAllocated() && + clazz.getLoader() == snapshot.getNullThing()) { + // static fields are only roots if they are in classes + // loaded by the root classloader. JavaHeapObject ho = (JavaHeapObject) value; String s = "Static reference from " + clazz.getName() + "." + field.getName();
--- a/jdk/src/share/classes/com/sun/tracing/ProviderFactory.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/com/sun/tracing/ProviderFactory.java Mon Jan 11 23:25:20 2010 -0800 @@ -4,7 +4,10 @@ import java.util.HashSet; import java.io.PrintStream; import java.lang.reflect.Field; -import java.util.logging.Logger; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import sun.security.action.GetPropertyAction; import sun.tracing.NullProviderFactory; import sun.tracing.PrintStreamProviderFactory; @@ -52,23 +55,17 @@ HashSet<ProviderFactory> factories = new HashSet<ProviderFactory>(); // Try to instantiate a DTraceProviderFactory - String prop = null; - try { prop = System.getProperty("com.sun.tracing.dtrace"); } - catch (java.security.AccessControlException e) { - Logger.getAnonymousLogger().fine( - "Cannot access property com.sun.tracing.dtrace"); - } + String prop = AccessController.doPrivileged( + new GetPropertyAction("com.sun.tracing.dtrace")); + if ( (prop == null || !prop.equals("disable")) && DTraceProviderFactory.isSupported() ) { factories.add(new DTraceProviderFactory()); } // Try to instantiate an output stream factory - try { prop = System.getProperty("sun.tracing.stream"); } - catch (java.security.AccessControlException e) { - Logger.getAnonymousLogger().fine( - "Cannot access property sun.tracing.stream"); - } + prop = AccessController.doPrivileged( + new GetPropertyAction("sun.tracing.stream")); if (prop != null) { for (String spec : prop.split(",")) { PrintStream ps = getPrintStreamFromSpec(spec); @@ -89,22 +86,29 @@ } } - private static PrintStream getPrintStreamFromSpec(String spec) { + private static PrintStream getPrintStreamFromSpec(final String spec) { try { // spec is in the form of <class>.<field>, where <class> is // a fully specified class name, and <field> is a static member // in that class. The <field> must be a 'PrintStream' or subtype // in order to be used. - int fieldpos = spec.lastIndexOf('.'); - Class<?> cls = Class.forName(spec.substring(0, fieldpos)); - Field f = cls.getField(spec.substring(fieldpos + 1)); - Class<?> fieldType = f.getType(); + final int fieldpos = spec.lastIndexOf('.'); + final Class<?> cls = Class.forName(spec.substring(0, fieldpos)); + + Field f = AccessController.doPrivileged(new PrivilegedExceptionAction<Field>() { + public Field run() throws NoSuchFieldException { + return cls.getField(spec.substring(fieldpos + 1)); + } + }); + return (PrintStream)f.get(null); - } catch (Exception e) { - Logger.getAnonymousLogger().warning( - "Could not parse sun.tracing.stream property: " + e); + } catch (ClassNotFoundException e) { + throw new AssertionError(e); + } catch (IllegalAccessException e) { + throw new AssertionError(e); + } catch (PrivilegedActionException e) { + throw new AssertionError(e); } - return null; } }
--- a/jdk/src/share/classes/java/awt/Component.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/awt/Component.java Mon Jan 11 23:25:20 2010 -0800 @@ -871,7 +871,7 @@ return comp.canBeFocusOwner(); } - public boolean isVisible_NoClientCode(Component comp) { + public boolean isVisible(Component comp) { return comp.isVisible_NoClientCode(); } public void setRequestFocusController @@ -885,6 +885,71 @@ public void setAppContext(Component comp, AppContext appContext) { comp.appContext = appContext; } + public Container getParent(Component comp) { + return comp.getParent_NoClientCode(); + } + public void setParent(Component comp, Container parent) { + comp.parent = parent; + } + public void setSize(Component comp, int width, int height) { + comp.width = width; + comp.height = height; + } + public Point getLocation(Component comp) { + return comp.location_NoClientCode(); + } + public void setLocation(Component comp, int x, int y) { + comp.x = x; + comp.y = y; + } + public boolean isEnabled(Component comp) { + return comp.isEnabledImpl(); + } + public boolean isDisplayable(Component comp) { + return comp.peer != null; + } + public Cursor getCursor(Component comp) { + return comp.getCursor_NoClientCode(); + } + public ComponentPeer getPeer(Component comp) { + return comp.peer; + } + public void setPeer(Component comp, ComponentPeer peer) { + comp.peer = peer; + } + public boolean isLightweight(Component comp) { + return (comp.peer instanceof LightweightPeer); + } + public boolean getIgnoreRepaint(Component comp) { + return comp.ignoreRepaint; + } + public int getWidth(Component comp) { + return comp.width; + } + public int getHeight(Component comp) { + return comp.height; + } + public int getX(Component comp) { + return comp.x; + } + public int getY(Component comp) { + return comp.y; + } + public Color getForeground(Component comp) { + return comp.foreground; + } + public Color getBackground(Component comp) { + return comp.background; + } + public void setBackground(Component comp, Color background) { + comp.background = background; + } + public Font getFont(Component comp) { + return comp.getFont_NoClientCode(); + } + public void processEvent(Component comp, AWTEvent e) { + comp.processEvent(e); + } }); } @@ -8021,7 +8086,7 @@ Container getNativeContainer() { Container p = parent; while (p != null && p.peer instanceof LightweightPeer) { - p = p.getParent(); + p = p.getParent_NoClientCode(); } return p; }
--- a/jdk/src/share/classes/java/awt/EventDispatchThread.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/awt/EventDispatchThread.java Mon Jan 11 23:25:20 2010 -0800 @@ -104,11 +104,8 @@ } else { stopEvent.dispatch(); } - synchronized (theQueue) { - if (theQueue.getDispatchThread() == this) { - theQueue.detachDispatchThread(); - } - } + + theQueue.detachDispatchThread(this, false); } public void stopDispatching() { @@ -142,35 +139,7 @@ } }); } finally { - /* - * This synchronized block is to secure that the event dispatch - * thread won't die in the middle of posting a new event to the - * associated event queue. It is important because we notify - * that the event dispatch thread is busy after posting a new event - * to its queue, so the EventQueue.dispatchThread reference must - * be valid at that point. - */ - synchronized (theQueue) { - if (theQueue.getDispatchThread() == this) { - theQueue.detachDispatchThread(); - } - /* - * Event dispatch thread dies in case of an uncaught exception. - * A new event dispatch thread for this queue will be started - * only if a new event is posted to it. In case if no more - * events are posted after this thread died all events that - * currently are in the queue will never be dispatched. - */ - /* - * Fix for 4648733. Check both the associated java event - * queue and the PostEventQueue. - */ - if (theQueue.peekEvent() != null || - !SunToolkit.isPostEventQueueEmpty()) { - theQueue.initDispatchThread(); - } - AWTAutoShutdown.getInstance().notifyThreadFree(this); - } + theQueue.detachDispatchThread(this, true); } }
--- a/jdk/src/share/classes/java/awt/EventQueue.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/awt/EventQueue.java Mon Jan 11 23:25:20 2010 -0800 @@ -45,6 +45,9 @@ import sun.awt.EventQueueItem; import sun.awt.AWTAccessor; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; + /** * <code>EventQueue</code> is a platform-independent class * that queues events, both from the underlying peer classes @@ -127,6 +130,14 @@ */ private EventQueue previousQueue; + /* + * A single lock to synchronize the push()/pop() and related operations with + * all the EventQueues from the AppContext. Synchronization on any particular + * event queue(s) is not enough: we should lock the whole stack. + */ + private final Lock pushPopLock; + private final Condition pushPopCond; + private EventDispatchThread dispatchThread; private final ThreadGroup threadGroup = @@ -158,11 +169,11 @@ static { AWTAccessor.setEventQueueAccessor( new AWTAccessor.EventQueueAccessor() { - public EventQueue getNextQueue(EventQueue eventQueue) { - return eventQueue.nextQueue; + public Thread getDispatchThread(EventQueue eventQueue) { + return eventQueue.getDispatchThread(); } - public Thread getDispatchThread(EventQueue eventQueue) { - return eventQueue.dispatchThread; + public boolean isDispatchThreadImpl(EventQueue eventQueue) { + return eventQueue.isDispatchThreadImpl(); } }); } @@ -179,6 +190,9 @@ * may call AppContext.getAppContext() before createNewAppContext() * completes thus causing mess in thread group to appcontext mapping. */ + + pushPopLock = (Lock)AppContext.getAppContext().get(AppContext.EVENT_QUEUE_LOCK_KEY); + pushPopCond = (Condition)AppContext.getAppContext().get(AppContext.EVENT_QUEUE_COND_KEY); } /** @@ -207,7 +221,8 @@ */ final void postEventPrivate(AWTEvent theEvent) { theEvent.isPosted = true; - synchronized(this) { + pushPopLock.lock(); + try { if (dispatchThread == null && nextQueue == null) { if (theEvent.getSource() == AWTAutoShutdown.getInstance()) { return; @@ -221,6 +236,8 @@ return; } postEvent(theEvent, getPriority(theEvent)); + } finally { + pushPopLock.unlock(); } } @@ -280,9 +297,9 @@ if (theEvent.getSource() != AWTAutoShutdown.getInstance()) { AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); } - notifyAll(); + pushPopCond.signalAll(); } else if (notifyID) { - notifyAll(); + pushPopCond.signalAll(); } } else { // The event was not coalesced or has non-Component source. @@ -290,7 +307,7 @@ queues[priority].tail.next = newItem; queues[priority].tail = newItem; if (notifyID) { - notifyAll(); + pushPopCond.signalAll(); } } } @@ -482,7 +499,8 @@ * event queues are nested with push()/pop(). */ SunToolkit.flushPendingEvents(); - synchronized (this) { + pushPopLock.lock(); + try { for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { if (queues[i].head != null) { EventQueueItem entry = queues[i].head; @@ -495,7 +513,9 @@ } } AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread); - wait(); + pushPopCond.await(); + } finally { + pushPopLock.unlock(); } } while(true); } @@ -508,7 +528,8 @@ * event queues are nested with push()/pop(). */ SunToolkit.flushPendingEvents(); - synchronized (this) { + pushPopLock.lock(); + try { for (int i = 0; i < NUM_PRIORITIES; i++) { for (EventQueueItem entry = queues[i].head, prev = null; entry != null; prev = entry, entry = entry.next) @@ -527,9 +548,11 @@ } } } - this.waitForID = id; - wait(); - this.waitForID = 0; + waitForID = id; + pushPopCond.await(); + waitForID = 0; + } finally { + pushPopLock.unlock(); } } while(true); } @@ -539,11 +562,16 @@ * without removing it. * @return the first event */ - public synchronized AWTEvent peekEvent() { - for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { - if (queues[i].head != null) { - return queues[i].head.event; + public AWTEvent peekEvent() { + pushPopLock.lock(); + try { + for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { + if (queues[i].head != null) { + return queues[i].head.event; + } } + } finally { + pushPopLock.unlock(); } return null; @@ -555,14 +583,19 @@ * @return the first event of the specified id or <code>null</code> * if there is no such event */ - public synchronized AWTEvent peekEvent(int id) { - for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { - EventQueueItem q = queues[i].head; - for (; q != null; q = q.next) { - if (q.event.getID() == id) { - return q.event; + public AWTEvent peekEvent(int id) { + pushPopLock.lock(); + try { + for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { + EventQueueItem q = queues[i].head; + for (; q != null; q = q.next) { + if (q.event.getID() == id) { + return q.event; + } } } + } finally { + pushPopLock.unlock(); } return null; @@ -661,17 +694,27 @@ public static long getMostRecentEventTime() { return Toolkit.getEventQueue().getMostRecentEventTimeImpl(); } - private synchronized long getMostRecentEventTimeImpl() { - return (Thread.currentThread() == dispatchThread) - ? mostRecentEventTime - : System.currentTimeMillis(); + private long getMostRecentEventTimeImpl() { + pushPopLock.lock(); + try { + return (Thread.currentThread() == dispatchThread) + ? mostRecentEventTime + : System.currentTimeMillis(); + } finally { + pushPopLock.unlock(); + } } /** * @return most recent event time on all threads. */ - synchronized long getMostRecentEventTimeEx() { - return mostRecentEventTime; + long getMostRecentEventTimeEx() { + pushPopLock.lock(); + try { + return mostRecentEventTime; + } finally { + pushPopLock.unlock(); + } } /** @@ -689,10 +732,15 @@ public static AWTEvent getCurrentEvent() { return Toolkit.getEventQueue().getCurrentEventImpl(); } - private synchronized AWTEvent getCurrentEventImpl() { - return (Thread.currentThread() == dispatchThread) - ? ((AWTEvent)currentEvent.get()) - : null; + private AWTEvent getCurrentEventImpl() { + pushPopLock.lock(); + try { + return (Thread.currentThread() == dispatchThread) + ? ((AWTEvent)currentEvent.get()) + : null; + } finally { + pushPopLock.unlock(); + } } /** @@ -706,21 +754,22 @@ * @throws NullPointerException if <code>newEventQueue</code> is <code>null</code> * @since 1.2 */ - public synchronized void push(EventQueue newEventQueue) { + public void push(EventQueue newEventQueue) { if (eventLog.isLoggable(PlatformLogger.FINE)) { eventLog.fine("EventQueue.push(" + newEventQueue + ")"); } - if (nextQueue != null) { - nextQueue.push(newEventQueue); - return; - } + pushPopLock.lock(); + try { + EventQueue toPush = this; + while (toPush.nextQueue != null) { + toPush = toPush.nextQueue; + } - synchronized (newEventQueue) { // Transfer all events forward to new EventQueue. - while (peekEvent() != null) { + while (toPush.peekEvent() != null) { try { - newEventQueue.postEventPrivate(getNextEvent()); + newEventQueue.postEventPrivate(toPush.getNextEvent()); } catch (InterruptedException ie) { if (eventLog.isLoggable(PlatformLogger.FINE)) { eventLog.fine("Interrupted push", ie); @@ -728,27 +777,30 @@ } } - newEventQueue.previousQueue = this; - } - /* - * Stop the event dispatch thread associated with the currently - * active event queue, so that after the new queue is pushed - * on the top this event dispatch thread won't prevent AWT from - * being automatically shut down. - * Use stopDispatchingLater() to avoid deadlock: stopDispatching() - * waits for the dispatch thread to exit, so if the dispatch - * thread attempts to synchronize on this EventQueue object - * it will never exit since we already hold this lock. - */ - if (dispatchThread != null) { - dispatchThread.stopDispatchingLater(); - } + newEventQueue.previousQueue = toPush; - nextQueue = newEventQueue; + /* + * Stop the event dispatch thread associated with the currently + * active event queue, so that after the new queue is pushed + * on the top this event dispatch thread won't prevent AWT from + * being automatically shut down. + * Use stopDispatchingLater() to avoid deadlock: stopDispatching() + * waits for the dispatch thread to exit, which in turn waits + * for the lock in EQ.detachDispatchThread(), which is hold by + * this method. + */ + if (toPush.dispatchThread != null) { + toPush.dispatchThread.stopDispatchingLater(); + } - AppContext appContext = AppContext.getAppContext(); - if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) { - appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue); + toPush.nextQueue = newEventQueue; + + AppContext appContext = AppContext.getAppContext(); + if (appContext.get(AppContext.EVENT_QUEUE_KEY) == toPush) { + appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue); + } + } finally { + pushPopLock.unlock(); } } @@ -770,25 +822,24 @@ eventLog.fine("EventQueue.pop(" + this + ")"); } - // To prevent deadlock, we lock on the previous EventQueue before - // this one. This uses the same locking order as everything else - // in EventQueue.java, so deadlock isn't possible. - EventQueue prev = previousQueue; - synchronized ((prev != null) ? prev : this) { - synchronized(this) { - if (nextQueue != null) { - nextQueue.pop(); - return; + EventDispatchThread dt = null; + pushPopLock.lock(); + try { + EventQueue toPop = this; + while (toPop.nextQueue != null) { + toPop = toPop.nextQueue; } - if (previousQueue == null) { + EventQueue prev = toPop.previousQueue; + if (prev == null) { throw new EmptyStackException(); } + toPop.previousQueue = null; // Transfer all events back to previous EventQueue. - previousQueue.nextQueue = null; - while (peekEvent() != null) { + prev.nextQueue = null; + while (toPop.peekEvent() != null) { try { - previousQueue.postEventPrivate(getNextEvent()); + prev.postEventPrivate(toPop.getNextEvent()); } catch (InterruptedException ie) { if (eventLog.isLoggable(PlatformLogger.FINE)) { eventLog.fine("Interrupted pop", ie); @@ -797,14 +848,14 @@ } AppContext appContext = AppContext.getAppContext(); if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) { - appContext.put(AppContext.EVENT_QUEUE_KEY, previousQueue); + appContext.put(AppContext.EVENT_QUEUE_KEY, prev); } - previousQueue = null; - } + dt = toPop.dispatchThread; + } finally { + pushPopLock.unlock(); } - EventDispatchThread dt = this.dispatchThread; if (dt != null) { dt.stopDispatching(); // Must be done outside synchronized // block to avoid possible deadlock @@ -833,16 +884,27 @@ */ public static boolean isDispatchThread() { EventQueue eq = Toolkit.getEventQueue(); - EventQueue next = eq.nextQueue; - while (next != null) { - eq = next; - next = eq.nextQueue; + return eq.isDispatchThreadImpl(); + } + + final boolean isDispatchThreadImpl() { + EventQueue eq = this; + pushPopLock.lock(); + try { + EventQueue next = eq.nextQueue; + while (next != null) { + eq = next; + next = eq.nextQueue; + } + return (Thread.currentThread() == eq.dispatchThread); + } finally { + pushPopLock.unlock(); } - return (Thread.currentThread() == eq.dispatchThread); } final void initDispatchThread() { - synchronized (this) { + pushPopLock.lock(); + try { AppContext appContext = AppContext.getAppContext(); if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) { dispatchThread = (EventDispatchThread) @@ -861,11 +923,45 @@ AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); dispatchThread.start(); } + } finally { + pushPopLock.unlock(); } } - final void detachDispatchThread() { - dispatchThread = null; + final void detachDispatchThread(EventDispatchThread edt, boolean restart) { + /* + * This synchronized block is to secure that the event dispatch + * thread won't die in the middle of posting a new event to the + * associated event queue. It is important because we notify + * that the event dispatch thread is busy after posting a new event + * to its queue, so the EventQueue.dispatchThread reference must + * be valid at that point. + */ + pushPopLock.lock(); + try { + EventDispatchThread oldDispatchThread = dispatchThread; + if (dispatchThread == edt) { + dispatchThread = null; + } + if (restart) { + /* + * Event dispatch thread dies in case of an uncaught exception. + * A new event dispatch thread for this queue will be started + * only if a new event is posted to it. In case if no more + * events are posted after this thread died all events that + * currently are in the queue will never be dispatched. + * + * Fix for 4648733. Check both the associated java event + * queue and the PostEventQueue. + */ + if ((peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) { + initDispatchThread(); + } + AWTAutoShutdown.getInstance().notifyThreadFree(oldDispatchThread); + } + } finally { + pushPopLock.unlock(); + } } /* @@ -878,7 +974,12 @@ * @see java.awt.EventQueue#detachDispatchThread */ final EventDispatchThread getDispatchThread() { - return dispatchThread; + pushPopLock.lock(); + try { + return dispatchThread; + } finally { + pushPopLock.unlock(); + } } /* @@ -895,7 +996,8 @@ */ final void removeSourceEvents(Object source, boolean removeAllEvents) { SunToolkit.flushPendingEvents(); - synchronized (this) { + pushPopLock.lock(); + try { for (int i = 0; i < NUM_PRIORITIES; i++) { EventQueueItem entry = queues[i].head; EventQueueItem prev = null; @@ -928,43 +1030,49 @@ } queues[i].tail = prev; } + } finally { + pushPopLock.unlock(); } } static void setCurrentEventAndMostRecentTime(AWTEvent e) { Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e); } - private synchronized void setCurrentEventAndMostRecentTimeImpl(AWTEvent e) - { - if (Thread.currentThread() != dispatchThread) { - return; - } + private void setCurrentEventAndMostRecentTimeImpl(AWTEvent e) { + pushPopLock.lock(); + try { + if (Thread.currentThread() != dispatchThread) { + return; + } - currentEvent = new WeakReference(e); + currentEvent = new WeakReference(e); - // This series of 'instanceof' checks should be replaced with a - // polymorphic type (for example, an interface which declares a - // getWhen() method). However, this would require us to make such - // a type public, or to place it in sun.awt. Both of these approaches - // have been frowned upon. So for now, we hack. - // - // In tiger, we will probably give timestamps to all events, so this - // will no longer be an issue. - long mostRecentEventTime2 = Long.MIN_VALUE; - if (e instanceof InputEvent) { - InputEvent ie = (InputEvent)e; - mostRecentEventTime2 = ie.getWhen(); - } else if (e instanceof InputMethodEvent) { - InputMethodEvent ime = (InputMethodEvent)e; - mostRecentEventTime2 = ime.getWhen(); - } else if (e instanceof ActionEvent) { - ActionEvent ae = (ActionEvent)e; - mostRecentEventTime2 = ae.getWhen(); - } else if (e instanceof InvocationEvent) { - InvocationEvent ie = (InvocationEvent)e; - mostRecentEventTime2 = ie.getWhen(); + // This series of 'instanceof' checks should be replaced with a + // polymorphic type (for example, an interface which declares a + // getWhen() method). However, this would require us to make such + // a type public, or to place it in sun.awt. Both of these approaches + // have been frowned upon. So for now, we hack. + // + // In tiger, we will probably give timestamps to all events, so this + // will no longer be an issue. + long mostRecentEventTime2 = Long.MIN_VALUE; + if (e instanceof InputEvent) { + InputEvent ie = (InputEvent)e; + mostRecentEventTime2 = ie.getWhen(); + } else if (e instanceof InputMethodEvent) { + InputMethodEvent ime = (InputMethodEvent)e; + mostRecentEventTime2 = ime.getWhen(); + } else if (e instanceof ActionEvent) { + ActionEvent ae = (ActionEvent)e; + mostRecentEventTime2 = ae.getWhen(); + } else if (e instanceof InvocationEvent) { + InvocationEvent ie = (InvocationEvent)e; + mostRecentEventTime2 = ie.getWhen(); + } + mostRecentEventTime = Math.max(mostRecentEventTime, mostRecentEventTime2); + } finally { + pushPopLock.unlock(); } - mostRecentEventTime = Math.max(mostRecentEventTime, mostRecentEventTime2); } /** @@ -1045,15 +1153,18 @@ * or starts a new one otherwise. */ private void wakeup(boolean isShutdown) { - synchronized(this) { + pushPopLock.lock(); + try { if (nextQueue != null) { // Forward call to the top of EventQueue stack. nextQueue.wakeup(isShutdown); } else if (dispatchThread != null) { - notifyAll(); + pushPopCond.signalAll(); } else if (!isShutdown) { initDispatchThread(); } + } finally { + pushPopLock.unlock(); } } }
--- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Mon Jan 11 23:25:20 2010 -0800 @@ -53,8 +53,7 @@ import java.util.StringTokenizer; import java.util.WeakHashMap; -import java.util.logging.Level; -import java.util.logging.Logger; +import sun.util.logging.PlatformLogger; import sun.awt.AppContext; import sun.awt.HeadlessToolkit; @@ -111,7 +110,7 @@ { // Shared focus engine logger - private static final Logger focusLog = Logger.getLogger("java.awt.focus.KeyboardFocusManager"); + private static final PlatformLogger focusLog = PlatformLogger.getLogger("java.awt.focus.KeyboardFocusManager"); static { /* ensure that the necessary native libraries are loaded */ @@ -154,7 +153,7 @@ */ private static native void initIDs(); - private static final Logger log = Logger.getLogger("java.awt.KeyboardFocusManager"); + private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.KeyboardFocusManager"); /** * The identifier for the Forward focus traversal keys. @@ -504,8 +503,8 @@ if (this == getCurrentKeyboardFocusManager()) { return focusOwner; } else { - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); } throw new SecurityException(notPrivileged); } @@ -609,9 +608,9 @@ } void setNativeFocusOwner(Component comp) { - if (focusLog.isLoggable(Level.FINEST)) { - focusLog.log(Level.FINEST, "Calling peer {0} setCurrentFocusOwner for {1}", - new Object[] {String.valueOf(peer), String.valueOf(comp)}); + if (focusLog.isLoggable(PlatformLogger.FINEST)) { + focusLog.finest("Calling peer {0} setCurrentFocusOwner for {1}", + String.valueOf(peer), String.valueOf(comp)); } peer.setCurrentFocusOwner(comp); } @@ -673,8 +672,8 @@ if (this == getCurrentKeyboardFocusManager()) { return permanentFocusOwner; } else { - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); } throw new SecurityException(notPrivileged); } @@ -781,8 +780,8 @@ if (this == getCurrentKeyboardFocusManager()) { return focusedWindow; } else { - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); } throw new SecurityException(notPrivileged); } @@ -885,8 +884,8 @@ if (this == getCurrentKeyboardFocusManager()) { return activeWindow; } else { - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); } throw new SecurityException(notPrivileged); } @@ -919,8 +918,8 @@ Window oldActiveWindow; synchronized (KeyboardFocusManager.class) { oldActiveWindow = getActiveWindow(); - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "Setting global active window to " + activeWindow + ", old active " + oldActiveWindow); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("Setting global active window to " + activeWindow + ", old active " + oldActiveWindow); } try { @@ -1215,8 +1214,8 @@ if (this == getCurrentKeyboardFocusManager()) { return currentFocusCycleRoot; } else { - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); } throw new SecurityException(notPrivileged); } @@ -2149,9 +2148,9 @@ HeavyweightFocusRequest(Component heavyweight, Component descendant, boolean temporary, CausedFocusEvent.Cause cause) { - if (log.isLoggable(Level.FINE)) { + if (log.isLoggable(PlatformLogger.FINE)) { if (heavyweight == null) { - log.log(Level.FINE, "Assertion (heavyweight != null) failed"); + log.fine("Assertion (heavyweight != null) failed"); } } @@ -2161,12 +2160,12 @@ } boolean addLightweightRequest(Component descendant, boolean temporary, CausedFocusEvent.Cause cause) { - if (log.isLoggable(Level.FINE)) { + if (log.isLoggable(PlatformLogger.FINE)) { if (this == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) { - log.log(Level.FINE, "Assertion (this != HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) failed"); + log.fine("Assertion (this != HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) failed"); } if (descendant == null) { - log.log(Level.FINE, "Assertion (descendant != null) failed"); + log.fine("Assertion (descendant != null) failed"); } } @@ -2339,12 +2338,12 @@ (Component heavyweight, Component descendant, boolean temporary, boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause) { - if (log.isLoggable(Level.FINE)) { + if (log.isLoggable(PlatformLogger.FINE)) { if (heavyweight == null) { - log.log(Level.FINE, "Assertion (heavyweight != null) failed"); + log.fine("Assertion (heavyweight != null) failed"); } if (time == 0) { - log.log(Level.FINE, "Assertion (time != 0) failed"); + log.fine("Assertion (time != 0) failed"); } } @@ -2361,31 +2360,31 @@ Component currentFocusOwner = thisManager.getGlobalFocusOwner(); Component nativeFocusOwner = thisManager.getNativeFocusOwner(); Window nativeFocusedWindow = thisManager.getNativeFocusedWindow(); - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "SNFH for {0} in {1}", - new Object[] {String.valueOf(descendant), String.valueOf(heavyweight)}); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("SNFH for {0} in {1}", + String.valueOf(descendant), String.valueOf(heavyweight)); } - if (focusLog.isLoggable(Level.FINEST)) { - focusLog.log(Level.FINEST, "0. Current focus owner {0}", - String.valueOf(currentFocusOwner)); - focusLog.log(Level.FINEST, "0. Native focus owner {0}", - String.valueOf(nativeFocusOwner)); - focusLog.log(Level.FINEST, "0. Native focused window {0}", - String.valueOf(nativeFocusedWindow)); + if (focusLog.isLoggable(PlatformLogger.FINEST)) { + focusLog.finest("0. Current focus owner {0}", + String.valueOf(currentFocusOwner)); + focusLog.finest("0. Native focus owner {0}", + String.valueOf(nativeFocusOwner)); + focusLog.finest("0. Native focused window {0}", + String.valueOf(nativeFocusedWindow)); } synchronized (heavyweightRequests) { HeavyweightFocusRequest hwFocusRequest = getLastHWRequest(); - if (focusLog.isLoggable(Level.FINEST)) { - focusLog.log(Level.FINEST, "Request {0}", String.valueOf(hwFocusRequest)); + if (focusLog.isLoggable(PlatformLogger.FINEST)) { + focusLog.finest("Request {0}", String.valueOf(hwFocusRequest)); } if (hwFocusRequest == null && heavyweight == nativeFocusOwner) { if (descendant == currentFocusOwner) { // Redundant request. - if (focusLog.isLoggable(Level.FINEST)) - focusLog.log(Level.FINEST, "1. SNFH_FAILURE for {0}", - String.valueOf(descendant)); + if (focusLog.isLoggable(PlatformLogger.FINEST)) + focusLog.finest("1. SNFH_FAILURE for {0}", + String.valueOf(descendant)); return SNFH_FAILURE; } @@ -2417,8 +2416,8 @@ // SunToolkit.postPriorityEvent(newFocusOwnerEvent); SunToolkit.postEvent(descendant.appContext, newFocusOwnerEvent); - if (focusLog.isLoggable(Level.FINEST)) - focusLog.log(Level.FINEST, "2. SNFH_HANDLED for {0}", String.valueOf(descendant)); + if (focusLog.isLoggable(PlatformLogger.FINEST)) + focusLog.finest("2. SNFH_HANDLED for {0}", String.valueOf(descendant)); return SNFH_SUCCESS_HANDLED; } else if (hwFocusRequest != null && hwFocusRequest.heavyweight == heavyweight) { @@ -2431,7 +2430,7 @@ manager.enqueueKeyEvents(time, descendant); } - if (focusLog.isLoggable(Level.FINEST)) + if (focusLog.isLoggable(PlatformLogger.FINEST)) focusLog.finest("3. SNFH_HANDLED for lightweight" + descendant + " in " + heavyweight); return SNFH_SUCCESS_HANDLED; @@ -2454,7 +2453,7 @@ (hwFocusRequest != null) ? hwFocusRequest.heavyweight : nativeFocusedWindow)) { - if (focusLog.isLoggable(Level.FINEST)) + if (focusLog.isLoggable(PlatformLogger.FINEST)) focusLog.finest("4. SNFH_FAILURE for " + descendant); return SNFH_FAILURE; } @@ -2464,7 +2463,7 @@ heavyweightRequests.add (new HeavyweightFocusRequest(heavyweight, descendant, temporary, cause)); - if (focusLog.isLoggable(Level.FINEST)) + if (focusLog.isLoggable(PlatformLogger.FINEST)) focusLog.finest("5. SNFH_PROCEED for " + descendant); return SNFH_SUCCESS_PROCEED; } @@ -2855,14 +2854,14 @@ } KeyboardFocusManager manager = getCurrentKeyboardFocusManager(); - if (focusLog.isLoggable(Level.FINER)) { + if (focusLog.isLoggable(PlatformLogger.FINER)) { if (event instanceof FocusEvent || event instanceof WindowEvent) { - focusLog.log(Level.FINER, ">>> {0}", new Object[] {String.valueOf(event)}); + focusLog.finer(">>> {0}", String.valueOf(event)); } - if (focusLog.isLoggable(Level.FINER) && event instanceof KeyEvent) { - focusLog.log(Level.FINER, " focus owner is {0}", - new Object[] {String.valueOf(manager.getGlobalFocusOwner())}); - focusLog.log(Level.FINER, ">>> {0}", new Object[] {String.valueOf(event)}); + if (focusLog.isLoggable(PlatformLogger.FINER) && event instanceof KeyEvent) { + focusLog.finer(" focus owner is {0}", + String.valueOf(manager.getGlobalFocusOwner())); + focusLog.finer(">>> {0}", String.valueOf(event)); } } @@ -2946,9 +2945,9 @@ } } static void removeLastFocusRequest(Component heavyweight) { - if (log.isLoggable(Level.FINE)) { + if (log.isLoggable(PlatformLogger.FINE)) { if (heavyweight == null) { - log.log(Level.FINE, "Assertion (heavyweight != null) failed"); + log.fine("Assertion (heavyweight != null) failed"); } }
--- a/jdk/src/share/classes/java/awt/Window.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/awt/Window.java Mon Jan 11 23:25:20 2010 -0800 @@ -148,6 +148,51 @@ public class Window extends Container implements Accessible { /** + * Enumeration of available <i>window types</i>. + * + * A window type defines the generic visual appearance and behavior of a + * top-level window. For example, the type may affect the kind of + * decorations of a decorated {@code Frame} or {@code Dialog} instance. + * <p> + * Some platforms may not fully support a certain window type. Depending on + * the level of support, some properties of the window type may be + * disobeyed. + * + * @see #getType + * @see #setType + * @since 1.7 + */ + public static enum Type { + /** + * Represents a <i>normal</i> window. + * + * This is the default type for objects of the {@code Window} class or + * its descendants. Use this type for regular top-level windows. + */ + NORMAL, + + /** + * Represents a <i>utility</i> window. + * + * A utility window is usually a small window such as a toolbar or a + * palette. The native system may render the window with smaller + * title-bar if the window is either a {@code Frame} or a {@code + * Dialog} object, and if it has its decorations enabled. + */ + UTILITY, + + /** + * Represents a <i>popup</i> window. + * + * A popup window is a temporary window such as a drop-down menu or a + * tooltip. On some platforms, windows of that type may be forcibly + * made undecorated even if they are instances of the {@code Frame} or + * {@code Dialog} class, and have decorations enabled. + */ + POPUP + } + + /** * This represents the warning message that is * to be displayed in a non secure window. ie : * a window that has a security manager installed for @@ -2718,6 +2763,52 @@ } /** + * Window type. + * + * Synchronization: ObjectLock + */ + private Type type = Type.NORMAL; + + /** + * Sets the type of the window. + * + * This method can only be called while the window is not displayable. + * + * @throws IllegalComponentStateException if the window + * is displayable. + * @throws IllegalArgumentException if the type is {@code null} + * @see Component#isDisplayable + * @see #getType + * @since 1.7 + */ + public void setType(Type type) { + if (type == null) { + throw new IllegalArgumentException("type should not be null."); + } + synchronized (getTreeLock()) { + if (isDisplayable()) { + throw new IllegalComponentStateException( + "The window is displayable."); + } + synchronized (getObjectLock()) { + this.type = type; + } + } + } + + /** + * Returns the type of the window. + * + * @see #setType + * @since 1.7 + */ + public Type getType() { + synchronized (getObjectLock()) { + return type; + } + } + + /** * The window serialized data version. * * @serial @@ -3873,6 +3964,18 @@ public void setLWRequestStatus(Window changed, boolean status) { changed.syncLWRequests = status; } + + public boolean isAutoRequestFocus(Window w) { + return w.autoRequestFocus; + } + + public boolean isTrayIconWindow(Window w) { + return w.isTrayIconWindow; + } + + public void setTrayIconWindow(Window w, boolean isTrayIconWindow) { + w.isTrayIconWindow = isTrayIconWindow; + } }); // WindowAccessor } // static
--- a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java Mon Jan 11 23:25:20 2010 -0800 @@ -313,11 +313,14 @@ } /** - * Gets the <code>Class</code> object of the indexed properties' type. - * The returned <code>Class</code> may describe a primitive type such as <code>int</code>. + * Returns the Java type info for the indexed property. + * Note that the {@code Class} object may describe + * primitive Java types such as {@code int}. + * This type is returned by the indexed read method + * or is used as the parameter type of the indexed write method. * - * @return The <code>Class</code> for the indexed properties' type; may return <code>null</code> - * if the type cannot be determined. + * @return the {@code Class} object that represents the Java type info, + * or {@code null} if the type cannot be determined */ public synchronized Class<?> getIndexedPropertyType() { Class type = getIndexedPropertyType0();
--- a/jdk/src/share/classes/java/beans/Introspector.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/beans/Introspector.java Mon Jan 11 23:25:20 2010 -0800 @@ -25,26 +25,19 @@ package java.beans; +import com.sun.beans.WeakCache; import com.sun.beans.finder.BeanInfoFinder; import com.sun.beans.finder.ClassFinder; -import java.lang.ref.Reference; -import java.lang.ref.SoftReference; - import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedAction; - -import java.util.Collections; import java.util.Map; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.EventListener; import java.util.List; -import java.util.WeakHashMap; import java.util.TreeMap; import sun.awt.AppContext; @@ -85,20 +78,7 @@ * patterns to identify property accessors, event sources, or public * methods. We then proceed to analyze the class's superclass and add * in the information from it (and possibly on up the superclass chain). - * * <p> - * Because the Introspector caches BeanInfo classes for better performance, - * take care if you use it in an application that uses - * multiple class loaders. - * In general, when you destroy a <code>ClassLoader</code> - * that has been used to introspect classes, - * you should use the - * {@link #flushCaches <code>Introspector.flushCaches</code>} - * or - * {@link #flushFromCaches <code>Introspector.flushFromCaches</code>} method - * to flush all of the introspected classes out of the cache. - * - * <P> * For more information about introspection and design patterns, please * consult the * <a href="http://java.sun.com/products/javabeans/docs/index.html">JavaBeans specification</a>. @@ -112,8 +92,8 @@ public final static int IGNORE_ALL_BEANINFO = 3; // Static Caches to speed up introspection. - private static Map declaredMethodCache = - Collections.synchronizedMap(new WeakHashMap()); + private static WeakCache<Class<?>, Method[]> declaredMethodCache = + new WeakCache<Class<?>, Method[]>(); private static final Object BEANINFO_CACHE = new Object(); @@ -174,20 +154,21 @@ if (!ReflectUtil.isPackageAccessible(beanClass)) { return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); } - Map<Class<?>, BeanInfo> map; synchronized (BEANINFO_CACHE) { - map = (Map<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE); - if (map == null) { - map = Collections.synchronizedMap(new WeakHashMap<Class<?>, BeanInfo>()); - AppContext.getAppContext().put(BEANINFO_CACHE, map); + WeakCache<Class<?>, BeanInfo> beanInfoCache = + (WeakCache<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE); + + if (beanInfoCache == null) { + beanInfoCache = new WeakCache<Class<?>, BeanInfo>(); + AppContext.getAppContext().put(BEANINFO_CACHE, beanInfoCache); } + BeanInfo beanInfo = beanInfoCache.get(beanClass); + if (beanInfo == null) { + beanInfo = (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); + beanInfoCache.put(beanClass, beanInfo); + } + return beanInfo; } - BeanInfo bi = map.get(beanClass); - if (bi == null) { - bi = (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); - map.put(beanClass, bi); - } - return bi; } /** @@ -359,11 +340,13 @@ */ public static void flushCaches() { - Map map = (Map) AppContext.getAppContext().get(BEANINFO_CACHE); - if (map != null) { - map.clear(); + synchronized (BEANINFO_CACHE) { + WeakCache beanInfoCache = (WeakCache) AppContext.getAppContext().get(BEANINFO_CACHE); + if (beanInfoCache != null) { + beanInfoCache.clear(); + } + declaredMethodCache.clear(); } - declaredMethodCache.clear(); } /** @@ -385,11 +368,13 @@ if (clz == null) { throw new NullPointerException(); } - Map map = (Map) AppContext.getAppContext().get(BEANINFO_CACHE); - if (map != null) { - map.remove(clz); + synchronized (BEANINFO_CACHE) { + WeakCache beanInfoCache = (WeakCache) AppContext.getAppContext().get(BEANINFO_CACHE); + if (beanInfoCache != null) { + beanInfoCache.put(clz, null); + } + declaredMethodCache.put(clz, null); } - declaredMethodCache.remove(clz); } //====================================================================== @@ -1272,41 +1257,26 @@ /* * Internal method to return *public* methods within a class. */ - private static synchronized Method[] getPublicDeclaredMethods(Class clz) { + private static Method[] getPublicDeclaredMethods(Class clz) { // Looking up Class.getDeclaredMethods is relatively expensive, // so we cache the results. - Method[] result = null; if (!ReflectUtil.isPackageAccessible(clz)) { return new Method[0]; } - final Class fclz = clz; - Reference ref = (Reference)declaredMethodCache.get(fclz); - if (ref != null) { - result = (Method[])ref.get(); - if (result != null) { - return result; - } - } - - // We have to raise privilege for getDeclaredMethods - result = (Method[]) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return fclz.getDeclaredMethods(); + synchronized (BEANINFO_CACHE) { + Method[] result = declaredMethodCache.get(clz); + if (result == null) { + result = clz.getMethods(); + for (int i = 0; i < result.length; i++) { + Method method = result[i]; + if (!method.getDeclaringClass().equals(clz)) { + result[i] = null; + } } - }); - - - // Null out any non-public methods. - for (int i = 0; i < result.length; i++) { - Method method = result[i]; - int mods = method.getModifiers(); - if (!Modifier.isPublic(mods)) { - result[i] = null; + declaredMethodCache.put(clz, result); } + return result; } - // Add it to the cache. - declaredMethodCache.put(fclz, new SoftReference(result)); - return result; } //======================================================================
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java Mon Jan 11 23:25:20 2010 -0800 @@ -164,14 +164,16 @@ } /** - * Gets the Class object for the property. + * Returns the Java type info for the property. + * Note that the {@code Class} object may describe + * primitive Java types such as {@code int}. + * This type is returned by the read method + * or is used as the parameter type of the write method. + * Returns {@code null} if the type is an indexed property + * that does not support non-indexed access. * - * @return The Java type info for the property. Note that - * the "Class" object may describe a built-in Java type such as "int". - * The result may be "null" if this is an indexed property that - * does not support non-indexed access. - * <p> - * This is the type that will be returned by the ReadMethod. + * @return the {@code Class} object that represents the Java type info, + * or {@code null} if the type cannot be determined */ public synchronized Class<?> getPropertyType() { Class type = getPropertyType0();
--- a/jdk/src/share/classes/java/lang/ClassLoader.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/lang/ClassLoader.java Mon Jan 11 23:25:20 2010 -0800 @@ -175,15 +175,8 @@ public abstract class ClassLoader { private static native void registerNatives(); - - // Set of classes which are registered as parallel capable class loaders - private static final Set<Class<? extends ClassLoader>> parallelLoaders - = Collections.newSetFromMap(Collections.synchronizedMap - (new WeakHashMap<Class<? extends ClassLoader>, Boolean>())); - static { registerNatives(); - parallelLoaders.add(ClassLoader.class); } // The parent class loader for delegation @@ -191,6 +184,52 @@ // must be added *after* it. private final ClassLoader parent; + /** + * Encapsulates the set of parallel capable loader types. + */ + private static class ParallelLoaders { + private ParallelLoaders() {} + + // the set of parallel capable loader types + private static final Set<Class<? extends ClassLoader>> loaderTypes = + Collections.newSetFromMap( + new WeakHashMap<Class<? extends ClassLoader>, Boolean>()); + static { + synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); } + } + + /** + * Registers the given class loader type as parallel capabale. + * Returns {@code true} is successfully registered; {@code false} if + * loader's super class is not registered. + */ + static boolean register(Class<? extends ClassLoader> c) { + synchronized (loaderTypes) { + if (loaderTypes.contains(c.getSuperclass())) { + // register the class loader as parallel capable + // if and only if all of its super classes are. + // Note: given current classloading sequence, if + // the immediate super class is parallel capable, + // all the super classes higher up must be too. + loaderTypes.add(c); + return true; + } else { + return false; + } + } + } + + /** + * Returns {@code true} if the given class loader type is + * registered as parallel capable. + */ + static boolean isRegistered(Class<? extends ClassLoader> c) { + synchronized (loaderTypes) { + return loaderTypes.contains(c); + } + } + } + // Maps class name to the corresponding lock object when the current // class loader is parallel capable. // Note: VM also uses this field to decide if the current class loader @@ -237,7 +276,7 @@ private ClassLoader(Void unused, ClassLoader parent) { this.parent = parent; - if (parallelLoaders.contains(this.getClass())) { + if (ParallelLoaders.isRegistered(this.getClass())) { parallelLockMap = new ConcurrentHashMap<String, Object>(); package2certs = new ConcurrentHashMap<String, Certificate[]>(); domains = @@ -1194,24 +1233,7 @@ * @since 1.7 */ protected static boolean registerAsParallelCapable() { - Class<? extends ClassLoader> caller = getCaller(1); - Class superCls = caller.getSuperclass(); - boolean result = false; - // Explicit synchronization needed for composite action - synchronized (parallelLoaders) { - if (!parallelLoaders.contains(caller)) { - if (parallelLoaders.contains(superCls)) { - // register the immediate caller as parallel capable - // if and only if all of its super classes are. - // Note: given current classloading sequence, if - // the immediate super class is parallel capable, - // all the super classes higher up must be too. - result = true; - parallelLoaders.add(caller); - } - } else result = true; - } - return result; + return ParallelLoaders.register(getCaller(1)); } /** @@ -2174,4 +2196,3 @@ return sys; } } -
--- a/jdk/src/share/classes/java/lang/System.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/lang/System.java Mon Jan 11 23:25:20 2010 -0800 @@ -620,6 +620,20 @@ } /** + * Returns the system-dependent line separator string. It always + * returns the same value - the initial value of the {@linkplain + * #getProperty(String) system property} {@code line.separator}. + * + * <p>On UNIX systems, it returns {@code "\n"}; on Microsoft + * Windows systems it returns {@code "\r\n"}. + */ + public static String lineSeparator() { + return lineSeparator; + } + + private static String lineSeparator; + + /** * Sets the system properties to the <code>Properties</code> * argument. * <p> @@ -1104,6 +1118,7 @@ private static void initializeSystemClass() { props = new Properties(); initProperties(props); + lineSeparator = props.getProperty("line.separator"); sun.misc.Version.init(); // Workaround until DownloadManager initialization is revisited. @@ -1192,7 +1207,7 @@ } /* returns the class of the caller. */ - static Class getCallerClass() { + static Class<?> getCallerClass() { // NOTE use of more generic Reflection.getCallerClass() return Reflection.getCallerClass(3); }
--- a/jdk/src/share/classes/java/net/CookieManager.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/net/CookieManager.java Mon Jan 11 23:25:20 2010 -0800 @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.Comparator; import java.io.IOException; +import sun.util.logging.PlatformLogger; /** * CookieManager provides a concrete implementation of {@link CookieHandler}, @@ -263,6 +264,7 @@ if (cookieJar == null) return; + PlatformLogger logger = PlatformLogger.getLogger("java.net.CookieManager"); for (String headerKey : responseHeaders.keySet()) { // RFC 2965 3.2.2, key must be 'Set-Cookie2' // we also accept 'Set-Cookie' here for backward compatibility @@ -277,7 +279,16 @@ for (String headerValue : responseHeaders.get(headerKey)) { try { - List<HttpCookie> cookies = HttpCookie.parse(headerValue); + List<HttpCookie> cookies; + try { + cookies = HttpCookie.parse(headerValue); + } catch (IllegalArgumentException e) { + // Bogus header, make an empty list and log the error + cookies = java.util.Collections.EMPTY_LIST; + if (logger.isLoggable(PlatformLogger.SEVERE)) { + logger.severe("Invalid cookie for " + uri + ": " + headerValue); + } + } for (HttpCookie cookie : cookies) { if (cookie.getPath() == null) { // If no path is specified, then by default
--- a/jdk/src/share/classes/java/net/HttpCookie.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/net/HttpCookie.java Mon Jan 11 23:25:20 2010 -0800 @@ -1036,7 +1036,7 @@ int version = Integer.parseInt(attrValue); cookie.setVersion(version); } catch (NumberFormatException ignored) { - throw new IllegalArgumentException("Illegal cookie version attribute"); + // Just ignore bogus version, it will default to 0 or 1 } } }); @@ -1147,12 +1147,15 @@ } private static String stripOffSurroundingQuote(String str) { - if (str != null && str.length() > 0 && + if (str != null && str.length() > 2 && str.charAt(0) == '"' && str.charAt(str.length() - 1) == '"') { return str.substring(1, str.length() - 1); - } else { - return str; } + if (str != null && str.length() > 2 && + str.charAt(0) == '\'' && str.charAt(str.length() - 1) == '\'') { + return str.substring(1, str.length() - 1); + } + return str; } private static boolean equalsIgnoreCase(String s, String t) {
--- a/jdk/src/share/classes/java/nio/channels/Selector.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/nio/channels/Selector.java Mon Jan 11 23:25:20 2010 -0800 @@ -25,6 +25,7 @@ package java.nio.channels; +import java.io.Closeable; import java.io.IOException; import java.nio.channels.spi.SelectorProvider; import java.util.Set; @@ -202,7 +203,7 @@ * @see SelectionKey */ -public abstract class Selector { +public abstract class Selector implements Closeable { /** * Initializes a new instance of this class.
--- a/jdk/src/share/classes/java/util/DualPivotQuicksort.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/util/DualPivotQuicksort.java Mon Jan 11 23:25:20 2010 -0800 @@ -36,12 +36,12 @@ * @author Jon Bentley * @author Josh Bloch * - * @version 2009.11.16 m765.827.v12a + * @version 2009.11.29 m765.827.12i */ final class DualPivotQuicksort { /** - * Suppresses default constructor. + * Prevents instantiation. */ private DualPivotQuicksort() {} @@ -84,7 +84,7 @@ * Sorts the specified range of the array into ascending order. The range * to be sorted extends from the index {@code fromIndex}, inclusive, to * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty. + * the range to be sorted is empty (and the call is a no-op). * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -101,8 +101,8 @@ /** * Sorts the specified range of the array into ascending order. This * method differs from the public {@code sort} method in that the - * {@code right} index is inclusive, and it does no range checking on - * {@code left} or {@code right}. + * {@code right} index is inclusive, and it does no range checking + * on {@code left} or {@code right}. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted @@ -111,13 +111,13 @@ private static void doSort(int[] a, int left, int right) { // Use insertion sort on tiny arrays if (right - left + 1 < INSERTION_SORT_THRESHOLD) { - for (int k = left + 1; k <= right; k++) { - int ak = a[k]; + for (int i = left + 1; i <= right; i++) { + int ai = a[i]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { + for (j = i - 1; j >= left && ai < a[j]; j--) { a[j + 1] = a[j]; } - a[j + 1] = ak; + a[j + 1] = ai; } } else { // Use Dual-Pivot Quicksort on large arrays dualPivotQuicksort(a, left, right); @@ -162,7 +162,7 @@ * second terciles of the array. Note that pivot1 <= pivot2. * * The pivots are stored in local variables, and the first and - * the last of the sorted elements are moved to the locations + * the last of the elements to be sorted are moved to the locations * formerly occupied by the pivots. When partitioning is complete, * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. @@ -170,27 +170,26 @@ int pivot1 = ae2; a[e2] = a[left]; int pivot2 = ae4; a[e4] = a[right]; - /* - * Partitioning - * - * left part center part right part - * ------------------------------------------------------------ - * [ < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 ] - * ------------------------------------------------------------ - * ^ ^ ^ - * | | | - * less k great - */ - // Pointers int less = left + 1; // The index of first element of center part int great = right - 1; // The index before first element of right part - boolean pivotsDiffer = pivot1 != pivot2; + boolean pivotsDiffer = (pivot1 != pivot2); if (pivotsDiffer) { /* + * Partitioning: + * + * left part center part right part + * +------------------------------------------------------------+ + * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | + * +------------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * * Invariants: + * * all in (left, less) < pivot1 * pivot1 <= all in [less, k) <= pivot2 * all in (great, right) > pivot2 @@ -200,37 +199,37 @@ outer: for (int k = less; k <= great; k++) { int ak = a[k]; - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else if (ak > pivot2) { + } else if (ak > pivot2) { // Move a[k] to right part while (a[great] > pivot2) { - if (k == great--) { + if (great-- == k) { break outer; } } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // pivot1 <= a[great] <= pivot2 + a[k] = a[great]; + a[great--] = ak; } } } } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way - * (or "Dutch National Flag") partition: + * Partition degenerates to the traditional 3-way, + * or "Dutch National Flag", partition: * * left part center part right part - * ------------------------------------------------- - * [ < pivot | == pivot | ? | > pivot ] - * ------------------------------------------------- - * + * +----------------------------------------------+ + * | < pivot | == pivot | ? | > pivot | + * +----------------------------------------------+ * ^ ^ ^ * | | | * less k great @@ -243,30 +242,34 @@ * * Pointer k is the first index of ?-part */ - outer: for (int k = less; k <= great; k++) { int ak = a[k]; if (ak == pivot1) { continue; } - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else { // a[k] > pivot + } else { // (a[k] > pivot1) - Move a[k] to right part + /* + * We know that pivot1 == a[e3] == pivot2. Thus, we know + * that great will still be >= k when the following loop + * terminates, even though we don't test for it explicitly. + * In other words, a[e3] acts as a sentinel for great. + */ while (a[great] > pivot1) { - if (k == great--) { - break outer; - } + great--; } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // a[great] == pivot1 + a[k] = pivot1; + a[great--] = ak; } } } @@ -289,26 +292,55 @@ } /* - * If center part is too large (comprises > 5/6 of - * the array), swap internal pivot values to ends + * If center part is too large (comprises > 2/3 of the array), + * swap internal pivot values to ends */ - if (less < e1 && e5 < great) { + if (less < e1 && great > e5) { while (a[less] == pivot1) { less++; } while (a[great] == pivot2) { great--; } - for (int k = less + 1; k <= great; ) { + + /* + * Partitioning: + * + * left part center part right part + * +----------------------------------------------------------+ + * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | + * +----------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * + * Invariants: + * + * all in (*, less) == pivot1 + * pivot1 < all in [less, k) < pivot2 + * all in (great, *) == pivot2 + * + * Pointer k is the first index of ?-part + */ + outer: + for (int k = less; k <= great; k++) { int ak = a[k]; - if (ak == pivot1) { - a[k++] = a[less]; + if (ak == pivot2) { // Move a[k] to right part + while (a[great] == pivot2) { + if (great-- == k) { + break outer; + } + } + if (a[great] == pivot1) { + a[k] = a[less]; + a[less++] = pivot1; + } else { // pivot1 < a[great] < pivot2 + a[k] = a[great]; + } + a[great--] = pivot2; + } else if (ak == pivot1) { // Move a[k] to left part + a[k] = a[less]; a[less++] = pivot1; - } else if (ak == pivot2) { - a[k] = a[great]; - a[great--] = pivot2; - } else { - k++; } } } @@ -330,7 +362,7 @@ * Sorts the specified range of the array into ascending order. The range * to be sorted extends from the index {@code fromIndex}, inclusive, to * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty. + * the range to be sorted is empty (and the call is a no-op). * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -357,13 +389,13 @@ private static void doSort(long[] a, int left, int right) { // Use insertion sort on tiny arrays if (right - left + 1 < INSERTION_SORT_THRESHOLD) { - for (int k = left + 1; k <= right; k++) { - long ak = a[k]; + for (int i = left + 1; i <= right; i++) { + long ai = a[i]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { + for (j = i - 1; j >= left && ai < a[j]; j--) { a[j + 1] = a[j]; } - a[j + 1] = ak; + a[j + 1] = ai; } } else { // Use Dual-Pivot Quicksort on large arrays dualPivotQuicksort(a, left, right); @@ -408,7 +440,7 @@ * second terciles of the array. Note that pivot1 <= pivot2. * * The pivots are stored in local variables, and the first and - * the last of the sorted elements are moved to the locations + * the last of the elements to be sorted are moved to the locations * formerly occupied by the pivots. When partitioning is complete, * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. @@ -416,27 +448,26 @@ long pivot1 = ae2; a[e2] = a[left]; long pivot2 = ae4; a[e4] = a[right]; - /* - * Partitioning - * - * left part center part right part - * ------------------------------------------------------------ - * [ < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 ] - * ------------------------------------------------------------ - * ^ ^ ^ - * | | | - * less k great - */ - // Pointers int less = left + 1; // The index of first element of center part int great = right - 1; // The index before first element of right part - boolean pivotsDiffer = pivot1 != pivot2; + boolean pivotsDiffer = (pivot1 != pivot2); if (pivotsDiffer) { /* + * Partitioning: + * + * left part center part right part + * +------------------------------------------------------------+ + * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | + * +------------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * * Invariants: + * * all in (left, less) < pivot1 * pivot1 <= all in [less, k) <= pivot2 * all in (great, right) > pivot2 @@ -446,37 +477,37 @@ outer: for (int k = less; k <= great; k++) { long ak = a[k]; - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else if (ak > pivot2) { + } else if (ak > pivot2) { // Move a[k] to right part while (a[great] > pivot2) { - if (k == great--) { + if (great-- == k) { break outer; } } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // pivot1 <= a[great] <= pivot2 + a[k] = a[great]; + a[great--] = ak; } } } } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way - * (or "Dutch National Flag") partition: + * Partition degenerates to the traditional 3-way, + * or "Dutch National Flag", partition: * * left part center part right part - * ------------------------------------------------- - * [ < pivot | == pivot | ? | > pivot ] - * ------------------------------------------------- - * + * +----------------------------------------------+ + * | < pivot | == pivot | ? | > pivot | + * +----------------------------------------------+ * ^ ^ ^ * | | | * less k great @@ -489,30 +520,34 @@ * * Pointer k is the first index of ?-part */ - outer: for (int k = less; k <= great; k++) { long ak = a[k]; if (ak == pivot1) { continue; } - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else { // a[k] > pivot + } else { // (a[k] > pivot1) - Move a[k] to right part + /* + * We know that pivot1 == a[e3] == pivot2. Thus, we know + * that great will still be >= k when the following loop + * terminates, even though we don't test for it explicitly. + * In other words, a[e3] acts as a sentinel for great. + */ while (a[great] > pivot1) { - if (k == great--) { - break outer; - } + great--; } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // a[great] == pivot1 + a[k] = pivot1; + a[great--] = ak; } } } @@ -535,26 +570,55 @@ } /* - * If center part is too large (comprises > 5/6 of - * the array), swap internal pivot values to ends + * If center part is too large (comprises > 2/3 of the array), + * swap internal pivot values to ends */ - if (less < e1 && e5 < great) { + if (less < e1 && great > e5) { while (a[less] == pivot1) { less++; } while (a[great] == pivot2) { great--; } - for (int k = less + 1; k <= great; ) { + + /* + * Partitioning: + * + * left part center part right part + * +----------------------------------------------------------+ + * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | + * +----------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * + * Invariants: + * + * all in (*, less) == pivot1 + * pivot1 < all in [less, k) < pivot2 + * all in (great, *) == pivot2 + * + * Pointer k is the first index of ?-part + */ + outer: + for (int k = less; k <= great; k++) { long ak = a[k]; - if (ak == pivot1) { - a[k++] = a[less]; + if (ak == pivot2) { // Move a[k] to right part + while (a[great] == pivot2) { + if (great-- == k) { + break outer; + } + } + if (a[great] == pivot1) { + a[k] = a[less]; + a[less++] = pivot1; + } else { // pivot1 < a[great] < pivot2 + a[k] = a[great]; + } + a[great--] = pivot2; + } else if (ak == pivot1) { // Move a[k] to left part + a[k] = a[less]; a[less++] = pivot1; - } else if (ak == pivot2) { - a[k] = a[great]; - a[great--] = pivot2; - } else { - k++; } } } @@ -576,7 +640,7 @@ * Sorts the specified range of the array into ascending order. The range * to be sorted extends from the index {@code fromIndex}, inclusive, to * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty. + * the range to be sorted is empty (and the call is a no-op). * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -606,13 +670,13 @@ private static void doSort(short[] a, int left, int right) { // Use insertion sort on tiny arrays if (right - left + 1 < INSERTION_SORT_THRESHOLD) { - for (int k = left + 1; k <= right; k++) { - short ak = a[k]; + for (int i = left + 1; i <= right; i++) { + short ai = a[i]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { + for (j = i - 1; j >= left && ai < a[j]; j--) { a[j + 1] = a[j]; } - a[j + 1] = ak; + a[j + 1] = ai; } } else if (right-left+1 > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { // Use counting sort on huge arrays @@ -671,7 +735,7 @@ * second terciles of the array. Note that pivot1 <= pivot2. * * The pivots are stored in local variables, and the first and - * the last of the sorted elements are moved to the locations + * the last of the elements to be sorted are moved to the locations * formerly occupied by the pivots. When partitioning is complete, * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. @@ -679,27 +743,26 @@ short pivot1 = ae2; a[e2] = a[left]; short pivot2 = ae4; a[e4] = a[right]; - /* - * Partitioning - * - * left part center part right part - * ------------------------------------------------------------ - * [ < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 ] - * ------------------------------------------------------------ - * ^ ^ ^ - * | | | - * less k great - */ - // Pointers int less = left + 1; // The index of first element of center part int great = right - 1; // The index before first element of right part - boolean pivotsDiffer = pivot1 != pivot2; + boolean pivotsDiffer = (pivot1 != pivot2); if (pivotsDiffer) { /* + * Partitioning: + * + * left part center part right part + * +------------------------------------------------------------+ + * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | + * +------------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * * Invariants: + * * all in (left, less) < pivot1 * pivot1 <= all in [less, k) <= pivot2 * all in (great, right) > pivot2 @@ -709,37 +772,37 @@ outer: for (int k = less; k <= great; k++) { short ak = a[k]; - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else if (ak > pivot2) { + } else if (ak > pivot2) { // Move a[k] to right part while (a[great] > pivot2) { - if (k == great--) { + if (great-- == k) { break outer; } } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // pivot1 <= a[great] <= pivot2 + a[k] = a[great]; + a[great--] = ak; } } } } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way - * (or "Dutch National Flag") partition: + * Partition degenerates to the traditional 3-way, + * or "Dutch National Flag", partition: * * left part center part right part - * ------------------------------------------------- - * [ < pivot | == pivot | ? | > pivot ] - * ------------------------------------------------- - * + * +----------------------------------------------+ + * | < pivot | == pivot | ? | > pivot | + * +----------------------------------------------+ * ^ ^ ^ * | | | * less k great @@ -752,30 +815,34 @@ * * Pointer k is the first index of ?-part */ - outer: for (int k = less; k <= great; k++) { short ak = a[k]; if (ak == pivot1) { continue; } - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else { // a[k] > pivot + } else { // (a[k] > pivot1) - Move a[k] to right part + /* + * We know that pivot1 == a[e3] == pivot2. Thus, we know + * that great will still be >= k when the following loop + * terminates, even though we don't test for it explicitly. + * In other words, a[e3] acts as a sentinel for great. + */ while (a[great] > pivot1) { - if (k == great--) { - break outer; - } + great--; } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // a[great] == pivot1 + a[k] = pivot1; + a[great--] = ak; } } } @@ -798,26 +865,55 @@ } /* - * If center part is too large (comprises > 5/6 of - * the array), swap internal pivot values to ends + * If center part is too large (comprises > 2/3 of the array), + * swap internal pivot values to ends */ - if (less < e1 && e5 < great) { + if (less < e1 && great > e5) { while (a[less] == pivot1) { less++; } while (a[great] == pivot2) { great--; } - for (int k = less + 1; k <= great; ) { + + /* + * Partitioning: + * + * left part center part right part + * +----------------------------------------------------------+ + * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | + * +----------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * + * Invariants: + * + * all in (*, less) == pivot1 + * pivot1 < all in [less, k) < pivot2 + * all in (great, *) == pivot2 + * + * Pointer k is the first index of ?-part + */ + outer: + for (int k = less; k <= great; k++) { short ak = a[k]; - if (ak == pivot1) { - a[k++] = a[less]; + if (ak == pivot2) { // Move a[k] to right part + while (a[great] == pivot2) { + if (great-- == k) { + break outer; + } + } + if (a[great] == pivot1) { + a[k] = a[less]; + a[less++] = pivot1; + } else { // pivot1 < a[great] < pivot2 + a[k] = a[great]; + } + a[great--] = pivot2; + } else if (ak == pivot1) { // Move a[k] to left part + a[k] = a[less]; a[less++] = pivot1; - } else if (ak == pivot2) { - a[k] = a[great]; - a[great--] = pivot2; - } else { - k++; } } } @@ -839,7 +935,7 @@ * Sorts the specified range of the array into ascending order. The range * to be sorted extends from the index {@code fromIndex}, inclusive, to * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty. + * the range to be sorted is empty (and the call is a no-op). * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -869,13 +965,13 @@ private static void doSort(char[] a, int left, int right) { // Use insertion sort on tiny arrays if (right - left + 1 < INSERTION_SORT_THRESHOLD) { - for (int k = left + 1; k <= right; k++) { - char ak = a[k]; + for (int i = left + 1; i <= right; i++) { + char ai = a[i]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { + for (j = i - 1; j >= left && ai < a[j]; j--) { a[j + 1] = a[j]; } - a[j + 1] = ak; + a[j + 1] = ai; } } else if (right-left+1 > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { // Use counting sort on huge arrays @@ -932,7 +1028,7 @@ * second terciles of the array. Note that pivot1 <= pivot2. * * The pivots are stored in local variables, and the first and - * the last of the sorted elements are moved to the locations + * the last of the elements to be sorted are moved to the locations * formerly occupied by the pivots. When partitioning is complete, * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. @@ -940,27 +1036,26 @@ char pivot1 = ae2; a[e2] = a[left]; char pivot2 = ae4; a[e4] = a[right]; - /* - * Partitioning - * - * left part center part right part - * ------------------------------------------------------------ - * [ < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 ] - * ------------------------------------------------------------ - * ^ ^ ^ - * | | | - * less k great - */ - // Pointers int less = left + 1; // The index of first element of center part int great = right - 1; // The index before first element of right part - boolean pivotsDiffer = pivot1 != pivot2; + boolean pivotsDiffer = (pivot1 != pivot2); if (pivotsDiffer) { /* + * Partitioning: + * + * left part center part right part + * +------------------------------------------------------------+ + * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | + * +------------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * * Invariants: + * * all in (left, less) < pivot1 * pivot1 <= all in [less, k) <= pivot2 * all in (great, right) > pivot2 @@ -970,37 +1065,37 @@ outer: for (int k = less; k <= great; k++) { char ak = a[k]; - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else if (ak > pivot2) { + } else if (ak > pivot2) { // Move a[k] to right part while (a[great] > pivot2) { - if (k == great--) { + if (great-- == k) { break outer; } } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // pivot1 <= a[great] <= pivot2 + a[k] = a[great]; + a[great--] = ak; } } } } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way - * (or "Dutch National Flag") partition: + * Partition degenerates to the traditional 3-way, + * or "Dutch National Flag", partition: * * left part center part right part - * ------------------------------------------------- - * [ < pivot | == pivot | ? | > pivot ] - * ------------------------------------------------- - * + * +----------------------------------------------+ + * | < pivot | == pivot | ? | > pivot | + * +----------------------------------------------+ * ^ ^ ^ * | | | * less k great @@ -1013,30 +1108,34 @@ * * Pointer k is the first index of ?-part */ - outer: for (int k = less; k <= great; k++) { char ak = a[k]; if (ak == pivot1) { continue; } - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else { // a[k] > pivot + } else { // (a[k] > pivot1) - Move a[k] to right part + /* + * We know that pivot1 == a[e3] == pivot2. Thus, we know + * that great will still be >= k when the following loop + * terminates, even though we don't test for it explicitly. + * In other words, a[e3] acts as a sentinel for great. + */ while (a[great] > pivot1) { - if (k == great--) { - break outer; - } + great--; } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // a[great] == pivot1 + a[k] = pivot1; + a[great--] = ak; } } } @@ -1059,26 +1158,55 @@ } /* - * If center part is too large (comprises > 5/6 of - * the array), swap internal pivot values to ends + * If center part is too large (comprises > 2/3 of the array), + * swap internal pivot values to ends */ - if (less < e1 && e5 < great) { + if (less < e1 && great > e5) { while (a[less] == pivot1) { less++; } while (a[great] == pivot2) { great--; } - for (int k = less + 1; k <= great; ) { + + /* + * Partitioning: + * + * left part center part right part + * +----------------------------------------------------------+ + * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | + * +----------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * + * Invariants: + * + * all in (*, less) == pivot1 + * pivot1 < all in [less, k) < pivot2 + * all in (great, *) == pivot2 + * + * Pointer k is the first index of ?-part + */ + outer: + for (int k = less; k <= great; k++) { char ak = a[k]; - if (ak == pivot1) { - a[k++] = a[less]; + if (ak == pivot2) { // Move a[k] to right part + while (a[great] == pivot2) { + if (great-- == k) { + break outer; + } + } + if (a[great] == pivot1) { + a[k] = a[less]; + a[less++] = pivot1; + } else { // pivot1 < a[great] < pivot2 + a[k] = a[great]; + } + a[great--] = pivot2; + } else if (ak == pivot1) { // Move a[k] to left part + a[k] = a[less]; a[less++] = pivot1; - } else if (ak == pivot2) { - a[k] = a[great]; - a[great--] = pivot2; - } else { - k++; } } } @@ -1100,7 +1228,7 @@ * Sorts the specified range of the array into ascending order. The range * to be sorted extends from the index {@code fromIndex}, inclusive, to * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty. + * the range to be sorted is empty (and the call is a no-op). * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -1130,13 +1258,13 @@ private static void doSort(byte[] a, int left, int right) { // Use insertion sort on tiny arrays if (right - left + 1 < INSERTION_SORT_THRESHOLD) { - for (int k = left + 1; k <= right; k++) { - byte ak = a[k]; + for (int i = left + 1; i <= right; i++) { + byte ai = a[i]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { + for (j = i - 1; j >= left && ai < a[j]; j--) { a[j + 1] = a[j]; } - a[j + 1] = ak; + a[j + 1] = ai; } } else if (right - left + 1 > COUNTING_SORT_THRESHOLD_FOR_BYTE) { // Use counting sort on huge arrays @@ -1195,7 +1323,7 @@ * second terciles of the array. Note that pivot1 <= pivot2. * * The pivots are stored in local variables, and the first and - * the last of the sorted elements are moved to the locations + * the last of the elements to be sorted are moved to the locations * formerly occupied by the pivots. When partitioning is complete, * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. @@ -1203,27 +1331,26 @@ byte pivot1 = ae2; a[e2] = a[left]; byte pivot2 = ae4; a[e4] = a[right]; - /* - * Partitioning - * - * left part center part right part - * ------------------------------------------------------------ - * [ < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 ] - * ------------------------------------------------------------ - * ^ ^ ^ - * | | | - * less k great - */ - // Pointers int less = left + 1; // The index of first element of center part int great = right - 1; // The index before first element of right part - boolean pivotsDiffer = pivot1 != pivot2; + boolean pivotsDiffer = (pivot1 != pivot2); if (pivotsDiffer) { /* + * Partitioning: + * + * left part center part right part + * +------------------------------------------------------------+ + * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | + * +------------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * * Invariants: + * * all in (left, less) < pivot1 * pivot1 <= all in [less, k) <= pivot2 * all in (great, right) > pivot2 @@ -1233,37 +1360,37 @@ outer: for (int k = less; k <= great; k++) { byte ak = a[k]; - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else if (ak > pivot2) { + } else if (ak > pivot2) { // Move a[k] to right part while (a[great] > pivot2) { - if (k == great--) { + if (great-- == k) { break outer; } } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // pivot1 <= a[great] <= pivot2 + a[k] = a[great]; + a[great--] = ak; } } } } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way - * (or "Dutch National Flag") partition: + * Partition degenerates to the traditional 3-way, + * or "Dutch National Flag", partition: * * left part center part right part - * ------------------------------------------------- - * [ < pivot | == pivot | ? | > pivot ] - * ------------------------------------------------- - * + * +----------------------------------------------+ + * | < pivot | == pivot | ? | > pivot | + * +----------------------------------------------+ * ^ ^ ^ * | | | * less k great @@ -1276,30 +1403,34 @@ * * Pointer k is the first index of ?-part */ - outer: for (int k = less; k <= great; k++) { byte ak = a[k]; if (ak == pivot1) { continue; } - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else { // a[k] > pivot + } else { // (a[k] > pivot1) - Move a[k] to right part + /* + * We know that pivot1 == a[e3] == pivot2. Thus, we know + * that great will still be >= k when the following loop + * terminates, even though we don't test for it explicitly. + * In other words, a[e3] acts as a sentinel for great. + */ while (a[great] > pivot1) { - if (k == great--) { - break outer; - } + great--; } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // a[great] == pivot1 + a[k] = pivot1; + a[great--] = ak; } } } @@ -1322,26 +1453,55 @@ } /* - * If center part is too large (comprises > 5/6 of - * the array), swap internal pivot values to ends + * If center part is too large (comprises > 2/3 of the array), + * swap internal pivot values to ends */ - if (less < e1 && e5 < great) { + if (less < e1 && great > e5) { while (a[less] == pivot1) { less++; } while (a[great] == pivot2) { great--; } - for (int k = less + 1; k <= great; ) { + + /* + * Partitioning: + * + * left part center part right part + * +----------------------------------------------------------+ + * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | + * +----------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * + * Invariants: + * + * all in (*, less) == pivot1 + * pivot1 < all in [less, k) < pivot2 + * all in (great, *) == pivot2 + * + * Pointer k is the first index of ?-part + */ + outer: + for (int k = less; k <= great; k++) { byte ak = a[k]; - if (ak == pivot1) { - a[k++] = a[less]; + if (ak == pivot2) { // Move a[k] to right part + while (a[great] == pivot2) { + if (great-- == k) { + break outer; + } + } + if (a[great] == pivot1) { + a[k] = a[less]; + a[less++] = pivot1; + } else { // pivot1 < a[great] < pivot2 + a[k] = a[great]; + } + a[great--] = pivot2; + } else if (ak == pivot1) { // Move a[k] to left part + a[k] = a[less]; a[less++] = pivot1; - } else if (ak == pivot2) { - a[k] = a[great]; - a[great--] = pivot2; - } else { - k++; } } } @@ -1371,7 +1531,7 @@ * Sorts the specified range of the array into ascending order. The range * to be sorted extends from the index {@code fromIndex}, inclusive, to * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty. + * the range to be sorted is empty and the call is a no-op). * * <p>The {@code <} relation does not provide a total order on all float * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN} @@ -1485,13 +1645,13 @@ private static void doSort(float[] a, int left, int right) { // Use insertion sort on tiny arrays if (right - left + 1 < INSERTION_SORT_THRESHOLD) { - for (int k = left + 1; k <= right; k++) { - float ak = a[k]; + for (int i = left + 1; i <= right; i++) { + float ai = a[i]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { + for (j = i - 1; j >= left && ai < a[j]; j--) { a[j + 1] = a[j]; } - a[j + 1] = ak; + a[j + 1] = ai; } } else { // Use Dual-Pivot Quicksort on large arrays dualPivotQuicksort(a, left, right); @@ -1536,7 +1696,7 @@ * second terciles of the array. Note that pivot1 <= pivot2. * * The pivots are stored in local variables, and the first and - * the last of the sorted elements are moved to the locations + * the last of the elements to be sorted are moved to the locations * formerly occupied by the pivots. When partitioning is complete, * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. @@ -1544,27 +1704,26 @@ float pivot1 = ae2; a[e2] = a[left]; float pivot2 = ae4; a[e4] = a[right]; - /* - * Partitioning - * - * left part center part right part - * ------------------------------------------------------------ - * [ < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 ] - * ------------------------------------------------------------ - * ^ ^ ^ - * | | | - * less k great - */ - // Pointers int less = left + 1; // The index of first element of center part int great = right - 1; // The index before first element of right part - boolean pivotsDiffer = pivot1 != pivot2; + boolean pivotsDiffer = (pivot1 != pivot2); if (pivotsDiffer) { /* + * Partitioning: + * + * left part center part right part + * +------------------------------------------------------------+ + * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | + * +------------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * * Invariants: + * * all in (left, less) < pivot1 * pivot1 <= all in [less, k) <= pivot2 * all in (great, right) > pivot2 @@ -1574,37 +1733,37 @@ outer: for (int k = less; k <= great; k++) { float ak = a[k]; - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else if (ak > pivot2) { + } else if (ak > pivot2) { // Move a[k] to right part while (a[great] > pivot2) { - if (k == great--) { + if (great-- == k) { break outer; } } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // pivot1 <= a[great] <= pivot2 + a[k] = a[great]; + a[great--] = ak; } } } } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way - * (or "Dutch National Flag") partition: + * Partition degenerates to the traditional 3-way, + * or "Dutch National Flag", partition: * * left part center part right part - * ------------------------------------------------- - * [ < pivot | == pivot | ? | > pivot ] - * ------------------------------------------------- - * + * +----------------------------------------------+ + * | < pivot | == pivot | ? | > pivot | + * +----------------------------------------------+ * ^ ^ ^ * | | | * less k great @@ -1617,30 +1776,34 @@ * * Pointer k is the first index of ?-part */ - outer: for (int k = less; k <= great; k++) { float ak = a[k]; if (ak == pivot1) { continue; } - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else { // a[k] > pivot + } else { // (a[k] > pivot1) - Move a[k] to right part + /* + * We know that pivot1 == a[e3] == pivot2. Thus, we know + * that great will still be >= k when the following loop + * terminates, even though we don't test for it explicitly. + * In other words, a[e3] acts as a sentinel for great. + */ while (a[great] > pivot1) { - if (k == great--) { - break outer; - } + great--; } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // a[great] == pivot1 + a[k] = pivot1; + a[great--] = ak; } } } @@ -1663,26 +1826,55 @@ } /* - * If center part is too large (comprises > 5/6 of - * the array), swap internal pivot values to ends + * If center part is too large (comprises > 2/3 of the array), + * swap internal pivot values to ends */ - if (less < e1 && e5 < great) { + if (less < e1 && great > e5) { while (a[less] == pivot1) { less++; } while (a[great] == pivot2) { great--; } - for (int k = less + 1; k <= great; ) { + + /* + * Partitioning: + * + * left part center part right part + * +----------------------------------------------------------+ + * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | + * +----------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * + * Invariants: + * + * all in (*, less) == pivot1 + * pivot1 < all in [less, k) < pivot2 + * all in (great, *) == pivot2 + * + * Pointer k is the first index of ?-part + */ + outer: + for (int k = less; k <= great; k++) { float ak = a[k]; - if (ak == pivot1) { - a[k++] = a[less]; + if (ak == pivot2) { // Move a[k] to right part + while (a[great] == pivot2) { + if (great-- == k) { + break outer; + } + } + if (a[great] == pivot1) { + a[k] = a[less]; + a[less++] = pivot1; + } else { // pivot1 < a[great] < pivot2 + a[k] = a[great]; + } + a[great--] = pivot2; + } else if (ak == pivot1) { // Move a[k] to left part + a[k] = a[less]; a[less++] = pivot1; - } else if (ak == pivot2) { - a[k] = a[great]; - a[great--] = pivot2; - } else { - k++; } } } @@ -1712,7 +1904,7 @@ * Sorts the specified range of the array into ascending order. The range * to be sorted extends from the index {@code fromIndex}, inclusive, to * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty. + * the range to be sorted is empty (and the call is a no-op). * * <p>The {@code <} relation does not provide a total order on all double * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN} @@ -1826,13 +2018,13 @@ private static void doSort(double[] a, int left, int right) { // Use insertion sort on tiny arrays if (right - left + 1 < INSERTION_SORT_THRESHOLD) { - for (int k = left + 1; k <= right; k++) { - double ak = a[k]; + for (int i = left + 1; i <= right; i++) { + double ai = a[i]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { + for (j = i - 1; j >= left && ai < a[j]; j--) { a[j + 1] = a[j]; } - a[j + 1] = ak; + a[j + 1] = ai; } } else { // Use Dual-Pivot Quicksort on large arrays dualPivotQuicksort(a, left, right); @@ -1877,7 +2069,7 @@ * second terciles of the array. Note that pivot1 <= pivot2. * * The pivots are stored in local variables, and the first and - * the last of the sorted elements are moved to the locations + * the last of the elements to be sorted are moved to the locations * formerly occupied by the pivots. When partitioning is complete, * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. @@ -1885,27 +2077,26 @@ double pivot1 = ae2; a[e2] = a[left]; double pivot2 = ae4; a[e4] = a[right]; - /* - * Partitioning - * - * left part center part right part - * ------------------------------------------------------------ - * [ < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 ] - * ------------------------------------------------------------ - * ^ ^ ^ - * | | | - * less k great - */ - // Pointers int less = left + 1; // The index of first element of center part int great = right - 1; // The index before first element of right part - boolean pivotsDiffer = pivot1 != pivot2; + boolean pivotsDiffer = (pivot1 != pivot2); if (pivotsDiffer) { /* + * Partitioning: + * + * left part center part right part + * +------------------------------------------------------------+ + * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | + * +------------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * * Invariants: + * * all in (left, less) < pivot1 * pivot1 <= all in [less, k) <= pivot2 * all in (great, right) > pivot2 @@ -1915,37 +2106,37 @@ outer: for (int k = less; k <= great; k++) { double ak = a[k]; - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else if (ak > pivot2) { + } else if (ak > pivot2) { // Move a[k] to right part while (a[great] > pivot2) { - if (k == great--) { + if (great-- == k) { break outer; } } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // pivot1 <= a[great] <= pivot2 + a[k] = a[great]; + a[great--] = ak; } } } } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way - * (or "Dutch National Flag") partition: + * Partition degenerates to the traditional 3-way, + * or "Dutch National Flag", partition: * * left part center part right part - * ------------------------------------------------- - * [ < pivot | == pivot | ? | > pivot ] - * ------------------------------------------------- - * + * +----------------------------------------------+ + * | < pivot | == pivot | ? | > pivot | + * +----------------------------------------------+ * ^ ^ ^ * | | | * less k great @@ -1958,30 +2149,34 @@ * * Pointer k is the first index of ?-part */ - outer: for (int k = less; k <= great; k++) { double ak = a[k]; if (ak == pivot1) { continue; } - if (ak < pivot1) { - if (k > less) { + if (ak < pivot1) { // Move a[k] to left part + if (k != less) { a[k] = a[less]; a[less] = ak; } less++; - } else { // a[k] > pivot + } else { // (a[k] > pivot1) - Move a[k] to right part + /* + * We know that pivot1 == a[e3] == pivot2. Thus, we know + * that great will still be >= k when the following loop + * terminates, even though we don't test for it explicitly. + * In other words, a[e3] acts as a sentinel for great. + */ while (a[great] > pivot1) { - if (k == great--) { - break outer; - } + great--; } - a[k] = a[great]; - a[great--] = ak; - - if ((ak = a[k]) < pivot1) { + if (a[great] < pivot1) { a[k] = a[less]; - a[less++] = ak; + a[less++] = a[great]; + a[great--] = ak; + } else { // a[great] == pivot1 + a[k] = pivot1; + a[great--] = ak; } } } @@ -2004,26 +2199,55 @@ } /* - * If center part is too large (comprises > 5/6 of - * the array), swap internal pivot values to ends + * If center part is too large (comprises > 2/3 of the array), + * swap internal pivot values to ends */ - if (less < e1 && e5 < great) { + if (less < e1 && great > e5) { while (a[less] == pivot1) { less++; } while (a[great] == pivot2) { great--; } - for (int k = less + 1; k <= great; ) { + + /* + * Partitioning: + * + * left part center part right part + * +----------------------------------------------------------+ + * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | + * +----------------------------------------------------------+ + * ^ ^ ^ + * | | | + * less k great + * + * Invariants: + * + * all in (*, less) == pivot1 + * pivot1 < all in [less, k) < pivot2 + * all in (great, *) == pivot2 + * + * Pointer k is the first index of ?-part + */ + outer: + for (int k = less; k <= great; k++) { double ak = a[k]; - if (ak == pivot1) { - a[k++] = a[less]; + if (ak == pivot2) { // Move a[k] to right part + while (a[great] == pivot2) { + if (great-- == k) { + break outer; + } + } + if (a[great] == pivot1) { + a[k] = a[less]; + a[less++] = pivot1; + } else { // pivot1 < a[great] < pivot2 + a[k] = a[great]; + } + a[great--] = pivot2; + } else if (ak == pivot1) { // Move a[k] to left part + a[k] = a[less]; a[less++] = pivot1; - } else if (ak == pivot2) { - a[k] = a[great]; - a[great--] = pivot2; - } else { - k++; } } }
--- a/jdk/src/share/classes/java/util/Formatter.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/util/Formatter.java Mon Jan 11 23:25:20 2010 -0800 @@ -2552,9 +2552,6 @@ private boolean dt = false; private char c; - // cache the line separator - private String ls; - private int index(String s) { if (s != null) { try { @@ -2702,9 +2699,7 @@ printHashCode(arg); break; case Conversion.LINE_SEPARATOR: - if (ls == null) - ls = System.getProperty("line.separator"); - a.append(ls); + a.append(System.lineSeparator()); break; case Conversion.PERCENT_SIGN: a.append('%');
--- a/jdk/src/share/classes/java/util/zip/Deflater.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/util/zip/Deflater.java Mon Jan 11 23:25:20 2010 -0800 @@ -318,7 +318,7 @@ /** * Compresses the input data and fills specified buffer with compressed * data. Returns actual number of bytes of compressed data. A return value - * of 0 indicates that {@link needsInput() needsInput} should be called + * of 0 indicates that {@link #needsInput() needsInput} should be called * in order to determine if more input data is required. * * <p>This method uses {@link #NO_FLUSH} as its compression flush mode. @@ -339,7 +339,7 @@ /** * Compresses the input data and fills specified buffer with compressed * data. Returns actual number of bytes of compressed data. A return value - * of 0 indicates that {@link needsInput() needsInput} should be called + * of 0 indicates that {@link #needsInput() needsInput} should be called * in order to determine if more input data is required. * * <p>This method uses {@link #NO_FLUSH} as its compression flush mode.
--- a/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java Mon Jan 11 23:25:20 2010 -0800 @@ -66,7 +66,7 @@ * @param def the compressor ("deflater") * @param size the output buffer size * @param syncFlush - * if {@code true} the {@link flush()} method of this + * if {@code true} the {@link #flush()} method of this * instance flushes the compressor with flush mode * {@link Deflater#SYNC_FLUSH} before flushing the output * stream, otherwise only flushes the output stream @@ -114,7 +114,7 @@ * @param out the output stream * @param def the compressor ("deflater") * @param syncFlush - * if {@code true} the {@link flush()} method of this + * if {@code true} the {@link #flush()} method of this * instance flushes the compressor with flush mode * {@link Deflater#SYNC_FLUSH} before flushing the output * stream, otherwise only flushes the output stream @@ -151,7 +151,7 @@ * * @param out the output stream * @param syncFlush - * if {@code true} the {@link flush()} method of this + * if {@code true} the {@link #flush()} method of this * instance flushes the compressor with flush mode * {@link Deflater#SYNC_FLUSH} before flushing the output * stream, otherwise only flushes the output stream @@ -262,10 +262,10 @@ /** * Flushes the compressed output stream. * - * If {@link DeflaterOutputStream(OutputStream, Deflater, int, boolean) + * If {@link #DeflaterOutputStream(OutputStream, Deflater, int, boolean) * syncFlush} is {@code true} when this compressed output stream is - * constructed this method flushes the underlying {@code compressor} - * first with the flush mode {@link Deflater#SYNC_FLUSH} to force + * constructed, this method first flushes the underlying {@code compressor} + * with the flush mode {@link Deflater#SYNC_FLUSH} to force * all pending data to be flushed out to the output stream and then * flushes the output stream. Otherwise this method only flushes the * output stream without flushing the {@code compressor}.
--- a/jdk/src/share/classes/javax/naming/InitialContext.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/naming/InitialContext.java Mon Jan 11 23:25:20 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, Inc. 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 @@ -198,6 +198,8 @@ * * <p> This constructor will not modify <tt>environment</tt> * or save a reference to it, but may save a clone. + * Caller should not modify mutable keys and values in + * <tt>environment</tt> after it has been passed to the constructor. * * @param environment * environment used to create the initial context.
--- a/jdk/src/share/classes/javax/naming/directory/InitialDirContext.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/naming/directory/InitialDirContext.java Mon Jan 11 23:25:20 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, Inc. 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 @@ -86,6 +86,8 @@ * * <p> This constructor will not modify <tt>environment</tt> * or save a reference to it, but may save a clone. + * Caller should not modify mutable keys and values in + * <tt>environment</tt> after it has been passed to the constructor. * * @param environment * environment used to create the initial DirContext.
--- a/jdk/src/share/classes/javax/naming/ldap/InitialLdapContext.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/naming/ldap/InitialLdapContext.java Mon Jan 11 23:25:20 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, Inc. 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 @@ -110,6 +110,8 @@ * * <p> This constructor will not modify its parameters or * save references to them, but may save a clone or copy. + * Caller should not modify mutable keys and values in + * <tt>environment</tt> after it has been passed to the constructor. * * <p> <tt>connCtls</tt> is used as the underlying context instance's * connection request controls. See the class description
--- a/jdk/src/share/classes/javax/security/auth/Subject.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/security/auth/Subject.java Mon Jan 11 23:25:20 2010 -0800 @@ -40,7 +40,6 @@ import java.security.PrivilegedActionException; import java.security.ProtectionDomain; import sun.security.util.ResourcesMgr; -import sun.security.util.SecurityConstants; /** * <p> A <code>Subject</code> represents a grouping of related information @@ -239,7 +238,7 @@ public void setReadOnly() { java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(new AuthPermission("setReadOnly")); + sm.checkPermission(AuthPermissionHolder.SET_READ_ONLY_PERMISSION); } this.readOnly = true; @@ -285,7 +284,7 @@ java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(new AuthPermission("getSubject")); + sm.checkPermission(AuthPermissionHolder.GET_SUBJECT_PERMISSION); } if (acc == null) { @@ -343,7 +342,7 @@ java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(SecurityConstants.DO_AS_PERMISSION); + sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION); } if (action == null) throw new NullPointerException @@ -402,7 +401,7 @@ java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(SecurityConstants.DO_AS_PERMISSION); + sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION); } if (action == null) @@ -456,7 +455,7 @@ java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION); + sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION); } if (action == null) @@ -520,7 +519,7 @@ java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION); + sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION); } if (action == null) @@ -1044,16 +1043,13 @@ if (sm != null) { switch (which) { case Subject.PRINCIPAL_SET: - sm.checkPermission(new AuthPermission - ("modifyPrincipals")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION); break; case Subject.PUB_CREDENTIAL_SET: - sm.checkPermission(new AuthPermission - ("modifyPublicCredentials")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION); break; default: - sm.checkPermission(new AuthPermission - ("modifyPrivateCredentials")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION); break; } } @@ -1073,16 +1069,13 @@ if (sm != null) { switch (which) { case Subject.PRINCIPAL_SET: - sm.checkPermission - (new AuthPermission("modifyPrincipals")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION); break; case Subject.PUB_CREDENTIAL_SET: - sm.checkPermission - (new AuthPermission("modifyPublicCredentials")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION); break; default: - sm.checkPermission - (new AuthPermission("modifyPrivateCredentials")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION); break; } } @@ -1405,4 +1398,27 @@ return set.add(o); } } + + static class AuthPermissionHolder { + static final AuthPermission DO_AS_PERMISSION = + new AuthPermission("doAs"); + + static final AuthPermission DO_AS_PRIVILEGED_PERMISSION = + new AuthPermission("doAsPrivileged"); + + static final AuthPermission SET_READ_ONLY_PERMISSION = + new AuthPermission("setReadOnly"); + + static final AuthPermission GET_SUBJECT_PERMISSION = + new AuthPermission("getSubject"); + + static final AuthPermission MODIFY_PRINCIPALS_PERMISSION = + new AuthPermission("modifyPrincipals"); + + static final AuthPermission MODIFY_PUBLIC_CREDENTIALS_PERMISSION = + new AuthPermission("modifyPublicCredentials"); + + static final AuthPermission MODIFY_PRIVATE_CREDENTIALS_PERMISSION = + new AuthPermission("modifyPrivateCredentials"); + } }
--- a/jdk/src/share/classes/javax/swing/AbstractListModel.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/AbstractListModel.java Mon Jan 11 23:25:20 2010 -0800 @@ -42,9 +42,11 @@ * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * + * @param <E> the type of the elements of this model + * * @author Hans Muller */ -public abstract class AbstractListModel implements ListModel, Serializable +public abstract class AbstractListModel<E> implements ListModel<E>, Serializable { protected EventListenerList listenerList = new EventListenerList();
--- a/jdk/src/share/classes/javax/swing/DefaultListCellRenderer.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/DefaultListCellRenderer.java Mon Jan 11 23:25:20 2010 -0800 @@ -71,7 +71,7 @@ * @author Hans Muller */ public class DefaultListCellRenderer extends JLabel - implements ListCellRenderer, Serializable + implements ListCellRenderer<Object>, Serializable { /** @@ -111,7 +111,7 @@ } public Component getListCellRendererComponent( - JList list, + JList<?> list, Object value, int index, boolean isSelected,
--- a/jdk/src/share/classes/javax/swing/DefaultListModel.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/DefaultListModel.java Mon Jan 11 23:25:20 2010 -0800 @@ -48,11 +48,13 @@ * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * + * @param <E> the type of the elements of this model + * * @author Hans Muller */ -public class DefaultListModel extends AbstractListModel +public class DefaultListModel<E> extends AbstractListModel<E> { - private Vector delegate = new Vector(); + private Vector<E> delegate = new Vector<E>(); /** * Returns the number of components in this list. @@ -83,7 +85,7 @@ * list * @see #get(int) */ - public Object getElementAt(int index) { + public E getElementAt(int index) { return delegate.elementAt(index); } @@ -175,7 +177,7 @@ * @return an enumeration of the components of this list * @see Vector#elements() */ - public Enumeration<?> elements() { + public Enumeration<E> elements() { return delegate.elements(); } @@ -260,7 +262,7 @@ * @see #get(int) * @see Vector#elementAt(int) */ - public Object elementAt(int index) { + public E elementAt(int index) { return delegate.elementAt(index); } @@ -271,7 +273,7 @@ * @return the first component of this list * @see Vector#firstElement() */ - public Object firstElement() { + public E firstElement() { return delegate.firstElement(); } @@ -283,13 +285,13 @@ * @return the last component of the list * @see Vector#lastElement() */ - public Object lastElement() { + public E lastElement() { return delegate.lastElement(); } /** * Sets the component at the specified <code>index</code> of this - * list to be the specified object. The previous component at that + * list to be the specified element. The previous component at that * position is discarded. * <p> * Throws an <code>ArrayIndexOutOfBoundsException</code> if the index @@ -300,13 +302,13 @@ * <code>List</code> interface defined in the 1.2 Collections framework. * </blockquote> * - * @param obj what the component is to be set to + * @param element what the component is to be set to * @param index the specified index * @see #set(int,Object) * @see Vector#setElementAt(Object,int) */ - public void setElementAt(Object obj, int index) { - delegate.setElementAt(obj, index); + public void setElementAt(E element, int index) { + delegate.setElementAt(element, index); fireContentsChanged(this, index, index); } @@ -331,7 +333,7 @@ } /** - * Inserts the specified object as a component in this list at the + * Inserts the specified element as a component in this list at the * specified <code>index</code>. * <p> * Throws an <code>ArrayIndexOutOfBoundsException</code> if the index @@ -342,26 +344,26 @@ * <code>List</code> interface defined in the 1.2 Collections framework. * </blockquote> * - * @param obj the component to insert + * @param element the component to insert * @param index where to insert the new component * @exception ArrayIndexOutOfBoundsException if the index was invalid * @see #add(int,Object) * @see Vector#insertElementAt(Object,int) */ - public void insertElementAt(Object obj, int index) { - delegate.insertElementAt(obj, index); + public void insertElementAt(E element, int index) { + delegate.insertElementAt(element, index); fireIntervalAdded(this, index, index); } /** * Adds the specified component to the end of this list. * - * @param obj the component to be added + * @param element the component to be added * @see Vector#addElement(Object) */ - public void addElement(Object obj) { + public void addElement(E element) { int index = delegate.size(); - delegate.addElement(obj); + delegate.addElement(element); fireIntervalAdded(this, index, index); } @@ -441,7 +443,7 @@ * * @param index index of element to return */ - public Object get(int index) { + public E get(int index) { return delegate.elementAt(index); } @@ -457,8 +459,8 @@ * @param element element to be stored at the specified position * @return the element previously at the specified position */ - public Object set(int index, Object element) { - Object rv = delegate.elementAt(index); + public E set(int index, E element) { + E rv = delegate.elementAt(index); delegate.setElementAt(element, index); fireContentsChanged(this, index, index); return rv; @@ -474,7 +476,7 @@ * @param index index at which the specified element is to be inserted * @param element element to be inserted */ - public void add(int index, Object element) { + public void add(int index, E element) { delegate.insertElementAt(element, index); fireIntervalAdded(this, index, index); } @@ -488,9 +490,10 @@ * (<code>index < 0 || index >= size()</code>). * * @param index the index of the element to removed + * @return the element previously at the specified position */ - public Object remove(int index) { - Object rv = delegate.elementAt(index); + public E remove(int index) { + E rv = delegate.elementAt(index); delegate.removeElementAt(index); fireIntervalRemoved(this, index, index); return rv;
--- a/jdk/src/share/classes/javax/swing/JList.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/JList.java Mon Jan 11 23:25:20 2010 -0800 @@ -25,11 +25,24 @@ package javax.swing; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.GraphicsEnvironment; +import java.awt.HeadlessException; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; import java.awt.event.*; -import java.awt.*; import java.util.Vector; import java.util.Locale; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -59,28 +72,30 @@ * constructor that automatically builds a read-only {@code ListModel} instance * for you: * <pre> + * {@code * // Create a JList that displays strings from an array * * String[] data = {"one", "two", "three", "four"}; - * JList myList = new JList(data); + * JList<String> myList = new JList<String>(data); * * // Create a JList that displays the superclasses of JList.class, by * // creating it with a Vector populated with this data * - * Vector superClasses = new Vector(); - * Class rootClass = javax.swing.JList.class; - * for(Class cls = rootClass; cls != null; cls = cls.getSuperclass()) { + * Vector<Class<?>> superClasses = new Vector<Class<?>>(); + * Class<JList> rootClass = javax.swing.JList.class; + * for(Class<?> cls = rootClass; cls != null; cls = cls.getSuperclass()) { * superClasses.addElement(cls); * } - * JList myList = new JList(superClasses); + * JList<Class<?>> myList = new JList<Class<?>>(superClasses); * * // The automatically created model is stored in JList's "model" * // property, which you can retrieve * - * ListModel model = myList.getModel(); + * ListModel<Class<?>> model = myList.getModel(); * for(int i = 0; i < model.getSize(); i++) { * System.out.println(model.getElementAt(i)); * } + * } * </pre> * <p> * A {@code ListModel} can be supplied directly to a {@code JList} by way of a @@ -103,12 +118,14 @@ * notifying listeners. For example, a read-only implementation of * {@code AbstractListModel}: * <pre> + * {@code * // This list model has about 2^16 elements. Enjoy scrolling. * - * ListModel bigData = new AbstractListModel() { + * ListModel<String> bigData = new AbstractListModel<String>() { * public int getSize() { return Short.MAX_VALUE; } - * public Object getElementAt(int index) { return "Index " + index; } + * public String getElementAt(int index) { return "Index " + index; } * }; + * } * </pre> * <p> * The selection state of a {@code JList} is managed by another separate @@ -150,9 +167,10 @@ * component to render, is installed by the lists's {@code ListUI}. You can * substitute your own renderer using code like this: * <pre> + * {@code * // Display an icon and a string for each object in the list. * - * class MyCellRenderer extends JLabel implements ListCellRenderer { + * class MyCellRenderer extends JLabel implements ListCellRenderer<Object> { * final static ImageIcon longIcon = new ImageIcon("long.gif"); * final static ImageIcon shortIcon = new ImageIcon("short.gif"); * @@ -160,7 +178,7 @@ * // We just reconfigure the JLabel each time we're called. * * public Component getListCellRendererComponent( - * JList list, // the list + * JList<?> list, // the list * Object value, // value to display * int index, // cell index * boolean isSelected, // is the cell selected @@ -184,6 +202,7 @@ * } * * myList.setCellRenderer(new MyCellRenderer()); + * } * </pre> * <p> * Another job for the cell renderer is in helping to determine sizing @@ -195,7 +214,8 @@ * automatically based on a single prototype value: * <a name="prototype_example"> * <pre> - * JList bigDataList = new JList(bigData); + * {@code + * JList<String> bigDataList = new JList<String>(bigData); * * // We don't want the JList implementation to compute the width * // or height of all of the list cells, so we give it a string @@ -204,6 +224,7 @@ * // properties. * * bigDataList.setPrototypeCellValue("Index 1234567890"); + * } * </pre> * <p> * {@code JList} doesn't implement scrolling directly. To create a list that @@ -260,13 +281,15 @@ * @see ListCellRenderer * @see DefaultListCellRenderer * + * @param <E> the type of the elements of this list + * * @beaninfo * attribute: isContainer false * description: A component which allows for the selection of one or more objects from a list. * * @author Hans Muller */ -public class JList extends JComponent implements Scrollable, Accessible +public class JList<E> extends JComponent implements Scrollable, Accessible { /** * @see #getUIClassID @@ -301,15 +324,15 @@ private int fixedCellWidth = -1; private int fixedCellHeight = -1; private int horizontalScrollIncrement = -1; - private Object prototypeCellValue; + private E prototypeCellValue; private int visibleRowCount = 8; private Color selectionForeground; private Color selectionBackground; private boolean dragEnabled; private ListSelectionModel selectionModel; - private ListModel dataModel; - private ListCellRenderer cellRenderer; + private ListModel<E> dataModel; + private ListCellRenderer<? super E> cellRenderer; private ListSelectionListener selectionListener; /** @@ -402,7 +425,7 @@ * @param dataModel the model for the list * @exception IllegalArgumentException if the model is {@code null} */ - public JList(ListModel dataModel) + public JList(ListModel<E> dataModel) { if (dataModel == null) { throw new IllegalArgumentException("dataModel must be non null"); @@ -437,12 +460,12 @@ * @param listData the array of Objects to be loaded into the data model, * {@code non-null} */ - public JList(final Object[] listData) + public JList(final E[] listData) { this ( - new AbstractListModel() { + new AbstractListModel<E>() { public int getSize() { return listData.length; } - public Object getElementAt(int i) { return listData[i]; } + public E getElementAt(int i) { return listData[i]; } } ); } @@ -462,11 +485,11 @@ * @param listData the <code>Vector</code> to be loaded into the * data model, {@code non-null} */ - public JList(final Vector<?> listData) { + public JList(final Vector<? extends E> listData) { this ( - new AbstractListModel() { + new AbstractListModel<E>() { public int getSize() { return listData.size(); } - public Object getElementAt(int i) { return listData.elementAt(i); } + public E getElementAt(int i) { return listData.elementAt(i); } } ); } @@ -477,9 +500,9 @@ */ public JList() { this ( - new AbstractListModel() { + new AbstractListModel<E>() { public int getSize() { return 0; } - public Object getElementAt(int i) { return "No Data Model"; } + public E getElementAt(int i) { throw new IndexOutOfBoundsException("No Data Model"); } } ); } @@ -526,7 +549,7 @@ public void updateUI() { setUI((ListUI)UIManager.getUI(this)); - ListCellRenderer renderer = getCellRenderer(); + ListCellRenderer<? super E> renderer = getCellRenderer(); if (renderer instanceof Component) { SwingUtilities.updateComponentTreeUI((Component)renderer); } @@ -560,8 +583,8 @@ */ private void updateFixedCellSize() { - ListCellRenderer cr = getCellRenderer(); - Object value = getPrototypeCellValue(); + ListCellRenderer<? super E> cr = getCellRenderer(); + E value = getPrototypeCellValue(); if ((cr != null) && (value != null)) { Component c = cr.getListCellRendererComponent(this, value, 0, false, false); @@ -592,7 +615,7 @@ * @return the value of the {@code prototypeCellValue} property * @see #setPrototypeCellValue */ - public Object getPrototypeCellValue() { + public E getPrototypeCellValue() { return prototypeCellValue; } @@ -632,8 +655,8 @@ * attribute: visualUpdate true * description: The cell prototype value, used to compute cell width and height. */ - public void setPrototypeCellValue(Object prototypeCellValue) { - Object oldValue = this.prototypeCellValue; + public void setPrototypeCellValue(E prototypeCellValue) { + E oldValue = this.prototypeCellValue; this.prototypeCellValue = prototypeCellValue; /* If the prototypeCellValue has changed and is non-null, @@ -727,7 +750,7 @@ * @see #setCellRenderer */ @Transient - public ListCellRenderer getCellRenderer() { + public ListCellRenderer<? super E> getCellRenderer() { return cellRenderer; } @@ -755,8 +778,8 @@ * attribute: visualUpdate true * description: The component used to draw the cells. */ - public void setCellRenderer(ListCellRenderer cellRenderer) { - ListCellRenderer oldValue = this.cellRenderer; + public void setCellRenderer(ListCellRenderer<? super E> cellRenderer) { + ListCellRenderer<? super E> oldValue = this.cellRenderer; this.cellRenderer = cellRenderer; /* If the cellRenderer has changed and prototypeCellValue @@ -1455,7 +1478,7 @@ * @since 1.4 */ public int getNextMatch(String prefix, int startIndex, Position.Bias bias) { - ListModel model = getModel(); + ListModel<E> model = getModel(); int max = model.getSize(); if (prefix == null) { throw new IllegalArgumentException(); @@ -1469,16 +1492,16 @@ int increment = (bias == Position.Bias.Forward) ? 1 : -1; int index = startIndex; do { - Object o = model.getElementAt(index); - - if (o != null) { + E element = model.getElementAt(index); + + if (element != null) { String string; - if (o instanceof String) { - string = ((String)o).toUpperCase(); + if (element instanceof String) { + string = ((String)element).toUpperCase(); } else { - string = o.toString(); + string = element.toString(); if (string != null) { string = string.toUpperCase(); } @@ -1516,7 +1539,7 @@ if(event != null) { Point p = event.getPoint(); int index = locationToIndex(p); - ListCellRenderer r = getCellRenderer(); + ListCellRenderer<? super E> r = getCellRenderer(); Rectangle cellBounds; if (index != -1 && r != null && (cellBounds = @@ -1634,7 +1657,7 @@ * list of items * @see #setModel */ - public ListModel getModel() { + public ListModel<E> getModel() { return dataModel; } @@ -1656,11 +1679,11 @@ * attribute: visualUpdate true * description: The object that contains the data to be drawn by this JList. */ - public void setModel(ListModel model) { + public void setModel(ListModel<E> model) { if (model == null) { throw new IllegalArgumentException("model must be non null"); } - ListModel oldValue = dataModel; + ListModel<E> oldValue = dataModel; dataModel = model; firePropertyChange("model", oldValue, dataModel); clearSelection(); @@ -1668,7 +1691,7 @@ /** - * Constructs a read-only <code>ListModel</code> from an array of objects, + * Constructs a read-only <code>ListModel</code> from an array of items, * and calls {@code setModel} with this model. * <p> * Attempts to pass a {@code null} value to this method results in @@ -1676,15 +1699,15 @@ * references the given array directly. Attempts to modify the array * after invoking this method results in undefined behavior. * - * @param listData an array of {@code Objects} containing the items to + * @param listData an array of {@code E} containing the items to * display in the list * @see #setModel */ - public void setListData(final Object[] listData) { + public void setListData(final E[] listData) { setModel ( - new AbstractListModel() { + new AbstractListModel<E>() { public int getSize() { return listData.length; } - public Object getElementAt(int i) { return listData[i]; } + public E getElementAt(int i) { return listData[i]; } } ); } @@ -1703,11 +1726,11 @@ * display in the list * @see #setModel */ - public void setListData(final Vector<?> listData) { + public void setListData(final Vector<? extends E> listData) { setModel ( - new AbstractListModel() { + new AbstractListModel<E>() { public int getSize() { return listData.size(); } - public Object getElementAt(int i) { return listData.elementAt(i); } + public E getElementAt(int i) { return listData.elementAt(i); } } ); } @@ -2235,10 +2258,13 @@ * @see #isSelectedIndex * @see #getModel * @see #addListSelectionListener + * + * @deprecated As of JDK 1.7, replaced by {@link #getSelectedValuesList()} */ + @Deprecated public Object[] getSelectedValues() { ListSelectionModel sm = getSelectionModel(); - ListModel dm = getModel(); + ListModel<E> dm = getModel(); int iMin = sm.getMinSelectionIndex(); int iMax = sm.getMaxSelectionIndex(); @@ -2259,6 +2285,37 @@ return rv; } + /** + * Returns a list of all the selected items, in increasing order based + * on their indices in the list. + * + * @return the selected items, or an empty list if nothing is selected + * @see #isSelectedIndex + * @see #getModel + * @see #addListSelectionListener + * + * @since 1.7 + */ + public List<E> getSelectedValuesList() { + ListSelectionModel sm = getSelectionModel(); + ListModel<E> dm = getModel(); + + int iMin = sm.getMinSelectionIndex(); + int iMax = sm.getMaxSelectionIndex(); + + if ((iMin < 0) || (iMax < 0)) { + return Collections.emptyList(); + } + + List<E> selectedItems = new ArrayList<E>(); + for(int i = iMin; i <= iMax; i++) { + if (sm.isSelectedIndex(i)) { + selectedItems.add(dm.getElementAt(i)); + } + } + return selectedItems; + } + /** * Returns the smallest selected cell index; <i>the selection</i> when only @@ -2291,7 +2348,7 @@ * @see #getModel * @see #addListSelectionListener */ - public Object getSelectedValue() { + public E getSelectedValue() { int i = getMinSelectionIndex(); return (i == -1) ? null : getModel().getElementAt(i); } @@ -2309,7 +2366,7 @@ setSelectedIndex(-1); else if(!anObject.equals(getSelectedValue())) { int i,c; - ListModel dm = getModel(); + ListModel<E> dm = getModel(); for(i=0,c=dm.getSize();i<c;i++) if(anObject.equals(dm.getElementAt(i))){ setSelectedIndex(i); @@ -3138,14 +3195,14 @@ */ protected class AccessibleJListChild extends AccessibleContext implements Accessible, AccessibleComponent { - private JList parent = null; + private JList<E> parent = null; private int indexInParent; private Component component = null; private AccessibleContext accessibleContext = null; - private ListModel listModel; - private ListCellRenderer cellRenderer = null; - - public AccessibleJListChild(JList parent, int indexInParent) { + private ListModel<E> listModel; + private ListCellRenderer<? super E> cellRenderer = null; + + public AccessibleJListChild(JList<E> parent, int indexInParent) { this.parent = parent; this.setAccessibleParent(parent); this.indexInParent = indexInParent; @@ -3175,7 +3232,7 @@ if ((parent != null) && (listModel != null) && cellRenderer != null) { - Object value = listModel.getElementAt(index); + E value = listModel.getElementAt(index); boolean isSelected = parent.isSelectedIndex(index); boolean isFocussed = parent.isFocusOwner() && (index == parent.getLeadSelectionIndex());
--- a/jdk/src/share/classes/javax/swing/JTable.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/JTable.java Mon Jan 11 23:25:20 2010 -0800 @@ -1337,7 +1337,11 @@ return (TableCellRenderer)renderer; } else { - return getDefaultRenderer(columnClass.getSuperclass()); + Class c = columnClass.getSuperclass(); + if (c == null && columnClass != Object.class) { + c = Object.class; + } + return getDefaultRenderer(c); } } }
--- a/jdk/src/share/classes/javax/swing/ListCellRenderer.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/ListCellRenderer.java Mon Jan 11 23:25:20 2010 -0800 @@ -33,12 +33,13 @@ * the cells in a JList. For example, to use a JLabel as a * ListCellRenderer, you would write something like this: * <pre> - * class MyCellRenderer extends JLabel implements ListCellRenderer { + * {@code + * class MyCellRenderer extends JLabel implements ListCellRenderer<Object> { * public MyCellRenderer() { * setOpaque(true); * } * - * public Component getListCellRendererComponent(JList list, + * public Component getListCellRendererComponent(JList<?> list, * Object value, * int index, * boolean isSelected, @@ -75,14 +76,17 @@ * return this; * } * } + * } * </pre> * + * @param <E> the type of values this renderer can be used for + * * @see JList * @see DefaultListCellRenderer * * @author Hans Muller */ -public interface ListCellRenderer +public interface ListCellRenderer<E> { /** * Return a component that has been configured to display the specified @@ -104,8 +108,8 @@ * @see ListModel */ Component getListCellRendererComponent( - JList list, - Object value, + JList<? extends E> list, + E value, int index, boolean isSelected, boolean cellHasFocus);
--- a/jdk/src/share/classes/javax/swing/ListModel.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/ListModel.java Mon Jan 11 23:25:20 2010 -0800 @@ -35,10 +35,12 @@ * length of the data model must be reported to all of the * ListDataListeners. * + * @param <E> the type of the elements of this model + * * @author Hans Muller * @see JList */ -public interface ListModel +public interface ListModel<E> { /** * Returns the length of the list. @@ -51,7 +53,7 @@ * @param index the requested index * @return the value at <code>index</code> */ - Object getElementAt(int index); + E getElementAt(int index); /** * Adds a listener to the list that's notified each time a change
--- a/jdk/src/share/classes/javax/swing/Popup.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/Popup.java Mon Jan 11 23:25:20 2010 -0800 @@ -227,12 +227,8 @@ HeavyWeightWindow(Window parent) { super(parent); setFocusableWindowState(false); - Toolkit tk = Toolkit.getDefaultToolkit(); - if (tk instanceof SunToolkit) { - // all the short-lived windows like Popups should be - // OverrideRedirect on X11 platforms - ((SunToolkit)tk).setOverrideRedirect(this); - } + setType(Window.Type.POPUP); + // Popups are typically transient and most likely won't benefit // from true double buffering. Turn it off here. getRootPane().setUseTrueDoubleBuffering(false);
--- a/jdk/src/share/classes/javax/swing/plaf/ComponentUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/ComponentUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -60,13 +60,13 @@ } /** - * Configures the specified component appropriate for the look and feel. + * Configures the specified component appropriately for the look and feel. * This method is invoked when the <code>ComponentUI</code> instance is being installed * as the UI delegate on the specified component. This method should * completely configure the component for the look and feel, * including the following: * <ol> - * <li>Install any default property values for color, fonts, borders, + * <li>Install default property values for color, fonts, borders, * icons, opacity, etc. on the component. Whenever possible, * property values initialized by the client program should <i>not</i> * be overridden. @@ -116,7 +116,7 @@ } /** - * Paints the specified component appropriate for the look and feel. + * Paints the specified component appropriately for the look and feel. * This method is invoked from the <code>ComponentUI.update</code> method when * the specified component is being painted. Subclasses should override * this method and use the specified <code>Graphics</code> object to @@ -134,15 +134,15 @@ } /** - * Notifies this UI delegate that it's time to paint the specified + * Notifies this UI delegate that it is time to paint the specified * component. This method is invoked by <code>JComponent</code> * when the specified component is being painted. - * By default this method will fill the specified component with - * its background color (if its <code>opaque</code> property is - * <code>true</code>) and then immediately call <code>paint</code>. - * In general this method need not be overridden by subclasses; - * all look-and-feel rendering code should reside in the <code>paint</code> - * method. + * + * <p>By default this method fills the specified component with + * its background color if its {@code opaque} property is {@code true}, + * and then immediately calls {@code paint}. In general this method need + * not be overridden by subclasses; all look-and-feel rendering code should + * reside in the {@code paint} method. * * @param g the <code>Graphics</code> context in which to paint * @param c the component being painted;
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java Mon Jan 11 23:25:20 2010 -0800 @@ -24,14 +24,10 @@ */ package javax.swing.plaf.basic; -import javax.swing.*; +import javax.swing.ComboBoxEditor; +import javax.swing.JTextField; import javax.swing.border.Border; - -import javax.swing.text.AttributeSet; -import javax.swing.text.BadLocationException; -import javax.swing.text.PlainDocument; - -import java.awt.*; +import java.awt.Component; import java.awt.event.*; import java.lang.reflect.Method; @@ -73,12 +69,17 @@ * @param anObject the displayed value of the editor */ public void setItem(Object anObject) { + String text; + if ( anObject != null ) { - editor.setText(anObject.toString()); - + text = anObject.toString(); oldValue = anObject; } else { - editor.setText(""); + text = ""; + } + // workaround for 4530952 + if (! text.equals(editor.getText())) { + editor.setText(text); } }
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -30,7 +30,6 @@ import javax.swing.*; import javax.accessibility.*; import javax.swing.plaf.*; -import javax.swing.border.*; import javax.swing.text.*; import javax.swing.event.*; import java.beans.PropertyChangeListener; @@ -189,19 +188,20 @@ /** * Indicates whether or not the combo box button should be square. * If square, then the width and height are equal, and are both set to - * the height of the combo (minus appropriate insets). + * the height of the combo minus appropriate insets. + * + * @since 1.7 */ - private boolean squareButton = true; + protected boolean squareButton = true; /** - * Optional: if specified, these insets act as padding around the cell - * renderer when laying out and painting the "selected" item in the - * combo box. BasicComboBoxUI uses a single combo box renderer for rendering - * both the main combo box item and also all the items in the dropdown - * for the combo box. padding allows you to specify addition insets in - * addition to those specified by the cell renderer. + * If specified, these insets act as padding around the cell renderer when + * laying out and painting the "selected" item in the combo box. These + * insets add to those specified by the cell renderer. + * + * @since 1.7 */ - private Insets padding; + protected Insets padding; // Used for calculating the default size. private static ListCellRenderer getDefaultListCellRenderer() { @@ -345,7 +345,7 @@ } /** - * Create and install the listeners for the combo box and its model. + * Creates and installs listeners for the combo box and its model. * This method is called when the UI is installed. */ protected void installListeners() { @@ -379,8 +379,8 @@ } /** - * Uninstalls the default colors, default font, default renderer, and default - * editor into the JComboBox. + * Uninstalls the default colors, default font, default renderer, + * and default editor from the combo box. */ protected void uninstallDefaults() { LookAndFeel.installColorsAndFont( comboBox, @@ -391,7 +391,7 @@ } /** - * Remove the installed listeners from the combo box and its model. + * Removes the installed listeners from the combo box and its model. * The number and types of listeners removed and in this method should be * the same that was added in <code>installListeners</code> */ @@ -839,7 +839,7 @@ } /** - * Creates an button which will be used as the control to show or hide + * Creates a button which will be used as the control to show or hide * the popup portion of the combo box. * * @return a button which represents the popup control @@ -1392,12 +1392,17 @@ } /** - * This has been refactored out in hopes that it may be investigated and - * simplified for the next major release. adding/removing - * the component to the currentValuePane and changing the font may be - * redundant operations. + * Returns the size a component would have if used as a cell renderer. + * + * @param comp a {@code Component} to check + * @return size of the component + * @since 1.7 */ - private Dimension getSizeForComponent(Component comp) { + protected Dimension getSizeForComponent(Component comp) { + // This has been refactored out in hopes that it may be investigated and + // simplified for the next major release. adding/removing + // the component to the currentValuePane and changing the font may be + // redundant operations. currentValuePane.add(comp); comp.setFont(comboBox.getFont()); Dimension d = comp.getPreferredSize();
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -141,11 +141,10 @@ } /** - * Paint the label text in the foreground color, if the label - * is opaque then paint the entire background with the background - * color. The Label text is drawn by paintEnabledText() or - * paintDisabledText(). The locations of the label parts are computed - * by layoutCL. + * Paints the label text with the foreground color, if the label is opaque + * then paints the entire background with the background color. The Label + * text is drawn by {@link #paintEnabledText} or {@link #paintDisabledText}. + * The locations of the label parts are computed by {@link #layoutCL}. * * @see #paintEnabledText * @see #paintDisabledText
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicListUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicListUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -685,7 +685,7 @@ /** - * Create and install the listeners for the JList, its model, and its + * Creates and installs the listeners for the JList, its model, and its * selectionModel. This method is called at installUI() time. * * @see #installUI @@ -728,7 +728,7 @@ /** - * Remove the listeners for the JList, its model, and its + * Removes the listeners from the JList, its model, and its * selectionModel. All of the listener fields, are reset to * null here. This method is called at uninstallUI() time, * it should be kept in sync with installListeners. @@ -764,8 +764,8 @@ /** - * Initialize JList properties, e.g. font, foreground, and background, - * and add the CellRendererPane. The font, foreground, and background + * Initializes list properties such as font, foreground, and background, + * and adds the CellRendererPane. The font, foreground, and background * properties are only set if their current value is either null * or a UIResource, other properties are set if the current * value is null. @@ -820,9 +820,9 @@ /** - * Set the JList properties that haven't been explicitly overridden to - * null. A property is considered overridden if its current value - * is not a UIResource. + * Sets the list properties that have not been explicitly overridden to + * {@code null}. A property is considered overridden if its current value + * is not a {@code UIResource}. * * @see #installDefaults * @see #uninstallUI
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -32,7 +32,6 @@ import javax.swing.*; import javax.swing.event.*; -import javax.swing.border.*; import javax.swing.plaf.*; import javax.swing.text.View; @@ -54,7 +53,12 @@ protected Color disabledForeground; protected Color acceleratorForeground; protected Color acceleratorSelectionForeground; - private String acceleratorDelimiter; + + /** + * Accelerator delimiter string, such as {@code '+'} in {@code 'Ctrl+C'}. + * @since 1.7 + */ + protected String acceleratorDelimiter; protected int defaultTextIconGap; protected Font acceleratorFont;
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -93,10 +93,13 @@ * scrollbar. */ private boolean supportsAbsolutePositioning; - /** Hint as to what width (when vertical) or height (when horizontal) + /** + * Hint as to what width (when vertical) or height (when horizontal) * should be. + * + * @since 1.7 */ - private int scrollBarWidth; + protected int scrollBarWidth; private Handler handler; @@ -117,18 +120,18 @@ * number. If negative, then an overlap between the button and track will occur, * which is useful for shaped buttons. * - * TODO This should be made protected in a feature release + * @since 1.7 */ - private int incrGap; + protected int incrGap; /** * Distance between the decrement button and the track. This may be a negative * number. If negative, then an overlap between the button and track will occur, * which is useful for shaped buttons. * - * TODO This should be made protected in a feature release + * @since 1.7 */ - private int decrGap; + protected int decrGap; static void loadActionMap(LazyActionMap map) { map.put(new Actions(Actions.POSITIVE_UNIT_INCREMENT)); @@ -586,7 +589,7 @@ /** - * Return the smallest acceptable size for the thumb. If the scrollbar + * Returns the smallest acceptable size for the thumb. If the scrollbar * becomes so small that this size isn't available, the thumb will be * hidden. * <p> @@ -601,7 +604,7 @@ } /** - * Return the largest acceptable size for the thumb. To create a fixed + * Returns the largest acceptable size for the thumb. To create a fixed * size thumb one make this method and <code>getMinimumThumbSize</code> * return the same value. * <p>
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -1409,9 +1409,10 @@ } /** - * Returns a value give a y position. If yPos is past the track at the top or the - * bottom it will set the value to the min or max of the slider, depending if the - * slider is inverted or not. + * Returns the value at the y position. If {@code yPos} is beyond the + * track at the the bottom or the top, this method sets the value to either + * the minimum or maximum value of the slider, depending on if the slider + * is inverted or not. */ public int valueForYPosition( int yPos ) { int value; @@ -1440,9 +1441,10 @@ } /** - * Returns a value give an x position. If xPos is past the track at the left or the - * right it will set the value to the min or max of the slider, depending if the - * slider is inverted or not. + * Returns the value at the x position. If {@code xPos} is beyond the + * track at the left or the right, this method sets the value to either the + * minimum or maximum value of the slider, depending on if the slider is + * inverted or not. */ public int valueForXPosition( int xPos ) { int value;
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -268,7 +268,7 @@ } /** - * Create a <code>LayoutManager</code> that manages the <code>editor</code>, + * Creates a <code>LayoutManager</code> that manages the <code>editor</code>, * <code>nextButton</code>, and <code>previousButton</code> * children of the JSpinner. These three children must be * added with a constraint that identifies their role: @@ -286,7 +286,7 @@ /** - * Create a <code>PropertyChangeListener</code> that can be + * Creates a <code>PropertyChangeListener</code> that can be * added to the JSpinner itself. Typically, this listener * will call replaceEditor when the "editor" property changes, * since it's the <code>SpinnerUI's</code> responsibility to @@ -302,16 +302,13 @@ /** - * Create a component that will replace the spinner models value - * with the object returned by <code>spinner.getPreviousValue</code>. - * By default the <code>previousButton</code> is a JButton. This - * method invokes <code>installPreviousButtonListeners</code> to - * install the necessary listeners to update the <code>JSpinner</code>'s - * model in response to a user gesture. If a previousButton isn't needed - * (in a subclass) then override this method to return null. + * Creates a decrement button, i.e. component that replaces the spinner + * value with the object returned by <code>spinner.getPreviousValue</code>. + * By default the <code>previousButton</code> is a {@code JButton}. If the + * decrement button is not needed this method should return {@code null}. * - * @return a component that will replace the spinners model with the - * next value in the sequence, or null + * @return a component that will replace the spinner's value with the + * previous value in the sequence, or {@code null} * @see #installUI * @see #createNextButton * @see #installPreviousButtonListeners @@ -325,15 +322,13 @@ /** - * Create a component that will replace the spinner models value - * with the object returned by <code>spinner.getNextValue</code>. - * By default the <code>nextButton</code> is a JButton - * who's <code>ActionListener</code> updates it's <code>JSpinner</code> - * ancestors model. If a nextButton isn't needed (in a subclass) - * then override this method to return null. + * Creates an increment button, i.e. component that replaces the spinner + * value with the object returned by <code>spinner.getNextValue</code>. + * By default the <code>nextButton</code> is a {@code JButton}. If the + * increment button is not needed this method should return {@code null}. * - * @return a component that will replace the spinners model with the - * next value in the sequence, or null + * @return a component that will replace the spinner's value with the + * next value in the sequence, or {@code null} * @see #installUI * @see #createPreviousButton * @see #installNextButtonListeners
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -829,7 +829,7 @@ /** * Returns the default non continuous layout divider, which is an - * instanceof Canvas that fills the background in dark gray. + * instance of {@code Canvas} that fills in the background with dark gray. */ protected Component createDefaultNonContinuousLayoutDivider() { return new Canvas() { @@ -1041,11 +1041,11 @@ /** - * Messaged after the JSplitPane the receiver is providing the look - * and feel for paints its children. + * Called when the specified split pane has finished painting + * its children. */ - public void finishedPaintingChildren(JSplitPane jc, Graphics g) { - if(jc == splitPane && getLastDragLocation() != -1 && + public void finishedPaintingChildren(JSplitPane sp, Graphics g) { + if(sp == splitPane && getLastDragLocation() != -1 && !isContinuousLayout() && !draggingHW) { Dimension size = splitPane.getSize(); @@ -1062,7 +1062,7 @@ /** - * Messaged to paint the look and feel. + * @inheritDoc */ public void paint(Graphics g, JComponent jc) { if (!painted && splitPane.getDividerLocation()<0) {
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTableHeaderUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTableHeaderUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -306,7 +306,7 @@ } /** - * Initialize JTableHeader properties, e.g. font, foreground, and background. + * Initializes JTableHeader properties such as font, foreground, and background. * The font, foreground, and background properties are only set if their * current value is either null or a UIResource, other properties are set * if the current value is null. @@ -403,9 +403,9 @@ } /** - * This method gets called every time the rollover column in the table - * header is updated. Every look and feel supporting rollover effect - * in table header should override this method and repaint the header. + * This method gets called every time when a rollover column in the table + * header is updated. Every look and feel that supports a rollover effect + * in a table header should override this method and repaint the header. * * @param oldColumn the index of the previous rollover column or -1 if the * mouse was not over a column @@ -736,7 +736,6 @@ } private Dimension createHeaderSize(long width) { - TableColumnModel columnModel = header.getColumnModel(); // None of the callers include the intercell spacing, do it here. if (width > Integer.MAX_VALUE) { width = Integer.MAX_VALUE;
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -37,6 +37,7 @@ import javax.swing.event.*; import javax.swing.border.Border; import javax.swing.plaf.UIResource; +import javax.swing.plaf.synth.SynthUI; import sun.swing.DefaultLookup; import sun.awt.AppContext; import javax.swing.plaf.basic.DragRecognitionSupport.BeforeDrag; @@ -221,8 +222,7 @@ // is ==, which is the case for the windows look and feel. // Until an appropriate solution is found, the code is being // reverted to what it was before the original fix. - if (this instanceof sun.swing.plaf.synth.SynthUI || - (c instanceof JTextArea)) { + if (this instanceof SynthUI || (c instanceof JTextArea)) { return; } Color background = c.getBackground(); @@ -289,7 +289,7 @@ protected abstract String getPropertyPrefix(); /** - * Initializes component properties, e.g. font, foreground, + * Initializes component properties, such as font, foreground, * background, caret color, selection color, selected text color, * disabled text color, and border color. The font, foreground, and * background properties are only set if their current value is either null @@ -377,9 +377,9 @@ } /** - * Sets the component properties that haven't been explicitly overridden to - * null. A property is considered overridden if its current value - * is not a UIResource. + * Sets the component properties that have not been explicitly overridden + * to {@code null}. A property is considered overridden if its current + * value is not a {@code UIResource}. * * @see #installDefaults * @see #uninstallUI @@ -756,18 +756,18 @@ * things. * <ol> * <li> - * Set the associated component to opaque (can be changed + * Sets the associated component to opaque (can be changed * easily by a subclass or on JTextComponent directly), * which is the most common case. This will cause the * component's background color to be painted. * <li> - * Install the default caret and highlighter into the + * Installs the default caret and highlighter into the * associated component. * <li> - * Attach to the editor and model. If there is no + * Attaches to the editor and model. If there is no * model, a default one is created. * <li> - * create the view factory and the view hierarchy used + * Creates the view factory and the view hierarchy used * to represent the model. * </ol> * @@ -784,7 +784,7 @@ // This is a workaround as these should not override what synth has // set them to - if (!(this instanceof sun.swing.plaf.synth.SynthUI)){ + if (! (this instanceof SynthUI)) { // common case is background painted... this can // easily be changed by subclasses or from outside // of the component. @@ -857,9 +857,9 @@ * To prevent this from happening twice, this method is * reimplemented to simply paint. * <p> - * <em>NOTE:</em> Superclass is also not thread-safe in - * it's rendering of the background, although that's not - * an issue with the default rendering. + * <em>NOTE:</em> NOTE: Superclass is also not thread-safe in its + * rendering of the background, although that is not an issue with the + * default rendering. */ public void update(Graphics g, JComponent c) { paint(g, c);
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -669,7 +669,7 @@ /** * Sets the border of the component to have a rollover border which - * was created by <code>createRolloverBorder</code>. + * was created by the {@link #createRolloverBorder} method. * * @param c component which will have a rollover border installed * @see #createRolloverBorder @@ -709,7 +709,7 @@ /** * Sets the border of the component to have a non-rollover border which - * was created by <code>createNonRolloverBorder</code>. + * was created by the {@link #createNonRolloverBorder} method. * * @param c component which will have a non-rollover border installed * @see #createNonRolloverBorder
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -30,16 +30,12 @@ import java.awt.*; import java.awt.event.*; import java.awt.datatransfer.*; -import java.awt.dnd.*; import java.beans.*; -import java.io.*; import java.util.Enumeration; import java.util.Hashtable; -import java.util.TooManyListenersException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.TreeUI; @@ -1244,11 +1240,26 @@ drawingCache.clear(); } - private boolean isDropLine(JTree.DropLocation loc) { + /** + * Tells if a {@code DropLocation} should be indicated by a line between + * nodes. This is meant for {@code javax.swing.DropMode.INSERT} and + * {@code javax.swing.DropMode.ON_OR_INSERT} drop modes. + * + * @param loc a {@code DropLocation} + * @return {@code true} if the drop location should be shown as a line + * @since 1.7 + */ + protected boolean isDropLine(JTree.DropLocation loc) { return loc != null && loc.getPath() != null && loc.getChildIndex() != -1; } - private void paintDropLine(Graphics g) { + /** + * Paints the drop line. + * + * @param g {@code Graphics} object to draw on + * @since 1.7 + */ + protected void paintDropLine(Graphics g) { JTree.DropLocation loc = tree.getDropLocation(); if (!isDropLine(loc)) { return; @@ -1262,7 +1273,14 @@ } } - private Rectangle getDropLineRect(JTree.DropLocation loc) { + /** + * Returns a ubounding box for the drop line. + * + * @param loc a {@code DropLocation} + * @return bounding box for the drop line + * @since 1.7 + */ + protected Rectangle getDropLineRect(JTree.DropLocation loc) { Rectangle rect; TreePath path = loc.getPath(); int index = loc.getChildIndex(); @@ -1684,7 +1702,7 @@ treeState.setExpandedState(path, true); } } - updateLeadRow(); + updateLeadSelectionRow(); updateSize(); } } @@ -2425,11 +2443,21 @@ return tree.getLeadSelectionPath(); } - private void updateLeadRow() { + /** + * Updates the lead row of the selection. + * @since 1.7 + */ + protected void updateLeadSelectionRow() { leadRow = getRowForPath(tree, getLeadSelectionPath()); } - private int getLeadSelectionRow() { + /** + * Returns the lead row of the selection. + * + * @return selection lead row + * @since 1.7 + */ + protected int getLeadSelectionRow() { return leadRow; } @@ -3345,7 +3373,7 @@ if (changeName == JTree.LEAD_SELECTION_PATH_PROPERTY) { if (!ignoreLAChange) { - updateLeadRow(); + updateLeadSelectionRow(); repaintPath((TreePath)event.getOldValue()); repaintPath((TreePath)event.getNewValue()); } @@ -3763,7 +3791,7 @@ completeEditing(); if(path != null && tree.isVisible(path)) { treeState.setExpandedState(path, false); - updateLeadRow(); + updateLeadSelectionRow(); updateSize(); } } @@ -3823,7 +3851,7 @@ if(treeState != null && e != null) { treeState.treeNodesInserted(e); - updateLeadRow(); + updateLeadSelectionRow(); TreePath path = e.getTreePath(); @@ -3848,7 +3876,7 @@ if(treeState != null && e != null) { treeState.treeNodesRemoved(e); - updateLeadRow(); + updateLeadSelectionRow(); TreePath path = e.getTreePath(); @@ -3862,7 +3890,7 @@ if(treeState != null && e != null) { treeState.treeStructureChanged(e); - updateLeadRow(); + updateLeadSelectionRow(); TreePath pPath = e.getTreePath();
--- a/jdk/src/share/classes/javax/swing/plaf/basic/DefaultMenuLayout.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/DefaultMenuLayout.java Mon Jan 11 23:25:20 2010 -0800 @@ -34,7 +34,7 @@ /** * The default layout manager for Popup menus and menubars. This * class is an extension of BoxLayout which adds the UIResource tag - * so that plauggable L&Fs can distinguish it from user-installed + * so that pluggable L&Fs can distinguish it from user-installed * layout managers on menus. * * @author Georges Saab
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java Mon Jan 11 23:25:20 2010 -0800 @@ -257,13 +257,41 @@ /** * @inheritDoc - * @return true + * @return {@code true} */ @Override public boolean shouldUpdateStyleOnAncestorChanged() { return true; } /** + * @inheritDoc + * + * <p>Overridden to return {@code true} when one of the following + * properties change: + * <ul> + * <li>{@code "Nimbus.Overrides"} + * <li>{@code "Nimbus.Overrides.InheritDefaults"} + * <li>{@code "JComponent.sizeVariant"} + * </ul> + * + * @since 1.7 + */ + @Override + protected boolean shouldUpdateStyleOnEvent(PropertyChangeEvent ev) { + String eName = ev.getPropertyName(); + + // Always update when overrides or size variant change + if ("Nimbus.Overrides" == eName || + "Nimbus.Overrides.InheritDefaults" == eName || + "JComponent.sizeVariant" == eName) { + + return true; + } + + return super.shouldUpdateStyleOnEvent(ev); + } + + /** * <p>Registers a third party component with the NimbusLookAndFeel.</p> * * <p>Regions represent Components and areas within Components that act as
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/package.html Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/package.html Mon Jan 11 23:25:20 2010 -0800 @@ -88,12 +88,11 @@ <p><strong>Note:</strong> Most of the Swing API is <em>not</em> thread safe. For details, see -<a -href="http://java.sun.com/docs/books/tutorial/uiswing/overview/threads.html" -target="_top">Threads and Swing</a>, +<a href="http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html" + target="_top">Concurrency in Swing</a>, a section in <em><a href="http://java.sun.com/docs/books/tutorial/" -target="_top">The Java Tutorial</a></em>. + target="_top">The Java Tutorial</a></em>. @since 1.7 @serial exclude
--- a/jdk/src/share/classes/javax/swing/plaf/synth/DefaultMenuLayout.java Wed Jan 06 19:32:55 2010 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright 2002-2008 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package javax.swing.plaf.synth; - -import javax.swing.*; -import javax.swing.plaf.UIResource; - -import java.awt.Container; -import java.awt.Dimension; - -/** - * The default layout manager for Popup menus and menubars. This - * class is an extension of BoxLayout which adds the UIResource tag - * so that plauggable L&Fs can distinguish it from user-installed - * layout managers on menus. - * - * Derived from javax.swing.plaf.basic.DefaultMenuLayout - * - * @author Georges Saab - */ - -class DefaultMenuLayout extends BoxLayout implements UIResource { - public DefaultMenuLayout(Container target, int axis) { - super(target, axis); - } - - public Dimension preferredLayoutSize(Container target) { - if (target instanceof JPopupMenu) { - JPopupMenu popupMenu = (JPopupMenu) target; - - popupMenu.putClientProperty( - SynthMenuItemLayoutHelper.MAX_ACC_OR_ARROW_WIDTH, null); - sun.swing.MenuItemLayoutHelper.clearUsedClientProperties(popupMenu); - - if (popupMenu.getComponentCount() == 0) { - return new Dimension(0, 0); - } - } - - // Make BoxLayout recalculate cached preferred sizes - super.invalidateLayout(target); - - return super.preferredLayoutSize(target); - } -}
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthBorder.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthBorder.java Mon Jan 11 23:25:20 2010 -0800 @@ -29,7 +29,6 @@ import javax.swing.text.JTextComponent; import javax.swing.border.*; import javax.swing.plaf.UIResource; -import sun.swing.plaf.synth.SynthUI; /** * SynthBorder is a border that delegates to a Painter. The Insets
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -25,40 +25,49 @@ package javax.swing.plaf.synth; +import javax.swing.*; import java.awt.*; -import java.awt.event.*; -import java.io.Serializable; -import javax.swing.*; -import javax.swing.border.*; -import java.awt.*; -import java.awt.event.*; import java.beans.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicButtonUI; import javax.swing.plaf.basic.BasicHTML; import javax.swing.text.View; -import sun.swing.plaf.synth.SynthUI; -import sun.swing.plaf.synth.DefaultSynthStyle; /** - * Synth's ButtonUI implementation. + * Provides the Synth L&F UI delegate for + * {@link javax.swing.JButton}. * * @author Scott Violet + * @since 1.7 */ -class SynthButtonUI extends BasicButtonUI implements +public class SynthButtonUI extends BasicButtonUI implements PropertyChangeListener, SynthUI { private SynthStyle style; + /** + * Creates a new UI object for the given component. + * + * @param c component to create UI object for + * @return the UI object + */ public static ComponentUI createUI(JComponent c) { return new SynthButtonUI(); } + /** + * @inheritDoc + */ + @Override protected void installDefaults(AbstractButton b) { updateStyle(b); LookAndFeel.installProperty(b, "rolloverEnabled", Boolean.TRUE); } + /** + * @inheritDoc + */ + @Override protected void installListeners(AbstractButton b) { super.installListeners(b); b.addPropertyChangeListener(this); @@ -99,11 +108,19 @@ context.dispose(); } + /** + * @inheritDoc + */ + @Override protected void uninstallListeners(AbstractButton b) { super.uninstallListeners(b); b.removePropertyChangeListener(this); } + /** + * @inheritDoc + */ + @Override protected void uninstallDefaults(AbstractButton b) { SynthContext context = getContext(b, ENABLED); @@ -112,20 +129,20 @@ style = null; } + /** + * @inheritDoc + */ + @Override public SynthContext getContext(JComponent c) { return getContext(c, getComponentState(c)); } SynthContext getContext(JComponent c, int state) { - Region region = getRegion(c); + Region region = SynthLookAndFeel.getRegion(c); return SynthContext.getContext(SynthContext.class, c, region, style, state); } - private Region getRegion(JComponent c) { - return SynthLookAndFeel.getRegion(c); - } - /** * Returns the current state of the passed in <code>AbstractButton</code>. */ @@ -164,6 +181,10 @@ return state; } + /** + * @inheritDoc + */ + @Override public int getBaseline(JComponent c, int width, int height) { if (c == null) { throw new NullPointerException("Component must be non-null"); @@ -215,6 +236,10 @@ // Paint Methods // ******************************** + /** + * @inheritDoc + */ + @Override public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -224,6 +249,10 @@ context.dispose(); } + /** + * @inheritDoc + */ + @Override public void paint(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -231,6 +260,12 @@ context.dispose(); } + /** + * Paints the specified component. + * + * @param context context for the component being painted + * @param g {@code Graphics} object used for painting + */ protected void paint(SynthContext context, Graphics g) { AbstractButton b = (AbstractButton)context.getComponent(); @@ -253,19 +288,22 @@ } } + /** + * @inheritDoc + */ + @Override public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) { context.getPainter().paintButtonBorder(context, g, x, y, w, h); } /** - * Returns the default icon. This should NOT callback + * Returns the default icon. This should not callback * to the JComponent. * - * @param b AbstractButton the icon is associated with + * @param b button the icon is associated with * @return default icon */ - protected Icon getDefaultIcon(AbstractButton b) { SynthContext context = getContext(b); Icon icon = context.getStyle().getIcon(context, getPropertyPrefix() + "icon"); @@ -274,7 +312,11 @@ } /** - * Returns the Icon to use in painting the button. + * Returns the Icon to use for painting the button. The icon is chosen with + * respect to the current state of the button. + * + * @param b button the icon is associated with + * @return an icon */ protected Icon getIcon(AbstractButton b) { Icon icon = b.getIcon(); @@ -374,7 +416,7 @@ /** * Returns the amount to shift the text/icon when painting. */ - protected int getTextShiftOffset(SynthContext state) { + private int getTextShiftOffset(SynthContext state) { AbstractButton button = (AbstractButton)state.getComponent(); ButtonModel model = button.getModel(); @@ -389,6 +431,11 @@ // ******************************** // Layout Methods // ******************************** + + /** + * @inheritDoc + */ + @Override public Dimension getMinimumSize(JComponent c) { if (c.getComponentCount() > 0 && c.getLayout() != null) { return null; @@ -406,6 +453,10 @@ return size; } + /** + * @inheritDoc + */ + @Override public Dimension getPreferredSize(JComponent c) { if (c.getComponentCount() > 0 && c.getLayout() != null) { return null; @@ -423,6 +474,10 @@ return size; } + /** + * @inheritDoc + */ + @Override public Dimension getMaximumSize(JComponent c) { if (c.getComponentCount() > 0 && c.getLayout() != null) { return null; @@ -442,7 +497,8 @@ } /** - * Returns the Icon used in calculating the pref/min/max size. + * Returns the Icon used in calculating the + * preferred/minimum/maximum size. */ protected Icon getSizingIcon(AbstractButton b) { Icon icon = getEnabledIcon(b, b.getIcon()); @@ -452,6 +508,10 @@ return icon; } + /** + * @inheritDoc + */ + @Override public void propertyChange(PropertyChangeEvent e) { if (SynthLookAndFeel.shouldUpdateStyle(e)) { updateStyle((AbstractButton)e.getSource());
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxMenuItemUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxMenuItemUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -27,56 +27,50 @@ import java.awt.*; -import java.awt.event.*; import javax.swing.*; import javax.swing.plaf.*; -import javax.swing.border.*; -import java.io.Serializable; /** - * Synth's CheckBoxMenuItemUI. + * Provides the Synth L&F UI delegate for + * {@link javax.swing.JCheckBoxMenuItem}. * * @author Leif Samuelsson * @author Georges Saab * @author David Karlton * @author Arnaud Weber + * @since 1.7 */ -class SynthCheckBoxMenuItemUI extends SynthMenuItemUI { +public class SynthCheckBoxMenuItemUI extends SynthMenuItemUI { + /** + * Creates a new UI object for the given component. + * + * @param c component to create UI object for + * @return the UI object + */ public static ComponentUI createUI(JComponent c) { return new SynthCheckBoxMenuItemUI(); } + /** + * @inheritDoc + */ + @Override protected String getPropertyPrefix() { return "CheckBoxMenuItem"; } - public void processMouseEvent(JMenuItem item, MouseEvent e, - MenuElement path[], MenuSelectionManager manager) { - Point p = e.getPoint(); - if (p.x >= 0 && p.x < item.getWidth() && p.y >= 0 && p.y < item.getHeight()) { - if (e.getID() == MouseEvent.MOUSE_RELEASED) { - manager.clearSelectedPath(); - item.doClick(0); - } else { - manager.setSelectedPath(path); - } - } else if (item.getModel().isArmed()) { - int c = path.length - 1; - MenuElement newPath[] = new MenuElement[c]; - for (int i = 0; i < c; i++) { - newPath[i] = path[i]; - } - manager.setSelectedPath(newPath); - } - } - + @Override void paintBackground(SynthContext context, Graphics g, JComponent c) { context.getPainter().paintCheckBoxMenuItemBackground(context, g, 0, 0, c.getWidth(), c.getHeight()); } + /** + * @inheritDoc + */ + @Override public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) { context.getPainter().paintCheckBoxMenuItemBorder(context, g, x, y, w, h);
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -25,36 +25,51 @@ package javax.swing.plaf.synth; -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import javax.swing.plaf.*; -import java.io.Serializable; +import javax.swing.JComponent; +import java.awt.Graphics; +import javax.swing.plaf.ComponentUI; /** - * Synth's CheckBoxUI. + * Provides the Synth L&F UI delegate for + * {@link javax.swing.JCheckBox}. * * @author Jeff Dinkins + * @since 1.7 */ -class SynthCheckBoxUI extends SynthRadioButtonUI { +public class SynthCheckBoxUI extends SynthRadioButtonUI { // ******************************** // Create PLAF // ******************************** + /** + * Creates a new UI object for the given component. + * + * @param b component to create UI object for + * @return the UI object + */ public static ComponentUI createUI(JComponent b) { return new SynthCheckBoxUI(); } + /** + * @inheritDoc + */ + @Override protected String getPropertyPrefix() { return "CheckBox."; } + @Override void paintBackground(SynthContext context, Graphics g, JComponent c) { context.getPainter().paintCheckBoxBackground(context, g, 0, 0, c.getWidth(), c.getHeight()); } + /** + * @inheritDoc + */ + @Override public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) { context.getPainter().paintCheckBoxBorder(context, g, x, y, w, h);
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthColorChooserUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthColorChooserUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -28,34 +28,39 @@ import javax.swing.*; import javax.swing.colorchooser.*; -import javax.swing.event.*; -import javax.swing.border.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicColorChooserUI; -import java.util.*; import java.awt.*; -import java.awt.image.*; -import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.io.Serializable; -import sun.swing.plaf.synth.SynthUI; /** - * Synth's ColorChooserUI. + * Provides the Synth L&F UI delegate for + * {@link javax.swing.JColorChooser}. * * @author Tom Santos * @author Steve Wilson + * @since 1.7 */ -class SynthColorChooserUI extends BasicColorChooserUI implements +public class SynthColorChooserUI extends BasicColorChooserUI implements PropertyChangeListener, SynthUI { private SynthStyle style; + /** + * Creates a new UI object for the given component. + * + * @param c component to create UI object for + * @return the UI object + */ public static ComponentUI createUI(JComponent c) { return new SynthColorChooserUI(); } + /** + * @inheritDoc + */ + @Override protected AbstractColorChooserPanel[] createDefaultChoosers() { SynthContext context = getContext(chooser, ENABLED); AbstractColorChooserPanel[] panels = (AbstractColorChooserPanel[]) @@ -68,6 +73,10 @@ return panels; } + /** + * @inheritDoc + */ + @Override protected void installDefaults() { super.installDefaults(); updateStyle(chooser); @@ -79,6 +88,10 @@ context.dispose(); } + /** + * @inheritDoc + */ + @Override protected void uninstallDefaults() { SynthContext context = getContext(chooser, ENABLED); @@ -88,16 +101,28 @@ super.uninstallDefaults(); } + /** + * @inheritDoc + */ + @Override protected void installListeners() { super.installListeners(); chooser.addPropertyChangeListener(this); } + /** + * @inheritDoc + */ + @Override protected void uninstallListeners() { chooser.removePropertyChangeListener(this); super.uninstallListeners(); } + /** + * @inheritDoc + */ + @Override public SynthContext getContext(JComponent c) { return getContext(c, getComponentState(c)); } @@ -107,14 +132,14 @@ SynthLookAndFeel.getRegion(c), style, state); } - private Region getRegion(JComponent c) { - return SynthLookAndFeel.getRegion(c); - } - private int getComponentState(JComponent c) { return SynthLookAndFeel.getComponentState(c); } + /** + * @inheritDoc + */ + @Override public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -125,6 +150,10 @@ context.dispose(); } + /** + * @inheritDoc + */ + @Override public void paint(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -132,14 +161,29 @@ context.dispose(); } + /** + * Paints the specified component. + * This implementation does not perform any actions. + * + * @param context context for the component being painted + * @param g {@code Graphics} object used for painting + */ protected void paint(SynthContext context, Graphics g) { } + /** + * @inheritDoc + */ + @Override public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) { context.getPainter().paintColorChooserBorder(context, g, x, y,w,h); } + /** + * @inheritDoc + */ + @Override public void propertyChange(PropertyChangeEvent e) { if (SynthLookAndFeel.shouldUpdateStyle(e)) { updateStyle((JColorChooser)e.getSource());
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -27,21 +27,21 @@ import java.awt.*; import java.awt.event.*; -import java.lang.reflect.*; import javax.swing.*; import javax.swing.plaf.*; import javax.swing.event.*; import javax.swing.plaf.basic.*; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; -import sun.swing.plaf.synth.SynthUI; /** - * Synth's ComboBoxUI. + * Provides the Synth L&F UI delegate for + * {@link javax.swing.JComboBox}. * * @author Scott Violet + * @since 1.7 */ -class SynthComboBoxUI extends BasicComboBoxUI implements +public class SynthComboBoxUI extends BasicComboBoxUI implements PropertyChangeListener, SynthUI { private SynthStyle style; private boolean useListColors; @@ -93,12 +93,11 @@ private boolean forceOpaque = false; /** - * NOTE: This serves the same purpose as the same field in BasicComboBoxUI. - * It is here because I could not give the padding field in - * BasicComboBoxUI protected access in an update release. + * Creates a new UI object for the given component. + * + * @param c component to create UI object for + * @return the UI object */ - private Insets padding; - public static ComponentUI createUI(JComponent c) { return new SynthComboBoxUI(); } @@ -118,21 +117,6 @@ @Override protected void installDefaults() { - //NOTE: This next line of code was added because, since squareButton in - //BasicComboBoxUI is private, I need to have some way of reading it from UIManager. - //This is an incomplete solution (since it implies that squareButons, - //once set, cannot be reset per state. Probably ok, but not always ok). - //This line of code should be removed at the same time that squareButton - //is made protected in the super class. - super.installDefaults(); - - //This is here instead of in updateStyle because the value for padding - //needs to remain consistent with the value for padding in - //BasicComboBoxUI. I wouldn't have this value here at all if not - //for the fact that I cannot make "padding" protected in any way - //for an update release. This *should* be fixed in Java 7 - padding = UIManager.getInsets("ComboBox.padding"); - updateStyle(comboBox); } @@ -142,6 +126,7 @@ style = SynthLookAndFeel.updateStyle(context, this); if (style != oldStyle) { + padding = (Insets) style.get(context, "ComboBox.padding"); popupInsets = (Insets)style.get(context, "ComboBox.popupInsets"); useListColors = style.getBoolean(context, "ComboBox.rendererUseListColors", true); @@ -149,6 +134,8 @@ "ComboBox.buttonWhenNotEditable", false); pressedWhenPopupVisible = style.getBoolean(context, "ComboBox.pressedWhenPopupVisible", false); + squareButton = style.getBoolean(context, + "ComboBox.squareButton", true); if (oldStyle != null) { uninstallKeyboardActions(); @@ -164,6 +151,9 @@ } } + /** + * @inheritDoc + */ @Override protected void installListeners() { comboBox.addPropertyChangeListener(this); @@ -172,6 +162,9 @@ super.installListeners(); } + /** + * @inheritDoc + */ @Override public void uninstallUI(JComponent c) { if (popup instanceof SynthComboPopup) { @@ -181,6 +174,9 @@ buttonHandler = null; } + /** + * @inheritDoc + */ @Override protected void uninstallDefaults() { SynthContext context = getContext(comboBox, ENABLED); @@ -190,6 +186,9 @@ style = null; } + /** + * @inheritDoc + */ @Override protected void uninstallListeners() { editorFocusHandler.unregister(); @@ -200,6 +199,9 @@ super.uninstallListeners(); } + /** + * @inheritDoc + */ @Override public SynthContext getContext(JComponent c) { return getContext(c, getComponentState(c)); @@ -210,10 +212,6 @@ SynthLookAndFeel.getRegion(c), style, state); } - private Region getRegion(JComponent c) { - return SynthLookAndFeel.getRegion(c); - } - private int getComponentState(JComponent c) { // currently we have a broken situation where if a developer // takes the border from a JComboBox and sets it on a JTextField @@ -252,6 +250,9 @@ } } + /** + * @inheritDoc + */ @Override protected ComboPopup createPopup() { SynthComboPopup p = new SynthComboPopup(comboBox); @@ -259,11 +260,17 @@ return p; } + /** + * @inheritDoc + */ @Override protected ListCellRenderer createRenderer() { return new SynthComboBoxRenderer(); } + /** + * @inheritDoc + */ @Override protected ComboBoxEditor createEditor() { return new SynthComboBoxEditor(); @@ -273,6 +280,9 @@ // end UI Initialization //====================== + /** + * @inheritDoc + */ @Override public void propertyChange(PropertyChangeEvent e) { if (SynthLookAndFeel.shouldUpdateStyle(e)) { @@ -280,6 +290,9 @@ } } + /** + * @inheritDoc + */ @Override protected JButton createArrowButton() { SynthArrowButton button = new SynthArrowButton(SwingConstants.SOUTH); @@ -291,6 +304,9 @@ //================================= // begin ComponentUI Implementation + /** + * @inheritDoc + */ @Override public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -302,6 +318,9 @@ context.dispose(); } + /** + * @inheritDoc + */ @Override public void paint(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -310,6 +329,12 @@ context.dispose(); } + /** + * Paints the specified component. + * + * @param context context for the component being painted + * @param g {@code Graphics} object used for painting + */ protected void paint(SynthContext context, Graphics g) { hasFocus = comboBox.hasFocus(); if ( !comboBox.isEditable() ) { @@ -318,6 +343,9 @@ } } + /** + * @inheritDoc + */ @Override public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) { @@ -375,7 +403,7 @@ } /** - * Return the default size of an empty display area of the combo box using + * Returns the default size of an empty display area of the combo box using * the current renderer and font. * * This method was overridden to use SynthComboBoxRenderer instead of @@ -394,23 +422,6 @@ } /** - * This has been refactored out in hopes that it may be investigated and - * simplified for the next major release. adding/removing - * the component to the currentValuePane and changing the font may be - * redundant operations. - * - * NOTE: This method was copied in its entirety from BasicComboBoxUI. Might - * want to make it protected in BasicComboBoxUI in Java 7 - */ - private Dimension getSizeForComponent(Component comp) { - currentValuePane.add(comp); - comp.setFont(comboBox.getFont()); - Dimension d = comp.getPreferredSize(); - currentValuePane.remove(comp); - return d; - } - - /** * From BasicComboBoxRenderer v 1.18. * * Be aware that SynthFileChooserUIImpl relies on the fact that the default @@ -478,85 +489,17 @@ } - /** - * From BasicCombBoxEditor v 1.24. - */ - private static class SynthComboBoxEditor implements - ComboBoxEditor, UIResource { - protected JTextField editor; - private Object oldValue; - - public SynthComboBoxEditor() { - editor = new JTextField("",9); - editor.setName("ComboBox.textField"); - } - - @Override - public Component getEditorComponent() { - return editor; - } - - /** - * Sets the item that should be edited. - * - * @param anObject the displayed value of the editor - */ - @Override - public void setItem(Object anObject) { - String text; + private static class SynthComboBoxEditor + extends BasicComboBoxEditor.UIResource { - if ( anObject != null ) { - text = anObject.toString(); - oldValue = anObject; - } else { - text = ""; - } - // workaround for 4530952 - if (!text.equals(editor.getText())) { - editor.setText(text); - } - } - - @Override - public Object getItem() { - Object newValue = editor.getText(); - - if (oldValue != null && !(oldValue instanceof String)) { - // The original value is not a string. Should return the value in it's - // original type. - if (newValue.equals(oldValue.toString())) { - return oldValue; - } else { - // Must take the value from the editor and get the value and cast it to the new type. - Class<?> cls = oldValue.getClass(); - try { - Method method = cls.getMethod("valueOf", new Class[]{String.class}); - newValue = method.invoke(oldValue, new Object[] { editor.getText()}); - } catch (Exception ex) { - // Fail silently and return the newValue (a String object) - } - } - } - return newValue; - } - - @Override - public void selectAll() { - editor.selectAll(); - editor.requestFocus(); - } - - @Override - public void addActionListener(ActionListener l) { - editor.addActionListener(l); - } - - @Override - public void removeActionListener(ActionListener l) { - editor.removeActionListener(l); + @Override public JTextField createEditorComponent() { + JTextField f = new JTextField("", 9); + f.setName("ComboBox.textField"); + return f; } } + /** * Handles all the logic for treating the combo as a button when it is * not editable, and when shouldActLikeButton() is true. This class is a @@ -620,7 +563,7 @@ //------------------------------------------------------------------ /** - * {@inheritDoc} + * @inheritDoc * * Ensures that isPressed() will return true if the combo is pressed, * or the arrowButton is pressed, <em>or</em> if the combo popup is @@ -634,7 +577,7 @@ } /** - * {@inheritDoc} + * @inheritDoc * * Ensures that the armed state is in sync with the pressed state * if shouldActLikeButton is true. Without this method, the arrow @@ -649,7 +592,7 @@ } /** - * {@inheritDoc} + * @inheritDoc * * Ensures that isRollover() will return true if the combo is * rolled over, or the arrowButton is rolled over. @@ -660,7 +603,7 @@ } /** - * {@inheritDoc} + * @inheritDoc * * Forwards pressed states to the internal "pressed" field */ @@ -671,7 +614,7 @@ } /** - * {@inheritDoc} + * @inheritDoc * * Forwards rollover states to the internal "over" field */
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java Mon Jan 11 23:25:20 2010 -0800 @@ -27,7 +27,6 @@ import sun.swing.DefaultLookup; import javax.swing.JComponent; import javax.swing.plaf.ComponentUI; -import sun.swing.plaf.synth.SynthUI; /** * SynthDefaultLookup redirects all lookup calls to the SynthContext.
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -28,36 +28,44 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; -import javax.swing.event.*; -import javax.swing.border.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicDesktopIconUI; import java.beans.*; -import java.io.Serializable; -import sun.swing.plaf.synth.SynthUI; /** - * Synth L&F for a minimized window on a desktop. + * Provides the Synth L&F UI delegate for a minimized internal frame on a desktop. * * @author Joshua Outwater + * @since 1.7 */ -class SynthDesktopIconUI extends BasicDesktopIconUI implements SynthUI, - ActionListener, PropertyChangeListener { +public class SynthDesktopIconUI extends BasicDesktopIconUI + implements SynthUI, PropertyChangeListener { private SynthStyle style; + private Handler handler = new Handler(); + /** + * Creates a new UI object for the given component. + * + * @param c component to create UI object for + * @return the UI object + */ public static ComponentUI createUI(JComponent c) { return new SynthDesktopIconUI(); } + /** + * @inheritDoc + */ + @Override protected void installComponents() { if (UIManager.getBoolean("InternalFrame.useTaskBar")) { iconPane = new JToggleButton(frame.getTitle(), frame.getFrameIcon()) { - public String getToolTipText() { + @Override public String getToolTipText() { return getText(); } - public JPopupMenu getComponentPopupMenu() { + @Override public JPopupMenu getComponentPopupMenu() { return frame.getComponentPopupMenu(); } }; @@ -73,24 +81,37 @@ desktopIcon.add(iconPane, BorderLayout.CENTER); } + /** + * @inheritDoc + */ + @Override protected void installListeners() { super.installListeners(); desktopIcon.addPropertyChangeListener(this); if (iconPane instanceof JToggleButton) { frame.addPropertyChangeListener(this); - ((JToggleButton)iconPane).addActionListener(this); + ((JToggleButton)iconPane).addActionListener(handler); } } + /** + * @inheritDoc + */ + @Override protected void uninstallListeners() { if (iconPane instanceof JToggleButton) { + ((JToggleButton)iconPane).removeActionListener(handler); frame.removePropertyChangeListener(this); } desktopIcon.removePropertyChangeListener(this); super.uninstallListeners(); } + /** + * @inheritDoc + */ + @Override protected void installDefaults() { updateStyle(desktopIcon); } @@ -101,6 +122,10 @@ context.dispose(); } + /** + * @inheritDoc + */ + @Override protected void uninstallDefaults() { SynthContext context = getContext(desktopIcon, ENABLED); style.uninstallDefaults(context); @@ -108,12 +133,16 @@ style = null; } + /** + * @inheritDoc + */ + @Override public SynthContext getContext(JComponent c) { return getContext(c, getComponentState(c)); } private SynthContext getContext(JComponent c, int state) { - Region region = getRegion(c); + Region region = SynthLookAndFeel.getRegion(c); return SynthContext.getContext(SynthContext.class, c, region, style, state); } @@ -122,10 +151,10 @@ return SynthLookAndFeel.getComponentState(c); } - Region getRegion(JComponent c) { - return SynthLookAndFeel.getRegion(c); - } - + /** + * @inheritDoc + */ + @Override public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -136,6 +165,10 @@ context.dispose(); } + /** + * @inheritDoc + */ + @Override public void paint(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -143,33 +176,24 @@ context.dispose(); } + /** + * Paints the specified component. This implementation does nothing. + * + * @param context context for the component being painted + * @param g {@code Graphics} object used for painting + */ protected void paint(SynthContext context, Graphics g) { } + /** + * @inheritDoc + */ + @Override public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) { context.getPainter().paintDesktopIconBorder(context, g, x, y, w, h); } - public void actionPerformed(ActionEvent evt) { - if (evt.getSource() instanceof JToggleButton) { - // Either iconify the frame or deiconify and activate it. - JToggleButton button = (JToggleButton)evt.getSource(); - try { - boolean selected = button.isSelected(); - if (!selected && !frame.isIconifiable()) { - button.setSelected(true); - } else { - frame.setIcon(!selected); - if (selected) { - frame.setSelected(true); - } - } - } catch (PropertyVetoException e2) { - } - } - } - public void propertyChange(PropertyChangeEvent evt) { if (evt.getSource() instanceof JInternalFrame.JDesktopIcon) { if (SynthLookAndFeel.shouldUpdateStyle(evt)) { @@ -191,4 +215,25 @@ } } } + + private final class Handler implements ActionListener { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource() instanceof JToggleButton) { + // Either iconify the frame or deiconify and activate it. + JToggleButton button = (JToggleButton)evt.getSource(); + try { + boolean selected = button.isSelected(); + if (!selected && !frame.isIconifiable()) { + button.setSelected(true); + } else { + frame.setIcon(!selected); + if (selected) { + frame.setSelected(true); + } + } + } catch (PropertyVetoException e2) { + } + } + } + } }
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -29,34 +29,38 @@ import javax.swing.border.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicDesktopPaneUI; - import java.beans.*; - import java.awt.event.*; -import java.awt.Dimension; -import java.awt.Insets; -import java.awt.Graphics; -import java.awt.KeyboardFocusManager; import java.awt.*; -import java.util.Vector; -import sun.swing.plaf.synth.SynthUI; /** - * Synth L&F for a desktop. + * Provides the Synth L&F UI delegate for + * {@link javax.swing.JDesktopPane}. * * @author Joshua Outwater * @author Steve Wilson + * @since 1.7 */ -class SynthDesktopPaneUI extends BasicDesktopPaneUI implements +public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements PropertyChangeListener, SynthUI { private SynthStyle style; private TaskBar taskBar; private DesktopManager oldDesktopManager; + /** + * Creates a new UI object for the given component. + * + * @param c component to create UI object for + * @return the UI object + */ public static ComponentUI createUI(JComponent c) { return new SynthDesktopPaneUI(); } + /** + * @inheritDoc + */ + @Override protected void installListeners() { super.installListeners(); desktop.addPropertyChangeListener(this); @@ -68,6 +72,10 @@ } } + /** + * @inheritDoc + */ + @Override protected void installDefaults() { updateStyle(desktop); @@ -114,6 +122,10 @@ context.dispose(); } + /** + * @inheritDoc + */ + @Override protected void uninstallListeners() { if (taskBar != null) { desktop.removeComponentListener(taskBar); @@ -123,6 +135,10 @@ super.uninstallListeners(); } + /** + * @inheritDoc + */ + @Override protected void uninstallDefaults() { SynthContext context = getContext(desktop, ENABLED); @@ -147,6 +163,10 @@ } } + /** + * @inheritDoc + */ + @Override protected void installDesktopManager() { if (UIManager.getBoolean("InternalFrame.useTaskBar")) { desktopManager = oldDesktopManager = desktop.getDesktopManager(); @@ -159,6 +179,10 @@ } } + /** + * @inheritDoc + */ + @Override protected void uninstallDesktopManager() { if (oldDesktopManager != null && !(oldDesktopManager instanceof UIResource)) { desktopManager = desktop.getDesktopManager(); @@ -397,7 +421,10 @@ } } - + /** + * @inheritDoc + */ + @Override public SynthContext getContext(JComponent c) { return getContext(c, getComponentState(c)); } @@ -407,14 +434,14 @@ SynthLookAndFeel.getRegion(c), style, state); } - private Region getRegion(JComponent c) { - return SynthLookAndFeel.getRegion(c); - } - private int getComponentState(JComponent c) { return SynthLookAndFeel.getComponentState(c); } + /** + * @inheritDoc + */ + @Override public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -425,6 +452,10 @@ context.dispose(); } + /** + * @inheritDoc + */ + @Override public void paint(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -432,14 +463,28 @@ context.dispose(); } + /** + * Paints the specified component. This implementation does nothing. + * + * @param context context for the component being painted + * @param g {@code Graphics} object used for painting + */ protected void paint(SynthContext context, Graphics g) { } + /** + * @inheritDoc + */ + @Override public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) { context.getPainter().paintDesktopPaneBorder(context, g, x, y, w, h); } + /** + * @inheritDoc + */ + @Override public void propertyChange(PropertyChangeEvent evt) { if (SynthLookAndFeel.shouldUpdateStyle(evt)) { updateStyle((JDesktopPane)evt.getSource());
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -31,47 +31,52 @@ import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicEditorPaneUI; import java.beans.PropertyChangeEvent; -import sun.swing.plaf.synth.SynthUI; /** - * Provides the look and feel for a JEditorPane in the - * Synth look and feel. + * Provides the Synth L&F UI delegate for + * {@link javax.swing.JEditorPane}. * * @author Shannon Hickey + * @since 1.7 */ -class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI { +public class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI { private SynthStyle style; /* * I would prefer to use UIResource instad of this. * Unfortunately Boolean is a final class */ private Boolean localTrue = Boolean.TRUE; - private Boolean localFalse = Boolean.FALSE; /** - * Creates a UI for the JTextPane. + * Creates a new UI object for the given component. * - * @param c the JTextPane component - * @return the UI + * @param c component to create UI object for + * @return the UI object */ public static ComponentUI createUI(JComponent c) { return new SynthEditorPaneUI(); } + /** + * @inheritDoc + */ + @Override protected void installDefaults() { // Installs the text cursor on the component super.installDefaults(); JComponent c = getComponent(); Object clientProperty = c.getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES); - if (clientProperty == null - || clientProperty == localFalse) { - c.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, - localTrue); + if (clientProperty == null) { + c.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, localTrue); } updateStyle(getComponent()); } + /** + * @inheritDoc + */ + @Override protected void uninstallDefaults() { SynthContext context = getContext(getComponent(), ENABLED); JComponent c = getComponent(); @@ -84,7 +89,7 @@ Object clientProperty = c.getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES); if (clientProperty == localTrue) { - getComponent().putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, + c.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.FALSE); } super.uninstallDefaults(); @@ -100,6 +105,7 @@ * * @param evt the property change event */ + @Override protected void propertyChange(PropertyChangeEvent evt) { if (SynthLookAndFeel.shouldUpdateStyle(evt)) { updateStyle((JTextComponent)evt.getSource()); @@ -124,6 +130,10 @@ context.dispose(); } + /** + * @inheritDoc + */ + @Override public SynthContext getContext(JComponent c) { return getContext(c, getComponentState(c)); } @@ -137,6 +147,10 @@ return SynthLookAndFeel.getComponentState(c); } + /** + * @inheritDoc + */ + @Override public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -146,10 +160,20 @@ context.dispose(); } + /** + * Paints the specified component. + * + * @param context context for the component being painted + * @param g {@code Graphics} object used for painting + */ protected void paint(SynthContext context, Graphics g) { super.paint(g, getComponent()); } + /** + * @inheritDoc + */ + @Override protected void paintBackground(Graphics g) { // Overriden to do nothing, all our painting is done from update/paint. } @@ -159,6 +183,10 @@ c.getWidth(), c.getHeight()); } + /** + * @inheritDoc + */ + @Override public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) { context.getPainter().paintEditorPaneBorder(context, g, x, y, w, h);
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthFormattedTextFieldUI.java Wed Jan 06 19:32:55 2010 -0800 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthFormattedTextFieldUI.java Mon Jan 11 23:25:20 2010 -0800 @@ -24,16 +24,17 @@ */ package javax.swing.plaf.synth; -import java.awt.*; -import javax.swing.*; +import java.awt.Graphics; +import javax.swing.JComponent; import javax.swing.plaf.ComponentUI; /** - * Provides the look and feel implementation for - * <code>JFormattedTextField</code>. + * Provides the Synth L&F UI delegate for + * {@link javax.swing.JFormattedTextField}. * + * @since 1.7 */ -class SynthFormattedTextFieldUI extends SynthTextFieldUI {