--- a/.hgtags Tue Sep 11 13:32:48 2012 +0400
+++ b/.hgtags Fri Sep 14 13:52:30 2012 -0700
@@ -176,3 +176,4 @@
b67041a6cb508da18d2f5c7687e6a31e08bea4fc jdk8-b52
c7aa5cca1c01689a7b1a92411daf83684af05a33 jdk8-b53
7c6aa31ff1b2ae48c1c686ebe1aadf0c3da5be15 jdk8-b54
+319f583f66db47395fa86127dd3ddb729eb7c64f jdk8-b55
--- a/.hgtags-top-repo Tue Sep 11 13:32:48 2012 +0400
+++ b/.hgtags-top-repo Fri Sep 14 13:52:30 2012 -0700
@@ -176,3 +176,4 @@
8d24def5ceb3b8f2e857f2e18b2804fc59eecf8d jdk8-b52
febd7ff5280067ca482faaeb9418ae88764c1a35 jdk8-b53
c1a277c6022affbc6855bdfb039511e73fbe2395 jdk8-b54
+b85b44cced2406792cfb9baab1377ff03e7001d8 jdk8-b55
--- a/corba/.hgtags Tue Sep 11 13:32:48 2012 +0400
+++ b/corba/.hgtags Fri Sep 14 13:52:30 2012 -0700
@@ -176,3 +176,4 @@
80689ff9cb499837513f18a1136dac7f0686cd55 jdk8-b52
63aeb7a2472fb299134ad7388e0a111a5340b02d jdk8-b53
16c82fc74695bab9b9e0fb05c086a5a08ba0082f jdk8-b54
+e8a0e84383d6fbd303ce44bd355fb25972b13286 jdk8-b55
--- a/hotspot/.hgtags Tue Sep 11 13:32:48 2012 +0400
+++ b/hotspot/.hgtags Fri Sep 14 13:52:30 2012 -0700
@@ -274,3 +274,4 @@
9e3ae661284dc04185b029d85440fe7811f1ed07 hs24-b21
e8fb566b94667f88462164defa654203f0ab6820 jdk8-b54
09ea7e0752b306b8ae74713aeb4eb6263e1c6836 hs24-b22
+af0c8a0808516317333dcf9af15567cdd52761ce jdk8-b55
--- a/jaxp/.hgtags Tue Sep 11 13:32:48 2012 +0400
+++ b/jaxp/.hgtags Fri Sep 14 13:52:30 2012 -0700
@@ -176,3 +176,4 @@
bd3c00d5761408954cc29ffb82016a76cbc90b43 jdk8-b52
2c566f25c39f0087464b73e3bcf1c1421d0f2a7e jdk8-b53
7dd81ccb7c1134df70969b3068b1e98def701746 jdk8-b54
+7c2363666890c6675194948fbcd74d81ddb84298 jdk8-b55
--- a/jaxws/.hgtags Tue Sep 11 13:32:48 2012 +0400
+++ b/jaxws/.hgtags Fri Sep 14 13:52:30 2012 -0700
@@ -176,3 +176,4 @@
f62bc618122e87a8bea69865cc02074e9d850426 jdk8-b52
8a35fd644d3c0b75813ff0236adef8a1c6f895c6 jdk8-b53
91970935926a20f19a5cbbf20931745ac1975e91 jdk8-b54
+109c9e1f2d8546e9954e1b7be9a37a4396434544 jdk8-b55
--- a/jdk/.hgtags Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/.hgtags Fri Sep 14 13:52:30 2012 -0700
@@ -176,3 +176,5 @@
e8569a473cee7f4955bd9e76a9bdf6c6a07ced27 jdk8-b52
2c6933c5106b81a8578b70996fe5b735fb3adb60 jdk8-b53
70ad0ed1d6cef0e7712690d1bab21e4769708aad jdk8-b54
+1f3f4b333341873f00da3dee85e4879f0e89c9bb jdk8-b55
+2e9eeef2909b33c9224a024afddb61ccb0b77f14 jdk8-b56
--- a/jdk/make/common/Defs.gmk Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/make/common/Defs.gmk Fri Sep 14 13:52:30 2012 -0700
@@ -542,6 +542,21 @@
CXXFLAGS_$(VARIANT)/BYFILE = $(CXXFLAGS_$(VARIANT)/$(@F)) \
$(CXXFLAGS_$(VARIANT)$(CXXFLAGS_$(VARIANT)/$(@F)))
+# Command line define to provide basename of file being compiled to source.
+# The C macro THIS_FILE can replace the use of __FILE__ in the source
+# files for the current filename being compiled.
+# The value of the __FILE__ macro is unpredictable and can be anything
+# from a relative path to a full path, THIS_FILE will be more consistent..
+# The THIS_FILE macro will always be just the basename of the file being
+# compiled.
+# Different string literals in the the object files makes it difficult to
+# compare shared libraries from different builds.
+#
+# NOTE: If the THIS_FILE macro is actually expanded while in an included
+# source file, it will not return the name of the included file.
+#
+CPP_THIS_FILE = -DTHIS_FILE='"$(<F)"'
+
#
# Tool flags
#
@@ -551,7 +566,7 @@
CFLAGS = $(CFLAGS_$(VARIANT)/BYFILE) $(CFLAGS_COMMON) $(OTHER_CFLAGS) $(EXTRA_CFLAGS)
CXXFLAGS = $(CXXFLAGS_$(VARIANT)/BYFILE) $(CXXFLAGS_COMMON) $(OTHER_CXXFLAGS) $(EXTRA_CFLAGS)
CPPFLAGS = $(CPPFLAGS_$(VARIANT)) $(CPPFLAGS_COMMON) $(OTHER_CPPFLAGS) \
- $(DEFINES) $(OPTIONS:%=-D%)
+ $(DEFINES) $(OPTIONS:%=-D%) $(CPP_THIS_FILE)
LDFLAGS = $(LDFLAGS_$(VARIANT)) $(LDFLAGS_COMMON) $(OTHER_LDFLAGS)
LDLIBS = $(OTHER_LDLIBS) $(LDLIBS_$(VARIANT)) $(LDLIBS_COMMON)
LINTFLAGS = $(LINTFLAGS_$(VARIANT)) $(LINTFLAGS_COMMON) \
--- a/jdk/make/common/Demo.gmk Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/make/common/Demo.gmk Fri Sep 14 13:52:30 2012 -0700
@@ -320,10 +320,10 @@
ifeq ($(PLATFORM),windows)
$(RC) $(RC_FLAGS) $(CC_OBJECT_OUTPUT_FLAG)$(DEMO_VERSION_INFO) $(VERSIONINFO_RESOURCE)
$(LINK.demo) $(SHARED_LIBRARY_FLAG) -Fe$@ \
- $(DEMO_FULL_OBJECTS) $(LDLIBS.demo)
+ $(sort $(DEMO_FULL_OBJECTS)) $(LDLIBS.demo)
else
$(LINK.demo) $(SHARED_LIBRARY_FLAG) -o $@ \
- $(DEMO_FULL_OBJECTS) $(LDLIBS.demo)
+ $(sort $(DEMO_FULL_OBJECTS)) $(LDLIBS.demo)
endif
@$(call binary_file_verification,$@)
--- a/jdk/make/common/Library.gmk Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/make/common/Library.gmk Fri Sep 14 13:52:30 2012 -0700
@@ -199,7 +199,7 @@
$(OBJDIR)/$(LIBRARY).lcf: $(OBJDIR)/$(LIBRARY).res $(COMPILE_FILES_o) $(FILES_m)
@$(prep-target)
@$(MKDIR) -p $(TEMPDIR)
- @$(ECHO) $(FILES_o) > $@
+ @$(ECHO) $(sort $(FILES_o)) > $@
ifndef LOCAL_RESOURCE_FILE
@$(ECHO) $(OBJDIR)/$(LIBRARY).res >> $@
endif
@@ -256,9 +256,9 @@
@$(ECHO) "STATS: LIBRARY=$(LIBRARY), PRODUCT=$(PRODUCT), OPTIMIZATION_LEVEL=$(OPTIMIZATION_LEVEL)"
@$(ECHO) "Rebuilding $@ because of $?"
ifeq ($(LIBRARY), fdlibm)
- $(AR) $(ARFLAGS) $@ $(FILES_o)
+ $(AR) $(ARFLAGS) $@ $(sort $(FILES_o))
else # LIBRARY
- $(LINKER) $(SHARED_LIBRARY_FLAG) -o $@ $(FILES_o) $(LDLIBS)
+ $(LINKER) $(SHARED_LIBRARY_FLAG) -o $@ $(sort $(FILES_o)) $(LDLIBS)
@$(call binary_file_verification,$@)
ifeq ($(WRITE_LIBVERSION),true)
$(MCS) -d -a "$(FULL_VERSION)" $@
--- a/jdk/make/common/Program.gmk Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/make/common/Program.gmk Fri Sep 14 13:52:30 2012 -0700
@@ -262,7 +262,7 @@
$(ECHO) Rebuilding $@ because of $$1 $$2 $$3 $$4 $$5 $$6 $${7:+...};
@$(MKDIR) -p $(TEMPDIR)
$(LINK_PRE_CMD) $(CC) $(CC_OBJECT_OUTPUT_FLAG)$@ $(LDFLAGS) \
- $(FILES_o) $(THREADLIBS) $(LDLIBS)
+ $(sort $(FILES_o)) $(THREADLIBS) $(LDLIBS)
ifeq ($(findstring privileged, $(INFO_PLIST_FILE)), privileged)
-codesign -s openjdk_codesign $@
endif
@@ -392,8 +392,6 @@
VERSION_DEFINES += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \
-DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"'
-
-
$(OBJDIR)/main.$(OBJECT_SUFFIX): $(LAUNCHER_SHARE_SRC)/bin/main.c
@$(prep-target)
$(COMPILE.c) $(CC_OBJECT_OUTPUT_FLAG)$(OBJDIR)/main.$(OBJECT_SUFFIX) \
--- a/jdk/make/docs/Makefile Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/make/docs/Makefile Fri Sep 14 13:52:30 2012 -0700
@@ -73,7 +73,7 @@
else ifeq ($(ARCH),universal)
MAX_VM_MEMORY = 1024
else
- MAX_VM_MEMORY = 612
+ MAX_VM_MEMORY = 768
endif
# List of all possible directories for javadoc to look for sources
--- a/jdk/make/sun/security/ec/Makefile Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/make/sun/security/ec/Makefile Fri Sep 14 13:52:30 2012 -0700
@@ -128,7 +128,6 @@
# Exclude the sources that get built by ../other/Makefile
#
AUTO_JAVA_PRUNE = \
- ECKeyFactory.java \
ECParameters.java \
ECPrivateKeyImpl.java \
ECPublicKeyImpl.java \
--- a/jdk/make/sun/security/other/Makefile Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/make/sun/security/other/Makefile Fri Sep 14 13:52:30 2012 -0700
@@ -53,7 +53,6 @@
# EC classes used by the packages above
#
FILES_java += \
- sun/security/ec/ECKeyFactory.java \
sun/security/ec/ECParameters.java \
sun/security/ec/ECPrivateKeyImpl.java \
sun/security/ec/ECPublicKeyImpl.java \
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Fri Sep 14 13:52:30 2012 -0700
@@ -40,6 +40,7 @@
import java.awt.peer.ComponentPeer;
import java.awt.peer.ContainerPeer;
+import java.awt.peer.KeyboardFocusManagerPeer;
import java.util.concurrent.atomic.AtomicBoolean;
import java.lang.reflect.Field;
import java.security.AccessController;
@@ -894,15 +895,15 @@
", focusedWindowChangeAllowed=" + focusedWindowChangeAllowed +
", time= " + time + ", cause=" + cause);
}
- if (LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
- processSynchronousLightweightTransfer(getTarget(), lightweightChild, temporary,
- focusedWindowChangeAllowed, time)) {
+ if (LWKeyboardFocusManagerPeer.processSynchronousLightweightTransfer(
+ getTarget(), lightweightChild, temporary,
+ focusedWindowChangeAllowed, time)) {
return true;
}
- int result = LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
- shouldNativelyFocusHeavyweight(getTarget(), lightweightChild, temporary,
- focusedWindowChangeAllowed, time, cause);
+ int result = LWKeyboardFocusManagerPeer.shouldNativelyFocusHeavyweight(
+ getTarget(), lightweightChild, temporary,
+ focusedWindowChangeAllowed, time, cause);
switch (result) {
case LWKeyboardFocusManagerPeer.SNFH_FAILURE:
return false;
@@ -951,14 +952,13 @@
return false;
}
- LWComponentPeer focusOwnerPeer =
- LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
- getFocusOwner();
- Component focusOwner = (focusOwnerPeer != null) ? focusOwnerPeer.getTarget() : null;
+ KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+ Component focusOwner = kfmPeer.getCurrentFocusOwner();
return LWKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
getTarget(), temporary,
focusedWindowChangeAllowed,
time, cause, focusOwner);
+
case LWKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
return true;
}
@@ -1251,9 +1251,6 @@
if (!target.isFocusOwner() && LWKeyboardFocusManagerPeer.shouldFocusOnClick(target)) {
LWKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT);
- } else {
- // Anyway request focus to the toplevel.
- getWindowPeerOrSelf().requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
}
}
@@ -1263,8 +1260,8 @@
protected void handleJavaFocusEvent(FocusEvent e) {
// Note that the peer receives all the FocusEvents from
// its lightweight children as well
- LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
- setFocusOwner(e.getID() == FocusEvent.FOCUS_GAINED ? this : null);
+ KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+ kfmPeer.setCurrentFocusOwner(e.getID() == FocusEvent.FOCUS_GAINED ? getTarget() : null);
}
/**
--- a/jdk/src/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java Fri Sep 14 13:52:30 2012 -0700
@@ -26,85 +26,47 @@
package sun.lwawt;
import java.awt.Component;
-import java.awt.KeyboardFocusManager;
import java.awt.Window;
-
-import java.util.Map;
-import java.util.HashMap;
-
-import sun.awt.AWTAccessor;
-import sun.awt.AppContext;
import sun.awt.KeyboardFocusManagerPeerImpl;
public class LWKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
-
- private Object lock = new Object();
- private LWWindowPeer focusedWindow;
- private LWComponentPeer focusOwner;
+ private static final LWKeyboardFocusManagerPeer inst = new LWKeyboardFocusManagerPeer();
- private static Map<KeyboardFocusManager, LWKeyboardFocusManagerPeer> instances =
- new HashMap<KeyboardFocusManager, LWKeyboardFocusManagerPeer>();
+ private Window focusedWindow;
+ private Component focusOwner;
- public static synchronized LWKeyboardFocusManagerPeer getInstance(AppContext ctx) {
- return getInstance(AWTAccessor.getKeyboardFocusManagerAccessor().
- getCurrentKeyboardFocusManager(ctx));
+ public static LWKeyboardFocusManagerPeer getInstance() {
+ return inst;
}
- public static synchronized LWKeyboardFocusManagerPeer getInstance(KeyboardFocusManager manager) {
- LWKeyboardFocusManagerPeer instance = instances.get(manager);
- if (instance == null) {
- instance = new LWKeyboardFocusManagerPeer(manager);
- instances.put(manager, instance);
- }
- return instance;
+ private LWKeyboardFocusManagerPeer() {
}
- public LWKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
- super(manager);
+ @Override
+ public void setCurrentFocusedWindow(Window win) {
+ synchronized (this) {
+ focusedWindow = win;
+ }
}
@Override
public Window getCurrentFocusedWindow() {
- synchronized (lock) {
- return (focusedWindow != null) ? (Window)focusedWindow.getTarget() : null;
+ synchronized (this) {
+ return focusedWindow;
}
}
@Override
public Component getCurrentFocusOwner() {
- synchronized (lock) {
- return (focusOwner != null) ? focusOwner.getTarget() : null;
+ synchronized (this) {
+ return focusOwner;
}
}
@Override
public void setCurrentFocusOwner(Component comp) {
- synchronized (lock) {
- focusOwner = (comp != null) ? (LWComponentPeer)comp.getPeer() : null;
- }
- }
-
- void setFocusedWindow(LWWindowPeer peer) {
- synchronized (lock) {
- focusedWindow = peer;
- }
- }
-
- LWWindowPeer getFocusedWindow() {
- synchronized (lock) {
- return focusedWindow;
- }
- }
-
- void setFocusOwner(LWComponentPeer peer) {
- synchronized (lock) {
- focusOwner = peer;
- }
- }
-
- LWComponentPeer getFocusOwner() {
- synchronized (lock) {
- return focusOwner;
+ synchronized (this) {
+ focusOwner = comp;
}
}
}
--- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java Fri Sep 14 13:52:30 2012 -0700
@@ -415,8 +415,8 @@
}
@Override
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
- return LWKeyboardFocusManagerPeer.getInstance(manager);
+ public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
+ return LWKeyboardFocusManagerPeer.getInstance();
}
@Override
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Fri Sep 14 13:52:30 2012 -0700
@@ -88,10 +88,16 @@
private volatile int windowState = Frame.NORMAL;
+ // check that the mouse is over the window
+ private volatile boolean isMouseOver = false;
+
+ // A peer where the last mouse event came to. Used by cursor manager to
+ // find the component under cursor
+ private static volatile LWComponentPeer lastCommonMouseEventPeer = null;
+
// A peer where the last mouse event came to. Used to generate
- // MOUSE_ENTERED/EXITED notifications and by cursor manager to
- // find the component under cursor
- private static volatile LWComponentPeer lastMouseEventPeer = null;
+ // MOUSE_ENTERED/EXITED notifications
+ private volatile LWComponentPeer lastMouseEventPeer;
// Peers where all dragged/released events should come to,
// depending on what mouse button is being dragged according to Cocoa
@@ -232,8 +238,7 @@
// TODO: update graphicsConfig, see 4868278
platformWindow.setVisible(visible);
if (isSimpleWindow()) {
- LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer.
- getInstance(getAppContext());
+ KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
if (visible) {
if (!getTarget().isAutoRequestFocus()) {
@@ -242,7 +247,7 @@
requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
}
// Focus the owner in case this window is focused.
- } else if (manager.getCurrentFocusedWindow() == getTarget()) {
+ } else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) {
// Transfer focus to the owner.
LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
if (owner != null) {
@@ -707,66 +712,65 @@
Rectangle r = getBounds();
// findPeerAt() expects parent coordinates
LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
- LWWindowPeer lastWindowPeer =
- (lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
- LWWindowPeer curWindowPeer =
- (targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null;
if (id == MouseEvent.MOUSE_EXITED) {
- // Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched
- // to a peer from another window. So we must first check if this peer is
- // the same as lastWindowPeer
- if (lastWindowPeer == this) {
- if (isEnabled()) {
+ isMouseOver = false;
+ if (lastMouseEventPeer != null) {
+ if (lastMouseEventPeer.isEnabled()) {
Point lp = lastMouseEventPeer.windowToLocal(x, y,
- lastWindowPeer);
+ this);
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
- MouseEvent.MOUSE_EXITED, when,
- modifiers, lp.x, lp.y, screenX,
- screenY, clickCount, popupTrigger,
- button));
+ MouseEvent.MOUSE_EXITED, when,
+ modifiers, lp.x, lp.y, screenX,
+ screenY, clickCount, popupTrigger,
+ button));
+ }
+
+ // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched
+ // to a peer from another window. So we must first check if this peer is
+ // the same as lastWindowPeer
+ if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) {
+ lastCommonMouseEventPeer = null;
}
lastMouseEventPeer = null;
}
- } else {
- if (targetPeer != lastMouseEventPeer) {
-
- if (id != MouseEvent.MOUSE_DRAGGED || lastMouseEventPeer == null) {
- // lastMouseEventPeer may be null if mouse was out of Java windows
- if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
- // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit
- // later), in which case lastWindowPeer is another window
- if (lastWindowPeer != this) {
- Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
- // Additionally translate from this to lastWindowPeer coordinates
- Rectangle lr = lastWindowPeer.getBounds();
- oldp.x += r.x - lr.x;
- oldp.y += r.y - lr.y;
- postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
- MouseEvent.MOUSE_EXITED,
- when, modifiers,
- oldp.x, oldp.y, screenX, screenY,
- clickCount, popupTrigger, button));
- } else {
- Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
- postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
- MouseEvent.MOUSE_EXITED,
- when, modifiers,
- oldp.x, oldp.y, screenX, screenY,
- clickCount, popupTrigger, button));
- }
- }
- if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
- Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
+ } else if(id == MouseEvent.MOUSE_ENTERED) {
+ isMouseOver = true;
+ if (targetPeer != null) {
+ if (targetPeer.isEnabled()) {
+ Point lp = targetPeer.windowToLocal(x, y, this);
postEvent(new MouseEvent(targetPeer.getTarget(),
- MouseEvent.MOUSE_ENTERED,
- when, modifiers,
- newp.x, newp.y, screenX, screenY,
- clickCount, popupTrigger, button));
- }
+ MouseEvent.MOUSE_ENTERED, when,
+ modifiers, lp.x, lp.y, screenX,
+ screenY, clickCount, popupTrigger,
+ button));
}
+ lastCommonMouseEventPeer = targetPeer;
lastMouseEventPeer = targetPeer;
}
+ } else {
+ PlatformWindow topmostPlatforWindow =
+ platformWindow.getTopmostPlatformWindowUnderMouse();
+
+ LWWindowPeer topmostWindowPeer =
+ topmostPlatforWindow != null ? topmostPlatforWindow.getPeer() : null;
+
+ // topmostWindowPeer == null condition is added for the backward
+ // compatibility with applets. It can be removed when the
+ // getTopmostPlatformWindowUnderMouse() method will be properly
+ // implemented in CPlatformEmbeddedFrame class
+ if (topmostWindowPeer == this || topmostWindowPeer == null) {
+ generateMouseEnterExitEventsForComponents(when, button, x, y,
+ screenX, screenY, modifiers, clickCount, popupTrigger,
+ targetPeer);
+ } else {
+ LWComponentPeer topmostTargetPeer =
+ topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null;
+ topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y,
+ screenX, screenY, modifiers, clickCount, popupTrigger,
+ topmostTargetPeer);
+ }
+
// TODO: fill "bdata" member of AWTEvent
int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
@@ -794,6 +798,14 @@
mouseClickButtons |= eventButtonMask;
}
+ // The window should be focused on mouse click. If it gets activated by the native platform,
+ // this request will be no op. It will take effect when:
+ // 1. A simple not focused window is clicked.
+ // 2. An active but not focused owner frame/dialog is clicked.
+ // The mouse event then will trigger a focus request "in window" to the component, so the window
+ // should gain focus before.
+ requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
+
mouseDownTarget[targetIdx] = targetPeer;
} else if (id == MouseEvent.MOUSE_DRAGGED) {
// Cocoa dragged event has the information about which mouse
@@ -816,19 +828,13 @@
// mouseClickButtons is updated below, after MOUSE_CLICK is sent
}
- // check if we receive mouseEvent from outside the window's bounds
- // it can be either mouseDragged or mouseReleased
- if (curWindowPeer == null) {
- //TODO This can happen if this window is invisible. this is correct behavior in this case?
- curWindowPeer = this;
- }
if (targetPeer == null) {
//TODO This can happen if this window is invisible. this is correct behavior in this case?
targetPeer = this;
}
- Point lp = targetPeer.windowToLocal(x, y, curWindowPeer);
+ Point lp = targetPeer.windowToLocal(x, y, this);
if (targetPeer.isEnabled()) {
MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
when, modifiers, lp.x, lp.y,
@@ -852,6 +858,38 @@
notifyUpdateCursor();
}
+ private void generateMouseEnterExitEventsForComponents(long when,
+ int button, int x, int y, int screenX, int screenY,
+ int modifiers, int clickCount, boolean popupTrigger,
+ LWComponentPeer targetPeer) {
+
+ if (!isMouseOver || targetPeer == lastMouseEventPeer) {
+ return;
+ }
+
+ // Generate Mouse Exit for components
+ if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
+ Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
+ postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
+ MouseEvent.MOUSE_EXITED,
+ when, modifiers,
+ oldp.x, oldp.y, screenX, screenY,
+ clickCount, popupTrigger, button));
+ }
+ lastCommonMouseEventPeer = targetPeer;
+ lastMouseEventPeer = targetPeer;
+
+ // Generate Mouse Enter for components
+ if (targetPeer != null && targetPeer.isEnabled()) {
+ Point newp = targetPeer.windowToLocal(x, y, this);
+ postEvent(new MouseEvent(targetPeer.getTarget(),
+ MouseEvent.MOUSE_ENTERED,
+ when, modifiers,
+ newp.x, newp.y, screenX, screenY,
+ clickCount, popupTrigger, button));
+ }
+ }
+
public void dispatchMouseWheelEvent(long when, int x, int y, int modifiers,
int scrollType, int scrollAmount,
int wheelRotation, double preciseWheelRotation,
@@ -884,20 +922,16 @@
public void dispatchKeyEvent(int id, long when, int modifiers,
int keyCode, char keyChar, int keyLocation)
{
- LWComponentPeer focusOwner =
- LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
- getFocusOwner();
+ LWKeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+ Component focusOwner = kfmPeer.getCurrentFocusOwner();
- // Null focus owner may receive key event when
- // application hides the focused window upon ESC press
- // (AWT transfers/clears the focus owner) and pending ESC release
- // may come to already hidden window. This check eliminates NPE.
- if (focusOwner != null) {
- KeyEvent event =
- new KeyEvent(focusOwner.getTarget(), id, when, modifiers,
- keyCode, keyChar, keyLocation);
- focusOwner.postEvent(event);
+ if (focusOwner == null) {
+ focusOwner = kfmPeer.getCurrentFocusedWindow();
+ if (focusOwner == null) {
+ focusOwner = this.getTarget();
+ }
}
+ postEvent(new KeyEvent(focusOwner, id, when, modifiers, keyCode, keyChar, keyLocation));
}
@@ -1096,11 +1130,11 @@
}
public static LWWindowPeer getWindowUnderCursor() {
- return lastMouseEventPeer != null ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
+ return lastCommonMouseEventPeer != null ? lastCommonMouseEventPeer.getWindowPeerOrSelf() : null;
}
public static LWComponentPeer<?, ?> getPeerUnderCursor() {
- return lastMouseEventPeer;
+ return lastCommonMouseEventPeer;
}
/*
@@ -1213,10 +1247,8 @@
}
}
- LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer.
- getInstance(getAppContext());
-
- Window oppositeWindow = becomesFocused ? manager.getCurrentFocusedWindow() : null;
+ KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+ Window oppositeWindow = becomesFocused ? kfmPeer.getCurrentFocusedWindow() : null;
// Note, the method is not called:
// - when the opposite (gaining focus) window is an owned/owner window.
@@ -1229,10 +1261,10 @@
grabbingWindow.ungrab();
}
- manager.setFocusedWindow(becomesFocused ? LWWindowPeer.this : null);
+ kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
- WindowEvent windowEvent = new WindowEvent(getTarget(), eventID, oppositeWindow);
+ WindowEvent windowEvent = new TimedWindowEvent(getTarget(), eventID, oppositeWindow, System.currentTimeMillis());
// TODO: wrap in SequencedEvent
postEvent(windowEvent);
--- a/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java Fri Sep 14 13:52:30 2012 -0700
@@ -118,6 +118,8 @@
public void setAlwaysOnTop(boolean value);
+ public PlatformWindow getTopmostPlatformWindowUnderMouse();
+
public void updateFocusableWindowState();
public boolean rejectFocusRequest(CausedFocusEvent.Cause cause);
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Fri Sep 14 13:52:30 2012 -0700
@@ -151,6 +151,10 @@
@Override
public void setAlwaysOnTop(boolean value) {}
+ // This method should be properly implemented for applets.
+ // It returns null just as a stub.
+ public PlatformWindow getTopmostPlatformWindowUnderMouse() { return null; }
+
@Override
public void updateFocusableWindowState() {}
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Sep 14 13:52:30 2012 -0700
@@ -61,8 +61,9 @@
private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);
private static native void nativeSetNSWindowSecurityWarningPositioning(long nsWindowPtr, double x, double y, float biasX, float biasY);
private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled);
- private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr);
+ private static native void nativeSynthesizeMouseEnteredExitedEvents();
private static native void nativeDispose(long nsWindowPtr);
+ private static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse();
private static native int nativeGetNSWindowDisplayID_AppKitThread(long nsWindowPtr);
@@ -588,7 +589,7 @@
}
}
- nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
+ nativeSynthesizeMouseEnteredExitedEvents();
// Configure stuff #2
updateFocusabilityForAutoRequestFocus(true);
@@ -729,6 +730,10 @@
setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop);
}
+ public PlatformWindow getTopmostPlatformWindowUnderMouse(){
+ return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse();
+ }
+
@Override
public void setOpacity(float opacity) {
CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity);
@@ -803,7 +808,7 @@
throw new RuntimeException("Unknown window state: " + windowState);
}
- nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
+ nativeSynthesizeMouseEnteredExitedEvents();
// NOTE: the SWP.windowState field gets updated to the newWindowState
// value when the native notification comes to us
--- a/jdk/src/macosx/native/com/apple/laf/ScreenMenu.m Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/native/com/apple/laf/ScreenMenu.m Fri Sep 14 13:52:30 2012 -0700
@@ -37,7 +37,11 @@
#import "ThreadUtilities.h"
#import "CMenuBar.h"
-
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
static JNF_CLASS_CACHE(sjc_ScreenMenu, "com/apple/laf/ScreenMenu");
static jint ns2awtModifiers(NSUInteger keyMods) {
@@ -97,7 +101,7 @@
{
if (self.javaObjectWrapper == nil) {
#ifdef DEBUG
- NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__);
+ NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__);
#endif
return;
}
@@ -115,7 +119,7 @@
{
if (self.javaObjectWrapper == nil) {
#ifdef DEBUG
- NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__);
+ NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__);
#endif
return;
}
@@ -133,7 +137,7 @@
{
if (self.javaObjectWrapper == nil) {
#ifdef DEBUG
- NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__);
+ NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__);
#endif
return;
}
--- a/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiOut.c Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiOut.c Fri Sep 14 13:52:30 2012 -0700
@@ -26,6 +26,11 @@
//#define USE_ERROR
//#define USE_TRACE
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#if USE_PLATFORM_MIDI_OUT == TRUE
#include "PLATFORM_API_MacOSX_MidiUtils.h"
@@ -128,7 +133,7 @@
case 0xF7:
// System exclusive
fprintf(stderr, "%s: %d->internal error: sysex message status=0x%X while sending short message\n",
- __FILE__, __LINE__, data[0]);
+ THIS_FILE, __LINE__, data[0]);
byteIsInvalid = TRUE;
break;
@@ -154,7 +159,7 @@
default:
// Invalid message
fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n",
- __FILE__, __LINE__, data[0]);
+ THIS_FILE, __LINE__, data[0]);
byteIsInvalid = TRUE;
break;
}
@@ -164,7 +169,7 @@
default:
// This can't happen, but handle it anyway.
fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n",
- __FILE__, __LINE__, data[0]);
+ THIS_FILE, __LINE__, data[0]);
byteIsInvalid = TRUE;
break;
}
--- a/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiUtils.c Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiUtils.c Fri Sep 14 13:52:30 2012 -0700
@@ -42,6 +42,11 @@
//#define USE_ERROR
//#define USE_TRACE
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#if (USE_PLATFORM_MIDI_IN == TRUE) || (USE_PLATFORM_MIDI_OUT == TRUE)
#include "PLATFORM_API_MacOSX_MidiUtils.h"
@@ -317,7 +322,7 @@
packedMsg = pendingMessageStatus | pendingData[0] << 8;
} else {
fprintf(stderr, "%s: %d->internal error: pendingMessageStatus=0x%X, pendingDataLength=%d\n",
- __FILE__, __LINE__, pendingMessageStatus, pendingDataLength);
+ THIS_FILE, __LINE__, pendingMessageStatus, pendingDataLength);
byteIsInvalid = TRUE;
}
pendingDataLength = 0;
--- a/jdk/src/macosx/native/sun/awt/AWTView.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTView.h Fri Sep 14 13:52:30 2012 -0700
@@ -33,8 +33,8 @@
@private
jobject m_cPlatformView;
- // Handler for the tracking rect needed for Enter/Exit events management.
- NSTrackingRectTag rolloverTrackingRectTag;
+ // Handler for the tracking area needed for Enter/Exit events management.
+ NSTrackingArea* rolloverTrackingArea;
// TODO: NSMenu *contextualMenu;
@@ -61,7 +61,7 @@
- (id) initWithRect:(NSRect) rect platformView:(jobject)cPlatformView windowLayer:(CALayer*)windowLayer;
- (void) deliverJavaMouseEvent: (NSEvent *) event;
-- (void) resetTrackingRect;
+- (void) resetTrackingArea;
- (void) deliverJavaKeyEventHelper: (NSEvent *) event;
- (jobject) awtComponent:(JNIEnv *)env;
--- a/jdk/src/macosx/native/sun/awt/AWTView.m Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTView.m Fri Sep 14 13:52:30 2012 -0700
@@ -82,6 +82,7 @@
fPAHNeedsToSelect = NO;
mouseIsOver = NO;
+ [self resetTrackingArea];
if (windowLayer != nil) {
self.cglLayer = windowLayer;
@@ -146,7 +147,7 @@
[[self window] makeFirstResponder: self];
}];
if ([self window] != NULL) {
- [self resetTrackingRect];
+ [self resetTrackingArea];
}
}
@@ -368,30 +369,31 @@
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent);
}
-
-- (void) clearTrackingRect {
- if (rolloverTrackingRectTag > 0) {
- [self removeTrackingRect:rolloverTrackingRectTag];
- rolloverTrackingRectTag = 0;
+- (void) resetTrackingArea {
+ if (rolloverTrackingArea != nil) {
+ [self removeTrackingArea:rolloverTrackingArea];
+ [rolloverTrackingArea release];
}
-}
+
+ int options = (NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited |
+ NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag);
-- (void) resetTrackingRect {
- [self clearTrackingRect];
- rolloverTrackingRectTag = [self addTrackingRect:[self visibleRect]
- owner:self
- userData:NULL
- assumeInside:NO];
+ rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect]
+ options: options
+ owner:self
+ userInfo:nil
+ ];
+ [self addTrackingArea:rolloverTrackingArea];
}
- (void)updateTrackingAreas {
[super updateTrackingAreas];
- [self resetTrackingRect];
+ [self resetTrackingArea];
}
- (void) resetCursorRects {
[super resetCursorRects];
- [self resetTrackingRect];
+ [self resetTrackingArea];
}
-(void) deliverJavaKeyEventHelper: (NSEvent *) event {
@@ -402,7 +404,7 @@
}
[sLastKeyEvent release];
sLastKeyEvent = [event retain];
-
+
[AWTToolkit eventCountPlusPlus];
JNIEnv *env = [ThreadUtilities getJNIEnv];
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m Fri Sep 14 13:52:30 2012 -0700
@@ -238,10 +238,12 @@
return self;
}
-// checks that this window is under the mouse cursor and this point is not overlapped by others windows
-- (BOOL) isTopmostWindowUnderMouse {
++ (BOOL) isAWTWindow:(NSWindow *)window {
+ return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];
+}
- int currentWinID = [self.nsWindow windowNumber];
+// returns id for the topmost window under mouse
++ (NSInteger) getTopmostWindowUnderMouseID {
NSRect screenRect = [[NSScreen mainScreen] frame];
NSPoint nsMouseLocation = [NSEvent mouseLocation];
@@ -249,53 +251,77 @@
NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
-
for (NSDictionary *window in windows) {
- int layer = [[window objectForKey:(id)kCGWindowLayer] intValue];
+ NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue];
if (layer == 0) {
- int winID = [[window objectForKey:(id)kCGWindowNumber] intValue];
CGRect rect;
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
if (CGRectContainsPoint(rect, cgMouseLocation)) {
- return currentWinID == winID;
- } else if (currentWinID == winID) {
- return NO;
+ return [[window objectForKey:(id)kCGWindowNumber] integerValue];
}
}
}
- return NO;
+ return -1;
+}
+
+// checks that this window is under the mouse cursor and this point is not overlapped by others windows
+- (BOOL) isTopmostWindowUnderMouse {
+ return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];
}
-- (void) synthesizeMouseEnteredExitedEvents {
++ (AWTWindow *) getTopmostWindowUnderMouse {
+ NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];
+ NSWindow *window;
- int eventType = 0;
- BOOL isUnderMouse = [self isTopmostWindowUnderMouse];
- BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver];
+ NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
- if (isUnderMouse && !mouseIsOver) {
- eventType = NSMouseEntered;
- } else if (!isUnderMouse && mouseIsOver) {
- eventType = NSMouseExited;
- } else {
- return;
+ while ((window = [windowEnumerator nextObject]) != nil) {
+ if ([window windowNumber] == topmostWindowUnderMouseID) {
+ BOOL isAWTWindow = [AWTWindow isAWTWindow: window];
+ return isAWTWindow ? (AWTWindow *) [window delegate] : nil;
+ }
}
+ return nil;
+}
+
++ (void) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType {
NSPoint screenLocation = [NSEvent mouseLocation];
- NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation];
+ NSPoint windowLocation = [window convertScreenToBase: screenLocation];
int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
- location: windowLocation
- modifierFlags: modifierFlags
- timestamp: 0
- windowNumber: [self.nsWindow windowNumber]
- context: nil
- eventNumber: 0
- trackingNumber: 0
- userData: nil
- ];
+ location: windowLocation
+ modifierFlags: modifierFlags
+ timestamp: 0
+ windowNumber: [window windowNumber]
+ context: nil
+ eventNumber: 0
+ trackingNumber: 0
+ userData: nil
+ ];
+
+ [[window contentView] deliverJavaMouseEvent: mouseEvent];
+}
+
++ (void) synthesizeMouseEnteredExitedEventsForAllWindows {
- [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];
+ NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
+ NSArray *windows = [NSApp windows];
+ NSWindow *window;
+
+ NSEnumerator *windowEnumerator = [windows objectEnumerator];
+ while ((window = [windowEnumerator nextObject]) != nil) {
+ if ([AWTWindow isAWTWindow: window]) {
+ BOOL isUnderMouse = ([window windowNumber] == topmostWindowUnderMouseID);
+ BOOL mouseIsOver = [[window contentView] mouseIsOver];
+ if (isUnderMouse && !mouseIsOver) {
+ [AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseEntered];
+ } else if (!isUnderMouse && mouseIsOver) {
+ [AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseExited];
+ }
+ }
+ }
}
- (void) dealloc {
@@ -825,7 +851,7 @@
// (this will also re-enable screen updates, which were disabled above)
// TODO: send PaintEvent
- [window synthesizeMouseEnteredExitedEvents];
+ [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
}];
JNF_COCOA_EXIT(env);
@@ -1040,22 +1066,42 @@
/*
* Class: sun_lwawt_macosx_CPlatformWindow
+ * Method: nativeGetTopmostPlatformWindowUnderMouse
+ * Signature: (J)V
+ */
+JNIEXPORT jobject
+JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse
+(JNIEnv *env, jclass clazz)
+{
+ jobject topmostWindowUnderMouse = nil;
+
+ JNF_COCOA_ENTER(env);
+ AWT_ASSERT_APPKIT_THREAD;
+
+ AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse];
+ if (awtWindow != nil) {
+ topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject];
+ }
+
+ JNF_COCOA_EXIT(env);
+
+ return topmostWindowUnderMouse;
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeSynthesizeMouseEnteredExitedEvents
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
-(JNIEnv *env, jclass clazz, jlong windowPtr)
+(JNIEnv *env, jclass clazz)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
- NSWindow *nsWindow = OBJC(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
-
- AWTWindow *window = (AWTWindow*)[nsWindow delegate];
-
- [window synthesizeMouseEnteredExitedEvents];
+ [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
}];
JNF_COCOA_EXIT(env);
--- a/jdk/src/macosx/native/sun/awt/CSystemColors.m Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/CSystemColors.m Fri Sep 14 13:52:30 2012 -0700
@@ -33,6 +33,11 @@
#import "ThreadUtilities.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
NSColor **sColors = nil;
NSColor **appleColors = nil;
@@ -130,7 +135,7 @@
result = (useAppleColor ? appleColors : sColors)[colorIndex];
}
else {
- NSLog(@"%s: %s %sColor: %ld not found, returning black.", __FILE__, __FUNCTION__, (useAppleColor) ? "Apple" : "System", colorIndex);
+ NSLog(@"%s: %s %sColor: %ld not found, returning black.", THIS_FILE, __FUNCTION__, (useAppleColor) ? "Apple" : "System", colorIndex);
result = [NSColor blackColor];
}
--- a/jdk/src/macosx/native/sun/awt/CTextPipe.m Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/CTextPipe.m Fri Sep 14 13:52:30 2012 -0700
@@ -36,6 +36,10 @@
#import "QuartzSurfaceData.h"
#include "AWTStrike.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
static const CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
@@ -501,7 +505,7 @@
if (glyphs == NULL || advances == NULL)
{
(*env)->DeleteLocalRef(env, glyphsArray);
- [NSException raise:NSMallocException format:@"%s-%s:%d", __FILE__, __FUNCTION__, __LINE__];
+ [NSException raise:NSMallocException format:@"%s-%s:%d", THIS_FILE, __FUNCTION__, __LINE__];
return;
}
--- a/jdk/src/macosx/native/sun/font/AWTStrike.m Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/macosx/native/sun/font/AWTStrike.m Fri Sep 14 13:52:30 2012 -0700
@@ -33,6 +33,11 @@
#import "CoreTextSupport.h"
//#import "jni_util.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
@implementation AWTStrike
static CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
@@ -102,7 +107,7 @@
#define AWT_FONT_CLEANUP_FINISH \
if (_fontThrowJavaException == YES) { \
char s[512]; \
- sprintf(s, "%s-%s:%d", __FILE__, __FUNCTION__, __LINE__); \
+ sprintf(s, "%s-%s:%d", THIS_FILE, __FUNCTION__, __LINE__); \
[JNFException raise:env as:kRuntimeException reason:s]; \
}
--- a/jdk/src/share/back/error_messages.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/back/error_messages.h Fri Sep 14 13:52:30 2012 -0700
@@ -42,31 +42,36 @@
const char * eventText(int);
const char * jdwpErrorText(jdwpError);
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#define EXIT_ERROR(error,msg) \
{ \
print_message(stderr, "JDWP exit error ", "\n", \
"%s(%d): %s [%s:%d]", \
jvmtiErrorText((jvmtiError)error), error, (msg==NULL?"":msg), \
- __FILE__, __LINE__); \
+ THIS_FILE, __LINE__); \
debugInit_exit((jvmtiError)error, msg); \
}
#define JDI_ASSERT(expression) \
do { \
if (gdata && gdata->assertOn && !(expression)) { \
- jdiAssertionFailed(__FILE__, __LINE__, #expression); \
+ jdiAssertionFailed(THIS_FILE, __LINE__, #expression); \
} \
} while (0)
#define JDI_ASSERT_MSG(expression, msg) \
do { \
if (gdata && gdata->assertOn && !(expression)) { \
- jdiAssertionFailed(__FILE__, __LINE__, msg); \
+ jdiAssertionFailed(THIS_FILE, __LINE__, msg); \
} \
} while (0)
#define JDI_ASSERT_FAILED(msg) \
- jdiAssertionFailed(__FILE__, __LINE__, msg)
+ jdiAssertionFailed(THIS_FILE, __LINE__, msg)
void do_pause(void);
--- a/jdk/src/share/back/log_messages.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/back/log_messages.h Fri Sep 14 13:52:30 2012 -0700
@@ -33,11 +33,15 @@
#define LOG_NULL ((void)0)
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#ifdef JDWP_LOGGING
-
#define _LOG(flavor,args) \
- (log_message_begin(flavor,__FILE__,__LINE__), \
+ (log_message_begin(flavor,THIS_FILE,__LINE__), \
log_message_end args)
#define LOG_TEST(flag) (gdata->log_flags & (flag))
--- a/jdk/src/share/bin/jli_util.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/bin/jli_util.h Fri Sep 14 13:52:30 2012 -0700
@@ -68,12 +68,23 @@
#define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3))
#define JLI_Snprintf _snprintf
void JLI_CmdToArgs(char *cmdline);
-#else
+#define JLI_Lseek _lseeki64
+#else /* NIXES */
#include <unistd.h>
#include <strings.h>
#define JLI_StrCaseCmp(p1, p2) strcasecmp((p1), (p2))
#define JLI_StrNCaseCmp(p1, p2, p3) strncasecmp((p1), (p2), (p3))
#define JLI_Snprintf snprintf
+#ifdef __solaris__
+#define JLI_Lseek llseek
+#endif
+#ifdef __linux__
+#define _LARGFILE64_SOURCE
+#define JLI_Lseek lseek64
+#endif
+#ifdef MACOSX
+#define JLI_Lseek lseek
+#endif
#endif /* _WIN32 */
/*
--- a/jdk/src/share/bin/manifest_info.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/bin/manifest_info.h Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,8 @@
#define CENSIG 0x02014b50L /* "PK\001\002" */
#define ENDSIG 0x06054b50L /* "PK\005\006" */
+#define ZIP64_ENDSIG 0x06064b50L /* "PK\006\006" */
+#define ZIP64_LOCSIG 0x07064b50L /* "PK\006\007" */
/*
* Header sizes including signatures
*/
@@ -45,12 +47,21 @@
#define CENHDR 46
#define ENDHDR 22
+#define ZIP64_ENDHDR 56 // ZIP64 end header size
+#define ZIP64_LOCHDR 20 // ZIP64 end loc header size
+#define ZIP64_EXTHDR 24 // EXT header size
+#define ZIP64_EXTID 1 // Extra field Zip64 header ID
+
+#define ZIP64_MAGICVAL 0xffffffffLL
+#define ZIP64_MAGICCOUNT 0xffff
+
/*
* Header field access macros
*/
#define CH(b, n) (((unsigned char *)(b))[n])
#define SH(b, n) (CH(b, n) | (CH(b, n+1) << 8))
-#define LG(b, n) (SH(b, n) | (SH(b, n+2) << 16))
+#define LG(b, n) ((SH(b, n) | (SH(b, n+2) << 16)) &0xffffffffUL)
+#define LL(b, n) (((jlong)LG(b, n)) | (((jlong)LG(b, n+4)) << 32))
#define GETSIG(b) LG(b, 0)
/*
@@ -102,6 +113,26 @@
#define ENDCOM(b) SH(b, 20) /* size of zip file comment */
/*
+ * Macros for getting Zip64 end of central directory header fields
+ */
+#define ZIP64_ENDLEN(b) LL(b, 4) /* size of zip64 end of central dir */
+#define ZIP64_ENDVEM(b) SH(b, 12) /* version made by */
+#define ZIP64_ENDVER(b) SH(b, 14) /* version needed to extract */
+#define ZIP64_ENDNMD(b) LG(b, 16) /* number of this disk */
+#define ZIP64_ENDDSK(b) LG(b, 20) /* disk number of start */
+#define ZIP64_ENDTOD(b) LL(b, 24) /* total number of entries on this disk */
+#define ZIP64_ENDTOT(b) LL(b, 32) /* total number of entries */
+#define ZIP64_ENDSIZ(b) LL(b, 40) /* central directory size in bytes */
+#define ZIP64_ENDOFF(b) LL(b, 48) /* offset of first CEN header */
+
+/*
+ * Macros for getting Zip64 end of central directory locator fields
+ */
+#define ZIP64_LOCDSK(b) LG(b, 4) /* disk number start */
+#define ZIP64_LOCOFF(b) LL(b, 8) /* offset of zip64 end */
+#define ZIP64_LOCTOT(b) LG(b, 16) /* total number of disks */
+
+/*
* A comment of maximum length of 64kb can follow the END record. This
* is the furthest the END record can be from the end of the file.
*/
@@ -119,7 +150,7 @@
typedef struct zentry { /* Zip file entry */
size_t isize; /* size of inflated data */
size_t csize; /* size of compressed data (zero if uncompressed) */
- off_t offset; /* position of compressed data */
+ jlong offset; /* position of compressed data */
int how; /* compression method (if any) */
} zentry;
--- a/jdk/src/share/bin/parse_manifest.c Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/bin/parse_manifest.c Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -61,7 +61,7 @@
if (entry->csize == (size_t) -1 || entry->isize == (size_t) -1 )
return (NULL);
- if (lseek(fd, entry->offset, SEEK_SET) < (off_t)0)
+ if (JLI_Lseek(fd, entry->offset, SEEK_SET) < (jlong)0)
return (NULL);
if ((in = malloc(entry->csize + 1)) == NULL)
return (NULL);
@@ -110,6 +110,38 @@
return (NULL);
}
+static jboolean zip64_present = JNI_FALSE;
+
+/*
+ * Checks to see if we have ZIP64 archive, and save
+ * the check for later use
+ */
+static int
+haveZIP64(Byte *p) {
+ jlong cenlen, cenoff, centot;
+ cenlen = ENDSIZ(p);
+ cenoff = ENDOFF(p);
+ centot = ENDTOT(p);
+ zip64_present = (cenlen == ZIP64_MAGICVAL ||
+ cenoff == ZIP64_MAGICVAL ||
+ centot == ZIP64_MAGICCOUNT);
+ return zip64_present;
+}
+
+static jlong
+find_end64(int fd, Byte *ep, jlong pos)
+{
+ jlong end64pos;
+ jlong bytes;
+ if ((end64pos = JLI_Lseek(fd, pos - ZIP64_LOCHDR, SEEK_SET)) < (jlong)0)
+ return -1;
+ if ((bytes = read(fd, ep, ZIP64_LOCHDR)) < 0)
+ return -1;
+ if (GETSIG(ep) == ZIP64_LOCSIG)
+ return end64pos;
+ return -1;
+}
+
/*
* A very little used routine to handle the case that zip file has
* a comment at the end. Believe it or not, the only way to find the
@@ -122,12 +154,12 @@
* Returns the offset of the END record in the file on success,
* -1 on failure.
*/
-static off_t
+static jlong
find_end(int fd, Byte *eb)
{
- off_t len;
- off_t pos;
- off_t flen;
+ jlong len;
+ jlong pos;
+ jlong flen;
int bytes;
Byte *cp;
Byte *endpos;
@@ -136,14 +168,16 @@
/*
* 99.44% (or more) of the time, there will be no comment at the
* end of the zip file. Try reading just enough to read the END
- * record from the end of the file.
+ * record from the end of the file, at this time we should also
+ * check to see if we have a ZIP64 archive.
*/
- if ((pos = lseek(fd, -ENDHDR, SEEK_END)) < (off_t)0)
+ if ((pos = JLI_Lseek(fd, -ENDHDR, SEEK_END)) < (jlong)0)
return (-1);
if ((bytes = read(fd, eb, ENDHDR)) < 0)
return (-1);
- if (GETSIG(eb) == ENDSIG)
- return (pos);
+ if (GETSIG(eb) == ENDSIG) {
+ return haveZIP64(eb) ? find_end64(fd, eb, pos) : pos;
+ }
/*
* Shucky-Darn,... There is a comment at the end of the zip file.
@@ -151,10 +185,10 @@
* Allocate and fill a buffer with enough of the zip file
* to meet the specification for a maximal comment length.
*/
- if ((flen = lseek(fd, 0, SEEK_END)) < (off_t)0)
+ if ((flen = JLI_Lseek(fd, 0, SEEK_END)) < (jlong)0)
return (-1);
len = (flen < END_MAXLEN) ? flen : END_MAXLEN;
- if (lseek(fd, -len, SEEK_END) < (off_t)0)
+ if (JLI_Lseek(fd, -len, SEEK_END) < (jlong)0)
return (-1);
if ((buffer = malloc(END_MAXLEN)) == NULL)
return (-1);
@@ -175,12 +209,92 @@
(cp + ENDHDR + ENDCOM(cp) == endpos)) {
(void) memcpy(eb, cp, ENDHDR);
free(buffer);
- return (flen - (endpos - cp));
+ pos = flen - (endpos - cp);
+ return haveZIP64(eb) ? find_end64(fd, eb, pos) : pos;
}
free(buffer);
return (-1);
}
+#define BUFSIZE (3 * 65536 + CENHDR + SIGSIZ)
+#define MINREAD 1024
+
+/*
+ * Computes and positions at the start of the CEN header, ie. the central
+ * directory, this will also return the offset if there is a zip file comment
+ * at the end of the archive, for most cases this would be 0.
+ */
+static jlong
+compute_cen(int fd, Byte *bp)
+{
+ int bytes;
+ Byte *p;
+ jlong base_offset;
+ jlong offset;
+ char buffer[MINREAD];
+ p = buffer;
+ /*
+ * Read the END Header, which is the starting point for ZIP files.
+ * (Clearly designed to make writing a zip file easier than reading
+ * one. Now isn't that precious...)
+ */
+ if ((base_offset = find_end(fd, bp)) == -1) {
+ return (-1);
+ }
+ p = bp;
+ /*
+ * There is a historical, but undocumented, ability to allow for
+ * additional "stuff" to be prepended to the zip/jar file. It seems
+ * that this has been used to prepend an actual java launcher
+ * executable to the jar on Windows. Although this is just another
+ * form of statically linking a small piece of the JVM to the
+ * application, we choose to continue to support it. Note that no
+ * guarantees have been made (or should be made) to the customer that
+ * this will continue to work.
+ *
+ * Therefore, calculate the base offset of the zip file (within the
+ * expanded file) by assuming that the central directory is followed
+ * immediately by the end record.
+ */
+ if (zip64_present) {
+ if ((offset = ZIP64_LOCOFF(p)) < (jlong)0) {
+ return -1;
+ }
+ if (JLI_Lseek(fd, offset, SEEK_SET) < (jlong) 0) {
+ return (-1);
+ }
+ if ((bytes = read(fd, buffer, MINREAD)) < 0) {
+ return (-1);
+ }
+ if (GETSIG(buffer) != ZIP64_ENDSIG) {
+ return -1;
+ }
+ if ((offset = ZIP64_ENDOFF(buffer)) < (jlong)0) {
+ return -1;
+ }
+ if (JLI_Lseek(fd, offset, SEEK_SET) < (jlong)0) {
+ return (-1);
+ }
+ p = buffer;
+ base_offset = base_offset - ZIP64_ENDSIZ(p) - ZIP64_ENDOFF(p) - ZIP64_ENDHDR;
+ } else {
+ base_offset = base_offset - ENDSIZ(p) - ENDOFF(p);
+ /*
+ * The END Header indicates the start of the Central Directory
+ * Headers. Remember that the desired Central Directory Header (CEN)
+ * will almost always be the second one and the first one is a small
+ * directory entry ("META-INF/"). Keep the code optimized for
+ * that case.
+ *
+ * Seek to the beginning of the Central Directory.
+ */
+ if (JLI_Lseek(fd, base_offset + ENDOFF(p), SEEK_SET) < (jlong) 0) {
+ return (-1);
+ }
+ }
+ return base_offset;
+}
+
/*
* Locate the manifest file with the zip/jar file.
*
@@ -208,9 +322,6 @@
* a typical jar file (META-INF and META-INF/MANIFEST.MF). Keep this factoid
* in mind when optimizing this code.
*/
-#define BUFSIZE (3 * 65536 + CENHDR + SIGSIZ)
-#define MINREAD 1024
-
static int
find_file(int fd, zentry *entry, const char *file_name)
{
@@ -218,7 +329,7 @@
int res;
int entry_size;
int read_size;
- int base_offset;
+ jlong base_offset;
Byte *p;
Byte *bp;
Byte *buffer;
@@ -228,54 +339,18 @@
return(-1);
}
- p = buffer;
bp = buffer;
-
- /*
- * Read the END Header, which is the starting point for ZIP files.
- * (Clearly designed to make writing a zip file easier than reading
- * one. Now isn't that precious...)
- */
- if ((base_offset = find_end(fd, bp)) == -1) {
+ base_offset = compute_cen(fd, bp);
+ if (base_offset == -1) {
free(buffer);
- return (-1);
+ return -1;
}
- /*
- * There is a historical, but undocumented, ability to allow for
- * additional "stuff" to be prepended to the zip/jar file. It seems
- * that this has been used to prepend an actual java launcher
- * executable to the jar on Windows. Although this is just another
- * form of statically linking a small piece of the JVM to the
- * application, we choose to continue to support it. Note that no
- * guarantees have been made (or should be made) to the customer that
- * this will continue to work.
- *
- * Therefore, calculate the base offset of the zip file (within the
- * expanded file) by assuming that the central directory is followed
- * immediately by the end record.
- */
- base_offset = base_offset - ENDSIZ(p) - ENDOFF(p);
-
- /*
- * The END Header indicates the start of the Central Directory
- * Headers. Remember that the desired Central Directory Header (CEN)
- * will almost always be the second one and the first one is a small
- * directory entry ("META-INF/"). Keep the code optimized for
- * that case.
- *
- * Begin by seeking to the beginning of the Central Directory and
- * reading in the first buffer full of bits.
- */
- if (lseek(fd, base_offset + ENDOFF(p), SEEK_SET) < (off_t)0) {
- free(buffer);
- return (-1);
- }
if ((bytes = read(fd, bp, MINREAD)) < 0) {
free(buffer);
return (-1);
}
-
+ p = bp;
/*
* Loop through the Central Directory Headers. Note that a valid zip/jar
* must have an ENDHDR (with ENDSIG) after the Central Directory.
@@ -319,7 +394,7 @@
*/
if ((size_t)CENNAM(p) == JLI_StrLen(file_name) &&
memcmp((p + CENHDR), file_name, JLI_StrLen(file_name)) == 0) {
- if (lseek(fd, base_offset + CENOFF(p), SEEK_SET) < (off_t)0) {
+ if (JLI_Lseek(fd, base_offset + CENOFF(p), SEEK_SET) < (jlong)0) {
free(buffer);
return (-1);
}
@@ -487,6 +562,9 @@
char *splashscreen_name = NULL;
if ((fd = open(jarfile, O_RDONLY
+#ifdef O_LARGEFILE
+ | O_LARGEFILE /* large file mode on solaris */
+#endif
#ifdef O_BINARY
| O_BINARY /* use binary mode on windows */
#endif
--- a/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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,18 +47,122 @@
* @see OutputFeedback
*/
-public final class AESCipher extends CipherSpi {
+abstract class AESCipher extends CipherSpi {
+ public static final class General extends AESCipher {
+ public General() {
+ super(-1);
+ }
+ }
+ abstract static class OidImpl extends AESCipher {
+ protected OidImpl(int keySize, String mode, String padding) {
+ super(keySize);
+ try {
+ engineSetMode(mode);
+ engineSetPadding(padding);
+ } catch (GeneralSecurityException gse) {
+ // internal error; re-throw as provider exception
+ ProviderException pe =new ProviderException("Internal Error");
+ pe.initCause(gse);
+ throw pe;
+ }
+ }
+ }
+ public static final class AES128_ECB_NoPadding extends OidImpl {
+ public AES128_ECB_NoPadding() {
+ super(16, "ECB", "NOPADDING");
+ }
+ }
+ public static final class AES192_ECB_NoPadding extends OidImpl {
+ public AES192_ECB_NoPadding() {
+ super(24, "ECB", "NOPADDING");
+ }
+ }
+ public static final class AES256_ECB_NoPadding extends OidImpl {
+ public AES256_ECB_NoPadding() {
+ super(32, "ECB", "NOPADDING");
+ }
+ }
+ public static final class AES128_CBC_NoPadding extends OidImpl {
+ public AES128_CBC_NoPadding() {
+ super(16, "CBC", "NOPADDING");
+ }
+ }
+ public static final class AES192_CBC_NoPadding extends OidImpl {
+ public AES192_CBC_NoPadding() {
+ super(24, "CBC", "NOPADDING");
+ }
+ }
+ public static final class AES256_CBC_NoPadding extends OidImpl {
+ public AES256_CBC_NoPadding() {
+ super(32, "CBC", "NOPADDING");
+ }
+ }
+ public static final class AES128_OFB_NoPadding extends OidImpl {
+ public AES128_OFB_NoPadding() {
+ super(16, "OFB", "NOPADDING");
+ }
+ }
+ public static final class AES192_OFB_NoPadding extends OidImpl {
+ public AES192_OFB_NoPadding() {
+ super(24, "OFB", "NOPADDING");
+ }
+ }
+ public static final class AES256_OFB_NoPadding extends OidImpl {
+ public AES256_OFB_NoPadding() {
+ super(32, "OFB", "NOPADDING");
+ }
+ }
+ public static final class AES128_CFB_NoPadding extends OidImpl {
+ public AES128_CFB_NoPadding() {
+ super(16, "CFB", "NOPADDING");
+ }
+ }
+ public static final class AES192_CFB_NoPadding extends OidImpl {
+ public AES192_CFB_NoPadding() {
+ super(24, "CFB", "NOPADDING");
+ }
+ }
+ public static final class AES256_CFB_NoPadding extends OidImpl {
+ public AES256_CFB_NoPadding() {
+ super(32, "CFB", "NOPADDING");
+ }
+ }
+
+ // utility method used by AESCipher and AESWrapCipher
+ static final void checkKeySize(Key key, int fixedKeySize)
+ throws InvalidKeyException {
+ if (fixedKeySize != -1) {
+ if (key == null) {
+ throw new InvalidKeyException("The key must not be null");
+ }
+ byte[] value = key.getEncoded();
+ if (value == null) {
+ throw new InvalidKeyException("Key encoding must not be null");
+ } else if (value.length != fixedKeySize) {
+ throw new InvalidKeyException("The key must be " +
+ fixedKeySize*8 + " bits");
+ }
+ }
+ }
+
/*
* internal CipherCore object which does the real work.
*/
private CipherCore core = null;
+ /*
+ * needed to support AES oids which associates a fixed key size
+ * to the cipher object.
+ */
+ private final int fixedKeySize; // in bytes, -1 if no restriction
+
/**
* Creates an instance of AES cipher with default ECB mode and
* PKCS5Padding.
*/
- public AESCipher() {
+ protected AESCipher(int keySize) {
core = new CipherCore(new AESCrypt(), AESConstants.AES_BLOCK_SIZE);
+ fixedKeySize = keySize;
}
/**
@@ -183,6 +287,7 @@
*/
protected void engineInit(int opmode, Key key, SecureRandom random)
throws InvalidKeyException {
+ checkKeySize(key, fixedKeySize);
core.init(opmode, key, random);
}
@@ -214,6 +319,7 @@
AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
+ checkKeySize(key, fixedKeySize);
core.init(opmode, key, params, random);
}
@@ -221,6 +327,7 @@
AlgorithmParameters params,
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
+ checkKeySize(key, fixedKeySize);
core.init(opmode, key, params, random);
}
--- a/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2012, 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
@@ -43,8 +43,27 @@
*
* @see AESCipher
*/
-public final class AESWrapCipher extends CipherSpi {
-
+abstract class AESWrapCipher extends CipherSpi {
+ public static final class General extends AESWrapCipher {
+ public General() {
+ super(-1);
+ }
+ }
+ public static final class AES128 extends AESWrapCipher {
+ public AES128() {
+ super(16);
+ }
+ }
+ public static final class AES192 extends AESWrapCipher {
+ public AES192() {
+ super(24);
+ }
+ }
+ public static final class AES256 extends AESWrapCipher {
+ public AES256() {
+ super(32);
+ }
+ }
private static final byte[] IV = {
(byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6,
(byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6
@@ -62,12 +81,20 @@
*/
private boolean decrypting = false;
+ /*
+ * needed to support AES oids which associates a fixed key size
+ * to the cipher object.
+ */
+ private final int fixedKeySize; // in bytes, -1 if no restriction
+
/**
* Creates an instance of AES KeyWrap cipher with default
* mode, i.e. "ECB" and padding scheme, i.e. "NoPadding".
*/
- public AESWrapCipher() {
+ public AESWrapCipher(int keySize) {
cipher = new AESCrypt();
+ fixedKeySize = keySize;
+
}
/**
@@ -170,6 +197,7 @@
throw new UnsupportedOperationException("This cipher can " +
"only be used for key wrapping and unwrapping");
}
+ AESCipher.checkKeySize(key, fixedKeySize);
cipher.init(decrypting, key.getAlgorithm(), key.getEncoded());
}
--- a/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -80,10 +80,10 @@
* @param random the source of randomness
*/
public void initialize(int keysize, SecureRandom random) {
- if ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0)) {
+ if ((keysize < 512) || (keysize > 2048) || (keysize % 64 != 0)) {
throw new InvalidParameterException("Keysize must be multiple "
+ "of 64, and can only range "
- + "from 512 to 1024 "
+ + "from 512 to 2048 "
+ "(inclusive)");
}
this.pSize = keysize;
@@ -115,11 +115,11 @@
params = (DHParameterSpec)algParams;
pSize = params.getP().bitLength();
- if ((pSize < 512) || (pSize > 1024) ||
+ if ((pSize < 512) || (pSize > 2048) ||
(pSize % 64 != 0)) {
throw new InvalidAlgorithmParameterException
("Prime size must be multiple of 64, and can only range "
- + "from 512 to 1024 (inclusive)");
+ + "from 512 to 2048 (inclusive)");
}
// exponent size is optional, could be 0
@@ -156,10 +156,11 @@
BigInteger g = params.getG();
if (lSize <= 0) {
+ lSize = pSize >> 1;
// use an exponent size of (pSize / 2) but at least 384 bits
- lSize = Math.max(384, pSize >> 1);
- // if lSize is larger than pSize, limit by pSize
- lSize = Math.min(lSize, pSize);
+ if (lSize < 384) {
+ lSize = 384;
+ }
}
BigInteger x;
--- a/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -67,10 +67,10 @@
* @param random the source of randomness
*/
protected void engineInit(int keysize, SecureRandom random) {
- if ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0)) {
+ if ((keysize < 512) || (keysize > 2048) || (keysize % 64 != 0)) {
throw new InvalidParameterException("Keysize must be multiple "
+ "of 64, and can only range "
- + "from 512 to 1024 "
+ + "from 512 to 2048 "
+ "(inclusive)");
}
this.primeSize = keysize;
@@ -99,10 +99,10 @@
DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec;
primeSize = dhParamSpec.getPrimeSize();
- if ((primeSize<512) || (primeSize>1024) || (primeSize%64 != 0)) {
+ if ((primeSize<512) || (primeSize>2048) || (primeSize%64 != 0)) {
throw new InvalidAlgorithmParameterException
("Modulus size must be multiple of 64, and can only range "
- + "from 512 to 1024 (inclusive)");
+ + "from 512 to 2048 (inclusive)");
}
exponentSize = dhParamSpec.getExponentSize();
--- a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java Fri Sep 14 13:52:30 2012 -0700
@@ -167,17 +167,67 @@
put("Cipher.Blowfish SupportedPaddings", BLOCK_PADS);
put("Cipher.Blowfish SupportedKeyFormats", "RAW");
- put("Cipher.AES", "com.sun.crypto.provider.AESCipher");
+ put("Cipher.AES", "com.sun.crypto.provider.AESCipher$General");
put("Alg.Alias.Cipher.Rijndael", "AES");
put("Cipher.AES SupportedModes", BLOCK_MODES128);
put("Cipher.AES SupportedPaddings", BLOCK_PADS);
put("Cipher.AES SupportedKeyFormats", "RAW");
- put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher");
+ put("Cipher.AES_128/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_ECB_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding");
+ put("Cipher.AES_128/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CBC_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding");
+ put("Cipher.AES_128/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_OFB_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding");
+ put("Cipher.AES_128/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
+
+ put("Cipher.AES_192/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding");
+ put("Cipher.AES_192/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CBC_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding");
+ put("Cipher.AES_192/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_OFB_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding");
+ put("Cipher.AES_192/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
+
+
+ put("Cipher.AES_256/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding");
+ put("Cipher.AES_256/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CBC_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding");
+ put("Cipher.AES_256/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_OFB_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding");
+ put("Cipher.AES_256/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
+
+ put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher$General");
put("Cipher.AESWrap SupportedModes", "ECB");
put("Cipher.AESWrap SupportedPaddings", "NOPADDING");
put("Cipher.AESWrap SupportedKeyFormats", "RAW");
+ put("Cipher.AESWrap_128", "com.sun.crypto.provider.AESWrapCipher$AES128");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.5", "AESWrap_128");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.5", "AESWrap_128");
+ put("Cipher.AESWrap_192", "com.sun.crypto.provider.AESWrapCipher$AES192");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.25", "AESWrap_192");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.25", "AESWrap_192");
+ put("Cipher.AESWrap_256", "com.sun.crypto.provider.AESWrapCipher$AES256");
+ put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.45", "AESWrap_256");
+ put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.45", "AESWrap_256");
+
put("Cipher.RC2",
"com.sun.crypto.provider.RC2Cipher");
put("Cipher.RC2 SupportedModes", BLOCK_MODES);
@@ -192,7 +242,7 @@
put("Cipher.ARCFOUR SupportedKeyFormats", "RAW");
/*
- * Key(pair) Generator engines
+ * Key(pair) Generator engines
*/
put("KeyGenerator.DES",
"com.sun.crypto.provider.DESKeyGenerator");
@@ -221,6 +271,8 @@
put("KeyGenerator.HmacSHA1",
"com.sun.crypto.provider.HmacSHA1KeyGenerator");
+ put("Alg.Alias.KeyGenerator.OID.1.2.840.113549.2.7", "HmacSHA1");
+ put("Alg.Alias.KeyGenerator.1.2.840.113549.2.7", "HmacSHA1");
put("KeyGenerator.HmacSHA224",
"com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA224");
@@ -326,14 +378,12 @@
"com.sun.crypto.provider.AESParameters");
put("Alg.Alias.AlgorithmParameters.Rijndael", "AES");
-
put("AlgorithmParameters.RC2",
"com.sun.crypto.provider.RC2Parameters");
put("AlgorithmParameters.OAEP",
"com.sun.crypto.provider.OAEPParameters");
-
/*
* Key factories
*/
@@ -403,6 +453,8 @@
*/
put("Mac.HmacMD5", "com.sun.crypto.provider.HmacMD5");
put("Mac.HmacSHA1", "com.sun.crypto.provider.HmacSHA1");
+ put("Alg.Alias.Mac.OID.1.2.840.113549.2.7", "HmacSHA1");
+ put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1");
put("Mac.HmacSHA224",
"com.sun.crypto.provider.HmacCore$HmacSHA224");
put("Alg.Alias.Mac.OID.1.2.840.113549.2.8", "HmacSHA224");
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java Fri Sep 14 13:52:30 2012 -0700
@@ -30,6 +30,8 @@
import java.awt.Event;
import java.awt.KeyEventPostProcessor;
import java.awt.Window;
+import java.awt.Toolkit;
+import sun.awt.SunToolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
@@ -125,7 +127,19 @@
}
JMenu menu = mbar != null ? mbar.getMenu(0) : null;
- if (menu != null) {
+ // It might happen that the altRelease event is processed
+ // with a reasonable delay since it has been generated.
+ // Here we check the last deactivation time of the containing
+ // window. If this time appears to be greater than the altRelease
+ // event time the event is skipped to avoid unexpected menu
+ // activation. See 7121442.
+ boolean skip = false;
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ if (tk instanceof SunToolkit) {
+ skip = ev.getWhen() <= ((SunToolkit)tk).getWindowDeactivationTime(winAncestor);
+ }
+
+ if (menu != null && !skip) {
MenuElement[] path = new MenuElement[2];
path[0] = mbar;
path[1] = menu;
--- a/jdk/src/share/classes/java/awt/Component.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/awt/Component.java Fri Sep 14 13:52:30 2012 -0700
@@ -4710,7 +4710,10 @@
/*
* 0. Set timestamp and modifiers of current event.
*/
- EventQueue.setCurrentEventAndMostRecentTime(e);
+ if (!(e instanceof KeyEvent)) {
+ // Timestamp of a key event is set later in DKFM.preDispatchKeyEvent(KeyEvent).
+ EventQueue.setCurrentEventAndMostRecentTime(e);
+ }
/*
* 1. Pre-dispatchers. Do any necessary retargeting/reordering here
@@ -7606,13 +7609,33 @@
boolean focusedWindowChangeAllowed,
CausedFocusEvent.Cause cause)
{
+ // 1) Check if the event being dispatched is a system-generated mouse event.
+ AWTEvent currentEvent = EventQueue.getCurrentEvent();
+ if (currentEvent instanceof MouseEvent &&
+ SunToolkit.isSystemGenerated(currentEvent))
+ {
+ // 2) Sanity check: if the mouse event component source belongs to the same containing window.
+ Component source = ((MouseEvent)currentEvent).getComponent();
+ if (source == null || source.getContainingWindow() == getContainingWindow()) {
+ focusLog.finest("requesting focus by mouse event \"in window\"");
+
+ // If both the conditions are fulfilled the focus request should be strictly
+ // bounded by the toplevel window. It's assumed that the mouse event activates
+ // the window (if it wasn't active) and this makes it possible for a focus
+ // request with a strong in-window requirement to change focus in the bounds
+ // of the toplevel. If, by any means, due to asynchronous nature of the event
+ // dispatching mechanism, the window happens to be natively inactive by the time
+ // this focus request is eventually handled, it should not re-activate the
+ // toplevel. Otherwise the result may not meet user expectations. See 6981400.
+ focusedWindowChangeAllowed = false;
+ }
+ }
if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) {
if (focusLog.isLoggable(PlatformLogger.FINEST)) {
focusLog.finest("requestFocus is not accepted");
}
return false;
}
-
// Update most-recent map
KeyboardFocusManager.setMostRecentFocusOwner(this);
@@ -7645,7 +7668,15 @@
}
// Focus this Component
- long time = EventQueue.getMostRecentEventTime();
+ long time = 0;
+ if (EventQueue.isDispatchThread()) {
+ time = Toolkit.getEventQueue().getMostRecentKeyEventTime();
+ } else {
+ // A focus request made from outside EDT should not be associated with any event
+ // and so its time stamp is simply set to the current time.
+ time = System.currentTimeMillis();
+ }
+
boolean success = peer.requestFocus
(this, temporary, focusedWindowChangeAllowed, time, cause);
if (!success) {
--- a/jdk/src/share/classes/java/awt/Container.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/awt/Container.java Fri Sep 14 13:52:30 2012 -0700
@@ -2863,7 +2863,7 @@
// keep the KeyEvents from being dispatched
// until the focus has been transfered
- long time = Toolkit.getEventQueue().getMostRecentEventTime();
+ long time = Toolkit.getEventQueue().getMostRecentKeyEventTime();
Component predictedFocusOwner = (Component.isInstanceOf(this, "javax.swing.JInternalFrame")) ? ((javax.swing.JInternalFrame)(this)).getMostRecentFocusOwner() : null;
if (predictedFocusOwner != null) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().
--- a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Fri Sep 14 13:52:30 2012 -0700
@@ -41,6 +41,7 @@
import sun.awt.SunToolkit;
import sun.awt.AWTAccessor;
import sun.awt.CausedFocusEvent;
+import sun.awt.TimedWindowEvent;
/**
* The default KeyboardFocusManager for AWT applications. Focus traversal is
@@ -72,8 +73,8 @@
private WeakReference<Window> realOppositeWindowWR = NULL_WINDOW_WR;
private WeakReference<Component> realOppositeComponentWR = NULL_COMPONENT_WR;
private int inSendMessage;
- private LinkedList enqueuedKeyEvents = new LinkedList(),
- typeAheadMarkers = new LinkedList();
+ private LinkedList<KeyEvent> enqueuedKeyEvents = new LinkedList<KeyEvent>();
+ private LinkedList<TypeAheadMarker> typeAheadMarkers = new LinkedList<TypeAheadMarker>();
private boolean consumeNextKeyTyped;
static {
@@ -269,6 +270,31 @@
return se.dispatched;
}
+ /*
+ * Checks if the focus window event follows key events waiting in the type-ahead
+ * queue (if any). This may happen when a user types ahead in the window, the client
+ * listeners hang EDT for a while, and the user switches b/w toplevels. In that
+ * case the focus window events may be dispatched before the type-ahead events
+ * get handled. This may lead to wrong focus behavior and in order to avoid it,
+ * the focus window events are reposted to the end of the event queue. See 6981400.
+ */
+ private boolean repostIfFollowsKeyEvents(WindowEvent e) {
+ if (!(e instanceof TimedWindowEvent)) {
+ return false;
+ }
+ TimedWindowEvent we = (TimedWindowEvent)e;
+ long time = we.getWhen();
+ synchronized (this) {
+ for (KeyEvent ke: enqueuedKeyEvents) {
+ if (time >= ke.getWhen()) {
+ SunToolkit.postEvent(AppContext.getAppContext(), new SequencedEvent(e));
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* This method is called by the AWT event dispatcher requesting that the
* current KeyboardFocusManager dispatch the specified event on its behalf.
@@ -287,6 +313,10 @@
if (focusLog.isLoggable(PlatformLogger.FINE) && (e instanceof WindowEvent || e instanceof FocusEvent)) focusLog.fine("" + e);
switch (e.getID()) {
case WindowEvent.WINDOW_GAINED_FOCUS: {
+ if (repostIfFollowsKeyEvents((WindowEvent)e)) {
+ break;
+ }
+
WindowEvent we = (WindowEvent)e;
Window oldFocusedWindow = getGlobalFocusedWindow();
Window newFocusedWindow = we.getWindow();
@@ -646,6 +676,10 @@
}
case WindowEvent.WINDOW_LOST_FOCUS: {
+ if (repostIfFollowsKeyEvents((WindowEvent)e)) {
+ break;
+ }
+
WindowEvent we = (WindowEvent)e;
Window currentFocusedWindow = getGlobalFocusedWindow();
Window losingFocusWindow = we.getWindow();
@@ -825,10 +859,9 @@
ke = null;
synchronized (this) {
if (enqueuedKeyEvents.size() != 0) {
- ke = (KeyEvent)enqueuedKeyEvents.getFirst();
+ ke = enqueuedKeyEvents.getFirst();
if (typeAheadMarkers.size() != 0) {
- TypeAheadMarker marker = (TypeAheadMarker)
- typeAheadMarkers.getFirst();
+ TypeAheadMarker marker = typeAheadMarkers.getFirst();
// Fixed 5064013: may appears that the events have the same time
// if (ke.getWhen() >= marker.after) {
// The fix is rolled out.
@@ -857,9 +890,9 @@
focusLog.finest(">>> Markers dump, time: {0}", System.currentTimeMillis());
synchronized (this) {
if (typeAheadMarkers.size() != 0) {
- Iterator iter = typeAheadMarkers.iterator();
+ Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator();
while (iter.hasNext()) {
- TypeAheadMarker marker = (TypeAheadMarker)iter.next();
+ TypeAheadMarker marker = iter.next();
focusLog.finest(" {0}", marker);
}
}
@@ -881,8 +914,7 @@
KeyEvent ke = (KeyEvent)e;
synchronized (this) {
if (e.isPosted && typeAheadMarkers.size() != 0) {
- TypeAheadMarker marker = (TypeAheadMarker)
- typeAheadMarkers.getFirst();
+ TypeAheadMarker marker = typeAheadMarkers.getFirst();
// Fixed 5064013: may appears that the events have the same time
// if (ke.getWhen() >= marker.after) {
// The fix is rolled out.
@@ -915,12 +947,10 @@
synchronized (this) {
boolean found = false;
if (hasMarker(target)) {
- for (Iterator iter = typeAheadMarkers.iterator();
+ for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator();
iter.hasNext(); )
{
- if (((TypeAheadMarker)iter.next()).untilFocused ==
- target)
- {
+ if (iter.next().untilFocused == target) {
found = true;
} else if (found) {
break;
@@ -955,8 +985,8 @@
* @since 1.5
*/
private boolean hasMarker(Component comp) {
- for (Iterator iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
- if (((TypeAheadMarker)iter.next()).untilFocused == comp) {
+ for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
+ if (iter.next().untilFocused == comp) {
return true;
}
}
@@ -982,11 +1012,10 @@
return true;
}
- // Explicitly set the current event and most recent timestamp here in
- // addition to the call in Component.dispatchEventImpl. Because
- // KeyEvents can be delivered in response to a FOCUS_GAINED event, the
- // current timestamp may be incorrect. We need to set it here so that
- // KeyEventDispatchers will use the correct time.
+ // Explicitly set the key event timestamp here (not in Component.dispatchEventImpl):
+ // - A key event is anyway passed to this method which starts its actual dispatching.
+ // - If a key event is put to the type ahead queue, its time stamp should not be registered
+ // until its dispatching actually starts (by this method).
EventQueue.setCurrentEventAndMostRecentTime(ke);
/**
@@ -1174,10 +1203,10 @@
int insertionIndex = 0,
i = typeAheadMarkers.size();
- ListIterator iter = typeAheadMarkers.listIterator(i);
+ ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator(i);
for (; i > 0; i--) {
- TypeAheadMarker marker = (TypeAheadMarker)iter.previous();
+ TypeAheadMarker marker = iter.previous();
if (marker.after <= after) {
insertionIndex = i;
break;
@@ -1213,12 +1242,12 @@
after, untilFocused);
TypeAheadMarker marker;
- ListIterator iter = typeAheadMarkers.listIterator
+ ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator
((after >= 0) ? typeAheadMarkers.size() : 0);
if (after < 0) {
while (iter.hasNext()) {
- marker = (TypeAheadMarker)iter.next();
+ marker = iter.next();
if (marker.untilFocused == untilFocused)
{
iter.remove();
@@ -1227,7 +1256,7 @@
}
} else {
while (iter.hasPrevious()) {
- marker = (TypeAheadMarker)iter.previous();
+ marker = iter.previous();
if (marker.untilFocused == untilFocused &&
marker.after == after)
{
@@ -1255,8 +1284,8 @@
long start = -1;
- for (Iterator iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
- TypeAheadMarker marker = (TypeAheadMarker)iter.next();
+ for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
+ TypeAheadMarker marker = iter.next();
Component toTest = marker.untilFocused;
boolean match = (toTest == comp);
while (!match && toTest != null && !(toTest instanceof Window)) {
@@ -1287,8 +1316,8 @@
return;
}
- for (Iterator iter = enqueuedKeyEvents.iterator(); iter.hasNext(); ) {
- KeyEvent ke = (KeyEvent)iter.next();
+ for (Iterator<KeyEvent> iter = enqueuedKeyEvents.iterator(); iter.hasNext(); ) {
+ KeyEvent ke = iter.next();
long time = ke.getWhen();
if (start < time && (end < 0 || time <= end)) {
--- a/jdk/src/share/classes/java/awt/Dialog.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/awt/Dialog.java Fri Sep 14 13:52:30 2012 -0700
@@ -924,7 +924,7 @@
isEnabled() && !isModalBlocked()) {
// keep the KeyEvents from being dispatched
// until the focus has been transfered
- time.set(Toolkit.getEventQueue().getMostRecentEventTimeEx());
+ time.set(Toolkit.getEventQueue().getMostRecentKeyEventTime());
KeyboardFocusManager.getCurrentKeyboardFocusManager().
enqueueKeyEvents(time.get(), toFocus);
}
--- a/jdk/src/share/classes/java/awt/EventQueue.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/awt/EventQueue.java Fri Sep 14 13:52:30 2012 -0700
@@ -162,6 +162,11 @@
*/
private long mostRecentEventTime = System.currentTimeMillis();
+ /*
+ * The time stamp of the last KeyEvent .
+ */
+ private long mostRecentKeyEventTime = System.currentTimeMillis();
+
/**
* The modifiers field of the current event, if the current event is an
* InputEvent or ActionEvent.
@@ -1142,6 +1147,15 @@
}
}
+ synchronized long getMostRecentKeyEventTime() {
+ pushPopLock.lock();
+ try {
+ return mostRecentKeyEventTime;
+ } finally {
+ pushPopLock.unlock();
+ }
+ }
+
static void setCurrentEventAndMostRecentTime(AWTEvent e) {
Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e);
}
@@ -1166,6 +1180,9 @@
if (e instanceof InputEvent) {
InputEvent ie = (InputEvent)e;
mostRecentEventTime2 = ie.getWhen();
+ if (e instanceof KeyEvent) {
+ mostRecentKeyEventTime = ie.getWhen();
+ }
} else if (e instanceof InputMethodEvent) {
InputMethodEvent ime = (InputMethodEvent)e;
mostRecentEventTime2 = ime.getWhen();
--- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Fri Sep 14 13:52:30 2012 -0700
@@ -445,7 +445,7 @@
private void initPeer() {
Toolkit tk = Toolkit.getDefaultToolkit();
KeyboardFocusManagerPeerProvider peerProvider = (KeyboardFocusManagerPeerProvider)tk;
- peer = peerProvider.createKeyboardFocusManagerPeer(this);
+ peer = peerProvider.getKeyboardFocusManagerPeer();
}
/**
--- a/jdk/src/share/classes/java/awt/SequencedEvent.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/awt/SequencedEvent.java Fri Sep 14 13:52:30 2012 -0700
@@ -26,6 +26,7 @@
package java.awt;
import java.util.LinkedList;
+import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
@@ -54,6 +55,17 @@
private AppContext appContext;
private boolean disposed;
+ static {
+ AWTAccessor.setSequencedEventAccessor(new AWTAccessor.SequencedEventAccessor() {
+ public AWTEvent getNested(AWTEvent sequencedEvent) {
+ return ((SequencedEvent)sequencedEvent).nested;
+ }
+ public boolean isSequencedEvent(AWTEvent event) {
+ return event instanceof SequencedEvent;
+ }
+ });
+ }
+
/**
* Constructs a new SequencedEvent which will dispatch the specified
* nested event.
--- a/jdk/src/share/classes/java/awt/peer/KeyboardFocusManagerPeer.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/awt/peer/KeyboardFocusManagerPeer.java Fri Sep 14 13:52:30 2012 -0700
@@ -34,6 +34,14 @@
public interface KeyboardFocusManagerPeer {
/**
+ * Sets the window that should become the focused window.
+ *
+ * @param win the window that should become the focused window
+ *
+ */
+ void setCurrentFocusedWindow(Window win);
+
+ /**
* Returns the currently focused window.
*
* @return the currently focused window
--- a/jdk/src/share/classes/java/beans/Introspector.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/beans/Introspector.java Fri Sep 14 13:52:30 2012 -0700
@@ -1460,7 +1460,7 @@
private PropertyDescriptor[] properties;
private int defaultProperty;
private MethodDescriptor[] methods;
- private final Reference<BeanInfo> targetBeanInfoRef;
+ private Reference<BeanInfo> targetBeanInfoRef;
public GenericBeanInfo(BeanDescriptor beanDescriptor,
EventSetDescriptor[] events, int defaultEvent,
@@ -1472,7 +1472,9 @@
this.properties = properties;
this.defaultProperty = defaultProperty;
this.methods = methods;
- this.targetBeanInfoRef = new SoftReference<>(targetBeanInfo);
+ this.targetBeanInfoRef = (targetBeanInfo != null)
+ ? new SoftReference<>(targetBeanInfo)
+ : null;
}
/**
@@ -1539,10 +1541,25 @@
}
public java.awt.Image getIcon(int iconKind) {
- BeanInfo targetBeanInfo = this.targetBeanInfoRef.get();
+ BeanInfo targetBeanInfo = getTargetBeanInfo();
if (targetBeanInfo != null) {
return targetBeanInfo.getIcon(iconKind);
}
return super.getIcon(iconKind);
}
+
+ private BeanInfo getTargetBeanInfo() {
+ if (this.targetBeanInfoRef == null) {
+ return null;
+ }
+ BeanInfo targetBeanInfo = this.targetBeanInfoRef.get();
+ if (targetBeanInfo == null) {
+ targetBeanInfo = ThreadGroupContext.getContext().getBeanInfoFinder()
+ .find(this.beanDescriptor.getBeanClass());
+ if (targetBeanInfo != null) {
+ this.targetBeanInfoRef = new SoftReference<>(targetBeanInfo);
+ }
+ }
+ return targetBeanInfo;
+ }
}
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java Fri Sep 14 13:52:30 2012 -0700
@@ -109,6 +109,10 @@
if (writeMethodName != null && getWriteMethod() == null) {
throw new IntrospectionException("Method not found: " + writeMethodName);
}
+ boundInitialization(beanClass);
+ }
+
+ private void boundInitialization(Class<?> beanClass) {
// 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.
@@ -159,6 +163,7 @@
setReadMethod(read);
setWriteMethod(write);
this.baseName = base;
+ boundInitialization(bean);
}
/**
@@ -588,7 +593,7 @@
Method yw = y.getWriteMethod();
try {
- if (yw != null && yw.getDeclaringClass() == getClass0()) {
+ if (yw != null) {
setWriteMethod(yw);
} else {
setWriteMethod(xw);
--- a/jdk/src/share/classes/java/beans/XMLEncoder.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/beans/XMLEncoder.java Fri Sep 14 13:52:30 2012 -0700
@@ -631,7 +631,12 @@
}
if (d.name != null) {
- outputXML(isArgument ? "object" : "void", " idref=" + quote(d.name), value);
+ if (isArgument) {
+ writeln("<object idref=" + quote(d.name) + "/>");
+ }
+ else {
+ outputXML("void", " idref=" + quote(d.name), value);
+ }
}
else if (d.exp != null) {
outputStatement(d.exp, outer, isArgument);
@@ -710,12 +715,14 @@
}
else {
d.refs = 2;
- getValueData(target).refs++;
- List<Statement> statements = statementList(target);
- if (!statements.contains(exp)) {
- statements.add(exp);
+ if (d.name == null) {
+ getValueData(target).refs++;
+ List<Statement> statements = statementList(target);
+ if (!statements.contains(exp)) {
+ statements.add(exp);
+ }
+ outputValue(target, outer, false);
}
- outputValue(target, outer, false);
if (expression) {
outputValue(value, outer, isArgument);
}
--- a/jdk/src/share/classes/java/io/ByteArrayOutputStream.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/io/ByteArrayOutputStream.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2012, 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
@@ -210,21 +210,21 @@
/**
* Converts the buffer's contents into a string by decoding the bytes using
- * the specified {@link java.nio.charset.Charset charsetName}. The length of
- * the new <tt>String</tt> is a function of the charset, and hence may not be
- * equal to the length of the byte array.
+ * the named {@link java.nio.charset.Charset charset}. The length of the new
+ * <tt>String</tt> is a function of the charset, and hence may not be equal
+ * to the length of the byte array.
*
* <p> This method always replaces malformed-input and unmappable-character
* sequences with this charset's default replacement string. The {@link
* java.nio.charset.CharsetDecoder} class should be used when more control
* over the decoding process is required.
*
- * @param charsetName the name of a supported
- * {@linkplain java.nio.charset.Charset </code>charset<code>}
- * @return String decoded from the buffer's contents.
+ * @param charsetName the name of a supported
+ * {@link java.nio.charset.Charset charset}
+ * @return String decoded from the buffer's contents.
* @exception UnsupportedEncodingException
* If the named charset is not supported
- * @since JDK1.1
+ * @since JDK1.1
*/
public synchronized String toString(String charsetName)
throws UnsupportedEncodingException
--- a/jdk/src/share/classes/java/io/InputStreamReader.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/io/InputStreamReader.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, 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
@@ -86,7 +86,7 @@
*
* @param charsetName
* The name of a supported
- * {@link java.nio.charset.Charset </code>charset<code>}
+ * {@link java.nio.charset.Charset charset}
*
* @exception UnsupportedEncodingException
* If the named charset is not supported
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/annotation/ContainerFor.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 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.annotation;
+
+/**
+ * Indicates that an annotation type is a container for repeated
+ * instances of annotations of the type of the value of the
+ * {@code ContainerFor}'s value element.
+ *
+ * @since 1.8
+ * @jls 9.6 Annotation Types
+ * @jls 9.7 Annotations
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface ContainerFor {
+ /**
+ * The repeating annotation type that the annotation type
+ * annotated with this annotation is a container for.
+ */
+ Class<? extends Annotation> value();
+}
--- a/jdk/src/share/classes/java/security/interfaces/DSAKeyPairGenerator.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/security/interfaces/DSAKeyPairGenerator.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -62,6 +62,9 @@
* interface is all that is needed when you accept defaults for algorithm-specific
* parameters.
*
+ * <p>Note: Some earlier implementations of this interface may not support
+ * larger sizes of DSA parameters such as 2048 and 3072-bit.
+ *
* @see java.security.KeyPairGenerator
*/
public interface DSAKeyPairGenerator {
@@ -78,7 +81,7 @@
* can be null.
*
* @exception InvalidParameterException if the <code>params</code>
- * value is invalid or null.
+ * value is invalid, null, or unsupported.
*/
public void initialize(DSAParams params, SecureRandom random)
throws InvalidParameterException;
@@ -97,7 +100,7 @@
* default parameters for modulus lengths of 512 and 1024 bits.
*
* @param modlen the modulus length in bits. Valid values are any
- * multiple of 8 between 512 and 1024, inclusive.
+ * multiple of 64 between 512 and 1024, inclusive, 2048, and 3072.
*
* @param random the random bit source to use to generate key bits;
* can be null.
@@ -105,10 +108,9 @@
* @param genParams whether or not to generate new parameters for
* the modulus length requested.
*
- * @exception InvalidParameterException if <code>modlen</code> is not
- * between 512 and 1024, or if <code>genParams</code> is false and
- * there are no precomputed parameters for the requested modulus
- * length.
+ * @exception InvalidParameterException if <code>modlen</code> is
+ * invalid, or unsupported, or if <code>genParams</code> is false and there
+ * are no precomputed parameters for the requested modulus length.
*/
public void initialize(int modlen, boolean genParams, SecureRandom random)
throws InvalidParameterException;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/security/spec/DSAGenParameterSpec.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012, 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.security.spec;
+
+/**
+ * This immutable class specifies the set of parameters used for
+ * generating DSA parameters as specified in
+ * <a href="http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf">FIPS 186-3 Digital Signature Standard (DSS)</a>.
+ *
+ * @see AlgorithmParameterSpec
+ *
+ * @since 8
+ */
+public final class DSAGenParameterSpec implements AlgorithmParameterSpec {
+
+ private final int pLen;
+ private final int qLen;
+ private final int seedLen;
+
+ /**
+ * Creates a domain parameter specification for DSA parameter
+ * generation using <code>primePLen</code> and <code>subprimeQLen</code>.
+ * The value of <code>subprimeQLen</code> is also used as the default
+ * length of the domain parameter seed in bits.
+ * @param primePLen the desired length of the prime P in bits.
+ * @param subprimeQLen the desired length of the sub-prime Q in bits.
+ * @exception IllegalArgumentException if <code>primePLen</code>
+ * or <code>subprimeQLen</code> is illegal per the specification of
+ * FIPS 186-3.
+ */
+ public DSAGenParameterSpec(int primePLen, int subprimeQLen) {
+ this(primePLen, subprimeQLen, subprimeQLen);
+ }
+
+ /**
+ * Creates a domain parameter specification for DSA parameter
+ * generation using <code>primePLen</code>, <code>subprimeQLen</code>,
+ * and <code>seedLen</code>.
+ * @param primePLen the desired length of the prime P in bits.
+ * @param subprimeQLen the desired length of the sub-prime Q in bits.
+ * @param seedLen the desired length of the domain parameter seed in bits,
+ * shall be equal to or greater than <code>subprimeQLen</code>.
+ * @exception IllegalArgumentException if <code>primePLenLen</code>,
+ * <code>subprimeQLen</code>, or <code>seedLen</code> is illegal per the
+ * specification of FIPS 186-3.
+ */
+ public DSAGenParameterSpec(int primePLen, int subprimeQLen, int seedLen) {
+ switch (primePLen) {
+ case 1024:
+ if (subprimeQLen != 160) {
+ throw new IllegalArgumentException
+ ("subprimeQLen must be 160 when primePLen=1024");
+ }
+ break;
+ case 2048:
+ if (subprimeQLen != 224 && subprimeQLen != 256) {
+ throw new IllegalArgumentException
+ ("subprimeQLen must be 224 or 256 when primePLen=2048");
+ }
+ break;
+ case 3072:
+ if (subprimeQLen != 256) {
+ throw new IllegalArgumentException
+ ("subprimeQLen must be 256 when primePLen=3072");
+ }
+ break;
+ default:
+ throw new IllegalArgumentException
+ ("primePLen must be 1024, 2048, or 3072");
+ }
+ if (seedLen < subprimeQLen) {
+ throw new IllegalArgumentException
+ ("seedLen must be equal to or greater than subprimeQLen");
+ }
+ this.pLen = primePLen;
+ this.qLen = subprimeQLen;
+ this.seedLen = seedLen;
+ }
+
+ /**
+ * Returns the desired length of the prime P of the
+ * to-be-generated DSA domain parameters in bits.
+ * @return the length of the prime P.
+ */
+ public int getPrimePLength() {
+ return pLen;
+ }
+
+ /**
+ * Returns the desired length of the sub-prime Q of the
+ * to-be-generated DSA domain parameters in bits.
+ * @return the length of the sub-prime Q.
+ */
+ public int getSubprimeQLength() {
+ return qLen;
+ }
+
+ /**
+ * Returns the desired length of the domain parameter seed in bits.
+ * @return the length of the domain parameter seed.
+ */
+ public int getSeedLength() {
+ return seedLen;
+ }
+}
--- a/jdk/src/share/classes/java/sql/DriverManager.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/java/sql/DriverManager.java Fri Sep 14 13:52:30 2012 -0700
@@ -510,7 +510,7 @@
public Void run() {
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
- Iterator driversIterator = loadedDrivers.iterator();
+ Iterator<Driver> driversIterator = loadedDrivers.iterator();
/* Load these drivers, so that they can be instantiated.
* It may be the case that the driver class may not be there
--- a/jdk/src/share/classes/sun/awt/AWTAccessor.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java Fri Sep 14 13:52:30 2012 -0700
@@ -667,6 +667,21 @@
}
/*
+ * An accessor for the SequencedEventAccessor class
+ */
+ public interface SequencedEventAccessor {
+ /*
+ * Returns the nested event.
+ */
+ AWTEvent getNested(AWTEvent sequencedEvent);
+
+ /*
+ * Returns true if the event is an instances of SequencedEvent.
+ */
+ boolean isSequencedEvent(AWTEvent event);
+ }
+
+ /*
* Accessor instances are initialized in the static initializers of
* corresponding AWT classes by using setters defined below.
*/
@@ -692,6 +707,7 @@
private static SystemTrayAccessor systemTrayAccessor;
private static TrayIconAccessor trayIconAccessor;
private static DefaultKeyboardFocusManagerAccessor defaultKeyboardFocusManagerAccessor;
+ private static SequencedEventAccessor sequencedEventAccessor;
/*
* Set an accessor object for the java.awt.Component class.
@@ -1069,4 +1085,20 @@
}
return defaultKeyboardFocusManagerAccessor;
}
+ /*
+ * Set an accessor object for the java.awt.SequencedEvent class.
+ */
+ public static void setSequencedEventAccessor(SequencedEventAccessor sea) {
+ sequencedEventAccessor = sea;
+ }
+
+ /*
+ * Get the accessor object for the java.awt.SequencedEvent class.
+ */
+ public static SequencedEventAccessor getSequencedEventAccessor() {
+ // The class is not public. So we can't ensure it's initialized.
+ // Null returned value means it's not initialized
+ // (so not a single instance of the event has been created).
+ return sequencedEventAccessor;
+ }
}
--- a/jdk/src/share/classes/sun/awt/HToolkit.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/awt/HToolkit.java Fri Sep 14 13:52:30 2012 -0700
@@ -44,6 +44,14 @@
public class HToolkit extends SunToolkit
implements ComponentFactory {
+ private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
+ public void setCurrentFocusedWindow(Window win) {}
+ public Window getCurrentFocusedWindow() { return null; }
+ public void setCurrentFocusOwner(Component comp) {}
+ public Component getCurrentFocusOwner() { return null; }
+ public void clearGlobalFocusOwner(Window activeWindow) {}
+ };
+
public HToolkit() {
}
@@ -152,15 +160,9 @@
throw new HeadlessException();
}
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
+ public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
// See 6833019.
- return
- new KeyboardFocusManagerPeer() {
- public Window getCurrentFocusedWindow() { return null; }
- public void setCurrentFocusOwner(Component comp) {}
- public Component getCurrentFocusOwner() { return null; }
- public void clearGlobalFocusOwner(Window activeWindow) {}
- };
+ return kfmPeer;
}
public TrayIconPeer createTrayIcon(TrayIcon target)
--- a/jdk/src/share/classes/sun/awt/HeadlessToolkit.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/awt/HeadlessToolkit.java Fri Sep 14 13:52:30 2012 -0700
@@ -30,22 +30,25 @@
import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.event.*;
import java.awt.im.InputMethodHighlight;
-import java.awt.im.spi.InputMethodDescriptor;
import java.awt.image.*;
import java.awt.datatransfer.Clipboard;
import java.awt.peer.*;
import java.beans.PropertyChangeListener;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.Map;
import java.util.Properties;
-import sun.awt.im.InputContext;
-import sun.awt.image.ImageRepresentation;
public class HeadlessToolkit extends Toolkit
implements ComponentFactory, KeyboardFocusManagerPeerProvider {
+ private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
+ public void setCurrentFocusedWindow(Window win) {}
+ public Window getCurrentFocusedWindow() { return null; }
+ public void setCurrentFocusOwner(Component comp) {}
+ public Component getCurrentFocusOwner() { return null; }
+ public void clearGlobalFocusOwner(Window activeWindow) {}
+ };
+
private Toolkit tk;
private ComponentFactory componentFactory;
@@ -179,15 +182,9 @@
throw new HeadlessException();
}
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
+ public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
// See 6833019.
- return
- new KeyboardFocusManagerPeer() {
- public Window getCurrentFocusedWindow() { return null; }
- public void setCurrentFocusOwner(Component comp) {}
- public Component getCurrentFocusOwner() { return null; }
- public void clearGlobalFocusOwner(Window activeWindow) {}
- };
+ return kfmPeer;
}
public TrayIconPeer createTrayIcon(TrayIcon target)
--- a/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java Fri Sep 14 13:52:30 2012 -0700
@@ -53,12 +53,6 @@
public static final int SNFH_SUCCESS_HANDLED = 1;
public static final int SNFH_SUCCESS_PROCEED = 2;
- protected KeyboardFocusManager manager;
-
- public KeyboardFocusManagerPeerImpl(KeyboardFocusManager manager) {
- this.manager = manager;
- }
-
@Override
public void clearGlobalFocusOwner(Window activeWindow) {
if (activeWindow != null) {
@@ -134,7 +128,7 @@
if (focusLog.isLoggable(PlatformLogger.FINER))
focusLog.finer("Posting focus event: " + fl);
- SunToolkit.postPriorityEvent(fl);
+ SunToolkit.postEvent(SunToolkit.targetToAppContext(currentOwner), fl);
}
FocusEvent fg = new CausedFocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED,
@@ -142,7 +136,7 @@
if (focusLog.isLoggable(PlatformLogger.FINER))
focusLog.finer("Posting focus event: " + fg);
- SunToolkit.postPriorityEvent(fg);
+ SunToolkit.postEvent(SunToolkit.targetToAppContext(lightweightChild), fg);
return true;
}
--- a/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerProvider.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerProvider.java Fri Sep 14 13:52:30 2012 -0700
@@ -25,20 +25,19 @@
package sun.awt;
-import java.awt.KeyboardFocusManager;
import java.awt.peer.KeyboardFocusManagerPeer;
/**
* {@link KeyboardFocusManagerPeerProvider} is required to be implemented by
* the currently used {@link java.awt.Toolkit} instance. In order to initialize
- * {@link java.awt.KeyboardFocusManager}, an instance of {@link KeyboardFocusManagerPeer}
- * is needed. To create that instance, the {@link #createKeyboardFocusManagerPeer}
+ * {@link java.awt.KeyboardFocusManager}, a singleton instance of {@link KeyboardFocusManagerPeer}
+ * is needed. To obtain that instance, the {@link #getKeyboardFocusManagerPeer}
* method of the current toolkit is called.
*/
public interface KeyboardFocusManagerPeerProvider {
/**
- * Creates a KeyboardFocusManagerPeer for the specified KeyboardFocusManager.
+ * Gets a singleton KeyboardFocusManagerPeer instance.
*/
- KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager);
+ KeyboardFocusManagerPeer getKeyboardFocusManagerPeer();
}
--- a/jdk/src/share/classes/sun/awt/SunToolkit.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/awt/SunToolkit.java Fri Sep 14 13:52:30 2012 -0700
@@ -197,7 +197,7 @@
public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
throws AWTException;
- public abstract KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
+ public abstract KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
throws HeadlessException;
/**
@@ -463,6 +463,19 @@
if (event == null) {
throw new NullPointerException();
}
+
+ AWTAccessor.SequencedEventAccessor sea = AWTAccessor.getSequencedEventAccessor();
+ if (sea != null && sea.isSequencedEvent(event)) {
+ AWTEvent nested = sea.getNested(event);
+ if (nested.getID() == WindowEvent.WINDOW_LOST_FOCUS &&
+ nested instanceof TimedWindowEvent)
+ {
+ TimedWindowEvent twe = (TimedWindowEvent)nested;
+ ((SunToolkit)Toolkit.getDefaultToolkit()).
+ setWindowDeactivationTime((Window)twe.getSource(), twe.getWhen());
+ }
+ }
+
// All events posted via this method are system-generated.
// Placing the following call here reduces considerably the
// number of places throughout the toolkit that would
@@ -1863,6 +1876,28 @@
return false;
}
+ private static final Object DEACTIVATION_TIMES_MAP_KEY = new Object();
+
+ public synchronized void setWindowDeactivationTime(Window w, long time) {
+ AppContext ctx = getAppContext(w);
+ WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
+ if (map == null) {
+ map = new WeakHashMap<Window, Long>();
+ ctx.put(DEACTIVATION_TIMES_MAP_KEY, map);
+ }
+ map.put(w, time);
+ }
+
+ public synchronized long getWindowDeactivationTime(Window w) {
+ AppContext ctx = getAppContext(w);
+ WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
+ if (map == null) {
+ return -1;
+ }
+ Long time = map.get(w);
+ return time == null ? -1 : time;
+ }
+
// Cosntant alpha
public boolean isWindowOpacitySupported() {
return false;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/awt/TimedWindowEvent.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 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 sun.awt;
+
+import java.awt.event.WindowEvent;
+import java.awt.Window;
+
+public class TimedWindowEvent extends WindowEvent {
+
+ private long time;
+
+ public long getWhen() {
+ return time;
+ }
+
+ public TimedWindowEvent(Window source, int id, Window opposite, long time) {
+ super(source, id, opposite);
+ this.time = time;
+ }
+
+ public TimedWindowEvent(Window source, int id, Window opposite,
+ int oldState, int newState, long time)
+ {
+ super(source, id, opposite, oldState, newState);
+ this.time = time;
+ }
+}
+
--- a/jdk/src/share/classes/sun/security/ec/ECKeyFactory.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/ec/ECKeyFactory.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,33 +51,21 @@
*/
public final class ECKeyFactory extends KeyFactorySpi {
- // Used by translateKey() and the SunPKCS11 provider
- public final static KeyFactory INSTANCE;
-
- // Internal provider object we can obtain the KeyFactory and
- // AlgorithmParameters from. Used by ECParameters and AlgorithmId.
- // This can go away once we have EC always available in the SUN provider.
- // Used by ECParameters and AlgorithmId.
- public final static Provider ecInternalProvider;
+ // Used by translateKey()
+ private static KeyFactory instance;
- static {
- final Provider p = new Provider("SunEC-Internal", 1.0d, null) {
- private static final long serialVersionUID = 970685700309471261L;
- };
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- p.put("KeyFactory.EC", "sun.security.ec.ECKeyFactory");
- p.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters");
- p.put("Alg.Alias.AlgorithmParameters.1.2.840.10045.2.1", "EC");
- return null;
+ private static KeyFactory getInstance() {
+ if (instance == null) {
+ try {
+ instance = KeyFactory.getInstance("EC", "SunEC");
+ } catch (NoSuchProviderException e) {
+ throw new RuntimeException(e);
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
}
- });
- try {
- INSTANCE = KeyFactory.getInstance("EC", p);
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException(e);
}
- ecInternalProvider = p;
+
+ return instance;
}
public ECKeyFactory() {
@@ -102,7 +90,12 @@
checkKey(ecKey);
return ecKey;
} else {
- return (ECKey)INSTANCE.translateKey(key);
+ /*
+ * We don't call the engineTranslateKey method directly
+ * because KeyFactory.translateKey adds code to loop through
+ * all key factories.
+ */
+ return (ECKey)getInstance().translateKey(key);
}
}
--- a/jdk/src/share/classes/sun/security/ec/ECParameters.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/ec/ECParameters.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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
@@ -276,8 +276,8 @@
static AlgorithmParameters getAlgorithmParameters(ECParameterSpec spec)
throws InvalidKeyException {
try {
- AlgorithmParameters params = AlgorithmParameters.getInstance
- ("EC", ECKeyFactory.ecInternalProvider);
+ AlgorithmParameters params =
+ AlgorithmParameters.getInstance("EC", "SunEC");
params.init(spec);
return params;
} catch (GeneralSecurityException e) {
--- a/jdk/src/share/classes/sun/security/ec/ECPublicKeyImpl.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/ec/ECPublicKeyImpl.java Fri Sep 14 13:52:30 2012 -0700
@@ -96,8 +96,13 @@
*/
@SuppressWarnings("deprecation")
protected void parseKeyBits() throws InvalidKeyException {
+ AlgorithmParameters algParams = this.algid.getParameters();
+ if (algParams == null) {
+ throw new InvalidKeyException("EC domain parameters must be " +
+ "encoded in the algorithm identifier");
+ }
+
try {
- AlgorithmParameters algParams = this.algid.getParameters();
params = algParams.getParameterSpec(ECParameterSpec.class);
w = ECParameters.decodePoint(key, params.getCurve());
} catch (IOException e) {
--- a/jdk/src/share/classes/sun/security/ec/SunECEntries.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/ec/SunECEntries.java Fri Sep 14 13:52:30 2012 -0700
@@ -54,6 +54,7 @@
*/
map.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters");
map.put("Alg.Alias.AlgorithmParameters.EllipticCurve", "EC");
+ map.put("Alg.Alias.AlgorithmParameters.1.2.840.10045.2.1", "EC");
map.put("AlgorithmParameters.EC KeySize", "256");
@@ -133,6 +134,9 @@
"sun.security.ec.ECDSASignature$Raw");
map.put("Signature.SHA1withECDSA",
"sun.security.ec.ECDSASignature$SHA1");
+ map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.1", "SHA1withECDSA");
+ map.put("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
+
map.put("Signature.SHA224withECDSA",
"sun.security.ec.ECDSASignature$SHA224");
map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.1", "SHA224withECDSA");
--- a/jdk/src/share/classes/sun/security/krb5/Config.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/krb5/Config.java Fri Sep 14 13:52:30 2012 -0700
@@ -115,7 +115,12 @@
private static boolean isMacosLionOrBetter() {
// split the "10.x.y" version number
- String osVersion = System.getProperty("os.version");
+ String osname = getProperty("os.name");
+ if (!osname.contains("OS X")) {
+ return false;
+ }
+
+ String osVersion = getProperty("os.version");
String[] fragments = osVersion.split("\\.");
// sanity check the "10." part of the version
@@ -140,20 +145,14 @@
/*
* If either one system property is specified, we throw exception.
*/
- String tmp =
- java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction
- ("java.security.krb5.kdc"));
+ String tmp = getProperty("java.security.krb5.kdc");
if (tmp != null) {
// The user can specify a list of kdc hosts separated by ":"
defaultKDC = tmp.replace(':', ' ');
} else {
defaultKDC = null;
}
- defaultRealm =
- java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction
- ("java.security.krb5.realm"));
+ defaultRealm = getProperty("java.security.krb5.realm");
if ((defaultKDC == null && defaultRealm != null) ||
(defaultRealm == null && defaultKDC != null)) {
throw new KrbException
@@ -165,11 +164,34 @@
// Always read the Kerberos configuration file
try {
Vector<String> configFile;
- configFile = loadConfigFile();
- if (configFile == null && isMacosLionOrBetter()) {
- stanzaTable = SCDynamicStoreConfig.getConfig();
+ String fileName = getJavaFileName();
+ if (fileName != null) {
+ configFile = loadConfigFile(fileName);
+ stanzaTable = parseStanzaTable(configFile);
+ if (DEBUG) {
+ System.out.println("Loaded from Java config");
+ }
} else {
- stanzaTable = parseStanzaTable(configFile);
+ boolean found = false;
+ if (isMacosLionOrBetter()) {
+ try {
+ stanzaTable = SCDynamicStoreConfig.getConfig();
+ if (DEBUG) {
+ System.out.println("Loaded from SCDynamicStoreConfig");
+ }
+ found = true;
+ } catch (IOException ioe) {
+ // OK. Will go on with file
+ }
+ }
+ if (!found) {
+ fileName = getNativeFileName();
+ configFile = loadConfigFile(fileName);
+ stanzaTable = parseStanzaTable(configFile);
+ if (DEBUG) {
+ System.out.println("Loaded from native config");
+ }
+ }
}
} catch (IOException ioe) {
// No krb5.conf, no problem. We'll use DNS or system property etc.
@@ -546,10 +568,13 @@
* [domain_realm]
* blue.sample.com = TEST.SAMPLE.COM
* .backup.com = EXAMPLE.COM
+ *
+ * @params fileName the conf file, cannot be null
+ * @return the content, null if fileName is empty
+ * @throws IOException if there is an I/O or format error
*/
- private Vector<String> loadConfigFile() throws IOException {
+ private Vector<String> loadConfigFile(final String fileName) throws IOException {
try {
- final String fileName = getFileName();
if (!fileName.equals("")) {
BufferedReader br = new BufferedReader(new InputStreamReader(
java.security.AccessController.doPrivileged(
@@ -668,97 +693,106 @@
}
/**
- * Gets the default configuration file name. This method will never
- * return null.
+ * Gets the default Java configuration file name.
*
* If the system property "java.security.krb5.conf" is defined, we'll
- * use its value, no matter if the file exists or not. Otherwise,
- * the file will be searched in a list of possible loations in the
- * following order:
+ * use its value, no matter if the file exists or not. Otherwise, we
+ * will look at $JAVA_HOME/lib/security directory with "krb5.conf" name,
+ * and return it if the file exists.
*
- * 1. at Java home lib\security directory with "krb5.conf" name,
- * 2. at windows directory with the name of "krb5.ini" for Windows,
- * /etc/krb5/krb5.conf for Solaris, /etc/krb5.conf otherwise.
+ * The method returns null if it cannot find a Java config file.
+ */
+ private String getJavaFileName() {
+ String name = getProperty("java.security.krb5.conf");
+ if (name == null) {
+ name = getProperty("java.home") + File.separator +
+ "lib" + File.separator + "security" +
+ File.separator + "krb5.conf";
+ if (!fileExists(name)) {
+ name = null;
+ }
+ }
+ if (DEBUG) {
+ System.out.println("Java config name: " + name);
+ }
+ return name;
+ }
+
+ /**
+ * Gets the default native configuration file name.
+ *
+ * Depending on the OS type, the method returns the default native
+ * kerberos config file name, which is at windows directory with
+ * the name of "krb5.ini" for Windows, /etc/krb5/krb5.conf for Solaris,
+ * /etc/krb5.conf otherwise. Mac OSX X has a different file name.
*
* Note: When the Terminal Service is started in Windows (from 2003),
* there are two kinds of Windows directories: A system one (say,
* C:\Windows), and a user-private one (say, C:\Users\Me\Windows).
* We will first look for krb5.ini in the user-private one. If not
* found, try the system one instead.
+ *
+ * This method will always return a non-null non-empty file name,
+ * even if that file does not exist.
*/
- private String getFileName() {
- String name =
- java.security.AccessController.doPrivileged(
- new sun.security.action.
- GetPropertyAction("java.security.krb5.conf"));
- if (name == null) {
- name = java.security.AccessController.doPrivileged(
- new sun.security.action.
- GetPropertyAction("java.home")) + File.separator +
- "lib" + File.separator + "security" +
- File.separator + "krb5.conf";
- if (!fileExists(name)) {
- name = null;
- String osname =
- java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("os.name"));
- if (osname.startsWith("Windows")) {
- try {
- Credentials.ensureLoaded();
- } catch (Exception e) {
- // ignore exceptions
+ private String getNativeFileName() {
+ String name = null;
+ String osname = getProperty("os.name");
+ if (osname.startsWith("Windows")) {
+ try {
+ Credentials.ensureLoaded();
+ } catch (Exception e) {
+ // ignore exceptions
+ }
+ if (Credentials.alreadyLoaded) {
+ String path = getWindowsDirectory(false);
+ if (path != null) {
+ if (path.endsWith("\\")) {
+ path = path + "krb5.ini";
+ } else {
+ path = path + "\\krb5.ini";
}
- if (Credentials.alreadyLoaded) {
- String path = getWindowsDirectory(false);
- if (path != null) {
- if (path.endsWith("\\")) {
- path = path + "krb5.ini";
- } else {
- path = path + "\\krb5.ini";
- }
- if (fileExists(path)) {
- name = path;
- }
+ if (fileExists(path)) {
+ name = path;
+ }
+ }
+ if (name == null) {
+ path = getWindowsDirectory(true);
+ if (path != null) {
+ if (path.endsWith("\\")) {
+ path = path + "krb5.ini";
+ } else {
+ path = path + "\\krb5.ini";
}
- if (name == null) {
- path = getWindowsDirectory(true);
- if (path != null) {
- if (path.endsWith("\\")) {
- path = path + "krb5.ini";
- } else {
- path = path + "\\krb5.ini";
- }
- name = path;
- }
- }
+ name = path;
}
- if (name == null) {
- name = "c:\\winnt\\krb5.ini";
- }
- } else if (osname.startsWith("SunOS")) {
- name = "/etc/krb5/krb5.conf";
- } else if (osname.contains("OS X")) {
- if (isMacosLionOrBetter()) return "";
- name = findMacosConfigFile();
- } else {
- name = "/etc/krb5.conf";
}
}
+ if (name == null) {
+ name = "c:\\winnt\\krb5.ini";
+ }
+ } else if (osname.startsWith("SunOS")) {
+ name = "/etc/krb5/krb5.conf";
+ } else if (osname.contains("OS X")) {
+ name = findMacosConfigFile();
+ } else {
+ name = "/etc/krb5.conf";
}
if (DEBUG) {
- System.out.println("Config name: " + name);
+ System.out.println("Native config name: " + name);
}
return name;
}
- private String getProperty(String property) {
- return java.security.AccessController.doPrivileged(new sun.security.action.GetPropertyAction(property));
+ private static String getProperty(String property) {
+ return java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction(property));
}
private String findMacosConfigFile() {
String userHome = getProperty("user.home");
final String PREF_FILE = "/Library/Preferences/edu.mit.Kerberos";
- String userPrefs=userHome + PREF_FILE;
+ String userPrefs = userHome + PREF_FILE;
if (fileExists(userPrefs)) {
return userPrefs;
@@ -768,11 +802,7 @@
return PREF_FILE;
}
- if (fileExists("/etc/krb5.conf")) {
- return "/etc/krb5.conf";
- }
-
- return "";
+ return "/etc/krb5.conf";
}
private static String trimmed(String s) {
@@ -1344,32 +1374,52 @@
}
}
+ // Shows the content of the Config object for debug purpose.
+ //
+ // {
+ // libdefaults = {
+ // default_realm = R
+ // }
+ // realms = {
+ // R = {
+ // kdc = [k1,k2]
+ // }
+ // }
+ // }
+
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
- toStringIndented("", stanzaTable, sb);
+ toStringInternal("", stanzaTable, sb);
return sb.toString();
}
- private static void toStringIndented(String prefix, Object obj,
+ private static void toStringInternal(String prefix, Object obj,
StringBuffer sb) {
if (obj instanceof String) {
- sb.append(prefix);
- sb.append(obj);
- sb.append('\n');
+ // A string value, just print it
+ sb.append(obj).append('\n');
} else if (obj instanceof Hashtable) {
+ // A table, start a new sub-section...
Hashtable<?, ?> tab = (Hashtable<?, ?>)obj;
+ sb.append("{\n");
for (Object o: tab.keySet()) {
- sb.append(prefix);
+ // ...indent, print "key = ", and
+ sb.append(prefix).append(" ").append(o).append(" = ");
+ // ...go recursively into value
+ toStringInternal(prefix + " ", tab.get(o), sb);
+ }
+ sb.append(prefix).append("}\n");
+ } else if (obj instanceof Vector) {
+ // A vector of strings, print them inside [ and ]
+ Vector<?> v = (Vector<?>)obj;
+ sb.append("[");
+ boolean first = true;
+ for (Object o: v.toArray()) {
+ if (!first) sb.append(",");
sb.append(o);
- sb.append(" = {\n");
- toStringIndented(prefix + " ", tab.get(o), sb);
- sb.append(prefix + "}\n");
+ first = false;
}
- } else if (obj instanceof Vector) {
- Vector<?> v = (Vector<?>)obj;
- for (Object o: v.toArray()) {
- toStringIndented(prefix + " ", o, sb);
- }
+ sb.append("]\n");
}
}
}
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Fri Sep 14 13:52:30 2012 -0700
@@ -164,6 +164,10 @@
// if we do the padding
private int bytesBuffered;
+ // length of key size in bytes; currently only used by AES given its oid
+ // specification mandates a fixed size of the key
+ private int fixedKeySize = -1;
+
P11Cipher(Token token, String algorithm, long mechanism)
throws PKCS11Exception, NoSuchAlgorithmException {
super();
@@ -172,19 +176,26 @@
this.mechanism = mechanism;
String algoParts[] = algorithm.split("/");
- keyAlgorithm = algoParts[0];
- if (keyAlgorithm.equals("AES")) {
+ if (algoParts[0].startsWith("AES")) {
blockSize = 16;
- } else if (keyAlgorithm.equals("RC4") ||
- keyAlgorithm.equals("ARCFOUR")) {
- blockSize = 0;
- } else { // DES, DESede, Blowfish
- blockSize = 8;
+ int index = algoParts[0].indexOf('_');
+ if (index != -1) {
+ // should be well-formed since we specify what we support
+ fixedKeySize = Integer.parseInt(algoParts[0].substring(index+1))/8;
+ }
+ keyAlgorithm = "AES";
+ } else {
+ keyAlgorithm = algoParts[0];
+ if (keyAlgorithm.equals("RC4") ||
+ keyAlgorithm.equals("ARCFOUR")) {
+ blockSize = 0;
+ } else { // DES, DESede, Blowfish
+ blockSize = 8;
+ }
+ this.blockMode =
+ (algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB);
}
- this.blockMode =
- (algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB);
-
String defPadding = (blockSize == 0 ? "NoPadding" : "PKCS5Padding");
String paddingStr =
(algoParts.length > 2 ? algoParts[2] : defPadding);
@@ -333,6 +344,9 @@
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
cancelOperation();
+ if (fixedKeySize != -1 && key.getEncoded().length != fixedKeySize) {
+ throw new InvalidKeyException("Key size is invalid");
+ }
switch (opmode) {
case Cipher.ENCRYPT_MODE:
encrypt = true;
--- a/jdk/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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
@@ -304,7 +304,7 @@
}
KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
- return sun.security.ec.ECKeyFactory.INSTANCE;
+ return KeyFactory.getInstance("EC", "SunEC");
}
}
--- a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java Fri Sep 14 13:52:30 2012 -0700
@@ -399,12 +399,8 @@
return System.identityHashCode(this);
}
- private static String[] s(String s1) {
- return new String[] {s1};
- }
-
- private static String[] s(String s1, String s2) {
- return new String[] {s1, s2};
+ private static String[] s(String ...aliases) {
+ return aliases;
}
private static final class Descriptor {
@@ -521,7 +517,8 @@
m(CKM_MD2));
d(MD, "MD5", P11Digest,
m(CKM_MD5));
- d(MD, "SHA1", P11Digest, s("SHA", "SHA-1"),
+ d(MD, "SHA1", P11Digest,
+ s("SHA", "SHA-1", "1.3.14.3.2.26", "OID.1.3.14.3.2.26"),
m(CKM_SHA_1));
d(MD, "SHA-224", P11Digest,
@@ -540,6 +537,7 @@
d(MAC, "HmacMD5", P11MAC,
m(CKM_MD5_HMAC));
d(MAC, "HmacSHA1", P11MAC,
+ s("1.2.840.113549.2.7", "OID.1.2.840.113549.2.7"),
m(CKM_SHA_1_HMAC));
d(MAC, "HmacSHA224", P11MAC,
s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"),
@@ -561,6 +559,7 @@
d(KPG, "RSA", P11KeyPairGenerator,
m(CKM_RSA_PKCS_KEY_PAIR_GEN));
d(KPG, "DSA", P11KeyPairGenerator,
+ s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
m(CKM_DSA_KEY_PAIR_GEN));
d(KPG, "DH", P11KeyPairGenerator, s("DiffieHellman"),
m(CKM_DH_PKCS_KEY_PAIR_GEN));
@@ -583,6 +582,7 @@
d(KF, "RSA", P11RSAKeyFactory,
m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509));
d(KF, "DSA", P11DSAKeyFactory,
+ s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1));
d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"),
m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
@@ -609,6 +609,7 @@
d(SKF, "DESede", P11SecretKeyFactory,
m(CKM_DES3_CBC));
d(SKF, "AES", P11SecretKeyFactory,
+ s("2.16.840.1.101.3.4.1", "OID.2.16.840.1.101.3.4.1"),
m(CKM_AES_CBC));
d(SKF, "Blowfish", P11SecretKeyFactory,
m(CKM_BLOWFISH_CBC));
@@ -635,10 +636,28 @@
m(CKM_DES3_ECB));
d(CIP, "AES/CBC/NoPadding", P11Cipher,
m(CKM_AES_CBC));
+ d(CIP, "AES_128/CBC/NoPadding", P11Cipher,
+ s("2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"),
+ m(CKM_AES_CBC));
+ d(CIP, "AES_192/CBC/NoPadding", P11Cipher,
+ s("2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"),
+ m(CKM_AES_CBC));
+ d(CIP, "AES_256/CBC/NoPadding", P11Cipher,
+ s("2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42"),
+ m(CKM_AES_CBC));
d(CIP, "AES/CBC/PKCS5Padding", P11Cipher,
m(CKM_AES_CBC_PAD, CKM_AES_CBC));
d(CIP, "AES/ECB/NoPadding", P11Cipher,
m(CKM_AES_ECB));
+ d(CIP, "AES_128/ECB/NoPadding", P11Cipher,
+ s("2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"),
+ m(CKM_AES_ECB));
+ d(CIP, "AES_192/ECB/NoPadding", P11Cipher,
+ s("2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"),
+ m(CKM_AES_ECB));
+ d(CIP, "AES_256/ECB/NoPadding", P11Cipher,
+ s("2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41"),
+ m(CKM_AES_ECB));
d(CIP, "AES/ECB/PKCS5Padding", P11Cipher, s("AES"),
m(CKM_AES_ECB));
d(CIP, "AES/CTR/NoPadding", P11Cipher,
@@ -654,13 +673,16 @@
d(CIP, "RSA/ECB/NoPadding", P11RSACipher,
m(CKM_RSA_X_509));
- d(SIG, "RawDSA", P11Signature, s("NONEwithDSA"),
+ d(SIG, "RawDSA", P11Signature, s("NONEwithDSA"),
m(CKM_DSA));
- d(SIG, "DSA", P11Signature, s("SHA1withDSA"),
+ d(SIG, "DSA", P11Signature,
+ s("SHA1withDSA", "1.3.14.3.2.13", "1.3.14.3.2.27",
+ "1.2.840.10040.4.3", "OID.1.2.840.10040.4.3"),
m(CKM_DSA_SHA1, CKM_DSA));
d(SIG, "NONEwithECDSA", P11Signature,
m(CKM_ECDSA));
- d(SIG, "SHA1withECDSA", P11Signature, s("ECDSA"),
+ d(SIG, "SHA1withECDSA", P11Signature,
+ s("ECDSA", "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1"),
m(CKM_ECDSA_SHA1, CKM_ECDSA));
d(SIG, "SHA224withECDSA", P11Signature,
s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"),
@@ -675,10 +697,14 @@
s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"),
m(CKM_ECDSA));
d(SIG, "MD2withRSA", P11Signature,
+ s("1.2.840.113549.1.1.2", "OID.1.2.840.113549.1.1.2"),
m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
d(SIG, "MD5withRSA", P11Signature,
+ s("1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4"),
m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
d(SIG, "SHA1withRSA", P11Signature,
+ s("1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5",
+ "1.3.14.3.2.29"),
m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
d(SIG, "SHA224withRSA", P11Signature,
s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"),
--- a/jdk/src/share/classes/sun/security/provider/DSA.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/provider/DSA.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, 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
@@ -45,14 +45,15 @@
/**
* The Digital Signature Standard (using the Digital Signature
- * Algorithm), as described in fips186 of the National Instute of
- * Standards and Technology (NIST), using fips180-1 (SHA-1).
+ * Algorithm), as described in fips186-3 of the National Instute of
+ * Standards and Technology (NIST), using SHA digest algorithms
+ * from FIPS180-3.
*
* This file contains both the signature implementation for the
- * commonly used SHA1withDSA (DSS) as well as RawDSA, used by TLS
- * among others. RawDSA expects the 20 byte SHA-1 digest as input
- * via update rather than the original data like other signature
- * implementations.
+ * commonly used SHA1withDSA (DSS), SHA224withDSA, SHA256withDSA,
+ * as well as RawDSA, used by TLS among others. RawDSA expects
+ * the 20 byte SHA-1 digest as input via update rather than the
+ * original data like other signature implementations.
*
* @author Benjamin Renaud
*
@@ -78,129 +79,19 @@
/* The private key, if any */
private BigInteger presetX;
- /* The random seed used to generate k */
- private int[] Kseed;
-
- /* The random seed used to generate k (specified by application) */
- private byte[] KseedAsByteArray;
-
- /*
- * The random seed used to generate k
- * (prevent the same Kseed from being used twice in a row
- */
- private int[] previousKseed;
-
/* The RNG used to output a seed for generating k */
private SecureRandom signingRandom;
+ /* The message digest object used */
+ private final MessageDigest md;
+
/**
* Construct a blank DSA object. It must be
* initialized before being usable for signing or verifying.
*/
- DSA() {
+ DSA(MessageDigest md) {
super();
- }
-
- /**
- * Return the 20 byte hash value and reset the digest.
- */
- abstract byte[] getDigest() throws SignatureException;
-
- /**
- * Reset the digest.
- */
- abstract void resetDigest();
-
- /**
- * Standard SHA1withDSA implementation.
- */
- public static final class SHA1withDSA extends DSA {
-
- /* The SHA hash for the data */
- private final MessageDigest dataSHA;
-
- public SHA1withDSA() throws NoSuchAlgorithmException {
- dataSHA = MessageDigest.getInstance("SHA-1");
- }
-
- /**
- * Update a byte to be signed or verified.
- */
- protected void engineUpdate(byte b) {
- dataSHA.update(b);
- }
-
- /**
- * Update an array of bytes to be signed or verified.
- */
- protected void engineUpdate(byte[] data, int off, int len) {
- dataSHA.update(data, off, len);
- }
-
- protected void engineUpdate(ByteBuffer b) {
- dataSHA.update(b);
- }
-
- byte[] getDigest() {
- return dataSHA.digest();
- }
-
- void resetDigest() {
- dataSHA.reset();
- }
- }
-
- /**
- * RawDSA implementation.
- *
- * RawDSA requires the data to be exactly 20 bytes long. If it is
- * not, a SignatureException is thrown when sign()/verify() is called
- * per JCA spec.
- */
- public static final class RawDSA extends DSA {
-
- // length of the SHA-1 digest (20 bytes)
- private final static int SHA1_LEN = 20;
-
- // 20 byte digest buffer
- private final byte[] digestBuffer;
-
- // offset into the buffer
- private int ofs;
-
- public RawDSA() {
- digestBuffer = new byte[SHA1_LEN];
- }
-
- protected void engineUpdate(byte b) {
- if (ofs == SHA1_LEN) {
- ofs = SHA1_LEN + 1;
- return;
- }
- digestBuffer[ofs++] = b;
- }
-
- protected void engineUpdate(byte[] data, int off, int len) {
- if (ofs + len > SHA1_LEN) {
- ofs = SHA1_LEN + 1;
- return;
- }
- System.arraycopy(data, off, digestBuffer, ofs, len);
- ofs += len;
- }
-
- byte[] getDigest() throws SignatureException {
- if (ofs != SHA1_LEN) {
- throw new SignatureException
- ("Data for RawDSA must be exactly 20 bytes long");
- }
- ofs = 0;
- return digestBuffer;
- }
-
- void resetDigest() {
- ofs = 0;
- }
+ this.md = md;
}
/**
@@ -217,13 +108,25 @@
throw new InvalidKeyException("not a DSA private key: " +
privateKey);
}
+
java.security.interfaces.DSAPrivateKey priv =
(java.security.interfaces.DSAPrivateKey)privateKey;
+
+ // check for algorithm specific constraints before doing initialization
+ DSAParams params = priv.getParams();
+ if (params == null) {
+ throw new InvalidKeyException("DSA private key lacks parameters");
+ }
+ checkKey(params);
+
+ this.params = params;
this.presetX = priv.getX();
this.presetY = null;
- initialize(priv.getParams());
+ this.presetP = params.getP();
+ this.presetQ = params.getQ();
+ this.presetG = params.getG();
+ this.md.reset();
}
-
/**
* Initialize the DSA object with a DSA public key.
*
@@ -240,17 +143,43 @@
}
java.security.interfaces.DSAPublicKey pub =
(java.security.interfaces.DSAPublicKey)publicKey;
+
+ // check for algorithm specific constraints before doing initialization
+ DSAParams params = pub.getParams();
+ if (params == null) {
+ throw new InvalidKeyException("DSA public key lacks parameters");
+ }
+ checkKey(params);
+
+ this.params = params;
this.presetY = pub.getY();
this.presetX = null;
- initialize(pub.getParams());
+ this.presetP = params.getP();
+ this.presetQ = params.getQ();
+ this.presetG = params.getG();
+ this.md.reset();
}
- private void initialize(DSAParams params) throws InvalidKeyException {
- resetDigest();
- setParams(params);
+ /**
+ * Update a byte to be signed or verified.
+ */
+ protected void engineUpdate(byte b) {
+ md.update(b);
}
/**
+ * Update an array of bytes to be signed or verified.
+ */
+ protected void engineUpdate(byte[] data, int off, int len) {
+ md.update(data, off, len);
+ }
+
+ protected void engineUpdate(ByteBuffer b) {
+ md.update(b);
+ }
+
+
+ /**
* Sign all the data thus far updated. The signature is formatted
* according to the Canonical Encoding Rules, returned as a DER
* sequence of Integer, r and s.
@@ -352,23 +281,51 @@
}
}
+ @Deprecated
+ protected void engineSetParameter(String key, Object param) {
+ throw new InvalidParameterException("No parameter accepted");
+ }
+
+ @Deprecated
+ protected Object engineGetParameter(String key) {
+ return null;
+ }
+
+ protected void checkKey(DSAParams params) throws InvalidKeyException {
+ // FIPS186-3 states in sec4.2 that a hash function which provides
+ // a lower security strength than the (L, N) pair ordinarily should
+ // not be used.
+ int valueN = params.getQ().bitLength();
+ if (valueN > md.getDigestLength()*8) {
+ throw new InvalidKeyException("Key is too strong for this signature algorithm");
+ }
+ }
+
private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,
BigInteger k) {
BigInteger temp = g.modPow(k, p);
- return temp.remainder(q);
- }
+ return temp.mod(q);
+ }
private BigInteger generateS(BigInteger x, BigInteger q,
BigInteger r, BigInteger k) throws SignatureException {
- byte[] s2 = getDigest();
- BigInteger temp = new BigInteger(1, s2);
+ byte[] s2;
+ try {
+ s2 = md.digest();
+ } catch (RuntimeException re) {
+ // Only for RawDSA due to its 20-byte length restriction
+ throw new SignatureException(re.getMessage());
+ }
+ // get the leftmost min(N, outLen) bits of the digest value
+ int nBytes = q.bitLength()/8;
+ if (nBytes < s2.length) {
+ s2 = Arrays.copyOfRange(s2, 0, nBytes);
+ }
+ BigInteger z = new BigInteger(1, s2);
BigInteger k1 = k.modInverse(q);
- BigInteger s = x.multiply(r);
- s = temp.add(s);
- s = k1.multiply(s);
- return s.remainder(q);
+ return x.multiply(r).add(z).multiply(k1).mod(q);
}
private BigInteger generateW(BigInteger p, BigInteger q,
@@ -380,54 +337,41 @@
BigInteger q, BigInteger g, BigInteger w, BigInteger r)
throws SignatureException {
- byte[] s2 = getDigest();
- BigInteger temp = new BigInteger(1, s2);
+ byte[] s2;
+ try {
+ s2 = md.digest();
+ } catch (RuntimeException re) {
+ // Only for RawDSA due to its 20-byte length restriction
+ throw new SignatureException(re.getMessage());
+ }
+ // get the leftmost min(N, outLen) bits of the digest value
+ int nBytes = q.bitLength()/8;
+ if (nBytes < s2.length) {
+ s2 = Arrays.copyOfRange(s2, 0, nBytes);
+ }
+ BigInteger z = new BigInteger(1, s2);
- temp = temp.multiply(w);
- BigInteger u1 = temp.remainder(q);
-
- BigInteger u2 = (r.multiply(w)).remainder(q);
+ BigInteger u1 = z.multiply(w).mod(q);
+ BigInteger u2 = (r.multiply(w)).mod(q);
BigInteger t1 = g.modPow(u1,p);
BigInteger t2 = y.modPow(u2,p);
BigInteger t3 = t1.multiply(t2);
- BigInteger t5 = t3.remainder(p);
- return t5.remainder(q);
+ BigInteger t5 = t3.mod(p);
+ return t5.mod(q);
}
- /*
- * Please read bug report 4044247 for an alternative, faster,
- * NON-FIPS approved method to generate K
- */
- private BigInteger generateK(BigInteger q) {
-
- BigInteger k = null;
-
- // The application specified a Kseed for us to use.
- // Note that we do not allow usage of the same Kseed twice in a row
- if (Kseed != null && !Arrays.equals(Kseed, previousKseed)) {
- k = generateK(Kseed, q);
- if (k.signum() > 0 && k.compareTo(q) < 0) {
- previousKseed = new int [Kseed.length];
- System.arraycopy(Kseed, 0, previousKseed, 0, Kseed.length);
- return k;
- }
- }
-
- // The application did not specify a Kseed for us to use.
- // We'll generate a new Kseed by getting random bytes from
- // a SecureRandom object.
+ // NOTE: This following impl is defined in FIPS 186-3 AppendixB.2.2.
+ // Original DSS algos such as SHA1withDSA and RawDSA uses a different
+ // algorithm defined in FIPS 186-1 Sec3.2, and thus need to override this.
+ protected BigInteger generateK(BigInteger q) {
SecureRandom random = getSigningRandom();
+ byte[] kValue = new byte[q.bitLength()/8];
while (true) {
- int[] seed = new int[5];
-
- for (int i = 0; i < 5; i++)
- seed[i] = random.nextInt();
- k = generateK(seed, q);
+ random.nextBytes(kValue);
+ BigInteger k = new BigInteger(1, kValue).mod(q);
if (k.signum() > 0 && k.compareTo(q) < 0) {
- previousKseed = new int [seed.length];
- System.arraycopy(seed, 0, previousKseed, 0, seed.length);
return k;
}
}
@@ -435,7 +379,7 @@
// Use the application-specified SecureRandom Object if provided.
// Otherwise, use our default SecureRandom Object.
- private SecureRandom getSigningRandom() {
+ protected SecureRandom getSigningRandom() {
if (signingRandom == null) {
if (appRandom != null) {
signingRandom = appRandom;
@@ -447,171 +391,6 @@
}
/**
- * Compute k for a DSA signature.
- *
- * @param seed the seed for generating k. This seed should be
- * secure. This is what is refered to as the KSEED in the DSA
- * specification.
- *
- * @param g the g parameter from the DSA key pair.
- */
- private BigInteger generateK(int[] seed, BigInteger q) {
-
- // check out t in the spec.
- int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476,
- 0xC3D2E1F0, 0x67452301 };
- //
- int[] tmp = DSA.SHA_7(seed, t);
- byte[] tmpBytes = new byte[tmp.length * 4];
- for (int i = 0; i < tmp.length; i++) {
- int k = tmp[i];
- for (int j = 0; j < 4; j++) {
- tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
- }
- }
- BigInteger k = new BigInteger(1, tmpBytes).mod(q);
- return k;
- }
-
- // Constants for each round
- private static final int round1_kt = 0x5a827999;
- private static final int round2_kt = 0x6ed9eba1;
- private static final int round3_kt = 0x8f1bbcdc;
- private static final int round4_kt = 0xca62c1d6;
-
- /**
- * Computes set 1 thru 7 of SHA-1 on m1. */
- static int[] SHA_7(int[] m1, int[] h) {
-
- int[] W = new int[80];
- System.arraycopy(m1,0,W,0,m1.length);
- int temp = 0;
-
- for (int t = 16; t <= 79; t++){
- temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
- W[t] = ((temp << 1) | (temp >>>(32 - 1)));
- }
-
- int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4];
- for (int i = 0; i < 20; i++) {
- temp = ((a<<5) | (a>>>(32-5))) +
- ((b&c)|((~b)&d))+ e + W[i] + round1_kt;
- e = d;
- d = c;
- c = ((b<<30) | (b>>>(32-30)));
- b = a;
- a = temp;
- }
-
- // Round 2
- for (int i = 20; i < 40; i++) {
- temp = ((a<<5) | (a>>>(32-5))) +
- (b ^ c ^ d) + e + W[i] + round2_kt;
- e = d;
- d = c;
- c = ((b<<30) | (b>>>(32-30)));
- b = a;
- a = temp;
- }
-
- // Round 3
- for (int i = 40; i < 60; i++) {
- temp = ((a<<5) | (a>>>(32-5))) +
- ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
- e = d;
- d = c;
- c = ((b<<30) | (b>>>(32-30)));
- b = a;
- a = temp;
- }
-
- // Round 4
- for (int i = 60; i < 80; i++) {
- temp = ((a<<5) | (a>>>(32-5))) +
- (b ^ c ^ d) + e + W[i] + round4_kt;
- e = d;
- d = c;
- c = ((b<<30) | (b>>>(32-30)));
- b = a;
- a = temp;
- }
- int[] md = new int[5];
- md[0] = h[0] + a;
- md[1] = h[1] + b;
- md[2] = h[2] + c;
- md[3] = h[3] + d;
- md[4] = h[4] + e;
- return md;
- }
-
-
- /**
- * This implementation recognizes the following parameter:<dl>
- *
- * <dt><tt>Kseed</tt>
- *
- * <dd>a byte array.
- *
- * </dl>
- *
- * @deprecated
- */
- @Deprecated
- protected void engineSetParameter(String key, Object param) {
- if (key.equals("KSEED")) {
- if (param instanceof byte[]) {
- Kseed = byteArray2IntArray((byte[])param);
- KseedAsByteArray = (byte[])param;
- } else {
- debug("unrecognized param: " + key);
- throw new InvalidParameterException("Kseed not a byte array");
- }
- } else {
- throw new InvalidParameterException("invalid parameter");
- }
- }
-
- /**
- * Return the value of the requested parameter. Recognized
- * parameters are:
- *
- * <dl>
- *
- * <dt><tt>Kseed</tt>
- *
- * <dd>a byte array.
- *
- * </dl>
- *
- * @return the value of the requested parameter.
- *
- * @see java.security.SignatureEngine
- *
- * @deprecated
- */
- @Deprecated
- protected Object engineGetParameter(String key) {
- if (key.equals("KSEED")) {
- return KseedAsByteArray;
- } else {
- return null;
- }
- }
-
- /**
- * Set the algorithm object.
- */
- private void setParams(DSAParams params) throws InvalidKeyException {
- if (params == null) {
- throw new InvalidKeyException("DSA public key lacks parameters");
- }
- this.params = params;
- this.presetP = params.getP();
- this.presetQ = params.getQ();
- this.presetG = params.getG();
- }
-
- /**
* Return a human readable rendition of the engine.
*/
public String toString() {
@@ -632,38 +411,6 @@
return printable;
}
- /*
- * Utility routine for converting a byte array into an int array
- */
- private int[] byteArray2IntArray(byte[] byteArray) {
-
- int j = 0;
- byte[] newBA;
- int mod = byteArray.length % 4;
-
- // guarantee that the incoming byteArray is a multiple of 4
- // (pad with 0's)
- switch (mod) {
- case 3: newBA = new byte[byteArray.length + 1]; break;
- case 2: newBA = new byte[byteArray.length + 2]; break;
- case 1: newBA = new byte[byteArray.length + 3]; break;
- default: newBA = new byte[byteArray.length + 0]; break;
- }
- System.arraycopy(byteArray, 0, newBA, 0, byteArray.length);
-
- // copy each set of 4 bytes in the byte array into an integer
- int[] newSeed = new int[newBA.length / 4];
- for (int i = 0; i < newBA.length; i += 4) {
- newSeed[j] = newBA[i + 3] & 0xFF;
- newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00;
- newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000;
- newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000;
- j++;
- }
-
- return newSeed;
- }
-
private static void debug(Exception e) {
if (debug) {
e.printStackTrace();
@@ -675,4 +422,325 @@
System.err.println(s);
}
}
+
+ /**
+ * Standard SHA224withDSA implementation as defined in FIPS186-3.
+ */
+ public static final class SHA224withDSA extends DSA {
+ public SHA224withDSA() throws NoSuchAlgorithmException {
+ super(MessageDigest.getInstance("SHA-224"));
+ }
+ }
+
+ /**
+ * Standard SHA256withDSA implementation as defined in FIPS186-3.
+ */
+ public static final class SHA256withDSA extends DSA {
+ public SHA256withDSA() throws NoSuchAlgorithmException {
+ super(MessageDigest.getInstance("SHA-256"));
+ }
+ }
+
+ static class LegacyDSA extends DSA {
+ /* The random seed used to generate k */
+ private int[] kSeed;
+ /* The random seed used to generate k (specified by application) */
+ private byte[] kSeedAsByteArray;
+ /*
+ * The random seed used to generate k
+ * (prevent the same Kseed from being used twice in a row
+ */
+ private int[] kSeedLast;
+
+ public LegacyDSA(MessageDigest md) throws NoSuchAlgorithmException {
+ super(md);
+ }
+
+ @Deprecated
+ protected void engineSetParameter(String key, Object param) {
+ if (key.equals("KSEED")) {
+ if (param instanceof byte[]) {
+ kSeed = byteArray2IntArray((byte[])param);
+ kSeedAsByteArray = (byte[])param;
+ } else {
+ debug("unrecognized param: " + key);
+ throw new InvalidParameterException("kSeed not a byte array");
+ }
+ } else {
+ throw new InvalidParameterException("Unsupported parameter");
+ }
+ }
+
+ @Deprecated
+ protected Object engineGetParameter(String key) {
+ if (key.equals("KSEED")) {
+ return kSeedAsByteArray;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ protected void checkKey(DSAParams params) throws InvalidKeyException {
+ int valueL = params.getP().bitLength();
+ if (valueL > 1024) {
+ throw new InvalidKeyException("Key is too long for this algorithm");
+ }
+ }
+
+ /*
+ * Please read bug report 4044247 for an alternative, faster,
+ * NON-FIPS approved method to generate K
+ */
+ @Override
+ protected BigInteger generateK(BigInteger q) {
+ BigInteger k = null;
+
+ // The application specified a kSeed for us to use.
+ // Note: we dis-allow usage of the same Kseed twice in a row
+ if (kSeed != null && !Arrays.equals(kSeed, kSeedLast)) {
+ k = generateKUsingKSeed(kSeed, q);
+ if (k.signum() > 0 && k.compareTo(q) < 0) {
+ kSeedLast = kSeed.clone();
+ return k;
+ }
+ }
+
+ // The application did not specify a Kseed for us to use.
+ // We'll generate a new Kseed by getting random bytes from
+ // a SecureRandom object.
+ SecureRandom random = getSigningRandom();
+
+ while (true) {
+ int[] seed = new int[5];
+
+ for (int i = 0; i < 5; i++) seed[i] = random.nextInt();
+
+ k = generateKUsingKSeed(seed, q);
+ if (k.signum() > 0 && k.compareTo(q) < 0) {
+ kSeedLast = seed;
+ return k;
+ }
+ }
+ }
+
+ /**
+ * Compute k for the DSA signature as defined in the original DSS,
+ * i.e. FIPS186.
+ *
+ * @param seed the seed for generating k. This seed should be
+ * secure. This is what is refered to as the KSEED in the DSA
+ * specification.
+ *
+ * @param g the g parameter from the DSA key pair.
+ */
+ private BigInteger generateKUsingKSeed(int[] seed, BigInteger q) {
+
+ // check out t in the spec.
+ int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476,
+ 0xC3D2E1F0, 0x67452301 };
+ //
+ int[] tmp = SHA_7(seed, t);
+ byte[] tmpBytes = new byte[tmp.length * 4];
+ for (int i = 0; i < tmp.length; i++) {
+ int k = tmp[i];
+ for (int j = 0; j < 4; j++) {
+ tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
+ }
+ }
+ BigInteger k = new BigInteger(1, tmpBytes).mod(q);
+ return k;
+ }
+
+ // Constants for each round
+ private static final int round1_kt = 0x5a827999;
+ private static final int round2_kt = 0x6ed9eba1;
+ private static final int round3_kt = 0x8f1bbcdc;
+ private static final int round4_kt = 0xca62c1d6;
+
+ /**
+ * Computes set 1 thru 7 of SHA-1 on m1. */
+ static int[] SHA_7(int[] m1, int[] h) {
+
+ int[] W = new int[80];
+ System.arraycopy(m1,0,W,0,m1.length);
+ int temp = 0;
+
+ for (int t = 16; t <= 79; t++){
+ temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
+ W[t] = ((temp << 1) | (temp >>>(32 - 1)));
+ }
+
+ int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4];
+ for (int i = 0; i < 20; i++) {
+ temp = ((a<<5) | (a>>>(32-5))) +
+ ((b&c)|((~b)&d))+ e + W[i] + round1_kt;
+ e = d;
+ d = c;
+ c = ((b<<30) | (b>>>(32-30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 2
+ for (int i = 20; i < 40; i++) {
+ temp = ((a<<5) | (a>>>(32-5))) +
+ (b ^ c ^ d) + e + W[i] + round2_kt;
+ e = d;
+ d = c;
+ c = ((b<<30) | (b>>>(32-30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 3
+ for (int i = 40; i < 60; i++) {
+ temp = ((a<<5) | (a>>>(32-5))) +
+ ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
+ e = d;
+ d = c;
+ c = ((b<<30) | (b>>>(32-30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 4
+ for (int i = 60; i < 80; i++) {
+ temp = ((a<<5) | (a>>>(32-5))) +
+ (b ^ c ^ d) + e + W[i] + round4_kt;
+ e = d;
+ d = c;
+ c = ((b<<30) | (b>>>(32-30)));
+ b = a;
+ a = temp;
+ }
+ int[] md = new int[5];
+ md[0] = h[0] + a;
+ md[1] = h[1] + b;
+ md[2] = h[2] + c;
+ md[3] = h[3] + d;
+ md[4] = h[4] + e;
+ return md;
+ }
+
+ /*
+ * Utility routine for converting a byte array into an int array
+ */
+ private int[] byteArray2IntArray(byte[] byteArray) {
+
+ int j = 0;
+ byte[] newBA;
+ int mod = byteArray.length % 4;
+
+ // guarantee that the incoming byteArray is a multiple of 4
+ // (pad with 0's)
+ switch (mod) {
+ case 3: newBA = new byte[byteArray.length + 1]; break;
+ case 2: newBA = new byte[byteArray.length + 2]; break;
+ case 1: newBA = new byte[byteArray.length + 3]; break;
+ default: newBA = new byte[byteArray.length + 0]; break;
+ }
+ System.arraycopy(byteArray, 0, newBA, 0, byteArray.length);
+
+ // copy each set of 4 bytes in the byte array into an integer
+ int[] newSeed = new int[newBA.length / 4];
+ for (int i = 0; i < newBA.length; i += 4) {
+ newSeed[j] = newBA[i + 3] & 0xFF;
+ newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00;
+ newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000;
+ newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000;
+ j++;
+ }
+
+ return newSeed;
+ }
+ }
+
+ public static final class SHA1withDSA extends LegacyDSA {
+ public SHA1withDSA() throws NoSuchAlgorithmException {
+ super(MessageDigest.getInstance("SHA-1"));
+ }
+ }
+
+ /**
+ * RawDSA implementation.
+ *
+ * RawDSA requires the data to be exactly 20 bytes long. If it is
+ * not, a SignatureException is thrown when sign()/verify() is called
+ * per JCA spec.
+ */
+ public static final class RawDSA extends LegacyDSA {
+ // Internal special-purpose MessageDigest impl for RawDSA
+ // Only override whatever methods used
+ // NOTE: no clone support
+ public static final class NullDigest20 extends MessageDigest {
+ // 20 byte digest buffer
+ private final byte[] digestBuffer = new byte[20];
+
+ // offset into the buffer; use Integer.MAX_VALUE to indicate
+ // out-of-bound condition
+ private int ofs = 0;
+
+ protected NullDigest20() {
+ super("NullDigest20");
+ }
+ protected void engineUpdate(byte input) {
+ if (ofs == digestBuffer.length) {
+ ofs = Integer.MAX_VALUE;
+ } else {
+ digestBuffer[ofs++] = input;
+ }
+ }
+ protected void engineUpdate(byte[] input, int offset, int len) {
+ if (ofs + len > digestBuffer.length) {
+ ofs = Integer.MAX_VALUE;
+ } else {
+ System.arraycopy(input, offset, digestBuffer, ofs, len);
+ ofs += len;
+ }
+ }
+ protected final void engineUpdate(ByteBuffer input) {
+ int inputLen = input.remaining();
+ if (ofs + inputLen > digestBuffer.length) {
+ ofs = Integer.MAX_VALUE;
+ } else {
+ input.get(digestBuffer, ofs, inputLen);
+ ofs += inputLen;
+ }
+ }
+ protected byte[] engineDigest() throws RuntimeException {
+ if (ofs != digestBuffer.length) {
+ throw new RuntimeException
+ ("Data for RawDSA must be exactly 20 bytes long");
+ }
+ reset();
+ return digestBuffer;
+ }
+ protected int engineDigest(byte[] buf, int offset, int len)
+ throws DigestException {
+ if (ofs != digestBuffer.length) {
+ throw new DigestException
+ ("Data for RawDSA must be exactly 20 bytes long");
+ }
+ if (len < digestBuffer.length) {
+ throw new DigestException
+ ("Output buffer too small; must be at least 20 bytes");
+ }
+ System.arraycopy(digestBuffer, 0, buf, offset, digestBuffer.length);
+ reset();
+ return digestBuffer.length;
+ }
+
+ protected void engineReset() {
+ ofs = 0;
+ }
+ protected final int engineGetDigestLength() {
+ return digestBuffer.length;
+ }
+ }
+
+ public RawDSA() throws NoSuchAlgorithmException {
+ super(new NullDigest20());
+ }
+ }
}
--- a/jdk/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -48,8 +48,9 @@
public class DSAKeyPairGenerator extends KeyPairGenerator
implements java.security.interfaces.DSAKeyPairGenerator {
- /* The modulus length */
- private int modlen;
+ /* Length for prime P and subPrime Q in bits */
+ private int plen;
+ private int qlen;
/* whether to force new parameters to be generated for each KeyPair */
private boolean forceNewParameters;
@@ -65,20 +66,23 @@
initialize(1024, null);
}
- private static void checkStrength(int strength) {
- if ((strength < 512) || (strength > 1024) || (strength % 64 != 0)) {
+ private static void checkStrength(int sizeP, int sizeQ) {
+ if ((sizeP >= 512) && (sizeP <= 1024) && (sizeP % 64 == 0)
+ && sizeQ == 160) {
+ // traditional - allow for backward compatibility
+ // L=multiples of 64 and between 512 and 1024 (inclusive)
+ // N=160
+ } else if (sizeP == 2048 && (sizeQ == 224 || sizeQ == 256)) {
+ // L=2048, N=224 or 256
+ } else {
throw new InvalidParameterException
- ("Modulus size must range from 512 to 1024 "
- + "and be a multiple of 64");
+ ("Unsupported prime and subprime size combination: " +
+ sizeP + ", " + sizeQ);
}
}
public void initialize(int modlen, SecureRandom random) {
- checkStrength(modlen);
- this.random = random;
- this.modlen = modlen;
- this.params = null;
- this.forceNewParameters = false;
+ initialize(modlen, false, random);
}
/**
@@ -86,18 +90,27 @@
* is false, a set of pre-computed parameters is used.
*/
public void initialize(int modlen, boolean genParams, SecureRandom random) {
- checkStrength(modlen);
+ int subPrimeLen = -1;
+ if (modlen <= 1024) {
+ subPrimeLen = 160;
+ } else if (modlen == 2048) {
+ subPrimeLen = 224;
+ }
+ checkStrength(modlen, subPrimeLen);
if (genParams) {
params = null;
} else {
- params = ParameterCache.getCachedDSAParameterSpec(modlen);
+ params = ParameterCache.getCachedDSAParameterSpec(modlen,
+ subPrimeLen);
if (params == null) {
throw new InvalidParameterException
("No precomputed parameters for requested modulus size "
+ "available");
}
+
}
- this.modlen = modlen;
+ this.plen = modlen;
+ this.qlen = subPrimeLen;
this.random = random;
this.forceNewParameters = genParams;
}
@@ -136,9 +149,11 @@
}
private void initialize0(DSAParameterSpec params, SecureRandom random) {
- int modlen = params.getP().bitLength();
- checkStrength(modlen);
- this.modlen = modlen;
+ int sizeP = params.getP().bitLength();
+ int sizeQ = params.getQ().bitLength();
+ checkStrength(sizeP, sizeQ);
+ this.plen = sizeP;
+ this.qlen = sizeQ;
this.params = params;
this.random = random;
this.forceNewParameters = false;
@@ -156,11 +171,11 @@
try {
if (forceNewParameters) {
// generate new parameters each time
- spec = ParameterCache.getNewDSAParameterSpec(modlen, random);
+ spec = ParameterCache.getNewDSAParameterSpec(plen, qlen, random);
} else {
if (params == null) {
params =
- ParameterCache.getDSAParameterSpec(modlen, random);
+ ParameterCache.getDSAParameterSpec(plen, qlen, random);
}
spec = params;
}
@@ -203,43 +218,14 @@
*/
private BigInteger generateX(SecureRandom random, BigInteger q) {
BigInteger x = null;
+ byte[] temp = new byte[qlen];
while (true) {
- int[] seed = new int[5];
- for (int i = 0; i < 5; i++) {
- seed[i] = random.nextInt();
- }
- x = generateX(seed, q);
+ random.nextBytes(temp);
+ x = new BigInteger(1, temp).mod(q);
if (x.signum() > 0 && (x.compareTo(q) < 0)) {
- break;
+ return x;
}
}
- return x;
- }
-
- /**
- * Given a seed, generate the private key component of the key
- * pair. In the terminology used in the DSA specification
- * (FIPS-186) seed is the XSEED quantity.
- *
- * @param seed the seed to use to generate the private key.
- */
- BigInteger generateX(int[] seed, BigInteger q) {
-
- // check out t in the spec.
- int[] t = { 0x67452301, 0xEFCDAB89, 0x98BADCFE,
- 0x10325476, 0xC3D2E1F0 };
- //
-
- int[] tmp = DSA.SHA_7(seed, t);
- byte[] tmpBytes = new byte[tmp.length * 4];
- for (int i = 0; i < tmp.length; i++) {
- int k = tmp[i];
- for (int j = 0; j < 4; j++) {
- tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
- }
- }
- BigInteger x = new BigInteger(1, tmpBytes).mod(q);
- return x;
}
/**
--- a/jdk/src/share/classes/sun/security/provider/DSAParameterGenerator.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/provider/DSAParameterGenerator.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -32,10 +32,12 @@
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.InvalidParameterException;
+import java.security.MessageDigest;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.DSAParameterSpec;
+import java.security.spec.DSAGenParameterSpec;
/**
* This class generates parameters for the DSA algorithm. It uses a default
@@ -54,8 +56,14 @@
public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
- // the modulus length
- private int modLen = 1024; // default
+ // the default parameters
+ private static final DSAGenParameterSpec DEFAULTS =
+ new DSAGenParameterSpec(1024, 160, 160);
+
+ // the length of prime P, subPrime Q, and seed in bits
+ private int valueL = -1;
+ private int valueN = -1;
+ private int seedLen = -1;
// the source of randomness
private SecureRandom random;
@@ -65,11 +73,7 @@
private static final BigInteger ONE = BigInteger.valueOf(1);
private static final BigInteger TWO = BigInteger.valueOf(2);
- // Make a SHA-1 hash function
- private SHA sha;
-
public DSAParameterGenerator() {
- this.sha = new SHA();
}
/**
@@ -80,19 +84,18 @@
* @param random the source of randomness
*/
protected void engineInit(int strength, SecureRandom random) {
- /*
- * Bruce Schneier, "Applied Cryptography", 2nd Edition,
- * Description of DSA:
- * [...] The algorithm uses the following parameter:
- * p=a prime number L bits long, when L ranges from 512 to 1024 and is
- * a multiple of 64. [...]
- */
- if ((strength < 512) || (strength > 1024) || (strength % 64 != 0)) {
+ if ((strength >= 512) && (strength <= 1024) && (strength % 64 == 0)) {
+ this.valueN = 160;
+ } else if (strength == 2048) {
+ this.valueN = 224;
+// } else if (strength == 3072) {
+// this.valueN = 256;
+ } else {
throw new InvalidParameterException
- ("Prime size must range from 512 to 1024 "
- + "and be a multiple of 64");
+ ("Prime size should be 512 - 1024, or 2048");
}
- this.modLen = strength;
+ this.valueL = strength;
+ this.seedLen = valueN;
this.random = random;
}
@@ -100,7 +103,7 @@
* Initializes this parameter generator with a set of
* algorithm-specific parameter generation values.
*
- * @param params the set of algorithm-specific parameter generation values
+ * @param genParamSpec the set of algorithm-specific parameter generation values
* @param random the source of randomness
*
* @exception InvalidAlgorithmParameterException if the given parameter
@@ -109,7 +112,19 @@
protected void engineInit(AlgorithmParameterSpec genParamSpec,
SecureRandom random)
throws InvalidAlgorithmParameterException {
+ if (!(genParamSpec instanceof DSAGenParameterSpec)) {
throw new InvalidAlgorithmParameterException("Invalid parameter");
+ }
+ DSAGenParameterSpec dsaGenParams = (DSAGenParameterSpec) genParamSpec;
+ if (dsaGenParams.getPrimePLength() > 2048) {
+ throw new InvalidParameterException
+ ("Prime size should be 512 - 1024, or 2048");
+ }
+ // directly initialize using the already validated values
+ this.valueL = dsaGenParams.getPrimePLength();
+ this.valueN = dsaGenParams.getSubprimeQLength();
+ this.seedLen = dsaGenParams.getSeedLength();
+ this.random = random;
}
/**
@@ -123,15 +138,21 @@
if (this.random == null) {
this.random = new SecureRandom();
}
-
- BigInteger[] pAndQ = generatePandQ(this.random, this.modLen);
+ if (valueL == -1) {
+ try {
+ engineInit(DEFAULTS, this.random);
+ } catch (InvalidAlgorithmParameterException iape) {
+ // should never happen
+ }
+ }
+ BigInteger[] pAndQ = generatePandQ(this.random, valueL,
+ valueN, seedLen);
BigInteger paramP = pAndQ[0];
BigInteger paramQ = pAndQ[1];
BigInteger paramG = generateG(paramP, paramQ);
- DSAParameterSpec dsaParamSpec = new DSAParameterSpec(paramP,
- paramQ,
- paramG);
+ DSAParameterSpec dsaParamSpec =
+ new DSAParameterSpec(paramP, paramQ, paramG);
algParams = AlgorithmParameters.getInstance("DSA", "SUN");
algParams.init(dsaParamSpec);
} catch (InvalidParameterSpecException e) {
@@ -156,102 +177,98 @@
*
* @param random the source of randomness to generate the
* seed
- * @param L the size of <code>p</code>, in bits.
+ * @param valueL the size of <code>p</code>, in bits.
+ * @param valueN the size of <code>q</code>, in bits.
+ * @param seedLen the length of <code>seed</code>, in bits.
*
* @return an array of BigInteger, with <code>p</code> at index 0 and
- * <code>q</code> at index 1.
+ * <code>q</code> at index 1, the seed at index 2, and the counter value
+ * at index 3.
*/
- BigInteger[] generatePandQ(SecureRandom random, int L) {
- BigInteger[] result = null;
- byte[] seed = new byte[20];
-
- while(result == null) {
- for (int i = 0; i < 20; i++) {
- seed[i] = (byte)random.nextInt();
- }
- result = generatePandQ(seed, L);
+ private static BigInteger[] generatePandQ(SecureRandom random, int valueL,
+ int valueN, int seedLen) {
+ String hashAlg = null;
+ if (valueN == 160) {
+ hashAlg = "SHA";
+ } else if (valueN == 224) {
+ hashAlg = "SHA-224";
+ } else if (valueN == 256) {
+ hashAlg = "SHA-256";
}
- return result;
- }
+ MessageDigest hashObj = null;
+ try {
+ hashObj = MessageDigest.getInstance(hashAlg);
+ } catch (NoSuchAlgorithmException nsae) {
+ // should never happen
+ nsae.printStackTrace();
+ }
- /*
- * Generates the prime and subprime parameters for DSA.
- *
- * <p>The seed parameter corresponds to the <code>SEED</code> parameter
- * referenced in the FIPS specification of the DSA algorithm,
- * and L is the size of <code>p</code>, in bits.
- *
- * @param seed the seed to generate the parameters
- * @param L the size of <code>p</code>, in bits.
- *
- * @return an array of BigInteger, with <code>p</code> at index 0,
- * <code>q</code> at index 1, the seed at index 2, and the counter value
- * at index 3, or null if the seed does not yield suitable numbers.
- */
- BigInteger[] generatePandQ(byte[] seed, int L) {
+ /* Step 3, 4: Useful variables */
+ int outLen = hashObj.getDigestLength()*8;
+ int n = (valueL - 1) / outLen;
+ int b = (valueL - 1) % outLen;
+ byte[] seedBytes = new byte[seedLen/8];
+ BigInteger twoSl = TWO.pow(seedLen);
+ int primeCertainty = 80; // for 1024-bit prime P
+ if (valueL == 2048) {
+ primeCertainty = 112;
+ //} else if (valueL == 3072) {
+ // primeCertainty = 128;
+ }
- /* Useful variables */
- int g = seed.length * 8;
- int n = (L - 1) / 160;
- int b = (L - 1) % 160;
-
- BigInteger SEED = new BigInteger(1, seed);
- BigInteger TWOG = TWO.pow(2 * g);
-
- /* Step 2 (Step 1 is getting seed). */
- byte[] U1 = SHA(seed);
- byte[] U2 = SHA(toByteArray((SEED.add(ONE)).mod(TWOG)));
-
- xor(U1, U2);
- byte[] U = U1;
+ BigInteger resultP, resultQ, seed = null;
+ int counter;
+ while (true) {
+ do {
+ /* Step 5 */
+ random.nextBytes(seedBytes);
+ seed = new BigInteger(1, seedBytes);
- /* Step 3: For q by setting the msb and lsb to 1 */
- U[0] |= 0x80;
- U[19] |= 1;
- BigInteger q = new BigInteger(1, U);
-
- /* Step 5 */
- if (!q.isProbablePrime(80)) {
- return null;
+ /* Step 6 */
+ BigInteger U = new BigInteger(1, hashObj.digest(seedBytes)).
+ mod(TWO.pow(valueN - 1));
- } else {
- BigInteger V[] = new BigInteger[n + 1];
- BigInteger offset = TWO;
-
- /* Step 6 */
- for (int counter = 0; counter < 4096; counter++) {
-
- /* Step 7 */
- for (int k = 0; k <= n; k++) {
- BigInteger K = BigInteger.valueOf(k);
- BigInteger tmp = (SEED.add(offset).add(K)).mod(TWOG);
- V[k] = new BigInteger(1, SHA(toByteArray(tmp)));
- }
+ /* Step 7 */
+ resultQ = TWO.pow(valueN - 1).add(U).add(ONE). subtract(U.mod(TWO));
+ } while (!resultQ.isProbablePrime(primeCertainty));
- /* Step 8 */
- BigInteger W = V[0];
- for (int i = 1; i < n; i++) {
- W = W.add(V[i].multiply(TWO.pow(i * 160)));
- }
- W = W.add((V[n].mod(TWO.pow(b))).multiply(TWO.pow(n * 160)));
-
- BigInteger TWOLm1 = TWO.pow(L - 1);
- BigInteger X = W.add(TWOLm1);
+ /* Step 10 */
+ BigInteger offset = ONE;
+ /* Step 11 */
+ for (counter = 0; counter < 4*valueL; counter++) {
+ BigInteger V[] = new BigInteger[n + 1];
+ /* Step 11.1 */
+ for (int j = 0; j <= n; j++) {
+ BigInteger J = BigInteger.valueOf(j);
+ BigInteger tmp = (seed.add(offset).add(J)).mod(twoSl);
+ byte[] vjBytes = hashObj.digest(toByteArray(tmp));
+ V[j] = new BigInteger(1, vjBytes);
+ }
+ /* Step 11.2 */
+ BigInteger W = V[0];
+ for (int i = 1; i < n; i++) {
+ W = W.add(V[i].multiply(TWO.pow(i * outLen)));
+ }
+ W = W.add((V[n].mod(TWO.pow(b))).multiply(TWO.pow(n * outLen)));
+ /* Step 11.3 */
+ BigInteger twoLm1 = TWO.pow(valueL - 1);
+ BigInteger X = W.add(twoLm1);
+ /* Step 11.4, 11.5 */
+ BigInteger c = X.mod(resultQ.multiply(TWO));
+ resultP = X.subtract(c.subtract(ONE));
+ /* Step 11.6, 11.7 */
+ if (resultP.compareTo(twoLm1) > -1
+ && resultP.isProbablePrime(primeCertainty)) {
+ /* Step 11.8 */
+ BigInteger[] result = {resultP, resultQ, seed,
+ BigInteger.valueOf(counter)};
+ return result;
+ }
+ /* Step 11.9 */
+ offset = offset.add(BigInteger.valueOf(n)).add(ONE);
+ }
+ }
- /* Step 9 */
- BigInteger c = X.mod(q.multiply(TWO));
- BigInteger p = X.subtract(c.subtract(ONE));
-
- /* Step 10 - 13 */
- if (p.compareTo(TWOLm1) > -1 && p.isProbablePrime(80)) {
- BigInteger[] result = {p, q, SEED,
- BigInteger.valueOf(counter)};
- return result;
- }
- offset = offset.add(BigInteger.valueOf(n)).add(ONE);
- }
- return null;
- }
}
/*
@@ -262,31 +279,24 @@
*
* @param the <code>g</code>
*/
- BigInteger generateG(BigInteger p, BigInteger q) {
+ private static BigInteger generateG(BigInteger p, BigInteger q) {
BigInteger h = ONE;
+ /* Step 1 */
BigInteger pMinusOneOverQ = (p.subtract(ONE)).divide(q);
- BigInteger g = ONE;
- while (g.compareTo(TWO) < 0) {
- g = h.modPow(pMinusOneOverQ, p);
+ BigInteger resultG = ONE;
+ while (resultG.compareTo(TWO) < 0) {
+ /* Step 3 */
+ resultG = h.modPow(pMinusOneOverQ, p);
h = h.add(ONE);
}
- return g;
- }
-
- /*
- * Returns the SHA-1 digest of some data
- */
- private byte[] SHA(byte[] array) {
- sha.engineReset();
- sha.engineUpdate(array, 0, array.length);
- return sha.engineDigest();
+ return resultG;
}
/*
* Converts the result of a BigInteger.toByteArray call to an exact
* signed magnitude representation for any positive number.
*/
- private byte[] toByteArray(BigInteger bigInt) {
+ private static byte[] toByteArray(BigInteger bigInt) {
byte[] result = bigInt.toByteArray();
if (result[0] == 0) {
byte[] tmp = new byte[result.length - 1];
@@ -295,13 +305,4 @@
}
return result;
}
-
- /*
- * XORs U2 into U1
- */
- private void xor(byte[] U1, byte[] U2) {
- for (int i = 0; i < U1.length; i++) {
- U1[i] ^= U2[i];
- }
- }
}
--- a/jdk/src/share/classes/sun/security/provider/ParameterCache.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/provider/ParameterCache.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package sun.security.provider;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
import java.math.BigInteger;
import java.security.*;
@@ -55,11 +56,17 @@
private final static Map<Integer,DHParameterSpec> dhCache;
/**
- * Return cached DSA parameters for the given keylength, or null if none
- * are available in the cache.
+ * Return cached DSA parameters for the given length combination of
+ * prime and subprime, or null if none are available in the cache.
*/
- public static DSAParameterSpec getCachedDSAParameterSpec(int keyLength) {
- return dsaCache.get(Integer.valueOf(keyLength));
+ public static DSAParameterSpec getCachedDSAParameterSpec(int primeLen,
+ int subprimeLen) {
+ // ensure the sum is unique in all cases, i.e.
+ // case#1: (512 <= p <= 1024) AND q=160
+ // case#2: p=2048 AND q=224
+ // case#3: p=2048 AND q=256
+ // (NOT-YET-SUPPORTED)case#4: p=3072 AND q=256
+ return dsaCache.get(Integer.valueOf(primeLen+subprimeLen));
}
/**
@@ -71,18 +78,39 @@
}
/**
- * Return DSA parameters for the given keylength. Uses cache if possible,
- * generates new parameters and adds them to the cache otherwise.
+ * Return DSA parameters for the given primeLen. Uses cache if
+ * possible, generates new parameters and adds them to the cache
+ * otherwise.
*/
- public static DSAParameterSpec getDSAParameterSpec(int keyLength,
+ public static DSAParameterSpec getDSAParameterSpec(int primeLen,
SecureRandom random)
- throws NoSuchAlgorithmException, InvalidParameterSpecException {
- DSAParameterSpec spec = getCachedDSAParameterSpec(keyLength);
+ throws NoSuchAlgorithmException, InvalidParameterSpecException,
+ InvalidAlgorithmParameterException {
+ if (primeLen <= 1024) {
+ return getDSAParameterSpec(primeLen, 160, random);
+ } else if (primeLen == 2048) {
+ return getDSAParameterSpec(primeLen, 224, random);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Return DSA parameters for the given primeLen and subprimeLen.
+ * Uses cache if possible, generates new parameters and adds them to the
+ * cache otherwise.
+ */
+ public static DSAParameterSpec getDSAParameterSpec(int primeLen,
+ int subprimeLen, SecureRandom random)
+ throws NoSuchAlgorithmException, InvalidParameterSpecException,
+ InvalidAlgorithmParameterException {
+ DSAParameterSpec spec =
+ getCachedDSAParameterSpec(primeLen, subprimeLen);
if (spec != null) {
return spec;
}
- spec = getNewDSAParameterSpec(keyLength, random);
- dsaCache.put(Integer.valueOf(keyLength), spec);
+ spec = getNewDSAParameterSpec(primeLen, subprimeLen, random);
+ dsaCache.put(Integer.valueOf(primeLen + subprimeLen), spec);
return spec;
}
@@ -107,28 +135,28 @@
}
/**
- * Return new DSA parameters for the given keylength. Do not lookup in
- * cache and do not cache the newly generated parameters. This method
- * really only exists for the legacy method
+ * Return new DSA parameters for the given length combination of prime and
+ * sub prime. Do not lookup in cache and do not cache the newly generated
+ * parameters. This method really only exists for the legacy method
* DSAKeyPairGenerator.initialize(int, boolean, SecureRandom).
*/
- public static DSAParameterSpec getNewDSAParameterSpec(int keyLength,
- SecureRandom random)
- throws NoSuchAlgorithmException, InvalidParameterSpecException {
+ public static DSAParameterSpec getNewDSAParameterSpec(int primeLen,
+ int subprimeLen, SecureRandom random)
+ throws NoSuchAlgorithmException, InvalidParameterSpecException,
+ InvalidAlgorithmParameterException {
AlgorithmParameterGenerator gen =
AlgorithmParameterGenerator.getInstance("DSA");
- gen.init(keyLength, random);
+ DSAGenParameterSpec genParams =
+ new DSAGenParameterSpec(primeLen, subprimeLen);
+ gen.init(genParams, random);
AlgorithmParameters params = gen.generateParameters();
DSAParameterSpec spec = params.getParameterSpec(DSAParameterSpec.class);
return spec;
}
static {
- // XXX change to ConcurrentHashMap once available
- dhCache = Collections.synchronizedMap
- (new HashMap<Integer,DHParameterSpec>());
- dsaCache = Collections.synchronizedMap
- (new HashMap<Integer,DSAParameterSpec>());
+ dhCache = new ConcurrentHashMap<Integer,DHParameterSpec>();
+ dsaCache = new ConcurrentHashMap<Integer,DSAParameterSpec>();
/*
* We support precomputed parameter for 512, 768 and 1024 bit
@@ -210,17 +238,99 @@
"83dfe15ae59f06928b665e807b552564014c3bfecf" +
"492a", 16);
- dsaCache.put(Integer.valueOf(512),
+ dsaCache.put(Integer.valueOf(512+160),
new DSAParameterSpec(p512, q512, g512));
- dsaCache.put(Integer.valueOf(768),
+ dsaCache.put(Integer.valueOf(768+160),
new DSAParameterSpec(p768, q768, g768));
- dsaCache.put(Integer.valueOf(1024),
+ dsaCache.put(Integer.valueOf(1024+160),
new DSAParameterSpec(p1024, q1024, g1024));
+ /*
+ * L = 2048, N = 224
+ * SEED = 584236080cfa43c09b02354135f4cc5198a19efada08bd866d601ba4
+ * counter = 2666
+ */
+ BigInteger p2048_224 =
+ new BigInteger("8f7935d9b9aae9bfabed887acf4951b6f32ec59e3b" +
+ "af3718e8eac4961f3efd3606e74351a9c4183339b8" +
+ "09e7c2ae1c539ba7475b85d011adb8b47987754984" +
+ "695cac0e8f14b3360828a22ffa27110a3d62a99345" +
+ "3409a0fe696c4658f84bdd20819c3709a01057b195" +
+ "adcd00233dba5484b6291f9d648ef883448677979c" +
+ "ec04b434a6ac2e75e9985de23db0292fc1118c9ffa" +
+ "9d8181e7338db792b730d7b9e349592f6809987215" +
+ "3915ea3d6b8b4653c633458f803b32a4c2e0f27290" +
+ "256e4e3f8a3b0838a1c450e4e18c1a29a37ddf5ea1" +
+ "43de4b66ff04903ed5cf1623e158d487c608e97f21" +
+ "1cd81dca23cb6e380765f822e342be484c05763939" +
+ "601cd667", 16);
+
+ BigInteger q2048_224 =
+ new BigInteger("baf696a68578f7dfdee7fa67c977c785ef32b233ba" +
+ "e580c0bcd5695d", 16);
+
+ BigInteger g2048_224 =
+ new BigInteger("16a65c58204850704e7502a39757040d34da3a3478" +
+ "c154d4e4a5c02d242ee04f96e61e4bd0904abdac8f" +
+ "37eeb1e09f3182d23c9043cb642f88004160edf9ca" +
+ "09b32076a79c32a627f2473e91879ba2c4e744bd20" +
+ "81544cb55b802c368d1fa83ed489e94e0fa0688e32" +
+ "428a5c78c478c68d0527b71c9a3abb0b0be12c4468" +
+ "9639e7d3ce74db101a65aa2b87f64c6826db3ec72f" +
+ "4b5599834bb4edb02f7c90e9a496d3a55d535bebfc" +
+ "45d4f619f63f3dedbb873925c2f224e07731296da8" +
+ "87ec1e4748f87efb5fdeb75484316b2232dee553dd" +
+ "af02112b0d1f02da30973224fe27aeda8b9d4b2922" +
+ "d9ba8be39ed9e103a63c52810bc688b7e2ed4316e1" +
+ "ef17dbde", 16);
+ dsaCache.put(Integer.valueOf(2048+224),
+ new DSAParameterSpec(p2048_224, q2048_224, g2048_224));
+
+ /*
+ * L = 2048, N = 256
+ * SEED = b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536
+ * counter = 497
+ */
+ BigInteger p2048_256 =
+ new BigInteger("95475cf5d93e596c3fcd1d902add02f427f5f3c721" +
+ "0313bb45fb4d5bb2e5fe1cbd678cd4bbdd84c9836b" +
+ "e1f31c0777725aeb6c2fc38b85f48076fa76bcd814" +
+ "6cc89a6fb2f706dd719898c2083dc8d896f84062e2" +
+ "c9c94d137b054a8d8096adb8d51952398eeca852a0" +
+ "af12df83e475aa65d4ec0c38a9560d5661186ff98b" +
+ "9fc9eb60eee8b030376b236bc73be3acdbd74fd61c" +
+ "1d2475fa3077b8f080467881ff7e1ca56fee066d79" +
+ "506ade51edbb5443a563927dbc4ba520086746175c" +
+ "8885925ebc64c6147906773496990cb714ec667304" +
+ "e261faee33b3cbdf008e0c3fa90650d97d3909c927" +
+ "5bf4ac86ffcb3d03e6dfc8ada5934242dd6d3bcca2" +
+ "a406cb0b", 16);
+
+ BigInteger q2048_256 =
+ new BigInteger("f8183668ba5fc5bb06b5981e6d8b795d30b8978d43" +
+ "ca0ec572e37e09939a9773", 16);
+
+ BigInteger g2048_256 =
+ new BigInteger("42debb9da5b3d88cc956e08787ec3f3a09bba5f48b" +
+ "889a74aaf53174aa0fbe7e3c5b8fcd7a53bef563b0" +
+ "e98560328960a9517f4014d3325fc7962bf1e04937" +
+ "0d76d1314a76137e792f3f0db859d095e4a5b93202" +
+ "4f079ecf2ef09c797452b0770e1350782ed57ddf79" +
+ "4979dcef23cb96f183061965c4ebc93c9c71c56b92" +
+ "5955a75f94cccf1449ac43d586d0beee43251b0b22" +
+ "87349d68de0d144403f13e802f4146d882e057af19" +
+ "b6f6275c6676c8fa0e3ca2713a3257fd1b27d0639f" +
+ "695e347d8d1cf9ac819a26ca9b04cb0eb9b7b03598" +
+ "8d15bbac65212a55239cfc7e58fae38d7250ab9991" +
+ "ffbc97134025fe8ce04c4399ad96569be91a546f49" +
+ "78693c7a", 16);
+ dsaCache.put(Integer.valueOf(2048+256),
+ new DSAParameterSpec(p2048_256, q2048_256, g2048_256));
// use DSA parameters for DH as well
dhCache.put(Integer.valueOf(512), new DHParameterSpec(p512, g512));
dhCache.put(Integer.valueOf(768), new DHParameterSpec(p768, g768));
dhCache.put(Integer.valueOf(1024), new DHParameterSpec(p1024, g1024));
+ dhCache.put(Integer.valueOf(2048), new DHParameterSpec(p2048_224, g2048_224));
}
}
--- a/jdk/src/share/classes/sun/security/provider/SunEntries.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/provider/SunEntries.java Fri Sep 14 13:52:30 2012 -0700
@@ -47,6 +47,10 @@
* SHA-2 family of hash functions includes SHA-224, SHA-256, SHA-384,
* and SHA-512.
*
+ * - SHA-224withDSA/SHA-256withDSA are the signature schemes
+ * described in FIPS 186-3. The associated object identifiers are
+ * "OID.2.16.840.1.101.3.4.3.1", and "OID.2.16.840.1.101.3.4.3.2".
+
* - DSA is the key generation scheme as described in FIPS 186.
* Aliases for DSA include the OID strings "OID.1.3.14.3.2.12"
* and "OID.1.2.840.10040.4.1".
@@ -106,11 +110,15 @@
map.put("Signature.SHA1withDSA", "sun.security.provider.DSA$SHA1withDSA");
map.put("Signature.NONEwithDSA", "sun.security.provider.DSA$RawDSA");
map.put("Alg.Alias.Signature.RawDSA", "NONEwithDSA");
+ map.put("Signature.SHA224withDSA", "sun.security.provider.DSA$SHA224withDSA");
+ map.put("Signature.SHA256withDSA", "sun.security.provider.DSA$SHA256withDSA");
String dsaKeyClasses = "java.security.interfaces.DSAPublicKey" +
"|java.security.interfaces.DSAPrivateKey";
map.put("Signature.SHA1withDSA SupportedKeyClasses", dsaKeyClasses);
map.put("Signature.NONEwithDSA SupportedKeyClasses", dsaKeyClasses);
+ map.put("Signature.SHA224withDSA SupportedKeyClasses", dsaKeyClasses);
+ map.put("Signature.SHA256withDSA SupportedKeyClasses", dsaKeyClasses);
map.put("Alg.Alias.Signature.DSA", "SHA1withDSA");
map.put("Alg.Alias.Signature.DSS", "SHA1withDSA");
@@ -124,6 +132,10 @@
map.put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
map.put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA");
map.put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA");
+ map.put("Alg.Alias.Signature.OID.2.16.840.1.101.3.4.3.1", "SHA224withDSA");
+ map.put("Alg.Alias.Signature.2.16.840.1.101.3.4.3.1", "SHA224withDSA");
+ map.put("Alg.Alias.Signature.OID.2.16.840.1.101.3.4.3.2", "SHA256withDSA");
+ map.put("Alg.Alias.Signature.2.16.840.1.101.3.4.3.2", "SHA256withDSA");
/*
* Key Pair Generator engines
@@ -143,6 +155,8 @@
map.put("Alg.Alias.MessageDigest.SHA-1", "SHA");
map.put("Alg.Alias.MessageDigest.SHA1", "SHA");
+ map.put("Alg.Alias.MessageDigest.1.3.14.3.2.26", "SHA");
+ map.put("Alg.Alias.MessageDigest.OID.1.3.14.3.2.26", "SHA");
map.put("MessageDigest.SHA-224", "sun.security.provider.SHA2$SHA224");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.4", "SHA-224");
@@ -169,15 +183,17 @@
*/
map.put("AlgorithmParameters.DSA",
"sun.security.provider.DSAParameters");
+ map.put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.1", "DSA");
+ map.put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA");
- map.put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1", "DSA");
/*
* Key factories
*/
map.put("KeyFactory.DSA", "sun.security.provider.DSAKeyFactory");
+ map.put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSA");
+ map.put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA");
- map.put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");
/*
* Certificates
@@ -234,9 +250,13 @@
/*
* KeySize
*/
+ map.put("Signature.NONEwithDSA KeySize", "1024");
map.put("Signature.SHA1withDSA KeySize", "1024");
- map.put("KeyPairGenerator.DSA KeySize", "1024");
- map.put("AlgorithmParameterGenerator.DSA KeySize", "1024");
+ map.put("Signature.SHA224withDSA KeySize", "2048");
+ map.put("Signature.SHA256withDSA KeySize", "2048");
+
+ map.put("KeyPairGenerator.DSA KeySize", "2048");
+ map.put("AlgorithmParameterGenerator.DSA KeySize", "2048");
/*
* Implementation type: software or hardware
--- a/jdk/src/share/classes/sun/security/x509/AlgorithmId.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/classes/sun/security/x509/AlgorithmId.java Fri Sep 14 13:52:30 2012 -0700
@@ -120,21 +120,14 @@
try {
algParams = AlgorithmParameters.getInstance(algidString);
} catch (NoSuchAlgorithmException e) {
- try {
- // Try the internal EC code so that we can fully parse EC
- // keys even if the provider is not registered.
- // This code can go away once we have EC in the SUN provider.
- algParams = AlgorithmParameters.getInstance(algidString,
- sun.security.ec.ECKeyFactory.ecInternalProvider);
- } catch (NoSuchAlgorithmException ee) {
- /*
- * This algorithm parameter type is not supported, so we cannot
- * parse the parameters.
- */
- algParams = null;
- return;
- }
+ /*
+ * This algorithm parameter type is not supported, so we cannot
+ * parse the parameters.
+ */
+ algParams = null;
+ return;
}
+
// Decode (parse) the parameters
algParams.init(params.toByteArray());
}
@@ -505,6 +498,9 @@
if (name.equalsIgnoreCase("EC")) {
return EC_oid;
}
+ if (name.equalsIgnoreCase("ECDH")) {
+ return AlgorithmId.ECDH_oid;
+ }
// Common signature types
if (name.equalsIgnoreCase("MD5withRSA")
@@ -524,6 +520,12 @@
|| name.equalsIgnoreCase("SHA-1/DSA")) {
return AlgorithmId.sha1WithDSA_oid;
}
+ if (name.equalsIgnoreCase("SHA224WithDSA")) {
+ return AlgorithmId.sha224WithDSA_oid;
+ }
+ if (name.equalsIgnoreCase("SHA256WithDSA")) {
+ return AlgorithmId.sha256WithDSA_oid;
+ }
if (name.equalsIgnoreCase("SHA1WithRSA")
|| name.equalsIgnoreCase("SHA1/RSA")) {
return AlgorithmId.sha1WithRSAEncryption_oid;
@@ -654,6 +656,7 @@
public static final ObjectIdentifier DSA_oid;
public static final ObjectIdentifier DSA_OIW_oid;
public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1);
+ public static final ObjectIdentifier ECDH_oid = oid(1, 3, 132, 1, 12);
public static final ObjectIdentifier RSA_oid;
public static final ObjectIdentifier RSAEncryption_oid;
@@ -694,6 +697,10 @@
public static final ObjectIdentifier shaWithDSA_OIW_oid;
public static final ObjectIdentifier sha1WithDSA_OIW_oid;
public static final ObjectIdentifier sha1WithDSA_oid;
+ public static final ObjectIdentifier sha224WithDSA_oid =
+ oid(2, 16, 840, 1, 101, 3, 4, 3, 1);
+ public static final ObjectIdentifier sha256WithDSA_oid =
+ oid(2, 16, 840, 1, 101, 3, 4, 3, 2);
public static final ObjectIdentifier sha1WithECDSA_oid =
oid(1, 2, 840, 10045, 4, 1);
@@ -725,7 +732,6 @@
public static ObjectIdentifier pbeWithSHA1AndRC2_40_oid =
ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 6});
-
static {
/*
* Note the preferred OIDs are named simply with no "OIW" or
@@ -885,6 +891,8 @@
nameTable.put(DSA_oid, "DSA");
nameTable.put(DSA_OIW_oid, "DSA");
nameTable.put(EC_oid, "EC");
+ nameTable.put(ECDH_oid, "ECDH");
+
nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA");
nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA");
nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA");
@@ -895,6 +903,8 @@
nameTable.put(sha1WithDSA_oid, "SHA1withDSA");
nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA");
nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA");
+ nameTable.put(sha224WithDSA_oid, "SHA224withDSA");
+ nameTable.put(sha256WithDSA_oid, "SHA256withDSA");
nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA");
nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA");
nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA");
--- a/jdk/src/share/demo/applets/CardTest/example1.html Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/demo/applets/CardTest/example1.html Fri Sep 14 13:52:30 2012 -0700
@@ -5,7 +5,7 @@
<body>
<h1>Card Test (1.1)</h1>
<hr>
- <applet code=CardTest.class width=400 height=300>
+ <applet code=CardTest.class width=455 height=300>
alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason."
Your browser is completely ignoring the <APPLET> tag!
</applet>
--- a/jdk/src/share/demo/applets/DitherTest/example1.html Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/demo/applets/DitherTest/example1.html Fri Sep 14 13:52:30 2012 -0700
@@ -5,7 +5,7 @@
<body>
<h1>Dither Test (1.1)</h1>
<hr>
- <applet code=DitherTest.class width=425 height=400>
+ <applet code=DitherTest.class width=455 height=400>
alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason."
Your browser is completely ignoring the <APPLET> tag!
</applet>
--- a/jdk/src/share/demo/jvmti/hprof/debug_malloc.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/demo/jvmti/hprof/debug_malloc.h Fri Sep 14 13:52:30 2012 -0700
@@ -59,6 +59,11 @@
#include <stdlib.h>
#include <string.h>
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/* The real functions behind the macro curtains. */
void *debug_malloc(size_t, const char *, int);
@@ -71,10 +76,10 @@
void debug_malloc_verify(const char*, int);
#undef malloc_verify
-#define malloc_verify() debug_malloc_verify(__FILE__, __LINE__)
+#define malloc_verify() debug_malloc_verify(THIS_FILE, __LINE__)
void debug_malloc_police(const char*, int);
#undef malloc_police
-#define malloc_police() debug_malloc_police(__FILE__, __LINE__)
+#define malloc_police() debug_malloc_police(THIS_FILE, __LINE__)
#endif
--- a/jdk/src/share/demo/jvmti/hprof/hprof_error.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/demo/jvmti/hprof/hprof_error.h Fri Sep 14 13:52:30 2012 -0700
@@ -41,20 +41,25 @@
#ifndef HPROF_ERROR_H
#define HPROF_ERROR_H
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/* Macros over assert and error functions so we can capture the source loc. */
#define HPROF_BOOL(x) ((jboolean)((x)==0?JNI_FALSE:JNI_TRUE))
#define HPROF_ERROR(fatal,msg) \
- error_handler(HPROF_BOOL(fatal), JVMTI_ERROR_NONE, msg, __FILE__, __LINE__)
+ error_handler(HPROF_BOOL(fatal), JVMTI_ERROR_NONE, msg, THIS_FILE, __LINE__)
#define HPROF_JVMTI_ERROR(error,msg) \
error_handler(HPROF_BOOL(error!=JVMTI_ERROR_NONE), \
- error, msg, __FILE__, __LINE__)
+ error, msg, THIS_FILE, __LINE__)
#if defined(DEBUG) || !defined(NDEBUG)
#define HPROF_ASSERT(cond) \
- (((int)(cond))?(void)0:error_assert(#cond, __FILE__, __LINE__))
+ (((int)(cond))?(void)0:error_assert(#cond, THIS_FILE, __LINE__))
#else
#define HPROF_ASSERT(cond)
#endif
@@ -77,11 +82,11 @@
#define LOG_FORMAT(format) "HPROF LOG: " format " [%s:%d]\n"
#define LOG1(str1) LOG_STDERR((stderr, LOG_FORMAT("%s"), \
- str1, __FILE__, __LINE__ ))
+ str1, THIS_FILE, __LINE__ ))
#define LOG2(str1,str2) LOG_STDERR((stderr, LOG_FORMAT("%s %s"), \
- str1, str2, __FILE__, __LINE__ ))
+ str1, str2, THIS_FILE, __LINE__ ))
#define LOG3(str1,str2,num) LOG_STDERR((stderr, LOG_FORMAT("%s %s 0x%x"), \
- str1, str2, num, __FILE__, __LINE__ ))
+ str1, str2, num, THIS_FILE, __LINE__ ))
#define LOG(str) LOG1(str)
--- a/jdk/src/share/demo/jvmti/hprof/hprof_util.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/demo/jvmti/hprof/hprof_util.h Fri Sep 14 13:52:30 2012 -0700
@@ -41,6 +41,11 @@
#ifndef HPROF_UTIL_H
#define HPROF_UTIL_H
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/* Macros that protect code from accidently using a local ref improperly */
#define WITH_LOCAL_REFS(env, number) \
{ \
@@ -184,8 +189,8 @@
#ifdef DEBUG
void * hprof_debug_malloc(int size, char *file, int line);
void hprof_debug_free(void *ptr, char *file, int line);
- #define HPROF_MALLOC(size) hprof_debug_malloc(size, __FILE__, __LINE__)
- #define HPROF_FREE(ptr) hprof_debug_free(ptr, __FILE__, __LINE__)
+ #define HPROF_MALLOC(size) hprof_debug_malloc(size, THIS_FILE, __LINE__)
+ #define HPROF_FREE(ptr) hprof_debug_free(ptr, THIS_FILE, __LINE__)
#else
#define HPROF_MALLOC(size) hprof_malloc(size)
#define HPROF_FREE(ptr) hprof_free(ptr)
--- a/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c Fri Sep 14 13:52:30 2012 -0700
@@ -70,12 +70,20 @@
/* Macros over error functions to capture line numbers */
-#define CRW_FATAL(ci, message) fatal_error(ci, message, __FILE__, __LINE__)
+/* Fatal error used in all builds. */
+
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE "java_crw.demo.c" /* Never use __FILE__ */
+#endif
+
+#define CRW_FATAL(ci, message) fatal_error(ci, message, THIS_FILE, __LINE__)
#if defined(DEBUG) || !defined(NDEBUG)
+ /* This assert macro is only used in the debug builds. */
#define CRW_ASSERT(ci, cond) \
- ((cond)?(void)0:assert_error(ci, #cond, __FILE__, __LINE__))
+ ((cond)?(void)0:assert_error(ci, #cond, THIS_FILE, __LINE__))
#else
--- a/jdk/src/share/instrument/JPLISAssert.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/instrument/JPLISAssert.h Fri Sep 14 13:52:30 2012 -0700
@@ -49,10 +49,14 @@
#define JPLISASSERT_ENABLEASSERTIONS (0)
#endif
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
#if JPLISASSERT_ENABLEASSERTIONS
-#define jplis_assert(x) JPLISAssertCondition((jboolean)(x), #x, __FILE__, __LINE__)
-#define jplis_assert_msg(x, msg) JPLISAssertConditionWithMessage((jboolean)(x), #x, msg, __FILE__, __LINE__)
+#define jplis_assert(x) JPLISAssertCondition((jboolean)(x), #x, THIS_FILE, __LINE__)
+#define jplis_assert_msg(x, msg) JPLISAssertConditionWithMessage((jboolean)(x), #x, msg, THIS_FILE, __LINE__)
#else
#define jplis_assert(x)
#define jplis_assert_msg(x, msg)
--- a/jdk/src/share/native/sun/awt/debug/debug_assert.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/native/sun/awt/debug/debug_assert.h Fri Sep 14 13:52:30 2012 -0700
@@ -32,17 +32,22 @@
#include "debug_util.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#if defined(DEBUG)
#define DASSERT(_expr) \
if ( !(_expr) ) { \
- DAssert_Impl( #_expr, __FILE__, __LINE__); \
+ DAssert_Impl( #_expr, THIS_FILE, __LINE__); \
} else { \
}
#define DASSERTMSG(_expr, _msg) \
if ( !(_expr) ) { \
- DAssert_Impl( (_msg), __FILE__, __LINE__); \
+ DAssert_Impl( (_msg), THIS_FILE, __LINE__); \
} else { \
}
--- a/jdk/src/share/native/sun/awt/debug/debug_mem.c Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/native/sun/awt/debug/debug_mem.c Fri Sep 14 13:52:30 2012 -0700
@@ -27,6 +27,11 @@
#include "debug_util.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#define DMEM_MIN(a,b) (a) < (b) ? (a) : (b)
#define DMEM_MAX(a,b) (a) > (b) ? (a) : (b)
@@ -291,7 +296,7 @@
DMutex_Enter(DMemMutex);
/* Force memory leaks to be output regardless of trace settings */
- DTrace_EnableFile(__FILE__, TRUE);
+ DTrace_EnableFile(THIS_FILE, TRUE);
DTRACE_PRINTLN("--------------------------");
DTRACE_PRINTLN("Debug Memory Manager Leaks");
DTRACE_PRINTLN("--------------------------");
--- a/jdk/src/share/native/sun/awt/debug/debug_trace.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/native/sun/awt/debug/debug_trace.h Fri Sep 14 13:52:30 2012 -0700
@@ -34,6 +34,11 @@
#include "debug_util.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
typedef int dtrace_id;
enum {
UNDEFINED_TRACE_ID = -1 /* indicates trace point has not been registered yet */
@@ -69,7 +74,7 @@
#define _DTrace_Template(_func, _ac, _f, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) \
{ \
static dtrace_id _dt_lineid_ = UNDEFINED_TRACE_ID; \
- DTrace_PrintFunction((_func), &_Dt_FileTraceId, &_dt_lineid_, __FILE__, __LINE__, (_ac), (_f), (_a1), (_a2), (_a3), (_a4), (_a5), (_a6), (_a7), (_a8) ); \
+ DTrace_PrintFunction((_func), &_Dt_FileTraceId, &_dt_lineid_, THIS_FILE, __LINE__, (_ac), (_f), (_a1), (_a2), (_a3), (_a4), (_a5), (_a6), (_a7), (_a8) ); \
}
/* printf style trace macros */
--- a/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h Fri Sep 14 13:52:30 2012 -0700
@@ -452,7 +452,12 @@
void *p11malloc(size_t c, char *file, int line);
void p11free(void *p, char *file, int line);
-#define malloc(c) (p11malloc((c), __FILE__, __LINE__))
-#define free(c) (p11free((c), __FILE__, __LINE__))
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
+#define malloc(c) (p11malloc((c), THIS_FILE, __LINE__))
+#define free(c) (p11free((c), THIS_FILE, __LINE__))
#endif
--- a/jdk/src/share/npt/utf.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/npt/utf.h Fri Sep 14 13:52:30 2012 -0700
@@ -33,8 +33,13 @@
#include "jni.h"
#include "utf_md.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/* Error and assert macros */
-#define UTF_ERROR(m) utfError(__FILE__, __LINE__, m)
+#define UTF_ERROR(m) utfError(THIS_FILE, __LINE__, m)
#define UTF_ASSERT(x) ( (x)==0 ? UTF_ERROR("ASSERT ERROR " #x) : (void)0 )
void utfError(char *file, int line, char *message);
--- a/jdk/src/share/transport/shmem/shmemBase.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/share/transport/shmem/shmemBase.h Fri Sep 14 13:52:30 2012 -0700
@@ -49,11 +49,16 @@
jint shmemBase_name(SharedMemoryTransport *, char **name);
jint shmemBase_getlasterror(char *msg, jint size);
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#ifdef DEBUG
#define SHMEM_ASSERT(expression) \
do { \
if (!(expression)) { \
- exitTransportWithError("assertion failed", __FILE__, __DATE__, __LINE__); \
+ exitTransportWithError("assertion failed", THIS_FILE, __DATE__, __LINE__); \
} \
} while (0)
#else
@@ -63,7 +68,7 @@
#define SHMEM_GUARANTEE(expression) \
do { \
if (!(expression)) { \
- exitTransportWithError("assertion failed", __FILE__, __DATE__, __LINE__); \
+ exitTransportWithError("assertion failed", THIS_FILE, __DATE__, __LINE__); \
} \
} while (0)
--- a/jdk/src/solaris/bin/jexec.c Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/solaris/bin/jexec.c Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -80,6 +80,7 @@
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
+# include "jni.h"
# include "manifest_info.h"
#endif
--- a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java Fri Sep 14 13:52:30 2012 -0700
@@ -1001,6 +1001,13 @@
switch (xev.get_type()) {
case XConstants.ButtonPress:
if (buttonState == 0) {
+ XWindowPeer parent = getToplevelXWindow();
+ // See 6385277, 6981400.
+ if (parent != null && parent.isFocusableWindow()) {
+ // A click in a client area drops the actual focused window retaining.
+ parent.setActualFocusedWindow(null);
+ parent.requestWindowFocus(xbe.get_time(), true);
+ }
XAwtState.setAutoGrabWindow(this);
}
break;
--- a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java Fri Sep 14 13:52:30 2012 -0700
@@ -588,33 +588,6 @@
}
- public void handleButtonPressRelease(XEvent xev) {
- /*
- * Fix for 6385277.
- * We request focus on simple Window by click in order
- * to make it behave like Frame/Dialog in this case and also to unify
- * the behaviour with what we have on MS Windows.
- * handleJavaMouseEvent() would be more suitable place to do this
- * but we want Swing to have this functionality also.
- */
- if (xev.get_type() == XConstants.ButtonPress) {
- final XWindowPeer parentXWindow = getParentTopLevel();
- Window parentWindow = (Window)parentXWindow.getTarget();
- if (parentXWindow.isFocusableWindow() && parentXWindow.isSimpleWindow() &&
- XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() != parentWindow)
- {
- postEvent(new InvocationEvent(parentWindow, new Runnable() {
- public void run() {
- // Request focus on the EDT of 'parentWindow' because
- // XDecoratedPeer.requestWindowFocus() calls client code.
- parentXWindow.requestXFocus();
- }
- }));
- }
- }
- super.handleButtonPressRelease(xev);
- }
-
public Dimension getMinimumSize() {
return target.getSize();
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Fri Sep 14 13:52:30 2012 -0700
@@ -1108,7 +1108,7 @@
focusLog.fine("Request for decorated window focus");
// If this is Frame or Dialog we can't assure focus request success - but we still can try
// If this is Window and its owner Frame is active we can be sure request succedded.
- Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+ Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
focusLog.finer("Current window is: active={0}, focused={1}",
@@ -1201,7 +1201,7 @@
}
public void handleWindowFocusOut(Window oppositeWindow, long serial) {
- Window actualFocusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+ Window actualFocusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
// If the actual focused window is not this decorated window then retain it.
if (actualFocusedWindow != null && actualFocusedWindow != target) {
--- a/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java Fri Sep 14 13:52:30 2012 -0700
@@ -135,7 +135,7 @@
* Thus we don't have to perform any transitive (a blocker of a blocker) checks.
*/
boolean isFocusedWindowModalBlocker() {
- Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+ Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
XWindowPeer focusedWindowPeer = null;
if (focusedWindow != null) {
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java Fri Sep 14 13:52:30 2012 -0700
@@ -96,11 +96,11 @@
public void handleEvent(AWTEvent e) {
switch (e.getID()) {
case FocusEvent.FOCUS_GAINED:
- XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(proxy);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(proxy);
container.focusGained(handle);
break;
case FocusEvent.FOCUS_LOST:
- XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
container.focusLost(handle);
break;
case KeyEvent.KEY_PRESSED:
@@ -172,7 +172,7 @@
if (lightweightChild == null) {
lightweightChild = (Component)proxy;
}
- Component currentOwner = XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner();
+ Component currentOwner = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
if (currentOwner != null && currentOwner.getPeer() == null) {
currentOwner = null;
}
@@ -224,7 +224,8 @@
if (parent != null) {
Window parentWindow = (Window)parent;
// and check that it is focused
- if (!parentWindow.isFocused() && XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == parentWindow) {
+ if (!parentWindow.isFocused() &&
+ XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == parentWindow) {
// if it is not - skip requesting focus on Solaris
// but return true for compatibility.
return true;
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Fri Sep 14 13:52:30 2012 -0700
@@ -204,7 +204,7 @@
// XEMBED_FOCUS_OUT client messages), so we first need to check if
// embedded is an active window before sending WINDOW_LOST_FOCUS
// to shared code
- if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == embedded.target) {
+ if (XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == embedded.target) {
embedded.handleWindowFocusOut(null, 0);
}
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java Fri Sep 14 13:52:30 2012 -0700
@@ -25,66 +25,48 @@
package sun.awt.X11;
import java.awt.Component;
-import java.awt.KeyboardFocusManager;
import java.awt.Window;
-
-import java.awt.event.FocusEvent;
-
-import java.awt.peer.KeyboardFocusManagerPeer;
-import java.awt.peer.ComponentPeer;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
import sun.util.logging.PlatformLogger;
-
import sun.awt.CausedFocusEvent;
-import sun.awt.SunToolkit;
import sun.awt.KeyboardFocusManagerPeerImpl;
public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XKeyboardFocusManagerPeer");
+ private static final XKeyboardFocusManagerPeer inst = new XKeyboardFocusManagerPeer();
- private static Object lock = new Object() {};
- private static Component currentFocusOwner;
- private static Window currentFocusedWindow;
+ private Component currentFocusOwner;
+ private Window currentFocusedWindow;
- XKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
- super(manager);
+ public static XKeyboardFocusManagerPeer getInstance() {
+ return inst;
+ }
+
+ private XKeyboardFocusManagerPeer() {
}
@Override
public void setCurrentFocusOwner(Component comp) {
- setCurrentNativeFocusOwner(comp);
+ synchronized (this) {
+ currentFocusOwner = comp;
+ }
}
@Override
public Component getCurrentFocusOwner() {
- return getCurrentNativeFocusOwner();
- }
-
- @Override
- public Window getCurrentFocusedWindow() {
- return getCurrentNativeFocusedWindow();
- }
-
- public static void setCurrentNativeFocusOwner(Component comp) {
- synchronized (lock) {
- currentFocusOwner = comp;
- }
- }
-
- public static Component getCurrentNativeFocusOwner() {
- synchronized(lock) {
+ synchronized(this) {
return currentFocusOwner;
}
}
- public static void setCurrentNativeFocusedWindow(Window win) {
- if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer("Setting current native focused window " + win);
+ @Override
+ public void setCurrentFocusedWindow(Window win) {
+ if (focusLog.isLoggable(PlatformLogger.FINER)) {
+ focusLog.finer("Setting current focused window " + win);
+ }
+
XWindowPeer from = null, to = null;
- synchronized(lock) {
+ synchronized(this) {
if (currentFocusedWindow != null) {
from = (XWindowPeer)currentFocusedWindow.getPeer();
}
@@ -104,8 +86,9 @@
}
}
- public static Window getCurrentNativeFocusedWindow() {
- synchronized(lock) {
+ @Override
+ public Window getCurrentFocusedWindow() {
+ synchronized(this) {
return currentFocusedWindow;
}
}
@@ -124,6 +107,6 @@
focusedWindowChangeAllowed,
time,
cause,
- getCurrentNativeFocusOwner());
+ getInstance().getCurrentFocusOwner());
}
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Fri Sep 14 13:52:30 2012 -0700
@@ -663,7 +663,7 @@
long w = 0;
if (windowToXWindow(ev.get_xany().get_window()) != null) {
Component owner =
- XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner();
+ XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
if (owner != null) {
XWindow ownerWindow = (XWindow) AWTAccessor.getComponentAccessor().getPeer(owner);
if (ownerWindow != null) {
@@ -1155,9 +1155,8 @@
return peer;
}
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) throws HeadlessException {
- XKeyboardFocusManagerPeer peer = new XKeyboardFocusManagerPeer(manager);
- return peer;
+ public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() throws HeadlessException {
+ return XKeyboardFocusManagerPeer.getInstance();
}
/**
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Fri Sep 14 13:52:30 2012 -0700
@@ -617,7 +617,7 @@
public void handleWindowFocusIn_Dispatch() {
if (EventQueue.isDispatchThread()) {
- XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
SunToolkit.setSystemGenerated(we);
target.dispatchEvent(we);
@@ -626,7 +626,7 @@
public void handleWindowFocusInSync(long serial) {
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
- XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
sendEvent(we);
}
// NOTE: This method may be called by privileged threads.
@@ -634,7 +634,7 @@
public void handleWindowFocusIn(long serial) {
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
/* wrap in Sequenced, then post*/
- XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
postEvent(wrapInSequenced((AWTEvent) we));
}
@@ -642,15 +642,15 @@
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
public void handleWindowFocusOut(Window oppositeWindow, long serial) {
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
- XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow(null);
- XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
/* wrap in Sequenced, then post*/
postEvent(wrapInSequenced((AWTEvent) we));
}
public void handleWindowFocusOutSync(Window oppositeWindow, long serial) {
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
- XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow(null);
- XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
sendEvent(we);
}
@@ -1138,7 +1138,7 @@
// getWMState() always returns 0 (Withdrawn) for simple windows. Hence
// we ignore the state for such windows.
if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) {
- if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() ==
+ if (XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() ==
getTarget())
{
show = true;
@@ -1165,15 +1165,25 @@
}
public void dispose() {
+ if (isGrabbed()) {
+ if (grabLog.isLoggable(PlatformLogger.FINE)) {
+ grabLog.fine("Generating UngrabEvent on {0} because of the window disposal", this);
+ }
+ postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ }
+
SunToolkit.awtLock();
+
try {
windows.remove(this);
} finally {
SunToolkit.awtUnlock();
}
+
if (warningWindow != null) {
warningWindow.destroy();
}
+
removeRootPropertyEventDispatcher();
mustControlStackPosition = false;
super.dispose();
@@ -1185,12 +1195,13 @@
* receive WM_TAKE_FOCUS.
*/
if (isSimpleWindow()) {
- if (target == XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow()) {
+ if (target == XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow()) {
Window owner = getDecoratedOwner((Window)target);
((XWindowPeer)AWTAccessor.getComponentAccessor().getPeer(owner)).requestWindowFocus();
}
}
}
+
boolean isResizable() {
return winAttr.isResizable;
}
@@ -1825,7 +1836,7 @@
// If this is Frame or Dialog we can't assure focus request success - but we still can try
// If this is Window and its owner Frame is active we can be sure request succedded.
Window ownerWindow = XWindowPeer.getDecoratedOwner((Window)target);
- Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+ Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
if (isWMStateNetHidden()) {
--- a/jdk/src/solaris/instrument/EncodingSupport_md.c Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/solaris/instrument/EncodingSupport_md.c Fri Sep 14 13:52:30 2012 -0700
@@ -33,8 +33,13 @@
/* Routines to convert back and forth between Platform Encoding and UTF-8 */
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/* Error and assert macros */
-#define UTF_ERROR(m) utfError(__FILE__, __LINE__, m)
+#define UTF_ERROR(m) utfError(THIS_FILE, __LINE__, m)
#define UTF_ASSERT(x) ( (x)==0 ? UTF_ERROR("ASSERT ERROR " #x) : (void)0 )
#define UTF_DEBUG(x)
--- a/jdk/src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java Fri Sep 14 13:52:30 2012 -0700
@@ -25,7 +25,6 @@
package sun.awt.windows;
-import java.awt.KeyboardFocusManager;
import java.awt.Window;
import java.awt.Component;
import java.awt.peer.ComponentPeer;
@@ -37,8 +36,13 @@
static native Component getNativeFocusOwner();
static native Window getNativeFocusedWindow();
- WKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
- super(manager);
+ private static final WKeyboardFocusManagerPeer inst = new WKeyboardFocusManagerPeer();
+
+ public static WKeyboardFocusManagerPeer getInstance() {
+ return inst;
+ }
+
+ private WKeyboardFocusManagerPeer() {
}
@Override
@@ -52,6 +56,12 @@
}
@Override
+ public void setCurrentFocusedWindow(Window win) {
+ // Not used on Windows
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
public Window getCurrentFocusedWindow() {
return getNativeFocusedWindow();
}
--- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java Fri Sep 14 13:52:30 2012 -0700
@@ -506,10 +506,10 @@
return true;
}
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
+ public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
throws HeadlessException
{
- return new WKeyboardFocusManagerPeer(manager);
+ return WKeyboardFocusManagerPeer.getInstance();
}
protected native void setDynamicLayoutNative(boolean b);
--- a/jdk/src/windows/native/com/sun/management/OperatingSystem_md.c Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/windows/native/com/sun/management/OperatingSystem_md.c Fri Sep 14 13:52:30 2012 -0700
@@ -100,18 +100,20 @@
Java_com_sun_management_OperatingSystem_getTotalSwapSpaceSize
(JNIEnv *env, jobject mbean)
{
- MEMORYSTATUS ms;
- GlobalMemoryStatus(&ms);
- return (jlong)ms.dwTotalPageFile;
+ MEMORYSTATUSEX ms;
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatusEx(&ms);
+ return (jlong) ms.ullTotalPageFile;
}
JNIEXPORT jlong JNICALL
Java_com_sun_management_OperatingSystem_getFreeSwapSpaceSize
(JNIEnv *env, jobject mbean)
{
- MEMORYSTATUS ms;
- GlobalMemoryStatus(&ms);
- return (jlong)ms.dwAvailPageFile;
+ MEMORYSTATUSEX ms;
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatusEx(&ms);
+ return (jlong) ms.ullAvailPageFile;
}
JNIEXPORT jlong JNICALL
@@ -137,21 +139,20 @@
Java_com_sun_management_OperatingSystem_getFreePhysicalMemorySize
(JNIEnv *env, jobject mbean)
{
- MEMORYSTATUS ms;
- GlobalMemoryStatus(&ms);
- return (jlong) ms.dwAvailPhys;
+ MEMORYSTATUSEX ms;
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatusEx(&ms);
+ return (jlong) ms.ullAvailPhys;
}
JNIEXPORT jlong JNICALL
Java_com_sun_management_OperatingSystem_getTotalPhysicalMemorySize
(JNIEnv *env, jobject mbean)
{
- MEMORYSTATUS ms;
- // also returns dwAvailPhys (free physical memory bytes),
- // dwTotalVirtual, dwAvailVirtual,
- // dwMemoryLoad (% of memory in use)
- GlobalMemoryStatus(&ms);
- return ms.dwTotalPhys;
+ MEMORYSTATUSEX ms;
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatusEx(&ms);
+ return (jlong) ms.ullTotalPhys;
}
// Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer.
--- a/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiIn.cpp Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiIn.cpp Fri Sep 14 13:52:30 2012 -0700
@@ -35,9 +35,15 @@
#ifdef USE_ERROR
#include <stdio.h>
+
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#define MIDIIN_CHECK_ERROR { \
if (err != MMSYSERR_NOERROR) \
- ERROR3("MIDI IN Error in %s:%d : %s\n", __FILE__, __LINE__, MIDI_IN_GetErrorStr((INT32) err)); \
+ ERROR3("MIDI IN Error in %s:%d : %s\n", THIS_FILE, __LINE__, MIDI_IN_GetErrorStr((INT32) err)); \
}
#else
#define MIDIIN_CHECK_ERROR
--- a/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiOut.c Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiOut.c Fri Sep 14 13:52:30 2012 -0700
@@ -33,9 +33,15 @@
#ifdef USE_ERROR
#include <stdio.h>
+
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#define MIDIOUT_CHECK_ERROR { \
if (err != MMSYSERR_NOERROR) \
- ERROR3("MIDI OUT Error in %s:%d : %s\n", __FILE__, __LINE__, MIDI_OUT_GetErrorStr((INT32) err)); \
+ ERROR3("MIDI OUT Error in %s:%d : %s\n", THIS_FILE, __LINE__, MIDI_OUT_GetErrorStr((INT32) err)); \
}
#else
#define MIDIOUT_CHECK_ERROR
--- a/jdk/src/windows/native/sun/java2d/d3d/D3DPipeline.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/windows/native/sun/java2d/d3d/D3DPipeline.h Fri Sep 14 13:52:30 2012 -0700
@@ -28,6 +28,11 @@
#define D3D_DEBUG_INFO
#endif // DEBUG
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE THIS_FILE
+#endif
+
#ifdef D3D_PPL_DLL
@@ -104,7 +109,7 @@
#define ACT_IF_NULL(ACTION, value) \
if ((value) == NULL) { \
J2dTraceLn3(J2D_TRACE_ERROR, \
- "%s is null in %s:%d", #value, __FILE__, __LINE__); \
+ "%s is null in %s:%d", #value, THIS_FILE, __LINE__); \
ACTION; \
} else do { } while (0)
#define RETURN_IF_NULL(value) ACT_IF_NULL(return, value)
@@ -114,12 +119,12 @@
#define RETURN_STATUS_IF_EXP_FAILED(EXPR) \
if (FAILED(res = (EXPR))) { \
- DebugPrintD3DError(res, " " ## #EXPR ## " failed in " ## __FILE__); \
+ DebugPrintD3DError(res, " " ## #EXPR ## " failed in " ## THIS_FILE); \
return res; \
} else do { } while (0)
#define RETURN_STATUS_IF_FAILED(status) \
if (FAILED((status))) { \
- DebugPrintD3DError((status), " failed in " ## __FILE__ ## ", return;");\
+ DebugPrintD3DError((status), " failed in " ## THIS_FILE ## ", return;");\
return (status); \
} else do { } while (0)
--- a/jdk/src/windows/native/sun/windows/alloc.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/windows/native/sun/windows/alloc.h Fri Sep 14 13:52:30 2012 -0700
@@ -26,6 +26,11 @@
#ifndef _ALLOC_H_
#define _ALLOC_H_
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#include "stdhdrs.h"
// By defining std::bad_alloc in a local header file instead of including
@@ -127,12 +132,12 @@
throw (std::bad_alloc);
#define safe_Malloc(size) \
- safe_Malloc_outofmem(size, __FILE__, __LINE__)
+ safe_Malloc_outofmem(size, THIS_FILE, __LINE__)
#define safe_Calloc(num, size) \
- safe_Calloc_outofmem(num, size, __FILE__, __LINE__)
+ safe_Calloc_outofmem(num, size, THIS_FILE, __LINE__)
#define safe_Realloc(memblock, size) \
- safe_Realloc_outofmem(memblock, size, __FILE__, __LINE__)
- #define new new(__FILE__, __LINE__)
+ safe_Realloc_outofmem(memblock, size, THIS_FILE, __LINE__)
+ #define new new(THIS_FILE, __LINE__)
#endif /* OUTOFMEM_TEST */
#define TRY \
--- a/jdk/src/windows/native/sun/windows/awt_Debug.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Debug.h Fri Sep 14 13:52:30 2012 -0700
@@ -65,7 +65,12 @@
#define AWT_DUMP_CLIP_RECTANGLE(_msg, _hwnd) \
_DTrace_Template(DumpClipRectangle, 2, "", (_msg), (_hwnd), 0, 0, 0, 0, 0, 0)
- #define new new(__FILE__, __LINE__)
+ /* Use THIS_FILE when it is available. */
+ #ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+ #endif
+
+ #define new new(THIS_FILE, __LINE__)
#define VERIFY(exp) DASSERT(exp)
#define UNIMPLEMENTED() DASSERT(FALSE)
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h Fri Sep 14 13:52:30 2012 -0700
@@ -132,24 +132,30 @@
// Macros for using CriticalSection objects that help trace
// lock/unlock actions
+
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#define CRITICAL_SECTION_ENTER(cs) { \
J2dTraceLn4(J2D_TRACE_VERBOSE2, \
"CS.Wait: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
- GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
+ GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \
(cs).Enter(); \
J2dTraceLn4(J2D_TRACE_VERBOSE2, \
"CS.Enter: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
- GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
+ GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \
}
#define CRITICAL_SECTION_LEAVE(cs) { \
J2dTraceLn4(J2D_TRACE_VERBOSE2, \
"CS.Leave: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
- GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
+ GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \
(cs).Leave(); \
J2dTraceLn4(J2D_TRACE_VERBOSE2, \
"CS.Left: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
- GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
+ GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \
}
/************************************************************************
--- a/jdk/src/windows/native/sun/windows/awt_Window.cpp Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp Fri Sep 14 13:52:30 2012 -0700
@@ -1477,7 +1477,7 @@
if (wClassEvent == NULL) {
if (env->PushLocalFrame(1) < 0)
return;
- wClassEvent = env->FindClass("java/awt/event/WindowEvent");
+ wClassEvent = env->FindClass("sun/awt/TimedWindowEvent");
if (wClassEvent != NULL) {
wClassEvent = (jclass)env->NewGlobalRef(wClassEvent);
}
@@ -1491,7 +1491,7 @@
if (wEventInitMID == NULL) {
wEventInitMID =
env->GetMethodID(wClassEvent, "<init>",
- "(Ljava/awt/Window;ILjava/awt/Window;II)V");
+ "(Ljava/awt/Window;ILjava/awt/Window;IIJ)V");
DASSERT(wEventInitMID);
if (wEventInitMID == NULL) {
return;
@@ -1532,7 +1532,7 @@
}
}
jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id,
- jOpposite, oldState, newState);
+ jOpposite, oldState, newState, TimeHelper::getMessageTimeUTC());
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(event != NULL);
if (jOpposite != NULL) {
--- a/jdk/src/windows/transport/shmem/shmem_md.c Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/src/windows/transport/shmem/shmem_md.c Fri Sep 14 13:52:30 2012 -0700
@@ -30,6 +30,11 @@
#include "sysShmem.h"
#include "shmemBase.h" /* for exitTransportWithError */
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/*
* These functions are not completely universal. For now, they are used
* exclusively for Jbug's shared memory transport mechanism. They have
@@ -44,7 +49,7 @@
if (!(expression)) { \
exitTransportWithError \
("\"%s\", line %d: assertion failure\n", \
- __FILE__, __DATE__, __LINE__); \
+ THIS_FILE, __DATE__, __LINE__); \
} \
}
#else
--- a/jdk/test/ProblemList.txt Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/ProblemList.txt Fri Sep 14 13:52:30 2012 -0700
@@ -261,6 +261,18 @@
# 7146541
java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java linux-all
+# 7187882
+java/rmi/activation/checkusage/CheckUsage.java generic-all
+
+# 7190106
+java/rmi/reliability/benchmark/runRmiBench.sh generic-all
+
+# 7191877
+java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java generic-all
+
+# 7195095
+sun/rmi/transport/proxy/EagerHttpFallback.java linux-all
+
############################################################################
# jdk_security
--- a/jdk/test/com/sun/corba/cachedSocket/7056731.sh Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/com/sun/corba/cachedSocket/7056731.sh Fri Sep 14 13:52:30 2012 -0700
@@ -115,5 +115,8 @@
exitCode=0
fi
+#jtreg complaining about not being able to clean up; let's sleep
+sleep 2
rm -rf out.$$ client.$$
+sleep 2
exit ${exitCode}
--- a/jdk/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 6330287 6331386
+ * @bug 6330287 6331386 7044060
* @summary verify that DHKeyPairGenerator returns keys of the expected size
* (modulus and exponent)
* -and-
@@ -57,7 +57,8 @@
* Sizes and values for various lengths.
*/
private enum Sizes {
- two56(256), three84(384), five12(512), seven68(768), ten24(1024);
+ two56(256), three84(384), five12(512), seven68(768), ten24(1024),
+ twenty48(2048);
private final int intSize;
private final BigInteger bigIntValue;
@@ -82,7 +83,8 @@
KeyPair kp;
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", "SunJCE");
- // Sun's default uses a default psize of 1024/lsize of 512
+ // Sun's default uses a default psize of 1024 and
+ // lsize of (pSize / 2) but at least 384 bits
kp = kpg.generateKeyPair();
checkKeyPair(kp, Sizes.ten24, Sizes.five12);
@@ -114,6 +116,20 @@
kp = kpg.generateKeyPair();
checkKeyPair(kp, Sizes.seven68, Sizes.three84);
+ // test w/ only pSize
+ kpg.initialize(Sizes.twenty48.getIntSize());
+ kp = kpg.generateKeyPair();
+ checkKeyPair(kp, Sizes.twenty48, Sizes.ten24);
+
+ publicKey = (DHPublicKey)kp.getPublic();
+ p = publicKey.getParams().getP();
+ g = publicKey.getParams().getG();
+
+ // test w/ all values specified
+ kpg.initialize(new DHParameterSpec(p, g, Sizes.five12.getIntSize()));
+ kp = kpg.generateKeyPair();
+ checkKeyPair(kp, Sizes.twenty48, Sizes.five12);
+
System.out.println("OK");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/management/OperatingSystemMXBean/MemoryStatusOverflow.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @bug 6853676
+ * @summary On computers with more than 4 GB of memory,
+ * the GlobalMemoryStatus function can return incorrect information,
+ * reporting a value of -1 to indicate an overflow.
+ *
+ * @run main MemoryStatusOverflow
+ */
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+import java.lang.management.ManagementFactory;
+import com.sun.management.OperatingSystemMXBean;
+
+public class MemoryStatusOverflow {
+ static final long MEMORYSTATUS_OVERFLOW = (1L << 32) - 1; // (DWORD) -1
+
+ public static void main(String... args) throws Exception {
+ OperatingSystemMXBean bean = (OperatingSystemMXBean)
+ ManagementFactory.getOperatingSystemMXBean();
+ List<String> failedGetterNames = new ArrayList<String>();
+ List<String> testedGetterNames = Arrays.asList(
+ "getTotalSwapSpaceSize", "getFreeSwapSpaceSize",
+ "getTotalPhysicalMemorySize", "getFreePhysicalMemorySize");
+ for (String getterName : testedGetterNames) {
+ Method getter = OperatingSystemMXBean.class.getMethod(getterName);
+ long value = (Long) getter.invoke(bean);
+ if (value == MEMORYSTATUS_OVERFLOW) {
+ failedGetterNames.add(getterName);
+ }
+ }
+ if (!failedGetterNames.isEmpty()) {
+ throw new AssertionError(failedGetterNames);
+ }
+ System.out.println("Test passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/6981400/Test1.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * @test
+ * @bug 6981400
+ * @summary Tabbing between textfiled do not work properly when ALT+TAB
+ * @author anton.tarasov
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main Test1
+ */
+
+// This test shows a frame with four focusable components: b0, b1, b2, b3.
+// Then it presses Tab three times. EDT is freezed for a while on the first FOCUS_LOST event.
+// Meantime, the test clicks in a component of another frame and then clicks in the title
+// of the original frame. When EDT awakes and all the queued events get processed,
+// the other frame should ones gain focus and then pass it to the original frame.
+// The b3 component of the orinial frame should finally become a focus owner.
+// The FOCUS_LOST/FOCUS_GAINED events order in the original frame is tracked and should be:
+// b0 -> b1 -> b2 -> b3.
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.swing.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class Test1 {
+ static JFrame f0 = new JFrame("base_frame") { public String getName() {return "base_frame";} };
+ static JButton f0b0 = new JB("b0");
+ static JButton f0b1 = new JB("b1");
+ static JButton f0b2 = new JB("b2");
+ static JButton f0b3 = new JB("b3");
+
+ static JFrame f1 = new JFrame("swing_frame") { public String getName() {return "swing_frame";} };
+ static JButton f1b0 = new JButton("button");
+
+ static Frame f2 = new Frame("awt_frame") { public String getName() {return "awt_frame";} };
+ static Button f2b0 = new Button("button");
+
+ static Robot robot;
+
+ static List<Component> gainedList = new ArrayList<Component>();
+ static List<Component> lostList = new ArrayList<Component>();
+
+ static Component[] refGainedList = new Component[] {f0b1, f0b2, f0b3, f0b3};
+ static Component[] refLostList = new Component[] {f0b0, f0b1, f0b2, f0b3};
+
+ static boolean tracking;
+
+ public static void main(String[] args) {
+ Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+ public void eventDispatched(AWTEvent e) {
+ System.out.println(e);
+ }
+ }, FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_EVENT_MASK);
+
+ try {
+ robot = new Robot();
+ } catch (AWTException ex) {
+ throw new RuntimeException("Error: can't create Robot");
+ }
+
+ f0.add(f0b0);
+ f0.add(f0b1);
+ f0.add(f0b2);
+ f0.add(f0b3);
+ f0.setLayout(new FlowLayout());
+ f0.setBounds(0, 100, 400, 200);
+
+ f1.add(f1b0);
+ f1.setBounds(0, 400, 400, 200);
+
+ f2.add(f2b0);
+ f2.setBounds(0, 400, 400, 200);
+
+ f0b0.addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusLost(FocusEvent e) {
+ try {
+ Thread.sleep(1000);
+ } catch (Exception ex) {}
+ }
+ });
+
+ //
+ // Case 1. Test against swing JFrame.
+ //
+
+ f1.setVisible(true);
+ f0.setVisible(true);
+
+ Util.waitForIdle(robot);
+
+ if (!f0b0.isFocusOwner()) {
+ Util.clickOnComp(f0b0, robot);
+ Util.waitForIdle(robot);
+ if (!f0b0.isFocusOwner()) {
+ throw new RuntimeException("Error: can't focus the component " + f0b0);
+ }
+ }
+
+ System.out.println("\nTest case 1: swing frame\n");
+ test(f1b0);
+
+ //
+ // Case 2. Test against awt Frame.
+ //
+
+ tracking = false;
+ gainedList.clear();
+ lostList.clear();
+
+ f1.dispose();
+ f2.setAutoRequestFocus(false);
+ f2.setVisible(true);
+ Util.waitForIdle(robot);
+
+ Util.clickOnComp(f0b0, robot);
+ Util.waitForIdle(robot);
+ if (!f0b0.isFocusOwner()) {
+ throw new RuntimeException("Error: can't focus the component " + f0b0);
+ }
+
+ System.out.println("\nTest case 2: awt frame\n");
+ test(f2b0);
+
+ System.out.println("\nTest passed.");
+ }
+
+ public static void test(Component compToClick) {
+ tracking = true;
+
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ robot.delay(50);
+
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ robot.delay(50);
+
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+
+ robot.delay(50);
+ Util.clickOnComp(compToClick, robot);
+
+ robot.delay(50);
+ Util.clickOnTitle(f0, robot);
+
+ Util.waitForIdle(robot);
+
+ if (!f0b3.isFocusOwner()) {
+ throw new RuntimeException("Test failed: f0b3 is not a focus owner");
+ }
+
+ if (!"sun.awt.X11.XToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) {
+
+ if (!Arrays.asList(refGainedList).equals(gainedList)) {
+ System.out.println("gained list: " + gainedList);
+ throw new RuntimeException("Test failed: wrong FOCUS_GAINED events order");
+ }
+ if (!Arrays.asList(refLostList).equals(lostList)) {
+ System.out.println("lost list: " + lostList);
+ throw new RuntimeException("Test failed: wrong FOCUS_LOST events order");
+ }
+ }
+ }
+}
+
+class JB extends JButton {
+ String name;
+
+ public JB(String name) {
+ super(name);
+ this.name = name;
+
+ addFocusListener(new FocusListener() {
+ public void focusGained(FocusEvent e) {
+ if (Test1.tracking)
+ Test1.gainedList.add(e.getComponent());
+ }
+
+ public void focusLost(FocusEvent e) {
+ if (Test1.tracking)
+ Test1.lostList.add(e.getComponent());
+ }
+ });
+ }
+
+ public String toString() {
+ return "[" + name + "]";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/6981400/Test2.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * @test
+ * @bug 6981400
+ * @summary Tabbing between textfiled do not work properly when ALT+TAB
+ * @author anton.tarasov
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main Test2
+ */
+
+// A focus request made after a char is typed ahead shouldn't affect the char's target component.
+
+import java.awt.*;
+import java.awt.event.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class Test2 {
+ static Frame f = new Frame("frame");
+ static TextArea t0 = new TextArea(1, 10) { public String toString() { return "[TA-0]";} };
+ static TextArea t1 = new TextArea(1, 10) { public String toString() { return "[TA-1]";} };
+ static TextArea t2 = new TextArea(1, 10) { public String toString() { return "[TA-2]";} };
+
+ static volatile boolean passed = true;
+
+ static Robot robot;
+
+ public static void main(String[] args) {
+ Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+ public void eventDispatched(AWTEvent e) {
+ System.out.println(e);
+ if (e.getID() == KeyEvent.KEY_TYPED) {
+ if (e.getSource() != t1) {
+ passed = false;
+ throw new RuntimeException("Test failed: the key event has wrong source: " + e);
+ }
+ }
+ }
+ }, FocusEvent.FOCUS_EVENT_MASK | KeyEvent.KEY_EVENT_MASK);
+
+ try {
+ robot = new Robot();
+ } catch (AWTException ex) {
+ throw new RuntimeException("Error: can't create Robot");
+ }
+
+ f.add(t0);
+ f.add(t1);
+ f.add(t2);
+
+ f.setLayout(new FlowLayout());
+ f.pack();
+
+ t0.addFocusListener(new FocusAdapter() {
+ public void focusLost(FocusEvent e) {
+ try {
+ Thread.sleep(3000);
+ } catch (Exception ex) {}
+ }
+ });
+
+ // The request shouldn't affect the key event delivery.
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(2000);
+ } catch (Exception ex) {}
+ System.out.println("requesting focus to " + t2);
+ t2.requestFocus();
+ }
+ }).start();
+
+
+ f.setVisible(true);
+ Util.waitForIdle(robot);
+
+ test();
+
+ if (passed) System.out.println("\nTest passed.");
+ }
+
+ static void test() {
+ Util.clickOnComp(t1, robot);
+
+ // The key event should be eventually delivered to t1.
+ robot.delay(50);
+ robot.keyPress(KeyEvent.VK_A);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_A);
+
+ Util.waitForIdle(robot);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/6981400/Test3.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * @test
+ * @bug 6981400
+ * @summary Tabbing between textfiled do not work properly when ALT+TAB
+ * @author anton.tarasov
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main Test3
+ */
+
+// A menu item in a frame should not be auto-selected when switching by Alt+TAB back and forth.
+
+import java.awt.*;
+import javax.swing.*;
+import java.awt.event.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class Test3 {
+ static JFrame f = new JFrame("Frame");
+ static JMenuBar bar = new JMenuBar();
+ static JMenu menu = new JMenu("File");
+ static JMenuItem item = new JMenuItem("Save");
+
+ static JButton b0 = new JButton("b0");
+ static JButton b1 = new JButton("b1");
+
+ static Robot robot;
+
+ public static void main(String[] args) {
+ Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+ public void eventDispatched(AWTEvent e) {
+ System.err.println(e);
+ }
+ }, KeyEvent.KEY_EVENT_MASK);
+
+ try {
+ robot = new Robot();
+ } catch (AWTException ex) {
+ throw new RuntimeException("Error: can't create Robot");
+ }
+
+ try {
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+ } catch (Exception e) {}
+
+ b0.addFocusListener(new FocusAdapter() {
+ public void focusLost(FocusEvent f) {
+ try {
+ Thread.sleep(2000);
+ } catch (Exception e) {}
+ }
+ });
+
+ menu.add(item);
+ bar.add(menu);
+ f.setJMenuBar(bar);
+
+ f.add(b0);
+ f.add(b1);
+
+ f.setLayout(new FlowLayout());
+ f.setSize(400, 100);
+ f.setVisible(true);
+ Util.waitForIdle(robot);
+
+ if (!b0.hasFocus()) {
+ Util.clickOnComp(b0, robot);
+ Util.waitForIdle(robot);
+ if (!b0.hasFocus()) {
+ throw new RuntimeException("Error: can't focus " + b0);
+ }
+ }
+
+ test();
+
+ System.out.println("Test passed.");
+ }
+
+ public static void test() {
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ robot.delay(50);
+
+ robot.keyPress(KeyEvent.VK_ALT);
+ robot.delay(50);
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_ALT);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+
+ robot.delay(500);
+
+ robot.keyPress(KeyEvent.VK_ALT);
+ robot.delay(50);
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_ALT);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+
+ // Control shot.
+ Util.clickOnTitle(f, robot);
+ Util.waitForIdle(robot);
+
+ if (menu.isSelected()) {
+ throw new RuntimeException("Test failed: the menu gets selected");
+ }
+ if (!b1.hasFocus()) {
+ throw new RuntimeException("Test failed: the button is not a focus owner " + b1);
+ }
+ }
+}
+
+
--- a/jdk/test/java/beans/Introspector/6380849/TestBeanInfo.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/java/beans/Introspector/6380849/TestBeanInfo.java Fri Sep 14 13:52:30 2012 -0700
@@ -38,8 +38,7 @@
import java.beans.BeanInfo;
import java.beans.Introspector;
-import java.lang.ref.Reference;
-import java.lang.reflect.Field;
+import java.lang.reflect.Method;
public class TestBeanInfo implements Runnable {
@@ -60,10 +59,9 @@
try {
actual = Introspector.getBeanInfo(type);
type = actual.getClass();
- Field field = type.getDeclaredField("targetBeanInfoRef"); // NON-NLS: field name
- field.setAccessible(true);
- Reference ref = (Reference) field.get(actual);
- actual = (BeanInfo) ref.get();
+ Method method = type.getDeclaredMethod("getTargetBeanInfo"); // NON-NLS: method name
+ method.setAccessible(true);
+ actual = (BeanInfo) method.invoke(actual);
}
catch (Exception exception) {
throw new Error("unexpected error", exception);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Introspector/Test7186794.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7186794
+ * @summary Tests setter in the super class
+ * @author Sergey Malenkov
+ */
+
+import java.util.List;
+
+public class Test7186794 {
+
+ public static void main(String[] args) {
+ if (null == BeanUtils.findPropertyDescriptor(MyBean.class, "value").getWriteMethod()) {
+ throw new Error("The property setter is not found");
+ }
+ }
+
+ public static class BaseBean {
+
+ protected List<String> value;
+
+ public void setValue(List<String> value) {
+ this.value = value;
+ }
+ }
+
+ public static class MyBean extends BaseBean {
+ public List<String> getValue() {
+ return super.value;
+ }
+ }
+}
--- a/jdk/test/java/beans/Introspector/Test7189112.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/java/beans/Introspector/Test7189112.java Fri Sep 14 13:52:30 2012 -0700
@@ -28,17 +28,11 @@
* @author Sergey Malenkov
*/
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-
public class Test7189112 {
- public static void main(String[] args) throws IntrospectionException {
- for (PropertyDescriptor pd : Introspector.getBeanInfo(MyBean.class).getPropertyDescriptors()) {
- if (pd.getName().equals("value") && (null == pd.getWriteMethod())) {
- throw new Error("The property setter is not found");
- }
+ public static void main(String[] args) {
+ if (null == BeanUtils.findPropertyDescriptor(MyBean.class, "value").getWriteMethod()) {
+ throw new Error("The property setter is not found");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Introspector/Test7192955.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7192955
+ * @summary Tests that all properties are bound
+ * @author Sergey Malenkov
+ */
+
+import java.beans.PropertyChangeListener;
+import java.util.List;
+
+public class Test7192955 {
+
+ public static void main(String[] args) {
+ if (!BeanUtils.findPropertyDescriptor(MyBean.class, "test").isBound()) {
+ throw new Error("a simple property is not bound");
+ }
+ if (!BeanUtils.findPropertyDescriptor(MyBean.class, "list").isBound()) {
+ throw new Error("a generic property is not bound");
+ }
+ if (!BeanUtils.findPropertyDescriptor(MyBean.class, "readOnly").isBound()) {
+ throw new Error("a read-only property is not bound");
+ }
+ }
+
+ public static class BaseBean {
+
+ private List<String> list;
+
+ public List<String> getList() {
+ return this.list;
+ }
+
+ public void setList(List<String> list) {
+ this.list = list;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ }
+
+ public List<String> getReadOnly() {
+ return this.list;
+ }
+ }
+
+ public static class MyBean extends BaseBean {
+
+ private String test;
+
+ public String getTest() {
+ return this.test;
+ }
+
+ public void setTest(String test) {
+ this.test = test;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Introspector/Test7195106.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7195106
+ * @summary Tests that explicit BeanInfo is not collected
+ * @author Sergey Malenkov
+ */
+
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.SimpleBeanInfo;
+
+public class Test7195106 {
+
+ public static void main(String[] arg) throws Exception {
+ BeanInfo info = Introspector.getBeanInfo(My.class);
+ if (null == info.getIcon(BeanInfo.ICON_COLOR_16x16)) {
+ throw new Error("Unexpected behavior");
+ }
+ try {
+ int[] array = new int[1024];
+ while (true) {
+ array = new int[array.length << 1];
+ }
+ }
+ catch (OutOfMemoryError error) {
+ System.gc();
+ }
+ if (null == info.getIcon(BeanInfo.ICON_COLOR_16x16)) {
+ throw new Error("Explicit BeanInfo is collected");
+ }
+ }
+
+ public static class My {
+ }
+
+ public static class MyBeanInfo extends SimpleBeanInfo {
+ @Override
+ public Image getIcon(int type) {
+ return new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLEncoder/Test7169395.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7169395
+ * @summary Tests that array list initialized correctly
+ * @author Sergey Malenkov
+ */
+
+import java.beans.ConstructorProperties;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class Test7169395 extends AbstractTest {
+
+ public static void main(String[] args) {
+ new Test7169395().test(true);
+ }
+
+ protected Object getObject() {
+ Container container = new Container();
+ container.add("test-null", null);
+ container.add("test-value", "value");
+ container.add("test-other", "other");
+ return container;
+ }
+
+ public static class Component {
+
+ private final Container container;
+ private final String name;
+ private String value;
+
+ @ConstructorProperties({ "container", "name" })
+ public Component(Container container, String name) {
+ this.container = container;
+ this.name = name;
+ }
+
+ public Container getContainer() {
+ return this.container;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getValue() {
+ return this.value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+
+ public static class Container {
+
+ private final Map<String, Component> map = new TreeMap<String, Component>();
+
+ public Collection<Component> getComponents() {
+ return new ArrayList<Component>(this.map.values());
+ }
+
+ public void setComponents(Collection<Component> components) {
+ this.map.clear();
+ for (Component component : components){
+ this.map.put(component.getName(), component);
+ }
+ }
+
+ public void add(String name, String value) {
+ Component list = new Component(this, name);
+ list.setValue(value);
+ this.map.put(name, list);
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/CopyAndMove.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/java/nio/file/Files/CopyAndMove.java Fri Sep 14 13:52:30 2012 -0700
@@ -86,10 +86,12 @@
assertTrue(attrs1.isSymbolicLink() == attrs2.isSymbolicLink());
assertTrue(attrs1.isOther() == attrs2.isOther());
- // check last modified time
- long time1 = attrs1.lastModifiedTime().toMillis();
- long time2 = attrs2.lastModifiedTime().toMillis();
- assertTrue(time1 == time2);
+ // check last modified time if not a symbolic link
+ if (!attrs1.isSymbolicLink()) {
+ long time1 = attrs1.lastModifiedTime().toMillis();
+ long time2 = attrs2.lastModifiedTime().toMillis();
+ assertTrue(time1 == time2);
+ }
// check size
if (attrs1.isRegularFile())
--- a/jdk/test/sun/security/ec/TestEC.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/sun/security/ec/TestEC.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, 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
@@ -33,6 +33,7 @@
* @run main TestEC
*/
+import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.Security;
@@ -62,7 +63,12 @@
}
public static void main0(String[] args) throws Exception {
- Provider p = new sun.security.ec.SunEC();
+ Provider p = Security.getProvider("SunEC");
+
+ if (p == null) {
+ throw new NoSuchProviderException("Can't get SunEC provider");
+ }
+
System.out.println("Running tests with " + p.getName() +
" provider...\n");
long start = System.currentTimeMillis();
--- a/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java Fri Sep 14 13:52:30 2012 -0700
@@ -63,6 +63,10 @@
System.out.println("Provider does not support ECDSA, skipping...");
return;
}
+
+ /*
+ * PKCS11Test.main will remove this provider if needed
+ */
Providers.setAt(p, 1);
random = new SecureRandom();
@@ -132,7 +136,6 @@
}
}
- Security.removeProvider(p.getName());
System.out.println("OK");
}
--- a/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java Fri Sep 14 13:52:30 2012 -0700
@@ -53,6 +53,10 @@
System.out.println("Provider does not support ECDSA, skipping...");
return;
}
+
+ /*
+ * PKCS11Test.main will remove this provider if needed
+ */
Providers.setAt(p, 1);
CertificateFactory factory = CertificateFactory.getInstance("X.509");
@@ -147,7 +151,6 @@
out.close();
}
- Security.removeProvider(p.getName());
System.out.println("OK");
}
--- a/jdk/test/sun/security/pkcs11/ec/TestECDH.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDH.java Fri Sep 14 13:52:30 2012 -0700
@@ -60,6 +60,10 @@
System.out.println("Provider does not support ECDH, skipping");
return;
}
+
+ /*
+ * PKCS11Test.main will remove this provider if needed
+ */
Providers.setAt(p, 1);
if (false) {
@@ -77,7 +81,6 @@
test(p, pub192a, priv192a, pub192b, priv192b, secret192);
test(p, pub163a, priv163a, pub163b, priv163b, secret163);
- Security.removeProvider(p.getName());
System.out.println("OK");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDH2.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6405536
+ * @summary basic test of ECDSA signatures for P-256 and P-384 from the
+ * example data in "Suite B Implementer's Guide to FIPS 186-3".
+ * @library ..
+ * @library ../../../../java/security/testlibrary
+ * @compile -XDignore.symbol.file TestECDH2.java
+ * @run main TestECDH2
+ */
+
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.spec.*;
+import java.security.interfaces.*;
+import javax.crypto.*;
+
+import sun.security.ec.NamedCurve;
+
+public class TestECDH2 extends PKCS11Test {
+
+ // values of the keys we use for the tests
+
+ // keypair using NIST P-256
+ private final static String privD256 = "70a12c2db16845ed56ff68cfc21a472b3f04d7d6851bf6349f2d7d5b3452b38a";
+ private final static String pubX256 = "8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8";
+ private final static String pubY256 = "d8a12ba61d599235f67d9cb4d58f1783d3ca43e78f0a5abaa624079936c0c3a9";
+
+ // keypair using NIST P-384
+ private final static String privD384 = "c838b85253ef8dc7394fa5808a5183981c7deef5a69ba8f4f2117ffea39cfcd90e95f6cbc854abacab701d50c1f3cf24";
+ private final static String pubX384 = "1fbac8eebd0cbf35640b39efe0808dd774debff20a2a329e91713baf7d7f3c3e81546d883730bee7e48678f857b02ca0";
+ private final static String pubY384 = "eb213103bd68ce343365a8a4c3d4555fa385f5330203bdd76ffad1f3affb95751c132007e1b240353cb0a4cf1693bdf9";
+
+ private KeyFactory kf = null;
+ private KeyPairGenerator kpg = null;
+
+ private static void testKeyAgreement(KeyPair kpA, KeyPair kpB, Provider p)
+ throws Exception {
+ KeyAgreement ka1 = KeyAgreement.getInstance("ECDH", p);
+ ka1.init(kpA.getPrivate());
+ ka1.doPhase(kpB.getPublic(), true);
+ byte[] s1 = ka1.generateSecret();
+
+ KeyAgreement ka2 = KeyAgreement.getInstance("ECDH", p);
+ ka2.init(kpB.getPrivate());
+ ka2.doPhase(kpA.getPublic(), true);
+ byte[] s2 = ka2.generateSecret();
+ if (Arrays.equals(s1, s2) == false) {
+ System.out.println("expected: " + toString(s1));
+ System.out.println("actual: " + toString(s2));
+ throw new Exception("Generated secrets do not match");
+ }
+ }
+
+ private KeyPair genECKeyPair(String curvName, String privD, String pubX,
+ String pubY) throws Exception {
+ ECParameterSpec ecParams = NamedCurve.getECParameterSpec(curvName);
+ ECPrivateKeySpec privKeySpec =
+ new ECPrivateKeySpec(new BigInteger(privD, 16), ecParams);
+ ECPublicKeySpec pubKeySpec =
+ new ECPublicKeySpec(new ECPoint(new BigInteger(pubX, 16),
+ new BigInteger(pubY, 16)),
+ ecParams);
+ PrivateKey privKey = kf.generatePrivate(privKeySpec);
+ PublicKey pubKey = kf.generatePublic(pubKeySpec);
+ return new KeyPair(pubKey, privKey);
+ }
+ private KeyPair genECKeyPair(String curvName) throws Exception {
+ ECGenParameterSpec genParams = new ECGenParameterSpec(curvName);
+ kpg.initialize(genParams, null);
+ return kpg.generateKeyPair();
+ }
+ public static void main(String[] args) throws Exception {
+ main(new TestECDH2());
+ }
+
+ public void main(Provider provider) throws Exception {
+ if (provider.getService("KeyAgreement", "ECDH") == null) {
+ System.out.println("ECDH not supported, skipping");
+ return;
+ }
+
+ kf = KeyFactory.getInstance("EC", provider);
+ kpg = KeyPairGenerator.getInstance("EC", provider);
+
+ System.out.println("Testing against NIST P-256");
+
+ long start = System.currentTimeMillis();
+ KeyPair kp256A = genECKeyPair("secp256r1", privD256, pubX256, pubY256);
+ KeyPair kp256B = genECKeyPair("secp256r1");
+ testKeyAgreement(kp256A, kp256B, provider);
+
+ System.out.println("Testing against NIST P-384");
+ KeyPair kp384A = genECKeyPair("secp384r1", privD384, pubX384, pubY384);
+ KeyPair kp384B = genECKeyPair("secp384r1");
+ testKeyAgreement(kp384A, kp384B, provider);
+
+ long stop = System.currentTimeMillis();
+ System.out.println("All tests passed (" + (stop - start) + " ms).");
+ }
+}
--- a/jdk/test/sun/security/pkcs11/ec/TestECDSA.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDSA.java Fri Sep 14 13:52:30 2012 -0700
@@ -116,6 +116,10 @@
System.out.println("ECDSA not supported, skipping");
return;
}
+
+ /*
+ * PKCS11Test.main will remove this provider if needed
+ */
Providers.setAt(provider, 1);
if (false) {
@@ -137,7 +141,6 @@
test(provider, pub521, priv521, sig521);
test(provider, pub571, priv571, sig571);
- Security.removeProvider(provider.getName());
long stop = System.currentTimeMillis();
System.out.println("All tests passed (" + (stop - start) + " ms).");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6405536
+ * @summary basic test of ECDSA signatures for P-256 and P-384 from the
+ * example data in "Suite B Implementer's Guide to FIPS 186-3".
+ * @library ..
+ * @library ../../../../java/security/testlibrary
+ * @compile -XDignore.symbol.file TestECDSA2.java
+ * @run main TestECDSA2
+ */
+
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.spec.*;
+import java.security.interfaces.*;
+
+import sun.security.ec.NamedCurve;
+
+public class TestECDSA2 extends PKCS11Test {
+
+ // values of the keys we use for the tests
+
+ // keypair using NIST P-256
+ private final static String privD256 = "70a12c2db16845ed56ff68cfc21a472b3f04d7d6851bf6349f2d7d5b3452b38a";
+ private final static String pubX256 = "8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8";
+ private final static String pubY256 = "d8a12ba61d599235f67d9cb4d58f1783d3ca43e78f0a5abaa624079936c0c3a9";
+
+ // keypair using NIST P-384
+ private final static String privD384 = "c838b85253ef8dc7394fa5808a5183981c7deef5a69ba8f4f2117ffea39cfcd90e95f6cbc854abacab701d50c1f3cf24";
+ private final static String pubX384 = "1fbac8eebd0cbf35640b39efe0808dd774debff20a2a329e91713baf7d7f3c3e81546d883730bee7e48678f857b02ca0";
+ private final static String pubY384 = "eb213103bd68ce343365a8a4c3d4555fa385f5330203bdd76ffad1f3affb95751c132007e1b240353cb0a4cf1693bdf9";
+
+ // data to be signed
+ private final static byte[] data = "This is only a test message. It is 48 bytes long".getBytes();
+
+ private KeyFactory kf = null;
+
+ private static void testSignAndVerify(String alg, KeyPair kp, Provider p) throws Exception {
+ Signature s = Signature.getInstance(alg, p);
+ s.initSign(kp.getPrivate());
+ s.update(data);
+ byte[] result = s.sign();
+
+ s.initVerify(kp.getPublic());
+ s.update(data);
+ if (!s.verify(result)) {
+ throw new Exception("Error: Signature verification failed");
+ }
+ System.out.println(p.getName() + ": " + alg + " Passed");
+ }
+
+ private KeyPair genECKeyPair(String curvName, String privD, String pubX, String pubY) throws Exception {
+ ECParameterSpec ecParams = NamedCurve.getECParameterSpec(curvName);
+ ECPrivateKeySpec privKeySpec =
+ new ECPrivateKeySpec(new BigInteger(privD, 16), ecParams);
+ ECPublicKeySpec pubKeySpec =
+ new ECPublicKeySpec(new ECPoint(new BigInteger(pubX, 16), new BigInteger(pubY, 16)),
+ ecParams);
+ PrivateKey privKey = kf.generatePrivate(privKeySpec);
+ PublicKey pubKey = kf.generatePublic(pubKeySpec);
+ return new KeyPair(pubKey, privKey);
+ }
+
+ public static void main(String[] args) throws Exception {
+ main(new TestECDSA2());
+ }
+
+ public void main(Provider provider) throws Exception {
+ boolean testP256 =
+ (provider.getService("Signature", "SHA256withECDSA") != null);
+
+ boolean testP384 =
+ (provider.getService("Signature", "SHA384withECDSA") != null);
+
+ if (!testP256 && !testP384) {
+ System.out.println("ECDSA not supported, skipping");
+ return;
+ }
+
+ kf = KeyFactory.getInstance("EC", provider);
+
+ long start = System.currentTimeMillis();
+ if (testP256) {
+ // can use secp256r1, NIST P-256, X9.62 prime256v1, or 1.2.840.10045.3.1.7
+ KeyPair kp = genECKeyPair("secp256r1", privD256, pubX256, pubY256);
+ testSignAndVerify("SHA256withECDSA", kp, provider);
+ }
+ if (testP384) {
+ // can use secp384r1, NIST P-384, 1.3.132.0.34
+ KeyPair kp = genECKeyPair("secp384r1", privD384, pubX384, pubY384);
+ testSignAndVerify("SHA384withECDSA", kp, provider);
+ }
+ long stop = System.currentTimeMillis();
+ System.out.println("All tests passed (" + (stop - start) + " ms).");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/DSA/TestAlgParameterGenerator.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7044060
+ * @summary verify that DSA parameter generation works
+ * @run main/othervm/timeout=300 TestAlgParameterGenerator
+ */
+import java.security.*;
+import java.security.spec.*;
+import java.security.interfaces.*;
+
+public class TestAlgParameterGenerator {
+
+ private static void checkParamStrength(AlgorithmParameters param,
+ int strength) throws Exception {
+ String algo = param.getAlgorithm();
+ if (!algo.equalsIgnoreCase("DSA")) {
+ throw new Exception("Unexpected type of parameters: " + algo);
+ }
+ DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class);
+ int valueL = spec.getP().bitLength();
+ if (strength != valueL) {
+ System.out.println("Expected " + strength + " but actual " + valueL);
+ throw new Exception("Wrong P strength");
+ }
+ }
+ private static void checkParamStrength(AlgorithmParameters param,
+ DSAGenParameterSpec genParam)
+ throws Exception {
+ String algo = param.getAlgorithm();
+ if (!algo.equalsIgnoreCase("DSA")) {
+ throw new Exception("Unexpected type of parameters: " + algo);
+ }
+ DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class);
+ int valueL = spec.getP().bitLength();
+ int strength = genParam.getPrimePLength();
+ if (strength != valueL) {
+ System.out.println("P: Expected " + strength + " but actual " + valueL);
+ throw new Exception("Wrong P strength");
+ }
+ int valueN = spec.getQ().bitLength();
+ strength = genParam.getSubprimeQLength();
+ if (strength != valueN) {
+ System.out.println("Q: Expected " + strength + " but actual " + valueN);
+ throw new Exception("Wrong Q strength");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ AlgorithmParameterGenerator apg =
+ AlgorithmParameterGenerator.getInstance("DSA", "SUN");
+
+ long start, stop;
+ // make sure no-init still works
+ start = System.currentTimeMillis();
+ AlgorithmParameters param = apg.generateParameters();
+ stop = System.currentTimeMillis();
+ System.out.println("Time: " + (stop - start) + " ms.");
+ checkParamStrength(param, 1024);
+
+ // make sure the old model works
+ int[] strengths = { 512, 768, 1024 };
+ for (int i = 0; i < strengths.length; i++) {
+ int sizeP = strengths[i];
+ System.out.println("Generating " + sizeP + "-bit DSA Parameters");
+ start = System.currentTimeMillis();
+ apg.init(sizeP);
+ param = apg.generateParameters();
+ stop = System.currentTimeMillis();
+ System.out.println("Time: " + (stop - start) + " ms.");
+ checkParamStrength(param, sizeP);
+ }
+
+ // now the newer model
+ DSAGenParameterSpec spec1 = new DSAGenParameterSpec(1024, 160);
+ DSAGenParameterSpec spec2 = new DSAGenParameterSpec(2048, 224);
+ DSAGenParameterSpec spec3 = new DSAGenParameterSpec(2048, 256);
+ //DSAGenParameterSpec spec4 = new DSAGenParameterSpec(3072, 256);
+ DSAGenParameterSpec[] specSet = {
+ spec1, spec2, spec3//, spec4
+ };
+ for (int i = 0; i < specSet.length; i++) {
+ DSAGenParameterSpec genParam = specSet[i];
+ System.out.println("Generating (" + genParam.getPrimePLength() +
+ ", " + genParam.getSubprimeQLength() +
+ ") DSA Parameters");
+ start = System.currentTimeMillis();
+ apg.init(genParam, null);
+ param = apg.generateParameters();
+ stop = System.currentTimeMillis();
+ System.out.println("Time: " + (stop - start) + " ms.");
+ checkParamStrength(param, genParam);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/DSA/TestDSA2.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 7044060
+ * @run main/othervm/timeout=250 TestDSA2
+ * @summary verify that DSA signature works using SHA and SHA-224 and SHA-256 digests.
+ */
+
+
+import java.security.*;
+import java.security.spec.*;
+import java.security.interfaces.*;
+
+public class TestDSA2 {
+
+ // NOTE: need to explictly specify provider since the more
+ // preferred provider SunPKCS11 provider only supports up
+ // 1024 bits.
+ private static final String PROV = "SUN";
+
+ private static final String[] SIG_ALGOS = {
+ "SHA1withDSA", "SHA224withDSA", "SHA256withDSA"
+ };
+
+ private static final int[] KEYSIZES = {
+ 1024, 2048
+ };
+
+ public static void main(String[] args) throws Exception {
+ boolean[] expectedToPass = { true, true, true };
+ test(1024, expectedToPass);
+ boolean[] expectedToPass2 = { false, true, true };
+ test(2048, expectedToPass2);
+ }
+
+ private static void test(int keySize, boolean[] testStatus)
+ throws Exception {
+ byte[] data = "1234567890".getBytes();
+ System.out.println("Test against key size: " + keySize);
+
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", PROV);
+ keyGen.initialize(keySize, new SecureRandom());
+ KeyPair pair = keyGen.generateKeyPair();
+
+ if (testStatus.length != SIG_ALGOS.length) {
+ throw new RuntimeException("TestError: incorrect status array!");
+ }
+ for (int i = 0; i < SIG_ALGOS.length; i++) {
+ Signature dsa = Signature.getInstance(SIG_ALGOS[i], PROV);
+ try {
+ dsa.initSign(pair.getPrivate());
+ dsa.update(data);
+ byte[] sig = dsa.sign();
+ dsa.initVerify(pair.getPublic());
+ dsa.update(data);
+ boolean verifies = dsa.verify(sig);
+ if (verifies == testStatus[i]) {
+ System.out.println(SIG_ALGOS[i] + ": Passed");
+ } else {
+ System.out.println(SIG_ALGOS[i] + ": should " +
+ (testStatus[i]? "pass":"fail"));
+ throw new RuntimeException(SIG_ALGOS[i] + ": Unexpected Test result!");
+
+ }
+ } catch (Exception ex) {
+ if (testStatus[i]) {
+ ex.printStackTrace();
+ throw new RuntimeException(SIG_ALGOS[i] + ": Unexpected exception " + ex);
+ } else {
+ System.out.println(SIG_ALGOS[i] + ": Passed, expected " + ex);
+ }
+ }
+ }
+ }
+}
--- a/jdk/test/sun/security/provider/DSA/TestKeyPairGenerator.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/sun/security/provider/DSA/TestKeyPairGenerator.java Fri Sep 14 13:52:30 2012 -0700
@@ -24,7 +24,7 @@
/*
* @test
* @bug 4800108
- * @summary verify that precomputed DSA parameters are always used (512, 768, 1024 bit)
+ * @summary verify that precomputed DSA parameters are always used (512, 768, 1024, 2048 bit)
* @run main/othervm/timeout=15 TestKeyPairGenerator
*/
@@ -78,6 +78,10 @@
kp = kpg.generateKeyPair();
checkKeyLength(kp, 512);
+ kpg.initialize(2048);
+ kp = kpg.generateKeyPair();
+ checkKeyLength(kp, 2048);
+
long stop = System.currentTimeMillis();
System.out.println("Time: " + (stop - start) + " ms.");
}
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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,10 +27,9 @@
* @library ../../../httpstest/
* @build HttpCallback HttpServer ClosedChannelList HttpTransaction TunnelProxy
* @summary Redirect problem with HttpsURLConnection using a proxy
- * @run main/othervm B6216082
- *
* SunJSSE does not support dynamic system properties, no way to re-use
* system properties in samevm/agentvm mode.
+ * @run main/othervm B6216082
*/
import java.io.*;
@@ -54,7 +53,9 @@
try {
// XXX workaround for CNFE
Class.forName("java.nio.channels.ClosedByInterruptException");
- setupEnv();
+ if (!setupEnv()) {
+ return;
+ }
startHttpServer();
@@ -69,6 +70,12 @@
throw new RuntimeException("Test failed : bad http request");
}
} finally {
+ if (proxy != null) {
+ proxy.terminate();
+ }
+ if (server != null) {
+ server.terminate();
+ }
HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
}
}
@@ -80,18 +87,13 @@
static String keyStoreFile = "keystore";
static String trustStoreFile = "truststore";
static String passwd = "passphrase";
- public static void setupEnv() {
- try {
- firstNonLoAddress = getNonLoAddress();
-
- if (firstNonLoAddress == null) {
- System.out.println("The test needs at least one non-loopback address to run. Quit now.");
- System.exit(0);
- }
- System.out.println(firstNonLoAddress.getHostAddress());
- } catch (Exception e) {
- e.printStackTrace();
+ public static boolean setupEnv() throws Exception {
+ firstNonLoAddress = getNonLoAddress();
+ if (firstNonLoAddress == null) {
+ System.err.println("The test needs at least one non-loopback address to run. Quit now.");
+ return false;
}
+ System.out.println(firstNonLoAddress.getHostAddress());
// will use proxy
System.setProperty( "https.proxyHost", firstNonLoAddress.getHostAddress());
@@ -106,6 +108,7 @@
System.setProperty("javax.net.ssl.trustStore", trustFilename);
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+ return true;
}
public static InetAddress getNonLoAddress() throws Exception {
@@ -126,33 +129,22 @@
return null;
}
- public static void startHttpServer() {
- try {
- // Both the https server and the proxy let the
- // system pick up an ephemeral port.
- httpTrans = new SimpleHttpTransaction();
- server = new HttpServer(httpTrans, 1, 10, 0);
- proxy = new TunnelProxy(1, 10, 0);
- } catch (IOException e) {
- e.printStackTrace();
- }
+ public static void startHttpServer() throws IOException {
+ // Both the https server and the proxy let the
+ // system pick up an ephemeral port.
+ httpTrans = new SimpleHttpTransaction();
+ server = new HttpServer(httpTrans, 1, 10, 0);
+ proxy = new TunnelProxy(1, 10, 0);
}
- public static void makeHttpCall() {
- try {
- System.out.println("https server listen on: " + server.getLocalPort());
- System.out.println("https proxy listen on: " + proxy.getLocalPort());
- URL url = new URL("https" , firstNonLoAddress.getHostAddress(),
- server.getLocalPort(), "/");
- HttpURLConnection uc = (HttpURLConnection)url.openConnection();
- System.out.println(uc.getResponseCode());
- uc.disconnect();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- proxy.terminate();
- server.terminate();
- }
+ public static void makeHttpCall() throws Exception {
+ System.out.println("https server listen on: " + server.getLocalPort());
+ System.out.println("https proxy listen on: " + proxy.getLocalPort());
+ URL url = new URL("https" , firstNonLoAddress.getHostAddress(),
+ server.getLocalPort(), "/");
+ HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+ System.out.println(uc.getResponseCode());
+ uc.disconnect();
}
static class NameVerifier implements HostnameVerifier {
@@ -189,7 +181,7 @@
}
}
} catch (Exception e) {
- e.printStackTrace();
+ throw new RuntimeException(e);
}
}
}
--- a/jdk/test/sun/tools/jstatd/jpsOutput1.awk Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/sun/tools/jstatd/jpsOutput1.awk Fri Sep 14 13:52:30 2012 -0700
@@ -7,7 +7,7 @@
matched++;
}
-/^[0-9]+ -- process information unavailable$/ {
+/^[0-9]+ -- .*$/ {
matched++;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/BigJar.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7194005
+ * @summary launcher handling of zip64 archives (Scenario A and B)
+ * @compile -XDignore.symbol.file BigJar.java
+ * @run main/timeout=600 BigJar
+ */
+/*
+ * This test consists of two scenarios:
+ *
+ * Scenario A: create a jar with entries exceeding 64K, add a main class and
+ * see if the launcher can handle it.
+ *
+ * Scenario A1: create a jar as in A, but add a zipfile comment as well.
+ *
+ * Scenario B: create a jar with a large enough file exceeding 4GB, and
+ * similarly test the launcher. This test can be run optionally by using the
+ * following jtreg option:
+ * "-javaoptions:-DBigJar_testScenarioB=true"
+ * or set
+ * "BigJar_testScenarioB" environment variable.
+ *
+ * Note this test will only run iff all the disk requirements are met at runtime.
+ */
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.CRC32;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public class BigJar extends TestHelper {
+
+ private static final long GIGA = 1024 * 1024 * 1024;
+ private static final int BUFFER_LEN = Short.MAX_VALUE * 2;
+
+ long getCount(long minlength) {
+ return (minlength / BUFFER_LEN) + 1;
+ }
+
+ long computeCRC(long minlength) {
+ CRC32 crc = new CRC32();
+ byte[] buffer = new byte[BUFFER_LEN];
+ long count = getCount(minlength);
+ for (long i = 0; i < count; i++) {
+ crc.update(buffer);
+ }
+ return crc.getValue();
+ }
+
+ long computeCRC(File inFile) throws IOException {
+ byte[] buffer = new byte[8192];
+ CRC32 crc = new CRC32();
+ try (FileInputStream fis = new FileInputStream(inFile);
+ BufferedInputStream bis = new BufferedInputStream(fis)) {
+ int n = bis.read(buffer);
+ while (n > 0) {
+ crc.update(buffer, 0, n);
+ n = bis.read(buffer);
+ }
+ }
+ return crc.getValue();
+ }
+
+ void createLargeFile(OutputStream os, long minlength) throws IOException {
+ byte[] buffer = new byte[BUFFER_LEN];
+ long count = getCount(minlength);
+ for (long i = 0; i < count; i++) {
+ os.write(buffer);
+ }
+ os.flush();
+ }
+
+ Manifest createMainClass(File javaFile) throws IOException {
+ javaFile.delete();
+ List<String> content = new ArrayList<>();
+ content.add("public class " + baseName(javaFile) + "{");
+ content.add("public static void main(String... args) {");
+ content.add("System.out.println(\"Hello World\\n\");");
+ content.add("System.exit(0);");
+ content.add("}");
+ content.add("}");
+ createFile(javaFile, content);
+ compile(javaFile.getName());
+ Manifest manifest = new Manifest();
+ manifest.clear();
+ manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
+ manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, baseName(javaFile));
+ System.out.println(manifest.getMainAttributes().keySet());
+ System.out.println(manifest.getMainAttributes().values());
+ return manifest;
+ }
+
+ void createJarWithLargeFile(File jarFile, long minlength) throws IOException {
+ File javaFile = new File("Foo.java");
+ Manifest manifest = createMainClass(javaFile);
+ File classFile = getClassFile(javaFile);
+ try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile), manifest);
+ BufferedOutputStream bos = new BufferedOutputStream(jos);
+ FileInputStream fis = new FileInputStream(classFile);) {
+ jos.setLevel(ZipOutputStream.STORED);
+ jos.setMethod(0);
+
+ JarEntry je = new JarEntry("large.data");
+ je.setCompressedSize(getCount(minlength) * BUFFER_LEN);
+ je.setSize(getCount(minlength) * BUFFER_LEN);
+ je.setCrc(computeCRC(minlength));
+ je.setMethod(ZipEntry.STORED);
+ jos.putNextEntry(je);
+ createLargeFile(bos, minlength);
+
+ je = new JarEntry(classFile.getName());
+ je.setCompressedSize(classFile.length());
+ je.setSize(classFile.length());
+ je.setCrc(computeCRC(classFile));
+ je.setMethod(ZipEntry.STORED);
+ jos.putNextEntry(je);
+ copyStream(fis, bos);
+ bos.flush();
+ jos.closeEntry();
+ }
+ }
+
+ void createLargeJar(File jarFile, String comment) throws IOException {
+ final int MAX = Short.MAX_VALUE * 2 + 10;
+ JarEntry je = null;
+ File javaFile = new File("Foo.java");
+ File classFile = getClassFile(javaFile);
+ Manifest manifest = createMainClass(javaFile);
+ try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile), manifest);
+ FileInputStream fis = new FileInputStream(classFile)) {
+ jos.setLevel(JarOutputStream.STORED);
+ jos.setMethod(JarOutputStream.STORED);
+ for (int i = 0; i < MAX; i++) {
+ je = new JarEntry("X" + i + ".txt");
+ je.setSize(0);
+ je.setCompressedSize(0);
+ je.setCrc(0);
+ jos.putNextEntry(je);
+ }
+
+ // add a class file
+ je = new JarEntry(classFile.getName());
+ je.setCompressedSize(classFile.length());
+ je.setSize(classFile.length());
+ je.setCrc(computeCRC(classFile));
+ jos.putNextEntry(je);
+ copyStream(fis, jos);
+ jos.closeEntry();
+ if (comment != null) {
+ jos.setComment(comment);
+ }
+ }
+ }
+
+ void testTheJar(File theJar) throws Exception {
+ try {
+ TestResult tr = doExec(javaCmd, "-jar", theJar.getName());
+ tr.checkPositive();
+ if (!tr.testStatus) {
+ System.out.println(tr);
+ throw new Exception("Failed");
+ }
+ } finally {
+ theJar.delete();
+ }
+ }
+
+ // a jar with entries exceeding 64k + a class file for the existential test
+ @Test
+ void testScenarioA() throws Exception {
+ File largeJar = new File("large.jar");
+ createLargeJar(largeJar, null);
+ testTheJar(largeJar);
+ }
+
+ // a jar with entries exceeding 64k and zip comment
+ @Test
+ void testScenarioA1() throws Exception {
+ File largeJar = new File("largewithcomment.jar");
+ createLargeJar(largeJar, "A really large jar with a comment");
+ testTheJar(largeJar);
+ }
+
+ // a jar with an enormous file + a class file for the existential test
+ @Test
+ void testScenarioB() throws Exception {
+ final String testString = "BigJar_testScenarioB";
+ if (Boolean.getBoolean(testString) == false &&
+ System.getenv(testString) == null) {
+ System.out.println("Warning: testScenarioB passes vacuously");
+ return;
+ }
+ final File largeJar = new File("huge.jar");
+
+ final Path path = largeJar.getAbsoluteFile().getParentFile().toPath();
+ final long available = Files.getFileStore(path).getUsableSpace();
+ final long MAX_VALUE = 0xFFFF_FFFFL;
+
+ final long absolute = MAX_VALUE + 1L;
+ final long required = (long) (absolute * 1.1); // pad for sundries
+ System.out.println("\tavailable: " + available / GIGA + " GB");
+ System.out.println("\trequired: " + required / GIGA + " GB");
+
+ if (available > required) {
+ createJarWithLargeFile(largeJar, absolute);
+ testTheJar(largeJar);
+ } else {
+ System.out.println("Warning: testScenarioB passes vacuously,"
+ + " requirements exceeds available space");
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+ BigJar bj = new BigJar();
+ bj.run(args);
+ if (testExitValue > 0) {
+ System.out.println("Total of " + testExitValue + " failed");
+ System.exit(1);
+ } else {
+ System.out.println("All tests pass");
+ }
+ }
+}
--- a/jdk/test/tools/launcher/TestHelper.java Tue Sep 11 13:32:48 2012 +0400
+++ b/jdk/test/tools/launcher/TestHelper.java Fri Sep 14 13:52:30 2012 -0700
@@ -21,6 +21,8 @@
* questions.
*/
+import java.io.OutputStream;
+import java.io.InputStream;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -243,6 +245,21 @@
return null;
}
+ static File getClassFile(File javaFile) {
+ String s = javaFile.getAbsolutePath().replace(JAVA_FILE_EXT, CLASS_FILE_EXT);
+ return new File(s);
+ }
+
+ static File getJavaFile(File classFile) {
+ String s = classFile.getAbsolutePath().replace(CLASS_FILE_EXT, JAVA_FILE_EXT);
+ return new File(s);
+ }
+
+ static String baseName(File f) {
+ String s = f.getName();
+ return s.substring(0, s.indexOf("."));
+ }
+
/*
* A convenience method to create a jar with jar file name and defs
*/
@@ -324,6 +341,15 @@
}
}
+ static void copyStream(InputStream in, OutputStream out) throws IOException {
+ byte[] buf = new byte[8192];
+ int n = in.read(buf);
+ while (n > 0) {
+ out.write(buf, 0, n);
+ n = in.read(buf);
+ }
+ }
+
static void copyFile(File src, File dst) throws IOException {
Path parent = dst.toPath().getParent();
if (parent != null) {
--- a/langtools/.hgtags Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/.hgtags Fri Sep 14 13:52:30 2012 -0700
@@ -176,3 +176,4 @@
1d2db0e5eabc2eaf865986f7b7ffbf7b14b00232 jdk8-b52
d3d0b9cd76e04bf9e381b402630ac3cfe464bb38 jdk8-b53
9cf72631baf5cb1ebd8736c5efeab7746977ea68 jdk8-b54
+e48e7e1f026b82d921433150180799898c088890 jdk8-b55
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.code;
+
+import java.util.Map;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.comp.Annotate;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Pair;
+
+import static com.sun.tools.javac.code.Kinds.PCK;
+import com.sun.tools.javac.util.*;
+
+/**
+ * Container for all annotations (attributes in javac) on a Symbol.
+ *
+ * This class is explicitly mutable. Its contents will change when attributes
+ * are annotated onto the Symbol. However this class depends on the facts that
+ * List (in javac) is immutable.
+ *
+ * An instance of this class can be in one of three states:
+ *
+ * NOT_STARTED indicates that the Symbol this instance belongs to have not been
+ * annotated (yet). Specifically if the declaration is not annotated this
+ * instance will never move past NOT_STARTED. You can never go back to
+ * NOT_STARTED.
+ *
+ * IN_PROGRESS annotations have been found on the declaration. Will be processed
+ * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list
+ * of attributes (and this moves out of the IN_PROGRESS state).
+ *
+ * "unnamed" this Annotations contains some attributes, possibly the final set.
+ * While in this state you can only prepend or append to the attributes not set
+ * it directly. You can also move back to the IN_PROGRESS sate using reset().
+ *
+ * <p><b>This is NOT part of any supported API. If you write code that depends
+ * on this, you do so at your own risk. This code and its internal interfaces
+ * are subject to change or deletion without notice.</b>
+ */
+public class Annotations {
+
+ private static final List<Attribute.Compound> NOT_STARTED = List.of(null);
+ private static final List<Attribute.Compound> IN_PROGRESS = List.of(null);
+ /*
+ * This field should never be null
+ */
+ private List<Attribute.Compound> attributes = NOT_STARTED;
+ /*
+ * The Symbol this Annotatios belong to
+ */
+ private final Symbol s;
+
+ public Annotations(Symbol s) {
+ this.s = s;
+ }
+
+ public List<Attribute.Compound> getAttributes() {
+ return filterSentinels(attributes);
+ }
+
+ public void setAttributes(List<Attribute.Compound> a) {
+ Assert.check(pendingCompletion() || !isStarted());
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ attributes = a;
+ }
+
+ public void setAttributes(Annotations other) {
+ if (other == null) {
+ throw new NullPointerException();
+ }
+ setAttributes(other.getAttributes());
+ }
+
+ public void setAttributesWithCompletion(final Annotate.AnnotateRepeatedContext ctx) {
+ Assert.check(pendingCompletion() || (!isStarted() && s.kind == PCK));
+
+ Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated = ctx.annotated;
+ boolean atLeastOneRepeated = false;
+ List<Attribute.Compound> buf = List.<Attribute.Compound>nil();
+ for (ListBuffer<Attribute.Compound> lb : annotated.values()) {
+ if (lb.size() == 1) {
+ buf = buf.prepend(lb.first());
+ } else { // repeated
+ buf = buf.prepend(new Placeholder(lb.toList(), s));
+ atLeastOneRepeated = true;
+ }
+ }
+
+ // Add non-repeating attributes
+ setAttributes(buf.reverse());
+
+ if (atLeastOneRepeated) {
+ // The Symbol s is now annotated with a combination of
+ // finished non-repeating annotations and placeholders for
+ // repeating annotations.
+ //
+ // We need to do this in two passes because when creating
+ // a container for a repeating annotation we must
+ // guarantee that the @ContainedBy on the
+ // contained annotation is fully annotated
+ //
+ // The way we force this order is to do all repeating
+ // annotations in a pass after all non-repeating are
+ // finished. This will work because @ContainedBy
+ // is non-repeating and therefore will be annotated in the
+ // fist pass.
+
+ // Queue a pass that will replace Attribute.Placeholders
+ // with Attribute.Compound (made from synthesized containers).
+ ctx.annotateRepeated(new Annotate.Annotator() {
+
+ @Override
+ public String toString() {
+ return "repeated annotation pass of: " + s + " in: " + s.owner;
+ }
+
+ @Override
+ public void enterAnnotation() {
+ complete(ctx);
+ }
+ });
+ }
+ }
+
+ public Annotations reset() {
+ attributes = IN_PROGRESS;
+ return this;
+ }
+
+ public boolean isEmpty() {
+ return !isStarted()
+ || pendingCompletion()
+ || attributes.isEmpty();
+ }
+
+ public boolean pendingCompletion() {
+ return attributes == IN_PROGRESS;
+ }
+
+ public Annotations append(List<Attribute.Compound> l) {
+ attributes = filterSentinels(attributes);
+
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (attributes.isEmpty()) {
+ attributes = l;
+ } else {
+ attributes = attributes.appendList(l);
+ }
+ return this;
+ }
+
+ public Annotations prepend(List<Attribute.Compound> l) {
+ attributes = filterSentinels(attributes);
+
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (attributes.isEmpty()) {
+ attributes = l;
+ } else {
+ attributes = attributes.prependList(l);
+ }
+ return this;
+ }
+
+ private List<Attribute.Compound> filterSentinels(List<Attribute.Compound> a) {
+ return (a == IN_PROGRESS || a == NOT_STARTED)
+ ? List.<Attribute.Compound>nil()
+ : a;
+ }
+
+ private boolean isStarted() {
+ return attributes != NOT_STARTED;
+ }
+
+ private List<Attribute.Compound> getPlaceholders() {
+ List<Attribute.Compound> res = List.<Attribute.Compound>nil();
+ for (Attribute.Compound a : filterSentinels(attributes)) {
+ if (a instanceof Placeholder) {
+ res = res.prepend(a);
+ }
+ }
+ return res.reverse();
+ }
+
+ /*
+ * Replace Placeholders for repeating annotations with their containers
+ */
+ private void complete(Annotate.AnnotateRepeatedContext ctx) {
+ Assert.check(!pendingCompletion());
+ Log log = ctx.log;
+ Env<AttrContext> env = ctx.env;
+ JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
+ try {
+
+ if (isEmpty()) {
+ return;
+ }
+
+ List<Attribute.Compound> result = List.nil();
+ for (Attribute.Compound a : getAttributes()) {
+ if (a instanceof Placeholder) {
+ Attribute.Compound replacement = replaceOne((Placeholder) a, ctx);
+
+ if (null != replacement) {
+ result = result.prepend(replacement);
+ }
+ } else {
+ result = result.prepend(a);
+ }
+ }
+
+ attributes = result.reverse();
+
+ Assert.check(Annotations.this.getPlaceholders().isEmpty());
+ } finally {
+ log.useSource(oldSource);
+ }
+ }
+
+ private Attribute.Compound replaceOne(Placeholder placeholder, Annotate.AnnotateRepeatedContext ctx) {
+ Log log = ctx.log;
+
+ // Process repeated annotations
+ Attribute.Compound validRepeated =
+ ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor());
+
+ if (validRepeated != null) {
+ // Check that the container isn't manually
+ // present along with repeated instances of
+ // its contained annotation.
+ ListBuffer<Attribute.Compound> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
+ if (manualContainer != null) {
+ log.error(ctx.pos.get(manualContainer.first()), "invalid.containedby.annotation.repeated.and.container.present",
+ manualContainer.first().type.tsym);
+ }
+ }
+
+ // A null return will delete the Placeholder
+ return validRepeated;
+
+ }
+
+ private static class Placeholder extends Attribute.Compound {
+
+ private List<Attribute.Compound> placeholderFor;
+ private Symbol on;
+
+ public Placeholder(List<Attribute.Compound> placeholderFor, Symbol on) {
+ super(Type.noType, List.<Pair<Symbol.MethodSymbol, Attribute>>nil());
+ this.placeholderFor = placeholderFor;
+ this.on = on;
+ }
+
+ @Override
+ public String toString() {
+ return "<placeholder: " + placeholderFor + " on: " + on + ">";
+ }
+
+ public List<Attribute.Compound> getPlaceholderFor() {
+ return placeholderFor;
+ }
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -103,11 +103,11 @@
* represented as a ClassSymbol.
*/
public static class Class extends Attribute {
- public final Type type;
+ public final Type classType;
public void accept(Visitor v) { v.visitClass(this); }
public Class(Types types, Type type) {
super(makeClassType(types, type));
- this.type = type;
+ this.classType = type;
}
static Type makeClassType(Types types, Type type) {
Type arg = type.isPrimitive()
@@ -118,13 +118,13 @@
types.syms.classType.tsym);
}
public String toString() {
- return type + ".class";
+ return classType + ".class";
}
public Type getValue() {
- return type;
+ return classType;
}
public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
- return v.visitType(type, p);
+ return v.visitType(classType, p);
}
}
@@ -212,6 +212,12 @@
super(type);
this.values = values;
}
+
+ public Array(Type type, List<Attribute> values) {
+ super(type);
+ this.values = values.toArray(new Attribute[values.size()]);
+ }
+
public void accept(Visitor v) { v.visitArray(this); }
public String toString() {
StringBuilder buf = new StringBuilder();
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -70,16 +70,16 @@
* Returns the result of combining the values in this object with
* the given annotations.
*/
- public Lint augment(List<Attribute.Compound> attrs) {
- return augmentor.augment(this, attrs);
+ public Lint augment(Annotations annots) {
+ return augmentor.augment(this, annots.getAttributes());
}
/**
* Returns the result of combining the values in this object with
* the given annotations and flags.
*/
- public Lint augment(List<Attribute.Compound> attrs, long flags) {
- Lint l = augmentor.augment(this, attrs);
+ public Lint augment(Annotations annots, long flags) {
+ Lint l = augmentor.augment(this, annots.getAttributes());
if ((flags & DEPRECATED) != 0) {
if (l == this)
l = new Lint(this);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Fri Sep 14 13:52:30 2012 -0700
@@ -203,6 +203,9 @@
public boolean allowEffectivelyFinalInInnerClasses() {
return compareTo(JDK1_8) >= 0;
}
+ public boolean allowRepeatedAnnotations() {
+ return compareTo(JDK1_8) >= 0;
+ }
public static SourceVersion toSourceVersion(Source source) {
switch(source) {
case JDK1_2:
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Sep 14 13:52:30 2012 -0700
@@ -72,22 +72,24 @@
*/
public long flags() { return flags_field; }
- /** The attributes of this symbol.
+ /** The attributes of this symbol are contained in this
+ * Annotations. The Annotations instance is NOT immutable.
*/
- public List<Attribute.Compound> attributes_field;
+ public final Annotations annotations = new Annotations(this);
/** An accessor method for the attributes of this symbol.
* Attributes of class symbols should be accessed through the accessor
* method to make sure that the class symbol is loaded.
*/
public List<Attribute.Compound> getAnnotationMirrors() {
- return Assert.checkNonNull(attributes_field);
+ return Assert.checkNonNull(annotations.getAttributes());
}
/** Fetch a particular annotation from a symbol. */
public Attribute.Compound attribute(Symbol anno) {
- for (Attribute.Compound a : getAnnotationMirrors())
+ for (Attribute.Compound a : getAnnotationMirrors()) {
if (a.type.tsym == anno) return a;
+ }
return null;
}
@@ -120,7 +122,6 @@
this.owner = owner;
this.completer = null;
this.erasure_field = null;
- this.attributes_field = List.nil();
this.name = name;
}
@@ -657,10 +658,11 @@
if (completer != null) complete();
if (package_info != null && package_info.completer != null) {
package_info.complete();
- if (attributes_field.isEmpty())
- attributes_field = package_info.attributes_field;
+ if (annotations.isEmpty()) {
+ annotations.setAttributes(package_info.annotations);
}
- return Assert.checkNonNull(attributes_field);
+ }
+ return Assert.checkNonNull(annotations.getAttributes());
}
/** A package "exists" if a type or package that exists has
@@ -762,7 +764,7 @@
public List<Attribute.Compound> getAnnotationMirrors() {
if (completer != null) complete();
- return Assert.checkNonNull(attributes_field);
+ return Assert.checkNonNull(annotations.getAttributes());
}
public Type erasure(Types types) {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Fri Sep 14 13:52:30 2012 -0700
@@ -156,6 +156,10 @@
public final Type systemType;
public final Type autoCloseableType;
public final Type trustMeType;
+ public final Type containedByType;
+ public final Type containerForType;
+ public final Type documentedType;
+ public final Type elementTypeType;
/** The symbol representing the length field of an array.
*/
@@ -468,6 +472,10 @@
deprecatedType = enterClass("java.lang.Deprecated");
suppressWarningsType = enterClass("java.lang.SuppressWarnings");
inheritedType = enterClass("java.lang.annotation.Inherited");
+ containedByType = enterClass("java.lang.annotation.ContainedBy");
+ containerForType = enterClass("java.lang.annotation.ContainerFor");
+ documentedType = enterClass("java.lang.annotation.Documented");
+ elementTypeType = enterClass("java.lang.annotation.ElementType");
systemType = enterClass("java.lang.System");
autoCloseableType = enterClass("java.lang.AutoCloseable");
autoCloseableClose = new MethodSymbol(PUBLIC,
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Sep 14 13:52:30 2012 -0700
@@ -1358,6 +1358,20 @@
}
return result;
}
+
+ /**
+ * Returns an ArrayType with the component type t
+ *
+ * @param t The component type of the ArrayType
+ * @return the ArrayType for the given component
+ */
+ public ArrayType makeArrayType(Type t) {
+ if (t.tag == VOID ||
+ t.tag >= PACKAGE) {
+ Assert.error("Type t must not be a a VOID or PACKAGE type, " + t.toString());
+ }
+ return new ArrayType(t, syms.arrayClass);
+ }
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="asSuper">
@@ -3811,8 +3825,12 @@
// <editor-fold defaultstate="collapsed" desc="Annotation support">
public RetentionPolicy getRetention(Attribute.Compound a) {
+ return getRetention(a.type.tsym);
+ }
+
+ public RetentionPolicy getRetention(Symbol sym) {
RetentionPolicy vis = RetentionPolicy.CLASS; // the default
- Attribute.Compound c = a.type.tsym.attribute(syms.retentionType.tsym);
+ Attribute.Compound c = sym.attribute(syms.retentionType.tsym);
if (c != null) {
Attribute value = c.member(names.value);
if (value != null && value instanceof Attribute.Enum) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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,7 +25,11 @@
package com.sun.tools.javac.comp;
+import java.util.Map;
+import java.util.Objects;
+
import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.tree.*;
@@ -83,8 +87,9 @@
private int enterCount = 0;
ListBuffer<Annotator> q = new ListBuffer<Annotator>();
+ ListBuffer<Annotator> repeatedQ = new ListBuffer<Annotator>();
- public void later(Annotator a) {
+ public void normal(Annotator a) {
q.append(a);
}
@@ -92,6 +97,10 @@
q.prepend(a);
}
+ public void repeated(Annotator a) {
+ repeatedQ.append(a);
+ }
+
/** Called when the Enter phase starts. */
public void enterStart() {
enterCount++;
@@ -109,6 +118,10 @@
try {
while (q.nonEmpty())
q.next().enterAnnotation();
+
+ while (repeatedQ.nonEmpty()) {
+ repeatedQ.next().enterAnnotation();
+ }
} finally {
enterCount--;
}
@@ -124,6 +137,53 @@
String toString();
}
+ /**
+ * This context contains all the information needed to synthesize new
+ * annotations trees by the completer for repeating annotations.
+ */
+ public class AnnotateRepeatedContext {
+ public final Env<AttrContext> env;
+ public final Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated;
+ public final Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos;
+ public final Log log;
+
+ public AnnotateRepeatedContext(Env<AttrContext> env,
+ Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated,
+ Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos,
+ Log log) {
+ Objects.requireNonNull(env);
+ Objects.requireNonNull(annotated);
+ Objects.requireNonNull(pos);
+ Objects.requireNonNull(log);
+
+ this.env = env;
+ this.annotated = annotated;
+ this.pos = pos;
+ this.log = log;
+ }
+
+ /**
+ * Process a list of repeating annotations returning a new
+ * Attribute.Compound that is the attribute for the synthesized tree
+ * for the container.
+ *
+ * @param repeatingAnnotations a List of repeating annotations
+ * @return a new Attribute.Compound that is the container for the repeatingAnnotations
+ */
+ public Attribute.Compound processRepeatedAnnotations(List<Attribute.Compound> repeatingAnnotations) {
+ return Annotate.this.processRepeatedAnnotations(repeatingAnnotations, this);
+ }
+
+ /**
+ * Queue the Annotator a on the repeating annotations queue of the
+ * Annotate instance this context belongs to.
+ *
+ * @param a the Annotator to enqueue for repeating annotation annotating
+ */
+ public void annotateRepeated(Annotator a) {
+ Annotate.this.repeated(a);
+ }
+ }
/* ********************************************************************
* Compute an attribute from its annotation.
@@ -268,4 +328,219 @@
log.error(tree.pos(), "annotation.value.not.allowable.type");
return new Attribute.Error(attr.attribExpr(tree, env, expected));
}
+
+ /* *********************************
+ * Support for repeating annotations
+ ***********************************/
+
+ /* Process repeated annotations. This method returns the
+ * synthesized container annotation or null IFF all repeating
+ * annotation are invalid. This method reports errors/warnings.
+ */
+ private Attribute.Compound processRepeatedAnnotations(List<Attribute.Compound> annotations,
+ AnnotateRepeatedContext ctx) {
+ Attribute.Compound firstOccurrence = annotations.head;
+ List<Attribute> repeated = List.nil();
+ Type origAnnoType;
+ Type arrayOfOrigAnnoType = null;
+ Type targetContainerType = null;
+ MethodSymbol containerValueSymbol = null;
+
+ Assert.check(!annotations.isEmpty() &&
+ !annotations.tail.isEmpty()); // i.e. size() > 1
+
+ for (List<Attribute.Compound> al = annotations;
+ !al.isEmpty();
+ al = al.tail)
+ {
+ Attribute.Compound currentAnno = al.head;
+
+ origAnnoType = currentAnno.type;
+ if (arrayOfOrigAnnoType == null) {
+ arrayOfOrigAnnoType = types.makeArrayType(origAnnoType);
}
+
+ Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno));
+ if (currentContainerType == null) {
+ continue;
+ }
+ // Assert that the target Container is == for all repeated
+ // annos of the same annotation type, the types should
+ // come from the same Symbol, i.e. be '=='
+ Assert.check(targetContainerType == null || currentContainerType == targetContainerType);
+ targetContainerType = currentContainerType;
+
+ containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno));
+
+ if (containerValueSymbol == null) { // Check of CA type failed
+ // errors are already reported
+ continue;
+ }
+
+ repeated = repeated.prepend(currentAnno);
+ }
+
+ if (!repeated.isEmpty()) {
+ repeated = repeated.reverse();
+ JCAnnotation annoTree;
+ TreeMaker m = make.at(ctx.pos.get(firstOccurrence));
+ Pair<MethodSymbol, Attribute> p =
+ new Pair<MethodSymbol, Attribute>(containerValueSymbol,
+ new Attribute.Array(arrayOfOrigAnnoType, repeated));
+ annoTree = m.Annotation(new Attribute.Compound(targetContainerType,
+ List.of(p)));
+ Attribute.Compound c = enterAnnotation(annoTree,
+ targetContainerType,
+ ctx.env);
+ return c;
+ } else {
+ return null; // errors should have been reported elsewhere
+ }
+ }
+
+ /** Fetches the actual Type that should be the containing annotation. */
+ private Type getContainingType(Attribute.Compound currentAnno,
+ DiagnosticPosition pos)
+ {
+ Type origAnnoType = currentAnno.type;
+ TypeSymbol origAnnoDecl = origAnnoType.tsym;
+
+ // Fetch the ContainedBy annotation from the current
+ // annotation's declaration, or null if it has none
+ Attribute.Compound ca = origAnnoDecl.attribute(syms.containedByType.tsym);
+ if (ca == null) { // has no ContainedBy annotation
+ log.error(pos, "duplicate.annotation.missing.container", origAnnoType);
+ return null;
+ }
+
+ return filterSame(extractContainingType(ca, pos, origAnnoDecl),
+ origAnnoType);
+ }
+
+ // returns null if t is same as 's', returns 't' otherwise
+ private Type filterSame(Type t, Type s) {
+ if (t == null || s == null) {
+ return t;
+ }
+
+ return types.isSameType(t, s) ? null : t;
+ }
+
+ /** Extract the actual Type to be used for a containing annotation. */
+ private Type extractContainingType(Attribute.Compound ca,
+ DiagnosticPosition pos,
+ TypeSymbol annoDecl)
+ {
+ // The next three checks check that the ContainedBy annotation
+ // on the declaration of the annotation type that is repeating is
+ // valid.
+
+ // ContainedBy must have at least one element
+ if (ca.values.isEmpty()) {
+ log.error(pos, "invalid.containedby.annotation", annoDecl);
+ return null;
+ }
+ Pair<MethodSymbol,Attribute> p = ca.values.head;
+ Name name = p.fst.name;
+ if (name != names.value) { // should contain only one element, named "value"
+ log.error(pos, "invalid.containedby.annotation", annoDecl);
+ return null;
+ }
+ if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class
+ log.error(pos, "invalid.containedby.annotation", annoDecl);
+ return null;
+ }
+
+ return ((Attribute.Class)p.snd).getValue();
+ }
+
+ /* Validate that the suggested targetContainerType Type is a valid
+ * container type for repeated instances of originalAnnoType
+ * annotations. Return null and report errors if this is not the
+ * case, return the MethodSymbol of the value element in
+ * targetContainerType if it is suitable (this is needed to
+ * synthesize the container). */
+ private MethodSymbol validateContainer(Type targetContainerType,
+ Type originalAnnoType,
+ DiagnosticPosition pos) {
+ MethodSymbol containerValueSymbol = null;
+ boolean fatalError = false;
+
+ // Validate that there is a (and only 1) value method
+ Scope scope = targetContainerType.tsym.members();
+ int nr_value_elems = 0;
+ boolean error = false;
+ for(Symbol elm : scope.getElementsByName(names.value)) {
+ nr_value_elems++;
+
+ if (nr_value_elems == 1 &&
+ elm.kind == Kinds.MTH) {
+ containerValueSymbol = (MethodSymbol)elm;
+ } else {
+ error = true;
+ }
+ }
+ if (error) {
+ log.error(pos,
+ "invalid.containedby.annotation.multiple.values",
+ targetContainerType,
+ nr_value_elems);
+ return null;
+ } else if (nr_value_elems == 0) {
+ log.error(pos,
+ "invalid.containedby.annotation.no.value",
+ targetContainerType);
+ return null;
+ }
+
+ // validate that the 'value' element is a method
+ // probably "impossible" to fail this
+ if (containerValueSymbol.kind != Kinds.MTH) {
+ log.error(pos,
+ "invalid.containedby.annotation.invalid.value",
+ targetContainerType);
+ fatalError = true;
+ }
+
+ // validate that the 'value' element has the correct return type
+ // i.e. array of original anno
+ Type valueRetType = containerValueSymbol.type.getReturnType();
+ Type expectedType = types.makeArrayType(originalAnnoType);
+ if (!(types.isArray(valueRetType) &&
+ types.isSameType(expectedType, valueRetType))) {
+ log.error(pos,
+ "invalid.containedby.annotation.value.return",
+ targetContainerType,
+ valueRetType,
+ expectedType);
+ fatalError = true;
+ }
+
+ // validate that all other elements of containing type has defaults
+ scope = targetContainerType.tsym.members();
+ error = false;
+ for(Symbol elm : scope.getElements()) {
+ if (elm.name != names.value &&
+ elm.kind == Kinds.MTH &&
+ ((MethodSymbol)elm).defaultValue == null) {
+ log.error(pos,
+ "invalid.containedby.annotation.elem.nondefault",
+ targetContainerType,
+ elm);
+ containerValueSymbol = null;
+ error = true;
+ }
+ }
+ if (error) {
+ fatalError = true;
+ }
+
+ // Explicitly no check for/validity of @ContainerFor. That is
+ // done on declaration of the container, and at reflect time.
+
+ // The rest of the conditions for a valid containing annotation are made
+ // in Check.validateRepeatedAnnotaton();
+
+ return fatalError ? null : containerValueSymbol;
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Sep 14 13:52:30 2012 -0700
@@ -662,10 +662,12 @@
// env.info.enclVar.attributes_field might not yet have been evaluated, and so might be
// null. In that case, calling augment will throw an NPE. To avoid this, for now we
// revert to the jdk 6 behavior and ignore the (unevaluated) attributes.
- if (env.info.enclVar.attributes_field == null)
+ if (env.info.enclVar.annotations.pendingCompletion()) {
env.info.lint = lintEnv.info.lint;
- else
- env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.attributes_field, env.info.enclVar.flags());
+ } else {
+ env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.annotations,
+ env.info.enclVar.flags());
+ }
Lint prevLint = chk.setLint(env.info.lint);
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
@@ -776,7 +778,7 @@
public void visitMethodDef(JCMethodDecl tree) {
MethodSymbol m = tree.sym;
- Lint lint = env.info.lint.augment(m.attributes_field, m.flags());
+ Lint lint = env.info.lint.augment(m.annotations, m.flags());
Lint prevLint = chk.setLint(lint);
MethodSymbol prevMethod = chk.setMethod(m);
try {
@@ -921,7 +923,7 @@
}
VarSymbol v = tree.sym;
- Lint lint = env.info.lint.augment(v.attributes_field, v.flags());
+ Lint lint = env.info.lint.augment(v.annotations, v.flags());
Lint prevLint = chk.setLint(lint);
// Check that the variable's declared type is well-formed.
@@ -3069,7 +3071,7 @@
lintEnv = lintEnv.next;
// Having found the enclosing lint value, we can initialize the lint value for this class
- env.info.lint = lintEnv.info.lint.augment(c.attributes_field, c.flags());
+ env.info.lint = lintEnv.info.lint.augment(c.annotations, c.flags());
Lint prevLint = chk.setLint(env.info.lint);
JavaFileObject prev = log.useSource(c.sourcefile);
@@ -3133,6 +3135,26 @@
if (tree.typarams.nonEmpty())
log.error(tree.typarams.head.pos(),
"intf.annotation.cant.have.type.params");
+
+ // If this annotation has a @ContainedBy, validate
+ Attribute.Compound containedBy = c.attribute(syms.containedByType.tsym);
+ if (containedBy != null) {
+ // get diagnositc position for error reporting
+ DiagnosticPosition cbPos = getDiagnosticPosition(tree, containedBy.type);
+ Assert.checkNonNull(cbPos);
+
+ chk.validateContainedBy(c, containedBy, cbPos);
+ }
+
+ // If this annotation has a @ContainerFor, validate
+ Attribute.Compound containerFor = c.attribute(syms.containerForType.tsym);
+ if (containerFor != null) {
+ // get diagnositc position for error reporting
+ DiagnosticPosition cfPos = getDiagnosticPosition(tree, containerFor.type);
+ Assert.checkNonNull(cfPos);
+
+ chk.validateContainerFor(c, containerFor, cfPos);
+ }
} else {
// Check that all extended classes and interfaces
// are compatible (i.e. no two define methods with same arguments
@@ -3194,6 +3216,16 @@
}
}
// where
+ /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
+ private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
+ for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
+ if (types.isSameType(al.head.annotationType.type, t))
+ return al.head.pos();
+ }
+
+ return null;
+ }
+
/** check if a class is a subtype of Serializable, if that is available. */
private boolean isSerializable(ClassSymbol c) {
try {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Sep 14 13:52:30 2012 -0700
@@ -69,7 +69,6 @@
private final Infer infer;
private final Types types;
private final JCDiagnostic.Factory diags;
- private final boolean skipAnnotations;
private boolean warnOnSyntheticConflicts;
private boolean suppressAbortOnBadClassFile;
private boolean enableSunApiLintControl;
@@ -113,7 +112,6 @@
allowCovariantReturns = source.allowCovariantReturns();
allowSimplifiedVarargs = source.allowSimplifiedVarargs();
complexInference = options.isSet("complexinference");
- skipAnnotations = options.isSet("skipAnnotations");
warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
enableSunApiLintControl = options.isSet("enableSunApiLintControl");
@@ -2422,14 +2420,13 @@
/** Check the annotations of a symbol.
*/
public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
- if (skipAnnotations) return;
for (JCAnnotation a : annotations)
validateAnnotation(a, s);
}
/** Check an annotation of a symbol.
*/
- public void validateAnnotation(JCAnnotation a, Symbol s) {
+ private void validateAnnotation(JCAnnotation a, Symbol s) {
validateAnnotationTree(a);
if (!annotationApplicable(a, s))
@@ -2441,6 +2438,215 @@
}
}
+ /**
+ * Validate the proposed container 'containedBy' on the
+ * annotation type symbol 's'. Report errors at position
+ * 'pos'.
+ *
+ * @param s The (annotation)type declaration annotated with a @ContainedBy
+ * @param containerAnno the @ContainedBy on 's'
+ * @param pos where to report errors
+ */
+ public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) {
+ Assert.check(types.isSameType(containedBy.type, syms.containedByType));
+
+ Type t = null;
+ List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
+ if (!l.isEmpty()) {
+ Assert.check(l.head.fst.name == names.value);
+ t = ((Attribute.Class)l.head.snd).getValue();
+ }
+
+ if (t == null) {
+ log.error(pos, "invalid.container.wrong.containedby", s, containedBy);
+ return;
+ }
+
+ validateHasContainerFor(t.tsym, s, pos);
+ validateRetention(t.tsym, s, pos);
+ validateDocumented(t.tsym, s, pos);
+ validateInherited(t.tsym, s, pos);
+ validateTarget(t.tsym, s, pos);
+ }
+
+ /**
+ * Validate the proposed container 'containerFor' on the
+ * annotation type symbol 's'. Report errors at position
+ * 'pos'.
+ *
+ * @param s The (annotation)type declaration annotated with a @ContainerFor
+ * @param containerFor the @ContainedFor on 's'
+ * @param pos where to report errors
+ */
+ public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) {
+ Assert.check(types.isSameType(containerFor.type, syms.containerForType));
+
+ Type t = null;
+ List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
+ if (!l.isEmpty()) {
+ Assert.check(l.head.fst.name == names.value);
+ t = ((Attribute.Class)l.head.snd).getValue();
+ }
+
+ if (t == null) {
+ log.error(pos, "invalid.container.wrong.containerfor", s, containerFor);
+ return;
+ }
+
+ validateHasContainedBy(t.tsym, s, pos);
+ }
+
+ private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
+ Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym);
+
+ if (containedBy == null) {
+ log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym);
+ return;
+ }
+
+ Type t = null;
+ List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
+ if (!l.isEmpty()) {
+ Assert.check(l.head.fst.name == names.value);
+ t = ((Attribute.Class)l.head.snd).getValue();
+ }
+
+ if (t == null) {
+ log.error(pos, "invalid.container.wrong.containedby", container, contained);
+ return;
+ }
+
+ if (!types.isSameType(t, contained.type))
+ log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained);
+ }
+
+ private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
+ Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym);
+
+ if (containerFor == null) {
+ log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym);
+ return;
+ }
+
+ Type t = null;
+ List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
+ if (!l.isEmpty()) {
+ Assert.check(l.head.fst.name == names.value);
+ t = ((Attribute.Class)l.head.snd).getValue();
+ }
+
+ if (t == null) {
+ log.error(pos, "invalid.container.wrong.containerfor", container, contained);
+ return;
+ }
+
+ if (!types.isSameType(t, contained.type))
+ log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained);
+ }
+
+ private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) {
+ Attribute.RetentionPolicy containerRetention = types.getRetention(container);
+ Attribute.RetentionPolicy containedRetention = types.getRetention(contained);
+
+ boolean error = false;
+ switch (containedRetention) {
+ case RUNTIME:
+ if (containerRetention != Attribute.RetentionPolicy.RUNTIME) {
+ error = true;
+ }
+ break;
+ case CLASS:
+ if (containerRetention == Attribute.RetentionPolicy.SOURCE) {
+ error = true;
+ }
+ }
+ if (error ) {
+ log.error(pos, "invalid.containedby.annotation.retention",
+ container, containerRetention,
+ contained, containedRetention);
+ }
+ }
+
+ private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
+ if (contained.attribute(syms.documentedType.tsym) != null) {
+ if (container.attribute(syms.documentedType.tsym) == null) {
+ log.error(pos, "invalid.containedby.annotation.not.documented", container, contained);
+ }
+ }
+ }
+
+ private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
+ if (contained.attribute(syms.inheritedType.tsym) != null) {
+ if (container.attribute(syms.inheritedType.tsym) == null) {
+ log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained);
+ }
+ }
+ }
+
+ private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) {
+ Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
+
+ // If contained has no Target, we are done
+ if (containedTarget == null) {
+ return;
+ }
+
+ // If contained has Target m1, container must have a Target
+ // annotation, m2, and m2 must be a subset of m1. (This is
+ // trivially true if contained has no target as per above).
+
+ // contained has target, but container has not, error
+ Attribute.Array containerTarget = getAttributeTargetAttribute(container);
+ if (containerTarget == null) {
+ log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+ return;
+ }
+
+ Set<Name> containerTargets = new HashSet<Name>();
+ for (Attribute app : containerTarget.values) {
+ if (!(app instanceof Attribute.Enum)) {
+ continue; // recovery
+ }
+ Attribute.Enum e = (Attribute.Enum)app;
+ containerTargets.add(e.value.name);
+ }
+
+ Set<Name> containedTargets = new HashSet<Name>();
+ for (Attribute app : containedTarget.values) {
+ if (!(app instanceof Attribute.Enum)) {
+ continue; // recovery
+ }
+ Attribute.Enum e = (Attribute.Enum)app;
+ containedTargets.add(e.value.name);
+ }
+
+ if (!isTargetSubset(containedTargets, containerTargets)) {
+ log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+ }
+ }
+
+ /** Checks that t is a subset of s, with respect to ElementType
+ * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE}
+ */
+ private boolean isTargetSubset(Set<Name> s, Set<Name> t) {
+ // Check that all elements in t are present in s
+ for (Name n2 : t) {
+ boolean currentElementOk = false;
+ for (Name n1 : s) {
+ if (n1 == n2) {
+ currentElementOk = true;
+ break;
+ } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) {
+ currentElementOk = true;
+ break;
+ }
+ }
+ if (!currentElementOk)
+ return false;
+ }
+ return true;
+ }
+
/** Is s a method symbol that overrides a method in a superclass? */
boolean isOverrider(Symbol s) {
if (s.kind != MTH || s.isStatic())
@@ -2461,12 +2667,10 @@
/** Is the annotation applicable to the symbol? */
boolean annotationApplicable(JCAnnotation a, Symbol s) {
- Attribute.Compound atTarget =
- a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
- if (atTarget == null) return true;
- Attribute atValue = atTarget.member(names.value);
- if (!(atValue instanceof Attribute.Array)) return true; // error recovery
- Attribute.Array arr = (Attribute.Array) atValue;
+ Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
+ if (arr == null) {
+ return true;
+ }
for (Attribute app : arr.values) {
if (!(app instanceof Attribute.Enum)) return true; // recovery
Attribute.Enum e = (Attribute.Enum) app;
@@ -2508,6 +2712,16 @@
return false;
}
+
+ Attribute.Array getAttributeTargetAttribute(Symbol s) {
+ Attribute.Compound atTarget =
+ s.attribute(syms.annotationTargetType.tsym);
+ if (atTarget == null) return null; // ok, is applicable
+ Attribute atValue = atTarget.member(names.value);
+ if (!(atValue instanceof Attribute.Array)) return null; // error recovery
+ return (Attribute.Array) atValue;
+ }
+
/** Check an annotation value.
*/
public void validateAnnotation(JCAnnotation a) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Fri Sep 14 13:52:30 2012 -0700
@@ -157,7 +157,7 @@
Env<AttrContext> lintEnv = localEnv;
while (lintEnv.info.lint == null)
lintEnv = lintEnv.next;
- localEnv.info.lint = lintEnv.info.lint.augment(sym.attributes_field, sym.flags());
+ localEnv.info.lint = lintEnv.info.lint.augment(sym.annotations, sym.flags());
return localEnv;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Sep 14 13:52:30 2012 -0700
@@ -406,7 +406,7 @@
Lint lintPrev = lint;
pendingExits = new ListBuffer<PendingExit>();
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try {
// process all the static initializers
@@ -442,7 +442,7 @@
if (tree.body == null) return;
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
Assert.check(pendingExits.isEmpty());
@@ -468,7 +468,7 @@
public void visitVarDef(JCVariableDecl tree) {
if (tree.init != null) {
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try{
scan(tree.init);
} finally {
@@ -783,7 +783,7 @@
}
classDef = tree;
thrown = List.nil();
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try {
// process all the static initializers
@@ -863,7 +863,7 @@
List<Type> mthrown = tree.sym.type.getThrownTypes();
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
Assert.check(pendingExits.isEmpty());
@@ -902,7 +902,7 @@
public void visitVarDef(JCVariableDecl tree) {
if (tree.init != null) {
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try{
scan(tree.init);
} finally {
@@ -1491,7 +1491,7 @@
firstadr = nextadr;
}
classDef = tree;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try {
// define all the static fields
@@ -1558,7 +1558,7 @@
int firstadrPrev = firstadr;
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
Assert.check(pendingExits.isEmpty());
@@ -1609,7 +1609,7 @@
if (track && tree.sym.owner.kind == MTH) newVar(tree.sym);
if (tree.init != null) {
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try{
scanExpr(tree.init);
if (track) letInit(tree.pos(), tree.sym);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri Sep 14 13:52:30 2012 -0700
@@ -2257,7 +2257,7 @@
null, List.<JCExpression>nil(), List.<JCTree>nil());
ClassSymbol c = tree.packge.package_info;
c.flags_field |= flags;
- c.attributes_field = tree.packge.attributes_field;
+ c.annotations.setAttributes(tree.packge.annotations);
ClassType ctype = (ClassType) c.type;
ctype.supertype_field = syms.objectType;
ctype.interfaces_field = List.nil();
@@ -2274,7 +2274,8 @@
case LEGACY:
return tree.packageAnnotations.nonEmpty();
case NONEMPTY:
- for (Attribute.Compound a: tree.packge.attributes_field) {
+ for (Attribute.Compound a :
+ tree.packge.annotations.getAttributes()) {
Attribute.RetentionPolicy p = types.getRetention(a);
if (p != Attribute.RetentionPolicy.SOURCE)
return true;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Sep 14 13:52:30 2012 -0700
@@ -76,11 +76,10 @@
private final Annotate annotate;
private final Types types;
private final JCDiagnostic.Factory diags;
+ private final Source source;
private final Target target;
private final DeferredLintHandler deferredLintHandler;
- private final boolean skipAnnotations;
-
public static MemberEnter instance(Context context) {
MemberEnter instance = context.get(memberEnterKey);
if (instance == null)
@@ -102,10 +101,9 @@
annotate = Annotate.instance(context);
types = Types.instance(context);
diags = JCDiagnostic.Factory.instance(context);
+ source = Source.instance(context);
target = Target.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
- Options options = Options.instance(context);
- skipAnnotations = options.isSet("skipAnnotations");
}
/** A queue for classes whose members still need to be entered into the
@@ -690,7 +688,7 @@
public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) {
Env<AttrContext> mEnv = methodEnv(tree, env);
- mEnv.info.lint = mEnv.info.lint.augment(tree.sym.attributes_field, tree.sym.flags());
+ mEnv.info.lint = mEnv.info.lint.augment(tree.sym.annotations, tree.sym.flags());
for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
mEnv.info.scope.enterIfAbsent(l.head.type.tsym);
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail)
@@ -727,18 +725,24 @@
void annotateLater(final List<JCAnnotation> annotations,
final Env<AttrContext> localEnv,
final Symbol s) {
- if (annotations.isEmpty()) return;
- if (s.kind != PCK) s.attributes_field = null; // mark it incomplete for now
- annotate.later(new Annotate.Annotator() {
+ if (annotations.isEmpty()) {
+ return;
+ }
+ if (s.kind != PCK) {
+ s.annotations.reset(); // mark Annotations as incomplete for now
+ }
+ annotate.normal(new Annotate.Annotator() {
+ @Override
public String toString() {
return "annotate " + annotations + " onto " + s + " in " + s.owner;
}
+
+ @Override
public void enterAnnotation() {
- Assert.check(s.kind == PCK || s.attributes_field == null);
+ Assert.check(s.kind == PCK || s.annotations.pendingCompletion());
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
try {
- if (s.attributes_field != null &&
- s.attributes_field.nonEmpty() &&
+ if (!s.annotations.isEmpty() &&
annotations.nonEmpty())
log.error(annotations.head.pos,
"already.annotated",
@@ -756,7 +760,7 @@
* java.lang.Deprecated.
**/
private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
- for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
+ for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
JCAnnotation a = al.head;
if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
return true;
@@ -764,42 +768,62 @@
return false;
}
-
/** Enter a set of annotations. */
private void enterAnnotations(List<JCAnnotation> annotations,
Env<AttrContext> env,
Symbol s) {
- ListBuffer<Attribute.Compound> buf =
- new ListBuffer<Attribute.Compound>();
- Set<TypeSymbol> annotated = new HashSet<TypeSymbol>();
- if (!skipAnnotations)
- for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
+ Map<TypeSymbol, ListBuffer<Attribute.Compound>> annotated =
+ new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.Compound>>();
+ Map<Attribute.Compound, DiagnosticPosition> pos =
+ new HashMap<Attribute.Compound, DiagnosticPosition>();
+
+ for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
JCAnnotation a = al.head;
Attribute.Compound c = annotate.enterAnnotation(a,
syms.annotationType,
env);
- if (c == null) continue;
- buf.append(c);
+ if (c == null) {
+ continue;
+ }
+
+ if (annotated.containsKey(a.type.tsym)) {
+ if (source.allowRepeatedAnnotations()) {
+ ListBuffer<Attribute.Compound> l = annotated.get(a.type.tsym);
+ l = l.append(c);
+ annotated.put(a.type.tsym, l);
+ pos.put(c, a.pos());
+ } else {
+ log.error(a.pos(), "duplicate.annotation");
+ }
+ } else {
+ annotated.put(a.type.tsym, ListBuffer.of(c));
+ pos.put(c, a.pos());
+ }
+
// Note: @Deprecated has no effect on local variables and parameters
if (!c.type.isErroneous()
&& s.owner.kind != MTH
- && types.isSameType(c.type, syms.deprecatedType))
+ && types.isSameType(c.type, syms.deprecatedType)) {
s.flags_field |= Flags.DEPRECATED;
- if (!annotated.add(a.type.tsym))
- log.error(a.pos, "duplicate.annotation");
+ }
}
- s.attributes_field = buf.toList();
+
+ s.annotations.setAttributesWithCompletion(
+ annotate.new AnnotateRepeatedContext(env, annotated, pos, log));
}
/** Queue processing of an attribute default value. */
void annotateDefaultValueLater(final JCExpression defaultValue,
final Env<AttrContext> localEnv,
final MethodSymbol m) {
- annotate.later(new Annotate.Annotator() {
+ annotate.normal(new Annotate.Annotator() {
+ @Override
public String toString() {
return "annotate " + m.owner + "." +
m + " default " + defaultValue;
}
+
+ @Override
public void enterAnnotation() {
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
try {
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Sep 14 13:52:30 2012 -0700
@@ -1321,7 +1321,7 @@
else
proxies.append(proxy);
}
- annotate.later(new AnnotationCompleter(sym, proxies.toList()));
+ annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
}
}
@@ -1347,7 +1347,7 @@
void attachAnnotationDefault(final Symbol sym) {
final MethodSymbol meth = (MethodSymbol)sym; // only on methods
final Attribute value = readAttributeValue();
- annotate.later(new AnnotationDefaultCompleter(meth, value));
+ annotate.normal(new AnnotationDefaultCompleter(meth, value));
}
Type readTypeOrClassSymbol(int i) {
@@ -1693,10 +1693,13 @@
JavaFileObject previousClassFile = currentClassFile;
try {
currentClassFile = classFile;
+ Annotations annotations = sym.annotations;
List<Attribute.Compound> newList = deproxyCompoundList(l);
- sym.attributes_field = ((sym.attributes_field == null)
- ? newList
- : newList.prependList(sym.attributes_field));
+ if (annotations.pendingCompletion()) {
+ annotations.setAttributes(newList);
+ } else {
+ annotations.append(newList);
+ }
} finally {
currentClassFile = previousClassFile;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Sep 14 13:52:30 2012 -0700
@@ -825,7 +825,7 @@
}
public void visitClass(Attribute.Class clazz) {
databuf.appendByte('c');
- databuf.appendChar(pool.put(typeSig(clazz.type)));
+ databuf.appendChar(pool.put(typeSig(clazz.classType)));
}
public void visitCompound(Attribute.Compound compound) {
databuf.appendByte('@');
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Fri Sep 14 13:52:30 2012 -0700
@@ -157,7 +157,7 @@
if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
return false;
- for (Attribute.Compound a: c.attributes_field) {
+ for (Attribute.Compound a: c.annotations.getAttributes()) {
if (a.type.tsym == syms.nativeHeaderType.tsym)
return true;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -177,7 +177,7 @@
}
public void visitClass(Attribute.Class c) {
- value = new MirroredTypeExceptionProxy(c.type);
+ value = new MirroredTypeExceptionProxy(c.classType);
}
public void visitArray(Attribute.Array a) {
@@ -187,7 +187,7 @@
// Construct a proxy for a MirroredTypesException
ListBuffer<TypeMirror> elems = new ListBuffer<TypeMirror>();
for (Attribute value : a.values) {
- Type elem = ((Attribute.Class) value).type;
+ Type elem = ((Attribute.Class) value).classType;
elems.append(elem);
}
value = new MirroredTypesExceptionProxy(elems.toList());
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Sep 14 13:52:30 2012 -0700
@@ -250,6 +250,70 @@
compiler.err.duplicate.annotation.member.value=\
duplicate annotation member value {0} in {1}
+# 0: type
+compiler.err.duplicate.annotation.missing.container=\
+ duplicate annotation, the declaration of {0} does not have a ContainedBy annotation
+
+# 0: type, 1: type
+compiler.err.invalid.container.no.containedby=\
+ invalid contained repeatable annotation, {0} is not annotated with {1}
+
+# 0: type, 1: type
+compiler.err.invalid.container.wrong.containedby=\
+ invalid contained repeatable annotation, {0} does not match {1}
+
+# 0: type, 1: type
+compiler.err.invalid.container.no.containerfor=\
+ invalid container for repeating annotations, {0} is not annotated with {1}
+
+# 0: type, 1: type
+compiler.err.invalid.container.wrong.containerfor=\
+ invalid container for repeating annotations, {0} does not match {1}
+
+# 0: type
+compiler.err.invalid.containedby.annotation=\
+ duplicate annotation, {0} is annotated with an invalid ContainedBy annotation
+
+# 0: type
+compiler.err.invalid.containedby.annotation.no.value=\
+ duplicate annotation, {0} is not a valid ContainedBy, no value element method declared
+
+# 0: type, 1: number
+compiler.err.invalid.containedby.annotation.multiple.values=\
+ duplicate annotation, {0} is not a valid ContainedBy, {1} value element methods declared
+
+# 0: type
+compiler.err.invalid.containedby.annotation.invalid.value=\
+ duplicate annotation, {0} is not a valid ContainedBy, invalid value element, need a method
+
+# 0: type, 1: type, 2: type
+compiler.err.invalid.containedby.annotation.value.return=\
+ duplicate annotation, value element of containing annotation {0} should have type {2}, found {1}
+
+# 0: type, 1: symbol
+compiler.err.invalid.containedby.annotation.elem.nondefault=\
+ duplicate annotation, element {1} in containing annotation {0} does not have a default value
+
+# 0: symbol, 1: type, 2: symbol, 3: type
+compiler.err.invalid.containedby.annotation.retention=\
+ containing annotation {0} has shorter retention ({1}) than the contained annotation {2} with retention {3}
+
+# 0: symbol, 1: symbol
+compiler.err.invalid.containedby.annotation.not.documented=\
+ containing annotation type, {0}, is not @Documented while repeated annotation type, {1}, is
+
+# 0: symbol, 1: symbol
+compiler.err.invalid.containedby.annotation.not.inherited=\
+ containing annotation type, {0}, is not @Inherited while repeated annotation type, {1}, is
+
+# 0: symbol, 1: symbol
+compiler.err.invalid.containedby.annotation.incompatible.target=\
+ target of container annotation {0} is not a subset of target of repeated annotation {1}
+
+# 0: symbol
+compiler.err.invalid.containedby.annotation.repeated.and.container.present=\
+ container {0} must not be present at the same time as the element it contains
+
# 0: name
compiler.err.duplicate.class=\
duplicate class: {0}
--- a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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
@@ -206,9 +206,7 @@
}
ClassSymbol cs = (ClassSymbol) sym;
if (addLegacyAnnotation) {
- cs.attributes_field = (cs.attributes_field == null)
- ? List.of(proprietary)
- : cs.attributes_field.prepend(proprietary);
+ cs.annotations.prepend(List.of(proprietary));
}
writeClass(pool, cs, writer);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -740,7 +740,7 @@
result = Literal(v.value);
}
public void visitClass(Attribute.Class clazz) {
- result = ClassLiteral(clazz.type).setType(syms.classType);
+ result = ClassLiteral(clazz.classType).setType(syms.classType);
}
public void visitEnum(Attribute.Enum e) {
result = QualIdent(e.value);
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -83,7 +83,7 @@
public void visitClass(Attribute.Class c) {
value = TypeMaker.getType(env,
- env.types.erasure(c.type));
+ env.types.erasure(c.classType));
}
public void visitEnum(Attribute.Enum e) {
--- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -506,7 +506,7 @@
List<String> opts = new ArrayList<String>();
opts.add("-proc:only");
opts.addAll(javac_extras);
- CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, internalize(classes), null);
+ CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, classes, null);
JavahProcessor p = new JavahProcessor(g);
t.setProcessors(Collections.singleton(p));
@@ -516,14 +516,6 @@
return ok;
}
- private List<String> internalize(List<String> classes) {
- List<String> l = new ArrayList<String>();
- for (String c: classes) {
- l.add(c.replace('$', '.'));
- }
- return l;
- }
-
private List<File> pathToFiles(String path) {
List<File> files = new ArrayList<File>();
for (String f: path.split(File.pathSeparator)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean BasicRepeatingAnnotations BasicRepeatingAnnos BasicNonRepeatingAnno Foo Foos Bar
+ * @run compile BasicRepeatingAnnotations.java
+ * @run main BasicRepeatingAnnotations
+ */
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface Foos {
+ Foo[] value();
+}
+
+@interface Bar {}
+
+@Foo @Foo
+@Foo
+@Bar
+@Foo
+@Foo
+@Foo
+@Foo
+@Foo @Foo
+@Foo
+class BasicRepeatingAnnos {}
+
+@Foo
+class BasicNonRepeatingAnno {}
+
+public class BasicRepeatingAnnotations {
+ public static void main(String[] args) throws Exception {
+ Annotation a = BasicRepeatingAnnos.class.getAnnotation(Foos.class);
+ if (a == null) {
+ throw new RuntimeException("Container annotation missing");
+ }
+
+ // verify that container not present on nonrepeating
+ a = BasicNonRepeatingAnno.class.getAnnotation(Foos.class);
+ if (a != null) {
+ throw new RuntimeException("Container annotation present");
+ }
+ a = BasicNonRepeatingAnno.class.getAnnotation(Foo.class);
+ if (a == null) {
+ throw new RuntimeException("Repeated annoation not directly present");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean Foos Foo Bars Bar Baz Bazs CheckTargets
+ * @run compile CheckTargets.java
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@Target(ElementType.TYPE)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@Target(ElementType.ANNOTATION_TYPE)
+@interface Foos {
+ Foo[] value();
+}
+
+@ContainedBy(Bars.class)
+@Target(ElementType.TYPE)
+@interface Bar {}
+
+@ContainerFor(Bar.class)
+@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
+@interface Bars {
+ Bar[] value();
+}
+
+
+@ContainedBy(Bazs.class)
+@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
+@interface Baz {}
+
+@ContainerFor(Baz.class)
+@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
+@interface Bazs {
+ Baz[] value();
+}
+
+
+public class CheckTargets {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean Bar BarContainer ContainerHasRepeatedContained
+ * @run compile ContainerHasRepeatedContained.java
+ */
+
+import java.lang.annotation.ContainedBy;
+import java.lang.annotation.ContainerFor;
+
+@ContainedBy(BarContainer.class)
+@interface Bar {}
+
+@Bar
+@Bar
+@ContainerFor(Bar.class)
+@interface BarContainer {
+ Bar[] value();
+}
+
+public class ContainerHasRepeatedContained {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean DelayRepeatedContainer Bar BarContainer
+ * @run compile DelayRepeatedContainer.java
+ */
+
+import java.lang.annotation.*;
+
+public class DelayRepeatedContainer {
+ @Bar("apa") @Bar("banan")
+ String meh() { return "meh"; }
+}
+
+@Bar("katt")
+@Bar("lol")
+@ContainedBy(BarContainer.class)
+@interface Bar {
+ String value();
+}
+
+@ContainerFor(Bar.class)
+@interface BarContainer {
+ Bar[] value();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean Foos Foo
+ * @run compile/fail InvalidTarget.java
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@Target(ElementType.ANNOTATION_TYPE)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@Target(ElementType.TYPE)
+@interface Foos {
+ Foo[] value();
+}
+
+public class InvalidTargets {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail MissingContainedBy.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+
+@ContainerFor(MissingContainedBy.class)
+@interface Foos {
+ MissingContainedBy[] value();
+}
+
+public @interface MissingContainedBy {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail MissingContainerFor.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@interface Foos {
+ MissingContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface MissingContainerFor {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean NestedContainers BasicRepeatingAnnos BasicRepeatingAnnos2 Foo Foos FoosFoos
+ * @run compile NestedContainers.java
+ * @run main NestedContainers
+ */
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(FoosFoos.class)
+@ContainerFor(Foo.class)
+@interface Foos {
+ Foo[] value();
+}
+
+@ContainerFor(Foos.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface FoosFoos {
+ Foos[] value();
+}
+
+@Foo
+@Foo
+class BasicRepeatingAnnos {}
+
+@Foos({})
+@Foos({})
+class BasicRepeatingAnnos2 {}
+
+public class NestedContainers {
+ public static void main(String[] args) throws Exception {
+ Annotation a = BasicRepeatingAnnos.class.getAnnotation(Foos.class);
+ if (a == null) {
+ throw new RuntimeException("Container annotation missing");
+ }
+
+ // Check 2:nd level container
+ a = BasicRepeatingAnnos2.class.getAnnotation(FoosFoos.class);
+ if (a == null) {
+ throw new RuntimeException("Container annotation missing");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean RepMemberAnno Bar BarContainer
+ * @run compile RepMemberAnno.java
+ */
+
+import java.lang.annotation.ContainedBy;
+import java.lang.annotation.ContainerFor;
+
+public class RepMemberAnno {
+ @Bar("Apa") @Bar("Banan")
+ public void meh() {}
+}
+
+@ContainedBy(BarContainer.class)
+@interface Bar {
+ String value();
+}
+
+@ContainerFor(Bar.class)
+@interface BarContainer {
+ Bar[] value();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean RepSelfMemberAnno BarContainer BarContainerContainer
+ * @run compile RepSelfMemberAnno.java
+ */
+
+import java.lang.annotation.*;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(BarContainer.class)
+public @interface RepSelfMemberAnno {
+ @RepSelfMemberAnno @RepSelfMemberAnno
+ String meh() default "banan";
+}
+
+
+@ContainedBy(BarContainerContainer.class)
+@Retention(RetentionPolicy.RUNTIME)
+@ContainerFor(RepSelfMemberAnno.class)
+@interface BarContainer {
+ RepSelfMemberAnno[] value();
+}
+
+@ContainerFor(BarContainer.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface BarContainerContainer {
+ BarContainer[] value();
+ String meh() default "apa";
+}
+
+@BarContainer(value={})
+@BarContainer(value={})
+@interface Bar {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail RepeatingAndContainerPresent.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@interface Foos {
+ Foo[] value();
+}
+
+
+@Foo
+@Foo
+@Foos({})
+public class RepeatingAndContainerPresent {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean SelfRepeatingAnnotations Foos SelfRepeatingAnno
+ * @run compile SelfRepeatingAnnotations.java
+ * @run main SelfRepeatingAnnotations
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(SelfRepeatingAnno.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface Foos {
+ SelfRepeatingAnno[] value();
+}
+
+@SelfRepeatingAnno
+@Retention(RetentionPolicy.RUNTIME)
+@SelfRepeatingAnno
+@ContainedBy(Foos.class)
+@interface SelfRepeatingAnno {}
+
+public class SelfRepeatingAnnotations {
+ public static void main(String[] args) throws Exception {
+ Annotation a = SelfRepeatingAnno.class.getAnnotation(Foos.class);
+ if (a == null) {
+ throw new RuntimeException("Container annotation missing");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile SingleRepeatingAndContainer.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@interface Foos {
+ Foo[] value();
+}
+
+@Foo
+@Foos({})
+public class SingleRepeatingAndContainer {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail UseWrongContainedBy.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(UseWrongContainedBy.class)
+@interface Foos {
+ UseWrongContainedBy[] value();
+}
+
+@ContainedBy(Target.class)
+public @interface UseWrongContainedBy {}
+
+@UseWrongContainedBy @UseWrongContainedBy
+@interface Foo {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail UseWrongContainerFor.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(Retention.class)
+@interface Foos {
+ UseWrongContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface UseWrongContainerFor {}
+
+@UseWrongContainerFor @UseWrongContainerFor
+@interface Foo {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail WrongContainedBy.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(WrongContainedBy.class)
+@interface Foos {
+ WrongContainedBy[] value();
+}
+
+@ContainedBy(Target.class)
+public @interface WrongContainedBy {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail WrongContainerFor.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(Retention.class)
+@interface Foos {
+ WrongContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface WrongContainerFor {}
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Fri Sep 14 13:52:30 2012 -0700
@@ -5,6 +5,9 @@
compiler.err.cant.read.file # (apt.JavaCompiler?)
compiler.err.cant.select.static.class.from.param.type
compiler.err.illegal.char.for.encoding
+compiler.err.invalid.containedby.annotation # should not happen
+compiler.err.invalid.containedby.annotation.invalid.value # "can't" happen
+compiler.err.invalid.containedby.annotation.multiple.values # can't happen
compiler.err.io.exception # (javah.JavahTask?)
compiler.err.limit.code # Code
compiler.err.limit.code.too.large.for.try.stmt # Gen
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.not.documented
+
+import java.lang.annotation.*;
+
+@Documented
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class ContainedByDocumentedMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.not.inherited
+
+import java.lang.annotation.*;
+
+@Inherited
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class ContainedByInheritedMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.no.value
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos {}
+
+@Anno
+@Anno
+class ContainedByNoValue { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.elem.nondefault
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); String foo(); }
+
+@Anno
+@Anno
+class ContainedByNonDefault { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.retention
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class ContainedByRetentionMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.incompatible.target
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@Target(ElementType.METHOD)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+class ContainedByTargetMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.value.return
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { String value(); }
+
+@Anno
+@Anno
+class ContainedByWrongValueType { }
--- a/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java Tue Sep 11 13:32:48 2012 +0400
+++ b/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java Fri Sep 14 13:52:30 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012 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
@@ -22,6 +22,8 @@
*/
// key: compiler.err.duplicate.annotation
+// key: compiler.warn.source.no.bootclasspath
+// options: -source 7
@interface Anno { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/DuplicateAnnotationJava8.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.duplicate.annotation.missing.container
+
+@interface Anno { }
+
+@Anno
+@Anno
+class DuplicateAnnotationJava8 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.repeated.and.container.present
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+@Annos(@Anno)
+class RepeatingAnnotationAndContainer { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/WrongContainedBy.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.container.no.containerfor
+// key: compiler.err.invalid.container.wrong.containedby
+
+import java.lang.annotation.*;
+
+@ContainerFor(WrongContainedBy.class)
+@interface Foos {
+ WrongContainedBy[] value();
+}
+
+@ContainedBy(Target.class)
+public @interface WrongContainedBy {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/WrongContainerFor.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.container.wrong.containerfor
+// key: compiler.err.invalid.container.no.containedby
+
+import java.lang.annotation.*;
+
+@ContainerFor(Retention.class)
+@interface Foos {
+ WrongContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface WrongContainerFor {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javah/T7185778.java Fri Sep 14 13:52:30 2012 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7185778
+ * @summary javah error "Not a valid class name" on class names with dollar signs
+ * The first two tests are on an inner class name whose name does not contain $.
+ * The second two tests are on an inner class name whose name does contain $.
+ * The last test is on an outer class whose name contains $.
+ * @run main T7185778 T7185778$inner
+ * @run main T7185778 T7185778.inner
+ * @run main T7185778 T7185778$inner$
+ * @run main T7185778 T7185778.inner$
+ * @run main T7185778 xx$yy
+ */
+
+public class T7185778 {
+ class inner {
+ native byte[] xxxxx(String name);
+ }
+ class inner$ {
+ native byte[] xxxxx(String name);
+ }
+
+ static public void main(String[] args) {
+ int rc = com.sun.tools.javah.Main.run(args, null);
+ if ( rc != 0) {
+ throw new Error("javah returned non zero: " + rc);
+ }
+ }
+}
+
+class xx$yy {
+ native byte[] xxxxx(String name);
+}