diff --git a/.hgtags b/.hgtags index 8079102b3dd..6069f7df024 100644 --- a/.hgtags +++ b/.hgtags @@ -70,3 +70,9 @@ ff9031a745d9cc52318f2148e43ca3b07ee08098 jdk7-b92 b5dab6a313fdff4c043250e4d9c8f66fd624d27e jdk7-b93 8bb281f0f91582104d65d032be22522bfd2d8110 jdk7-b94 654298d26561b76dfe3cfcffbbd7078080837300 jdk7-b95 +d260f892491e040ae385a8e6df59557a7d721abf jdk7-b96 +7e406ebed9a5968b584f3c3e6b60893b5d6d9741 jdk7-b97 +db6e660120446c407e2d908d52ec046592b21726 jdk7-b98 +c4c8a5bc54f66abc68cd185d9294042121922154 jdk7-b99 +2d6ba7a221915bdf0311acc5641c7f3875cb793e jdk7-b100 +2548ac036b8fca3326d058d758e6df8355a42469 jdk7-b101 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 762d535ba7a..9b4264cf2d1 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -70,3 +70,9 @@ cf26288a114be67c39f2758959ce50b60f5ae330 jdk7-b85 5fc102ff48f0e787ce9cc77249841d5ff0941b75 jdk7-b93 d7f35c61afa092b6357c2c4bce3f298f16620f71 jdk7-b94 fd3663286e77b9f13c39eee124db2beb079b3ca6 jdk7-b95 +cf71cb5151166f35433afebaf67dbf34a704a170 jdk7-b96 +5e197c942c6ebd8b92f324a31049c5f1d26d40ef jdk7-b97 +6cea9984d73d74de0cd01f30d07ac0a1ed196117 jdk7-b98 +e7f18db469a3e947b7096bfd12e87380e5a042cd jdk7-b99 +b218a53ec7d3d42be61d31d6917a6c5c037b6f56 jdk7-b100 +4193eaf5f1b82794c6a0fb1a8d11af43d1b1d611 jdk7-b101 diff --git a/Makefile b/Makefile index 0e7f4b4de5d..065e0c55edc 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 1995, 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -29,10 +29,6 @@ ifndef TOPDIR TOPDIR:=. endif -ifndef CONTROL_TOPDIR - CONTROL_TOPDIR=$(TOPDIR) -endif - # Openjdk sources (only used if SKIP_OPENJDK_BUILD!=true) OPENJDK_SOURCETREE=$(TOPDIR)/openjdk OPENJDK_BUILDDIR:=$(shell \ @@ -120,7 +116,7 @@ endif all_product_build:: @$(FINISH_ECHO) -# Generis build of basic repo series +# Generic build of basic repo series generic_build_repo_series:: $(MKDIR) -p $(OUTPUTDIR) $(MKDIR) -p $(OUTPUTDIR)/j2sdk-image @@ -179,11 +175,15 @@ endif # The install process needs to know what the DEBUG_NAME is, so # look for INSTALL_DEBUG_NAME in the install rules. # +# NOTE: On windows, do not use $(ABS_BOOTDIR_OUTPUTDIR)-$(DEBUG_NAME). +# Due to the use of short paths in $(ABS_OUTPUTDIR), this may +# not be the same location. +# # Location of fresh bootdir output ABS_BOOTDIR_OUTPUTDIR=$(ABS_OUTPUTDIR)/bootjdk FRESH_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)/j2sdk-image -FRESH_DEBUG_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)-$(DEBUG_NAME)/j2sdk-image +FRESH_DEBUG_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-$(DEBUG_NAME)/j2sdk-image create_fresh_product_bootdir: FRC @$(START_ECHO) @@ -248,10 +248,14 @@ build_product_image: generic_build_repo_series @$(FINISH_ECHO) +# NOTE: On windows, do not use $(ABS_OUTPUTDIR)-$(DEBUG_NAME). +# Due to the use of short paths in $(ABS_OUTPUTDIR), this may +# not be the same location. + generic_debug_build: @$(START_ECHO) $(MAKE) \ - ALT_OUTPUTDIR=$(ABS_OUTPUTDIR)-$(DEBUG_NAME) \ + ALT_OUTPUTDIR=$(ABS_OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-$(DEBUG_NAME) \ DEBUG_NAME=$(DEBUG_NAME) \ GENERATE_DOCS=false \ $(BOOT_CYCLE_DEBUG_SETTINGS) \ @@ -348,8 +352,8 @@ endif clobber:: $(RM) -r $(OUTPUTDIR)/* - $(RM) -r $(OUTPUTDIR)-debug/* - $(RM) -r $(OUTPUTDIR)-fastdebug/* + $(RM) -r $(OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-debug/* + $(RM) -r $(OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-fastdebug/* -($(RMDIR) -p $(OUTPUTDIR) > $(DEV_NULL) 2>&1; $(TRUE)) clean: clobber @@ -550,6 +554,56 @@ ifeq ($(BUNDLE_RULES_AVAILABLE), true) include $(BUNDLE_RULES) endif +################################################################ +# rule to test +################################################################ + +.NOTPARALLEL: test + +test: test_clean test_start test_summary + +test_start: + @$(ECHO) "Tests started at `$(DATE)`" + +test_clean: + $(RM) $(OUTPUTDIR)/test_failures.txt $(OUTPUTDIR)/test_log.txt + +test_summary: $(OUTPUTDIR)/test_failures.txt + @$(ECHO) "#################################################" + @$(ECHO) "Tests completed at `$(DATE)`" + @( $(EGREP) '^TEST STATS:' $(OUTPUTDIR)/test_log.txt \ + || $(ECHO) "No TEST STATS seen in log" ) + @$(ECHO) "For complete details see: $(OUTPUTDIR)/test_log.txt" + @$(ECHO) "#################################################" + @if [ -s $< ] ; then \ + $(ECHO) "ERROR: Test failure count: `$(CAT) $< | $(WC) -l`"; \ + $(CAT) $<; \ + exit 1; \ + else \ + $(ECHO) "Success! No failures detected"; \ + fi + +# Get failure list from log +$(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt + @$(RM) $@ + @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) > $@ + +# Get log file of all tests run +JDK_TO_TEST := $(shell \ + if [ -d "$(ABS_OUTPUTDIR)/j2sdk-image" ] ; then \ + $(ECHO) "$(ABS_OUTPUTDIR)/j2sdk-image"; \ + elif [ -d "$(ABS_OUTPUTDIR)/bin" ] ; then \ + $(ECHO) "$(ABS_OUTPUTDIR)"; \ + elif [ "$(PRODUCT_HOME)" != "" -a -d "$(PRODUCT_HOME)/bin" ] ; then \ + $(ECHO) "$(PRODUCT_HOME)"; \ + fi \ +) +$(OUTPUTDIR)/test_log.txt: + $(RM) $@ + ( $(CD) test && \ + $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) \ + ) | tee $@ + ################################################################ # JPRT rule to build ################################################################ @@ -560,7 +614,7 @@ include ./make/jprt.gmk # PHONY ################################################################ -.PHONY: all \ +.PHONY: all test test_start test_summary test_clean \ generic_build_repo_series \ what clobber insane \ dev dev-build dev-sanity dev-clobber \ diff --git a/README-builds.html b/README-builds.html index 0b6fd25722b..00b8612911d 100644 --- a/README-builds.html +++ b/README-builds.html @@ -65,8 +65,9 @@
- Windows x64: Microsoft Visual Studio Compilers + Windows x64: Microsoft Visual Studio 2010 Professional CompilerBEGIN WARNING: At this time (Spring/Summer 2010) JDK 7 is starting a transition to @@ -971,14 +972,13 @@ So for now you should be able to build with either VS2003 or VS2010. We do not guarantee that VS2008 will work, although there is sufficient makefile support to make at least basic JDK builds plausible. Visual Studio 2010 Express compilers are now able to build all the -open source repositories, but this is 32 bit only, since -we have not yet seen the 7.1 Windows SDK with the 64 bit -compilers. END WARNING. +open source repositories, but this is 32 bit only. To build 64 bit +Windows binaries use the the 7.1 Windows SDK.END WARNING.
The 32-bit OpenJDK Windows build requires Microsoft Visual Studio C++ 2010 (VS2010) Professional - Edition compiler. + Edition or Express compiler. The compiler and other tools are expected to reside in the location defined by the variable VS100COMNTOOLS which @@ -1001,14 +1001,33 @@ compilers. END WARNING. The path /usr/bin must be after the path to the Visual Studio product.
- On X64, the set up is much the same in VS2010 + For X64, builds, when using the VS2010 Professional + compiler, the 64 bit build set up is much the same as 32 bit except that you run amd64\VCVARS64.BAT to set the compiler environment variables. - Previously 64 builds had used the 64 bit compiler in - an unbundled Windows SDK but this is no longer necessary. + Previously 64 bit builds had used the 64 bit compiler in + an unbundled Windows SDK but this is no longer necessary if + you have VS2010 Professional.+ Windows x64: Microsoft Windows 7.1 SDK 64 bit compilers. + For a free alternative for 64 bit builds, use the 7.1 SDK. + Microsoft say that to set up your paths for this run +
+ c:\Program Files\Microsoft SDKs\Windows\v7.1\bin\setenv.cmd /x64. ++ What was tested is just directly setting up LIB, INCLUDE, + PATH and based on the installation directories using the + DOS short name appropriate for the system, (you will + need to set them for yours, not just blindly copy this) eg : +
+ set VSINSTALLDIR=c:\PROGRA~2\MICROS~1.0 + set WindowsSdkDir=c:\PROGRA~1\MICROS~1\Windows\v7.1 + set PATH=%VSINSTALLDIR%\vc\bin\amd64;%VSINSTALLDIR%\Common7\IDE;%WindowsSdkDir%\bin;%PATH% + set INCLUDE=%VSINSTALLDIR%\vc\include;%WindowsSdkDir%\include + set LIB=%VSINSTALLDIR%\vc\lib\amd64;%WindowsSdkDir%\lib\x64 +
$(call CopyrightLine,,$1,)
+endef + +# Common trademark bottom argument (Not sure why this is used sometimes) +define CommonTrademarkBottom # year +\ +$(BUG_SUBMIT_LINE)\ +$(call CopyrightLine,$(COPYRIGHT_URL),$(FIRST_COPYRIGHT_YEAR),)\ +
+ +# Common javadoc options used by all COMMON_JAVADOCFLAGS = \ - $(NO_PROPRIETARY_API_WARNINGS) \ + $(NO_PROPRIETARY_API_WARNINGS) \ -source 1.5 \ -quiet \ -use \ -keywords \ - $(JAVADOC_VM_MEMORY_FLAGS) \ $(ADDITIONAL_JAVADOCFLAGS) ADDITIONAL_JAVADOCFLAGS = -CORE_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS) \ - $(TAGS) \ - -encoding ISO-8859-1 \ - -splitIndex \ - -doctitle $(DOCTITLE_SWITCH) \ - -windowtitle $(WINDOWTITLE_SWITCH) \ - -header $(HEADER_SWITCH) \ - $(TOPOPTION) \ - -bottom $(JAVADOCBOTTOM_SWITCH) \ - $(OVERVIEW_OPTION) - -DRAFT = 'Copyright $(THIS_YEAR) Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms. Also see the documentation redistribution policy.
' -JAVADOCOVERVIEW = $(SHARE_SRC)/classes/overview-core.html - -# -# Early access top and bottom text (for snapshots, beta and rc) -# -JAVADOCTOP_EARLYACCESS = 'Copyright $(THIS_YEAR) Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms.
' -JAVADOCTITLE_EARLYACCESS = $(subst Specification,Documentation,$(JAVADOCTITLE)) - -# -# Variables used by domapidocs target -# - -DOMAPI_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS) \ - -encoding ascii \ - -splitIndex \ - -doctitle $(DOMAPI_JAVADOCTITLE) \ - -windowtitle $(DOMAPI_JAVADOCWINDOWTITLE) \ - -header $(DOMAPI_JAVADOCHEADER) \ - -bottom $(DOMAPI_JAVADOCBOTTOM) \ - -group $(DOMAPI_GROUPNAME) $(DOMAPI_REGEXP) -DOMAPI_JAVADOCTITLE = 'Common DOM API' -DOMAPI_JAVADOCWINDOWTITLE = 'Common DOM API' -DOMAPI_JAVADOCHEADER = 'Common DOM API' -DOMAPI_JAVADOCBOTTOM = 'Submit a bug or feature
- * This method is called once immediately after instantiating this input
- * method.
- *
- * @param context the input method context for this input method
- * @exception NullPointerException if context
is null
- */
- public void setInputMethodContext(InputMethodContext context) {
-
- impl.setInputMethodContext(context);
- }
-
- /**
- * Attempts to set the input locale. If the input method supports the
- * desired locale, it changes its behavior to support input for the locale
- * and returns true.
- * Otherwise, it returns false and does not change its behavior.
- *
- * This method is called - *
locale
is null
- */
- public boolean setLocale(Locale locale) {
-
- if (locale.getLanguage().equals(this.locale.getLanguage())) {
- //System.out.println("returning true for locale " + locale);
- return true;
- }
- else {
- //System.out.println("returning false for locale " + locale);
- return false;
- }
- }
-
- /**
- * Returns the current input locale. Might return null in exceptional cases.
- * - * This method is called - *
- * This method is called - *
enable
.
- * - * An input method that is enabled for composition interprets incoming - * events for both composition and control purposes, while a - * disabled input method does not interpret events for composition. - * Note however that events are passed on to the input method regardless - * whether it is enabled or not, and that an input method that is disabled - * for composition may still interpret events for control purposes, - * including to enable or disable itself for composition. - *
- * This method is called - *
- * This method is called - *
true
if this input method is enabled for
- * composition; false
otherwise.
- * @throws UnsupportedOperationException if this input method does not
- * support checking whether it is enabled for composition
- * @see #setCompositionEnabled
- */
- public boolean isCompositionEnabled() {
-
- return true;
- }
-
- /**
- * Starts the reconversion operation. The input method obtains the
- * text to be reconverted from the current client component using the
- * {@link java.awt.im.InputMethodRequests#getSelectedText InputMethodRequests.getSelectedText}
- * method. It can use other InputMethodRequests
- * methods to request additional information required for the
- * reconversion operation. The composed and committed text
- * produced by the operation is sent to the client component as a
- * sequence of InputMethodEvent
s. If the given text
- * cannot be reconverted, the same text should be sent to the
- * client component as committed text.
- *
- * This method is called by
- * {@link java.awt.im.InputContext#reconvert() InputContext.reconvert}.
- *
- * @throws UnsupportedOperationException if the input method does not
- * support the reconversion operation.
- */
- public void reconvert() {
-
- throw new UnsupportedOperationException("This input method does not reconvert.");
- }
-
- /**
- * Dispatches the event to the input method. If input method support is
- * enabled for the focussed component, incoming events of certain types
- * are dispatched to the current input method for this component before
- * they are dispatched to the component's methods or event listeners.
- * The input method decides whether it needs to handle the event. If it
- * does, it also calls the event's consume
method; this
- * causes the event to not get dispatched to the component's event
- * processing methods or event listeners.
- *
- * Events are dispatched if they are instances of InputEvent or its - * subclasses. - * This includes instances of the AWT classes KeyEvent and MouseEvent. - *
- * This method is called by {@link java.awt.im.InputContext#dispatchEvent InputContext.dispatchEvent}.
- *
- * @param event the event being dispatched to the input method
- * @exception NullPointerException if event
is null
- */
- public void dispatchEvent(AWTEvent event) {
-
- if (event instanceof KeyEvent) {
-
- KeyEvent keyEvent = (KeyEvent) event;
- if (event.getID() == KeyEvent.KEY_TYPED) {
- impl.handleKeyTyped(keyEvent);
- }
- //System.out.println("handled event " + event);
- }
- else {
- //System.out.println("did not handle event " + event);
- }
- }
-
- /**
- * Notifies this input method of changes in the client window
- * location or state. This method is called while this input
- * method is the current input method of its input context and
- * notifications for it are enabled (see {@link
- * InputMethodContext#enableClientWindowNotification
- * InputMethodContext.enableClientWindowNotification}). Calls
- * to this method are temporarily suspended if the input context's
- * {@link java.awt.im.InputContext#removeNotify removeNotify}
- * method is called, and resume when the input method is activated
- * for a new client component. It is called in the following
- * situations:
- *
enableClientWindowNotification(inputMethod,
- * true)
if the current client component exists,enableClientWindowNotification(inputMethod,
- * true)
if during the call no current client component was
- * available,- * If an input method provides its own windows, it should make sure - * at this point that all necessary windows are open and visible. - *
- * This method is called - *
- * If an input method provides its own windows, only windows that relate - * to the current composition (such as a lookup choice window) should be - * closed at this point. - * It is possible that the input method will be immediately activated again - * for a different client component, and closing and reopening more - * persistent windows (such as a control panel) would create unnecessary - * screen flicker. - * Before an instance of a different input method class is activated, - * {@link #hideWindows} is called on the current input method. - *
- * This method is called - *
- * This method is called - *
- * This method is called by {@link java.awt.im.InputContext#removeNotify InputContext.removeNotify}. - *
- * The method is only called when the input method is inactive. - */ - public void removeNotify() { - } - - /** - * Ends any input composition that may currently be going on in this - * context. Depending on the platform and possibly user preferences, - * this may commit or delete uncommitted text. Any changes to the text - * are communicated to the active component using an input method event. - * - *
- * A text editing component may call this in a variety of situations, - * for example, when the user moves the insertion point within the text - * (but outside the composed text), or when the component's text is - * saved to a file or copied to the clipboard. - *
- * This method is called - *
- * This method is called by {@link java.awt.im.InputContext#dispose InputContext.dispose}. - *
- * The method is only called when the input method is inactive. - * No method of this interface is called on this instance after dispose. - */ - public void dispose() { - } - - /** - * Returns a control object from this input method, or null. A - * control object provides methods that control the behavior of the - * input method or obtain information from the input method. The type - * of the object is an input method specific class. Clients have to - * compare the result against known input method control object - * classes and cast to the appropriate class to invoke the methods - * provided. - *
- * This method is called by - * {@link java.awt.im.InputContext#getInputMethodControlObject InputContext.getInputMethodControlObject}. - * - * @return a control object from this input method, or null - */ - public Object getControlObject() { - - return null; - } -} diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/IndicInputMethodImpl.java b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/IndicInputMethodImpl.java deleted file mode 100644 index 4da58d9afed..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/IndicInputMethodImpl.java +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright IBM Corp. 2000 - All Rights Reserved - * - * The original version of this source code and documentation is - * copyrighted and owned by IBM. These materials are provided - * under terms of a License Agreement between IBM and Sun. - * This technology is protected by multiple US and International - * patents. This notice and attribution to IBM may not be removed. - * - */ - -package com.sun.inputmethods.internal.indicim; - -import java.awt.im.spi.InputMethodContext; - -import java.awt.event.KeyEvent; -import java.awt.event.InputMethodEvent; -import java.awt.font.TextAttribute; -import java.awt.font.TextHitInfo; - -import java.text.AttributedCharacterIterator; - -import java.util.Hashtable; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -class IndicInputMethodImpl { - - protected char[] KBD_MAP; - - private static final char SUBSTITUTION_BASE = '\uff00'; - - // Indexed by map value - SUBSTITUTION_BASE - protected char[][] SUBSTITUTION_TABLE; - - // Invalid character. - private static final char INVALID_CHAR = '\uffff'; - - // Unmapped versions of some interesting characters. - private static final char KEY_SIGN_VIRAMA = '\u0064'; // or just 'd'?? - private static final char KEY_SIGN_NUKTA = '\u005d'; // or just ']'?? - - // Two succeeding viramas are replaced by one virama and one ZWNJ. - // Viram followed by Nukta is replaced by one VIRAMA and one ZWJ - private static final char ZWJ = '\u200d'; - private static final char ZWNJ = '\u200c'; - - // Backspace - private static final char BACKSPACE = '\u0008'; - - // Sorted list of characters which can be followed by Nukta - protected char[] JOIN_WITH_NUKTA; - - // Nukta form of the above characters - protected char[] NUKTA_FORM; - - private int log2; - private int power; - private int extra; - - // cached TextHitInfo. Only one type of TextHitInfo is required. - private static final TextHitInfo ZERO_TRAILING_HIT_INFO = TextHitInfo.trailing(0); - - /** - * Returns the index of the given character in the JOIN_WITH_NUKTA array. - * If character is not found, -1 is returned. - */ - private int nuktaIndex(char ch) { - - if (JOIN_WITH_NUKTA == null) { - return -1; - } - - int probe = power; - int index = 0; - - if (JOIN_WITH_NUKTA[extra] <= ch) { - index = extra; - } - - while (probe > (1 << 0)) { - probe >>= 1; - - if (JOIN_WITH_NUKTA[index + probe] <= ch) { - index += probe; - } - } - - if (JOIN_WITH_NUKTA[index] != ch) { - index = -1; - } - - return index; - } - - /** - * Returns the equivalent character for hindi locale. - * @param originalChar The original character. - */ - private char getMappedChar( char originalChar ) - { - if (originalChar <= KBD_MAP.length) { - return KBD_MAP[originalChar]; - } - - return originalChar; - }//getMappedChar() - - // Array used to hold the text to be sent. - // If the last character was not committed it is stored in text[0]. - // The variable totalChars give an indication of whether the last - // character was committed or not. If at any time ( but not within a - // a call to dispatchEvent ) totalChars is not equal to 0 ( it can - // only be 1 otherwise ) the last character was not committed. - private char [] text = new char[4]; - - // this is always 0 before and after call to dispatchEvent. This character assumes - // significance only within a call to dispatchEvent. - private int committedChars = 0;// number of committed characters - - // the total valid characters in variable text currently. - private int totalChars = 0;//number of total characters ( committed + composed ) - - private boolean lastCharWasVirama = false; - - private InputMethodContext context; - - // - // Finds the high bit by binary searching - // through the bits in n. - // - private static byte highBit(int n) - { - if (n <= 0) { - return -32; - } - - byte bit = 0; - - if (n >= 1 << 16) { - n >>= 16; - bit += 16; - } - - if (n >= 1 << 8) { - n >>= 8; - bit += 8; - } - - if (n >= 1 << 4) { - n >>= 4; - bit += 4; - } - - if (n >= 1 << 2) { - n >>= 2; - bit += 2; - } - - if (n >= 1 << 1) { - n >>= 1; - bit += 1; - } - - return bit; - } - - IndicInputMethodImpl(char[] keyboardMap, char[] joinWithNukta, char[] nuktaForm, - char[][] substitutionTable) { - KBD_MAP = keyboardMap; - JOIN_WITH_NUKTA = joinWithNukta; - NUKTA_FORM = nuktaForm; - SUBSTITUTION_TABLE = substitutionTable; - - if (JOIN_WITH_NUKTA != null) { - int log2 = highBit(JOIN_WITH_NUKTA.length); - - power = 1 << log2; - extra = JOIN_WITH_NUKTA.length - power; - } else { - power = extra = 0; - } - - } - - void setInputMethodContext(InputMethodContext context) { - - this.context = context; - } - - void handleKeyTyped(KeyEvent kevent) { - - char keyChar = kevent.getKeyChar(); - char currentChar = getMappedChar(keyChar); - - // The Explicit and Soft Halanta case. - if ( lastCharWasVirama ) { - switch (keyChar) { - case KEY_SIGN_NUKTA: - currentChar = ZWJ; - break; - case KEY_SIGN_VIRAMA: - currentChar = ZWNJ; - break; - default: - }//endSwitch - }//endif - - if (currentChar == INVALID_CHAR) { - kevent.consume(); - return; - } - - if (currentChar == BACKSPACE) { - lastCharWasVirama = false; - - if (totalChars > 0) { - totalChars = committedChars = 0; - } else { - return; - } - } - else if (keyChar == KEY_SIGN_NUKTA) { - int nuktaIndex = nuktaIndex(text[0]); - - if (nuktaIndex != -1) { - text[0] = NUKTA_FORM[nuktaIndex]; - } else { - // the last character was committed, commit just Nukta. - // Note : the lastChar must have been committed if it is not one of - // the characters which combine with nukta. - // the state must be totalChars = committedChars = 0; - text[totalChars++] = currentChar; - } - - committedChars += 1; - } - else { - int nuktaIndex = nuktaIndex(currentChar); - - if (nuktaIndex != -1) { - // Commit everything but currentChar - text[totalChars++] = currentChar; - committedChars = totalChars-1; - } else { - if (currentChar >= SUBSTITUTION_BASE) { - char[] sub = SUBSTITUTION_TABLE[currentChar - SUBSTITUTION_BASE]; - - System.arraycopy(sub, 0, text, totalChars, sub.length); - totalChars += sub.length; - } else { - text[totalChars++] = currentChar; - } - - committedChars = totalChars; - } - } - - ACIText aText = new ACIText( text, 0, totalChars, committedChars ); - int composedCharLength = totalChars - committedChars; - TextHitInfo caret=null,visiblePosition=null; - switch( composedCharLength ) { - case 0: - break; - case 1: - visiblePosition = caret = ZERO_TRAILING_HIT_INFO; - break; - default: - assert false : "The code should not reach here. There is no case where there can be more than one character pending."; - } - - context.dispatchInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, - aText, - committedChars, - caret, - visiblePosition); - - if (totalChars == 0) { - text[0] = INVALID_CHAR; - } else { - text[0] = text[totalChars - 1];// make text[0] hold the last character - } - - lastCharWasVirama = keyChar == KEY_SIGN_VIRAMA && !lastCharWasVirama; - - totalChars -= committedChars; - committedChars = 0; - // state now text[0] = last character - // totalChars = ( last character committed )? 0 : 1; - // committedChars = 0; - - kevent.consume();// prevent client from getting this event. - }//dispatchEvent() - - void endComposition() { - if( totalChars != 0 ) {// if some character is not committed. - ACIText aText = new ACIText( text, 0, totalChars, totalChars ); - context.dispatchInputMethodEvent( InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, - aText, totalChars, null, null ); - totalChars = committedChars = 0; - text[0] = INVALID_CHAR; - lastCharWasVirama = false; - }//end if - }//endComposition() - - // custom AttributedCharacterIterator -- much lightweight since currently there is no - // attribute defined on the text being generated by the input method. - private class ACIText implements AttributedCharacterIterator { - private char [] text = null; - private int committed = 0; - private int index = 0; - - ACIText( char [] chArray, int offset, int length, int committed ) { - this.text = new char[length]; - this.committed = committed; - System.arraycopy( chArray, offset, text, 0, length ); - }//c'tor - - // CharacterIterator methods. - public char first() { - return _setIndex( 0 ); - } - - public char last() { - if( text.length == 0 ) { - return _setIndex( text.length ); - } - return _setIndex( text.length - 1 ); - } - - public char current() { - if( index == text.length ) - return DONE; - return text[index]; - } - - public char next() { - if( index == text.length ) { - return DONE; - } - return _setIndex( index + 1 ); - } - - public char previous() { - if( index == 0 ) - return DONE; - return _setIndex( index - 1 ); - } - - public char setIndex(int position) { - if( position < 0 || position > text.length ) { - throw new IllegalArgumentException(); - } - return _setIndex( position ); - } - - public int getBeginIndex() { - return 0; - } - - public int getEndIndex() { - return text.length; - } - - public int getIndex() { - return index; - } - - public Object clone() { - try { - ACIText clone = (ACIText) super.clone(); - return clone; - } catch (CloneNotSupportedException e) { - throw new InternalError(); - } - } - - - // AttributedCharacterIterator methods. - public int getRunStart() { - return index >= committed ? committed : 0; - } - - public int getRunStart(AttributedCharacterIterator.Attribute attribute) { - return (index >= committed && - attribute == TextAttribute.INPUT_METHOD_UNDERLINE) ? committed : 0; - } - - public int getRunStart(Set extends Attribute> attributes) { - return (index >= committed && - attributes.contains(TextAttribute.INPUT_METHOD_UNDERLINE)) ? committed : 0; - } - - public int getRunLimit() { - return index < committed ? committed : text.length; - } - - public int getRunLimit(AttributedCharacterIterator.Attribute attribute) { - return (index < committed && - attribute == TextAttribute.INPUT_METHOD_UNDERLINE) ? committed : text.length; - } - - public int getRunLimit(Set extends Attribute> attributes) { - return (index < committed && - attributes.contains(TextAttribute.INPUT_METHOD_UNDERLINE)) ? committed : text.length; - } - - public Map getAttributes() { - Hashtable result = new Hashtable(); - if (index >= committed && committed < text.length) { - result.put(TextAttribute.INPUT_METHOD_UNDERLINE, - TextAttribute.UNDERLINE_LOW_ONE_PIXEL); - } - return result; - } - - public Object getAttribute(AttributedCharacterIterator.Attribute attribute) { - if (index >= committed && - committed < text.length && - attribute == TextAttribute.INPUT_METHOD_UNDERLINE) { - - return TextAttribute.UNDERLINE_LOW_ONE_PIXEL; - } - return null; - } - - public Set getAllAttributeKeys() { - HashSet result = new HashSet(); - if (committed < text.length) { - result.add(TextAttribute.INPUT_METHOD_UNDERLINE); - } - return result; - } - - // private methods - - /** - * This is always called with valid i ( 0 < i <= text.length ) - */ - private char _setIndex( int i ) { - index = i; - if( i == text.length ) { - return DONE; - } - return text[i]; - }//_setIndex() - - }//end of inner class -} diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/java.awt.im.spi.InputMethodDescriptor b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/java.awt.im.spi.InputMethodDescriptor deleted file mode 100644 index f06b181876d..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/java.awt.im.spi.InputMethodDescriptor +++ /dev/null @@ -1 +0,0 @@ -com.sun.inputmethods.internal.indicim.DevanagariInputMethodDescriptor diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames.properties b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames.properties deleted file mode 100644 index f0feb6395c0..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames.properties +++ /dev/null @@ -1,6 +0,0 @@ -# -# Default Input method display names for Indic input methods -# - -DisplayName.Devanagari = Devanagari Input Method - diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_de.properties b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_de.properties deleted file mode 100644 index c460ffeb914..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_de.properties +++ /dev/null @@ -1,5 +0,0 @@ -# -# Default Input method display names for Indic input methods -# - -DisplayName.Devanagari = Devanagari Input Method diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_es.properties b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_es.properties deleted file mode 100644 index c460ffeb914..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_es.properties +++ /dev/null @@ -1,5 +0,0 @@ -# -# Default Input method display names for Indic input methods -# - -DisplayName.Devanagari = Devanagari Input Method diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_fr.properties b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_fr.properties deleted file mode 100644 index c460ffeb914..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_fr.properties +++ /dev/null @@ -1,5 +0,0 @@ -# -# Default Input method display names for Indic input methods -# - -DisplayName.Devanagari = Devanagari Input Method diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_it.properties b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_it.properties deleted file mode 100644 index c460ffeb914..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_it.properties +++ /dev/null @@ -1,5 +0,0 @@ -# -# Default Input method display names for Indic input methods -# - -DisplayName.Devanagari = Devanagari Input Method diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_ja.properties b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_ja.properties deleted file mode 100644 index e668c6e5c5a..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_ja.properties +++ /dev/null @@ -1,5 +0,0 @@ -# -# Default Input method display names for Indic input methods -# - -DisplayName.Devanagari = \u30c7\u30fc\u30f4\u30a1\u30ca\u30fc\u30ac\u30ea\u30fc\u30a4\u30f3\u30d7\u30c3\u30c8\u30e1\u30bd\u30c3\u30c9 diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_ko.properties b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_ko.properties deleted file mode 100644 index 514b240ca4b..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_ko.properties +++ /dev/null @@ -1,5 +0,0 @@ -# -# Default Input method display names for Indic input methods -# - -DisplayName.Devanagari = Devanagari \uc785\ub825 \uba54\uc18c\ub4dc diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_sv.properties b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_sv.properties deleted file mode 100644 index c460ffeb914..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_sv.properties +++ /dev/null @@ -1,5 +0,0 @@ -# -# Default Input method display names for Indic input methods -# - -DisplayName.Devanagari = Devanagari Input Method diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_zh_CN.properties b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_zh_CN.properties deleted file mode 100644 index 895fd8f8e6d..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_zh_CN.properties +++ /dev/null @@ -1,5 +0,0 @@ -# -# Default Input method display names for Indic input methods -# - -DisplayName.Devanagari = Devanagari \u8f93\u5165\u6cd5 diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_zh_TW.properties b/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_zh_TW.properties deleted file mode 100644 index 6b228d84ce2..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_zh_TW.properties +++ /dev/null @@ -1,5 +0,0 @@ -# -# Default Input method display names for Indic input methods -# - -DisplayName.Devanagari = Devanagari \u8f38\u5165\u6cd5 diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethod.java b/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethod.java deleted file mode 100644 index 40e6cc8ff0f..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethod.java +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * - * (C) Copyright IBM Corp. 2000 - All Rights Reserved - * - * The original version of this source code and documentation is - * copyrighted and owned by IBM. These materials are provided - * under terms of a License Agreement between IBM and Sun. - * This technology is protected by multiple US and International - * patents. This notice and attribution to IBM may not be removed. - * - */ - -package com.sun.inputmethods.internal.thaiim; - -import java.awt.im.spi.InputMethod; -import java.awt.im.spi.InputMethodContext; - -import java.awt.AWTEvent; -import java.awt.Rectangle; - -import java.awt.event.KeyEvent; -import java.awt.event.MouseEvent; - -import java.lang.Character.Subset; - -import java.util.Locale; - -class ThaiInputMethod implements InputMethod { - - private ThaiInputMethodImpl impl; - private Locale locale; - - ThaiInputMethod(Locale theLocale, ThaiInputMethodImpl theImplementation) { - locale = theLocale; - impl = theImplementation; - } - - /** - * Sets the input method context, which is used to dispatch input method - * events to the client component and to request information from - * the client component. - *
- * This method is called once immediately after instantiating this input
- * method.
- *
- * @param context the input method context for this input method
- * @exception NullPointerException if context
is null
- */
- public void setInputMethodContext(InputMethodContext context) {
-
- impl.setInputMethodContext(context);
- }
-
- /**
- * Attempts to set the input locale. If the input method supports the
- * desired locale, it changes its behavior to support input for the locale
- * and returns true.
- * Otherwise, it returns false and does not change its behavior.
- *
- * This method is called - *
locale
is null
- */
- public boolean setLocale(Locale locale) {
-
- if (locale.getLanguage().equals(this.locale.getLanguage())) {
- //System.out.println("returning true for locale " + locale);
- return true;
- }
- else {
- //System.out.println("returning false for locale " + locale);
- return false;
- }
- }
-
- /**
- * Returns the current input locale. Might return null in exceptional cases.
- * - * This method is called - *
- * This method is called - *
enable
.
- * - * An input method that is enabled for composition interprets incoming - * events for both composition and control purposes, while a - * disabled input method does not interpret events for composition. - * Note however that events are passed on to the input method regardless - * whether it is enabled or not, and that an input method that is disabled - * for composition may still interpret events for control purposes, - * including to enable or disable itself for composition. - *
- * This method is called - *
- * This method is called - *
true
if this input method is enabled for
- * composition; false
otherwise.
- * @throws UnsupportedOperationException if this input method does not
- * support checking whether it is enabled for composition
- * @see #setCompositionEnabled
- */
- public boolean isCompositionEnabled() {
-
- return true;
- }
-
- /**
- * Starts the reconversion operation. The input method obtains the
- * text to be reconverted from the current client component using the
- * {@link java.awt.im.InputMethodRequests#getSelectedText InputMethodRequests.getSelectedText}
- * method. It can use other InputMethodRequests
- * methods to request additional information required for the
- * reconversion operation. The composed and committed text
- * produced by the operation is sent to the client component as a
- * sequence of InputMethodEvent
s. If the given text
- * cannot be reconverted, the same text should be sent to the
- * client component as committed text.
- *
- * This method is called by
- * {@link java.awt.im.InputContext#reconvert() InputContext.reconvert}.
- *
- * @throws UnsupportedOperationException if the input method does not
- * support the reconversion operation.
- */
- public void reconvert() {
-
- throw new UnsupportedOperationException("This input method does not reconvert.");
- }
-
- /**
- * Dispatches the event to the input method. If input method support is
- * enabled for the focussed component, incoming events of certain types
- * are dispatched to the current input method for this component before
- * they are dispatched to the component's methods or event listeners.
- * The input method decides whether it needs to handle the event. If it
- * does, it also calls the event's consume
method; this
- * causes the event to not get dispatched to the component's event
- * processing methods or event listeners.
- *
- * Events are dispatched if they are instances of InputEvent or its - * subclasses. - * This includes instances of the AWT classes KeyEvent and MouseEvent. - *
- * This method is called by {@link java.awt.im.InputContext#dispatchEvent InputContext.dispatchEvent}.
- *
- * @param event the event being dispatched to the input method
- * @exception NullPointerException if event
is null
- */
- public void dispatchEvent(AWTEvent event) {
-
- if (event instanceof KeyEvent) {
-
- KeyEvent keyEvent = (KeyEvent) event;
- if (event.getID() == KeyEvent.KEY_TYPED) {
- //System.out.println("handled event " + event);
- impl.handleKeyTyped(keyEvent);
- }
- }
- else {
- //System.out.println("did not handle event " + event);
- }
- }
-
- /**
- * Notifies this input method of changes in the client window
- * location or state. This method is called while this input
- * method is the current input method of its input context and
- * notifications for it are enabled (see {@link
- * InputMethodContext#enableClientWindowNotification
- * InputMethodContext.enableClientWindowNotification}). Calls
- * to this method are temporarily suspended if the input context's
- * {@link java.awt.im.InputContext#removeNotify removeNotify}
- * method is called, and resume when the input method is activated
- * for a new client component. It is called in the following
- * situations:
- *
enableClientWindowNotification(inputMethod,
- * true)
if the current client component exists,enableClientWindowNotification(inputMethod,
- * true)
if during the call no current client component was
- * available,- * If an input method provides its own windows, it should make sure - * at this point that all necessary windows are open and visible. - *
- * This method is called - *
- * If an input method provides its own windows, only windows that relate - * to the current composition (such as a lookup choice window) should be - * closed at this point. - * It is possible that the input method will be immediately activated again - * for a different client component, and closing and reopening more - * persistent windows (such as a control panel) would create unnecessary - * screen flicker. - * Before an instance of a different input method class is activated, - * {@link #hideWindows} is called on the current input method. - *
- * This method is called - *
- * This method is called - *
- * This method is called by {@link java.awt.im.InputContext#removeNotify InputContext.removeNotify}. - *
- * The method is only called when the input method is inactive. - */ - public void removeNotify() { - } - - /** - * Ends any input composition that may currently be going on in this - * context. Depending on the platform and possibly user preferences, - * this may commit or delete uncommitted text. Any changes to the text - * are communicated to the active component using an input method event. - * - *
- * A text editing component may call this in a variety of situations, - * for example, when the user moves the insertion point within the text - * (but outside the composed text), or when the component's text is - * saved to a file or copied to the clipboard. - *
- * This method is called - *
- * This method is called by {@link java.awt.im.InputContext#dispose InputContext.dispose}. - *
- * The method is only called when the input method is inactive. - * No method of this interface is called on this instance after dispose. - */ - public void dispose() { - } - - /** - * Returns a control object from this input method, or null. A - * control object provides methods that control the behavior of the - * input method or obtain information from the input method. The type - * of the object is an input method specific class. Clients have to - * compare the result against known input method control object - * classes and cast to the appropriate class to invoke the methods - * provided. - *
- * This method is called by - * {@link java.awt.im.InputContext#getInputMethodControlObject InputContext.getInputMethodControlObject}. - * - * @return a control object from this input method, or null - */ - public Object getControlObject() { - - return null; - } -} diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethodDescriptor.java b/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethodDescriptor.java deleted file mode 100644 index 4d12a728df1..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethodDescriptor.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * - * (C) Copyright IBM Corp. 2000 - All Rights Reserved - * - * The original version of this source code and documentation is - * copyrighted and owned by IBM. These materials are provided - * under terms of a License Agreement between IBM and Sun. - * This technology is protected by multiple US and International - * patents. This notice and attribution to IBM may not be removed. - * - */ - -package com.sun.inputmethods.internal.thaiim; - -import java.awt.Image; -import java.awt.im.spi.InputMethod; -import java.awt.im.spi.InputMethodDescriptor; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -public class ThaiInputMethodDescriptor implements InputMethodDescriptor { - - static final Locale THAI = new Locale("th"); - - public ThaiInputMethodDescriptor() { - } - - /** - * @see java.awt.im.spi.InputMethodDescriptor#getAvailableLocales - */ - public Locale[] getAvailableLocales() { - return new Locale[] { THAI }; - } - - /** - * @see java.awt.im.spi.InputMethodDescriptor#hasDynamicLocaleList - */ - public boolean hasDynamicLocaleList() { - return false; - } - - /** - * @see java.awt.im.spi.InputMethodDescriptor#getInputMethodDisplayName - */ - public synchronized String getInputMethodDisplayName(Locale inputLocale, Locale displayLanguage) { - try { - ResourceBundle resources = ResourceBundle.getBundle( - "com.sun.inputmethods.internal.thaiim.resources.DisplayNames", displayLanguage); - return resources.getString("DisplayName.Thai"); - } catch (MissingResourceException mre) { - return "Thai Input Method"; - } - } - - /** - * @see java.awt.im.spi.InputMethodDescriptor#getInputMethodIcon - */ - public Image getInputMethodIcon(Locale inputLocale) { - return null; - } - - /** - * @see java.awt.im.spi.InputMethodDescriptor#createInputMethod - */ - public InputMethod createInputMethod() throws Exception { - ThaiInputMethodImpl impl = new ThaiInputMethodImpl(); - return new ThaiInputMethod(THAI, impl); - } - - public String toString() { - return getClass().getName(); - } -} diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethodImpl.java b/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethodImpl.java deleted file mode 100644 index 5cc66d97b52..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethodImpl.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * - * (C) Copyright IBM Corp. 2000 - All Rights Reserved - * - * The original version of this source code and documentation is - * copyrighted and owned by IBM. These materials are provided - * under terms of a License Agreement between IBM and Sun. - * This technology is protected by multiple US and International - * patents. This notice and attribution to IBM may not be removed. - * - */ - -package com.sun.inputmethods.internal.thaiim; - -import java.awt.im.InputMethodRequests; -import java.awt.im.spi.InputMethodContext; - -import java.awt.Toolkit; -import java.awt.event.KeyEvent; -import java.awt.event.InputMethodEvent; -import java.awt.font.TextAttribute; -import java.awt.font.TextHitInfo; - -import java.text.AttributedCharacterIterator; -import java.text.AttributedString; - -class ThaiInputMethodImpl { - - private static final char[] keyboardMap = { - /* 00 */ '\u0000', - /* 01 */ '\u0001', - /* 02 */ '\u0002', - /* 03 */ '\u0003', - /* 04 */ '\u0004', - /* 05 */ '\u0005', - /* 06 */ '\u0006', - /* 07 */ '\u0007', - /* 08 */ '\u0008', - /* 09 */ '\u0009', - /* 0A */ '\012', - /* 0B */ '\u000B', - /* 0C */ '\u000C', - /* 0D */ '\015', - /* 0E */ '\u000E', - /* 0F */ '\u000F', - /* 10 */ '\u0010', - /* 11 */ '\u0011', - /* 12 */ '\u0012', - /* 13 */ '\u0013', - /* 14 */ '\u0014', - /* 15 */ '\u0015', - /* 16 */ '\u0016', - /* 17 */ '\u0017', - /* 18 */ '\u0018', - /* 19 */ '\u0019', - /* 1A */ '\u001A', - /* 1B */ '\u001B', - /* 1C */ '\u001C', - /* 1D */ '\u001D', - /* 1E */ '\u001E', - /* 1F */ '\u001F', - /* 20 */ '\u0020', - /* 21 */ '\u0e45', // '!' - /* 22 */ '\u002e', // '"' - /* 23 */ '\u0e52', // '#' - /* 24 */ '\u0e53', // '$' - /* 25 */ '\u0e54', // '%' - /* 26 */ '\u0e4e', // '&' - /* 27 */ '\u0e07', // ''' - /* 28 */ '\u0e56', // '(' - /* 29 */ '\u0e57', // ')' - /* 2A */ '\u0e55', // '*' - /* 2B */ '\u0e59', // '+' - /* 2C */ '\u0e21', // ',' - /* 2D */ '\u0e02', // '-' - /* 2E */ '\u0e43', // '.' - /* 2F */ '\u0e1d', // '/' - /* 30 */ '\u0e08', // '0' - /* 31 */ '\u0e3f', // '1' - /* 32 */ '\u002f', // '2' - /* 33 */ '\u002d', // '3' - /* 34 */ '\u0e20', // '4' - /* 35 */ '\u0e16', // '5' - /* 36 */ '\u0e38', // '6' - /* 37 */ '\u0e36', // '7' - /* 38 */ '\u0e04', // '8' - /* 39 */ '\u0e15', // '9' - /* 3A */ '\u0e0b', // ':' - /* 3B */ '\u0e27', // ';' - /* 3C */ '\u0e12', // '<' - /* 3D */ '\u0e0a', // '=' - /* 3E */ '\u0e2c', // '>' - /* 3F */ '\u0e26', // '?' - /* 40 */ '\u0e51', // '@' - /* 41 */ '\u0e24', // 'A' - /* 42 */ '\u0e3a', // 'B' - /* 43 */ '\u0e09', // 'C' - /* 44 */ '\u0e0f', // 'D' - /* 45 */ '\u0e0e', // 'E' - /* 46 */ '\u0e42', // 'F' - /* 47 */ '\u0e0c', // 'G' - /* 48 */ '\u0e47', // 'H' - /* 49 */ '\u0e13', // 'I' - /* 4A */ '\u0e4b', // 'J' - /* 4B */ '\u0e29', // 'K' - /* 4C */ '\u0e28', // 'L' - /* 4D */ '\u003f', // 'M' - /* 4E */ '\u0e4c', // 'N' - /* 4F */ '\u0e2f', // 'O' - /* 50 */ '\u0e0d', // 'P' - /* 51 */ '\u0e50', // 'Q' - /* 52 */ '\u0e11', // 'R' - /* 53 */ '\u0e06', // 'S' - /* 54 */ '\u0e18', // 'T' - /* 55 */ '\u0e4a', // 'U' - /* 56 */ '\u0e2e', // 'V' - /* 57 */ '\u0022', // 'W' - /* 58 */ '\u0029', // 'X' - /* 59 */ '\u0e4d', // 'Y' - /* 5A */ '\u0028', // 'Z' - /* 5B */ '\u0e1a', // '[' - /* 5C */ '\u0e05', // '\' - /* 5D */ '\u0e25', // ']' - /* 5E */ '\u0e39', // '^' - /* 5F */ '\u0e58', // '_' - /* 60 */ '\u0e4f', // '`' - /* 61 */ '\u0e1f', // 'a' - /* 62 */ '\u0e34', // 'b' - /* 63 */ '\u0e41', // 'c' - /* 64 */ '\u0e01', // 'd' - /* 65 */ '\u0e33', // 'e' - /* 66 */ '\u0e14', // 'f' - /* 67 */ '\u0e40', // 'g' - /* 68 */ '\u0e49', // 'h' - /* 69 */ '\u0e23', // 'i' - /* 6A */ '\u0e48', // 'j' - /* 6B */ '\u0e32', // 'k' - /* 6C */ '\u0e2a', // 'l' - /* 6D */ '\u0e17', // 'm' - /* 6E */ '\u0e37', // 'n' - /* 6F */ '\u0e19', // 'o' - /* 70 */ '\u0e22', // 'p' - /* 71 */ '\u0e46', // 'q' - /* 72 */ '\u0e1e', // 'r' - /* 73 */ '\u0e2b', // 's' - /* 74 */ '\u0e30', // 't' - /* 75 */ '\u0e35', // 'u' - /* 76 */ '\u0e2d', // 'v' - /* 77 */ '\u0e44', // 'w' - /* 78 */ '\u0e1b', // 'x' - /* 79 */ '\u0e31', // 'y' - /* 7A */ '\u0e1c', // 'z' - /* 7B */ '\u0e10', // '{' - /* 7C */ '\u0e03', // '|' - /* 7D */ '\u002c', // '}' - /* 7E */ '\u0e5b', // '~' - /* 7F */ '\u007F' // - }; - - // cached TextHitInfo. Only one type of TextHitInfo is required. - private static final TextHitInfo ZERO_TRAILING_HIT_INFO = TextHitInfo.trailing(0); - - private ThaiRules rules; - - /** - * Returns the equivalent character for thai locale. - * @param originalChar The original character. - */ - private char getMappedChar( char originalChar ) - { - if (originalChar <= keyboardMap.length) { - return keyboardMap[originalChar]; - } - - return originalChar; - }//getMappedChar() - - private InputMethodContext context; - - void setInputMethodContext(InputMethodContext context) { - this.context = context; - rules = new ThaiRules((InputMethodRequests)context); - } - - void handleKeyTyped(KeyEvent kevent) { - char keyChar = kevent.getKeyChar(); - char currentChar = getMappedChar(keyChar); - if (!Character.UnicodeBlock.THAI.equals(Character.UnicodeBlock.of(currentChar))) { - // don't care - return; - } else if (rules.isInputValid(currentChar)) { - Character tmp = new Character(currentChar); - String tmp2 = tmp.toString(); - context.dispatchInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, - (new AttributedString(tmp2)).getIterator(), - 1, - ZERO_TRAILING_HIT_INFO, - ZERO_TRAILING_HIT_INFO); - } else { - // input sequence is not allowed - Toolkit.getDefaultToolkit().beep(); - } - - kevent.consume();// prevent client from getting this event. - return; - }//dispatchEvent() - - void endComposition() { - }//endComposition() -} diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiRules.java b/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiRules.java deleted file mode 100644 index 02e4b6ed479..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiRules.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.inputmethods.internal.thaiim; - -import java.awt.im.InputMethodRequests; - -public class ThaiRules { - - public static final char BASE = 0x0e00; - - public static final byte NON = 0; - public static final byte CONS = 1; - public static final byte LV = 2; - public static final byte FV1 = 3; - public static final byte FV2 = 4; - public static final byte FV3 = 5; - public static final byte FV4 = 6; - /* Note that FV4 is added. It is not in WTT. - * We need it for SARA AM since it has a - * weired characteristic to share the same - * cell with whatever consonant preceeds it. - */ - public static final byte BV1 = 7; - public static final byte BV2 = 8; - public static final byte BD = 9; - public static final byte TONE = 10; - public static final byte AD1 = 11; - public static final byte AD2 = 12; - public static final byte AD3 = 13; - public static final byte AV1 = 14; - public static final byte AV2 = 15; - public static final byte AV3 = 16; - - /** - * Constants for validity checking and auto correction - */ - public static final byte STRICT = 0; - public static final byte LOOSE = 1; - public static final byte NOREPLACE = 2; - - public static final byte[] CHARTYPE = { - /* 0e00 UNUSED */ NON, - /* THAI CHARACTER KO KAI */ CONS, - /* THAI CHARACTER KHO KHAI */ CONS, - /* THAI CHARACTER KHO KHUAT */ CONS, - /* THAI CHARACTER KHO KHWAI */ CONS, - /* THAI CHARACTER KHO KHON */ CONS, - /* THAI CHARACTER KHO RAKHANG */ CONS, - /* THAI CHARACTER NGO NGU */ CONS, - /* THAI CHARACTER CHO CHAN */ CONS, - /* THAI CHARACTER CHO CHING */ CONS, - /* THAI CHARACTER CHO CHANG */ CONS, - /* THAI CHARACTER SO SO */ CONS, - /* THAI CHARACTER CHO CHOE */ CONS, - /* THAI CHARACTER YO YING */ CONS, - /* THAI CHARACTER DO CHADA */ CONS, - /* THAI CHARACTER TO PATAK */ CONS, - /* THAI CHARACTER THO THAN */ CONS, - /* THAI CHARACTER THO NANGMONTHO */ CONS, - /* THAI CHARACTER THO PHUTHAO */ CONS, - /* THAI CHARACTER NO NEN */ CONS, - /* THAI CHARACTER DO DEK */ CONS, - /* THAI CHARACTER TO TAO */ CONS, - /* THAI CHARACTER THO THUNG */ CONS, - /* THAI CHARACTER THO THAHAN */ CONS, - /* THAI CHARACTER THO THONG */ CONS, - /* THAI CHARACTER NO NU */ CONS, - /* THAI CHARACTER BO BAIMAI */ CONS, - /* THAI CHARACTER PO PLA */ CONS, - /* THAI CHARACTER PHO PHUNG */ CONS, - /* THAI CHARACTER FO FA */ CONS, - /* THAI CHARACTER PHO PHAN */ CONS, - /* THAI CHARACTER FO FAN */ CONS, - /* THAI CHARACTER PHO SAMPHAO */ CONS, - /* THAI CHARACTER MO MA */ CONS, - /* THAI CHARACTER YO YAK */ CONS, - /* THAI CHARACTER RO RUA */ CONS, - /* THAI CHARACTER RU */ FV3, - /* THAI CHARACTER LO LING */ CONS, - /* THAI CHARACTER LU */ FV3, - /* THAI CHARACTER WO WAEN */ CONS, - /* THAI CHARACTER SO SALA */ CONS, - /* THAI CHARACTER SO RUSI */ CONS, - /* THAI CHARACTER SO SUA */ CONS, - /* THAI CHARACTER HO HIP */ CONS, - /* THAI CHARACTER LO CHULA */ CONS, - /* THAI CHARACTER O ANG */ CONS, - /* THAI CHARACTER HO NOKHUK */ CONS, - /* THAI CHARACTER PAIYANNOI */ NON, - /* THAI CHARACTER SARA A */ FV1, - /* THAI CHARACTER MAI HAN-AKAT */ AV2, - /* THAI CHARACTER SARA AA */ FV1, - /* THAI CHARACTER SARA AM */ FV4, - /* THAI CHARACTER SARA I */ AV1, - /* THAI CHARACTER SARA II */ AV3, - /* THAI CHARACTER SARA UE */ AV2, - /* THAI CHARACTER SARA UEE */ AV3, - /* THAI CHARACTER SARA U */ BV1, - /* THAI CHARACTER SARA UU */ BV2, - /* THAI CHARACTER PHINTHU */ BD, - /* 0e3b UNUSED */ NON, - /* 0e3c UNUSED */ NON, - /* 0e3d UNUSED */ NON, - /* 0e3e UNUSED */ NON, - /* THAI CURRENCY SYMBOL BAHT */ NON, - /* THAI CHARACTER SARA E */ LV, - /* THAI CHARACTER SARA AE */ LV, - /* THAI CHARACTER SARA O */ LV, - /* THAI CHARACTER SARA AI MAIMUAN */ LV, - /* THAI CHARACTER SARA AI MAIMALAI */ LV, - /* THAI CHARACTER LAKKHANGYAO */ FV2, - /* THAI CHARACTER MAIYAMOK */ NON, - /* THAI CHARACTER MAITAIKHU */ AD2, - /* THAI CHARACTER MAI EK */ TONE, - /* THAI CHARACTER MAI THO */ TONE, - /* THAI CHARACTER MAI TRI */ TONE, - /* THAI CHARACTER MAI CHATTAWA */ TONE, - /* THAI CHARACTER THANTHAKHAT */ AD1, - /* THAI CHARACTER NIKHAHIT */ AD3, - /* THAI CHARACTER YAMAKKAN */ AD3, - /* THAI CHARACTER FONGMAN */ NON, - /* THAI DIGIT ZERO */ NON, - /* THAI DIGIT ONE */ NON, - /* THAI DIGIT TWO */ NON, - /* THAI DIGIT THREE */ NON, - /* THAI DIGIT FOUR */ NON, - /* THAI DIGIT FIVE */ NON, - /* THAI DIGIT SIX */ NON, - /* THAI DIGIT SEVEN */ NON, - /* THAI DIGIT EIGHT */ NON, - /* THAI DIGIT NINE */ NON, - /* THAI CHARACTER ANGKHANKHU */ NON, - /* THAI CHARACTER KHOMUT */ NON - }; - - private InputMethodRequests requests; - - ThaiRules(InputMethodRequests requests) { - this.requests = requests; - } - - public static byte getCharType(char c) { - byte cType; - int ci = ((int) c) - (int) BASE; - if (ci < 0 || ci >= CHARTYPE.length) - cType = NON; - else - cType = CHARTYPE[ci]; - return cType; - } - - private static boolean isValid(char c1, char c2, int[] validityArray) { - return ((validityArray[getCharType(c1)] - & (1 << getCharType(c2))) != 0); - } - - /** - * VALIDITY is a bit matrix defining whether one - * character is allowed to be typed in after the - * previous one (array index). Determining the - * validity is done by bit-anding the 2nd char - * type's mask (obtained by 1 << chartype) with - * the array element indexed by the first char - * type. If the result is non-zero, the 2nd - * character is allowed to follow the first. - */ - - /* Please note that the bits in the comment below - * are displayed least significant bit first. - * The actual value reflexs this representation - * when the bits are swapped. - */ - - private static final int[] INPUTVALIDITY = { - /* NON 1110 010 0 0000 0000 0 */ 0x00027, - /* CONS 1111 111 1 1111 1111 1 */ 0x1ffff, - /* LV 0100 000 0 0000 0000 0 */ 0x00002, - /* FV1 1110 010 0 0000 0000 0 */ 0x00027, - /* FV2 1110 010 0 0000 0000 0 */ 0x00027, - /* FV3 1110 110 0 0000 0000 0 */ 0x00037, - /* FV4 1110 010 0 0000 0000 0 */ 0x00027, - /* BV1 1110 010 0 0011 0000 0 */ 0x00c27, - /* BV2 1110 010 0 0010 0000 0 */ 0x00427, - /* BD 1110 010 0 0000 0000 0 */ 0x00027, - /* TONE 1111 011 0 0000 0000 0 */ 0x0006f, - /* AD1 1110 010 0 0000 0000 0 */ 0x00027, - /* AD2 1110 010 0 0000 0000 0 */ 0x00027, - /* AD3 1110 010 0 0000 0000 0 */ 0x00027, - /* AV1 1110 010 0 0011 0000 0 */ 0x00c27, - /* AV2 1110 010 0 0010 0000 0 */ 0x00427, - /* AV3 1110 010 0 0010 0100 0 */ 0x02427 - }; - - private static final int[] COMPOSABLE = { - /* NON 0000 000 0 0000 0000 0 */ 0x00000, - /* CONS 0000 001 1 1111 1111 1 */ 0x1ffc0, - /* LV 0000 000 0 0000 0000 0 */ 0x00000, - /* FV1 0000 000 0 0000 0000 0 */ 0x00000, - /* FV2 0000 000 0 0000 0000 0 */ 0x00000, - /* FV3 0000 000 0 0000 0000 0 */ 0x00000, - /* FV4 0000 000 0 0000 0000 0 */ 0x00000, - /* BV1 0000 000 0 0011 0000 0 */ 0x00c00, - /* BV2 0000 000 0 0010 0000 0 */ 0x00400, - /* BD 0000 000 0 0000 0000 0 */ 0x00000, - /* TONE 0000 001 0 0000 0000 0 */ 0x00040, - /* AD1 0000 000 0 0000 0000 0 */ 0x00000, - /* AD2 0000 000 0 0000 0000 0 */ 0x00000, - /* AD3 0000 000 0 0000 0000 0 */ 0x00000, - /* AV1 0000 000 0 0011 0000 0 */ 0x00c00, - /* AV2 0000 000 0 0010 0000 0 */ 0x00400, - /* AV3 0000 000 0 0010 0100 0 */ 0x02400 - }; - - private static final int[] REPLACABLE = { - /* NON 0000 000 0 0000 0000 0 */ 0x00000, - /* CONS 0000 000 0 0000 0000 0 */ 0x00000, - /* LV 0000 000 0 0000 0000 0 */ 0x00000, - /* FV1 0000 000 0 0000 0000 0 */ 0x00000, - /* FV2 0000 000 0 0000 0000 0 */ 0x00000, - /* FV3 0000 000 0 0000 0000 0 */ 0x00000, - /* FV4 0000 001 1 1001 1111 1 */ 0x1f9c0, - /* BV1 0000 001 1 1100 1111 1 */ 0x1f3c0, - /* BV2 0000 001 1 1101 1111 1 */ 0x1fbc0, - /* BD 0000 001 1 1111 1111 1 */ 0x1ffc0, - /* TONE 0000 000 0 0111 1100 0 */ 0x03e00, - /* AD1 0000 001 0 1111 1101 1 */ 0x1bf40, - /* AD2 0000 001 1 1111 1111 1 */ 0x1ffc0, - /* AD3 0000 001 1 1111 1111 0 */ 0x0ffc0, - /* AV1 0000 001 1 1100 1111 1 */ 0x1f3c0, - /* AV2 0000 001 1 1101 1111 1 */ 0x1fbc0, - /* AV3 0000 001 1 1101 1011 1 */ 0x1dbc0 - }; - - private static final int[] SWAPPABLE = { - /* NON 0000 000 0 0000 0000 0 */ 0x00000, - /* CONS 0000 000 0 0000 0000 0 */ 0x00000, - /* LV 0000 000 0 0000 0000 0 */ 0x00000, - /* FV1 0000 000 0 0000 0000 0 */ 0x00000, - /* FV2 0000 000 0 0000 0000 0 */ 0x00000, - /* FV3 0000 000 0 0000 0000 0 */ 0x00000, - /* FV4 0000 000 0 0010 0000 0 */ 0x00400, - /* BV1 0000 000 0 0000 0000 0 */ 0x00000, - /* BV2 0000 000 0 0000 0000 0 */ 0x00000, - /* BD 0000 000 0 0000 0000 0 */ 0x00000, - /* TONE 0000 000 1 1000 0011 1 */ 0x1c180, - /* AD1 0000 000 1 0000 0010 0 */ 0x04080, - /* AD2 0000 000 0 0000 0000 0 */ 0x00000, - /* AD3 0000 000 0 0000 0000 1 */ 0x10000, - /* AV1 0000 000 0 0000 0000 0 */ 0x00000, - /* AV2 0000 000 0 0000 0000 0 */ 0x00000, - /* AV3 0000 000 0 0000 0000 0 */ 0x00000 - }; - - public static boolean isInputValid(char c1, char c2) { - return isValid(c1, c2, INPUTVALIDITY); - } - - public static boolean isComposable(char c1, char c2) { - return isValid(c1, c2, COMPOSABLE); - } - - public static boolean isSwappable(char c1, char c2) { - return isValid(c1, c2, SWAPPABLE); - } - - public static boolean isReplacable(char c1, char c2) { - return isValid(c1, c2, REPLACABLE); - } - - public static boolean isForward(char c) { - return (getCharType(c) < FV4); - } - - public static boolean isDead(char c) { - return (getCharType(c) > FV3); - } - - public boolean isInputValid(char current) { - int offset = requests.getInsertPositionOffset(); - if (offset == 0) { - byte charType = getCharType(current); - return ((charType < FV1) || (charType == FV3)); - } - else { - char prev = requests.getCommittedText(offset-1, offset, null).first(); - - if(isForward(current)) { - if (isInputValid(prev, current)) { - if (getCharType(prev) == TONE && - getCharType(current) == FV1) { - if (offset == 1) { - return true; - } else { - char pprev = - requests.getCommittedText(offset-2, offset-1, null).first(); - return isInputValid(pprev, current); - } - } else { - return true; - } - } else if (prev == '\u0e32' && // SARA AA - current == '\u0e30') { // SARA A - return true; - } else if (prev == '\u0e4d' && // NIKAHIT - current == '\u0e32') { // SARA AA - // Special compose to SARA AM - return true; - } else { - return false; - } - } else { - if(isInputValid(prev, current)) { - if (getCharType(prev) == TONE && - getCharType(current) == FV4) { - return (offset != 1); - } else { - return true; - } - } else { - return false; - } - } - } - } -} diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/java.awt.im.spi.InputMethodDescriptor b/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/java.awt.im.spi.InputMethodDescriptor deleted file mode 100644 index 9f60bbe9909..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/java.awt.im.spi.InputMethodDescriptor +++ /dev/null @@ -1 +0,0 @@ -com.sun.inputmethods.internal.thaiim.ThaiInputMethodDescriptor diff --git a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/resources/DisplayNames.properties b/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/resources/DisplayNames.properties deleted file mode 100644 index e4528a49a53..00000000000 --- a/jdk/src/share/classes/com/sun/inputmethods/internal/thaiim/resources/DisplayNames.properties +++ /dev/null @@ -1,6 +0,0 @@ -# -# Default Input method display names for Thai input methods -# - -DisplayName.Thai = Thai Input Method - diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java index 17774285d82..fa9a5a2fb15 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java @@ -1440,10 +1440,6 @@ class GTKPainter extends SynthPainter { } } - public Insets getBorderInsets(Component c) { - return getBorderInsets(c, null); - } - public Insets getBorderInsets(Component c, Insets i) { SynthContext context = getContext(c); diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java index 2999fe66f89..97df238d17b 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -271,7 +271,9 @@ public class MotifFileChooserUI extends BasicFileChooserUI { } public void uninstallUI(JComponent c) { - getFileChooser().removeAll(); + c.removePropertyChangeListener(filterComboBoxModel); + approveButton.removeActionListener(getApproveSelectionAction()); + filenameTextField.removeActionListener(getApproveSelectionAction()); super.uninstallUI(c); } @@ -515,6 +517,7 @@ public class MotifFileChooserUI extends BasicFileChooserUI { public void uninstallComponents(JFileChooser fc) { fc.removeAll(); + bottomPanel = null; if (filterComboBoxModel != null) { fc.removePropertyChangeListener(filterComboBoxModel); } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsComboBoxUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsComboBoxUI.java index 097e6a689cb..ae33ddd3665 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsComboBoxUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsComboBoxUI.java @@ -424,7 +424,7 @@ public class WindowsComboBoxUI extends BasicComboBoxUI { State rv; rv = super.getState(); if (rv != State.DISABLED - && ! comboBox.isEditable() + && comboBox != null && ! comboBox.isEditable() && XPStyle.getXP().isSkinDefined(comboBox, Part.CP_DROPDOWNBUTTONRIGHT)) { /* diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java index 164f865edce..42914f6a193 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java @@ -35,6 +35,7 @@ import javax.swing.table.*; import static com.sun.java.swing.plaf.windows.TMSchema.*; import static com.sun.java.swing.plaf.windows.XPStyle.*; import sun.swing.table.*; +import sun.swing.SwingUtilities2; public class WindowsTableHeaderUI extends BasicTableHeaderUI { @@ -163,18 +164,13 @@ public class WindowsTableHeaderUI extends BasicTableHeaderUI { return this; } - private int viewIndexForColumn(TableColumn aColumn) { - if (aColumn != null) { - return header.getTable().convertColumnIndexToView( - aColumn.getModelIndex()); - } - return -1; - } - public void paint(Graphics g) { Dimension size = getSize(); State state = State.NORMAL; - if (column == viewIndexForColumn(header.getDraggedColumn())) { + TableColumn draggedColumn = header.getDraggedColumn(); + if (draggedColumn != null && + column == SwingUtilities2.convertColumnIndexToView( + header.getColumnModel(), draggedColumn.getModelIndex())) { state = State.PRESSED; } else if (isSelected || hasFocus || hasRollover) { state = State.HOT; diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java index a9deb0cd877..19ce04cf559 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,10 +47,13 @@ interface Constants { public final static short JAVA5_MAX_CLASS_MAJOR_VERSION = 49; public final static short JAVA5_MAX_CLASS_MINOR_VERSION = 0; - // NOTE: ASSUMED for now + public final static short JAVA6_MAX_CLASS_MAJOR_VERSION = 50; public final static short JAVA6_MAX_CLASS_MINOR_VERSION = 0; + public final static short JAVA7_MAX_CLASS_MAJOR_VERSION = 51; + public final static short JAVA7_MAX_CLASS_MINOR_VERSION = 0; + public final static int JAVA_PACKAGE_MAGIC = 0xCAFED00D; public final static int JAVA5_PACKAGE_MAJOR_VERSION = 150; public final static int JAVA5_PACKAGE_MINOR_VERSION = 7; diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java index ad7fdbaa575..1ea04690ed8 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,8 +57,8 @@ class Package implements Constants { // These fields can be adjusted by driver properties. short min_class_majver = JAVA_MIN_CLASS_MAJOR_VERSION; short min_class_minver = JAVA_MIN_CLASS_MINOR_VERSION; - short max_class_majver = JAVA6_MAX_CLASS_MAJOR_VERSION; - short max_class_minver = JAVA6_MAX_CLASS_MINOR_VERSION; + short max_class_majver = JAVA7_MAX_CLASS_MAJOR_VERSION; + short max_class_minver = JAVA7_MAX_CLASS_MINOR_VERSION; short observed_max_class_majver = min_class_majver; short observed_max_class_minver = min_class_minver; @@ -122,13 +122,16 @@ class Package implements Constants { void choosePackageVersion() { assert(package_majver <= 0); // do not call this twice int classver = getHighestClassVersion(); - if (classver != 0 && - (classver >>> 16) < JAVA6_MAX_CLASS_MAJOR_VERSION) { - // There are only old classfiles in this segment. + if (classver == 0 || (classver >>> 16) < JAVA6_MAX_CLASS_MAJOR_VERSION) { + // There are only old classfiles in this segment or resources package_majver = JAVA5_PACKAGE_MAJOR_VERSION; package_minver = JAVA5_PACKAGE_MINOR_VERSION; + } else if ((classver >>> 16) == JAVA6_MAX_CLASS_MAJOR_VERSION) { + package_majver = JAVA6_PACKAGE_MAJOR_VERSION; + package_minver = JAVA6_PACKAGE_MINOR_VERSION; } else { - // Normal case. Use the newest archive format. + // Normal case. Use the newest archive format, when available + // TODO: replace the following with JAVA7* when the need arises package_majver = JAVA6_PACKAGE_MAJOR_VERSION; package_minver = JAVA6_PACKAGE_MINOR_VERSION; } diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java index c5eb8d75da1..6b92236f82e 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003,2010 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,8 +90,8 @@ class PropMap extends TreeMap { props.put(Utils.PACK_DEFAULT_TIMEZONE, String.valueOf(Boolean.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))); - // Limit segment size to less than a megabyte. - props.put(Pack200.Packer.SEGMENT_LIMIT, ""+(1*1000*1000)); + // The segment size is unlimited + props.put(Pack200.Packer.SEGMENT_LIMIT, ""); // Preserve file ordering by default. props.put(Pack200.Packer.KEEP_FILE_ORDER, Pack200.Packer.TRUE); diff --git a/jdk/src/share/classes/com/sun/jndi/dns/DnsClient.java b/jdk/src/share/classes/com/sun/jndi/dns/DnsClient.java index 06d14f2ede0..68dcee457e4 100644 --- a/jdk/src/share/classes/com/sun/jndi/dns/DnsClient.java +++ b/jdk/src/share/classes/com/sun/jndi/dns/DnsClient.java @@ -525,11 +525,11 @@ public class DnsClient { } byte[] pkt; if ((pkt = (byte[]) resps.get(xid)) != null) { + checkResponseCode(new Header(pkt, pkt.length)); synchronized (queuesLock) { resps.remove(xid); reqs.remove(xid); } - checkResponseCode(new Header(pkt, pkt.length)); if (debug) { dprint("FOUND (" + Thread.currentThread() + @@ -562,12 +562,12 @@ public class DnsClient { dprint("XID MATCH:" + xid); } + checkResponseCode(hdr); // remove the response for the xid if received by some other thread. synchronized (queuesLock) { resps.remove(xid); reqs.remove(xid); } - checkResponseCode(hdr); return true; } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java index 4ed945ec3b5..9e9c7de8b0f 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java @@ -41,7 +41,7 @@ import org.w3c.dom.Text; * @author Raul Benito(Of the xerces copy, and little adaptations). * @author Anli Shundi * @author Christian Geuer-Pollmann - * @see RFC 2045 + * @see RFC 2045 * @see com.sun.org.apache.xml.internal.security.transforms.implementations.TransformBase64Decode */ public class Base64 { diff --git a/jdk/src/share/classes/com/sun/security/auth/LdapPrincipal.java b/jdk/src/share/classes/com/sun/security/auth/LdapPrincipal.java index 25cef88e619..78a9e7ce522 100644 --- a/jdk/src/share/classes/com/sun/security/auth/LdapPrincipal.java +++ b/jdk/src/share/classes/com/sun/security/auth/LdapPrincipal.java @@ -31,7 +31,7 @@ import javax.naming.ldap.LdapName; /** * A principal identified by a distinguished name as specified by - * RFC 2253. + * RFC 2253. * *
* After successful authentication, a user {@link java.security.Principal}
@@ -122,7 +122,7 @@ public final class LdapPrincipal implements Principal, java.io.Serializable {
/**
* Creates a string representation of this principal's name in the format
- * defined by RFC 2253.
+ * defined by RFC 2253.
* If the name has zero components an empty string is returned.
*
* @return The principal's string name.
diff --git a/jdk/src/share/classes/com/sun/security/sasl/CramMD5Client.java b/jdk/src/share/classes/com/sun/security/sasl/CramMD5Client.java
index 3c032ded31e..2ed055b7ad3 100644
--- a/jdk/src/share/classes/com/sun/security/sasl/CramMD5Client.java
+++ b/jdk/src/share/classes/com/sun/security/sasl/CramMD5Client.java
@@ -33,7 +33,7 @@ import java.util.logging.Level;
/**
* Implements the CRAM-MD5 SASL client-side mechanism.
- * (RFC 2195).
+ * (RFC 2195).
* CRAM-MD5 has no initial response. It receives bytes from
* the server as a challenge, which it hashes by using MD5 and the password.
* It concatenates the authentication ID with this result and returns it
diff --git a/jdk/src/share/classes/com/sun/security/sasl/CramMD5Server.java b/jdk/src/share/classes/com/sun/security/sasl/CramMD5Server.java
index 2e8c69b94c1..c2e360c4986 100644
--- a/jdk/src/share/classes/com/sun/security/sasl/CramMD5Server.java
+++ b/jdk/src/share/classes/com/sun/security/sasl/CramMD5Server.java
@@ -38,7 +38,7 @@ import java.util.logging.Level;
/**
* Implements the CRAM-MD5 SASL server-side mechanism.
- * (RFC 2195).
+ * (RFC 2195).
* CRAM-MD5 has no initial response.
*
* client <---- M={random, timestamp, server-fqdn} ------- server
diff --git a/jdk/src/share/classes/com/sun/security/sasl/ExternalClient.java b/jdk/src/share/classes/com/sun/security/sasl/ExternalClient.java
index 0048ebc62cb..8c492e886db 100644
--- a/jdk/src/share/classes/com/sun/security/sasl/ExternalClient.java
+++ b/jdk/src/share/classes/com/sun/security/sasl/ExternalClient.java
@@ -29,7 +29,7 @@ import javax.security.sasl.*;
/**
* Implements the EXTERNAL SASL client mechanism.
- * (RFC 2222).
+ * (RFC 2222).
* The EXTERNAL mechanism returns the optional authorization ID as
* the initial response. It processes no challenges.
*
diff --git a/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java b/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java
index 636541f6584..f0e04aa16cb 100644
--- a/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java
+++ b/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java
@@ -39,10 +39,10 @@ import org.ietf.jgss.*;
/**
* Implements the GSSAPI SASL client mechanism for Kerberos V5.
- * (RFC 2222,
+ * (RFC 2222,
* draft-ietf-cat-sasl-gssapi-04.txt).
* It uses the Java Bindings for GSSAPI
- * (RFC 2853)
+ * (RFC 2853)
* for getting GSSAPI/Kerberos V5 support.
*
* The client/server interactions are:
diff --git a/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java b/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java
index d5b0a40668d..474f4303195 100644
--- a/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java
+++ b/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java
@@ -39,7 +39,7 @@ import org.ietf.jgss.*;
/**
* Implements the GSSAPI SASL server mechanism for Kerberos V5.
- * (RFC 2222,
+ * (RFC 2222,
* draft-ietf-cat-sasl-gssapi-00.txt).
*
* Expects thread's Subject to contain server's Kerberos credentials
diff --git a/jdk/src/share/classes/com/sun/servicetag/Registry.java b/jdk/src/share/classes/com/sun/servicetag/Registry.java
index 68386ce673b..14ad2fd623d 100644
--- a/jdk/src/share/classes/com/sun/servicetag/Registry.java
+++ b/jdk/src/share/classes/com/sun/servicetag/Registry.java
@@ -67,7 +67,6 @@ public class Registry {
// The stclient output has to be an exported interface
private static final String INSTANCE_URN_DESC = "Product instance URN=";
private static boolean initialized = false;
- private static boolean supportsHelperClass = true; // default
private static File stclient = null;
private static String stclientPath = null;
private static Registry registry = new Registry();
@@ -81,17 +80,6 @@ public class Registry {
private synchronized static String getSTclient() {
if (!initialized) {
- // the system property always overrides the default setting
- if (System.getProperty(SVCTAG_STHELPER_SUPPORTED) != null) {
- supportsHelperClass = Boolean.getBoolean(SVCTAG_STHELPER_SUPPORTED);
- }
-
- // This is only used for testing
- stclientPath = System.getProperty(SVCTAG_STCLIENT_CMD);
- if (stclientPath != null) {
- return stclientPath;
- }
-
// Initialization to determine the platform's stclient pathname
String os = System.getProperty("os.name");
if (os.equals("SunOS")) {
@@ -108,10 +96,26 @@ public class Registry {
initialized = true;
}
+ boolean supportsHelperClass = true; // default
+ if (System.getProperty(SVCTAG_STHELPER_SUPPORTED) != null) {
+ // the system property always overrides the default setting
+ supportsHelperClass = Boolean.getBoolean(SVCTAG_STHELPER_SUPPORTED);
+ }
+
+ if (!supportsHelperClass) {
+ // disable system registry
+ return null;
+ }
+
+ // This is only used for testing
+ String path = System.getProperty(SVCTAG_STCLIENT_CMD);
+ if (path != null) {
+ return path;
+ }
+
// com.sun.servicetag package has to be compiled with JDK 5 as well
// JDK 5 doesn't support the File.canExecute() method.
// Risk not checking isExecute() for the stclient command is very low.
-
if (stclientPath == null && stclient != null && stclient.exists()) {
stclientPath = stclient.getAbsolutePath();
}
@@ -142,8 +146,8 @@ public class Registry {
* @return {@code true} if the {@code Registry} class is supported;
* otherwise, return {@code false}.
*/
- public static boolean isSupported() {
- return (getSTclient() != null && supportsHelperClass);
+ public static synchronized boolean isSupported() {
+ return getSTclient() != null;
}
private static List Thank you for installing the
+ Thank you for installing the
Java Development Kit @@JDK_VERSION@@
- from Sun Microsystems. Registering your product will give you the following benefits: Product registration is FREE, quick and easy! Sun Microsystems, Inc. respects your privacy.
- We will use your personal information for communications
- and management of your Sun Online Account, the services
- and applications you access using your Sun Online Account,
+ Oracle Corporation respects your privacy.
+ We will use your personal information for communications
+ and management of your Sun Online Account, the services
+ and applications you access using your Sun Online Account,
and the products and systems you register with your Sun Online Account. For more information on the data that will be collected as
+ For more information on the data that will be collected as
part of the registration process and how it will be managed Sun Microsystems ã® Java Development Kit @@JDK_VERSION@@ をインストールã—ã¦ã„ãŸã ãã€ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ Oracle Corporation ã® Java Development Kit @@JDK_VERSION@@ をインストールã—ã¦ã„ãŸã ãã€ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ 製å“登録をã™ã‚‹ã¨ã€æ¬¡ã®ã‚ˆã†ãªç‰¹å…¸ã‚’å—ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ 製å“登録ã¯ç„¡æ–™ã§ã‚ã‚Šã€è¿…速ã§ç°¡å˜ã§ã™ã€‚ å¿…è¦ã«ãªã‚‹ã®ã¯ã€Sun 開発者å‘ã‘ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¾ãŸã¯ãã®ä»–ã® Sun オンラインアカウントã ã‘ã§ã™ã€‚ ã¾ã アカウントãŒãªã„å ´åˆã¯ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ä½œæˆãŒæ±‚ã‚られã¾ã™ã€‚ Sun Microsystems, Inc. ã¯ã€ãŠå®¢æ§˜ã®ãƒ—ライãƒã‚·ãƒ¼ã‚’å°Šé‡ã—ã¾ã™ã€‚ ãŠå®¢æ§˜ã®å€‹äººæƒ…å ±ã¯ã€ãŠå®¢æ§˜ã® Sun オンラインアカウントã€ãŠå®¢æ§˜ãŒ Sun オンラインアカウントを使用ã—ã¦ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã‚µãƒ¼ãƒ“スã¨ã‚¢ãƒ—リケーションã€ãŠã‚ˆã³ãŠå®¢æ§˜ãŒ Sun オンラインアカウントã§ç™»éŒ²ã™ã‚‹è£½å“ã¨ã‚·ã‚¹ãƒ†ãƒ ã®é€šä¿¡ã¨ç®¡ç†ã«ä½¿ç”¨ã—ã¾ã™ã€‚ 登録ã®éš›ã«åŽé›†ã•ã‚Œã‚‹ãƒ‡ãƒ¼ã‚¿ã‚„ã€ãれらãŒã©ã®ã‚ˆã†ã«ç®¡ç†ã•ã‚Œã‚‹ã‹ã«ã¤ã„ã¦ã®è©³ç´°ã¯ã€ Oracle Corporation ã¯ã€ãŠå®¢æ§˜ã®ãƒ—ライãƒã‚·ãƒ¼ã‚’å°Šé‡ã—ã¾ã™ã€‚ ãŠå®¢æ§˜ã®å€‹äººæƒ…å ±ã¯ã€ãŠå®¢æ§˜ã® Sun オンラインアカウントã€ãŠå®¢æ§˜ãŒ Sun オンラインアカウントを使用ã—ã¦ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã‚µãƒ¼ãƒ“スã¨ã‚¢ãƒ—リケーションã€ãŠã‚ˆã³ãŠå®¢æ§˜ãŒ Sun オンラインアカウントã§ç™»éŒ²ã™ã‚‹è£½å“ã¨ã‚·ã‚¹ãƒ†ãƒ ã®é€šä¿¡ã¨ç®¡ç†ã«ä½¿ç”¨ã—ã¾ã™ã€‚ 登録ã®éš›ã«åŽé›†ã•ã‚Œã‚‹ãƒ‡ãƒ¼ã‚¿ã‚„ã€ãれらãŒã©ã®ã‚ˆã†ã«ç®¡ç†ã•ã‚Œã‚‹ã‹ã«ã¤ã„ã¦ã®è©³ç´°ã¯ã€ 感谢您安装 Sun Microsystems çš„ Java Development Kit @@JDK_VERSION@@。 感谢您安装 Oracle Corporation çš„ Java Development Kit @@JDK_VERSION@@。 注册产å“åŽæ‚¨å°†èŽ·å¾—如下增值æœåŠ¡ï¼š 产å“注册是å…费的,å³å¿«é€Ÿåˆè½»æ¾ï¼ 您需è¦å…·æœ‰ Sun å¼€å‘者网络或其他 Sun è”机å¸æˆ·ã€‚如果您没有,系统将æ示您创建一个。 Sun Microsystems, Inc. å°Šé‡æ‚¨çš„éšç§ã€‚我们会将您的个人信æ¯ç”¨äºŽé€šä¿¡å’Œ Sun è”机å¸æˆ·çš„管ç†ã€Sun è”机å¸æˆ·è®¿é—®çš„æœåŠ¡å’Œåº”用程åºä»¥åŠç”¨äºŽä½¿ç”¨ Sun è”机å¸æˆ·æ³¨å†Œçš„产å“和系统。 有关注册过程ä¸æ”¶é›†çš„æ•°æ®ä»¥åŠè¿™äº›æ•°æ®çš„管ç†æ–¹å¼çš„更多信æ¯ï¼Œ Oracle å°Šé‡æ‚¨çš„éšç§ã€‚我们会将您的个人信æ¯ç”¨äºŽé€šä¿¡å’Œ Sun è”机å¸æˆ·çš„管ç†ã€Sun è”机å¸æˆ·è®¿é—®çš„æœåŠ¡å’Œåº”用程åºä»¥åŠç”¨äºŽä½¿ç”¨ Sun è”机å¸æˆ·æ³¨å†Œçš„产å“和系统。 有关注册过程ä¸æ”¶é›†çš„æ•°æ®ä»¥åŠè¿™äº›æ•°æ®çš„管ç†æ–¹å¼çš„更多信æ¯ï¼Œ
- * Used in the contructors of the EventSetDescriptor,
- * PropertyDescriptor and the IndexedPropertyDescriptor.
- *
- * @param cls The Class object on which to retrieve the method.
- * @param methodName Name of the method.
- * @param argCount Number of arguments for the desired method.
- * @param args Array of argument types for the method.
- * @return the method or null if not found
- */
- static Method findMethod(Class cls, String methodName, int argCount,
- Class args[]) {
- if (methodName == null) {
+ catch (NoSuchMethodException exception) {
return null;
}
- return internalFindMethod(cls, methodName, argCount, args);
}
/**
diff --git a/jdk/src/share/classes/java/beans/MetaData.java b/jdk/src/share/classes/java/beans/MetaData.java
index 578402129a1..12c4f81eca5 100644
--- a/jdk/src/share/classes/java/beans/MetaData.java
+++ b/jdk/src/share/classes/java/beans/MetaData.java
@@ -700,56 +700,6 @@ class java_beans_beancontext_BeanContextSupport_PersistenceDelegate extends java
// AWT
-/**
- * The persistence delegate for {@link Dimension}.
- * It is impossible to use {@link DefaultPersistenceDelegate}
- * because all getters have return types that differ from parameter types
- * of the constructor {@link Dimension#Dimension(int, int)}.
- *
- * @author Sergey A. Malenkov
- */
-final class java_awt_Dimension_PersistenceDelegate extends PersistenceDelegate {
- protected boolean mutatesTo(Object oldInstance, Object newInstance) {
- return oldInstance.equals(newInstance);
- }
-
- protected Expression instantiate(Object oldInstance, Encoder out) {
- Dimension dimension = (Dimension) oldInstance;
- Object[] args = new Object[] {
- dimension.width,
- dimension.height,
- };
- return new Expression(dimension, dimension.getClass(), "new", args);
- }
-}
-
-/**
- * The persistence delegate for {@link GridBagConstraints}.
- * It is impossible to use {@link DefaultPersistenceDelegate}
- * because this class does not have any properties.
- *
- * @author Sergey A. Malenkov
- */
-final class java_awt_GridBagConstraints_PersistenceDelegate extends PersistenceDelegate {
- protected Expression instantiate(Object oldInstance, Encoder out) {
- GridBagConstraints gbc = (GridBagConstraints) oldInstance;
- Object[] args = new Object[] {
- gbc.gridx,
- gbc.gridy,
- gbc.gridwidth,
- gbc.gridheight,
- gbc.weightx,
- gbc.weighty,
- gbc.anchor,
- gbc.fill,
- gbc.insets,
- gbc.ipadx,
- gbc.ipady,
- };
- return new Expression(gbc, gbc.getClass(), "new", args);
- }
-}
-
/**
* The persistence delegate for {@link Insets}.
* It is impossible to use {@link DefaultPersistenceDelegate}
@@ -774,54 +724,6 @@ final class java_awt_Insets_PersistenceDelegate extends PersistenceDelegate {
}
}
-/**
- * The persistence delegate for {@link Point}.
- * It is impossible to use {@link DefaultPersistenceDelegate}
- * because all getters have return types that differ from parameter types
- * of the constructor {@link Point#Point(int, int)}.
- *
- * @author Sergey A. Malenkov
- */
-final class java_awt_Point_PersistenceDelegate extends PersistenceDelegate {
- protected boolean mutatesTo(Object oldInstance, Object newInstance) {
- return oldInstance.equals(newInstance);
- }
-
- protected Expression instantiate(Object oldInstance, Encoder out) {
- Point point = (Point) oldInstance;
- Object[] args = new Object[] {
- point.x,
- point.y,
- };
- return new Expression(point, point.getClass(), "new", args);
- }
-}
-
-/**
- * The persistence delegate for {@link Rectangle}.
- * It is impossible to use {@link DefaultPersistenceDelegate}
- * because all getters have return types that differ from parameter types
- * of the constructor {@link Rectangle#Rectangle(int, int, int, int)}.
- *
- * @author Sergey A. Malenkov
- */
-final class java_awt_Rectangle_PersistenceDelegate extends PersistenceDelegate {
- protected boolean mutatesTo(Object oldInstance, Object newInstance) {
- return oldInstance.equals(newInstance);
- }
-
- protected Expression instantiate(Object oldInstance, Encoder out) {
- Rectangle rectangle = (Rectangle) oldInstance;
- Object[] args = new Object[] {
- rectangle.x,
- rectangle.y,
- rectangle.width,
- rectangle.height,
- };
- return new Expression(rectangle, rectangle.getClass(), "new", args);
- }
-}
-
/**
* The persistence delegate for {@link Font}.
* It is impossible to use {@link DefaultPersistenceDelegate}
diff --git a/jdk/src/share/classes/java/beans/MethodDescriptor.java b/jdk/src/share/classes/java/beans/MethodDescriptor.java
index 998aa23b217..74a7a16782d 100644
--- a/jdk/src/share/classes/java/beans/MethodDescriptor.java
+++ b/jdk/src/share/classes/java/beans/MethodDescriptor.java
@@ -82,21 +82,21 @@ public class MethodDescriptor extends FeatureDescriptor {
Method method = getMethod0();
if (method == null) {
Class cls = getClass0();
- if (cls != null) {
+ String name = getName();
+ if ((cls != null) && (name != null)) {
Class[] params = getParams();
if (params == null) {
for (int i = 0; i < 3; i++) {
// Find methods for up to 2 params. We are guessing here.
// This block should never execute unless the classloader
// that loaded the argument classes disappears.
- method = Introspector.findMethod(cls, getName(), i, null);
+ method = Introspector.findMethod(cls, name, i);
if (method != null) {
break;
}
}
} else {
- method = Introspector.findMethod(cls, getName(),
- params.length, params);
+ method = Statement.getMethod(cls, name, params);
}
setMethod(method);
}
diff --git a/jdk/src/share/classes/java/beans/PropertyDescriptor.java b/jdk/src/share/classes/java/beans/PropertyDescriptor.java
index a757530e5a8..c7524e3026f 100644
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java
+++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java
@@ -112,9 +112,7 @@ public class PropertyDescriptor extends FeatureDescriptor {
// If this class or one of its base classes allow PropertyChangeListener,
// then we assume that any properties we discover are "bound".
// See Introspector.getTargetPropertyInfo() method.
- String name = "addPropertyChangeListener";
- Class[] args = {PropertyChangeListener.class};
- this.bound = (null != Introspector.findMethod(beanClass, name, args.length, args));
+ this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class);
}
/**
@@ -225,10 +223,10 @@ public class PropertyDescriptor extends FeatureDescriptor {
// property type is. For booleans, there can be "is" and "get"
// methods. If an "is" method exists, this is the official
// reader method so look for this one first.
- readMethod = Introspector.findMethod(cls, readMethodName, 0);
+ readMethod = Introspector.findInstanceMethod(cls, readMethodName);
if (readMethod == null) {
readMethodName = Introspector.GET_PREFIX + getBaseName();
- readMethod = Introspector.findMethod(cls, readMethodName, 0);
+ readMethod = Introspector.findInstanceMethod(cls, readMethodName);
}
try {
setReadMethod(readMethod);
@@ -293,8 +291,7 @@ public class PropertyDescriptor extends FeatureDescriptor {
writeMethodName = Introspector.SET_PREFIX + getBaseName();
}
- writeMethod = Introspector.findMethod(cls, writeMethodName, 1,
- (type == null) ? null : new Class[] { type });
+ writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type);
if (writeMethod != null) {
if (!writeMethod.getReturnType().equals(void.class)) {
writeMethod = null;
diff --git a/jdk/src/share/classes/java/beans/PropertyEditorManager.java b/jdk/src/share/classes/java/beans/PropertyEditorManager.java
index 3dfbbca321b..6bdfa95f41b 100644
--- a/jdk/src/share/classes/java/beans/PropertyEditorManager.java
+++ b/jdk/src/share/classes/java/beans/PropertyEditorManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -81,10 +81,7 @@ public class PropertyEditorManager {
if (sm != null) {
sm.checkPropertiesAccess();
}
- PropertyEditorFinder finder = getFinder();
- synchronized (finder) {
- finder.register(targetType, editorClass);
- }
+ getFinder().register(targetType, editorClass);
}
/**
@@ -95,10 +92,7 @@ public class PropertyEditorManager {
* The result is null if no suitable editor can be found.
*/
public static PropertyEditor findEditor(Class> targetType) {
- PropertyEditorFinder finder = getFinder();
- synchronized (finder) {
- return finder.find(targetType);
- }
+ return getFinder().find(targetType);
}
/**
@@ -110,10 +104,7 @@ public class PropertyEditorManager {
* e.g. Sun implementation initially sets to {"sun.beans.editors"}.
*/
public static String[] getEditorSearchPath() {
- PropertyEditorFinder finder = getFinder();
- synchronized (finder) {
- return finder.getPackages();
- }
+ return getFinder().getPackages();
}
/**
@@ -134,10 +125,7 @@ public class PropertyEditorManager {
if (sm != null) {
sm.checkPropertiesAccess();
}
- PropertyEditorFinder finder = getFinder();
- synchronized (finder) {
- finder.setPackages(path);
- }
+ getFinder().setPackages(path);
}
private static PropertyEditorFinder getFinder() {
diff --git a/jdk/src/share/classes/java/beans/XMLDecoder.java b/jdk/src/share/classes/java/beans/XMLDecoder.java
index 4fd0f9dab77..a0d5aa04ff3 100644
--- a/jdk/src/share/classes/java/beans/XMLDecoder.java
+++ b/jdk/src/share/classes/java/beans/XMLDecoder.java
@@ -60,7 +60,7 @@ import org.xml.sax.helpers.DefaultHandler;
*
* @author Philip Milne
*/
-public class XMLDecoder {
+public class XMLDecoder implements AutoCloseable {
private final DocumentHandler handler = new DocumentHandler();
private final InputSource input;
private Object owner;
diff --git a/jdk/src/share/classes/java/beans/XMLEncoder.java b/jdk/src/share/classes/java/beans/XMLEncoder.java
index 970b86e25c0..3866a630187 100644
--- a/jdk/src/share/classes/java/beans/XMLEncoder.java
+++ b/jdk/src/share/classes/java/beans/XMLEncoder.java
@@ -204,7 +204,7 @@ import java.nio.charset.UnsupportedCharsetException;
*
* @author Philip Milne
*/
-public class XMLEncoder extends Encoder {
+public class XMLEncoder extends Encoder implements AutoCloseable {
private final CharsetEncoder encoder;
private final String charset;
@@ -407,7 +407,20 @@ public class XMLEncoder extends Encoder {
os.writeObject(this);
*/
mark(oldStm);
- statementList(oldStm.getTarget()).add(oldStm);
+ Object target = oldStm.getTarget();
+ if (target instanceof Field) {
+ String method = oldStm.getMethodName();
+ Object[] args = oldStm.getArguments();
+ if ((method == null) || (args == null)) {
+ }
+ else if (method.equals("get") && (args.length == 1)) {
+ target = args[0];
+ }
+ else if (method.equals("set") && (args.length == 2)) {
+ target = args[0];
+ }
+ }
+ statementList(target).add(oldStm);
}
catch (Exception e) {
getExceptionListener().exceptionThrown(new Exception("XMLEncoder: discarding statement " + oldStm, e));
@@ -703,7 +716,9 @@ public class XMLEncoder extends Encoder {
statements.add(exp);
}
outputValue(target, outer, false);
- outputValue(value, outer, isArgument);
+ if (expression) {
+ outputValue(value, outer, isArgument);
+ }
return;
}
if (expression && (d.refs > 1)) {
@@ -722,8 +737,10 @@ public class XMLEncoder extends Encoder {
}
else if ((!expression && methodName.startsWith("set") && args.length == 1) ||
(expression && methodName.startsWith("get") && args.length == 0)) {
- attributes = attributes + " property=" +
- quote(Introspector.decapitalize(methodName.substring(3)));
+ if (3 < methodName.length()) {
+ attributes = attributes + " property=" +
+ quote(Introspector.decapitalize(methodName.substring(3)));
+ }
}
else if (!methodName.equals("new") && !methodName.equals("newInstance")) {
attributes = attributes + " method=" + quote(methodName);
diff --git a/jdk/src/share/classes/java/dyn/CallSite.java b/jdk/src/share/classes/java/dyn/CallSite.java
index 94e58f6a815..b8335774851 100644
--- a/jdk/src/share/classes/java/dyn/CallSite.java
+++ b/jdk/src/share/classes/java/dyn/CallSite.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,25 +25,32 @@
package java.dyn;
-import sun.dyn.util.BytecodeName;
import sun.dyn.Access;
+import sun.dyn.MemberName;
import sun.dyn.CallSiteImpl;
-import sun.dyn.MethodHandleImpl;
/**
- * An {@code invokedynamic} call site, as reified by the
- * containing class's bootstrap method.
- * Every call site object corresponds to a distinct instance
- * of the
- * (Note: The bootstrap method may elect to produce call sites of a
+ * Every linked {@code CallSite} object has one state variable,
+ * a {@link MethodHandle} reference called the {@code target}.
+ * This reference is never null. Though it can change its value
+ * successive values must always have exactly the {@link MethodType method type}
+ * called for by the bytecodes of the associated {@code invokedynamic} instruction
+ *
+ * It is the responsibility of each class's
+ * {@link Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
+ * to produce call sites which have been pre-linked to an initial target method.
+ * The required {@link MethodType type} for the target method is a parameter
+ * to each bootstrap method call.
+ *
+ * The bootstrap method may elect to produce call sites of a
* language-specific subclass of {@code CallSite}. In such a case,
* the subclass may claim responsibility for initializing its target to
- * a non-null value, by overriding {@link #initialTarget}.)
+ * a non-null value, by overriding {@link #initialTarget}.
*
* An {@code invokedynamic} instruction which has not yet been executed
* is said to be unlinked. When an unlinked call site is executed,
@@ -52,54 +59,139 @@ import sun.dyn.MethodHandleImpl;
* value to the new call site's target variable, the method {@link #initialTarget}
* is called to produce the new call site's first target method.
*
+ * A freshly-created {@code CallSite} object is not yet in a linked state.
+ * An unlinked {@code CallSite} object reports null for its {@code callerClass}.
+ * When the JVM receives a {@code CallSite} object from a bootstrap method,
+ * it first ensures that its target is non-null and of the correct type.
+ * The JVM then links the {@code CallSite} object to the call site instruction,
+ * enabling the {@code callerClass} to return the class in which the instruction occurs.
+ *
+ * Next, the JVM links the instruction to the {@code CallSite}, at which point
+ * any further execution of the {@code invokedynamic} instruction implicitly
+ * invokes the current target of the {@code CallSite} object.
+ * After this two-way linkage, both the instruction and the {@code CallSite}
+ * object are said to be linked.
+ *
+ * This state of linkage continues until the method containing the
+ * dynamic call site is garbage collected, or the dynamic call site
+ * is invalidated by an explicit request.
+ *
+ * Linkage happens once in the lifetime of any given {@code CallSite} object.
+ * Because of call site invalidation, this linkage can be repeated for
+ * a single {@code invokedynamic} instruction, with multiple {@code CallSite} objects.
+ * When a {@code CallSite} is unlinked from an {@code invokedynamic} instruction,
+ * the instruction is reset so that it is no longer associated with
+ * the {@code CallSite} object, but the {@code CallSite} does not change
+ * state.
+ *
+ * Here is a sample use of call sites and bootstrap methods which links every
+ * dynamic call site to print its arguments:
+
+ * The arguments are the same as those passed to the bootstrap method.
+ * Thus, a bootstrap method is free to ignore the arguments and simply
+ * create a "blank" {@code CallSite} object of an appropriate subclass.
+ *
* If the bootstrap method itself does not initialize the call site,
* this method must be overridden, because it just raises an
* {@code InvokeDynamicBootstrapError}, which in turn causes the
* linkage of the {@code invokedynamic} instruction to terminate
* abnormally.
*/
- protected MethodHandle initialTarget() {
- throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+this);
+ protected MethodHandle initialTarget(Class> callerClass, String name, MethodType type) {
+ throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+name+type);
}
/**
@@ -137,11 +233,11 @@ public class CallSite
* @see #setTarget
*/
public MethodHandle getTarget() {
- return super.getTarget();
+ return target;
}
/**
- * Link or relink the call site, by setting its target method.
+ * Set the target method of this call site.
*
* The interactions of {@code setTarget} with memory are the same
* as of a write to an ordinary variable, such as an array element or a
@@ -152,96 +248,46 @@ public class CallSite
* Stronger guarantees can be created by putting appropriate operations
* into the bootstrap method and/or the target methods used
* at any given call site.
- * @param target the new target, or null if it is to be unlinked
+ * @param newTarget the new target
* @throws NullPointerException if the proposed new target is null
- * @throws WrongMethodTypeException if the proposed new target
- * has a method type that differs from the call site's {@link #type()}
+ * @throws WrongMethodTypeException if the call site is linked and the proposed new target
+ * has a method type that differs from the previous target
*/
- public void setTarget(MethodHandle target) {
- checkTarget(target);
- super.setTarget(target);
+ public void setTarget(MethodHandle newTarget) {
+ MethodType newType = newTarget.type(); // null check!
+ MethodHandle oldTarget = this.target;
+ if (oldTarget == null) {
+ // CallSite is not yet linked.
+ assert(!isLinked());
+ this.target = newTarget; // might be null!
+ return;
+ }
+ MethodType oldType = oldTarget.type();
+ if (!newTarget.type().equals(oldType))
+ throw wrongTargetType(newTarget, oldType);
+ if (oldTarget != newTarget)
+ CallSiteImpl.setCallSiteTarget(IMPL_TOKEN, this, newTarget);
}
- protected void checkTarget(MethodHandle target) {
- target.type(); // provoke NPE
- if (!canSetTarget(target))
- throw new WrongMethodTypeException(String.valueOf(target)+target.type()+" should be of type "+type());
+ private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
+ return new WrongMethodTypeException(String.valueOf(target)+target.type()+" should be of type "+type);
}
- protected boolean canSetTarget(MethodHandle target) {
- return (target != null && target.type() == type());
- }
-
- /**
- * Report the class containing the call site.
- * This is an immutable property of the call site, set from the first argument to the constructor.
- * @return class containing the call site
+ /** Produce a printed representation that displays information about this call site
+ * that may be useful to the human reader.
*/
- public Class> callerClass() {
- return (Class) caller;
- }
-
- /**
- * Report the method name specified in the {@code invokedynamic} instruction.
- * This is an immutable property of the call site, set from the second argument to the constructor.
- *
- * Note that the name is a JVM bytecode name, and as such can be any
- * non-empty string, as long as it does not contain certain "dangerous"
- * characters such as slash {@code '/'} and dot {@code '.'}.
- * See the Java Virtual Machine specification for more details.
- *
- * Application such as a language runtimes may need to encode
- * arbitrary program element names and other configuration information
- * into the name. A standard convention for doing this is
- * specified here.
- * @return method name specified by the call site
- */
- public String name() {
- return name;
- }
-
- /**
- * Report the method name specified in the {@code invokedynamic} instruction,
- * as a series of components, individually demangled according to
- * the standard convention
- * specified here.
- *
- * Non-empty runs of characters between dangerous characters are demangled.
- * Each component is either a completely arbitrary demangled string,
- * or else a character constant for a punctuation character, typically ':'.
- * (In principle, the character can be any dangerous character that the
- * JVM lets through in a method name, such as '$' or ']'.
- * Runtime implementors are encouraged to use colon ':' for building
- * structured names.)
- *
- * In the common case where the name contains no dangerous characters,
- * the result is an array whose only element array is the demangled
- * name at the call site. Such a demangled name can be any sequence
- * of any number of any unicode characters.
- * @return method name components specified by the call site
- */
- public Object[] nameComponents() {
- return BytecodeName.parseBytecodeName(name);
- }
-
- /**
- * Report the resolved result and parameter types of this call site,
- * which are derived from its bytecode-level invocation descriptor.
- * The types are packaged into a {@link MethodType}.
- * Any linked target of this call site must be exactly this method type.
- * This is an immutable property of the call site, set from the third argument to the constructor.
- * @return method type specified by the call site
- */
- public MethodType type() {
- return type;
- }
-
@Override
public String toString() {
- return "CallSite#"+hashCode()+"["+name+type+" => "+getTarget()+"]";
+ StringBuilder buf = new StringBuilder("CallSite#");
+ buf.append(hashCode());
+ if (!isLinked())
+ buf.append("[unlinked]");
+ else
+ buf.append("[")
+ .append("from ").append(vmmethod.getDeclaringClass().getName())
+ .append(" : ").append(getTarget().type())
+ .append(" => ").append(getTarget())
+ .append("]");
+ return buf.toString();
}
-
- // Package-local constant:
- static final MethodHandle GET_TARGET = MethodHandleImpl.getLookup(IMPL_TOKEN).
- findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
}
diff --git a/jdk/src/share/classes/java/dyn/InvokeDynamic.java b/jdk/src/share/classes/java/dyn/InvokeDynamic.java
index 7f9d4b0363f..021e75a1ea7 100644
--- a/jdk/src/share/classes/java/dyn/InvokeDynamic.java
+++ b/jdk/src/share/classes/java/dyn/InvokeDynamic.java
@@ -26,27 +26,25 @@
package java.dyn;
/**
- * Syntactic marker to request javac to emit an {@code invokedynamic} instruction.
- * An {@code invokedynamic} instruction is a 5-byte bytecoded instruction
- * which begins with an opcode byte of value 186 ({@code 0xBA}),
- * and is followed by a two-byte index of a {@code NameAndType} constant
- * pool entry, then by two zero bytes. The constant pool reference gives
- * the method name and argument and return types of the call site; there
- * is no other information provided at the call site.
+ * {@code InvokeDynamic} is a class with neither methods nor instances,
+ * which serves only as a syntactic marker in Java source code for
+ * an {@code invokedynamic} instruction.
+ * (See the package information for specifics on this instruction.)
*
* The {@code invokedynamic} instruction is incomplete without a target method.
- * The target method is a property of the reified call site object
- * (of type {@link CallSite}) which is in a one-to-one association with each
- * corresponding {@code invokedynamic} instruction. The call site object
- * is initially produced by a bootstrap method associated with
- * the call site, via the various overloadings of {@link Linkage#registerBootstrapMethod}.
+ * The target method is a property of the reified {@linkplain CallSite call site object}
+ * which is linked to each active {@code invokedynamic} instruction.
+ * The call site object is initially produced by a
+ * {@linkplain java.dyn.Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
+ * associated with the class whose bytecodes include the dynamic call site.
*
* The type {@code InvokeDynamic} has no particular meaning as a
* class or interface supertype, or an object type; it can never be instantiated.
* Logically, it denotes a source of all dynamically typed methods.
- * It may be viewed as a pure syntactic marker (an importable one) of static calls.
+ * It may be viewed as a pure syntactic marker of static calls.
+ * It may be imported for ease of use.
*
- * Here are some examples of usage:
+ * Here are some examples:
*
- * The boostrap method must have been declared during a class's initialization
- * by a call to {@link Linkage#registerBootstrapMethod}.
+ * The bootstrap method must have been declared during a class's initialization
+ * by a call to one of the overloadings of
+ * {@link Linkage#registerBootstrapMethod registerBootstrapMethod}.
*
* @author John Rose, JSR 292 EG
*/
public class InvokeDynamicBootstrapError extends LinkageError {
/**
- * Constructs a {@code InvokeDynamicBootstrapError} with no detail message.
+ * Constructs an {@code InvokeDynamicBootstrapError} with no detail message.
*/
public InvokeDynamicBootstrapError() {
super();
}
/**
- * Constructs a {@code InvokeDynamicBootstrapError} with the specified
+ * Constructs an {@code InvokeDynamicBootstrapError} with the specified
* detail message.
*
* @param s the detail message.
diff --git a/jdk/src/share/classes/java/dyn/JavaMethodHandle.java b/jdk/src/share/classes/java/dyn/JavaMethodHandle.java
index 0507eecb237..d8cd87a5ed5 100644
--- a/jdk/src/share/classes/java/dyn/JavaMethodHandle.java
+++ b/jdk/src/share/classes/java/dyn/JavaMethodHandle.java
@@ -28,7 +28,8 @@ package java.dyn;
import sun.dyn.Access;
/**
- * A Java method handle extends the basic method handle type with additional
+ * A Java method handle is a deprecated proposal for extending
+ * the basic method handle type with additional
* programmer defined methods and fields.
* Its behavior as a method handle is determined at instance creation time,
* by providing the new instance with an "entry point" method handle
@@ -62,11 +63,11 @@ import sun.dyn.Access;
* greeter.run(); // prints "hello, world"
* // Statically typed method handle invocation (most direct):
* MethodHandle mh = greeter;
- * mh.<void>invoke(); // also prints "hello, world"
+ * mh.<void>invokeExact(); // also prints "hello, world"
* // Dynamically typed method handle invocation:
- * MethodHandles.invoke(greeter); // also prints "hello, world"
+ * MethodHandles.invokeExact(greeter); // also prints "hello, world"
* greeter.setGreeting("howdy");
- * mh.invoke(); // prints "howdy, world" (object-like mutable behavior)
+ * mh.invokeExact(); // prints "howdy, world" (object-like mutable behavior)
*
* In the example of {@code Greeter}, the method {@code run} provides the entry point.
@@ -81,7 +82,7 @@ import sun.dyn.Access;
* inner class:
*
* Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle,
@@ -137,10 +138,12 @@ import sun.dyn.Access;
* public Number get(long i) { return stuff[(int)i]; }
* public void set(long i, Object x) { stuff[(int)i] = x; }
* }
- * int x = (Integer) stuffPtr.<Number>invoke(1L); // 456
- * stuffPtr.setter().<void>invoke(0L, (Number) 789); // replaces 123 with 789
+ * int x = (Integer) stuffPtr.<Number>invokeExact(1L); // 456
+ * stuffPtr.setter().<void>invokeExact(0L, (Number) 789); // replaces 123 with 789
*
* @see MethodHandle
+ * @deprecated The JSR 292 EG intends to replace {@code JavaMethodHandle} with
+ * an interface-based API for mixing method handle behavior with other classes.
* @author John Rose, JSR 292 EG
*/
public abstract class JavaMethodHandle
diff --git a/jdk/src/share/classes/java/dyn/Linkage.java b/jdk/src/share/classes/java/dyn/Linkage.java
index 9b6bd60ea96..d65ae41c31c 100644
--- a/jdk/src/share/classes/java/dyn/Linkage.java
+++ b/jdk/src/share/classes/java/dyn/Linkage.java
@@ -25,14 +25,19 @@
package java.dyn;
+import java.lang.annotation.Annotation;
import java.dyn.MethodHandles.Lookup;
import java.util.WeakHashMap;
import sun.dyn.Access;
+import sun.dyn.MethodHandleImpl;
import sun.reflect.Reflection;
import static sun.dyn.util.VerifyAccess.checkBootstrapPrivilege;
+import static sun.dyn.MemberName.newIllegalArgumentException;
/**
- * Static methods which control the linkage of invokedynamic call sites.
+ * This class consists exclusively of static methods that control
+ * the linkage of {@code invokedynamic} instructions, and specifically
+ * their reification as {@link CallSite} objects.
* @author John Rose, JSR 292 EG
*/
public class Linkage {
@@ -42,102 +47,137 @@ public class Linkage {
/**
* PROVISIONAL API, WORK IN PROGRESS:
- * Register a bootstrap method to use when linking a given caller class.
- * It must be a method handle of a type equivalent to {@link CallSite#CallSite}.
- * In other words, it must act as a factory method which accepts the arguments
- * to {@code CallSite}'s constructor (a class, a string, and a method type),
+ * Register a bootstrap method to use when linking dynamic call sites within
+ * a given caller class.
+ *
+ * A bootstrap method must be a method handle with a return type of {@link CallSite}
+ * and the following arguments:
+ *
- * The registration will fail with an {@code IllegalStateException} if any of the following conditions hold:
+ * The registration must take place exactly once, either before the class has begun
+ * being initialized, or from within the class's static initializer.
+ * Registration will fail with an exception if any of the following conditions hold:
*
* When this method returns, every matching
- * The target name is the name of the runtime permission (see below). The
- * naming convention follows the hierarchical property naming convention.
- * Also, an asterisk
- * may appear at the end of the name, following a ".", or by itself, to
- * signify a wildcard match. For example: "loadLibrary.*" or "*" is valid,
- * "*loadLibrary" or "a*b" is not valid.
- *
- * The following table lists all the possible RuntimePermission target names,
+ *
+ * The following table lists all the possible {@code LinkagePermission} target names,
* and for each provides a description of what the permission allows
* and a discussion of the risks of granting code the permission.
- *
+ *
*
*
* Method handles are strongly typed according to signature.
* They are not distinguished by method name or enclosing class.
* A method handle must be invoked under a signature which exactly matches
- * the method handle's own type.
+ * the method handle's own {@link MethodType method type}.
*
- * Every method handle confesses its type via the
* Every method handle appears as an object containing a method named
- *
* Every call to a method handle specifies an intended method type,
* which must exactly match the type of the method handle.
- * (The type is specified in the
* Bytecode in an extended JVM can directly call a method handle's
- *
- * Every
* Bytecode in an extended JVM can directly obtain a method handle
- * for any accessible method from a
- * All JVMs can also use a reflective API called
* A method reference may refer either to a static or non-static method.
@@ -104,7 +106,7 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* receiver argument, prepended before any other arguments.
* In the method handle's type, the initial receiver argument is typed
* according to the class under which the method was initially requested.
- * (E.g., if a non-static method handle is obtained via
* When a method handle to a virtual method is invoked, the method is
@@ -113,38 +115,38 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* A non-virtual method handles to a specific virtual method implementation
* can also be created. These do not perform virtual lookup based on
* receiver type. Such a method handle simulates the effect of
- * an
* Here are some examples of usage:
*
+ * Note: Like classes and strings, method handles that correspond directly
+ * to fields and methods can be represented directly as constants to be
+ * loaded by {@code ldc} bytecodes.
*
* @see MethodType
* @see MethodHandles
@@ -180,7 +190,15 @@ public abstract class MethodHandle
private static Access IMPL_TOKEN = Access.getToken();
// interface MethodHandle
* @author John Rose, JSR 292 EG
@@ -66,36 +66,44 @@ public class MethodHandles {
//// Method handle creation from ordinary methods.
- /** Create a {@link Lookup} lookup object on the caller.
- *
+ /**
+ * Return a {@link Lookup lookup object} on the caller,
+ * which has the capability to access any method handle that the caller has access to,
+ * including direct method handles to private fields and methods.
+ * This lookup object is a capability which may be delegated to trusted agents.
+ * Do not store it in place where untrusted code can access it.
*/
public static Lookup lookup() {
return new Lookup();
}
- /** Version of lookup which is trusted minimally.
- * It can only be used to create method handles to
- * publicly accessible members.
+ /**
+ * Return a {@link Lookup lookup object} which is trusted minimally.
+ * It can only be used to create method handles to
+ * publicly accessible fields and methods.
*/
public static Lookup publicLookup() {
return Lookup.PUBLIC_LOOKUP;
}
/**
- * A factory object for creating method handles, when the creation
- * requires access checking. Method handles do not perform
+ * A lookup object is a factory for creating method handles,
+ * when the creation requires access checking.
+ * Method handles do not perform
* access checks when they are called; this is a major difference
* from reflective {@link Method}, which performs access checking
- * against every caller, on every call. Method handle access
- * restrictions are enforced when a method handle is created.
+ * against every caller, on every call.
+ * Therefore, method handle access
+ * restrictions must be enforced when a method handle is created.
* The caller class against which those restrictions are enforced
- * is known as the "lookup class". {@link Lookup} embodies an
+ * is known as the {@linkplain #lookupClass lookup class}.
+ * A lookup object embodies an
* authenticated lookup class, and can be used to create any number
* of access-checked method handles, all checked against a single
* lookup class.
*
* A class which needs to create method handles will call
- * {@code MethodHandles.lookup()} to create a factory for itself.
+ * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
* It may then use this factory to create method handles on
* all of its methods, including private ones.
* It may also delegate the lookup (e.g., to a metaobject protocol)
@@ -104,12 +112,13 @@ public class MethodHandles {
* checked against the original lookup class, and not with any higher
* privileges.
*
- * Note that access checks only apply to named and reflected methods.
- * Other method handle creation methods, such as {@link #convertArguments},
+ * Access checks only apply to named and reflected methods.
+ * Other method handle creation methods, such as
+ * {@link #convertArguments MethodHandles.convertArguments},
* do not require any access checks, and can be done independently
* of any lookup class.
- *
- * A note about error conditions: A lookup can fail, because
+ *
@@ -136,57 +162,90 @@ public class MethodHandles {
return lookupClass;
}
+ // This is just for calling out to MethodHandleImpl.
+ private Class> lookupClassOrNull() {
+ return (allowedModes == TRUSTED) ? null : lookupClass;
+ }
+
+ /** Which types of members can this lookup object produce?
+ * The result is a bit-mask of the modifier bits PUBLIC, PROTECTED, PRIVATE, and STRICT.
+ * The modifier bit STRICT stands in for the (non-existent) package protection mode.
+ */
+ int lookupModes() {
+ return allowedModes & ALL_MODES;
+ }
+
/** Embody the current class (the lookupClass) as a lookup class
* for method handle creation.
* Must be called by from a method in this package,
* which in turn is called by a method not in this package.
+ *
* Also, don't make it private, lest javac interpose
* an access$N method.
*/
Lookup() {
- this(IMPL_TOKEN, getCallerClassAtEntryPoint());
+ this(getCallerClassAtEntryPoint(), ALL_MODES);
+ // make sure we haven't accidentally picked up a privileged class:
+ checkUnprivilegedlookupClass(lookupClass);
}
Lookup(Access token, Class> lookupClass) {
- // make sure we haven't accidentally picked up a privileged class:
- checkUnprivilegedlookupClass(lookupClass);
+ this(lookupClass, ALL_MODES);
+ Access.check(token);
+ }
+
+ private Lookup(Class> lookupClass, int allowedModes) {
this.lookupClass = lookupClass;
+ this.allowedModes = allowedModes;
}
/**
- * Create a lookup on the specified class.
- * The result is guaranteed to have no more access privileges
- * than the original.
+ * Create a lookup on the specified new lookup class.
+ * The resulting object will report the specified
+ * class as its own {@link #lookupClass}.
+ *
+ * However, the resulting {@code Lookup} object is guaranteed
+ * to have no more access capabilities than the original.
+ * In particular:
* (BUG NOTE: The type {@code Object} may be prepended instead
@@ -257,18 +336,44 @@ public class MethodHandles {
* implementation to enter.
* (The dispatching action is identical with that performed by an
* {@code invokevirtual} or {@code invokeinterface} instruction.)
- * @param defc the class or interface from which the method is accessed
+ * @param refc the class or interface from which the method is accessed
* @param name the name of the method
* @param type the type of the method, with the receiver argument omitted
* @return the desired method handle
* @exception SecurityException TBD
* @exception NoAccessException if the method does not exist or access checking fails
*/
- public MethodHandle findVirtual(Class> defc, String name, MethodType type) throws NoAccessException {
- MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type), true, lookupClass());
- VerifyAccess.checkName(method, this);
- checkStatic(false, method, this);
- return MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClass());
+ public MethodHandle findVirtual(Class> refc, String name, MethodType type) throws NoAccessException {
+ MemberName method = resolveOrFail(refc, name, type, false);
+ checkMethod(refc, method, false);
+ MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull());
+ return restrictProtectedReceiver(method, mh);
+ }
+
+ /**
+ * Produce a method handle which creates an object and initializes it, using
+ * the constructor of the specified type.
+ * The parameter types of the method handle will be those of the constructor,
+ * while the return type will be a reference to the constructor's class.
+ * The constructor and all its argument types must be accessible to the lookup class.
+ * If the constructor's class has not yet been initialized, that is done
+ * immediately, before the method handle is returned.
+ *
+ * Note: The requested type must have a return type of {@code void}.
+ * This is consistent with the JVM's treatment of constructor signatures.
+ * @param refc the class or interface from which the method is accessed
+ * @param type the type of the method, with the receiver argument omitted, and a void return type
+ * @return the desired method handle
+ * @exception SecurityException TBD
+ * @exception NoAccessException if the method does not exist or access checking fails
+ */
+ public MethodHandle findConstructor(Class> refc, MethodType type) throws NoAccessException {
+ String name = "
* If the explicitly specified caller class is not identical with the
* lookup class, a security check TBD is performed.
- * @param defc the class or interface from which the method is accessed
- * @param name the name of the method, or "
* This is equivalent to the following expression:
*
* If the constructor's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class.
- * @param ctor the reflected constructor
+ * @param c the reflected constructor
* @return a method handle which can invoke the reflected constructor
* @exception NoAccessException if access checking fails
*/
- public MethodHandle unreflectConstructor(Constructor ctor) throws NoAccessException {
- MemberName m = new MemberName(ctor);
- return unreflectImpl(m, ctor.isAccessible(), false, false, this);
+ public MethodHandle unreflectConstructor(Constructor c) throws NoAccessException {
+ MemberName ctor = new MemberName(c);
+ assert(ctor.isConstructor());
+ if (!c.isAccessible()) checkAccess(c.getDeclaringClass(), ctor);
+ MethodHandle rawCtor = MethodHandleImpl.findMethod(IMPL_TOKEN, ctor, false, lookupClassOrNull());
+ return MethodHandleImpl.makeAllocator(IMPL_TOKEN, rawCtor);
}
/**
@@ -424,8 +598,7 @@ public class MethodHandles {
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectGetter(Field f) throws NoAccessException {
- MemberName m = new MemberName(f);
- return unreflectImpl(m, f.isAccessible(), false, false, this);
+ return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), false);
}
/**
@@ -443,75 +616,134 @@ public class MethodHandles {
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectSetter(Field f) throws NoAccessException {
- MemberName m = new MemberName(f);
- return unreflectImpl(m, f.isAccessible(), false, true, this);
+ return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), true);
}
- }
+ /// Helper methods, all package-private.
- static /*must not be public*/
- MethodHandle findStaticFrom(Lookup lookup,
- Class> defc, String name, MethodType type) throws NoAccessException {
- MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type, Modifier.STATIC), true, lookup.lookupClass());
- VerifyAccess.checkName(method, lookup);
- checkStatic(true, method, lookup);
- return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookup.lookupClass());
- }
-
- static void checkStatic(boolean wantStatic, MemberName m, Lookup lookup) {
- if (wantStatic != m.isStatic()) {
- String message = wantStatic ? "expected a static method" : "expected a non-static method";
- throw newNoAccessException(message, m, lookup.lookupClass());
+ MemberName resolveOrFail(Class> refc, String name, Class> type, boolean isStatic) {
+ checkSymbolicClass(refc); // do this before attempting to resolve
+ int mods = (isStatic ? Modifier.STATIC : 0);
+ return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull());
}
- }
- static void checkSpecialCaller(Class> specialCaller, Lookup lookup) {
- if (lookup == Lookup.IMPL_LOOKUP)
- return; // privileged action
- assert(lookup.lookupClass() != null);
- if (!VerifyAccess.isSamePackageMember(specialCaller, lookup.lookupClass()))
- throw newNoAccessException("no private access", new MemberName(specialCaller), lookup.lookupClass());
- }
-
- // Helper for creating handles on reflected methods and constructors.
- static MethodHandle unreflectImpl(MemberName m, boolean isAccessible,
- boolean doDispatch, boolean isSetter, Lookup lookup) {
- MethodType narrowMethodType = null;
- Class> defc = m.getDeclaringClass();
- boolean isSpecialInvoke = m.isInvocable() && !doDispatch;
- int mods = m.getModifiers();
- if (m.isStatic()) {
- if (!isAccessible &&
- VerifyAccess.isAccessible(defc, mods, lookup.lookupClass(), false) == null)
- throw newNoAccessException(m, lookup);
- } else {
- Class> constraint;
- if (isAccessible) {
- // abbreviated access check for "unlocked" method
- constraint = doDispatch ? defc : lookup.lookupClass();
- } else {
- constraint = VerifyAccess.isAccessible(defc, mods, lookup.lookupClass(), isSpecialInvoke);
- }
- if (constraint == null) {
- throw newNoAccessException(m, lookup);
- }
- if (constraint != defc && !constraint.isAssignableFrom(defc)) {
- if (!defc.isAssignableFrom(constraint))
- throw newNoAccessException("receiver must be in caller class", m, lookup.lookupClass());
- if (m.isInvocable())
- narrowMethodType = m.getInvocationType().changeParameterType(0, constraint);
- else if (m.isField())
- narrowMethodType = (!isSetter
- ? MethodType.methodType(m.getFieldType(), constraint)
- : MethodType.methodType(void.class, constraint, m.getFieldType()));
- }
+ MemberName resolveOrFail(Class> refc, String name, MethodType type, boolean isStatic) {
+ checkSymbolicClass(refc); // do this before attempting to resolve
+ int mods = (isStatic ? Modifier.STATIC : 0);
+ return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull());
+ }
+
+ MemberName resolveOrFail(Class> refc, String name, MethodType type, boolean isStatic,
+ boolean searchSupers, Class> specialCaller) {
+ checkSymbolicClass(refc); // do this before attempting to resolve
+ int mods = (isStatic ? Modifier.STATIC : 0);
+ return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller);
+ }
+
+ void checkSymbolicClass(Class> refc) {
+ Class> caller = lookupClassOrNull();
+ if (caller != null && !VerifyAccess.isClassAccessible(refc, caller))
+ throw newNoAccessException("symbolic reference class is not public", new MemberName(refc), caller);
+ }
+
+ void checkMethod(Class> refc, MemberName m, boolean wantStatic) {
+ String message;
+ if (m.isConstructor())
+ message = "expected a method, not a constructor";
+ else if (!m.isMethod())
+ message = "expected a method";
+ else if (wantStatic != m.isStatic())
+ message = wantStatic ? "expected a static method" : "expected a non-static method";
+ else
+ { checkAccess(refc, m); return; }
+ throw newNoAccessException(message, m, lookupClass());
+ }
+
+ void checkAccess(Class> refc, MemberName m) {
+ int allowedModes = this.allowedModes;
+ if (allowedModes == TRUSTED) return;
+ int mods = m.getModifiers();
+ if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()))
+ return; // common case
+ int requestedModes = fixmods(mods); // adjust 0 => PACKAGE
+ if ((requestedModes & allowedModes) != 0
+ && VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
+ mods, lookupClass()))
+ return;
+ if (((requestedModes & ~allowedModes) & PROTECTED) != 0
+ && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
+ // Protected members can also be checked as if they were package-private.
+ return;
+ throw newNoAccessException(accessFailedMessage(refc, m), m, lookupClass());
+ }
+
+ String accessFailedMessage(Class> refc, MemberName m) {
+ Class> defc = m.getDeclaringClass();
+ int mods = m.getModifiers();
+ if (!VerifyAccess.isClassAccessible(defc, lookupClass()))
+ return "class is not public";
+ if (refc != defc && !VerifyAccess.isClassAccessible(refc, lookupClass()))
+ return "symbolic reference "+refc.getName()+" is not public";
+ if (Modifier.isPublic(mods))
+ return "access to public member failed"; // (how?)
+ else if (allowedModes == PUBLIC)
+ return "member is not public";
+ if (Modifier.isPrivate(mods))
+ return "member is private";
+ if (Modifier.isProtected(mods))
+ return "member is protected";
+ return "member is private to package";
+ }
+
+ void checkSpecialCaller(Class> specialCaller) {
+ if (allowedModes == TRUSTED) return;
+ if (!VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))
+ throw newNoAccessException("no private access for invokespecial",
+ new MemberName(specialCaller), lookupClass());
+ }
+
+ MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) {
+ // The accessing class only has the right to use a protected member
+ // on itself or a subclass. Enforce that restriction, from JVMS 5.4.4, etc.
+ if (!method.isProtected() || method.isStatic()
+ || allowedModes == TRUSTED
+ || VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass()))
+ return mh;
+ else
+ return restrictReceiver(method, mh, lookupClass());
+ }
+ MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class> caller) {
+ assert(!method.isStatic());
+ Class> defc = method.getDeclaringClass(); // receiver type of mh is too wide
+ if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
+ throw newNoAccessException("caller class must be a subclass below the method", method, caller);
+ }
+ MethodType rawType = mh.type();
+ if (rawType.parameterType(0) == caller) return mh;
+ MethodType narrowType = rawType.changeParameterType(0, caller);
+ return MethodHandleImpl.convertArguments(IMPL_TOKEN, mh, narrowType, rawType, null);
+ }
+
+ MethodHandle makeAccessor(Class> refc, String name, Class> type,
+ boolean isStatic, boolean isSetter) throws NoAccessException {
+ MemberName field = resolveOrFail(refc, name, type, isStatic);
+ if (isStatic != field.isStatic())
+ throw newNoAccessException(isStatic
+ ? "expected a static field"
+ : "expected a non-static field",
+ field, lookupClass());
+ return makeAccessor(refc, field, false, isSetter);
+ }
+
+ MethodHandle makeAccessor(Class> refc, MemberName field,
+ boolean trusted, boolean isSetter) throws NoAccessException {
+ assert(field.isField());
+ if (trusted)
+ return MethodHandleImpl.accessField(IMPL_TOKEN, field, isSetter, lookupClassOrNull());
+ checkAccess(refc, field);
+ MethodHandle mh = MethodHandleImpl.accessField(IMPL_TOKEN, field, isSetter, lookupClassOrNull());
+ return restrictProtectedReceiver(field, mh);
}
- if (m.isInvocable())
- return MethodHandleImpl.findMethod(IMPL_TOKEN, m, doDispatch, lookup.lookupClass());
- else if (m.isField())
- return MethodHandleImpl.accessField(IMPL_TOKEN, m, isSetter, lookup.lookupClass());
- else
- throw new InternalError();
}
/**
@@ -667,10 +899,15 @@ public class MethodHandles {
*/
public static
MethodHandle dynamicInvoker(CallSite site) {
- MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, CallSite.GET_TARGET, site);
+ MethodHandle getCSTarget = GET_TARGET;
+ if (getCSTarget == null)
+ GET_TARGET = getCSTarget = Lookup.IMPL_LOOKUP.
+ findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
+ MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, getCSTarget, site);
MethodHandle invoker = exactInvoker(site.type());
return foldArguments(invoker, getTarget);
}
+ private static MethodHandle GET_TARGET = null; // link this lazily, not eagerly
static Invokers invokers(MethodType type) {
return MethodTypeImpl.invokers(IMPL_TOKEN, type);
@@ -1025,15 +1262,15 @@ public class MethodHandles {
*
* The structure is a return type accompanied by any number of parameter types.
* The types (primitive, void, and reference) are represented by Class objects.
+ *
* All instances of
- * This type can be created only by factory methods, which manage interning.
- *
+ * This type can be created only by factory methods.
+ * All factory methods may cache values, though caching is not guaranteed.
+ *
+ * Note: Like classes and strings, method types can be represented directly
+ * as constants to be loaded by {@code ldc} bytecodes.
* @author John Rose, JSR 292 EG
*/
public final
@@ -109,7 +118,7 @@ class MethodType {
/** Find or create an instance of the given method type.
* @param rtype the return type
* @param ptypes the parameter types
- * @return the interned method type with the given parts
+ * @return a method type with the given parts
* @throws NullPointerException if rtype or any ptype is null
* @throws IllegalArgumentException if any of the ptypes is void
*/
@@ -626,7 +635,7 @@ class MethodType {
}
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
- * Find or create an instance (interned) of the given method type.
+ * Find or create an instance of the given method type.
* Any class or interface name embedded in the signature string
* will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
* on the given loader (or if it is null, on the system class loader).
diff --git a/jdk/src/share/classes/java/dyn/NoAccessException.java b/jdk/src/share/classes/java/dyn/NoAccessException.java
index 8547a5d777f..5e76f6a4aae 100644
--- a/jdk/src/share/classes/java/dyn/NoAccessException.java
+++ b/jdk/src/share/classes/java/dyn/NoAccessException.java
@@ -27,11 +27,12 @@ package java.dyn;
/**
* Thrown to indicate that a caller has attempted to create a method handle
- * which calls a method to which the caller does not have access.
+ * which accesses a field, method, or class to which the caller does not have access.
* This unchecked exception is analogous to {@link IllegalAccessException},
* which is a checked exception thrown when reflective invocation fails
* because of an access check. With method handles, this same access
- * checking is performed on behalf of the method handle creator,
+ * checking is performed by the {@link MethodHandles.Lookup lookup object}
+ * on behalf of the method handle creator,
* at the time of creation.
* @author John Rose, JSR 292 EG
*/
diff --git a/jdk/src/share/classes/java/dyn/package-info.java b/jdk/src/share/classes/java/dyn/package-info.java
index a1ed722ff9d..7a285b75d22 100644
--- a/jdk/src/share/classes/java/dyn/package-info.java
+++ b/jdk/src/share/classes/java/dyn/package-info.java
@@ -27,6 +27,105 @@
* PROVISIONAL API, WORK IN PROGRESS:
* This package contains dynamic language support provided directly by
* the Java core class libraries and virtual machine.
+ *
+ * Certain types in this package have special relations to dynamic
+ * language support in the virtual machine:
+ *
+ * As with {@code CONSTANT_Class} and {@code CONSTANT_MethodType} constants,
+ * the {@code Class} or {@code MethodType} object which reifies the field or method's
+ * type is created. Any classes mentioned in this reificaiton will be loaded if necessary,
+ * but not initialized, and access checking and error reporting performed as usual.
+ *
+ * The method handle itself will have a type and behavior determined by the subtag as follows:
+ *
+ * The special names {@code
+ * The verifier applies the same access checks and restrictions for these references as for the hypothetical
+ * bytecode instructions specified in the last column of the table. In particular, method handles to
+ * private and protected members can be created in exactly those classes for which the corresponding
+ * normal accesses are legal.
+ *
+ * None of these constant types force class initialization.
+ * Method handles for subtags {@code REF_getStatic}, {@code REF_putStatic}, and {@code REF_invokeStatic}
+ * may force class initialization on their first invocation, just like the corresponding bytecodes.
+ *
* @author John Rose, JSR 292 EG
*/
diff --git a/jdk/src/share/classes/java/io/Bits.java b/jdk/src/share/classes/java/io/Bits.java
index 4b65d817b18..3554c4fe268 100644
--- a/jdk/src/share/classes/java/io/Bits.java
+++ b/jdk/src/share/classes/java/io/Bits.java
@@ -41,51 +41,39 @@ class Bits {
}
static char getChar(byte[] b, int off) {
- return (char) (((b[off + 1] & 0xFF) << 0) +
- ((b[off + 0]) << 8));
+ return (char) ((b[off + 1] & 0xFF) +
+ (b[off] << 8));
}
static short getShort(byte[] b, int off) {
- return (short) (((b[off + 1] & 0xFF) << 0) +
- ((b[off + 0]) << 8));
+ return (short) ((b[off + 1] & 0xFF) +
+ (b[off] << 8));
}
static int getInt(byte[] b, int off) {
- return ((b[off + 3] & 0xFF) << 0) +
- ((b[off + 2] & 0xFF) << 8) +
+ return ((b[off + 3] & 0xFF) ) +
+ ((b[off + 2] & 0xFF) << 8) +
((b[off + 1] & 0xFF) << 16) +
- ((b[off + 0]) << 24);
+ ((b[off ] ) << 24);
}
static float getFloat(byte[] b, int off) {
- int i = ((b[off + 3] & 0xFF) << 0) +
- ((b[off + 2] & 0xFF) << 8) +
- ((b[off + 1] & 0xFF) << 16) +
- ((b[off + 0]) << 24);
- return Float.intBitsToFloat(i);
+ return Float.intBitsToFloat(getInt(b, off));
}
static long getLong(byte[] b, int off) {
- return ((b[off + 7] & 0xFFL) << 0) +
- ((b[off + 6] & 0xFFL) << 8) +
+ return ((b[off + 7] & 0xFFL) ) +
+ ((b[off + 6] & 0xFFL) << 8) +
((b[off + 5] & 0xFFL) << 16) +
((b[off + 4] & 0xFFL) << 24) +
((b[off + 3] & 0xFFL) << 32) +
((b[off + 2] & 0xFFL) << 40) +
((b[off + 1] & 0xFFL) << 48) +
- (((long) b[off + 0]) << 56);
+ (((long) b[off]) << 56);
}
static double getDouble(byte[] b, int off) {
- long j = ((b[off + 7] & 0xFFL) << 0) +
- ((b[off + 6] & 0xFFL) << 8) +
- ((b[off + 5] & 0xFFL) << 16) +
- ((b[off + 4] & 0xFFL) << 24) +
- ((b[off + 3] & 0xFFL) << 32) +
- ((b[off + 2] & 0xFFL) << 40) +
- ((b[off + 1] & 0xFFL) << 48) +
- (((long) b[off + 0]) << 56);
- return Double.longBitsToDouble(j);
+ return Double.longBitsToDouble(getLong(b, off));
}
/*
@@ -98,50 +86,38 @@ class Bits {
}
static void putChar(byte[] b, int off, char val) {
- b[off + 1] = (byte) (val >>> 0);
- b[off + 0] = (byte) (val >>> 8);
+ b[off + 1] = (byte) (val );
+ b[off ] = (byte) (val >>> 8);
}
static void putShort(byte[] b, int off, short val) {
- b[off + 1] = (byte) (val >>> 0);
- b[off + 0] = (byte) (val >>> 8);
+ b[off + 1] = (byte) (val );
+ b[off ] = (byte) (val >>> 8);
}
static void putInt(byte[] b, int off, int val) {
- b[off + 3] = (byte) (val >>> 0);
- b[off + 2] = (byte) (val >>> 8);
+ b[off + 3] = (byte) (val );
+ b[off + 2] = (byte) (val >>> 8);
b[off + 1] = (byte) (val >>> 16);
- b[off + 0] = (byte) (val >>> 24);
+ b[off ] = (byte) (val >>> 24);
}
static void putFloat(byte[] b, int off, float val) {
- int i = Float.floatToIntBits(val);
- b[off + 3] = (byte) (i >>> 0);
- b[off + 2] = (byte) (i >>> 8);
- b[off + 1] = (byte) (i >>> 16);
- b[off + 0] = (byte) (i >>> 24);
+ putInt(b, off, Float.floatToIntBits(val));
}
static void putLong(byte[] b, int off, long val) {
- b[off + 7] = (byte) (val >>> 0);
- b[off + 6] = (byte) (val >>> 8);
+ b[off + 7] = (byte) (val );
+ b[off + 6] = (byte) (val >>> 8);
b[off + 5] = (byte) (val >>> 16);
b[off + 4] = (byte) (val >>> 24);
b[off + 3] = (byte) (val >>> 32);
b[off + 2] = (byte) (val >>> 40);
b[off + 1] = (byte) (val >>> 48);
- b[off + 0] = (byte) (val >>> 56);
+ b[off ] = (byte) (val >>> 56);
}
static void putDouble(byte[] b, int off, double val) {
- long j = Double.doubleToLongBits(val);
- b[off + 7] = (byte) (j >>> 0);
- b[off + 6] = (byte) (j >>> 8);
- b[off + 5] = (byte) (j >>> 16);
- b[off + 4] = (byte) (j >>> 24);
- b[off + 3] = (byte) (j >>> 32);
- b[off + 2] = (byte) (j >>> 40);
- b[off + 1] = (byte) (j >>> 48);
- b[off + 0] = (byte) (j >>> 56);
+ putLong(b, off, Double.doubleToLongBits(val));
}
}
diff --git a/jdk/src/share/classes/java/io/Closeable.java b/jdk/src/share/classes/java/io/Closeable.java
index e47e70d6cda..0fbb1217cd0 100644
--- a/jdk/src/share/classes/java/io/Closeable.java
+++ b/jdk/src/share/classes/java/io/Closeable.java
@@ -28,14 +28,14 @@ package java.io;
import java.io.IOException;
/**
- * A Closeable is a source or destination of data that can be closed.
+ * A {@code Closeable} is a source or destination of data that can be closed.
* The close method is invoked to release resources that the object is
* holding (such as open files).
*
* @since 1.5
*/
-public interface Closeable {
+public interface Closeable extends AutoCloseable {
/**
* Closes this stream and releases any system resources associated
@@ -45,5 +45,4 @@ public interface Closeable {
* @throws IOException if an I/O error occurs
*/
public void close() throws IOException;
-
}
diff --git a/jdk/src/share/classes/java/io/ObjectInput.java b/jdk/src/share/classes/java/io/ObjectInput.java
index 179760b3d15..3c72518205a 100644
--- a/jdk/src/share/classes/java/io/ObjectInput.java
+++ b/jdk/src/share/classes/java/io/ObjectInput.java
@@ -36,7 +36,7 @@ package java.io;
* @see java.io.ObjectInputStream
* @since JDK1.1
*/
-public interface ObjectInput extends DataInput {
+public interface ObjectInput extends DataInput, AutoCloseable {
/**
* Read and return an object. The class that implements this interface
* defines where the object is "read" from.
diff --git a/jdk/src/share/classes/java/io/ObjectOutput.java b/jdk/src/share/classes/java/io/ObjectOutput.java
index 33426dd39f2..bf55305f388 100644
--- a/jdk/src/share/classes/java/io/ObjectOutput.java
+++ b/jdk/src/share/classes/java/io/ObjectOutput.java
@@ -36,7 +36,7 @@ package java.io;
* @see java.io.ObjectInputStream
* @since JDK1.1
*/
-public interface ObjectOutput extends DataOutput {
+public interface ObjectOutput extends DataOutput, AutoCloseable {
/**
* Write an object to the underlying storage or stream. The
* class that implements this interface defines how the object is
diff --git a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java
index 156937c3767..fad8ad6da66 100644
--- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java
+++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java
@@ -117,7 +117,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* size check or synchronization.
*/
void expandCapacity(int minimumCapacity) {
- int newCapacity = value.length * 2;
+ int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
@@ -721,19 +721,18 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* {@code codePoint} isn't a valid Unicode code point
*/
public AbstractStringBuilder appendCodePoint(int codePoint) {
- if (!Character.isValidCodePoint(codePoint)) {
- throw new IllegalArgumentException();
- }
- int n = 1;
- if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
- n++;
- }
- ensureCapacityInternal(count + n);
- if (n == 1) {
- value[count++] = (char) codePoint;
- } else {
+ final int count = this.count;
+
+ if (Character.isBmpCodePoint(codePoint)) {
+ ensureCapacityInternal(count + 1);
+ value[count] = (char) codePoint;
+ this.count = count + 1;
+ } else if (Character.isValidCodePoint(codePoint)) {
+ ensureCapacityInternal(count + 2);
Character.toSurrogates(codePoint, value, count);
- count += n;
+ this.count = count + 2;
+ } else {
+ throw new IllegalArgumentException();
}
return this;
}
diff --git a/jdk/src/share/classes/java/lang/AssertionError.java b/jdk/src/share/classes/java/lang/AssertionError.java
index 75e8cd8f02d..8fb577a6e32 100644
--- a/jdk/src/share/classes/java/lang/AssertionError.java
+++ b/jdk/src/share/classes/java/lang/AssertionError.java
@@ -66,7 +66,7 @@ public class AssertionError extends Error {
* defined in The Java Language Specification, Second
* Edition, Section 15.18.1.1.
*
- * If the specified object is an instance of Throwable, it
+ * If the specified object is an instance of {@code Throwable}, it
* becomes the cause of the newly constructed assertion error.
*
* @param detailMessage value to be used in constructing detail message
@@ -149,4 +149,21 @@ public class AssertionError extends Error {
public AssertionError(double detailMessage) {
this("" + detailMessage);
}
+
+ /**
+ * Constructs a new {@code AssertionError} with the specified
+ * detail message and cause.
+ *
+ * Note that the detail message associated with
+ * {@code cause} is not automatically incorporated in
+ * this error's detail message.
+ *
+ * @param message the detail message, may be {@code null}
+ * @param cause the cause, may be {@code null}
+ *
+ * @since 1.7
+ */
+ public AssertionError(String message, Throwable cause) {
+ super(message, cause);
+ }
}
diff --git a/jdk/src/share/classes/java/lang/AutoCloseable.java b/jdk/src/share/classes/java/lang/AutoCloseable.java
new file mode 100644
index 00000000000..0f7ed8e0dd6
--- /dev/null
+++ b/jdk/src/share/classes/java/lang/AutoCloseable.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang;
+
+/**
+ * A resource that must be closed when it is no longer needed.
+ *
+ * @author Josh Bloch
+ * @since 1.7
+ */
+public interface AutoCloseable {
+ /**
+ * Close this resource, relinquishing any underlying resources.
+ * This method is invoked automatically by the automatic resource
+ * management block construct.
+ *
+ * Classes implementing this method are strongly encouraged to
+ * be declared to throw more specific exceptions (or no exception
+ * at all, if the close cannot fail).
+ *
+ * @throws Exception if this resource cannot be closed
+ */
+ void close() throws Exception;
+}
diff --git a/jdk/src/share/classes/java/lang/Character.java b/jdk/src/share/classes/java/lang/Character.java
index 48488825d4c..69134bda77f 100644
--- a/jdk/src/share/classes/java/lang/Character.java
+++ b/jdk/src/share/classes/java/lang/Character.java
@@ -24,6 +24,8 @@
*/
package java.lang;
+
+import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;
import java.util.Locale;
@@ -66,17 +68,16 @@ import java.util.Locale;
* definition of the U+n notation in the Unicode
* standard.)
*
- * The set of characters from U+0000 to U+FFFF is sometimes
- * referred to as the Basic Multilingual Plane (BMP). Characters whose code points are greater
+ * The set of characters from U+0000 to U+FFFF is
+ * sometimes referred to as the Basic Multilingual Plane (BMP).
+ * Characters whose code points are greater
* than U+FFFF are called supplementary characters. The Java
- * 2 platform uses the UTF-16 representation in A Note: This method cannot handle supplementary
- * characters. To support all Unicode characters,
- * including supplementary characters, use the {@link
- * #of(int)} method.
+ * Note: This method cannot handle
+ * supplementary
+ * characters. To support all Unicode characters, including
+ * supplementary characters, use the {@link #of(int)} method.
*
* @param c The character in question
* @return The
+ * Character case is ignored for all of the valid script names.
+ * The en_US locale's case mapping rules are used to provide
+ * case-insensitive string comparisons for script name validation.
+ *
+ *
+ * @param scriptName A If
+ * {@link #isSupplementaryCodePoint isSupplementaryCodePoint(x)}
+ * is {@code true}, then
+ * {@link #isHighSurrogate isHighSurrogate}{@code (highSurrogate(x))} and
+ * {@link #toCodePoint toCodePoint}{@code (highSurrogate(x), }{@link #lowSurrogate lowSurrogate}{@code (x)) == x}
+ * are also always {@code true}.
+ *
+ * @param codePoint a supplementary character (Unicode code point)
+ * @return the leading surrogate code unit used to represent the
+ * character in the UTF-16 encoding
+ * @since 1.7
+ */
+ public static char highSurrogate(int codePoint) {
+ return (char) ((codePoint >>> 10)
+ + (MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10)));
+ }
+
+ /**
+ * Returns the trailing surrogate (a
+ *
+ * low surrogate code unit) of the
+ *
+ * surrogate pair
+ * representing the specified supplementary character (Unicode
+ * code point) in the UTF-16 encoding. If the specified character
+ * is not a
+ * supplementary character,
+ * an unspecified {@code char} is returned.
+ *
+ * If
+ * {@link #isSupplementaryCodePoint isSupplementaryCodePoint(x)}
+ * is {@code true}, then
+ * {@link #isLowSurrogate isLowSurrogate}{@code (lowSurrogate(x))} and
+ * {@link #toCodePoint toCodePoint}{@code (}{@link #highSurrogate highSurrogate}{@code (x), lowSurrogate(x)) == x}
+ * are also always {@code true}.
+ *
+ * @param codePoint a supplementary character (Unicode code point)
+ * @return the trailing surrogate code unit used to represent the
+ * character in the UTF-16 encoding
+ * @since 1.7
+ */
+ public static char lowSurrogate(int codePoint) {
+ return (char) ((codePoint & 0x3ff) + MIN_LOW_SURROGATE);
+ }
+
/**
* Converts the specified character (Unicode code point) to its
* UTF-16 representation. If the specified code point is a BMP
@@ -3075,15 +4486,15 @@ class Character extends Object implements java.io.Serializable, Comparable
* A character is uppercase if its general category type, provided by
@@ -3422,10 +4826,10 @@ class Character extends Object implements java.io.Serializable, Comparable
-
@@ -81,16 +81,16 @@ a:visited,a:visited code{color:#917E9C}
-
- You need to be connected to the Internet to register this Sun product.
+ You need to be connected to the Internet to register this Oracle product.
-
+ For more information on Oracle's Privacy Policy see http://www.oracle.com/html/privacy.html or contact privacy_ww@oracle.com.
- see http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html.
+ see http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html.
- For more information on Sun's Privacy Policy see http://www.sun.com/privacy/ or contact privacy@sun.com.
diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html b/jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html
index dae43771227..3da70723ef8 100644
--- a/jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html
+++ b/jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html
@@ -50,11 +50,11 @@ a:visited,a:visited code{color:#917E9C}
-
@@ -75,8 +75,8 @@ a:visited,a:visited code{color:#917E9C}
-
-
+
http://java.sun.com/javase/ja/registration/JDKRegistrationPrivacy.html ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
Sun ã®ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ã«ã¤ã„ã¦ã®è©³ç´°ã¯ã€http://jp.sun.com/privacy/ ã‚’å‚ç…§ã™ã‚‹ã‹ã€ãŠå•ã„åˆã‚ã›ãƒ•ã‚©ãƒ¼ãƒ ã‹ã‚‰ãŠå•ã„åˆã‚ã›ãã ã•ã„。
http://java.sun.com/javase/ja/registration/JDKRegistrationPrivacy.html ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
Oracle ã®ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ã«ã¤ã„ã¦ã®è©³ç´°ã¯ã€http://www.oracle.com/html/privacy.html ã‚’å‚ç…§ã™ã‚‹ã‹ã€ãŠå•ã„åˆã‚ã›ãƒ•ã‚©ãƒ¼ãƒ ã‹ã‚‰ãŠå•ã„åˆã‚ã›ãã ã•ã„。
diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html b/jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html
index dfc24dc9407..f5bad110b4f 100644
--- a/jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html
+++ b/jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html
@@ -51,11 +51,11 @@ a:visited,a:visited code{color:#917E9C}
-
@@ -76,8 +76,8 @@ a:visited,a:visited code{color:#917E9C}
-
-您需è¦è¿žæŽ¥åˆ° Internet æ¥æ³¨å†Œæ¤ Sun 产å“。
+您需è¦è¿žæŽ¥åˆ° Internet æ¥æ³¨å†Œæ¤ Oracle 产å“。
-
+
请访问 http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html。
有关 Sun éšç§æ”¿ç–的更多信æ¯ï¼Œè¯·è®¿é—® http://www.sun.com/privacy/ 或与 privacy@sun.com è”系。
请访问 http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html。
有关 Oracle éšç§æ”¿ç–的更多信æ¯ï¼Œè¯·è®¿é—® http://www.oracle.com/html/privacy.html 或与 privacy_ww@oracle.com è”系。
diff --git a/jdk/src/share/classes/java/awt/EventDispatchThread.java b/jdk/src/share/classes/java/awt/EventDispatchThread.java
index 3c290fdc756..eed2c16e514 100644
--- a/jdk/src/share/classes/java/awt/EventDispatchThread.java
+++ b/jdk/src/share/classes/java/awt/EventDispatchThread.java
@@ -61,85 +61,43 @@ import sun.awt.EventQueueDelegate;
* @since 1.1
*/
class EventDispatchThread extends Thread {
+
private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");
private EventQueue theQueue;
private boolean doDispatch = true;
+ private boolean threadDeathCaught = false;
+
private static final int ANY_EVENT = -1;
private Vectorjava.awt.AWTEvent
,
* or a subclass of it
*/
- final void postEventPrivate(AWTEvent theEvent) {
+ private final void postEventPrivate(AWTEvent theEvent) {
theEvent.isPosted = true;
pushPopLock.lock();
try {
- if (dispatchThread == null && nextQueue == null) {
+ if (nextQueue != null) {
+ // Forward the event to the top of EventQueue stack
+ nextQueue.postEventPrivate(theEvent);
+ return;
+ }
+ if (dispatchThread == null) {
if (theEvent.getSource() == AWTAutoShutdown.getInstance()) {
return;
} else {
initDispatchThread();
}
}
- if (nextQueue != null) {
- // Forward event to top of EventQueue stack.
- nextQueue.postEventPrivate(theEvent);
- return;
- }
postEvent(theEvent, getPriority(theEvent));
} finally {
pushPopLock.unlock();
@@ -242,29 +251,20 @@ public class EventQueue {
}
private static int getPriority(AWTEvent theEvent) {
- if (theEvent instanceof PeerEvent &&
- (((PeerEvent)theEvent).getFlags() &
- PeerEvent.ULTIMATE_PRIORITY_EVENT) != 0)
- {
- return ULTIMATE_PRIORITY;
+ if (theEvent instanceof PeerEvent) {
+ PeerEvent peerEvent = (PeerEvent)theEvent;
+ if ((peerEvent.getFlags() & PeerEvent.ULTIMATE_PRIORITY_EVENT) != 0) {
+ return ULTIMATE_PRIORITY;
+ }
+ if ((peerEvent.getFlags() & PeerEvent.PRIORITY_EVENT) != 0) {
+ return HIGH_PRIORITY;
+ }
+ if ((peerEvent.getFlags() & PeerEvent.LOW_PRIORITY_EVENT) != 0) {
+ return LOW_PRIORITY;
+ }
}
-
- if (theEvent instanceof PeerEvent &&
- (((PeerEvent)theEvent).getFlags() &
- PeerEvent.PRIORITY_EVENT) != 0)
- {
- return HIGH_PRIORITY;
- }
-
- if (theEvent instanceof PeerEvent &&
- (((PeerEvent)theEvent).getFlags() &
- PeerEvent.LOW_PRIORITY_EVENT) != 0)
- {
- return LOW_PRIORITY;
- }
-
int id = theEvent.getID();
- if (id == PaintEvent.PAINT || id == PaintEvent.UPDATE) {
+ if ((id >= PaintEvent.PAINT_FIRST) && (id <= PaintEvent.PAINT_LAST)) {
return LOW_PRIORITY;
}
return NORM_PRIORITY;
@@ -501,16 +501,9 @@ public class EventQueue {
SunToolkit.flushPendingEvents();
pushPopLock.lock();
try {
- for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
- if (queues[i].head != null) {
- EventQueueItem entry = queues[i].head;
- queues[i].head = entry.next;
- if (entry.next == null) {
- queues[i].tail = null;
- }
- uncacheEQItem(entry);
- return entry.event;
- }
+ AWTEvent event = getNextEventPrivate();
+ if (event != null) {
+ return event;
}
AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread);
pushPopCond.await();
@@ -520,6 +513,24 @@ public class EventQueue {
} while(true);
}
+ /*
+ * Must be called under the lock. Doesn't call flushPendingEvents()
+ */
+ AWTEvent getNextEventPrivate() throws InterruptedException {
+ for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
+ if (queues[i].head != null) {
+ EventQueueItem entry = queues[i].head;
+ queues[i].head = entry.next;
+ if (entry.next == null) {
+ queues[i].tail = null;
+ }
+ uncacheEQItem(entry);
+ return entry.event;
+ }
+ }
+ return null;
+ }
+
AWTEvent getNextEvent(int id) throws InterruptedException {
do {
/*
@@ -659,7 +670,9 @@ public class EventQueue {
dispatchThread.stopDispatching();
}
} else {
- System.err.println("unable to dispatch event: " + event);
+ if (eventLog.isLoggable(PlatformLogger.FINE)) {
+ eventLog.fine("Unable to dispatch event: " + event);
+ }
}
}
@@ -761,15 +774,23 @@ public class EventQueue {
pushPopLock.lock();
try {
- EventQueue toPush = this;
- while (toPush.nextQueue != null) {
- toPush = toPush.nextQueue;
+ EventQueue topQueue = this;
+ while (topQueue.nextQueue != null) {
+ topQueue = topQueue.nextQueue;
+ }
+
+ if ((topQueue.dispatchThread != null) &&
+ (topQueue.dispatchThread.getEventQueue() == this))
+ {
+ newEventQueue.dispatchThread = topQueue.dispatchThread;
+ topQueue.dispatchThread.setEventQueue(newEventQueue);
}
// Transfer all events forward to new EventQueue.
- while (toPush.peekEvent() != null) {
+ while (topQueue.peekEvent() != null) {
try {
- newEventQueue.postEventPrivate(toPush.getNextEvent());
+ // Use getNextEventPrivate() as it doesn't call flushPendingEvents()
+ newEventQueue.postEventPrivate(topQueue.getNextEventPrivate());
} catch (InterruptedException ie) {
if (eventLog.isLoggable(PlatformLogger.FINE)) {
eventLog.fine("Interrupted push", ie);
@@ -777,28 +798,21 @@ public class EventQueue {
}
}
- newEventQueue.previousQueue = toPush;
+ // Wake up EDT waiting in getNextEvent(), so it can
+ // pick up a new EventQueue. Post the waking event before
+ // topQueue.nextQueue is assigned, otherwise the event would
+ // go newEventQueue
+ topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
- /*
- * 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();
- }
-
- toPush.nextQueue = newEventQueue;
+ newEventQueue.previousQueue = topQueue;
+ topQueue.nextQueue = newEventQueue;
AppContext appContext = AppContext.getAppContext();
- if (appContext.get(AppContext.EVENT_QUEUE_KEY) == toPush) {
+ if (appContext.get(AppContext.EVENT_QUEUE_KEY) == topQueue) {
appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue);
}
+
+ pushPopCond.signalAll();
} finally {
pushPopLock.unlock();
}
@@ -822,44 +836,51 @@ public class EventQueue {
eventLog.fine("EventQueue.pop(" + this + ")");
}
- EventDispatchThread dt = null;
pushPopLock.lock();
try {
- EventQueue toPop = this;
- while (toPop.nextQueue != null) {
- toPop = toPop.nextQueue;
+ EventQueue topQueue = this;
+ while (topQueue.nextQueue != null) {
+ topQueue = topQueue.nextQueue;
}
- EventQueue prev = toPop.previousQueue;
- if (prev == null) {
+ EventQueue prevQueue = topQueue.previousQueue;
+ if (prevQueue == null) {
throw new EmptyStackException();
}
- toPop.previousQueue = null;
+
+ topQueue.previousQueue = null;
+ prevQueue.nextQueue = null;
// Transfer all events back to previous EventQueue.
- prev.nextQueue = null;
- while (toPop.peekEvent() != null) {
+ while (topQueue.peekEvent() != null) {
try {
- prev.postEventPrivate(toPop.getNextEvent());
+ prevQueue.postEventPrivate(topQueue.getNextEventPrivate());
} catch (InterruptedException ie) {
if (eventLog.isLoggable(PlatformLogger.FINE)) {
eventLog.fine("Interrupted pop", ie);
}
}
}
- AppContext appContext = AppContext.getAppContext();
- if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) {
- appContext.put(AppContext.EVENT_QUEUE_KEY, prev);
+
+ if ((topQueue.dispatchThread != null) &&
+ (topQueue.dispatchThread.getEventQueue() == this))
+ {
+ prevQueue.dispatchThread = topQueue.dispatchThread;
+ topQueue.dispatchThread.setEventQueue(prevQueue);
}
- dt = toPop.dispatchThread;
+ AppContext appContext = AppContext.getAppContext();
+ if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) {
+ appContext.put(AppContext.EVENT_QUEUE_KEY, prevQueue);
+ }
+
+ // Wake up EDT waiting in getNextEvent(), so it can
+ // pick up a new EventQueue
+ topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
+
+ pushPopCond.signalAll();
} finally {
pushPopLock.unlock();
}
-
- if (dt != null) {
- dt.stopDispatching(); // Must be done outside synchronized
- // block to avoid possible deadlock
- }
}
/**
@@ -907,9 +928,9 @@ public class EventQueue {
try {
AppContext appContext = AppContext.getAppContext();
if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) {
- dispatchThread = (EventDispatchThread)
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
+ dispatchThread = AccessController.doPrivileged(
+ new PrivilegedActioninvokedynamic
instruction, and vice versa.
- * Every call site has one state variable, called the {@code target}.
- * It is typed as a {@link MethodHandle}. This state is never null, and
- * it is the responsibility of the bootstrap method to produce call sites
- * which have been pre-linked to an initial target method.
+ * A {@code CallSite} reifies an {@code invokedynamic} instruction from bytecode,
+ * and controls its linkage.
+ * Every linked {@code CallSite} object corresponds to a distinct instance
+ * of the {@code invokedynamic} instruction, and vice versa.
*
* @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
* @author John Rose, JSR 292 EG
*/
public class CallSite
- // Note: This is an implementation inheritance hack, and will be removed
- // with a JVM change which moves the required hidden state onto this class.
- extends CallSiteImpl
{
private static final Access IMPL_TOKEN = Access.getToken();
- /*
-
// Fields used only by the JVM. Do not use or change.
- private Object vmmethod;
- int callerMID, callerBCI; // supplied by the JVM
+ private MemberName vmmethod; // supplied by the JVM (ref. to calling method)
+ private int vmindex; // supplied by the JVM (BCI within calling method)
+ // The actual payload of this call site:
private MethodHandle target;
- final Object caller; // usually a class
- final String name;
- final MethodType type;
- */
+ // Remove this field for PFD and delete deprecated methods:
+ private MemberName calleeNameRemoveForPFD;
/**
- * Make a call site given the parameters from a call to the bootstrap method.
- * The resulting call site is in an unlinked state, which means that before
- * it is returned from a bootstrap method call it must be provided with
- * a target method via a call to {@link CallSite#setTarget}.
- * @param caller the class in which the relevant {@code invokedynamic} instruction occurs
- * @param name the name specified by the {@code invokedynamic} instruction
- * @param type the method handle type derived from descriptor of the {@code invokedynamic} instruction
+ * Make a blank call site object.
+ * Before it is returned from a bootstrap method, this {@code CallSite} object
+ * must be provided with
+ * a target method via a call to {@link CallSite#setTarget(MethodHandle) setTarget},
+ * or by a subclass override of {@link CallSite#initialTarget(Class,String,MethodType) initialTarget}.
*/
- public CallSite(Object caller, String name, MethodType type) {
- super(IMPL_TOKEN, caller, name, type);
+ public CallSite() {
}
- private static void privateInitializeCallSite(CallSite site, int callerMID, int callerBCI) {
- site.callerMID = callerMID;
- site.callerBCI = callerBCI;
- site.ensureTarget();
+ /**
+ * Make a blank call site object, possibly equipped with an initial target method handle.
+ * The initial target reference may be null, in which case the {@code CallSite} object
+ * must be provided with a target method via a call to {@link CallSite#setTarget},
+ * or by a subclass override of {@link CallSite#initialTarget}.
+ * @param target the method handle which will be the initial target of the call site, or null if there is none yet
+ */
+ public CallSite(MethodHandle target) {
+ this.target = target;
}
- private void ensureTarget() {
- // Note use of super, which accesses the field directly,
- // without deferring to possible subclass overrides.
- if (super.getTarget() == null) {
- super.setTarget(this.initialTarget());
- super.getTarget().type(); // provoke NPE if still null
+
+ /** @deprecated transitional form defined in EDR but removed in PFD */
+ public CallSite(Class> caller, String name, MethodType type) {
+ this.calleeNameRemoveForPFD = new MemberName(caller, name, type);
+ }
+ /** @deprecated transitional form defined in EDR but removed in PFD */
+ public Class> callerClass() {
+ MemberName callee = this.calleeNameRemoveForPFD;
+ return callee == null ? null : callee.getDeclaringClass();
+ }
+ /** @deprecated transitional form defined in EDR but removed in PFD */
+ public String name() {
+ MemberName callee = this.calleeNameRemoveForPFD;
+ return callee == null ? null : callee.getName();
+ }
+ /** @deprecated transitional form defined in EDR but removed in PFD */
+ public MethodType type() {
+ MemberName callee = this.calleeNameRemoveForPFD;
+ return callee == null ? (target == null ? null : target.type()) : callee.getMethodType();
+ }
+ /** @deprecated transitional form defined in EDR but removed in PFD */
+ protected MethodHandle initialTarget() {
+ return initialTarget(callerClass(), name(), type());
+ }
+
+ /** Report if the JVM has linked this {@code CallSite} object to a dynamic call site instruction.
+ * Once it is linked, it is never unlinked.
+ */
+ private boolean isLinked() {
+ return vmmethod != null;
+ }
+
+ /** Called from JVM (or low-level Java code) after the BSM returns the newly created CallSite.
+ * The parameters are JVM-specific.
+ */
+ void initializeFromJVM(String name,
+ MethodType type,
+ MemberName callerMethod,
+ int callerBCI) {
+ if (this.isLinked()) {
+ throw new InvokeDynamicBootstrapError("call site has already been linked to an invokedynamic instruction");
}
+ MethodHandle target = this.target;
+ if (target == null) {
+ this.target = target = this.initialTarget(callerMethod.getDeclaringClass(), name, type);
+ }
+ if (!target.type().equals(type)) {
+ throw wrongTargetType(target, type);
+ }
+ this.vmindex = callerBCI;
+ this.vmmethod = callerMethod;
+ assert(this.isLinked());
}
/**
@@ -108,14 +200,18 @@ public class CallSite
* the method {@code initialTarget} is called to produce an initial
* non-null target. (Live call sites must never have null targets.)
*
+private static void printArgs(Object... args) {
+ System.out.println(java.util.Arrays.deepToString(args));
+}
+private static final MethodHandle printArgs;
+static {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ Class thisClass = lookup.lookupClass(); // (who am I?)
+ printArgs = lookup.findStatic(thisClass,
+ "printArgs", MethodType.methodType(void.class, Object[].class));
+ Linkage.registerBootstrapMethod("bootstrapDynamic");
+}
+private static CallSite bootstrapDynamic(Class caller, String name, MethodType type) {
+ // ignore caller and name, but match the type:
+ return new CallSite(MethodHandles.collectArguments(printArgs, type));
+}
+
*
* Object x; String s; int i;
* x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object;
@@ -65,6 +63,7 @@ package java.dyn;
* which must be registered by the static initializer of the enclosing class.
* @author John Rose, JSR 292 EG
*/
+@MethodHandle.PolymorphicSignature
public final class InvokeDynamic {
private InvokeDynamic() { throw new InternalError(); } // do not instantiate
diff --git a/jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java b/jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
index e0517361ecf..83ebcd464b4 100644
--- a/jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
+++ b/jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,24 +27,29 @@ package java.dyn;
/**
* Thrown to indicate that an {@code invokedynamic} instruction has
- * failed to find its bootstrap method, or the bootstrap method has
- * failed to provide a call site with a non-null target.
+ * failed to find its
+ * {@linkplain Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method},
+ * or the bootstrap method has
+ * failed to provide a
+ * {@linkplain CallSite} call site with a non-null {@linkplain MethodHandle target}
+ * of the correct {@linkplain MethodType method type}.
*
@@ -101,7 +102,7 @@ import sun.dyn.Access;
* Greeter greeter = new Greeter("world");
* greeter.run(); // prints "hello, world"
* MethodHandle mh = MethodHanndles.insertArgument(Greeter.RUN, 0, greeter);
- * mh.invoke(); // also prints "hello, world"
+ * mh.invokeExact(); // also prints "hello, world"
*
* Note that the method handle must be separately created as a view on the base object.
* This increases footprint, complexity, and dynamic indirections.
@@ -113,7 +114,7 @@ import sun.dyn.Access;
* MethodHandle greeter = new JavaMethodHandle("run") {
* private void run() { System.out.println("hello, "+greetee); }
* }
- * greeter.invoke(); // prints "hello, world"
+ * greeter.invokeExact(); // prints "hello, world"
*
*
* // We can also do this with symbolic names and/or inner classes:
- * MethodHandles.invoke(new JavaMethodHandle("yow") {
+ * MethodHandles.invokeExact(new JavaMethodHandle("yow") {
* void yow() { System.out.println("yow, world"); }
* });
*
+ *
+ * (TBD: The final argument type may be missing from the method handle's type.
+ * Additional arguments may be added in the future.)
+ * The bootstrap method acts as a factory method which accepts the given arguments
* and returns a {@code CallSite} object (possibly of a subclass of {@code CallSite}).
*
- *
* Because of these rules, a class may install its own bootstrap method in
* a static initializer.
* @param callerClass a class that may have {@code invokedynamic} sites
* @param bootstrapMethod the method to use to bootstrap all such sites
+ * @exception IllegalArgumentException if the class argument is null or
+ * a primitive class, or if the bootstrap method is the wrong type
+ * @exception IllegalStateException if the class already has a bootstrap
+ * method, or if the its static initializer has already run
+ * or is already running in another thread
+ * @exception SecurityException if there is a security manager installed,
+ * and a {@link LinkagePermission} check fails for "registerBootstrapMethod"
*/
public static
void registerBootstrapMethod(Class callerClass, MethodHandle bootstrapMethod) {
Class callc = Reflection.getCallerClass(2);
checkBootstrapPrivilege(callc, callerClass, "registerBootstrapMethod");
checkBSM(bootstrapMethod);
- synchronized (bootstrapMethods) {
- if (bootstrapMethods.containsKey(callerClass))
- throw new IllegalStateException("bootstrap method already declared in "+callerClass);
- bootstrapMethods.put(callerClass, bootstrapMethod);
- }
+ MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
}
- static void checkBSM(MethodHandle mh) {
- if (mh == null) throw new IllegalArgumentException("null bootstrap method");
- if (mh.type() == OLD_BOOTSTRAP_METHOD_TYPE) // FIXME: delete at EDR/PFD
- throw new WrongMethodTypeException("bootstrap method must be a CallSite factory");
- if (mh.type() != BOOTSTRAP_METHOD_TYPE)
- throw new WrongMethodTypeException(mh.toString());
+ static private void checkBSM(MethodHandle mh) {
+ if (mh == null) throw newIllegalArgumentException("null bootstrap method");
+ if (mh.type() == BOOTSTRAP_METHOD_TYPE_2)
+ // For now, always pass an empty array for the Annotations argument
+ mh = MethodHandles.insertArguments(mh, BOOTSTRAP_METHOD_TYPE_2.parameterCount()-1,
+ (Object)NO_ANNOTATIONS);
+ if (mh.type() == BOOTSTRAP_METHOD_TYPE) return;
+ throw new WrongMethodTypeException(mh.toString());
}
+ static private final Annotation[] NO_ANNOTATIONS = { };
/**
* PROVISIONAL API, WORK IN PROGRESS:
- * Simplified version of registerBootstrapMethod for self-registration,
+ * Simplified version of {@code registerBootstrapMethod} for self-registration,
* to be called from a static initializer.
* Finds a static method of the required type in the
- * given class, and installs it on the caller.
- * @throws IllegalArgumentException if there is no such method
+ * given runtime class, and installs it on the caller class.
+ * @throws NoSuchMethodException if there is no such method
+ * @throws IllegalStateException if the caller class's static initializer
+ * has already run, or is already running in another thread
*/
public static
void registerBootstrapMethod(Class> runtime, String name) {
- Class callc = Reflection.getCallerClass(2);
- Lookup lookup = new Lookup(IMPL_TOKEN, callc);
- MethodHandle bootstrapMethod =
- lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
- // FIXME: exception processing wrong here
- checkBSM(bootstrapMethod);
- Linkage.registerBootstrapMethod(callc, bootstrapMethod);
+ Class callerClass = Reflection.getCallerClass(2);
+ registerBootstrapMethodLookup(callerClass, runtime, name);
}
/**
* PROVISIONAL API, WORK IN PROGRESS:
- * Simplified version of registerBootstrapMethod for self-registration,
+ * Simplified version of {@code registerBootstrapMethod} for self-registration,
* to be called from a static initializer.
* Finds a static method of the required type in the
- * caller's class, and installs it on the caller.
+ * caller class itself, and installs it on the caller class.
* @throws IllegalArgumentException if there is no such method
+ * @throws IllegalStateException if the caller class's static initializer
+ * has already run, or is already running in another thread
*/
public static
void registerBootstrapMethod(String name) {
- Class callc = Reflection.getCallerClass(2);
- Lookup lookup = new Lookup(IMPL_TOKEN, callc);
- MethodHandle bootstrapMethod =
- lookup.findStatic(callc, name, BOOTSTRAP_METHOD_TYPE);
- // FIXME: exception processing wrong here
+ Class callerClass = Reflection.getCallerClass(2);
+ registerBootstrapMethodLookup(callerClass, callerClass, name);
+ }
+
+ private static
+ void registerBootstrapMethodLookup(Class> callerClass, Class> runtime, String name) {
+ Lookup lookup = new Lookup(IMPL_TOKEN, callerClass);
+ MethodHandle bootstrapMethod;
+ // Try both types. TBD
+ try {
+ bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE_2);
+ } catch (NoAccessException ex) {
+ bootstrapMethod = null;
+ }
+ if (bootstrapMethod == null) {
+ try {
+ bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
+ } catch (NoAccessException ex) {
+ throw new IllegalArgumentException("no such bootstrap method in "+runtime+": "+name, ex);
+ }
+ }
checkBSM(bootstrapMethod);
- Linkage.registerBootstrapMethod(callc, bootstrapMethod);
+ MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
}
/**
* PROVISIONAL API, WORK IN PROGRESS:
- * Report the bootstrap method registered for a given class.
+ * Report the bootstrap method registered for a given caller class.
* Returns null if the class has never yet registered a bootstrap method.
* Only callers privileged to set the bootstrap method may inquire
* about it, because a bootstrap method is potentially a back-door entry
* point into its class.
+ * @exception IllegalArgumentException if the argument is null or
+ * a primitive class
+ * @exception SecurityException if there is a security manager installed,
+ * and the immediate caller of this method is not in the same
+ * package as the caller class
+ * and a {@link LinkagePermission} check fails for "getBootstrapMethod"
*/
public static
MethodHandle getBootstrapMethod(Class callerClass) {
Class callc = Reflection.getCallerClass(2);
- checkBootstrapPrivilege(callc, callerClass, "registerBootstrapMethod");
- synchronized (bootstrapMethods) {
- return bootstrapMethods.get(callerClass);
- }
+ checkBootstrapPrivilege(callc, callerClass, "getBootstrapMethod");
+ return MethodHandleImpl.getBootstrap(IMPL_TOKEN, callerClass);
}
/**
@@ -148,13 +188,10 @@ public class Linkage {
public static final MethodType BOOTSTRAP_METHOD_TYPE
= MethodType.methodType(CallSite.class,
Class.class, String.class, MethodType.class);
-
- private static final MethodType OLD_BOOTSTRAP_METHOD_TYPE
- = MethodType.methodType(Object.class,
- CallSite.class, Object[].class);
-
- private static final WeakHashMapinvokedynamic
call sites in the bytecodes
+ * Invalidate all {@code invokedynamic} call sites in the bytecodes
* of any methods of the given class.
- * (These are exactly those sites which report the given class
- * via the {@link CallSite#callerClass()} method.)
* invokedynamic
* instruction will invoke its bootstrap method on next call.
@@ -201,18 +236,4 @@ public class Linkage {
}
throw new UnsupportedOperationException("NYI");
}
-
- private static Object doNotBootstrap(CallSite site, Object... arguments) {
- throw new UnsupportedOperationException("call site must not have null target: "+site);
- }
-
- private static final MethodHandle DO_NOT_BOOTSTRAP =
- MethodHandles.Lookup.IMPL_LOOKUP.findStatic(Linkage.class, "doNotBootstrap",
- OLD_BOOTSTRAP_METHOD_TYPE);
-
- // Up-call from the JVM. Obsolete. FIXME: Delete from VM then from here.
- static
- MethodHandle findBootstrapMethod(Class callerClass, Class searchBootstrapClass) {
- return DO_NOT_BOOTSTRAP;
- }
}
diff --git a/jdk/src/share/classes/java/dyn/LinkagePermission.java b/jdk/src/share/classes/java/dyn/LinkagePermission.java
index ab4ce04dd2b..4478d959853 100644
--- a/jdk/src/share/classes/java/dyn/LinkagePermission.java
+++ b/jdk/src/share/classes/java/dyn/LinkagePermission.java
@@ -31,23 +31,17 @@ import java.util.Hashtable;
import java.util.StringTokenizer;
/**
- * This class is for runtime permissions. A RuntimePermission
- * contains a name (also referred to as a "target name") but
+ * This class is for managing runtime permission checking for
+ * operations performed by methods in the {@link Linkage} class.
+ * Like a {@link RuntimePermission}, on which it is modeled,
+ * a {@code LinkagePermission} contains a target name but
* no actions list; you either have the named permission
* or you don't.
- *
- *
@@ -59,15 +53,17 @@ import java.util.StringTokenizer;
*
*
*
- * @see java.security.BasicPermission
+ * @see java.security.RuntimePermission
* @see java.lang.SecurityManager
*
* @author John Rose, JSR 292 EG
diff --git a/jdk/src/share/classes/java/dyn/MethodHandle.java b/jdk/src/share/classes/java/dyn/MethodHandle.java
index 25d575b9f25..20387ca6859 100644
--- a/jdk/src/share/classes/java/dyn/MethodHandle.java
+++ b/jdk/src/share/classes/java/dyn/MethodHandle.java
@@ -34,32 +34,34 @@ import static java.dyn.MethodHandles.invokers; // package-private API
import static sun.dyn.MemberName.newIllegalArgumentException; // utility
/**
- * A method handle is a typed reference to the entry point of a method.
+ * A method handle is a typed, directly executable reference to a method,
+ * constructor, field, or similar low-level operation, with optional
+ * conversion or substitution of arguments or return values.
*
*
*
* registerBootstrapMethod.{class name}
- * Specifying a bootstrap method for invokedynamic, within a class of the given name
+ * Specifying a bootstrap method for {@code invokedynamic} instructions within a class of the given name
* An attacker could attempt to attach a bootstrap method to a class which
- * has just been loaded, thus gaining control of its invokedynamic calls.
+ * has just been loaded, thus gaining control of its {@code invokedynamic} calls.
*
*
*
*
@@ -78,7 +74,7 @@ import java.util.StringTokenizer;
*
* invalidateAll
* Force the relinking of invokedynamic call sites everywhere.
- * This could allow an attacker to slow down the system, or perhaps surface timing bugs in a dynamic language implementations, by forcing redundant relinking operations.
+ * This could allow an attacker to slow down the system,
+ * or perhaps expose timing bugs in a dynamic language implementations,
+ * by forcing redundant relinking operations.
* type
accessor.
+ * Every method handle confesses its type via the {@code type} accessor.
* The structure of this type is a series of classes, one of which is
- * the return type of the method (or void.class
if none).
+ * the return type of the method (or {@code void.class} if none).
* invoke
, whose signature exactly matches
+ * {@code invoke}, whose signature exactly matches
* the method handle's type.
* A Java method call expression, which compiles to an
- * invokevirtual
instruction,
+ * {@code invokevirtual} instruction,
* can invoke this method from Java source code.
* invokevirtual
instruction,
+ * (The type is specified in the {@code invokevirtual} instruction,
* via a {@code CONSTANT_NameAndType} constant pool entry.)
* The call looks within the receiver object for a method
- * named invoke
of the intended method type.
+ * named {@code invoke} of the intended method type.
* The call fails with a {@link WrongMethodTypeException}
- * if the method does not exist, even if there is an invoke
+ * if the method does not exist, even if there is an {@code invoke}
* method of a closely similar signature.
* As with other kinds
* of methods in the JVM, signature matching during method linkage
@@ -76,13 +78,13 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* They should not be passed to untrusted code.
* invoke
from an invokevirtual
instruction.
- * The receiver class type must be MethodHandle
and the method name
- * must be invoke
. The signature of the invocation
+ * {@code invoke} from an {@code invokevirtual} instruction.
+ * The receiver class type must be {@code MethodHandle} and the method name
+ * must be {@code invoke}. The signature of the invocation
* (after resolving symbolic type names) must exactly match the method type
* of the target method.
* invoke
method always throws {@link Exception},
+ * Every {@code invoke} method always throws {@link Exception},
* which is to say that there is no static restriction on what a method handle
* can throw. Since the JVM does not distinguish between checked
* and unchecked exceptions (other than by their class, of course),
@@ -92,11 +94,11 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* throw {@code Exception}, or else must catch all checked exceptions locally.
* ldc
instruction
- * which refers to a CONSTANT_Methodref
or
- * CONSTANT_InterfaceMethodref
constant pool entry.
+ * for any accessible method from a {@code ldc} instruction
+ * which refers to a {@code CONSTANT_Methodref} or
+ * {@code CONSTANT_InterfaceMethodref} constant pool entry.
* MethodHandles
+ * All JVMs can also use a reflective API called {@code MethodHandles}
* for creating and calling method handles.
* ldc
,
+ * (E.g., if a non-static method handle is obtained via {@code ldc},
* the type of the receiver is the class named in the constant pool entry.)
* invokespecial
instruction to the same method.
+ * an {@code invokespecial} instruction to the same method.
*
* Each of the above calls generates a single invokevirtual instruction
* with the name {@code invoke} and the type descriptors indicated in the comments.
@@ -167,6 +169,14 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* those of multiple arities. It is impossible to represent such
* genericity with a Java type parameter.
*
+ * Signature polymorphic methods in this class appear to be documented
+ * as having type parameters for return types and a parameter, but that is
+ * merely a documentation convention. These type parameters do
+ * not play a role in type-checking method handle invocations.
+ *
- * Object x, y; String s; int i;
- * MethodType mt; MethodHandle mh;
- * MethodHandles.Lookup lookup = MethodHandles.lookup();
- * // mt is {(char,char) => String}
- * mt = MethodType.make(String.class, char.class, char.class);
- * mh = lookup.findVirtual(String.class, "replace", mt);
- * // (Ljava/lang/String;CC)Ljava/lang/String;
- * s = mh.<String>invoke("daddy",'d','n');
- * assert(s.equals("nanny"));
- * // weakly typed invocation (using MHs.invoke)
- * s = (String) MethodHandles.invoke(mh, "sappy", 'p', 'v');
- * assert(s.equals("savvy"));
- * // mt is {Object[] => List}
- * mt = MethodType.make(java.util.List.class, Object[].class);
- * mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
- * // mt is {(Object,Object,Object) => Object}
- * mt = MethodType.makeGeneric(3);
- * mh = MethodHandles.collectArguments(mh, mt);
- * // mt is {(Object,Object,Object) => Object}
- * // (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
- * x = mh.invoke((Object)1, (Object)2, (Object)3);
- * assert(x.equals(java.util.Arrays.asList(1,2,3)));
- * // mt is { => int}
- * mt = MethodType.make(int.class);
- * mh = lookup.findVirtual(java.util.List.class, "size", mt);
- * // (Ljava/util/List;)I
- * i = mh.<int>invoke(java.util.Arrays.asList(1,2,3));
- * assert(i == 3);
+Object x, y; String s; int i;
+MethodType mt; MethodHandle mh;
+MethodHandles.Lookup lookup = MethodHandles.lookup();
+// mt is {(char,char) => String}
+mt = MethodType.methodType(String.class, char.class, char.class);
+mh = lookup.findVirtual(String.class, "replace", mt);
+// (Ljava/lang/String;CC)Ljava/lang/String;
+s = mh.<String>invokeExact("daddy",'d','n');
+assert(s.equals("nanny"));
+// weakly typed invocation (using MHs.invoke)
+s = (String) mh.invokeVarargs("sappy", 'p', 'v');
+assert(s.equals("savvy"));
+// mt is {Object[] => List}
+mt = MethodType.methodType(java.util.List.class, Object[].class);
+mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
+// mt is {(Object,Object,Object) => Object}
+mt = MethodType.genericMethodType(3);
+mh = MethodHandles.collectArguments(mh, mt);
+// mt is {(Object,Object,Object) => Object}
+// (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+x = mh.invokeExact((Object)1, (Object)2, (Object)3);
+assert(x.equals(java.util.Arrays.asList(1,2,3)));
+// mt is { => int}
+mt = MethodType.methodType(int.class);
+mh = lookup.findVirtual(java.util.List.class, "size", mt);
+// (Ljava/util/List;)I
+i = mh.<int>invokeExact(java.util.Arrays.asList(1,2,3));
+assert(i == 3);
*
* @param arguments the arguments to pass to the target
* @return the result returned by the target
* @see MethodHandles#genericInvoker
*/
- public final Object invokeVarargs(Object[] arguments) throws Throwable {
+ public final Object invokeVarargs(Object... arguments) throws Throwable {
int argc = arguments == null ? 0 : arguments.length;
MethodType type = type();
if (argc <= 10) {
MethodHandle invoker = MethodHandles.invokers(type).genericInvoker();
switch (argc) {
- case 0: return invoker.invoke(this);
- case 1: return invoker.invoke(this,
+ case 0: return invoker.invokeExact(this);
+ case 1: return invoker.invokeExact(this,
arguments[0]);
- case 2: return invoker.invoke(this,
+ case 2: return invoker.invokeExact(this,
arguments[0], arguments[1]);
- case 3: return invoker.invoke(this,
+ case 3: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2]);
- case 4: return invoker.invoke(this,
+ case 4: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
arguments[3]);
- case 5: return invoker.invoke(this,
+ case 5: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4]);
- case 6: return invoker.invoke(this,
+ case 6: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5]);
- case 7: return invoker.invoke(this,
+ case 7: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5],
arguments[6]);
- case 8: return invoker.invoke(this,
+ case 8: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5],
arguments[6], arguments[7]);
- case 9: return invoker.invoke(this,
+ case 9: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5],
arguments[6], arguments[7], arguments[8]);
- case 10: return invoker.invoke(this,
+ case 10: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5],
arguments[6], arguments[7], arguments[8],
@@ -391,7 +362,7 @@ public abstract class MethodHandle
// more than ten arguments get boxed in a varargs list:
MethodHandle invoker = MethodHandles.invokers(type).varargsInvoker(0);
- return invoker.invoke(this, arguments);
+ return invoker.invokeExact(this, arguments);
}
/** Equivalent to {@code invokeVarargs(arguments.toArray())}. */
public final Object invokeVarargs(java.util.List> arguments) throws Throwable {
diff --git a/jdk/src/share/classes/java/dyn/MethodHandles.java b/jdk/src/share/classes/java/dyn/MethodHandles.java
index 3f53e4a19e9..ac35f88e143 100644
--- a/jdk/src/share/classes/java/dyn/MethodHandles.java
+++ b/jdk/src/share/classes/java/dyn/MethodHandles.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,13 +44,13 @@ import static sun.dyn.MemberName.newIllegalArgumentException;
import static sun.dyn.MemberName.newNoAccessException;
/**
- * Fundamental operations and utilities for MethodHandle.
- * They fall into several categories:
+ * This class consists exclusively of static methods that operate on or return
+ * method handles. They fall into several categories:
*
* MethodHandle invoker = MethodHandles.genericInvoker(this.type(), 0, true);
- * Object result = invoker.invoke(this, arguments);
+ * Object result = invoker.invokeExact(this, arguments);
*
- *
* How access errors are handled
+ * A lookup can fail, because
* the containing class is not accessible to the lookup class, or
* because the desired class member is missing, or because the
* desired class member is not accessible to the lookup class.
@@ -124,8 +133,25 @@ public class MethodHandles {
*/
public static final
class Lookup {
+ /** The class on behalf of whom the lookup is being performed. */
private final Class> lookupClass;
+ /** The allowed sorts of members which may be looked up (public, etc.), with STRICT for package. */
+ private final int allowedModes;
+
+ private static final int
+ PUBLIC = Modifier.PUBLIC,
+ PACKAGE = Modifier.STRICT,
+ PROTECTED = Modifier.PROTECTED,
+ PRIVATE = Modifier.PRIVATE,
+ ALL_MODES = (PUBLIC | PACKAGE | PROTECTED | PRIVATE),
+ TRUSTED = -1;
+
+ private static int fixmods(int mods) {
+ mods &= (ALL_MODES - PACKAGE);
+ return (mods != 0) ? mods : PACKAGE;
+ }
+
/** Which class is performing the lookup? It is this class against
* which checks are performed for visibility and access permissions.
*
+ *
*/
- public Lookup in(Class> newLookupClass) {
- if (this == PUBLIC_LOOKUP) return PUBLIC_LOOKUP;
- if (newLookupClass == null) return PUBLIC_LOOKUP;
- if (newLookupClass == lookupClass) return this;
- if (this != IMPL_LOOKUP) {
- if (!VerifyAccess.isSamePackage(lookupClass, newLookupClass))
- throw newNoAccessException(new MemberName(newLookupClass), this);
- checkUnprivilegedlookupClass(newLookupClass);
+ public Lookup in(Class> requestedLookupClass) {
+ requestedLookupClass.getClass(); // null check
+ if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all
+ return new Lookup(requestedLookupClass, ALL_MODES);
+ if (requestedLookupClass == this.lookupClass)
+ return this; // keep same capabilities
+ int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
+ if ((newModes & PACKAGE) != 0
+ && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
+ newModes &= ~(PACKAGE|PRIVATE);
}
- return new Lookup(newLookupClass);
- }
-
- private Lookup(Class> lookupClass) {
- this.lookupClass = lookupClass;
+ if ((newModes & PRIVATE) != 0
+ && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
+ newModes &= ~PRIVATE;
+ }
+ checkUnprivilegedlookupClass(requestedLookupClass);
+ return new Lookup(requestedLookupClass, newModes);
}
// Make sure outer class is initialized first.
static { IMPL_TOKEN.getClass(); }
- private static final Class> PUBLIC_ONLY = sun.dyn.empty.Empty.class;
-
/** Version of lookup which is trusted minimally.
* It can only be used to create method handles to
* publicly accessible members.
*/
- static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_ONLY);
+ static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
/** Package-private version of lookup which is trusted. */
- static final Lookup IMPL_LOOKUP = new Lookup(null);
+ static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
static { MethodHandleImpl.initLookup(IMPL_TOKEN, IMPL_LOOKUP); }
private static void checkUnprivilegedlookupClass(Class> lookupClass) {
@@ -195,13 +254,35 @@ public class MethodHandles {
throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
}
+ /** Display the name of the class.
+ * If there are restrictions on the access permitted to this lookup,
+ * display those also.
+ */
@Override
public String toString() {
- if (lookupClass == PUBLIC_ONLY)
- return "public";
- if (lookupClass == null)
- return "privileged";
- return lookupClass.getName();
+ String modestr;
+ String cname = lookupClass.getName();
+ switch (allowedModes) {
+ case TRUSTED:
+ return "/trusted";
+ case PUBLIC:
+ modestr = "/public";
+ if (lookupClass == Object.class)
+ return modestr;
+ break;
+ case PUBLIC|PACKAGE:
+ return cname + "/package";
+ case 0: // should not happen
+ return cname + "/empty";
+ case ALL_MODES:
+ return cname;
+ }
+ StringBuilder buf = new StringBuilder(cname);
+ if ((allowedModes & PUBLIC) != 0) buf.append("/public");
+ if ((allowedModes & PACKAGE) != 0) buf.append("/package");
+ if ((allowedModes & PROTECTED) != 0) buf.append("/protected");
+ if ((allowedModes & PRIVATE) != 0) buf.append("/private");
+ return buf.toString();
}
// call this from an entry point method in Lookup with extraFrames=0.
@@ -219,11 +300,11 @@ public class MethodHandles {
* The type of the method handle will be that of the method.
* (Since static methods do not take receivers, there is no
* additional receiver argument inserted into the method handle type,
- * as there would be with {@linkplain #findVirtual} or {@linkplain #findSpecial}.)
+ * as there would be with {@link #findVirtual} or {@link #findSpecial}.)
* The method and all its argument types must be accessible to the lookup class.
* If the method's class has not yet been initialized, that is done
* immediately, before the method handle is returned.
- * @param defc the class from which the method is accessed
+ * @param refc the class from which the method is accessed
* @param name the name of the method
* @param type the type of the method
* @return the desired method handle
@@ -231,18 +312,16 @@ public class MethodHandles {
* @exception NoAccessException if the method does not exist or access checking fails
*/
public
- MethodHandle findStatic(Class> defc, String name, MethodType type) throws NoAccessException {
- MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type, Modifier.STATIC), true, lookupClass());
- VerifyAccess.checkName(method, this);
- checkStatic(true, method, this);
- //throw NoSuchMethodException
- return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClass());
+ MethodHandle findStatic(Class> refc, String name, MethodType type) throws NoAccessException {
+ MemberName method = resolveOrFail(refc, name, type, true);
+ checkMethod(refc, method, true);
+ return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClassOrNull());
}
/**
* Produce a method handle for a virtual method.
* The type of the method handle will be that of the method,
- * with the receiver type ({@code defc}) prepended.
+ * with the receiver type (usually {@code refc}) prepended.
* The method and all its argument types must be accessible to the lookup class.
*
- * {@link #insertArguments}({@link #findVirtual}(defc, name, type), receiver)
+ * {@link #insertArguments insertArguments}({@link #findVirtual findVirtual}(defc, name, type), receiver)
*
* where {@code defc} is either {@code receiver.getClass()} or a super
* type of that class, in which the requested method is accessible
@@ -336,15 +501,13 @@ public class MethodHandles {
* @exception NoAccessException if the method does not exist or access checking fails
*/
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoAccessException {
- Class extends Object> rcvc = receiver.getClass(); // may get NPE
- MemberName reference = new MemberName(rcvc, name, type);
- MemberName method = IMPL_NAMES.resolveOrFail(reference, true, lookupClass());
- VerifyAccess.checkName(method, this);
- checkStatic(false, method, this);
- MethodHandle dmh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClass());
+ Class extends Object> refc = receiver.getClass(); // may get NPE
+ MemberName method = resolveOrFail(refc, name, type, false);
+ checkMethod(refc, method, false);
+ MethodHandle dmh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull());
MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, dmh, receiver);
if (bmh == null)
- throw newNoAccessException(method, this);
+ throw newNoAccessException(method, lookupClass());
return bmh;
}
@@ -364,29 +527,37 @@ public class MethodHandles {
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflect(Method m) throws NoAccessException {
- return unreflectImpl(new MemberName(m), m.isAccessible(), true, false, this);
+ MemberName method = new MemberName(m);
+ assert(method.isMethod());
+ if (!m.isAccessible()) checkMethod(method.getDeclaringClass(), method, method.isStatic());
+ MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull());
+ if (!m.isAccessible()) mh = restrictProtectedReceiver(method, mh);
+ return mh;
}
/**
* PROVISIONAL API, WORK IN PROGRESS:
* Produce a method handle for a reflected method.
* It will bypass checks for overriding methods on the receiver,
- * as if by the {@code invokespecial} instruction.
+ * as if by a {@code invokespecial} instruction from within the {@code specialCaller}.
* The type of the method handle will be that of the method,
- * with the receiver type prepended.
+ * with the special caller type prepended (and not the receiver of the method).
* If the method's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class,
* as if {@code invokespecial} instruction were being linked.
* @param m the reflected method
+ * @param specialCaller the class nominally calling the method
* @return a method handle which can invoke the reflected method
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectSpecial(Method m, Class> specialCaller) throws NoAccessException {
- checkSpecialCaller(specialCaller, this);
- Lookup slookup = this.in(specialCaller);
- MemberName mname = new MemberName(m);
- checkStatic(false, mname, this);
- return unreflectImpl(mname, m.isAccessible(), false, false, slookup);
+ checkSpecialCaller(specialCaller);
+ MemberName method = new MemberName(m);
+ assert(method.isMethod());
+ // ignore m.isAccessible: this is a new kind of access
+ checkMethod(m.getDeclaringClass(), method, false);
+ MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClassOrNull());
+ return restrictReceiver(method, mh, specialCaller);
}
/**
@@ -400,13 +571,16 @@ public class MethodHandles {
*
* @param target the method handle to invoke after the argument is dropped
* @param valueTypes the type(s) of the argument to drop
@@ -1254,7 +1491,7 @@ public class MethodHandles {
MethodHandle dispatch = compose(choose, test);
// dispatch = \(a...).(test(a...) ? target : fallback)
return combineArguments(invoke, dispatch, 0);
- // return \(a...).((test(a...) ? target : fallback).invoke(a...))
+ // return \(a...).((test(a...) ? target : fallback).invokeExact(a...))
} */
return MethodHandleImpl.makeGuardWithTest(IMPL_TOKEN, test, target, fallback);
}
@@ -1325,22 +1562,4 @@ public class MethodHandles {
MethodHandle throwException(Class> returnType, Class extends Throwable> exType) {
return MethodHandleImpl.throwException(IMPL_TOKEN, MethodType.methodType(returnType, exType));
}
-
- /** Alias for {@link MethodType#methodType}. */
- @Deprecated // "use MethodType.methodType instead"
- public static MethodType methodType(Class> rtype) {
- return MethodType.methodType(rtype);
- }
-
- /** Alias for {@link MethodType#methodType}. */
- @Deprecated // "use MethodType.methodType instead"
- public static MethodType methodType(Class> rtype, Class> ptype) {
- return MethodType.methodType(rtype, ptype);
- }
-
- /** Alias for {@link MethodType#methodType}. */
- @Deprecated // "use MethodType.methodType instead"
- public static MethodType methodType(Class> rtype, Class> ptype0, Class>... ptypes) {
- return MethodType.methodType(rtype, ptype0, ptypes);
- }
}
diff --git a/jdk/src/share/classes/java/dyn/MethodType.java b/jdk/src/share/classes/java/dyn/MethodType.java
index f50ea446199..c9001bd25a6 100644
--- a/jdk/src/share/classes/java/dyn/MethodType.java
+++ b/jdk/src/share/classes/java/dyn/MethodType.java
@@ -36,15 +36,24 @@ import sun.dyn.util.BytecodeDescriptor;
import static sun.dyn.MemberName.newIllegalArgumentException;
/**
- * Run-time token used to match call sites with method handles.
+ * A method type represents the arguments and return type accepted and
+ * returned by a method handle, or the arguments and return type passed
+ * and expected by a method handle caller. Method types must be properly
+ * matched between a method handle and all its callers,
+ * and the JVM's operations enforce this matching at all times.
+ *
* MethodHandle cat = MethodHandles.lookup().
* findVirtual(String.class, "concat", String.class, String.class);
- * System.out.println(cat.<String>invoke("x", "y")); // xy
+ * System.out.println(cat.<String>invokeExact("x", "y")); // xy
* MethodHandle d0 = dropArguments(cat, 0, String.class);
- * System.out.println(d0.<String>invoke("x", "y", "z")); // xy
+ * System.out.println(d0.<String>invokeExact("x", "y", "z")); // xy
* MethodHandle d1 = dropArguments(cat, 1, String.class);
- * System.out.println(d1.<String>invoke("x", "y", "z")); // xz
+ * System.out.println(d1.<String>invokeExact("x", "y", "z")); // xz
* MethodHandle d2 = dropArguments(cat, 2, String.class);
- * System.out.println(d2.<String>invoke("x", "y", "z")); // yz
+ * System.out.println(d2.<String>invokeExact("x", "y", "z")); // yz
* MethodHandle d12 = dropArguments(cat, 1, String.class, String.class);
- * System.out.println(d12.<String>invoke("w", "x", "y", "z")); // wz
+ * System.out.println(d12.<String>invokeExact("w", "x", "y", "z")); // wz
*
MethodType
are immutable.
* Two instances are completely interchangeable if they compare equal.
- * Equality depends exactly on the return and parameter types.
+ * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
*
+ *
+ *
+ * Corresponding JVM bytecode format changes
+ * The following low-level information is presented here as a preview of
+ * changes being made to the Java Virtual Machine specification for JSR 292.
+ *
+ * {@code invokedynamic} instruction format
+ * In bytecode, an {@code invokedynamic} instruction is formatted as five bytes.
+ * The first byte is the opcode 186 (hexadecimal {@code BA}).
+ * The next two bytes are a constant pool index (in the same format as for the other {@code invoke} instructions).
+ * The final two bytes are reserved for future use and required to be zero.
+ * The constant pool reference is to a entry with tag {@code CONSTANT_NameAndType}
+ * (decimal 12). It is thus not a method reference of any sort, but merely
+ * the method name, argument types, and return type of the dynamic call site.
+ * (TBD: The EG is discussing the possibility of a special constant pool entry type,
+ * so that other information may be added, such as a per-instruction bootstrap
+ * method and/or annotations.)
+ *
+ * constant pool entries for {@code MethodType}s
+ * If a constant pool entry has the tag {@code CONSTANT_MethodType} (decimal 16),
+ * it must contain exactly two more bytes, which are an index to a {@code CONSTANT_Utf8}
+ * entry which represents a method type signature. The JVM will ensure that on first
+ * execution of an {@code ldc} instruction for this entry, a {@link java.dyn.MethodType}
+ * will be created which represents the signature.
+ * Any classes mentioned in the {@code MethodType} will be loaded if necessary,
+ * but not initialized.
+ * Access checking and error reporting is performed exactly as it is for
+ * references by {@code ldc} instructions to {@code CONSTANT_Class} constants.
+ *
+ * constant pool entries for {@code MethodHandle}s
+ * If a constant pool entry has the tag {@code CONSTANT_MethodHandle} (decimal 15),
+ * it must contain exactly three more bytes. The first byte after the tag is a subtag
+ * value in the range 1 through 9, and the last two are an index to a
+ * {@code CONSTANT_Fieldref}, {@code CONSTANT_Methodref}, or
+ * {@code CONSTANT_InterfaceMethodref} entry which represents a field or method
+ * for which a method handle is to be created.
+ * The JVM will ensure that on first execution of an {@code ldc} instruction
+ * for this entry, a {@link java.dyn.MethodHandle} will be created which represents
+ * the field or method reference, according to the specific mode implied by the subtag.
+ *
+ *
+ *
+ *
+ *
+ * N subtag name member MH type MH behavior
+ * 1 REF_getField C.f:T (C)T getfield C.f:T
+ * 2 REF_getStatic C.f:T ( )T getstatic C.f:T
+ * 3 REF_putField C.f:T (C,T)void putfield C.f:T
+ * 4 REF_putStatic C.f:T (T)void putstatic C.f:T
+ * 5 REF_invokeVirtual C.m(A*)T (C,A*)T invokevirtual C.m(A*)T
+ * 6 REF_invokeStatic C.m(A*)T (C,A*)T invokestatic C.m(A*)T
+ * 7 REF_invokeSpecial C.m(A*)T (C,A*)T invokespecial C.m(A*)T
+ * 8 REF_newInvokeSpecial C.<init>(A*)void (A*)C new C; dup; invokespecial C.<init>(A*)void
+ * 9 REF_invokeInterface C.m(A*)T (C,A*)T invokeinterface C.m(A*)T char
- * arrays and in the String
and StringBuffer
- * classes. In this representation, supplementary characters are
- * represented as a pair of char
values, the first from
- * the high-surrogates range, (\uD800-\uDBFF), the
- * second from the low-surrogates range
- * (\uDC00-\uDFFF).
+ * platform uses the UTF-16 representation in char
arrays and
+ * in the String
and StringBuffer
classes. In
+ * this representation, supplementary characters are represented as a pair
+ * of char
values, the first from the high-surrogates
+ * range, (\uD800-\uDBFF), the second from the
+ * low-surrogates range (\uDC00-\uDFFF).
*
* char
value, therefore, represents Basic
* Multilingual Plane (BMP) code points, including the surrogate
@@ -114,10 +115,12 @@ import java.util.Locale;
* @author Lee Boynton
* @author Guy Steele
* @author Akira Tanaka
+ * @author Martin Buchholz
+ * @author Ulf Zibis
* @since 1.0
*/
public final
-class Character extends Object implements java.io.Serializable, ComparableInteger
.
*
- * @see java.lang.Character#digit(char, int)
- * @see java.lang.Character#forDigit(int, int)
- * @see java.lang.Integer#toString(int, int)
- * @see java.lang.Integer#valueOf(java.lang.String)
+ * @see Character#digit(char, int)
+ * @see Character#forDigit(int, int)
+ * @see Integer#toString(int, int)
+ * @see Integer#valueOf(String)
*/
public static final int MIN_RADIX = 2;
@@ -141,10 +144,10 @@ class Character extends Object implements java.io.Serializable, ComparableInteger
.
*
- * @see java.lang.Character#digit(char, int)
- * @see java.lang.Character#forDigit(int, int)
- * @see java.lang.Integer#toString(int, int)
- * @see java.lang.Integer#valueOf(java.lang.String)
+ * @see Character#digit(char, int)
+ * @see Character#forDigit(int, int)
+ * @see Integer#toString(int, int)
+ * @see Integer#valueOf(String)
*/
public static final int MAX_RADIX = 36;
@@ -154,7 +157,7 @@ class Character extends Object implements java.io.Serializable, Comparable{@link Character.UnicodeBlock
- * UnicodeBlock}
. Other portions of the Java API may define other
- * subsets for their own purposes.
+ * Character
class is {@link Character.UnicodeBlock}.
+ * Other portions of the Java API may define other subsets for their
+ * own purposes.
*
* @since 1.2
*/
@@ -623,6 +597,7 @@ class Character extends Object implements java.io.Serializable, Comparablenull
*/
protected Subset(String name) {
if (name == null) {
@@ -661,6 +636,9 @@ class Character extends Object implements java.io.Serializable, ComparableUnicodeBlock
instance representing the
@@ -2461,22 +2556,21 @@ class Character extends Object implements java.io.Serializable, ComparableUnicodeBlock
instance representing the
* Unicode block of which this character is a member, or
* null
if the character is not a member of any
* Unicode block
- * @exception IllegalArgumentException if the specified
- * codePoint
is an invalid Unicode code point.
- * @see Character#isValidCodePoint(int)
- * @since 1.5
+ * @exception IllegalArgumentException if the specified
+ * codePoint
is an invalid Unicode code point.
+ * @see Character#isValidCodePoint(int)
+ * @since 1.5
*/
public static UnicodeBlock of(int codePoint) {
if (!isValidCodePoint(codePoint)) {
@@ -2518,7 +2612,7 @@ class Character extends Object implements java.io.Serializable, ComparableUnicodeScript
constant representing the
+ * Unicode script of which this character is assigned to.
+ *
+ * @exception IllegalArgumentException if the specified
+ * codePoint
is an invalid Unicode code point.
+ * @see Character#isValidCodePoint(int)
+ *
+ */
+ public static UnicodeScript of(int codePoint) {
+ if (!isValidCodePoint(codePoint))
+ throw new IllegalArgumentException();
+ int type = getType(codePoint);
+ // leave SURROGATE and PRIVATE_USE for table lookup
+ if (type == UNASSIGNED)
+ return UNKNOWN;
+ int index = Arrays.binarySearch(scriptStarts, codePoint);
+ if (index < 0)
+ index = -index - 2;
+ return scripts[index];
+ }
+
+ /**
+ * Returns the UnicodeScript constant with the given Unicode script
+ * name or the script name alias. Script names and their aliases are
+ * determined by The Unicode Standard. The files Scripts<version>.txt
+ * and PropertyValueAliases<version>.txt define script names
+ * and the script name aliases for a particular version of the
+ * standard. The {@link Character} class specifies the version of
+ * the standard that it supports.
+ * UnicodeScript
name.
+ * @return The UnicodeScript
constant identified
+ * by scriptName
+ * @throws IllegalArgumentException if scriptName
is an
+ * invalid name
+ * @throws NullPointerException if scriptName
is null
+ */
+ public static final UnicodeScript forName(String scriptName) {
+ scriptName = scriptName.toUpperCase(Locale.ENGLISH);
+ //.replace(' ', '_'));
+ UnicodeScript sc = aliases.get(scriptName);
+ if (sc != null)
+ return sc;
+ return valueOf(scriptName);
+ }
+ }
+
/**
* The value of the Character
.
*
@@ -2573,7 +3902,7 @@ class Character extends Object implements java.io.Serializable, Comparablefalse
otherwise.
- * @see java.lang.Character#isLowerCase(char)
- * @see java.lang.Character#isTitleCase(char)
- * @see java.lang.Character#toLowerCase(char)
- * @see java.lang.Character#getType(char)
+ * @see Character#isLowerCase(char)
+ * @see Character#isTitleCase(char)
+ * @see Character#toLowerCase(char)
+ * @see Character#getType(char)
*/
public static boolean isLowerCase(char ch) {
return isLowerCase((int)ch);
@@ -3388,17 +4792,17 @@ class Character extends Object implements java.io.Serializable, Comparablefalse
otherwise.
- * @see java.lang.Character#isLowerCase(int)
- * @see java.lang.Character#isTitleCase(int)
- * @see java.lang.Character#toLowerCase(int)
- * @see java.lang.Character#getType(int)
+ * @see Character#isLowerCase(int)
+ * @see Character#isTitleCase(int)
+ * @see Character#toLowerCase(int)
+ * @see Character#getType(int)
* @since 1.5
*/
public static boolean isLowerCase(int codePoint) {
return getType(codePoint) == Character.LOWERCASE_LETTER;
}
- /**
+ /**
* Determines if the specified character is an uppercase character.
* false
otherwise.
- * @see java.lang.Character#isLowerCase(char)
- * @see java.lang.Character#isTitleCase(char)
- * @see java.lang.Character#toUpperCase(char)
- * @see java.lang.Character#getType(char)
+ * @see Character#isLowerCase(char)
+ * @see Character#isTitleCase(char)
+ * @see Character#toUpperCase(char)
+ * @see Character#getType(char)
* @since 1.0
*/
public static boolean isUpperCase(char ch) {
@@ -3451,10 +4855,10 @@ class Character extends Object implements java.io.Serializable, Comparablefalse
otherwise.
- * @see java.lang.Character#isLowerCase(int)
- * @see java.lang.Character#isTitleCase(int)
- * @see java.lang.Character#toUpperCase(int)
- * @see java.lang.Character#getType(int)
+ * @see Character#isLowerCase(int)
+ * @see Character#isTitleCase(int)
+ * @see Character#toUpperCase(int)
+ * @see Character#getType(int)
* @since 1.5
*/
public static boolean isUpperCase(int codePoint) {
@@ -3492,10 +4896,10 @@ class Character extends Object implements java.io.Serializable, Comparablefalse
otherwise.
- * @see java.lang.Character#isLowerCase(char)
- * @see java.lang.Character#isUpperCase(char)
- * @see java.lang.Character#toTitleCase(char)
- * @see java.lang.Character#getType(char)
+ * @see Character#isLowerCase(char)
+ * @see Character#isUpperCase(char)
+ * @see Character#toTitleCase(char)
+ * @see Character#getType(char)
* @since 1.0.2
*/
public static boolean isTitleCase(char ch) {
@@ -3528,10 +4932,10 @@ class Character extends Object implements java.io.Serializable, Comparablefalse
otherwise.
- * @see java.lang.Character#isLowerCase(int)
- * @see java.lang.Character#isUpperCase(int)
- * @see java.lang.Character#toTitleCase(int)
- * @see java.lang.Character#getType(int)
+ * @see Character#isLowerCase(int)
+ * @see Character#isUpperCase(int)
+ * @see Character#toTitleCase(int)
+ * @see Character#getType(int)
* @since 1.5
*/
public static boolean isTitleCase(int codePoint) {
@@ -3569,9 +4973,9 @@ class Character extends Object implements java.io.Serializable, Comparablefalse
otherwise.
- * @see java.lang.Character#digit(char, int)
- * @see java.lang.Character#forDigit(int, int)
- * @see java.lang.Character#getType(char)
+ * @see Character#digit(char, int)
+ * @see Character#forDigit(int, int)
+ * @see Character#getType(char)
*/
public static boolean isDigit(char ch) {
return isDigit((int)ch);
@@ -3603,8 +5007,8 @@ class Character extends Object implements java.io.Serializable, Comparablefalse
otherwise.
- * @see java.lang.Character#forDigit(int, int)
- * @see java.lang.Character#getType(int)
+ * @see Character#forDigit(int, int)
+ * @see Character#getType(int)
* @since 1.5
*/
public static boolean isDigit(int codePoint) {
@@ -3628,12 +5032,12 @@ class Character extends Object implements java.io.Serializable, Comparablefalse
otherwise.
- * @see java.lang.Character#isDigit(char)
- * @see java.lang.Character#isLetter(char)
- * @see java.lang.Character#isLetterOrDigit(char)
- * @see java.lang.Character#isLowerCase(char)
- * @see java.lang.Character#isTitleCase(char)
- * @see java.lang.Character#isUpperCase(char)
+ * @see Character#isDigit(char)
+ * @see Character#isLetter(char)
+ * @see Character#isLetterOrDigit(char)
+ * @see Character#isLowerCase(char)
+ * @see Character#isTitleCase(char)
+ * @see Character#isUpperCase(char)
* @since 1.0.2
*/
public static boolean isDefined(char ch) {
@@ -3652,12 +5056,12 @@ class Character extends Object implements java.io.Serializable, Comparable