提交 46117574 编写于 作者: C chegar

Merge

# #
# Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
FILES_export = \ FILES_export = \
sun/management/ClassLoadingImpl.java \ sun/management/ClassLoadingImpl.java \
sun/management/DiagnosticCommandImpl.java \
sun/management/FileSystemImpl.java \ sun/management/FileSystemImpl.java \
sun/management/Flag.java \ sun/management/Flag.java \
sun/management/GarbageCollectorImpl.java \ sun/management/GarbageCollectorImpl.java \
......
# #
# Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
FILES_c = \ FILES_c = \
ClassLoadingImpl.c \ ClassLoadingImpl.c \
DiagnosticCommandImpl.c \
FileSystemImpl.c \ FileSystemImpl.c \
Flag.c \ Flag.c \
GarbageCollectorImpl.c \ GarbageCollectorImpl.c \
......
# #
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -39,6 +39,10 @@ SUNWprivate_1.1 { ...@@ -39,6 +39,10 @@ SUNWprivate_1.1 {
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize; Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
Java_com_sun_management_UnixOperatingSystem_initialize; Java_com_sun_management_UnixOperatingSystem_initialize;
Java_sun_management_ClassLoadingImpl_setVerboseClass; Java_sun_management_ClassLoadingImpl_setVerboseClass;
Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand;
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands;
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo;
Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled;
Java_sun_management_FileSystemImpl_isAccessUserOnly0; Java_sun_management_FileSystemImpl_isAccessUserOnly0;
Java_sun_management_Flag_getAllFlagNames; Java_sun_management_Flag_getAllFlagNames;
Java_sun_management_Flag_getFlags; Java_sun_management_Flag_getFlags;
......
...@@ -171,3 +171,13 @@ FILES_NO_MOTIF_c = \ ...@@ -171,3 +171,13 @@ FILES_NO_MOTIF_c = \
GLXSurfaceData.c \ GLXSurfaceData.c \
AccelGlyphCache.c \ AccelGlyphCache.c \
CUPSfuncs.c CUPSfuncs.c
ifeq ($(PLATFORM), macosx)
FILES_NO_MOTIF_objc = \
AWTFont.m \
AWTStrike.m \
CCharToGlyphMapper.m \
CGGlyphImages.m \
CGGlyphOutlines.m \
CoreTextSupport.m
endif # PLATFORM
...@@ -187,3 +187,14 @@ FILES_export2 = \ ...@@ -187,3 +187,14 @@ FILES_export2 = \
java/awt/dnd/DnDConstants.java \ java/awt/dnd/DnDConstants.java \
sun/awt/CausedFocusEvent.java sun/awt/CausedFocusEvent.java
ifeq ($(PLATFORM), macosx)
ifeq ($(HEADLESS), true)
FILES_export += \
sun/awt/SunHints.java \
sun/font/CCharToGlyphMapper.java \
sun/font/CFont.java \
sun/font/CFontManager.java \
sun/font/CStrike.java \
sun/font/CStrikeDisposer.java
endif # HEADLESS
endif # PLATFORM
...@@ -43,6 +43,10 @@ include $(BUILDDIR)/sun/awt/FILES_export_unix.gmk ...@@ -43,6 +43,10 @@ include $(BUILDDIR)/sun/awt/FILES_export_unix.gmk
# compiled based on the motif version. # compiled based on the motif version.
FILES_c = $(FILES_NO_MOTIF_c) FILES_c = $(FILES_NO_MOTIF_c)
ifeq ($(PLATFORM), macosx)
FILES_objc = $(FILES_NO_MOTIF_objc)
endif # PLATFORM
ifeq ($(PLATFORM), solaris) ifeq ($(PLATFORM), solaris)
ifneq ($(ARCH), amd64) ifneq ($(ARCH), amd64)
FILES_reorder += reorder-$(ARCH) FILES_reorder += reorder-$(ARCH)
...@@ -97,6 +101,10 @@ vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/../java2d/pipe ...@@ -97,6 +101,10 @@ vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/../java2d/pipe
vpath %.cpp $(SHARE_SRC)/native/$(PKGDIR)/image vpath %.cpp $(SHARE_SRC)/native/$(PKGDIR)/image
vpath %.c $(PLATFORM_SRC)/native/$(PKGDIR)/robot_child vpath %.c $(PLATFORM_SRC)/native/$(PKGDIR)/robot_child
ifeq ($(PLATFORM), macosx)
vpath %.m $(call NativeSrcDirList,,native/sun/font)
endif # PLATFORM
# #
# Libraries to link in. # Libraries to link in.
# #
...@@ -192,13 +200,21 @@ CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR)/debug \ ...@@ -192,13 +200,21 @@ CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR)/debug \
$(EVENT_MODEL) $(EVENT_MODEL)
ifeq ($(PLATFORM), macosx) ifeq ($(PLATFORM), macosx)
CPPFLAGS += -I$(CUPS_HEADERS_PATH) CPPFLAGS += -I$(CUPS_HEADERS_PATH) \
$(call NativeSrcDirList,-I,native/sun/awt) \
$(call NativeSrcDirList,-I,native/sun/font)
ifndef HEADLESS ifndef HEADLESS
CPPFLAGS += -I$(MOTIF_DIR)/include \ CPPFLAGS += -I$(MOTIF_DIR)/include \
-I$(OPENWIN_HOME)/include -I$(OPENWIN_HOME)/include
LDFLAGS += -L$(MOTIF_LIB) -L$(OPENWIN_LIB) LDFLAGS += -L$(MOTIF_LIB) -L$(OPENWIN_LIB)
else
LDFLAGS += -framework Accelerate \
-framework ApplicationServices \
-framework Cocoa \
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport
endif # !HEADLESS endif # !HEADLESS
endif # PLATFORM endif # PLATFORM
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
# (2)Added 2 new codepoints (KS X 1001:1998) # (2)Added 2 new codepoints (KS X 1001:1998)
# 0xA2E6 0x20AC # EURO Sign # 0xA2E6 0x20AC # EURO Sign
# 0xA2E7 0x00AE # Registered Sign # 0xA2E7 0x00AE # Registered Sign
# (3) KS X 1001:2002
# 0xA2E8 0x327E # CIRCLED KOREAN CHARACTER JUEUI (Postal Code Mark)
# #
0x00 0x0000 0x00 0x0000
0x01 0x0001 0x01 0x0001
...@@ -295,6 +297,7 @@ ...@@ -295,6 +297,7 @@
# #
0xA2E6 0x20AC # EURO Sign 0xA2E6 0x20AC # EURO Sign
0xA2E7 0x00AE # Registered Sign 0xA2E7 0x00AE # Registered Sign
0xA2E8 0x327E # CIRCLED KOREAN CHARACTER JUEUI
# #
0xA2E0 0x2116 # NUMERO SIGN 0xA2E0 0x2116 # NUMERO SIGN
0xA2E1 0x33C7 # SQUARE CO 0xA2E1 0x33C7 # SQUARE CO
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
package build.tools.generatebreakiteratordata; package build.tools.generatebreakiteratordata;
import java.util.Arrays;
import java.util.Hashtable; import java.util.Hashtable;
/** /**
...@@ -701,7 +702,14 @@ class CharSet { ...@@ -701,7 +702,14 @@ class CharSet {
* the exact same characters as this one * the exact same characters as this one
*/ */
public boolean equals(Object that) { public boolean equals(Object that) {
return (that instanceof CharSet) && chars.equals(((CharSet)that).chars); return (that instanceof CharSet) && Arrays.equals(chars, ((CharSet)that).chars);
}
/**
* Returns the hash code for this set of characters
*/
public int hashCode() {
return Arrays.hashCode(chars);
} }
/** /**
......
...@@ -342,7 +342,7 @@ $(eval $(call SetupJavaCompilation,BUILD_JOBJC,\ ...@@ -342,7 +342,7 @@ $(eval $(call SetupJavaCompilation,BUILD_JOBJC,\
DISABLE_SJAVAC:=true,\ DISABLE_SJAVAC:=true,\
SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \ SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \ $(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
$(JDK_OUTPUTDIR)/gensrc, \ $(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
INCLUDES := com/apple/jobjc,\ INCLUDES := com/apple/jobjc,\
EXCLUDES := tests/java/com/apple/jobjc,\ EXCLUDES := tests/java/com/apple/jobjc,\
BIN:=$(JDK_OUTPUTDIR)/jobjc_classes,\ BIN:=$(JDK_OUTPUTDIR)/jobjc_classes,\
...@@ -355,7 +355,7 @@ $(eval $(call SetupJavaCompilation,BUILD_JOBJC_HEADERS,\ ...@@ -355,7 +355,7 @@ $(eval $(call SetupJavaCompilation,BUILD_JOBJC_HEADERS,\
SETUP:=GENERATE_JDKBYTECODE,\ SETUP:=GENERATE_JDKBYTECODE,\
SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \ SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \ $(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
$(JDK_OUTPUTDIR)/gensrc, \ $(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
INCLUDES := com/apple/jobjc,\ INCLUDES := com/apple/jobjc,\
EXCLUDES := tests/java/com/apple/jobjc,\ EXCLUDES := tests/java/com/apple/jobjc,\
BIN:=$(JDK_OUTPUTDIR)/jobjc_classes_headers,\ BIN:=$(JDK_OUTPUTDIR)/jobjc_classes_headers,\
......
...@@ -2314,6 +2314,10 @@ LIBAWT_HEADLESS_DIRS:=$(JDK_TOPDIR)/src/share/native/sun/font \ ...@@ -2314,6 +2314,10 @@ LIBAWT_HEADLESS_DIRS:=$(JDK_TOPDIR)/src/share/native/sun/font \
$(JDK_TOPDIR)/src/solaris/native/sun/java2d/opengl \ $(JDK_TOPDIR)/src/solaris/native/sun/java2d/opengl \
$(JDK_TOPDIR)/src/solaris/native/sun/java2d/x11 $(JDK_TOPDIR)/src/solaris/native/sun/java2d/x11
ifeq ($(OPENJDK_TARGET_OS),macosx)
LIBAWT_HEADLESS_DIRS+=$(JDK_TOPDIR)/src/macosx/native/sun/font
endif
LIBAWT_HEADLESS_CFLAGS:=-DHEADLESS=true \ LIBAWT_HEADLESS_CFLAGS:=-DHEADLESS=true \
-DX11_PATH=\"$(X11_PATH)\" -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \ -DX11_PATH=\"$(X11_PATH)\" -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \
$(CUPS_CFLAGS) \ $(CUPS_CFLAGS) \
...@@ -2328,6 +2332,12 @@ LIBAWT_HEADLESS_CFLAGS:=-DHEADLESS=true \ ...@@ -2328,6 +2332,12 @@ LIBAWT_HEADLESS_CFLAGS:=-DHEADLESS=true \
-I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/jdga \ -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/jdga \
$(foreach dir,$(LIBAWT_HEADLESS_DIRS),-I$(dir)) $(foreach dir,$(LIBAWT_HEADLESS_DIRS),-I$(dir))
ifeq ($(OPENJDK_TARGET_OS),macosx)
LIBAWT_HEADLESS_CFLAGS+=\
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-F/System/Library/Frameworks/ApplicationServices.framework/Frameworks
endif
LIBAWT_HEADLESS_FILES:=\ LIBAWT_HEADLESS_FILES:=\
awt_Font.c \ awt_Font.c \
HeadlessToolkit.c \ HeadlessToolkit.c \
...@@ -2356,6 +2366,16 @@ LIBAWT_HEADLESS_FILES:=\ ...@@ -2356,6 +2366,16 @@ LIBAWT_HEADLESS_FILES:=\
AccelGlyphCache.c \ AccelGlyphCache.c \
CUPSfuncs.c CUPSfuncs.c
ifeq ($(OPENJDK_TARGET_OS),macosx)
LIBAWT_HEADLESS_FILES+=\
AWTFont.m \
AWTStrike.m \
CCharToGlyphMapper.m \
CGGlyphImages.m \
CGGlyphOutlines.m \
CoreTextSupport.m
endif
LIBAWT_HEADLESS_REORDER:= LIBAWT_HEADLESS_REORDER:=
ifeq ($(OPENJDK_TARGET_OS), solaris) ifeq ($(OPENJDK_TARGET_OS), solaris)
ifneq ($(OPENJDK_TARGET_CPU), x86_64) ifneq ($(OPENJDK_TARGET_CPU), x86_64)
...@@ -2382,7 +2402,13 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_HEADLESS,\ ...@@ -2382,7 +2402,13 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_HEADLESS,\
REORDER:=$(LIBAWT_HEADLESS_REORDER), \ REORDER:=$(LIBAWT_HEADLESS_REORDER), \
LDFLAGS_SUFFIX_linux:=-ljvm -lawt -lm $(LIBDL) -ljava,\ LDFLAGS_SUFFIX_linux:=-ljvm -lawt -lm $(LIBDL) -ljava,\
LDFLAGS_SUFFIX_solaris:=$(LIBDL) -ljvm -lawt -lm -ljava $(LIBCXX) -lc,\ LDFLAGS_SUFFIX_solaris:=$(LIBDL) -ljvm -lawt -lm -ljava $(LIBCXX) -lc,\
LDFLAGS_SUFFIX_macosx:=-ljvm $(LIBCXX) -lawt $(LIBDL) -ljava,\ LDFLAGS_SUFFIX_macosx:=-ljvm $(LIBCXX) -lawt $(LIBDL) -ljava \
-framework Accelerate \
-framework ApplicationServices \
-framework Cocoa \
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport,\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libawt_headless,\ OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libawt_headless,\
DEBUG_SYMBOLS:=$(DEBUG_ALL_BINARIES))) DEBUG_SYMBOLS:=$(DEBUG_ALL_BINARIES)))
......
...@@ -69,6 +69,9 @@ define typesAndBits ...@@ -69,6 +69,9 @@ define typesAndBits
$1_fulltype := character $1_fulltype := character
$1_Fulltype := Character $1_Fulltype := Character
$1_category := integralType $1_category := integralType
$1_streams := streamableType
$1_streamtype := int
$1_Streamtype := Int
$1_LBPV := 1 $1_LBPV := 1
endif endif
...@@ -97,7 +100,7 @@ define typesAndBits ...@@ -97,7 +100,7 @@ define typesAndBits
$1_Type := Long $1_Type := Long
$1_fulltype := long $1_fulltype := long
$1_Fulltype := Long $1_Fulltype := Long
$1_category := integralType $1_category := integralType
$1_LBPV := 3 $1_LBPV := 3
endif endif
...@@ -231,10 +234,13 @@ $$($1_DST) : $$($1_DEP) $(GENSRC_BUFFER_DST)/_the.buffer.dir ...@@ -231,10 +234,13 @@ $$($1_DST) : $$($1_DEP) $(GENSRC_BUFFER_DST)/_the.buffer.dir
$(TOOL_SPP) < $$($1_SRC) > $$($1_OUT).tmp \ $(TOOL_SPP) < $$($1_SRC) > $$($1_OUT).tmp \
-K$$($1_type) \ -K$$($1_type) \
-K$$($1_category) \ -K$$($1_category) \
-K$$($1_streams) \
-Dtype=$$($1_type) \ -Dtype=$$($1_type) \
-DType=$$($1_Type) \ -DType=$$($1_Type) \
-Dfulltype=$$($1_fulltype) \ -Dfulltype=$$($1_fulltype) \
-DFulltype=$$($1_Fulltype) \ -DFulltype=$$($1_Fulltype) \
-Dstreamtype=$$($1_streamtype) \
-DStreamtype=$$($1_Streamtype) \
-Dx=$$($1_x) \ -Dx=$$($1_x) \
-Dmemtype=$$($1_memtype) \ -Dmemtype=$$($1_memtype) \
-DMemtype=$$($1_Memtype) \ -DMemtype=$$($1_Memtype) \
......
# #
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -39,6 +39,10 @@ SUNWprivate_1.1 { ...@@ -39,6 +39,10 @@ SUNWprivate_1.1 {
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize; Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
Java_com_sun_management_UnixOperatingSystem_initialize; Java_com_sun_management_UnixOperatingSystem_initialize;
Java_sun_management_ClassLoadingImpl_setVerboseClass; Java_sun_management_ClassLoadingImpl_setVerboseClass;
Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand;
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands;
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo;
Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled;
Java_sun_management_FileSystemImpl_isAccessUserOnly0; Java_sun_management_FileSystemImpl_isAccessUserOnly0;
Java_sun_management_Flag_getAllFlagNames; Java_sun_management_Flag_getAllFlagNames;
Java_sun_management_Flag_getFlags; Java_sun_management_Flag_getFlags;
......
...@@ -44,7 +44,6 @@ ...@@ -44,7 +44,6 @@
#include <Cocoa/Cocoa.h> #include <Cocoa/Cocoa.h>
#include <objc/objc-runtime.h> #include <objc/objc-runtime.h>
#include <objc/objc-auto.h> #include <objc/objc-auto.h>
#include <dispatch/dispatch.h>
#include <errno.h> #include <errno.h>
#include <spawn.h> #include <spawn.h>
...@@ -1001,6 +1000,32 @@ SetXStartOnFirstThreadArg() ...@@ -1001,6 +1000,32 @@ SetXStartOnFirstThreadArg()
setenv(envVar, "1", 1); setenv(envVar, "1", 1);
} }
/* This class is made for performSelectorOnMainThread when java main
* should be launched on main thread.
* We cannot use dispatch_sync here, because it blocks the main dispatch queue
* which is used inside Cocoa
*/
@interface JavaLaunchHelper : NSObject {
int _returnValue;
}
- (void) launchJava:(NSValue*)argsValue;
- (int) getReturnValue;
@end
@implementation JavaLaunchHelper
- (void) launchJava:(NSValue*)argsValue
{
_returnValue = JavaMain([argsValue pointerValue]);
}
- (int) getReturnValue
{
return _returnValue;
}
@end
// MacOSX we may continue in the same thread // MacOSX we may continue in the same thread
int int
JVMInit(InvocationFunctions* ifn, jlong threadStackSize, JVMInit(InvocationFunctions* ifn, jlong threadStackSize,
...@@ -1010,16 +1035,22 @@ JVMInit(InvocationFunctions* ifn, jlong threadStackSize, ...@@ -1010,16 +1035,22 @@ JVMInit(InvocationFunctions* ifn, jlong threadStackSize,
JLI_TraceLauncher("In same thread\n"); JLI_TraceLauncher("In same thread\n");
// need to block this thread against the main thread // need to block this thread against the main thread
// so signals get caught correctly // so signals get caught correctly
__block int rslt; JavaMainArgs args;
dispatch_sync(dispatch_get_main_queue(), ^(void) { args.argc = argc;
JavaMainArgs args; args.argv = argv;
args.argc = argc; args.mode = mode;
args.argv = argv; args.what = what;
args.mode = mode; args.ifn = *ifn;
args.what = what; int rslt;
args.ifn = *ifn; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
rslt = JavaMain((void*)&args); {
}); JavaLaunchHelper* launcher = [[[JavaLaunchHelper alloc] init] autorelease];
[launcher performSelectorOnMainThread:@selector(launchJava:)
withObject:[NSValue valueWithPointer:(void*)&args]
waitUntilDone:YES];
rslt = [launcher getReturnValue];
}
[pool drain];
return rslt; return rslt;
} else { } else {
return ContinueInNewThread(ifn, threadStackSize, argc, argv, mode, what, ret); return ContinueInNewThread(ifn, threadStackSize, argc, argv, mode, what, ret);
......
...@@ -38,7 +38,7 @@ final class CDropTargetContextPeer extends SunDropTargetContextPeer { ...@@ -38,7 +38,7 @@ final class CDropTargetContextPeer extends SunDropTargetContextPeer {
private long fNativeDropTransfer = 0; private long fNativeDropTransfer = 0;
private long fNativeDataAvailable = 0; private long fNativeDataAvailable = 0;
private Object fNativeData = null; private Object fNativeData = null;
private boolean insideTarget = false; private boolean insideTarget = true;
Object awtLockAccess = new Object(); Object awtLockAccess = new Object();
......
...@@ -115,6 +115,8 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -115,6 +115,8 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
static final int RESIZABLE = 1 << 9; // both a style bit and prop bit static final int RESIZABLE = 1 << 9; // both a style bit and prop bit
static final int NONACTIVATING = 1 << 24; static final int NONACTIVATING = 1 << 24;
static final int IS_DIALOG = 1 << 25;
static final int IS_MODAL = 1 << 26;
static final int _STYLE_PROP_BITMASK = DECORATED | TEXTURED | UNIFIED | UTILITY | HUD | SHEET | CLOSEABLE | MINIMIZABLE | RESIZABLE; static final int _STYLE_PROP_BITMASK = DECORATED | TEXTURED | UNIFIED | UTILITY | HUD | SHEET | CLOSEABLE | MINIMIZABLE | RESIZABLE;
...@@ -376,6 +378,13 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -376,6 +378,13 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
} }
} }
if (isDialog) {
styleBits = SET(styleBits, IS_DIALOG, true);
if (((Dialog) target).isModal()) {
styleBits = SET(styleBits, IS_MODAL, true);
}
}
peer.setTextured(IS(TEXTURED, styleBits)); peer.setTextured(IS(TEXTURED, styleBits));
return styleBits; return styleBits;
......
...@@ -36,6 +36,7 @@ import java.security.PrivilegedAction; ...@@ -36,6 +36,7 @@ import java.security.PrivilegedAction;
import javax.print.*; import javax.print.*;
import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet; import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.PageRanges;
import sun.java2d.*; import sun.java2d.*;
import sun.print.*; import sun.print.*;
...@@ -173,6 +174,19 @@ public class CPrinterJob extends RasterPrinterJob { ...@@ -173,6 +174,19 @@ public class CPrinterJob extends RasterPrinterJob {
if (nsPrintInfo != null) { if (nsPrintInfo != null) {
fNSPrintInfo = nsPrintInfo.getValue(); fNSPrintInfo = nsPrintInfo.getValue();
} }
PageRanges pageRangesAttr = (PageRanges)attributes.get(PageRanges.class);
if (isSupportedValue(pageRangesAttr, attributes)) {
SunPageSelection rangeSelect = (SunPageSelection)attributes.get(SunPageSelection.class);
// If rangeSelect is not null, we are using AWT's print dialog that has
// All, Selection, and Range radio buttons
if (rangeSelect == null || rangeSelect == SunPageSelection.RANGE) {
int[][] range = pageRangesAttr.getMembers();
// setPageRange will set firstPage and lastPage as called in getFirstPage
// and getLastPage
setPageRange(range[0][0] - 1, range[0][1] - 1);
}
}
} }
volatile boolean onEventThread; volatile boolean onEventThread;
...@@ -225,7 +239,6 @@ public class CPrinterJob extends RasterPrinterJob { ...@@ -225,7 +239,6 @@ public class CPrinterJob extends RasterPrinterJob {
* the end of the document. Note that firstPage * the end of the document. Note that firstPage
* and lastPage are 0 based page indices. * and lastPage are 0 based page indices.
*/ */
int numPages = mDocument.getNumberOfPages();
int firstPage = getFirstPage(); int firstPage = getFirstPage();
int lastPage = getLastPage(); int lastPage = getLastPage();
...@@ -242,42 +255,53 @@ public class CPrinterJob extends RasterPrinterJob { ...@@ -242,42 +255,53 @@ public class CPrinterJob extends RasterPrinterJob {
userCancelled = false; userCancelled = false;
} }
if (EventQueue.isDispatchThread()) { //Add support for PageRange
// This is an AWT EventQueue, and this print rendering loop needs to block it. PageRanges pr = (attributes == null) ? null
: (PageRanges)attributes.get(PageRanges.class);
int[][] prMembers = (pr == null) ? new int[0][0] : pr.getMembers();
int loopi = 0;
do {
if (EventQueue.isDispatchThread()) {
// This is an AWT EventQueue, and this print rendering loop needs to block it.
onEventThread = true;
printingLoop = AccessController.doPrivileged(new PrivilegedAction<SecondaryLoop>() {
@Override
public SecondaryLoop run() {
return Toolkit.getDefaultToolkit()
.getSystemEventQueue()
.createSecondaryLoop();
}
});
onEventThread = true; try {
// Fire off the print rendering loop on the AppKit thread, and don't have
printingLoop = AccessController.doPrivileged(new PrivilegedAction<SecondaryLoop>() { // it wait and block this thread.
@Override if (printLoop(false, firstPage, lastPage)) {
public SecondaryLoop run() { // Start a secondary loop on EDT until printing operation is finished or cancelled
return Toolkit.getDefaultToolkit() printingLoop.enter();
.getSystemEventQueue() }
.createSecondaryLoop(); } catch (Exception e) {
e.printStackTrace();
} }
}); } else {
// Fire off the print rendering loop on the AppKit, and block this thread
// until it is done.
// But don't actually block... we need to come back here!
onEventThread = false;
try { try {
// Fire off the print rendering loop on the AppKit thread, and don't have printLoop(true, firstPage, lastPage);
// it wait and block this thread. } catch (Exception e) {
if (printLoop(false, firstPage, lastPage)) { e.printStackTrace();
// Start a secondary loop on EDT until printing operation is finished or cancelled
printingLoop.enter();
} }
} catch (Exception e) {
e.printStackTrace();
} }
} else { if (++loopi < prMembers.length) {
// Fire off the print rendering loop on the AppKit, and block this thread firstPage = prMembers[loopi][0]-1;
// until it is done. lastPage = prMembers[loopi][1] -1;
// But don't actually block... we need to come back here!
onEventThread = false;
try {
printLoop(true, firstPage, lastPage);
} catch (Exception e) {
e.printStackTrace();
} }
} } while (loopi < prMembers.length);
} finally { } finally {
synchronized (this) { synchronized (this) {
// NOTE: Native code shouldn't allow exceptions out while // NOTE: Native code shouldn't allow exceptions out while
......
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -536,8 +536,12 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -536,8 +536,12 @@ AWT_ASSERT_APPKIT_THREAD;
- (void) windowDidBecomeKey: (NSNotification *) notification { - (void) windowDidBecomeKey: (NSNotification *) notification {
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;
[AWTToolkit eventCountPlusPlus]; [AWTToolkit eventCountPlusPlus];
[CMenuBar activate:self.javaMenuBar modallyDisabled:NO];
AWTWindow *opposite = [AWTWindow lastKeyWindow]; AWTWindow *opposite = [AWTWindow lastKeyWindow];
if (!IS(self.styleBits, IS_DIALOG)) {
[CMenuBar activate:self.javaMenuBar modallyDisabled:NO];
} else if (IS(self.styleBits, IS_MODAL)) {
[CMenuBar activate:opposite->javaMenuBar modallyDisabled:YES];
}
[AWTWindow setLastKeyWindow:nil]; [AWTWindow setLastKeyWindow:nil];
[self _deliverWindowFocusEvent:YES oppositeWindow: opposite]; [self _deliverWindowFocusEvent:YES oppositeWindow: opposite];
......
...@@ -395,6 +395,7 @@ JNF_COCOA_EXIT(env); ...@@ -395,6 +395,7 @@ JNF_COCOA_EXIT(env);
#pragma mark --- Miscellaneous JNI --- #pragma mark --- Miscellaneous JNI ---
#ifndef HEADLESS
/* /*
* Class: sun_awt_PlatformFont * Class: sun_awt_PlatformFont
* Method: initIDs * Method: initIDs
...@@ -416,3 +417,4 @@ Java_sun_awt_FontDescriptor_initIDs ...@@ -416,3 +417,4 @@ Java_sun_awt_FontDescriptor_initIDs
(JNIEnv *env, jclass cls) (JNIEnv *env, jclass cls)
{ {
} }
#endif
/* /*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
*/ */
package com.sun.beans.finder; package com.sun.beans.finder;
import java.lang.reflect.Executable;
import java.lang.reflect.Modifier;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -37,7 +40,7 @@ import java.util.Map; ...@@ -37,7 +40,7 @@ import java.util.Map;
* *
* @author Sergey A. Malenkov * @author Sergey A. Malenkov
*/ */
abstract class AbstractFinder<T> { abstract class AbstractFinder<T extends Executable> {
private final Class<?>[] args; private final Class<?>[] args;
/** /**
...@@ -52,27 +55,6 @@ abstract class AbstractFinder<T> { ...@@ -52,27 +55,6 @@ abstract class AbstractFinder<T> {
this.args = args; this.args = args;
} }
/**
* Returns an array of {@code Class} objects
* that represent the formal parameter types of the method.
* Returns an empty array if the method takes no parameters.
*
* @param method the object that represents method
* @return the parameter types of the method
*/
protected abstract Class<?>[] getParameters(T method);
/**
* Returns {@code true} if and only if the method
* was declared to take a variable number of arguments.
*
* @param method the object that represents method
* @return {@code true} if the method was declared
* to take a variable number of arguments;
* {@code false} otherwise
*/
protected abstract boolean isVarArgs(T method);
/** /**
* Checks validness of the method. * Checks validness of the method.
* At least the valid method should be public. * At least the valid method should be public.
...@@ -81,7 +63,9 @@ abstract class AbstractFinder<T> { ...@@ -81,7 +63,9 @@ abstract class AbstractFinder<T> {
* @return {@code true} if the method is valid, * @return {@code true} if the method is valid,
* {@code false} otherwise * {@code false} otherwise
*/ */
protected abstract boolean isValid(T method); protected boolean isValid(T method) {
return Modifier.isPublic(method.getModifiers());
}
/** /**
* Performs a search in the {@code methods} array. * Performs a search in the {@code methods} array.
...@@ -109,7 +93,7 @@ abstract class AbstractFinder<T> { ...@@ -109,7 +93,7 @@ abstract class AbstractFinder<T> {
for (T newMethod : methods) { for (T newMethod : methods) {
if (isValid(newMethod)) { if (isValid(newMethod)) {
Class<?>[] newParams = getParameters(newMethod); Class<?>[] newParams = newMethod.getParameterTypes();
if (newParams.length == this.args.length) { if (newParams.length == this.args.length) {
PrimitiveWrapperMap.replacePrimitivesWithWrappers(newParams); PrimitiveWrapperMap.replacePrimitivesWithWrappers(newParams);
if (isAssignable(newParams, this.args)) { if (isAssignable(newParams, this.args)) {
...@@ -120,6 +104,11 @@ abstract class AbstractFinder<T> { ...@@ -120,6 +104,11 @@ abstract class AbstractFinder<T> {
boolean useNew = isAssignable(oldParams, newParams); boolean useNew = isAssignable(oldParams, newParams);
boolean useOld = isAssignable(newParams, oldParams); boolean useOld = isAssignable(newParams, oldParams);
if (useOld && useNew) {
// only if parameters are equal
useNew = !newMethod.isSynthetic();
useOld = !oldMethod.isSynthetic();
}
if (useOld == useNew) { if (useOld == useNew) {
ambiguous = true; ambiguous = true;
} else if (useNew) { } else if (useNew) {
...@@ -130,7 +119,7 @@ abstract class AbstractFinder<T> { ...@@ -130,7 +119,7 @@ abstract class AbstractFinder<T> {
} }
} }
} }
if (isVarArgs(newMethod)) { if (newMethod.isVarArgs()) {
int length = newParams.length - 1; int length = newParams.length - 1;
if (length <= this.args.length) { if (length <= this.args.length) {
Class<?>[] array = new Class<?>[this.args.length]; Class<?>[] array = new Class<?>[this.args.length];
...@@ -160,6 +149,11 @@ abstract class AbstractFinder<T> { ...@@ -160,6 +149,11 @@ abstract class AbstractFinder<T> {
boolean useNew = isAssignable(oldParams, newParams); boolean useNew = isAssignable(oldParams, newParams);
boolean useOld = isAssignable(newParams, oldParams); boolean useOld = isAssignable(newParams, oldParams);
if (useOld && useNew) {
// only if parameters are equal
useNew = !newMethod.isSynthetic();
useOld = !oldMethod.isSynthetic();
}
if (useOld == useNew) { if (useOld == useNew) {
if (oldParams == map.get(oldMethod)) { if (oldParams == map.get(oldMethod)) {
ambiguous = true; ambiguous = true;
......
/* /*
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -86,44 +86,4 @@ public final class ConstructorFinder extends AbstractFinder<Constructor<?>> { ...@@ -86,44 +86,4 @@ public final class ConstructorFinder extends AbstractFinder<Constructor<?>> {
private ConstructorFinder(Class<?>[] args) { private ConstructorFinder(Class<?>[] args) {
super(args); super(args);
} }
/**
* Returns an array of {@code Class} objects
* that represent the formal parameter types of the constructor.
* Returns an empty array if the constructor takes no parameters.
*
* @param constructor the object that represents constructor
* @return the parameter types of the constructor
*/
@Override
protected Class<?>[] getParameters(Constructor<?> constructor) {
return constructor.getParameterTypes();
}
/**
* Returns {@code true} if and only if the constructor
* was declared to take a variable number of arguments.
*
* @param constructor the object that represents constructor
* @return {@code true} if the constructor was declared
* to take a variable number of arguments;
* {@code false} otherwise
*/
@Override
protected boolean isVarArgs(Constructor<?> constructor) {
return constructor.isVarArgs();
}
/**
* Checks validness of the constructor.
* The valid constructor should be public.
*
* @param constructor the object that represents constructor
* @return {@code true} if the constructor is valid,
* {@code false} otherwise
*/
@Override
protected boolean isValid(Constructor<?> constructor) {
return Modifier.isPublic(constructor.getModifiers());
}
} }
/* /*
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -195,33 +195,6 @@ public final class MethodFinder extends AbstractFinder<Method> { ...@@ -195,33 +195,6 @@ public final class MethodFinder extends AbstractFinder<Method> {
this.name = name; this.name = name;
} }
/**
* Returns an array of {@code Class} objects
* that represent the formal parameter types of the method.
* Returns an empty array if the method takes no parameters.
*
* @param method the object that represents method
* @return the parameter types of the method
*/
@Override
protected Class<?>[] getParameters(Method method) {
return method.getParameterTypes();
}
/**
* Returns {@code true} if and only if the method
* was declared to take a variable number of arguments.
*
* @param method the object that represents method
* @return {@code true} if the method was declared
* to take a variable number of arguments;
* {@code false} otherwise
*/
@Override
protected boolean isVarArgs(Method method) {
return method.isVarArgs();
}
/** /**
* Checks validness of the method. * Checks validness of the method.
* The valid method should be public and * The valid method should be public and
...@@ -233,6 +206,6 @@ public final class MethodFinder extends AbstractFinder<Method> { ...@@ -233,6 +206,6 @@ public final class MethodFinder extends AbstractFinder<Method> {
*/ */
@Override @Override
protected boolean isValid(Method method) { protected boolean isValid(Method method) {
return !method.isBridge() && Modifier.isPublic(method.getModifiers()) && method.getName().equals(this.name); return super.isValid(method) && method.getName().equals(this.name);
} }
} }
/* /*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -403,8 +403,9 @@ extends KeyAgreementSpi { ...@@ -403,8 +403,9 @@ extends KeyAgreementSpi {
} }
return skey; return skey;
} else if (algorithm.equals("TlsPremasterSecret")) { } else if (algorithm.equals("TlsPremasterSecret")) {
// return entire secret // remove leading zero bytes per RFC 5246 Section 8.1.2
return new SecretKeySpec(secret, "TlsPremasterSecret"); return new SecretKeySpec(
KeyUtil.trimZeroes(secret), "TlsPremasterSecret");
} else { } else {
throw new NoSuchAlgorithmException("Unsupported secret key " throw new NoSuchAlgorithmException("Unsupported secret key "
+ "algorithm: "+ algorithm); + "algorithm: "+ algorithm);
......
...@@ -86,12 +86,13 @@ public final class HmacPKCS12PBESHA1 extends HmacCore { ...@@ -86,12 +86,13 @@ public final class HmacPKCS12PBESHA1 extends HmacCore {
throw new InvalidKeyException("SecretKey of PBE type required"); throw new InvalidKeyException("SecretKey of PBE type required");
} }
if (params == null) { if (params == null) {
// generate default for salt and iteration count if necessary // should not auto-generate default values since current
if (salt == null) { // javax.crypto.Mac api does not have any method for caller to
salt = new byte[20]; // retrieve the generated defaults.
SunJCE.getRandom().nextBytes(salt); if ((salt == null) || (iCount == 0)) {
throw new InvalidAlgorithmParameterException
("PBEParameterSpec required for salt and iteration count");
} }
if (iCount == 0) iCount = 100;
} else if (!(params instanceof PBEParameterSpec)) { } else if (!(params instanceof PBEParameterSpec)) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("PBEParameterSpec type required"); ("PBEParameterSpec type required");
......
...@@ -42,12 +42,10 @@ import java.security.spec.*; ...@@ -42,12 +42,10 @@ import java.security.spec.*;
*/ */
abstract class PBMAC1Core extends HmacCore { abstract class PBMAC1Core extends HmacCore {
private static final int DEFAULT_SALT_LENGTH = 20; // NOTE: this class inherits the Cloneable interface from HmacCore
private static final int DEFAULT_COUNT = 4096; // Need to override clone() if mutable fields are added.
private final String kdfAlgo; private final String kdfAlgo;
private final String hashAlgo; private final String hashAlgo;
private final PBKDF2Core kdf;
private final int blockLength; // in octets private final int blockLength; // in octets
/** /**
...@@ -56,13 +54,15 @@ abstract class PBMAC1Core extends HmacCore { ...@@ -56,13 +54,15 @@ abstract class PBMAC1Core extends HmacCore {
*/ */
PBMAC1Core(String kdfAlgo, String hashAlgo, int blockLength) PBMAC1Core(String kdfAlgo, String hashAlgo, int blockLength)
throws NoSuchAlgorithmException { throws NoSuchAlgorithmException {
super(hashAlgo, blockLength); super(hashAlgo, blockLength);
this.kdfAlgo = kdfAlgo; this.kdfAlgo = kdfAlgo;
this.hashAlgo = hashAlgo; this.hashAlgo = hashAlgo;
this.blockLength = blockLength; this.blockLength = blockLength;
}
switch(kdfAlgo) { private static PBKDF2Core getKDFImpl(String algo) {
PBKDF2Core kdf = null;
switch(algo) {
case "HmacSHA1": case "HmacSHA1":
kdf = new PBKDF2Core.HmacSHA1(); kdf = new PBKDF2Core.HmacSHA1();
break; break;
...@@ -79,9 +79,10 @@ abstract class PBMAC1Core extends HmacCore { ...@@ -79,9 +79,10 @@ abstract class PBMAC1Core extends HmacCore {
kdf = new PBKDF2Core.HmacSHA512(); kdf = new PBKDF2Core.HmacSHA512();
break; break;
default: default:
throw new NoSuchAlgorithmException( throw new ProviderException(
"No MAC implementation for " + kdfAlgo); "No MAC implementation for " + algo);
} }
return kdf;
} }
/** /**
...@@ -120,12 +121,13 @@ abstract class PBMAC1Core extends HmacCore { ...@@ -120,12 +121,13 @@ abstract class PBMAC1Core extends HmacCore {
throw new InvalidKeyException("SecretKey of PBE type required"); throw new InvalidKeyException("SecretKey of PBE type required");
} }
if (params == null) { if (params == null) {
// generate default for salt and iteration count if necessary // should not auto-generate default values since current
if (salt == null) { // javax.crypto.Mac api does not have any method for caller to
salt = new byte[DEFAULT_SALT_LENGTH]; // retrieve the generated defaults.
SunJCE.getRandom().nextBytes(salt); if ((salt == null) || (iCount == 0)) {
throw new InvalidAlgorithmParameterException
("PBEParameterSpec required for salt and iteration count");
} }
if (iCount == 0) iCount = DEFAULT_COUNT;
} else if (!(params instanceof PBEParameterSpec)) { } else if (!(params instanceof PBEParameterSpec)) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("PBEParameterSpec type required"); ("PBEParameterSpec type required");
...@@ -168,7 +170,7 @@ abstract class PBMAC1Core extends HmacCore { ...@@ -168,7 +170,7 @@ abstract class PBMAC1Core extends HmacCore {
java.util.Arrays.fill(passwdChars, ' '); java.util.Arrays.fill(passwdChars, ' ');
SecretKey s = null; SecretKey s = null;
PBKDF2Core kdf = getKDFImpl(kdfAlgo);
try { try {
s = kdf.engineGenerateSecret(pbeSpec); s = kdf.engineGenerateSecret(pbeSpec);
......
...@@ -731,10 +731,11 @@ public final class SunJCE extends Provider { ...@@ -731,10 +731,11 @@ public final class SunJCE extends Provider {
put("Mac.HmacSHA384 SupportedKeyFormats", "RAW"); put("Mac.HmacSHA384 SupportedKeyFormats", "RAW");
put("Mac.HmacSHA512 SupportedKeyFormats", "RAW"); put("Mac.HmacSHA512 SupportedKeyFormats", "RAW");
put("Mac.HmacPBESHA1 SupportedKeyFormats", "RAW"); put("Mac.HmacPBESHA1 SupportedKeyFormats", "RAW");
put("Mac.HmacPBESHA224 SupportedKeyFormats", "RAW"); put("Mac.PBEWithHmacSHA1 SupportedKeyFormatS", "RAW");
put("Mac.HmacPBESHA256 SupportedKeyFormats", "RAW"); put("Mac.PBEWithHmacSHA224 SupportedKeyFormats", "RAW");
put("Mac.HmacPBESHA384 SupportedKeyFormats", "RAW"); put("Mac.PBEWithHmacSHA256 SupportedKeyFormats", "RAW");
put("Mac.HmacPBESHA512 SupportedKeyFormats", "RAW"); put("Mac.PBEWithHmacSHA384 SupportedKeyFormats", "RAW");
put("Mac.PBEWithHmacSHA512 SupportedKeyFormats", "RAW");
put("Mac.SslMacMD5 SupportedKeyFormats", "RAW"); put("Mac.SslMacMD5 SupportedKeyFormats", "RAW");
put("Mac.SslMacSHA1 SupportedKeyFormats", "RAW"); put("Mac.SslMacSHA1 SupportedKeyFormats", "RAW");
......
/* /*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -90,14 +90,16 @@ public class Continuation extends ResolveResult { ...@@ -90,14 +90,16 @@ public class Continuation extends ResolveResult {
* Constructs a new instance of Continuation. * Constructs a new instance of Continuation.
* @param top The name of the object that is to be resolved/operated upon. * @param top The name of the object that is to be resolved/operated upon.
* This becomes the Continuation's 'starter' and is used to * This becomes the Continuation's 'starter' and is used to
* calculate the "resolved name" when filling in a NamingException. * calculate the "resolved name" when filling in a NamingException.
* @param environment The environment used by the caller. It is used * @param environment The environment used by the caller. It is used
* when setting the "environment" of a CannotProceedException. * when setting the "environment" of a CannotProceedException.
*/ */
@SuppressWarnings("unchecked") // For Hashtable clone: environment.clone()
public Continuation(Name top, Hashtable<?,?> environment) { public Continuation(Name top, Hashtable<?,?> environment) {
super(); super();
starter = top; starter = top;
this.environment = environment; this.environment = (Hashtable<?,?>)
((environment == null) ? null : environment.clone());
} }
/** /**
......
/* /*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -69,6 +69,7 @@ final public class LazySearchEnumerationImpl ...@@ -69,6 +69,7 @@ final public class LazySearchEnumerationImpl
} }
} }
@SuppressWarnings("unchecked") // For Hashtable clone: env.clone()
public LazySearchEnumerationImpl(NamingEnumeration<Binding> candidates, public LazySearchEnumerationImpl(NamingEnumeration<Binding> candidates,
AttrFilter filter, SearchControls cons, AttrFilter filter, SearchControls cons,
Context ctx, Hashtable<String, Object> env, boolean useFactory) Context ctx, Hashtable<String, Object> env, boolean useFactory)
...@@ -76,7 +77,8 @@ final public class LazySearchEnumerationImpl ...@@ -76,7 +77,8 @@ final public class LazySearchEnumerationImpl
this.candidates = candidates; this.candidates = candidates;
this.filter = filter; this.filter = filter;
this.env = env; this.env = (Hashtable<String, Object>)
((env == null) ? null : env.clone());
this.context = ctx; this.context = ctx;
this.useFactory = useFactory; this.useFactory = useFactory;
......
...@@ -396,7 +396,7 @@ public class SearchFilter implements AttrFilter { ...@@ -396,7 +396,7 @@ public class SearchFilter implements AttrFilter {
// do we need to begin with the first token? // do we need to begin with the first token?
if(proto.charAt(0) != WILDCARD_TOKEN && if(proto.charAt(0) != WILDCARD_TOKEN &&
!value.toString().toLowerCase(Locale.ENGLISH).startsWith( !value.toLowerCase(Locale.ENGLISH).startsWith(
subStrs.nextToken().toLowerCase(Locale.ENGLISH))) { subStrs.nextToken().toLowerCase(Locale.ENGLISH))) {
if(debug) { if(debug) {
System.out.println("faild initial test"); System.out.println("faild initial test");
......
/* /*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -53,7 +53,8 @@ abstract public class GenericURLContext implements Context { ...@@ -53,7 +53,8 @@ abstract public class GenericURLContext implements Context {
@SuppressWarnings("unchecked") // Expect Hashtable<String, Object> @SuppressWarnings("unchecked") // Expect Hashtable<String, Object>
public GenericURLContext(Hashtable<?,?> env) { public GenericURLContext(Hashtable<?,?> env) {
// context that is not tied to any specific URL // context that is not tied to any specific URL
myEnv = (Hashtable<String, Object>)env; // copied on write myEnv =
(Hashtable<String, Object>)(env == null ? null : env.clone());
} }
public void close() throws NamingException { public void close() throws NamingException {
...@@ -488,22 +489,19 @@ abstract public class GenericURLContext implements Context { ...@@ -488,22 +489,19 @@ abstract public class GenericURLContext implements Context {
return result; return result;
} }
@SuppressWarnings("unchecked") // clone()
public Object removeFromEnvironment(String propName) public Object removeFromEnvironment(String propName)
throws NamingException { throws NamingException {
if (myEnv == null) { if (myEnv == null) {
return null; return null;
} }
myEnv = (Hashtable<String, Object>)myEnv.clone();
return myEnv.remove(propName); return myEnv.remove(propName);
} }
@SuppressWarnings("unchecked") // clone()
public Object addToEnvironment(String propName, Object propVal) public Object addToEnvironment(String propName, Object propVal)
throws NamingException { throws NamingException {
myEnv = (myEnv == null) if (myEnv == null) {
? new Hashtable<String, Object>(11, 0.75f) myEnv = new Hashtable<String, Object>(11, 0.75f);
: (Hashtable<String, Object>)myEnv.clone(); }
return myEnv.put(propName, propVal); return myEnv.put(propName, propVal);
} }
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.management;
import java.lang.management.PlatformManagedObject;
import javax.management.DynamicMBean;
/**
* Management interface for the diagnostic commands for the HotSpot Virtual Machine.
*
* <p>The {code DiagnosticCommandMBean} is registered to the
* {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer
* platform MBeanServer} as are other platform MBeans.
*
* <p>The {@link javax.management.ObjectName ObjectName} for uniquely identifying
* the diagnostic MBean within an MBeanServer is:
* <blockquote>
* {@code com.sun.management:type=DiagnosticCommand}
* </blockquote>
*
* <p>This MBean is a {@link javax.management.DynamicMBean DynamicMBean}
* and also a {@link javax.management.NotificationEmitter}.
* The {@code DiagnosticCommandMBean} is generated at runtime and is subject to
* modifications during the lifetime of the Java virtual machine.
*
* A <em>diagnostic command</em> is represented as an operation of
* the {@code DiagnosticCommandMBean} interface. Each diagnostic command has:
* <ul>
* <li>the diagnostic command name which is the name being referenced in
* the HotSpot Virtual Machine</li>
* <li>the MBean operation name which is the
* {@linkplain javax.management.MBeanOperationInfo#getName() name}
* generated for the diagnostic command operation invocation.
* The MBean operation name is implementation dependent</li>
* </ul>
*
* The recommended way to transform a diagnostic command name into a MBean
* operation name is as follows:
* <ul>
* <li>All characters from the first one to the first dot are set to be
* lower-case characters</li>
* <li>Every dot or underline character is removed and the following
* character is set to be an upper-case character</li>
* <li>All other characters are copied without modification</li>
* </ul>
*
* <p>The diagnostic command name is always provided with the meta-data on the
* operation in a field named {@code dcmd.name} (see below).
*
* <p>A diagnostic command may or may not support options or arguments.
* All the operations return {@code String} and either take
* no parameter for operations that do not support any option or argument,
* or take a {@code String[]} parameter for operations that support at least
* one option or argument.
* Each option or argument must be stored in a single String.
* Options or arguments split across several String instances are not supported.
*
* <p>The distinction between options and arguments: options are identified by
* the option name while arguments are identified by their position in the
* command line. Options and arguments are processed in the order of the array
* passed to the invocation method.
*
* <p>Like any operation of a dynamic MBean, each of these operations is
* described by {@link javax.management.MBeanOperationInfo MBeanOperationInfo}
* instance. Here's the values returned by this object:
* <ul>
* <li>{@link javax.management.MBeanOperationInfo#getName() getName()}
* returns the operation name generated from the diagnostic command name</li>
* <li>{@link javax.management.MBeanOperationInfo#getDescription() getDescription()}
* returns the diagnostic command description
* (the same as the one return in the 'help' command)</li>
* <li>{@link javax.management.MBeanOperationInfo#getImpact() getImpact()}
* returns <code>ACTION_INFO</code></li>
* <li>{@link javax.management.MBeanOperationInfo#getReturnType() getReturnType()}
* returns {@code java.lang.String}</li>
* <li>{@link javax.management.MBeanOperationInfo#getDescriptor() getDescriptor()}
* returns a Descriptor instance (see below)</li>
* </ul>
*
* <p>The {@link javax.management.Descriptor Descriptor}
* is a collection of fields containing additional
* meta-data for a JMX element. A field is a name and an associated value.
* The additional meta-data provided for an operation associated with a
* diagnostic command are described in the table below:
* <p>
*
* <table border="1" cellpadding="5">
* <tr>
* <th>Name</th><th>Type</th><th>Description</th>
* </tr>
* <tr>
* <td>dcmd.name</td><td>String</td>
* <td>The original diagnostic command name (not the operation name)</td>
* </tr>
* <tr>
* <td>dcmd.description</td><td>String</td>
* <td>The diagnostic command description</td>
* </tr>
* <tr>
* <td>dcmd.help</td><td>String</td>
* <td>The full help message for this diagnostic command (same output as
* the one produced by the 'help' command)</td>
* </tr>
* <tr>
* <td>dcmd.vmImpact</td><td>String</td>
* <td>The impact of the diagnostic command,
* this value is the same as the one printed in the 'impact'
* section of the help message of the diagnostic command, and it
* is different from the getImpact() of the MBeanOperationInfo</td>
* </tr>
* <tr>
* <td>dcmd.enabled</td><td>boolean</td>
* <td>True if the diagnostic command is enabled, false otherwise</td>
* </tr>
* <tr>
* <td>dcmd.permissionClass</td><td>String</td>
* <td>Some diagnostic command might require a specific permission to be
* executed, in addition to the MBeanPermission to invoke their
* associated MBean operation. This field returns the fully qualified
* name of the permission class or null if no permission is required
* </td>
* </tr>
* <tr>
* <td>dcmd.permissionName</td><td>String</td>
* <td>The fist argument of the permission required to execute this
* diagnostic command or null if no permission is required</td>
* </tr>
* <tr>
* <td>dcmd.permissionAction</td><td>String</td>
* <td>The second argument of the permission required to execute this
* diagnostic command or null if the permission constructor has only
* one argument (like the ManagementPermission) or if no permission
* is required</td>
* </tr>
* <tr>
* <td>dcmd.arguments</td><td>Descriptor</td>
* <td>A Descriptor instance containing the descriptions of options and
* arguments supported by the diagnostic command (see below)</td>
* </tr>
* </table>
* <p>
*
* <p>The description of parameters (options or arguments) of a diagnostic
* command is provided within a Descriptor instance. In this Descriptor,
* each field name is a parameter name, and each field value is itself
* a Descriptor instance. The fields provided in this second Descriptor
* instance are described in the table below:
*
* <table border="1" cellpadding="5">
* <tr>
* <th>Name</th><th>Type</th><th>Description</th>
* </tr>
* <tr>
* <td>dcmd.arg.name</td><td>String</td>
* <td>The name of the parameter</td>
* </tr>
* <tr>
* <td>dcmd.arg.type</td><td>String</td>
* <td>The type of the parameter. The returned String is the name of a type
* recognized by the diagnostic command parser. These types are not
* Java types and are implementation dependent.
* </td>
* </tr>
* <tr>
* <td>dcmd.arg.description</td><td>String</td>
* <td>The parameter description</td>
* </tr>
* <tr>
* <td>dcmd.arg.isMandatory</td><td>boolean</td>
* <td>True if the parameter is mandatory, false otherwise</td>
* </tr>
* <tr>
* <td>dcmd.arg.isOption</td><td>boolean</td>
* <td>True if the parameter is an option, false if it is an argument</td>
* </tr>
* <tr>
* <td>dcmd.arg.isMultiple</td><td>boolean</td>
* <td>True if the parameter can be specified several times, false
* otherwise</td>
* </tr>
* </table>
*
* <p>When the set of diagnostic commands currently supported by the Java
* Virtual Machine is modified, the {@code DiagnosticCommandMBean} emits
* a {@link javax.management.Notification} with a
* {@linkplain javax.management.Notification#getType() type} of
* <a href="{@docRoot}/../../../../api/javax/management/MBeanInfo.html#info-changed">
* {@code "jmx.mbean.info.changed"}</a> and a
* {@linkplain javax.management.Notification#getUserData() userData} that
* is the new {@code MBeanInfo}.
*
* @since 8
*/
public interface DiagnosticCommandMBean extends DynamicMBean
{
}
...@@ -240,13 +240,15 @@ class FileInputStream extends InputStream ...@@ -240,13 +240,15 @@ class FileInputStream extends InputStream
* *
* <p>The <code>skip</code> method may, for a variety of * <p>The <code>skip</code> method may, for a variety of
* reasons, end up skipping over some smaller number of bytes, * reasons, end up skipping over some smaller number of bytes,
* possibly <code>0</code>. If <code>n</code> is negative, an * possibly <code>0</code>. If <code>n</code> is negative, the method
* <code>IOException</code> is thrown, even though the <code>skip</code> * will try to skip backwards. In case the backing file does not support
* method of the {@link InputStream} superclass does nothing in this case. * backward skip at its current position, an <code>IOException</code> is
* The actual number of bytes skipped is returned. * thrown. The actual number of bytes skipped is returned. If it skips
* forwards, it returns a positive value. If it skips backwards, it
* returns a negative value.
* *
* <p>This method may skip more bytes than are remaining in the backing * <p>This method may skip more bytes than what are remaining in the
* file. This produces no exception and the number of bytes skipped * backing file. This produces no exception and the number of bytes skipped
* may include some number of bytes that were beyond the EOF of the * may include some number of bytes that were beyond the EOF of the
* backing file. Attempting to read from the stream after skipping past * backing file. Attempting to read from the stream after skipping past
* the end will result in -1 indicating the end of the file. * the end will result in -1 indicating the end of the file.
...@@ -261,9 +263,10 @@ class FileInputStream extends InputStream ...@@ -261,9 +263,10 @@ class FileInputStream extends InputStream
/** /**
* Returns an estimate of the number of remaining bytes that can be read (or * Returns an estimate of the number of remaining bytes that can be read (or
* skipped over) from this input stream without blocking by the next * skipped over) from this input stream without blocking by the next
* invocation of a method for this input stream. The next invocation might be * invocation of a method for this input stream. Returns 0 when the file
* the same thread or another thread. A single read or skip of this * position is beyond EOF. The next invocation might be the same thread
* many bytes will not block, but may read or skip fewer bytes. * or another thread. A single read or skip of this many bytes will not
* block, but may read or skip fewer bytes.
* *
* <p> In some cases, a non-blocking read (or skip) may appear to be * <p> In some cases, a non-blocking read (or skip) may appear to be
* blocked when it is merely slow, for example when reading large * blocked when it is merely slow, for example when reading large
......
/* /*
* Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -193,8 +193,10 @@ public abstract class InputStream implements Closeable { ...@@ -193,8 +193,10 @@ public abstract class InputStream implements Closeable {
* up skipping over some smaller number of bytes, possibly <code>0</code>. * up skipping over some smaller number of bytes, possibly <code>0</code>.
* This may result from any of a number of conditions; reaching end of file * This may result from any of a number of conditions; reaching end of file
* before <code>n</code> bytes have been skipped is only one possibility. * before <code>n</code> bytes have been skipped is only one possibility.
* The actual number of bytes skipped is returned. If <code>n</code> is * The actual number of bytes skipped is returned. If {@code n} is
* negative, no bytes are skipped. * negative, the {@code skip} method for class {@code InputStream} always
* returns 0, and no bytes are skipped. Subclasses may handle the negative
* value differently.
* *
* <p> The <code>skip</code> method of this class creates a * <p> The <code>skip</code> method of this class creates a
* byte array and then repeatedly reads into it until <code>n</code> bytes * byte array and then repeatedly reads into it until <code>n</code> bytes
......
/* /*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -689,7 +689,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -689,7 +689,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @return a reference to this object. * @return a reference to this object.
*/ */
public AbstractStringBuilder append(float f) { public AbstractStringBuilder append(float f) {
new FloatingDecimal(f).appendTo(this); FloatingDecimal.appendTo(f,this);
return this; return this;
} }
...@@ -706,7 +706,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -706,7 +706,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @return a reference to this object. * @return a reference to this object.
*/ */
public AbstractStringBuilder append(double d) { public AbstractStringBuilder append(double d) {
new FloatingDecimal(d).appendTo(this); FloatingDecimal.appendTo(d,this);
return this; return this;
} }
......
...@@ -179,10 +179,25 @@ public interface CharSequence { ...@@ -179,10 +179,25 @@ public interface CharSequence {
@Override @Override
public void forEachRemaining(IntConsumer block) { public void forEachRemaining(IntConsumer block) {
while (cur < length()) { final int length = length();
int cp = Character.codePointAt(CharSequence.this, cur); int i = cur;
cur += Character.charCount(cp); try {
block.accept(cp); while (i < length) {
char c1 = charAt(i++);
if (!Character.isHighSurrogate(c1) || i >= length) {
block.accept(c1);
} else {
char c2 = charAt(i);
if (Character.isLowSurrogate(c2)) {
i++;
block.accept(Character.toCodePoint(c1, c2));
} else {
block.accept(c1);
}
}
}
} finally {
cur = i;
} }
} }
...@@ -191,12 +206,20 @@ public interface CharSequence { ...@@ -191,12 +206,20 @@ public interface CharSequence {
} }
public int nextInt() { public int nextInt() {
if (!hasNext()) { final int length = length();
if (cur >= length) {
throw new NoSuchElementException(); throw new NoSuchElementException();
} }
int cp = Character.codePointAt(CharSequence.this, cur); char c1 = charAt(cur++);
cur += Character.charCount(cp); if (Character.isHighSurrogate(c1) && cur < length) {
return cp; char c2 = charAt(cur);
if (Character.isLowSurrogate(c2)) {
cur++;
return Character.toCodePoint(c1, c2);
}
}
return c1;
} }
} }
......
...@@ -28,6 +28,7 @@ package java.lang; ...@@ -28,6 +28,7 @@ package java.lang;
import java.lang.reflect.AnnotatedElement; import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericArrayType;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Member; import java.lang.reflect.Member;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Executable; import java.lang.reflect.Executable;
...@@ -115,9 +116,9 @@ import sun.reflect.misc.ReflectUtil; ...@@ -115,9 +116,9 @@ import sun.reflect.misc.ReflectUtil;
* @since JDK1.0 * @since JDK1.0
*/ */
public final class Class<T> implements java.io.Serializable, public final class Class<T> implements java.io.Serializable,
java.lang.reflect.GenericDeclaration, GenericDeclaration,
java.lang.reflect.Type, Type,
java.lang.reflect.AnnotatedElement { AnnotatedElement {
private static final int ANNOTATION= 0x00002000; private static final int ANNOTATION= 0x00002000;
private static final int ENUM = 0x00004000; private static final int ENUM = 0x00004000;
private static final int SYNTHETIC = 0x00001000; private static final int SYNTHETIC = 0x00001000;
...@@ -2284,14 +2285,6 @@ public final class Class<T> implements java.io.Serializable, ...@@ -2284,14 +2285,6 @@ public final class Class<T> implements java.io.Serializable,
*/ */
private native java.security.ProtectionDomain getProtectionDomain0(); private native java.security.ProtectionDomain getProtectionDomain0();
/**
* Set the ProtectionDomain for this class. Called by
* ClassLoader.defineClass.
*/
native void setProtectionDomain0(java.security.ProtectionDomain pd);
/* /*
* Return the Virtual Machine's Class object for the named * Return the Virtual Machine's Class object for the named
* primitive type. * primitive type.
...@@ -3255,7 +3248,7 @@ public final class Class<T> implements java.io.Serializable, ...@@ -3255,7 +3248,7 @@ public final class Class<T> implements java.io.Serializable,
*/ */
@Override @Override
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
return AnnotatedElement.super.isAnnotationPresent(annotationClass); return GenericDeclaration.super.isAnnotationPresent(annotationClass);
} }
/** /**
......
...@@ -201,7 +201,7 @@ public final class Double extends Number implements Comparable<Double> { ...@@ -201,7 +201,7 @@ public final class Double extends Number implements Comparable<Double> {
* @return a string representation of the argument. * @return a string representation of the argument.
*/ */
public static String toString(double d) { public static String toString(double d) {
return new FloatingDecimal(d).toJavaFormatString(); return FloatingDecimal.toJavaFormatString(d);
} }
/** /**
...@@ -509,7 +509,7 @@ public final class Double extends Number implements Comparable<Double> { ...@@ -509,7 +509,7 @@ public final class Double extends Number implements Comparable<Double> {
* parsable number. * parsable number.
*/ */
public static Double valueOf(String s) throws NumberFormatException { public static Double valueOf(String s) throws NumberFormatException {
return new Double(FloatingDecimal.readJavaFormatString(s).doubleValue()); return new Double(parseDouble(s));
} }
/** /**
...@@ -545,7 +545,7 @@ public final class Double extends Number implements Comparable<Double> { ...@@ -545,7 +545,7 @@ public final class Double extends Number implements Comparable<Double> {
* @since 1.2 * @since 1.2
*/ */
public static double parseDouble(String s) throws NumberFormatException { public static double parseDouble(String s) throws NumberFormatException {
return FloatingDecimal.readJavaFormatString(s).doubleValue(); return FloatingDecimal.parseDouble(s);
} }
/** /**
......
/* /*
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -203,7 +203,7 @@ public final class Float extends Number implements Comparable<Float> { ...@@ -203,7 +203,7 @@ public final class Float extends Number implements Comparable<Float> {
* @return a string representation of the argument. * @return a string representation of the argument.
*/ */
public static String toString(float f) { public static String toString(float f) {
return new FloatingDecimal(f).toJavaFormatString(); return FloatingDecimal.toJavaFormatString(f);
} }
/** /**
...@@ -421,7 +421,7 @@ public final class Float extends Number implements Comparable<Float> { ...@@ -421,7 +421,7 @@ public final class Float extends Number implements Comparable<Float> {
* parsable number. * parsable number.
*/ */
public static Float valueOf(String s) throws NumberFormatException { public static Float valueOf(String s) throws NumberFormatException {
return new Float(FloatingDecimal.readJavaFormatString(s).floatValue()); return new Float(parseFloat(s));
} }
/** /**
...@@ -456,7 +456,7 @@ public final class Float extends Number implements Comparable<Float> { ...@@ -456,7 +456,7 @@ public final class Float extends Number implements Comparable<Float> {
* @since 1.2 * @since 1.2
*/ */
public static float parseFloat(String s) throws NumberFormatException { public static float parseFloat(String s) throws NumberFormatException {
return FloatingDecimal.readJavaFormatString(s).floatValue(); return FloatingDecimal.parseFloat(s);
} }
/** /**
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
package java.lang; package java.lang;
import java.lang.annotation.Native; import java.lang.annotation.Native;
import java.util.Properties;
/** /**
* The {@code Integer} class wraps a value of the primitive type * The {@code Integer} class wraps a value of the primitive type
...@@ -185,7 +184,7 @@ public final class Integer extends Number implements Comparable<Integer> { ...@@ -185,7 +184,7 @@ public final class Integer extends Number implements Comparable<Integer> {
* @since 1.8 * @since 1.8
*/ */
public static String toUnsignedString(int i, int radix) { public static String toUnsignedString(int i, int radix) {
return Long.toString(toUnsignedLong(i), radix); return Long.toUnsignedString(toUnsignedLong(i), radix);
} }
/** /**
...@@ -307,20 +306,39 @@ public final class Integer extends Number implements Comparable<Integer> { ...@@ -307,20 +306,39 @@ public final class Integer extends Number implements Comparable<Integer> {
/** /**
* Convert the integer to an unsigned number. * Convert the integer to an unsigned number.
*/ */
private static String toUnsignedString0(int i, int shift) { private static String toUnsignedString0(int val, int shift) {
char[] buf = new char[32]; // assert shift > 0 && shift <=5 : "Illegal shift value";
int charPos = 32; int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
char[] buf = new char[chars];
formatUnsignedInt(val, shift, buf, 0, chars);
// Use special constructor which takes over "buf".
return new String(buf, true);
}
/**
* Format a long (treated as unsigned) into a character buffer.
* @param val the unsigned int to format
* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
* @param buf the character buffer to write to
* @param offset the offset in the destination buffer to start at
* @param len the number of characters to write
* @return the lowest character location used
*/
static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
int charPos = len;
int radix = 1 << shift; int radix = 1 << shift;
int mask = radix - 1; int mask = radix - 1;
do { do {
buf[--charPos] = digits[i & mask]; buf[offset + --charPos] = Integer.digits[val & mask];
i >>>= shift; val >>>= shift;
} while (i != 0); } while (val != 0 && charPos > 0);
return new String(buf, charPos, (32 - charPos)); return charPos;
} }
final static char [] DigitTens = { final static char [] DigitTens = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
...@@ -875,6 +893,7 @@ public final class Integer extends Number implements Comparable<Integer> { ...@@ -875,6 +893,7 @@ public final class Integer extends Number implements Comparable<Integer> {
* Returns the value of this {@code Integer} as a {@code long} * Returns the value of this {@code Integer} as a {@code long}
* after a widening primitive conversion. * after a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions * @jls 5.1.2 Widening Primitive Conversions
* @see Integer#toUnsignedLong(int)
*/ */
public long longValue() { public long longValue() {
return (long)value; return (long)value;
......
...@@ -28,6 +28,7 @@ package java.lang; ...@@ -28,6 +28,7 @@ package java.lang;
import java.lang.annotation.Native; import java.lang.annotation.Native;
import java.math.*; import java.math.*;
/** /**
* The {@code Long} class wraps a value of the primitive type {@code * The {@code Long} class wraps a value of the primitive type {@code
* long} in an object. An object of type {@code Long} contains a * long} in an object. An object of type {@code Long} contains a
...@@ -344,18 +345,39 @@ public final class Long extends Number implements Comparable<Long> { ...@@ -344,18 +345,39 @@ public final class Long extends Number implements Comparable<Long> {
} }
/** /**
* Convert the integer to an unsigned number. * Format a long (treated as unsigned) into a String.
* @param val the value to format
* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
*/ */
private static String toUnsignedString0(long i, int shift) { static String toUnsignedString0(long val, int shift) {
char[] buf = new char[64]; // assert shift > 0 && shift <=5 : "Illegal shift value";
int charPos = 64; int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
char[] buf = new char[chars];
formatUnsignedLong(val, shift, buf, 0, chars);
return new String(buf, true);
}
/**
* Format a long (treated as unsigned) into a character buffer.
* @param val the unsigned long to format
* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
* @param buf the character buffer to write to
* @param offset the offset in the destination buffer to start at
* @param len the number of characters to write
* @return the lowest character location used
*/
static int formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {
int charPos = len;
int radix = 1 << shift; int radix = 1 << shift;
long mask = radix - 1; int mask = radix - 1;
do { do {
buf[--charPos] = Integer.digits[(int)(i & mask)]; buf[offset + --charPos] = Integer.digits[((int) val) & mask];
i >>>= shift; val >>>= shift;
} while (i != 0); } while (val != 0 && charPos > 0);
return new String(buf, charPos, (64 - charPos));
return charPos;
} }
/** /**
......
...@@ -1010,13 +1010,14 @@ public final class String ...@@ -1010,13 +1010,14 @@ public final class String
private boolean nonSyncContentEquals(AbstractStringBuilder sb) { private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
char v1[] = value; char v1[] = value;
char v2[] = sb.getValue(); char v2[] = sb.getValue();
int i = 0; int n = v1.length;
int n = value.length; if (n != sb.length()) {
while (n-- != 0) { return false;
}
for (int i = 0; i < n; i++) {
if (v1[i] != v2[i]) { if (v1[i] != v2[i]) {
return false; return false;
} }
i++;
} }
return true; return true;
} }
...@@ -1038,8 +1039,6 @@ public final class String ...@@ -1038,8 +1039,6 @@ public final class String
* @since 1.5 * @since 1.5
*/ */
public boolean contentEquals(CharSequence cs) { public boolean contentEquals(CharSequence cs) {
if (value.length != cs.length())
return false;
// Argument is a StringBuffer, StringBuilder // Argument is a StringBuffer, StringBuilder
if (cs instanceof AbstractStringBuilder) { if (cs instanceof AbstractStringBuilder) {
if (cs instanceof StringBuffer) { if (cs instanceof StringBuffer) {
...@@ -1055,12 +1054,14 @@ public final class String ...@@ -1055,12 +1054,14 @@ public final class String
return true; return true;
// Argument is a generic CharSequence // Argument is a generic CharSequence
char v1[] = value; char v1[] = value;
int i = 0; int n = v1.length;
int n = value.length; if (n != cs.length()) {
while (n-- != 0) { return false;
if (v1[i] != cs.charAt(i)) }
for (int i = 0; i < n; i++) {
if (v1[i] != cs.charAt(i)) {
return false; return false;
i++; }
} }
return true; return true;
} }
......
...@@ -335,10 +335,8 @@ import java.util.Arrays; ...@@ -335,10 +335,8 @@ import java.util.Arrays;
* @since 1.5 * @since 1.5
*/ */
@Override @Override
public StringBuffer append(CharSequence s) { public synchronized StringBuffer append(CharSequence s) {
// Note, synchronization achieved via invocations of other StringBuffer methods after toStringCache = null;
// narrowing of s to specific type
// Ditto for toStringCache clearing
super.append(s); super.append(s);
return this; return this;
} }
......
...@@ -145,10 +145,10 @@ class Thread implements Runnable { ...@@ -145,10 +145,10 @@ class Thread implements Runnable {
registerNatives(); registerNatives();
} }
private char name[]; private volatile char name[];
private int priority; private int priority;
private Thread threadQ; private Thread threadQ;
private long eetop; private long eetop;
/* Whether or not to single_step this thread. */ /* Whether or not to single_step this thread. */
private boolean single_step; private boolean single_step;
...@@ -1135,7 +1135,7 @@ class Thread implements Runnable { ...@@ -1135,7 +1135,7 @@ class Thread implements Runnable {
* @see #getName * @see #getName
* @see #checkAccess() * @see #checkAccess()
*/ */
public final void setName(String name) { public final synchronized void setName(String name) {
checkAccess(); checkAccess();
this.name = name.toCharArray(); this.name = name.toCharArray();
if (threadStatus != 0) { if (threadStatus != 0) {
...@@ -1150,7 +1150,7 @@ class Thread implements Runnable { ...@@ -1150,7 +1150,7 @@ class Thread implements Runnable {
* @see #setName(String) * @see #setName(String)
*/ */
public final String getName() { public final String getName() {
return String.valueOf(name); return new String(name, true);
} }
/** /**
......
...@@ -55,8 +55,7 @@ public class IncompleteAnnotationException extends RuntimeException { ...@@ -55,8 +55,7 @@ public class IncompleteAnnotationException extends RuntimeException {
public IncompleteAnnotationException( public IncompleteAnnotationException(
Class<? extends Annotation> annotationType, Class<? extends Annotation> annotationType,
String elementName) { String elementName) {
super(annotationType.getName().toString() + super(annotationType.getName() + " missing element " +
" missing element " +
elementName.toString()); elementName.toString());
this.annotationType = annotationType; this.annotationType = annotationType;
......
/* /*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -42,7 +42,9 @@ import javax.management.StandardMBean; ...@@ -42,7 +42,9 @@ import javax.management.StandardMBean;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.security.AccessController; import java.security.AccessController;
import java.security.Permission; import java.security.Permission;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
...@@ -482,6 +484,11 @@ public class ManagementFactory { ...@@ -482,6 +484,11 @@ public class ManagementFactory {
} }
} }
} }
HashMap<ObjectName, DynamicMBean> dynmbeans =
ManagementFactoryHelper.getPlatformDynamicMBeans();
for (Map.Entry<ObjectName, DynamicMBean> e : dynmbeans.entrySet()) {
addDynamicMBean(platformMBeanServer, e.getValue(), e.getKey());
}
} }
return platformMBeanServer; return platformMBeanServer;
} }
...@@ -825,4 +832,24 @@ public class ManagementFactory { ...@@ -825,4 +832,24 @@ public class ManagementFactory {
} }
} }
/**
* Registers a DynamicMBean.
*/
private static void addDynamicMBean(final MBeanServer mbs,
final DynamicMBean dmbean,
final ObjectName on) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws InstanceAlreadyExistsException,
MBeanRegistrationException,
NotCompliantMBeanException {
mbs.registerMBean(dmbean, on);
return null;
}
});
} catch (PrivilegedActionException e) {
throw new RuntimeException(e.getException());
}
}
} }
/* /*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -138,8 +138,23 @@ public abstract class Reference<T> { ...@@ -138,8 +138,23 @@ public abstract class Reference<T> {
pending = r.discovered; pending = r.discovered;
r.discovered = null; r.discovered = null;
} else { } else {
// The waiting on the lock may cause an OOME because it may try to allocate
// exception objects, so also catch OOME here to avoid silent exit of the
// reference handler thread.
//
// Explicitly define the order of the two exceptions we catch here
// when waiting for the lock.
//
// We do not want to try to potentially load the InterruptedException class
// (which would be done if this was its first use, and InterruptedException
// were checked first) in this situation.
//
// This may lead to the VM not ever trying to load the InterruptedException
// class again.
try { try {
lock.wait(); try {
lock.wait();
} catch (OutOfMemoryError x) { }
} catch (InterruptedException x) { } } catch (InterruptedException x) { }
continue; continue;
} }
......
/* /*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,7 +30,7 @@ package java.lang.reflect; ...@@ -30,7 +30,7 @@ package java.lang.reflect;
* *
* @since 1.5 * @since 1.5
*/ */
public interface GenericDeclaration { public interface GenericDeclaration extends AnnotatedElement {
/** /**
* Returns an array of {@code TypeVariable} objects that * Returns an array of {@code TypeVariable} objects that
* represent the type variables declared by the generic * represent the type variables declared by the generic
......
...@@ -59,6 +59,8 @@ public interface CookiePolicy { ...@@ -59,6 +59,8 @@ public interface CookiePolicy {
*/ */
public static final CookiePolicy ACCEPT_ORIGINAL_SERVER = new CookiePolicy(){ public static final CookiePolicy ACCEPT_ORIGINAL_SERVER = new CookiePolicy(){
public boolean shouldAccept(URI uri, HttpCookie cookie) { public boolean shouldAccept(URI uri, HttpCookie cookie) {
if (uri == null || cookie == null)
return false;
return HttpCookie.domainMatches(cookie.getDomain(), uri.getHost()); return HttpCookie.domainMatches(cookie.getDomain(), uri.getHost());
} }
}; };
......
...@@ -128,8 +128,7 @@ public final class HttpCookie implements Cloneable { ...@@ -128,8 +128,7 @@ public final class HttpCookie implements Cloneable {
* a {@code String} specifying the value of the cookie * a {@code String} specifying the value of the cookie
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if the cookie name contains illegal characters or it is one of * if the cookie name contains illegal characters
* the tokens reserved for use by the cookie protocol
* @throws NullPointerException * @throws NullPointerException
* if {@code name} is {@code null} * if {@code name} is {@code null}
* *
...@@ -142,7 +141,7 @@ public final class HttpCookie implements Cloneable { ...@@ -142,7 +141,7 @@ public final class HttpCookie implements Cloneable {
private HttpCookie(String name, String value, String header) { private HttpCookie(String name, String value, String header) {
name = name.trim(); name = name.trim();
if (name.length() == 0 || !isToken(name)) { if (name.length() == 0 || !isToken(name) || name.charAt(0) == '$') {
throw new IllegalArgumentException("Illegal cookie name"); throw new IllegalArgumentException("Illegal cookie name");
} }
...@@ -170,9 +169,8 @@ public final class HttpCookie implements Cloneable { ...@@ -170,9 +169,8 @@ public final class HttpCookie implements Cloneable {
* @return a List of cookie parsed from header line string * @return a List of cookie parsed from header line string
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if header string violates the cookie specification's syntax, or * if header string violates the cookie specification's syntax or
* the cookie name contains illegal characters, or the cookie name * the cookie name contains illegal characters.
* is one of the tokens reserved for use by the cookie protocol
* @throws NullPointerException * @throws NullPointerException
* if the header string is {@code null} * if the header string is {@code null}
*/ */
......
...@@ -377,7 +377,7 @@ public final class HttpURLPermission extends Permission { ...@@ -377,7 +377,7 @@ public final class HttpURLPermission extends Permission {
throw new IllegalArgumentException ("unexpected URL scheme"); throw new IllegalArgumentException ("unexpected URL scheme");
} }
if (!u.getSchemeSpecificPart().equals("*")) { if (!u.getSchemeSpecificPart().equals("*")) {
u = URI.create(scheme + "://" + u.getAuthority() + u.getPath()); u = URI.create(scheme + "://" + u.getRawAuthority() + u.getRawPath());
} }
return u; return u;
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package java.nio; package java.nio;
import java.util.Spliterator;
/** /**
* A container for data of a specific primitive type. * A container for data of a specific primitive type.
...@@ -173,6 +174,13 @@ package java.nio; ...@@ -173,6 +174,13 @@ package java.nio;
public abstract class Buffer { public abstract class Buffer {
/**
* The characteristics of Spliterators that traverse and split elements
* maintained in Buffers.
*/
static final int SPLITERATOR_CHARACTERISTICS =
Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
// Invariants: mark <= position <= limit <= capacity // Invariants: mark <= position <= limit <= capacity
private int mark = -1; private int mark = -1;
private int position = 0; private int position = 0;
......
...@@ -115,6 +115,12 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private ...@@ -115,6 +115,12 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
return Bits.get$Type$$BO$(bb, ix(checkIndex(i))); return Bits.get$Type$$BO$(bb, ix(checkIndex(i)));
} }
#if[streamableType]
$type$ getUnchecked(int i) {
return Bits.get$Type$$BO$(bb, ix(i));
}
#end[streamableType]
#end[rw] #end[rw]
public $Type$Buffer put($type$ x) { public $Type$Buffer put($type$ x) {
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.nio;
import java.util.Comparator;
import java.util.Spliterator;
import java.util.function.IntConsumer;
/**
* A Spliterator.OfInt for sources that traverse and split elements
* maintained in a CharBuffer.
*
* @implNote
* The implementation is based on the code for the Array-based spliterators.
*/
class CharBufferSpliterator implements Spliterator.OfInt {
private final CharBuffer buffer;
private int index; // current index, modified on advance/split
private final int limit;
CharBufferSpliterator(CharBuffer buffer) {
this(buffer, buffer.position(), buffer.limit());
}
CharBufferSpliterator(CharBuffer buffer, int origin, int limit) {
assert origin <= limit;
this.buffer = buffer;
this.index = (origin <= limit) ? origin : limit;
this.limit = limit;
}
@Override
public OfInt trySplit() {
int lo = index, mid = (lo + limit) >>> 1;
return (lo >= mid)
? null
: new CharBufferSpliterator(buffer, lo, index = mid);
}
@Override
public void forEachRemaining(IntConsumer action) {
if (action == null)
throw new NullPointerException();
CharBuffer cb = buffer;
int i = index;
int hi = limit;
index = hi;
while (i < hi) {
action.accept(cb.getUnchecked(i++));
}
}
@Override
public boolean tryAdvance(IntConsumer action) {
if (action == null)
throw new NullPointerException();
if (index >= 0 && index < limit) {
action.accept(buffer.getUnchecked(index++));
return true;
}
return false;
}
@Override
public long estimateSize() {
return (long)(limit - index);
}
@Override
public int characteristics() {
return Buffer.SPLITERATOR_CHARACTERISTICS;
}
}
...@@ -253,6 +253,12 @@ class Direct$Type$Buffer$RW$$BO$ ...@@ -253,6 +253,12 @@ class Direct$Type$Buffer$RW$$BO$
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i))))); return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i)))));
} }
#if[streamableType]
$type$ getUnchecked(int i) {
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(i))));
}
#end[streamableType]
public $Type$Buffer get($type$[] dst, int offset, int length) { public $Type$Buffer get($type$[] dst, int offset, int length) {
#if[rw] #if[rw]
if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) { if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
......
...@@ -139,6 +139,12 @@ class Heap$Type$Buffer$RW$ ...@@ -139,6 +139,12 @@ class Heap$Type$Buffer$RW$
return hb[ix(checkIndex(i))]; return hb[ix(checkIndex(i))];
} }
#if[streamableType]
$type$ getUnchecked(int i) {
return hb[ix(i)];
}
#end[streamableType]
public $Type$Buffer get($type$[] dst, int offset, int length) { public $Type$Buffer get($type$[] dst, int offset, int length) {
checkBounds(offset, length, dst.length); checkBounds(offset, length, dst.length);
if (length > remaining()) if (length > remaining())
......
...@@ -77,6 +77,10 @@ class StringCharBuffer // package-private ...@@ -77,6 +77,10 @@ class StringCharBuffer // package-private
return str.charAt(checkIndex(index) + offset); return str.charAt(checkIndex(index) + offset);
} }
char getUnchecked(int index) {
return str.charAt(index + offset);
}
// ## Override bulk get methods for better performance // ## Override bulk get methods for better performance
public final CharBuffer put(char c) { public final CharBuffer put(char c) {
......
...@@ -30,6 +30,11 @@ package java.nio; ...@@ -30,6 +30,11 @@ package java.nio;
#if[char] #if[char]
import java.io.IOException; import java.io.IOException;
#end[char] #end[char]
#if[streamableType]
import java.util.Spliterator;
import java.util.stream.StreamSupport;
import java.util.stream.$Streamtype$Stream;
#end[streamableType]
/** /**
* $A$ $type$ buffer. * $A$ $type$ buffer.
...@@ -589,6 +594,19 @@ public abstract class $Type$Buffer ...@@ -589,6 +594,19 @@ public abstract class $Type$Buffer
*/ */
public abstract $type$ get(int index); public abstract $type$ get(int index);
#if[streamableType]
/**
* Absolute <i>get</i> method. Reads the $type$ at the given
* index without any validation of the index.
*
* @param index
* The index from which the $type$ will be read
*
* @return The $type$ at the given index
*/
abstract $type$ getUnchecked(int index); // package-private
#end[streamableType]
/** /**
* Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>. * Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
* *
...@@ -1458,4 +1476,16 @@ public abstract class $Type$Buffer ...@@ -1458,4 +1476,16 @@ public abstract class $Type$Buffer
#end[byte] #end[byte]
#if[streamableType]
#if[char]
@Override
#end[char]
public $Streamtype$Stream $type$s() {
return StreamSupport.$streamtype$Stream(() -> new $Type$BufferSpliterator(this),
Buffer.SPLITERATOR_CHARACTERISTICS);
}
#end[streamableType]
} }
...@@ -34,6 +34,7 @@ import java.nio.BufferOverflowException; ...@@ -34,6 +34,7 @@ import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException; import java.nio.BufferUnderflowException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.nio.charset.CoderMalfunctionError; // javadoc import java.nio.charset.CoderMalfunctionError; // javadoc
import java.util.Arrays;
/** /**
...@@ -244,7 +245,12 @@ public abstract class Charset$Coder$ { ...@@ -244,7 +245,12 @@ public abstract class Charset$Coder$ {
* which is never <tt>null</tt> and is never empty * which is never <tt>null</tt> and is never empty
*/ */
public final $replType$ replacement() { public final $replType$ replacement() {
#if[decoder]
return replacement; return replacement;
#end[decoder]
#if[encoder]
return Arrays.copyOf(replacement, replacement.$replLength$);
#end[encoder]
} }
/** /**
...@@ -280,12 +286,15 @@ public abstract class Charset$Coder$ { ...@@ -280,12 +286,15 @@ public abstract class Charset$Coder$ {
throw new IllegalArgumentException("Empty replacement"); throw new IllegalArgumentException("Empty replacement");
if (len > max$ItypesPerOtype$) if (len > max$ItypesPerOtype$)
throw new IllegalArgumentException("Replacement too long"); throw new IllegalArgumentException("Replacement too long");
#if[decoder]
this.replacement = newReplacement;
#end[decoder]
#if[encoder] #if[encoder]
if (!isLegalReplacement(newReplacement)) if (!isLegalReplacement(newReplacement))
throw new IllegalArgumentException("Illegal replacement"); throw new IllegalArgumentException("Illegal replacement");
this.replacement = Arrays.copyOf(newReplacement, newReplacement.$replLength$);
#end[encoder] #end[encoder]
this.replacement = newReplacement; implReplaceWith(this.replacement);
implReplaceWith(newReplacement);
return this; return this;
} }
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.nio.file;
import java.io.Closeable;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.nio.file.FileTreeWalker.Event;
/**
* An {@code Iterator to iterate over the nodes of a file tree.
*
* <pre>{@code
* try (FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options)) {
* while (iterator.hasNext()) {
* Event ev = iterator.next();
* Path path = ev.file();
* BasicFileAttributes attrs = ev.attributes();
* }
* }
* }</pre>
*/
class FileTreeIterator implements Iterator<Event>, Closeable {
private final FileTreeWalker walker;
private Event next;
/**
* Creates a new iterator to walk the file tree starting at the given file.
*
* @throws IllegalArgumentException
* if {@code maxDepth} is negative
* @throws IOException
* if an I/O errors occurs opening the starting file
* @throws SecurityException
* if the security manager denies access to the starting file
* @throws NullPointerException
* if {@code start} or {@code options} is {@ocde null} or
* the options array contains a {@code null} element
*/
FileTreeIterator(Path start, int maxDepth, FileVisitOption... options)
throws IOException
{
this.walker = new FileTreeWalker(Arrays.asList(options), maxDepth);
this.next = walker.walk(start);
assert next.type() == FileTreeWalker.EventType.ENTRY ||
next.type() == FileTreeWalker.EventType.START_DIRECTORY;
// IOException if there a problem accessing the starting file
IOException ioe = next.ioeException();
if (ioe != null)
throw ioe;
}
private void fetchNextIfNeeded() {
if (next == null) {
FileTreeWalker.Event ev = walker.next();
while (ev != null) {
IOException ioe = ev.ioeException();
if (ioe != null)
throw new UncheckedIOException(ioe);
// END_DIRECTORY events are ignored
if (ev.type() != FileTreeWalker.EventType.END_DIRECTORY) {
next = ev;
return;
}
ev = walker.next();
}
}
}
@Override
public boolean hasNext() {
if (!walker.isOpen())
throw new IllegalStateException();
fetchNextIfNeeded();
return next != null;
}
@Override
public Event next() {
if (!walker.isOpen())
throw new IllegalStateException();
fetchNextIfNeeded();
if (next == null)
throw new NoSuchElementException();
Event result = next;
next = null;
return result;
}
@Override
public void close() {
walker.close();
}
}
...@@ -29,8 +29,8 @@ import java.nio.file.attribute.BasicFileAttributes; ...@@ -29,8 +29,8 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set;
import sun.nio.fs.BasicFileAttributesHolder; import sun.nio.fs.BasicFileAttributesHolder;
/** /**
...@@ -164,8 +164,17 @@ class FileTreeWalker implements Closeable { ...@@ -164,8 +164,17 @@ class FileTreeWalker implements Closeable {
/** /**
* Creates a {@code FileTreeWalker}. * Creates a {@code FileTreeWalker}.
*
* @throws IllegalArgumentException
* if {@code maxDepth} is negative
* @throws ClassCastException
* if (@code options} contains an element that is not a
* {@code FileVisitOption}
* @throws NullPointerException
* if {@code options} is {@ocde null} or the options
* array contains a {@code null} element
*/ */
FileTreeWalker(Set<FileVisitOption> options, int maxDepth) { FileTreeWalker(Collection<FileVisitOption> options, int maxDepth) {
boolean fl = false; boolean fl = false;
for (FileVisitOption option: options) { for (FileVisitOption option: options) {
// will throw NPE if options contains null // will throw NPE if options contains null
...@@ -175,6 +184,9 @@ class FileTreeWalker implements Closeable { ...@@ -175,6 +184,9 @@ class FileTreeWalker implements Closeable {
throw new AssertionError("Should not get here"); throw new AssertionError("Should not get here");
} }
} }
if (maxDepth < 0)
throw new IllegalArgumentException("'maxDepth' is negative");
this.followLinks = fl; this.followLinks = fl;
this.linkOptions = (fl) ? new LinkOption[0] : this.linkOptions = (fl) ? new LinkOption[0] :
new LinkOption[] { LinkOption.NOFOLLOW_LINKS }; new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
......
...@@ -25,10 +25,13 @@ ...@@ -25,10 +25,13 @@
package java.nio.file; package java.nio.file;
import java.nio.ByteBuffer;
import java.nio.file.attribute.*; import java.nio.file.attribute.*;
import java.nio.file.spi.FileSystemProvider; import java.nio.file.spi.FileSystemProvider;
import java.nio.file.spi.FileTypeDetector; import java.nio.file.spi.FileTypeDetector;
import java.nio.channels.FileChannel;
import java.nio.channels.SeekableByteChannel; import java.nio.channels.SeekableByteChannel;
import java.io.Closeable;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Reader; import java.io.Reader;
...@@ -38,7 +41,13 @@ import java.io.BufferedWriter; ...@@ -38,7 +41,13 @@ import java.io.BufferedWriter;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.IOException; import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.*; import java.util.*;
import java.util.function.BiPredicate;
import java.util.stream.CloseableStream;
import java.util.stream.DelegatingStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.nio.charset.Charset; import java.nio.charset.Charset;
...@@ -2596,9 +2605,6 @@ public final class Files { ...@@ -2596,9 +2605,6 @@ public final class Files {
FileVisitor<? super Path> visitor) FileVisitor<? super Path> visitor)
throws IOException throws IOException
{ {
if (maxDepth < 0)
throw new IllegalArgumentException("'maxDepth' is negative");
/** /**
* Create a FileTreeWalker to walk the file tree, invoking the visitor * Create a FileTreeWalker to walk the file tree, invoking the visitor
* for each event. * for each event.
...@@ -2949,40 +2955,6 @@ public final class Files { ...@@ -2949,40 +2955,6 @@ public final class Files {
} }
} }
/**
* Read all the bytes from an input stream. The {@code initialSize}
* parameter indicates the initial size of the byte[] to allocate.
*/
private static byte[] read(InputStream source, int initialSize)
throws IOException
{
int capacity = initialSize;
byte[] buf = new byte[capacity];
int nread = 0;
int rem = buf.length;
int n;
// read to EOF which may read more or less than initialSize (eg: file
// is truncated while we are reading)
while ((n = source.read(buf, nread, rem)) > 0) {
nread += n;
rem -= n;
assert rem >= 0;
if (rem == 0) {
// need larger buffer
int newCapacity = capacity << 1;
if (newCapacity < 0) {
if (capacity == Integer.MAX_VALUE)
throw new OutOfMemoryError("Required array size too large");
newCapacity = Integer.MAX_VALUE;
}
rem = newCapacity - capacity;
buf = Arrays.copyOf(buf, newCapacity);
capacity = newCapacity;
}
}
return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
}
/** /**
* Read all the bytes from a file. The method ensures that the file is * Read all the bytes from a file. The method ensures that the file is
* closed when all bytes have been read or an I/O error, or other runtime * closed when all bytes have been read or an I/O error, or other runtime
...@@ -3008,12 +2980,22 @@ public final class Files { ...@@ -3008,12 +2980,22 @@ public final class Files {
* method is invoked to check read access to the file. * method is invoked to check read access to the file.
*/ */
public static byte[] readAllBytes(Path path) throws IOException { public static byte[] readAllBytes(Path path) throws IOException {
long size = size(path); try (FileChannel fc = FileChannel.open(path)) {
if (size > (long)Integer.MAX_VALUE) long size = fc.size();
throw new OutOfMemoryError("Required array size too large"); if (size > (long)Integer.MAX_VALUE)
throw new OutOfMemoryError("Required array size too large");
byte[] arr = new byte[(int)size];
ByteBuffer bb = ByteBuffer.wrap(arr);
while (bb.hasRemaining()) {
if (fc.read(bb) < 0) {
// truncated
break;
}
}
try (InputStream in = newInputStream(path)) { int nread = bb.position();
return read(in, (int)size); return (nread == size) ? arr : Arrays.copyOf(arr, nread);
} }
} }
...@@ -3186,4 +3168,336 @@ public final class Files { ...@@ -3186,4 +3168,336 @@ public final class Files {
} }
return path; return path;
} }
// -- Stream APIs --
/**
* Implementation of CloseableStream
*/
private static class DelegatingCloseableStream<T> extends DelegatingStream<T>
implements CloseableStream<T>
{
private final Closeable closeable;
DelegatingCloseableStream(Closeable c, Stream<T> delegate) {
super(delegate);
this.closeable = c;
}
public void close() {
try {
closeable.close();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
}
/**
* Return a lazily populated {@code CloseableStream}, the elements of
* which are the entries in the directory. The listing is not recursive.
*
* <p> The elements of the stream are {@link Path} objects that are
* obtained as if by {@link Path#resolve(Path) resolving} the name of the
* directory entry against {@code dir}. Some file systems maintain special
* links to the directory itself and the directory's parent directory.
* Entries representing these links are not included.
*
* <p> The stream is <i>weakly consistent</i>. It is thread safe but does
* not freeze the directory while iterating, so it may (or may not)
* reflect updates to the directory that occur after returning from this
* method.
*
* <p> When not using the try-with-resources construct, then the stream's
* {@link CloseableStream#close close} method should be invoked after the
* operation is completed so as to free any resources held for the open
* directory. Operating on a closed stream behaves as if the end of stream
* has been reached. Due to read-ahead, one or more elements may be
* returned after the stream has been closed.
*
* <p> If an {@link IOException} is thrown when accessing the directory
* after this method has returned, it is wrapped in an {@link
* UncheckedIOException} which will be thrown from the method that caused
* the access to take place.
*
* @param dir The path to the directory
*
* @return The {@code CloseableStream} describing the content of the
* directory
*
* @throws NotDirectoryException
* if the file could not otherwise be opened because it is not
* a directory <i>(optional specific exception)</i>
* @throws IOException
* if an I/O error occurs when opening the directory
* @throws SecurityException
* In the case of the default provider, and a security manager is
* installed, the {@link SecurityManager#checkRead(String) checkRead}
* method is invoked to check read access to the directory.
*
* @see #newDirectoryStream(Path)
* @since 1.8
*/
public static CloseableStream<Path> list(Path dir) throws IOException {
DirectoryStream<Path> ds = Files.newDirectoryStream(dir);
final Iterator<Path> delegate = ds.iterator();
// Re-wrap DirectoryIteratorException to UncheckedIOException
Iterator<Path> it = new Iterator<Path>() {
public boolean hasNext() {
try {
return delegate.hasNext();
} catch (DirectoryIteratorException e) {
throw new UncheckedIOException(e.getCause());
}
}
public Path next() {
try {
return delegate.next();
} catch (DirectoryIteratorException e) {
throw new UncheckedIOException(e.getCause());
}
}
};
return new DelegatingCloseableStream<>(ds,
StreamSupport.stream(Spliterators.spliteratorUnknownSize(it,
Spliterator.DISTINCT)));
}
/**
* Return a {@code CloseableStream} that is lazily populated with {@code
* Path} by walking the file tree rooted at a given starting file. The
* file tree is traversed <em>depth-first</em>, the elements in the stream
* are {@link Path} objects that are obtained as if by {@link
* Path#resolve(Path) resolving} the relative path against {@code start}.
*
* <p> The {@code stream} walks the file tree as elements are consumed.
* The {@code CloseableStream} returned is guaranteed to have at least one
* element, the starting file itself. For each file visited, the stream
* attempts to read its {@link BasicFileAttributes}. If the file is a
* directory and can be opened successfully, entries in the directory, and
* their <em>descendants</em> will follow the directory in the stream as
* they are encountered. When all entries have been visited, then the
* directory is closed. The file tree walk then continues at the next
* <em>sibling</em> of the directory.
*
* <p> The stream is <i>weakly consistent</i>. It does not freeze the
* file tree while iterating, so it may (or may not) reflect updates to
* the file tree that occur after returned from this method.
*
* <p> By default, symbolic links are not automatically followed by this
* method. If the {@code options} parameter contains the {@link
* FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then symbolic links are
* followed. When following links, and the attributes of the target cannot
* be read, then this method attempts to get the {@code BasicFileAttributes}
* of the link.
*
* <p> If the {@code options} parameter contains the {@link
* FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then the stream keeps
* track of directories visited so that cycles can be detected. A cycle
* arises when there is an entry in a directory that is an ancestor of the
* directory. Cycle detection is done by recording the {@link
* java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
* or if file keys are not available, by invoking the {@link #isSameFile
* isSameFile} method to test if a directory is the same file as an
* ancestor. When a cycle is detected it is treated as an I/O error with
* an instance of {@link FileSystemLoopException}.
*
* <p> The {@code maxDepth} parameter is the maximum number of levels of
* directories to visit. A value of {@code 0} means that only the starting
* file is visited, unless denied by the security manager. A value of
* {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
* levels should be visited.
*
* <p> When a security manager is installed and it denies access to a file
* (or directory), then it is ignored and not included in the stream.
*
* <p> When not using the try-with-resources construct, then the stream's
* {@link CloseableStream#close close} method should be invoked after the
* operation is completed so as to free any resources held for the open
* directory. Operate the stream after it is closed will throw an
* {@link java.lang.IllegalStateException}.
*
* <p> If an {@link IOException} is thrown when accessing the directory
* after this method has returned, it is wrapped in an {@link
* UncheckedIOException} which will be thrown from the method that caused
* the access to take place.
*
* @param start
* the starting file
* @param maxDepth
* the maximum number of directory levels to visit
* @param options
* options to configure the traversal
*
* @return the {@link CloseableStream} of {@link Path}
*
* @throws IllegalArgumentException
* if the {@code maxDepth} parameter is negative
* @throws SecurityException
* If the security manager denies access to the starting file.
* In the case of the default provider, the {@link
* SecurityManager#checkRead(String) checkRead} method is invoked
* to check read access to the directory.
* @throws IOException
* if an I/O error is thrown when accessing the starting file.
* @since 1.8
*/
public static CloseableStream<Path> walk(Path start, int maxDepth,
FileVisitOption... options)
throws IOException
{
FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
return new DelegatingCloseableStream<>(iterator,
StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT))
.map(entry -> entry.file()));
}
/**
* Return a {@code CloseableStream} that is lazily populated with {@code
* Path} by walking the file tree rooted at a given starting file. The
* file tree is traversed <em>depth-first</em>, the elements in the stream
* are {@link Path} objects that are obtained as if by {@link
* Path#resolve(Path) resolving} the relative path against {@code start}.
*
* <p> This method works as if invoking it were equivalent to evaluating the
* expression:
* <blockquote><pre>
* walk(start, Integer.MAX_VALUE, options)
* </pre></blockquote>
* In other words, it visits all levels of the file tree.
*
* @param start
* the starting file
* @param options
* options to configure the traversal
*
* @return the {@link CloseableStream} of {@link Path}
*
* @throws SecurityException
* If the security manager denies access to the starting file.
* In the case of the default provider, the {@link
* SecurityManager#checkRead(String) checkRead} method is invoked
* to check read access to the directory.
* @throws IOException
* if an I/O error is thrown when accessing the starting file.
*
* @see #walk(Path, int, FileVisitOption...)
* @since 1.8
*/
public static CloseableStream<Path> walk(Path start,
FileVisitOption... options)
throws IOException
{
return walk(start, Integer.MAX_VALUE, options);
}
/**
* Return a {@code CloseableStream} that is lazily populated with {@code
* Path} by searching for files in a file tree rooted at a given starting
* file.
*
* <p> This method walks the file tree in exactly the manner specified by
* the {@link #walk walk} method. For each file encountered, the given
* {@link BiPredicate} is invoked with its {@link Path} and {@link
* BasicFileAttributes}. The {@code Path} object is obtained as if by
* {@link Path#resolve(Path) resolving} the relative path against {@code
* start} and is only included in the returned {@link CloseableStream} if
* the {@code BiPredicate} returns true. Compare to calling {@link
* java.util.stream.Stream#filter filter} on the {@code Stream}
* returned by {@code walk} method, this method may be more efficient by
* avoiding redundant retrieval of the {@code BasicFileAttributes}.
*
* <p> If an {@link IOException} is thrown when accessing the directory
* after returned from this method, it is wrapped in an {@link
* UncheckedIOException} which will be thrown from the method that caused
* the access to take place.
*
* @param start
* the starting file
* @param maxDepth
* the maximum number of directory levels to search
* @param matcher
* the function used to decide whether a file should be included
* in the returned stream
* @param options
* options to configure the traversal
*
* @return the {@link CloseableStream} of {@link Path}
*
* @throws IllegalArgumentException
* if the {@code maxDepth} parameter is negative
* @throws SecurityException
* If the security manager denies access to the starting file.
* In the case of the default provider, the {@link
* SecurityManager#checkRead(String) checkRead} method is invoked
* to check read access to the directory.
* @throws IOException
* if an I/O error is thrown when accessing the starting file.
*
* @see #walk(Path, int, FileVisitOption...)
* @since 1.8
*/
public static CloseableStream<Path> find(Path start,
int maxDepth,
BiPredicate<Path, BasicFileAttributes> matcher,
FileVisitOption... options)
throws IOException
{
FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
return new DelegatingCloseableStream<>(iterator,
StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT))
.filter(entry -> matcher.test(entry.file(), entry.attributes()))
.map(entry -> entry.file()));
}
/**
* Read all lines from a file as a {@code CloseableStream}. Unlike {@link
* #readAllLines(Path, Charset) readAllLines}, this method does not read
* all lines into a {@code List}, but instead populates lazily as the stream
* is consumed.
*
* <p> Bytes from the file are decoded into characters using the specified
* charset and the same line terminators as specified by {@code
* readAllLines} are supported.
*
* <p> After this method returns, then any subsequent I/O exception that
* occurs while reading from the file or when a malformed or unmappable byte
* sequence is read, is wrapped in an {@link UncheckedIOException} that will
* be thrown form the
* {@link java.util.stream.Stream} method that caused the read to take
* place. In case an {@code IOException} is thrown when closing the file,
* it is also wrapped as an {@code UncheckedIOException}.
*
* <p> When not using the try-with-resources construct, then stream's
* {@link CloseableStream#close close} method should be invoked after
* operation is completed so as to free any resources held for the open
* file.
*
* @param path
* the path to the file
* @param cs
* the charset to use for decoding
*
* @return the lines from the file as a {@code CloseableStream}
*
* @throws IOException
* if an I/O error occurs opening the file
* @throws SecurityException
* In the case of the default provider, and a security manager is
* installed, the {@link SecurityManager#checkRead(String) checkRead}
* method is invoked to check read access to the file.
*
* @see #readAllLines(Path, Charset)
* @see #newBufferedReader(Path, Charset)
* @see java.io.BufferedReader#lines()
* @since 1.8
*/
public static CloseableStream<String> lines(Path path, Charset cs)
throws IOException
{
BufferedReader br = Files.newBufferedReader(path, cs);
return new DelegatingCloseableStream<>(br, br.lines());
}
} }
...@@ -82,9 +82,15 @@ import sun.reflect.Reflection; ...@@ -82,9 +82,15 @@ import sun.reflect.Reflection;
* else if (caller i is marked as privileged) { * else if (caller i is marked as privileged) {
* if (a context was specified in the call to doPrivileged) * if (a context was specified in the call to doPrivileged)
* context.checkPermission(permission) * context.checkPermission(permission)
* return; * if (limited permissions were specified in the call to doPrivileged) {
* for (each limited permission) {
* if (the limited permission implies the requested permission)
* return;
* }
* } else
* return;
* } * }
* }; * }
* *
* // Next, check the context inherited when the thread was created. * // Next, check the context inherited when the thread was created.
* // Whenever a new thread is created, the AccessControlContext at * // Whenever a new thread is created, the AccessControlContext at
...@@ -101,11 +107,16 @@ import sun.reflect.Reflection; ...@@ -101,11 +107,16 @@ import sun.reflect.Reflection;
* was marked as "privileged" via a <code>doPrivileged</code> * was marked as "privileged" via a <code>doPrivileged</code>
* call without a context argument (see below for information about a * call without a context argument (see below for information about a
* context argument). If that caller's domain has the * context argument). If that caller's domain has the
* specified permission, no further checking is done and * specified permission and at least one limiting permission argument (if any)
* implies the requested permission, no further checking is done and
* <code>checkPermission</code> * <code>checkPermission</code>
* returns quietly, indicating that the requested access is allowed. * returns quietly, indicating that the requested access is allowed.
* If that domain does not have the specified permission, an exception * If that domain does not have the specified permission, an exception
* is thrown, as usual. * is thrown, as usual. If the caller's domain had the specified permission
* but it was not implied by any limiting permission arguments given in the call
* to <code>doPrivileged</code> then the permission checking continues
* until there are no more callers or another <code>doPrivileged</code>
* call matches the requested permission and returns normally.
* *
* <p> The normal use of the "privileged" feature is as follows. If you * <p> The normal use of the "privileged" feature is as follows. If you
* don't need to return a value from within the "privileged" block, do * don't need to return a value from within the "privileged" block, do
...@@ -180,6 +191,9 @@ import sun.reflect.Reflection; ...@@ -180,6 +191,9 @@ import sun.reflect.Reflection;
* *
* <p> Be *very* careful in your use of the "privileged" construct, and * <p> Be *very* careful in your use of the "privileged" construct, and
* always remember to make the privileged code section as small as possible. * always remember to make the privileged code section as small as possible.
* You can pass <code>Permission</code> arguments to further limit the
* scope of the "privilege" (see below).
*
* *
* <p> Note that <code>checkPermission</code> always performs security checks * <p> Note that <code>checkPermission</code> always performs security checks
* within the context of the currently executing thread. * within the context of the currently executing thread.
...@@ -215,7 +229,9 @@ import sun.reflect.Reflection; ...@@ -215,7 +229,9 @@ import sun.reflect.Reflection;
* *
* <p> There are also times where you don't know a priori which permissions * <p> There are also times where you don't know a priori which permissions
* to check the context against. In these cases you can use the * to check the context against. In these cases you can use the
* doPrivileged method that takes a context: * doPrivileged method that takes a context. You can also limit the scope
* of the privileged code by passing additional <code>Permission</code>
* parameters.
* *
* <pre> {@code * <pre> {@code
* somemethod() { * somemethod() {
...@@ -223,12 +239,21 @@ import sun.reflect.Reflection; ...@@ -223,12 +239,21 @@ import sun.reflect.Reflection;
* public Object run() { * public Object run() {
* // Code goes here. Any permission checks within this * // Code goes here. Any permission checks within this
* // run method will require that the intersection of the * // run method will require that the intersection of the
* // callers protection domain and the snapshot's * // caller's protection domain and the snapshot's
* // context have the desired permission. * // context have the desired permission. If a requested
* // permission is not implied by the limiting FilePermission
* // argument then checking of the thread continues beyond the
* // caller of doPrivileged.
* } * }
* }, acc); * }, acc, new FilePermission("/temp/*", read));
* ...normal code here... * ...normal code here...
* }}</pre> * }}</pre>
* <p> Passing a limiting <code>Permission</code> argument of an instance of
* <code>AllPermission</code> is equivalent to calling the equivalent
* <code>doPrivileged</code> method without limiting <code>Permission</code>
* arguments. Passing a zero length array of <code>Permission</code> disables
* the code privileges so that checking always continues beyond the caller of
* that <code>doPrivileged</code> method.
* *
* @see AccessControlContext * @see AccessControlContext
* *
...@@ -337,6 +362,112 @@ public final class AccessController { ...@@ -337,6 +362,112 @@ public final class AccessController {
public static native <T> T doPrivileged(PrivilegedAction<T> action, public static native <T> T doPrivileged(PrivilegedAction<T> action,
AccessControlContext context); AccessControlContext context);
/**
* Performs the specified <code>PrivilegedAction</code> with privileges
* enabled and restricted by the specified
* <code>AccessControlContext</code> and with a privilege scope limited
* by specified <code>Permission</code> arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* <code>AccessControlContext</code>.
* <p>
* If the action's <code>run</code> method throws an (unchecked) exception,
* it will propagate through this method.
*
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* <code>null</code>,
* then no additional restriction is applied.
* @param perms the <code>Permission</code> arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's <code>run</code> method.
*
* @throws NullPointerException if action or perms or any element of
* perms is <code>null</code>
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivileged(PrivilegedAction<T> action,
AccessControlContext context, Permission... perms) {
AccessControlContext parent = getContext();
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(null,
caller, parent, context, perms));
}
/**
* Performs the specified <code>PrivilegedAction</code> with privileges
* enabled and restricted by the specified
* <code>AccessControlContext</code> and with a privilege scope limited
* by specified <code>Permission</code> arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* <code>AccessControlContext</code>.
* <p>
* If the action's <code>run</code> method throws an (unchecked) exception,
* it will propagate through this method.
*
* <p> This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
*
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* <code>null</code>,
* then no additional restriction is applied.
* @param perms the <code>Permission</code> arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's <code>run</code> method.
*
* @throws NullPointerException if action or perms or any element of
* perms is <code>null</code>
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
* @see java.security.DomainCombiner
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action,
AccessControlContext context, Permission... perms) {
AccessControlContext parent = getContext();
DomainCombiner dc = parent.getCombiner();
if (dc == null && context != null) {
dc = context.getCombiner();
}
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(dc, caller,
parent, context, perms));
}
/** /**
* Performs the specified <code>PrivilegedExceptionAction</code> with * Performs the specified <code>PrivilegedExceptionAction</code> with
* privileges enabled. The action is performed with <i>all</i> of the * privileges enabled. The action is performed with <i>all</i> of the
...@@ -411,6 +542,22 @@ public final class AccessController { ...@@ -411,6 +542,22 @@ public final class AccessController {
private static AccessControlContext preserveCombiner(DomainCombiner combiner, private static AccessControlContext preserveCombiner(DomainCombiner combiner,
Class<?> caller) Class<?> caller)
{ {
return createWrapper(combiner, caller, null, null, null);
}
/**
* Create a wrapper to contain the limited privilege scope data.
*/
private static AccessControlContext
createWrapper(DomainCombiner combiner, Class<?> caller,
AccessControlContext parent, AccessControlContext context,
Permission[] perms)
{
return new AccessControlContext(getCallerPD(caller), combiner, parent,
context, perms);
}
private static ProtectionDomain getCallerPD(final Class <?> caller) {
ProtectionDomain callerPd = doPrivileged ProtectionDomain callerPd = doPrivileged
(new PrivilegedAction<ProtectionDomain>() { (new PrivilegedAction<ProtectionDomain>() {
public ProtectionDomain run() { public ProtectionDomain run() {
...@@ -418,18 +565,9 @@ public final class AccessController { ...@@ -418,18 +565,9 @@ public final class AccessController {
} }
}); });
// perform 'combine' on the caller of doPrivileged, return callerPd;
// even if the caller is from the bootclasspath
ProtectionDomain[] pds = new ProtectionDomain[] {callerPd};
if (combiner == null) {
return new AccessControlContext(pds);
} else {
return new AccessControlContext(combiner.combine(pds, null),
combiner);
}
} }
/** /**
* Performs the specified {@code PrivilegedExceptionAction} with * Performs the specified {@code PrivilegedExceptionAction} with
* privileges enabled and restricted by the specified * privileges enabled and restricted by the specified
...@@ -461,7 +599,7 @@ public final class AccessController { ...@@ -461,7 +599,7 @@ public final class AccessController {
* @exception NullPointerException if the action is {@code null} * @exception NullPointerException if the action is {@code null}
* *
* @see #doPrivileged(PrivilegedAction) * @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) * @see #doPrivileged(PrivilegedAction,AccessControlContext)
*/ */
@CallerSensitive @CallerSensitive
public static native <T> T public static native <T> T
...@@ -469,6 +607,118 @@ public final class AccessController { ...@@ -469,6 +607,118 @@ public final class AccessController {
AccessControlContext context) AccessControlContext context)
throws PrivilegedActionException; throws PrivilegedActionException;
/**
* Performs the specified <code>PrivilegedExceptionAction</code> with
* privileges enabled and restricted by the specified
* <code>AccessControlContext</code> and with a privilege scope limited by
* specified <code>Permission</code> arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* <code>AccessControlContext</code>.
* <p>
* If the action's <code>run</code> method throws an (unchecked) exception,
* it will propagate through this method.
*
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* <code>null</code>,
* then no additional restriction is applied.
* @param perms the <code>Permission</code> arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's <code>run</code> method.
*
* @throws PrivilegedActionException if the specified action's
* <code>run</code> method threw a <i>checked</i> exception
* @throws NullPointerException if action or perms or any element of
* perms is <code>null</code>
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivileged(PrivilegedExceptionAction<T> action,
AccessControlContext context, Permission... perms)
throws PrivilegedActionException
{
AccessControlContext parent = getContext();
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms));
}
/**
* Performs the specified <code>PrivilegedExceptionAction</code> with
* privileges enabled and restricted by the specified
* <code>AccessControlContext</code> and with a privilege scope limited by
* specified <code>Permission</code> arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* <code>AccessControlContext</code>.
* <p>
* If the action's <code>run</code> method throws an (unchecked) exception,
* it will propagate through this method.
*
* <p> This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
*
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* <code>null</code>,
* then no additional restriction is applied.
* @param perms the <code>Permission</code> arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's <code>run</code> method.
*
* @throws PrivilegedActionException if the specified action's
* <code>run</code> method threw a <i>checked</i> exception
* @throws NullPointerException if action or perms or any element of
* perms is <code>null</code>
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
* @see java.security.DomainCombiner
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action,
AccessControlContext context,
Permission... perms)
throws PrivilegedActionException
{
AccessControlContext parent = getContext();
DomainCombiner dc = parent.getCombiner();
if (dc == null && context != null) {
dc = context.getCombiner();
}
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(dc, caller,
parent, context, perms));
}
/** /**
* Returns the AccessControl context. i.e., it gets * Returns the AccessControl context. i.e., it gets
* the protection domains of all the callers on the stack, * the protection domains of all the callers on the stack,
...@@ -481,6 +731,7 @@ public final class AccessController { ...@@ -481,6 +731,7 @@ public final class AccessController {
private static native AccessControlContext getStackAccessControlContext(); private static native AccessControlContext getStackAccessControlContext();
/** /**
* Returns the "inherited" AccessControl context. This is the context * Returns the "inherited" AccessControl context. This is the context
* that existed when the thread was created. Package private so * that existed when the thread was created. Package private so
...@@ -491,9 +742,9 @@ public final class AccessController { ...@@ -491,9 +742,9 @@ public final class AccessController {
/** /**
* This method takes a "snapshot" of the current calling context, which * This method takes a "snapshot" of the current calling context, which
* includes the current Thread's inherited AccessControlContext, * includes the current Thread's inherited AccessControlContext and any
* and places it in an AccessControlContext object. This context may then * limited privilege scope, and places it in an AccessControlContext object.
* be checked at a later point, possibly in another thread. * This context may then be checked at a later point, possibly in another thread.
* *
* @see AccessControlContext * @see AccessControlContext
* *
...@@ -531,7 +782,7 @@ public final class AccessController { ...@@ -531,7 +782,7 @@ public final class AccessController {
*/ */
public static void checkPermission(Permission perm) public static void checkPermission(Permission perm)
throws AccessControlException throws AccessControlException
{ {
//System.err.println("checkPermission "+perm); //System.err.println("checkPermission "+perm);
//Thread.currentThread().dumpStack(); //Thread.currentThread().dumpStack();
......
/* /*
* Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -112,10 +112,10 @@ public class DigestOutputStream extends FilterOutputStream { ...@@ -112,10 +112,10 @@ public class DigestOutputStream extends FilterOutputStream {
* @see MessageDigest#update(byte) * @see MessageDigest#update(byte)
*/ */
public void write(int b) throws IOException { public void write(int b) throws IOException {
out.write(b);
if (on) { if (on) {
digest.update((byte)b); digest.update((byte)b);
} }
out.write(b);
} }
/** /**
...@@ -142,10 +142,10 @@ public class DigestOutputStream extends FilterOutputStream { ...@@ -142,10 +142,10 @@ public class DigestOutputStream extends FilterOutputStream {
* @see MessageDigest#update(byte[], int, int) * @see MessageDigest#update(byte[], int, int)
*/ */
public void write(byte[] b, int off, int len) throws IOException { public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
if (on) { if (on) {
digest.update(b, off, len); digest.update(b, off, len);
} }
out.write(b, off, len);
} }
/** /**
......
...@@ -59,7 +59,7 @@ import sun.util.locale.provider.TimeZoneNameUtility; ...@@ -59,7 +59,7 @@ import sun.util.locale.provider.TimeZoneNameUtility;
* <code>DateFormatSymbols</code> is a public class for encapsulating * <code>DateFormatSymbols</code> is a public class for encapsulating
* localizable date-time formatting data, such as the names of the * localizable date-time formatting data, such as the names of the
* months, the names of the days of the week, and the time zone data. * months, the names of the days of the week, and the time zone data.
* <code>DateFormat</code> and <code>SimpleDateFormat</code> both use * <code>SimpleDateFormat</code> uses
* <code>DateFormatSymbols</code> to encapsulate this information. * <code>DateFormatSymbols</code> to encapsulate this information.
* *
* <p> * <p>
......
...@@ -271,7 +271,7 @@ final class DigitList implements Cloneable { ...@@ -271,7 +271,7 @@ final class DigitList implements Cloneable {
* @param maximumFractionDigits The most fractional digits which should * @param maximumFractionDigits The most fractional digits which should
* be converted. * be converted.
*/ */
public final void set(boolean isNegative, double source, int maximumFractionDigits) { final void set(boolean isNegative, double source, int maximumFractionDigits) {
set(isNegative, source, maximumFractionDigits, true); set(isNegative, source, maximumFractionDigits, true);
} }
...@@ -288,10 +288,11 @@ final class DigitList implements Cloneable { ...@@ -288,10 +288,11 @@ final class DigitList implements Cloneable {
*/ */
final void set(boolean isNegative, double source, int maximumDigits, boolean fixedPoint) { final void set(boolean isNegative, double source, int maximumDigits, boolean fixedPoint) {
FloatingDecimal fd = new FloatingDecimal(source); FloatingDecimal.BinaryToASCIIConverter fdConverter = FloatingDecimal.getBinaryToASCIIConverter(source);
boolean hasBeenRoundedUp = fd.digitsRoundedUp(); boolean hasBeenRoundedUp = fdConverter.digitsRoundedUp();
boolean allDecimalDigits = fd.decimalDigitsExact(); boolean allDecimalDigits = fdConverter.decimalDigitsExact();
String digitsString = fd.toJavaFormatString(); assert !fdConverter.isExceptional();
String digitsString = fdConverter.toJavaFormatString();
set(isNegative, digitsString, set(isNegative, digitsString,
hasBeenRoundedUp, allDecimalDigits, hasBeenRoundedUp, allDecimalDigits,
...@@ -305,9 +306,9 @@ final class DigitList implements Cloneable { ...@@ -305,9 +306,9 @@ final class DigitList implements Cloneable {
* @param allDecimalDigits Boolean value indicating if the digits in s are * @param allDecimalDigits Boolean value indicating if the digits in s are
* an exact decimal representation of the double that was passed. * an exact decimal representation of the double that was passed.
*/ */
final void set(boolean isNegative, String s, private void set(boolean isNegative, String s,
boolean roundedUp, boolean allDecimalDigits, boolean roundedUp, boolean allDecimalDigits,
int maximumDigits, boolean fixedPoint) { int maximumDigits, boolean fixedPoint) {
this.isNegative = isNegative; this.isNegative = isNegative;
int len = s.length(); int len = s.length();
char[] source = getDataChars(len); char[] source = getDataChars(len);
...@@ -607,7 +608,7 @@ final class DigitList implements Cloneable { ...@@ -607,7 +608,7 @@ final class DigitList implements Cloneable {
/** /**
* Utility routine to set the value of the digit list from a long * Utility routine to set the value of the digit list from a long
*/ */
public final void set(boolean isNegative, long source) { final void set(boolean isNegative, long source) {
set(isNegative, source, 0); set(isNegative, source, 0);
} }
...@@ -620,7 +621,7 @@ final class DigitList implements Cloneable { ...@@ -620,7 +621,7 @@ final class DigitList implements Cloneable {
* If maximumDigits is lower than the number of significant digits * If maximumDigits is lower than the number of significant digits
* in source, the representation will be rounded. Ignored if <= 0. * in source, the representation will be rounded. Ignored if <= 0.
*/ */
public final void set(boolean isNegative, long source, int maximumDigits) { final void set(boolean isNegative, long source, int maximumDigits) {
this.isNegative = isNegative; this.isNegative = isNegative;
// This method does not expect a negative number. However, // This method does not expect a negative number. However,
......
...@@ -1845,6 +1845,8 @@ public class SimpleDateFormat extends DateFormat { ...@@ -1845,6 +1845,8 @@ public class SimpleDateFormat extends DateFormat {
} }
++pos.index; ++pos.index;
} }
// Remember the actual start index
int actualStart = pos.index;
parsing: parsing:
{ {
...@@ -1924,9 +1926,9 @@ public class SimpleDateFormat extends DateFormat { ...@@ -1924,9 +1926,9 @@ public class SimpleDateFormat extends DateFormat {
// we made adjustments to place the 2-digit year in the proper // we made adjustments to place the 2-digit year in the proper
// century, for parsed strings from "00" to "99". Any other string // century, for parsed strings from "00" to "99". Any other string
// is treated literally: "2250", "-1", "1", "002". // is treated literally: "2250", "-1", "1", "002".
if (count <= 2 && (pos.index - start) == 2 if (count <= 2 && (pos.index - actualStart) == 2
&& Character.isDigit(text.charAt(start)) && Character.isDigit(text.charAt(actualStart))
&& Character.isDigit(text.charAt(start+1))) { && Character.isDigit(text.charAt(actualStart + 1))) {
// Assume for example that the defaultCenturyStart is 6/18/1903. // Assume for example that the defaultCenturyStart is 6/18/1903.
// This means that two-digit years will be forced into the range // This means that two-digit years will be forced into the range
// 6/18/1903 to 6/17/2003. As a result, years 00, 01, and 02 // 6/18/1903 to 6/17/2003. As a result, years 00, 01, and 02
......
...@@ -86,9 +86,13 @@ class ComparableTimSort { ...@@ -86,9 +86,13 @@ class ComparableTimSort {
private static final int INITIAL_TMP_STORAGE_LENGTH = 256; private static final int INITIAL_TMP_STORAGE_LENGTH = 256;
/** /**
* Temp storage for merges. * Temp storage for merges. A workspace array may optionally be
* provided in constructor, and if so will be used as long as it
* is big enough.
*/ */
private Object[] tmp; private Object[] tmp;
private int tmpBase; // base of tmp array slice
private int tmpLen; // length of tmp array slice
/** /**
* A stack of pending runs yet to be merged. Run i starts at * A stack of pending runs yet to be merged. Run i starts at
...@@ -108,15 +112,27 @@ class ComparableTimSort { ...@@ -108,15 +112,27 @@ class ComparableTimSort {
* Creates a TimSort instance to maintain the state of an ongoing sort. * Creates a TimSort instance to maintain the state of an ongoing sort.
* *
* @param a the array to be sorted * @param a the array to be sorted
* @param work a workspace array (slice)
* @param workBase origin of usable space in work array
* @param workLen usable size of work array
*/ */
private ComparableTimSort(Object[] a) { private ComparableTimSort(Object[] a, Object[] work, int workBase, int workLen) {
this.a = a; this.a = a;
// Allocate temp storage (which may be increased later if necessary) // Allocate temp storage (which may be increased later if necessary)
int len = a.length; int len = a.length;
Object[] newArray = new Object[len < 2 * INITIAL_TMP_STORAGE_LENGTH ? int tlen = (len < 2 * INITIAL_TMP_STORAGE_LENGTH) ?
len >>> 1 : INITIAL_TMP_STORAGE_LENGTH]; len >>> 1 : INITIAL_TMP_STORAGE_LENGTH;
tmp = newArray; if (work == null || workLen < tlen || workBase + tlen > work.length) {
tmp = new Object[tlen];
tmpBase = 0;
tmpLen = tlen;
}
else {
tmp = work;
tmpBase = workBase;
tmpLen = workLen;
}
/* /*
* Allocate runs-to-be-merged stack (which cannot be expanded). The * Allocate runs-to-be-merged stack (which cannot be expanded). The
...@@ -136,17 +152,28 @@ class ComparableTimSort { ...@@ -136,17 +152,28 @@ class ComparableTimSort {
} }
/* /*
* The next two methods (which are package private and static) constitute * The next method (package private and static) constitutes the
* the entire API of this class. Each of these methods obeys the contract * entire API of this class.
* of the public method with the same signature in java.util.Arrays.
*/ */
static void sort(Object[] a) { /**
sort(a, 0, a.length); * Sorts the given range, using the given workspace array slice
} * for temp storage when possible. This method is designed to be
* invoked from public methods (in class Arrays) after performing
* any necessary array bounds checks and expanding parameters into
* the required forms.
*
* @param a the array to be sorted
* @param lo the index of the first element, inclusive, to be sorted
* @param hi the index of the last element, exclusive, to be sorted
* @param work a workspace array (slice)
* @param workBase origin of usable space in work array
* @param workLen usable size of work array
* @since 1.8
*/
static void sort(Object[] a, int lo, int hi, Object[] work, int workBase, int workLen) {
assert a != null && lo >= 0 && lo <= hi && hi <= a.length;
static void sort(Object[] a, int lo, int hi) {
rangeCheck(a.length, lo, hi);
int nRemaining = hi - lo; int nRemaining = hi - lo;
if (nRemaining < 2) if (nRemaining < 2)
return; // Arrays of size 0 and 1 are always sorted return; // Arrays of size 0 and 1 are always sorted
...@@ -163,7 +190,7 @@ class ComparableTimSort { ...@@ -163,7 +190,7 @@ class ComparableTimSort {
* extending short natural runs to minRun elements, and merging runs * extending short natural runs to minRun elements, and merging runs
* to maintain stack invariant. * to maintain stack invariant.
*/ */
ComparableTimSort ts = new ComparableTimSort(a); ComparableTimSort ts = new ComparableTimSort(a, work, workBase, workLen);
int minRun = minRunLength(nRemaining); int minRun = minRunLength(nRemaining);
do { do {
// Identify next run // Identify next run
...@@ -619,11 +646,11 @@ class ComparableTimSort { ...@@ -619,11 +646,11 @@ class ComparableTimSort {
// Copy first run into temp array // Copy first run into temp array
Object[] a = this.a; // For performance Object[] a = this.a; // For performance
Object[] tmp = ensureCapacity(len1); Object[] tmp = ensureCapacity(len1);
System.arraycopy(a, base1, tmp, 0, len1);
int cursor1 = 0; // Indexes into tmp array int cursor1 = tmpBase; // Indexes into tmp array
int cursor2 = base2; // Indexes int a int cursor2 = base2; // Indexes int a
int dest = base1; // Indexes int a int dest = base1; // Indexes int a
System.arraycopy(a, base1, tmp, cursor1, len1);
// Move first element of second run and deal with degenerate cases // Move first element of second run and deal with degenerate cases
a[dest++] = a[cursor2++]; a[dest++] = a[cursor2++];
...@@ -736,16 +763,17 @@ class ComparableTimSort { ...@@ -736,16 +763,17 @@ class ComparableTimSort {
// Copy second run into temp array // Copy second run into temp array
Object[] a = this.a; // For performance Object[] a = this.a; // For performance
Object[] tmp = ensureCapacity(len2); Object[] tmp = ensureCapacity(len2);
System.arraycopy(a, base2, tmp, 0, len2); int tmpBase = this.tmpBase;
System.arraycopy(a, base2, tmp, tmpBase, len2);
int cursor1 = base1 + len1 - 1; // Indexes into a int cursor1 = base1 + len1 - 1; // Indexes into a
int cursor2 = len2 - 1; // Indexes into tmp array int cursor2 = tmpBase + len2 - 1; // Indexes into tmp array
int dest = base2 + len2 - 1; // Indexes into a int dest = base2 + len2 - 1; // Indexes into a
// Move last element of first run and deal with degenerate cases // Move last element of first run and deal with degenerate cases
a[dest--] = a[cursor1--]; a[dest--] = a[cursor1--];
if (--len1 == 0) { if (--len1 == 0) {
System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2); System.arraycopy(tmp, tmpBase, a, dest - (len2 - 1), len2);
return; return;
} }
if (len2 == 1) { if (len2 == 1) {
...@@ -803,7 +831,7 @@ class ComparableTimSort { ...@@ -803,7 +831,7 @@ class ComparableTimSort {
if (--len2 == 1) if (--len2 == 1)
break outer; break outer;
count2 = len2 - gallopLeft((Comparable) a[cursor1], tmp, 0, len2, len2 - 1); count2 = len2 - gallopLeft((Comparable) a[cursor1], tmp, tmpBase, len2, len2 - 1);
if (count2 != 0) { if (count2 != 0) {
dest -= count2; dest -= count2;
cursor2 -= count2; cursor2 -= count2;
...@@ -835,7 +863,7 @@ class ComparableTimSort { ...@@ -835,7 +863,7 @@ class ComparableTimSort {
} else { } else {
assert len1 == 0; assert len1 == 0;
assert len2 > 0; assert len2 > 0;
System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2); System.arraycopy(tmp, tmpBase, a, dest - (len2 - 1), len2);
} }
} }
...@@ -848,7 +876,7 @@ class ComparableTimSort { ...@@ -848,7 +876,7 @@ class ComparableTimSort {
* @return tmp, whether or not it grew * @return tmp, whether or not it grew
*/ */
private Object[] ensureCapacity(int minCapacity) { private Object[] ensureCapacity(int minCapacity) {
if (tmp.length < minCapacity) { if (tmpLen < minCapacity) {
// Compute smallest power of 2 > minCapacity // Compute smallest power of 2 > minCapacity
int newSize = minCapacity; int newSize = minCapacity;
newSize |= newSize >> 1; newSize |= newSize >> 1;
...@@ -863,30 +891,13 @@ class ComparableTimSort { ...@@ -863,30 +891,13 @@ class ComparableTimSort {
else else
newSize = Math.min(newSize, a.length >>> 1); newSize = Math.min(newSize, a.length >>> 1);
@SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
Object[] newArray = new Object[newSize]; Object[] newArray = new Object[newSize];
tmp = newArray; tmp = newArray;
tmpLen = newSize;
tmpBase = 0;
} }
return tmp; return tmp;
} }
/**
* Checks that fromIndex and toIndex are in range, and throws an
* appropriate exception if they aren't.
*
* @param arrayLen the length of the array
* @param fromIndex the index of the first element of the range
* @param toIndex the index after the last element of the range
* @throws IllegalArgumentException if fromIndex > toIndex
* @throws ArrayIndexOutOfBoundsException if fromIndex < 0
* or toIndex > arrayLen
*/
private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) {
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex+")");
if (fromIndex < 0)
throw new ArrayIndexOutOfBoundsException(fromIndex);
if (toIndex > arrayLen)
throw new ArrayIndexOutOfBoundsException(toIndex);
}
} }
/* /*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -2807,10 +2807,10 @@ public final class Formatter implements Closeable, Flushable { ...@@ -2807,10 +2807,10 @@ public final class Formatter implements Closeable, Flushable {
cal = Calendar.getInstance(l == null ? Locale.US : l); cal = Calendar.getInstance(l == null ? Locale.US : l);
cal.setTime((Date)arg); cal.setTime((Date)arg);
} else if (arg instanceof Calendar) { } else if (arg instanceof Calendar) {
cal = (Calendar) ((Calendar)arg).clone(); cal = (Calendar) ((Calendar) arg).clone();
cal.setLenient(true); cal.setLenient(true);
} else if (arg instanceof TemporalAccessor) { } else if (arg instanceof TemporalAccessor) {
print((TemporalAccessor)arg, c, l); print((TemporalAccessor) arg, c, l);
return; return;
} else { } else {
failConversion(c, arg); failConversion(c, arg);
...@@ -3242,13 +3242,10 @@ public final class Formatter implements Closeable, Flushable { ...@@ -3242,13 +3242,10 @@ public final class Formatter implements Closeable, Flushable {
int prec = (precision == -1 ? 6 : precision); int prec = (precision == -1 ? 6 : precision);
FormattedFloatingDecimal fd FormattedFloatingDecimal fd
= new FormattedFloatingDecimal(value, prec, = FormattedFloatingDecimal.valueOf(value, prec,
FormattedFloatingDecimal.Form.SCIENTIFIC); FormattedFloatingDecimal.Form.SCIENTIFIC);
char[] v = new char[MAX_FD_CHARS]; char[] mant = addZeros(fd.getMantissa(), prec);
int len = fd.getChars(v);
char[] mant = addZeros(mantissa(v, len), prec);
// If the precision is zero and the '#' flag is set, add the // If the precision is zero and the '#' flag is set, add the
// requested decimal point. // requested decimal point.
...@@ -3256,7 +3253,7 @@ public final class Formatter implements Closeable, Flushable { ...@@ -3256,7 +3253,7 @@ public final class Formatter implements Closeable, Flushable {
mant = addDot(mant); mant = addDot(mant);
char[] exp = (value == 0.0) char[] exp = (value == 0.0)
? new char[] {'+','0','0'} : exponent(v, len); ? new char[] {'+','0','0'} : fd.getExponent();
int newW = width; int newW = width;
if (width != -1) if (width != -1)
...@@ -3279,15 +3276,10 @@ public final class Formatter implements Closeable, Flushable { ...@@ -3279,15 +3276,10 @@ public final class Formatter implements Closeable, Flushable {
int prec = (precision == -1 ? 6 : precision); int prec = (precision == -1 ? 6 : precision);
FormattedFloatingDecimal fd FormattedFloatingDecimal fd
= new FormattedFloatingDecimal(value, prec, = FormattedFloatingDecimal.valueOf(value, prec,
FormattedFloatingDecimal.Form.DECIMAL_FLOAT); FormattedFloatingDecimal.Form.DECIMAL_FLOAT);
// MAX_FD_CHARS + 1 (round?)
char[] v = new char[MAX_FD_CHARS + 1
+ Math.abs(fd.getExponent())];
int len = fd.getChars(v);
char[] mant = addZeros(mantissa(v, len), prec); char[] mant = addZeros(fd.getMantissa(), prec);
// If the precision is zero and the '#' flag is set, add the // If the precision is zero and the '#' flag is set, add the
// requested decimal point. // requested decimal point.
...@@ -3306,22 +3298,17 @@ public final class Formatter implements Closeable, Flushable { ...@@ -3306,22 +3298,17 @@ public final class Formatter implements Closeable, Flushable {
prec = 1; prec = 1;
FormattedFloatingDecimal fd FormattedFloatingDecimal fd
= new FormattedFloatingDecimal(value, prec, = FormattedFloatingDecimal.valueOf(value, prec,
FormattedFloatingDecimal.Form.GENERAL); FormattedFloatingDecimal.Form.GENERAL);
// MAX_FD_CHARS + 1 (round?) char[] exp = fd.getExponent();
char[] v = new char[MAX_FD_CHARS + 1
+ Math.abs(fd.getExponent())];
int len = fd.getChars(v);
char[] exp = exponent(v, len);
if (exp != null) { if (exp != null) {
prec -= 1; prec -= 1;
} else { } else {
prec = prec - (value == 0 ? 0 : fd.getExponentRounded()) - 1; prec = prec - (value == 0 ? 0 : fd.getExponentRounded()) - 1;
} }
char[] mant = addZeros(mantissa(v, len), prec); char[] mant = addZeros(fd.getMantissa(), prec);
// If the precision is zero and the '#' flag is set, add the // If the precision is zero and the '#' flag is set, add the
// requested decimal point. // requested decimal point.
if (f.contains(Flags.ALTERNATE) && (prec == 0)) if (f.contains(Flags.ALTERNATE) && (prec == 0))
...@@ -3380,30 +3367,6 @@ public final class Formatter implements Closeable, Flushable { ...@@ -3380,30 +3367,6 @@ public final class Formatter implements Closeable, Flushable {
} }
} }
private char[] mantissa(char[] v, int len) {
int i;
for (i = 0; i < len; i++) {
if (v[i] == 'e')
break;
}
char[] tmp = new char[i];
System.arraycopy(v, 0, tmp, 0, i);
return tmp;
}
private char[] exponent(char[] v, int len) {
int i;
for (i = len - 1; i >= 0; i--) {
if (v[i] == 'e')
break;
}
if (i == -1)
return null;
char[] tmp = new char[len - i - 1];
System.arraycopy(v, i + 1, tmp, 0, len - i - 1);
return tmp;
}
// Add zeros to the requested precision. // Add zeros to the requested precision.
private char[] addZeros(char[] v, int prec) { private char[] addZeros(char[] v, int prec) {
// Look for the dot. If we don't find one, the we'll need to add // Look for the dot. If we don't find one, the we'll need to add
......
...@@ -180,13 +180,27 @@ public class Hashtable<K,V> ...@@ -180,13 +180,27 @@ public class Hashtable<K,V>
*/ */
static final long HASHSEED_OFFSET; static final long HASHSEED_OFFSET;
static final boolean USE_HASHSEED;
static { static {
try { String hashSeedProp = java.security.AccessController.doPrivileged(
UNSAFE = sun.misc.Unsafe.getUnsafe(); new sun.security.action.GetPropertyAction(
HASHSEED_OFFSET = UNSAFE.objectFieldOffset( "jdk.map.useRandomSeed"));
Hashtable.class.getDeclaredField("hashSeed")); boolean localBool = (null != hashSeedProp)
} catch (NoSuchFieldException | SecurityException e) { ? Boolean.parseBoolean(hashSeedProp) : false;
throw new InternalError("Failed to record hashSeed offset", e); USE_HASHSEED = localBool;
if (USE_HASHSEED) {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
HASHSEED_OFFSET = UNSAFE.objectFieldOffset(
Hashtable.class.getDeclaredField("hashSeed"));
} catch (NoSuchFieldException | SecurityException e) {
throw new InternalError("Failed to record hashSeed offset", e);
}
} else {
UNSAFE = null;
HASHSEED_OFFSET = 0;
} }
} }
} }
...@@ -194,21 +208,24 @@ public class Hashtable<K,V> ...@@ -194,21 +208,24 @@ public class Hashtable<K,V>
/** /**
* A randomizing value associated with this instance that is applied to * A randomizing value associated with this instance that is applied to
* hash code of keys to make hash collisions harder to find. * hash code of keys to make hash collisions harder to find.
*
* Non-final so it can be set lazily, but be sure not to set more than once.
*/ */
transient final int hashSeed = sun.misc.Hashing.randomHashSeed(this); transient final int hashSeed;
private int hash(Object k) { /**
if (k instanceof String) { * Return an initial value for the hashSeed, or 0 if the random seed is not
return ((String)k).hash32(); * enabled.
*/
final int initHashSeed() {
if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) {
return sun.misc.Hashing.randomHashSeed(this);
} }
return 0;
}
int h = hashSeed ^ k.hashCode(); private int hash(Object k) {
return hashSeed ^ k.hashCode();
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
} }
/** /**
...@@ -232,6 +249,7 @@ public class Hashtable<K,V> ...@@ -232,6 +249,7 @@ public class Hashtable<K,V>
this.loadFactor = loadFactor; this.loadFactor = loadFactor;
table = new Entry<?,?>[initialCapacity]; table = new Entry<?,?>[initialCapacity];
threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1); threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
hashSeed = initHashSeed();
} }
/** /**
...@@ -1187,8 +1205,10 @@ public class Hashtable<K,V> ...@@ -1187,8 +1205,10 @@ public class Hashtable<K,V>
s.defaultReadObject(); s.defaultReadObject();
// set hashMask // set hashMask
Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET, if (Holder.USE_HASHSEED) {
sun.misc.Hashing.randomHashSeed(this)); Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET,
sun.misc.Hashing.randomHashSeed(this));
}
// Read the original length of the array and number of elements // Read the original length of the array and number of elements
int origlength = s.readInt(); int origlength = s.readInt();
......
...@@ -159,7 +159,7 @@ public class IntSummaryStatistics implements IntConsumer { ...@@ -159,7 +159,7 @@ public class IntSummaryStatistics implements IntConsumer {
*/ */
public String toString() { public String toString() {
return String.format( return String.format(
"%s{count=%d, sum=%d, min=%d, average=%d, max=%d}", "%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
this.getClass().getSimpleName(), this.getClass().getSimpleName(),
getCount(), getCount(),
getSum(), getSum(),
......
...@@ -55,9 +55,9 @@ import java.io.*; ...@@ -55,9 +55,9 @@ import java.io.*;
* order they were presented.) * order they were presented.)
* *
* <p>A special {@link #LinkedHashMap(int,float,boolean) constructor} is * <p>A special {@link #LinkedHashMap(int,float,boolean) constructor} is
* provided to create a linked hash map whose order of iteration is the order * provided to create a <tt>LinkedHashMap</tt> whose order of iteration is the
* in which its entries were last accessed, from least-recently accessed to * order in which its entries were last accessed, from least-recently accessed
* most-recently (<i>access-order</i>). This kind of map is well-suited to * to most-recently (<i>access-order</i>). This kind of map is well-suited to
* building LRU caches. Invoking the <tt>put</tt> or <tt>get</tt> method * building LRU caches. Invoking the <tt>put</tt> or <tt>get</tt> method
* results in an access to the corresponding entry (assuming it exists after * results in an access to the corresponding entry (assuming it exists after
* the invocation completes). The <tt>putAll</tt> method generates one entry * the invocation completes). The <tt>putAll</tt> method generates one entry
...@@ -242,23 +242,6 @@ public class LinkedHashMap<K,V> ...@@ -242,23 +242,6 @@ public class LinkedHashMap<K,V>
header.before = header.after = header; header.before = header.after = header;
} }
/**
* Transfers all entries to new table array. This method is called
* by superclass resize. It is overridden for performance, as it is
* faster to iterate using our linked list.
*/
@Override
@SuppressWarnings("unchecked")
void transfer(HashMap.Entry[] newTable) {
int newCapacity = newTable.length;
for (Entry<K,V> e = header.after; e != header; e = e.after) {
int index = indexFor(e.hash, newCapacity);
e.next = (HashMap.Entry<K,V>)newTable[index];
newTable[index] = e;
}
}
/** /**
* Returns <tt>true</tt> if this map maps one or more keys to the * Returns <tt>true</tt> if this map maps one or more keys to the
* specified value. * specified value.
...@@ -320,7 +303,7 @@ public class LinkedHashMap<K,V> ...@@ -320,7 +303,7 @@ public class LinkedHashMap<K,V>
// These fields comprise the doubly linked list used for iteration. // These fields comprise the doubly linked list used for iteration.
Entry<K,V> before, after; Entry<K,V> before, after;
Entry(int hash, K key, V value, HashMap.Entry<K,V> next) { Entry(int hash, K key, V value, Object next) {
super(hash, key, value, next); super(hash, key, value, next);
} }
...@@ -344,7 +327,7 @@ public class LinkedHashMap<K,V> ...@@ -344,7 +327,7 @@ public class LinkedHashMap<K,V>
/** /**
* This method is invoked by the superclass whenever the value * This method is invoked by the superclass whenever the value
* of a pre-existing entry is read by Map.get or modified by Map.set. * of a pre-existing entry is read by Map.get or modified by Map.put.
* If the enclosing Map is access-ordered, it moves the entry * If the enclosing Map is access-ordered, it moves the entry
* to the end of the list; otherwise, it does nothing. * to the end of the list; otherwise, it does nothing.
*/ */
...@@ -422,8 +405,9 @@ public class LinkedHashMap<K,V> ...@@ -422,8 +405,9 @@ public class LinkedHashMap<K,V>
* allocated entry to get inserted at the end of the linked list and * allocated entry to get inserted at the end of the linked list and
* removes the eldest entry if appropriate. * removes the eldest entry if appropriate.
*/ */
void addEntry(int hash, K key, V value, int bucketIndex) { @Override
super.addEntry(hash, key, value, bucketIndex); void addEntry(int hash, K key, V value, int bucketIndex, boolean checkIfNeedTree) {
super.addEntry(hash, key, value, bucketIndex, checkIfNeedTree);
// Remove eldest entry if instructed // Remove eldest entry if instructed
Entry<K,V> eldest = header.after; Entry<K,V> eldest = header.after;
...@@ -432,17 +416,14 @@ public class LinkedHashMap<K,V> ...@@ -432,17 +416,14 @@ public class LinkedHashMap<K,V>
} }
} }
/** /*
* This override differs from addEntry in that it doesn't resize the * Create a new LinkedHashMap.Entry and setup the before/after pointers
* table or remove the eldest entry.
*/ */
void createEntry(int hash, K key, V value, int bucketIndex) { @Override
@SuppressWarnings("unchecked") HashMap.Entry<K,V> newEntry(int hash, K key, V value, Object next) {
HashMap.Entry<K,V> old = (HashMap.Entry<K,V>)table[bucketIndex]; Entry<K,V> newEntry = new Entry<>(hash, key, value, next);
Entry<K,V> e = new Entry<>(hash, key, value, old); newEntry.addBefore(header);
table[bucketIndex] = e; return newEntry;
e.addBefore(header);
size++;
} }
/** /**
......
...@@ -89,7 +89,7 @@ import sun.util.ResourceBundleEnumeration; ...@@ -89,7 +89,7 @@ import sun.util.ResourceBundleEnumeration;
* *
* public class MyResources_fr extends ListResourceBundle { * public class MyResources_fr extends ListResourceBundle {
* protected Object[][] getContents() { * protected Object[][] getContents() {
* return new Object[][] = { * return new Object[][] {
* // LOCALIZE THIS * // LOCALIZE THIS
* {"s1", "Le disque \"{1}\" {0}."}, // MessageFormat pattern * {"s1", "Le disque \"{1}\" {0}."}, // MessageFormat pattern
* {"s2", "1"}, // location of {0} in pattern * {"s2", "1"}, // location of {0} in pattern
......
...@@ -171,7 +171,7 @@ public class LongSummaryStatistics implements LongConsumer, IntConsumer { ...@@ -171,7 +171,7 @@ public class LongSummaryStatistics implements LongConsumer, IntConsumer {
*/ */
public String toString() { public String toString() {
return String.format( return String.format(
"%s{count=%d, sum=%d, min=%d, average=%d, max=%d}", "%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
this.getClass().getSimpleName(), this.getClass().getSimpleName(),
getCount(), getCount(),
getSum(), getSum(),
......
...@@ -91,6 +91,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> { ...@@ -91,6 +91,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
* @throws NullPointerException if the specified action is null * @throws NullPointerException if the specified action is null
*/ */
default void forEachRemaining(IntConsumer action) { default void forEachRemaining(IntConsumer action) {
Objects.requireNonNull(action);
while (hasNext()) while (hasNext())
action.accept(nextInt()); action.accept(nextInt());
} }
...@@ -123,6 +124,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> { ...@@ -123,6 +124,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
forEachRemaining((IntConsumer) action); forEachRemaining((IntConsumer) action);
} }
else { else {
// The method reference action::accept is never null
Objects.requireNonNull(action);
if (Tripwire.ENABLED) if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.forEachRemainingInt(action::accept)"); Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.forEachRemainingInt(action::accept)");
forEachRemaining((IntConsumer) action::accept); forEachRemaining((IntConsumer) action::accept);
...@@ -162,6 +165,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> { ...@@ -162,6 +165,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
* @throws NullPointerException if the specified action is null * @throws NullPointerException if the specified action is null
*/ */
default void forEachRemaining(LongConsumer action) { default void forEachRemaining(LongConsumer action) {
Objects.requireNonNull(action);
while (hasNext()) while (hasNext())
action.accept(nextLong()); action.accept(nextLong());
} }
...@@ -194,6 +198,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> { ...@@ -194,6 +198,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
forEachRemaining((LongConsumer) action); forEachRemaining((LongConsumer) action);
} }
else { else {
// The method reference action::accept is never null
Objects.requireNonNull(action);
if (Tripwire.ENABLED) if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.forEachRemainingLong(action::accept)"); Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.forEachRemainingLong(action::accept)");
forEachRemaining((LongConsumer) action::accept); forEachRemaining((LongConsumer) action::accept);
...@@ -232,6 +238,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> { ...@@ -232,6 +238,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
* @throws NullPointerException if the specified action is null * @throws NullPointerException if the specified action is null
*/ */
default void forEachRemaining(DoubleConsumer action) { default void forEachRemaining(DoubleConsumer action) {
Objects.requireNonNull(action);
while (hasNext()) while (hasNext())
action.accept(nextDouble()); action.accept(nextDouble());
} }
...@@ -265,6 +272,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> { ...@@ -265,6 +272,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
forEachRemaining((DoubleConsumer) action); forEachRemaining((DoubleConsumer) action);
} }
else { else {
// The method reference action::accept is never null
Objects.requireNonNull(action);
if (Tripwire.ENABLED) if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.forEachRemainingDouble(action::accept)"); Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.forEachRemainingDouble(action::accept)");
forEachRemaining((DoubleConsumer) action::accept); forEachRemaining((DoubleConsumer) action::accept);
......
...@@ -124,6 +124,8 @@ public class PropertyResourceBundle extends ResourceBundle { ...@@ -124,6 +124,8 @@ public class PropertyResourceBundle extends ResourceBundle {
* to read from. * to read from.
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
* @throws NullPointerException if <code>stream</code> is null * @throws NullPointerException if <code>stream</code> is null
* @throws IllegalArgumentException if {@code stream} contains a
* malformed Unicode escape sequence.
*/ */
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"})
public PropertyResourceBundle (InputStream stream) throws IOException { public PropertyResourceBundle (InputStream stream) throws IOException {
...@@ -142,6 +144,8 @@ public class PropertyResourceBundle extends ResourceBundle { ...@@ -142,6 +144,8 @@ public class PropertyResourceBundle extends ResourceBundle {
* read from. * read from.
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
* @throws NullPointerException if <code>reader</code> is null * @throws NullPointerException if <code>reader</code> is null
* @throws IllegalArgumentException if a malformed Unicode escape sequence appears
* from {@code reader}.
* @since 1.6 * @since 1.6
*/ */
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"})
......
...@@ -29,14 +29,6 @@ package java.util; ...@@ -29,14 +29,6 @@ package java.util;
* by a delimiter and optionally starting with a supplied prefix * by a delimiter and optionally starting with a supplied prefix
* and ending with a supplied suffix. * and ending with a supplied suffix.
* <p> * <p>
* For example, the String {@code "[George:Sally:Fred]"} may
* be constructed as follows:
* <pre> {@code
* StringJoiner sj = new StringJoiner(":", "[", "]");
* sj.add("George").add("Sally").add("Fred");
* String desiredString = sj.toString();
* }</pre>
* <p>
* Prior to adding something to the {@code StringJoiner}, its * Prior to adding something to the {@code StringJoiner}, its
* {@code sj.toString()} method will, by default, return {@code prefix + suffix}. * {@code sj.toString()} method will, by default, return {@code prefix + suffix}.
* However, if the {@code setEmptyValue} method is called, the {@code emptyValue} * However, if the {@code setEmptyValue} method is called, the {@code emptyValue}
...@@ -45,17 +37,28 @@ package java.util; ...@@ -45,17 +37,28 @@ package java.util;
* <code>"{}"</code>, where the {@code prefix} is <code>"{"</code>, the * <code>"{}"</code>, where the {@code prefix} is <code>"{"</code>, the
* {@code suffix} is <code>"}"</code> and nothing has been added to the * {@code suffix} is <code>"}"</code> and nothing has been added to the
* {@code StringJoiner}. * {@code StringJoiner}.
*
* @apiNote
* <p>The String {@code "[George:Sally:Fred]"} may be constructed as follows:
*
* <pre> {@code
* StringJoiner sj = new StringJoiner(":", "[", "]");
* sj.add("George").add("Sally").add("Fred");
* String desiredString = sj.toString();
* }</pre>
* <p> * <p>
* A {@code StringJoiner} may be employed to create formatted output from a * A {@code StringJoiner} may be employed to create formatted output from a
* collection using lambda expressions as shown in the following example. * {@link java.util.stream.Stream} using
* {@link java.util.stream.Collectors#toStringJoiner}. For example:
* *
* <pre> {@code * <pre> {@code
* List<Person> people = ... * List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
* String commaSeparatedNames = * String commaSeparatedNumbers = numbers.stream()
* people.map(p -> p.getName()).into(new StringJoiner(", ")).toString(); * .map(i -> i.toString())
* .collect(Collectors.toStringJoiner(", ")).toString();
* }</pre> * }</pre>
* *
* @author Jim Gish * @see java.util.stream.Collectors#toStringJoiner
* @since 1.8 * @since 1.8
*/ */
public final class StringJoiner { public final class StringJoiner {
......
...@@ -40,5 +40,5 @@ public interface BooleanSupplier { ...@@ -40,5 +40,5 @@ public interface BooleanSupplier {
* *
* @return a {@code boolean} value * @return a {@code boolean} value
*/ */
public boolean getAsBoolean(); boolean getAsBoolean();
} }
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册