mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-12 17:03:14 +00:00
Merge
This commit is contained in:
commit
29bddce0bb
@ -1,5 +1,5 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
FILES_export = \
|
||||
sun/management/ClassLoadingImpl.java \
|
||||
sun/management/DiagnosticCommandImpl.java \
|
||||
sun/management/FileSystemImpl.java \
|
||||
sun/management/Flag.java \
|
||||
sun/management/GarbageCollectorImpl.java \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
FILES_c = \
|
||||
ClassLoadingImpl.c \
|
||||
DiagnosticCommandImpl.c \
|
||||
FileSystemImpl.c \
|
||||
Flag.c \
|
||||
GarbageCollectorImpl.c \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -39,6 +39,10 @@ SUNWprivate_1.1 {
|
||||
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
|
||||
Java_com_sun_management_UnixOperatingSystem_initialize;
|
||||
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_Flag_getAllFlagNames;
|
||||
Java_sun_management_Flag_getFlags;
|
||||
|
||||
@ -390,12 +390,9 @@ ifeq ($(PLATFORM), linux)
|
||||
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv LINUX
|
||||
ifdef OPENJDK
|
||||
|
||||
FONTCONFIGS_SRC = $(PLATFORM_SRC)/classes/sun/awt/fontconfigs
|
||||
_FONTCONFIGS = \
|
||||
fontconfig.properties \
|
||||
fontconfig.SuSE.properties \
|
||||
fontconfig.Ubuntu.properties \
|
||||
fontconfig.Fedora.properties
|
||||
FONTCONFIGS_SRC =
|
||||
_FONTCONFIGS =
|
||||
|
||||
else
|
||||
|
||||
FONTCONFIGS_SRC = $(CLOSED_SRC)/solaris/classes/sun/awt/fontconfigs
|
||||
@ -441,7 +438,11 @@ endif # PLATFORM
|
||||
FONTCONFIGS = $(_FONTCONFIGS:%=$(LIBDIR)/%.src)
|
||||
BINARYFONTCONFIGS = $(_FONTCONFIGS:%.properties=$(LIBDIR)/%.bfc)
|
||||
|
||||
ifneq ("x$(_FONTCONFIGS)", "x")
|
||||
fontconfigs: $(FONTCONFIGS) $(BINARYFONTCONFIGS)
|
||||
else
|
||||
fontconfigs:
|
||||
endif
|
||||
|
||||
$(LIBDIR)/%.src: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%
|
||||
$(install-file)
|
||||
@ -455,9 +456,13 @@ $(LIBDIR)/%.bfc: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%.properties \
|
||||
$(call chmod-file, 444)
|
||||
@$(java-vm-cleanup)
|
||||
|
||||
ifneq ("x$(_FONTCONFIGS)", "x")
|
||||
fontconfigs.clean :
|
||||
$(RM) $(FONTCONFIGS)
|
||||
$(RM) $(BINARYFONTCONFIGS)
|
||||
else
|
||||
fontconfigs.clean :
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM), windows)
|
||||
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv WINDOWS
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
# (2)Added 2 new codepoints (KS X 1001:1998)
|
||||
# 0xA2E6 0x20AC # EURO Sign
|
||||
# 0xA2E7 0x00AE # Registered Sign
|
||||
# (3) KS X 1001:2002
|
||||
# 0xA2E8 0x327E # CIRCLED KOREAN CHARACTER JUEUI (Postal Code Mark)
|
||||
#
|
||||
0x00 0x0000
|
||||
0x01 0x0001
|
||||
@ -295,6 +297,7 @@
|
||||
#
|
||||
0xA2E6 0x20AC # EURO Sign
|
||||
0xA2E7 0x00AE # Registered Sign
|
||||
0xA2E8 0x327E # CIRCLED KOREAN CHARACTER JUEUI
|
||||
#
|
||||
0xA2E0 0x2116 # NUMERO SIGN
|
||||
0xA2E1 0x33C7 # SQUARE CO
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
|
||||
package build.tools.generatebreakiteratordata;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
@ -701,7 +702,14 @@ class CharSet {
|
||||
* the exact same characters as this one
|
||||
*/
|
||||
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,\
|
||||
DISABLE_SJAVAC:=true,\
|
||||
SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
|
||||
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
|
||||
$(JDK_OUTPUTDIR)/gensrc, \
|
||||
$(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
|
||||
INCLUDES := com/apple/jobjc,\
|
||||
EXCLUDES := tests/java/com/apple/jobjc,\
|
||||
BIN:=$(JDK_OUTPUTDIR)/jobjc_classes,\
|
||||
@ -355,7 +355,7 @@ $(eval $(call SetupJavaCompilation,BUILD_JOBJC_HEADERS,\
|
||||
SETUP:=GENERATE_JDKBYTECODE,\
|
||||
SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
|
||||
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
|
||||
$(JDK_OUTPUTDIR)/gensrc, \
|
||||
$(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
|
||||
INCLUDES := com/apple/jobjc,\
|
||||
EXCLUDES := tests/java/com/apple/jobjc,\
|
||||
BIN:=$(JDK_OUTPUTDIR)/jobjc_classes_headers,\
|
||||
|
||||
@ -36,11 +36,9 @@ ifeq ($(OPENJDK_TARGET_OS), linux)
|
||||
ifdef OPENJDK
|
||||
GENDATA_FONT_CONFIG_SRC_DIR := \
|
||||
$(JDK_TOPDIR)/src/solaris/classes/sun/awt/fontconfigs
|
||||
GENDATA_FONT_CONFIG_SRC_FILES := \
|
||||
fontconfig.properties \
|
||||
fontconfig.SuSE.properties \
|
||||
fontconfig.Ubuntu.properties \
|
||||
fontconfig.Fedora.properties
|
||||
# This is placeholder for possible fonconfig files which may
|
||||
# useful for some highly specialized Linux distributions
|
||||
GENDATA_FONT_CONFIG_SRC_FILES :=
|
||||
else
|
||||
GENDATA_FONT_CONFIG_SRC_DIR := \
|
||||
$(JDK_TOPDIR)/src/closed/solaris/classes/sun/awt/fontconfigs
|
||||
|
||||
@ -69,6 +69,9 @@ define typesAndBits
|
||||
$1_fulltype := character
|
||||
$1_Fulltype := Character
|
||||
$1_category := integralType
|
||||
$1_streams := streamableType
|
||||
$1_streamtype := int
|
||||
$1_Streamtype := Int
|
||||
$1_LBPV := 1
|
||||
endif
|
||||
|
||||
@ -97,7 +100,7 @@ define typesAndBits
|
||||
$1_Type := Long
|
||||
$1_fulltype := long
|
||||
$1_Fulltype := Long
|
||||
$1_category := integralType
|
||||
$1_category := integralType
|
||||
$1_LBPV := 3
|
||||
endif
|
||||
|
||||
@ -231,10 +234,13 @@ $$($1_DST) : $$($1_DEP) $(GENSRC_BUFFER_DST)/_the.buffer.dir
|
||||
$(TOOL_SPP) < $$($1_SRC) > $$($1_OUT).tmp \
|
||||
-K$$($1_type) \
|
||||
-K$$($1_category) \
|
||||
-K$$($1_streams) \
|
||||
-Dtype=$$($1_type) \
|
||||
-DType=$$($1_Type) \
|
||||
-Dfulltype=$$($1_fulltype) \
|
||||
-DFulltype=$$($1_Fulltype) \
|
||||
-Dstreamtype=$$($1_streamtype) \
|
||||
-DStreamtype=$$($1_Streamtype) \
|
||||
-Dx=$$($1_x) \
|
||||
-Dmemtype=$$($1_memtype) \
|
||||
-DMemtype=$$($1_Memtype) \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -39,6 +39,10 @@ SUNWprivate_1.1 {
|
||||
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
|
||||
Java_com_sun_management_UnixOperatingSystem_initialize;
|
||||
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_Flag_getAllFlagNames;
|
||||
Java_sun_management_Flag_getFlags;
|
||||
|
||||
@ -130,7 +130,17 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
}
|
||||
|
||||
public synchronized int charToGlyph(int unicode) {
|
||||
return charToGlyph((char)unicode);
|
||||
if (unicode >= 0x10000) {
|
||||
int[] glyphs = new int[2];
|
||||
char[] surrogates = new char[2];
|
||||
int base = unicode - 0x10000;
|
||||
surrogates[0] = (char)((base >>> 10) + HI_SURROGATE_START);
|
||||
surrogates[1] = (char)((base % 0x400) + LO_SURROGATE_START);
|
||||
charsToGlyphs(2, surrogates, glyphs);
|
||||
return glyphs[0];
|
||||
} else {
|
||||
return charToGlyph((char)unicode);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void charsToGlyphs(int count, char[] unicodes, int[] glyphs) {
|
||||
@ -138,9 +148,9 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
}
|
||||
|
||||
public synchronized void charsToGlyphs(int count, int[] unicodes, int[] glyphs) {
|
||||
final char[] unicodeChars = new char[count];
|
||||
for (int i = 0; i < count; i++) unicodeChars[i] = (char)unicodes[i];
|
||||
cache.get(count, unicodeChars, glyphs);
|
||||
for (int i = 0; i < count; i++) {
|
||||
glyphs[i] = charToGlyph(unicodes[i]);
|
||||
};
|
||||
}
|
||||
|
||||
// This mapper returns either the glyph code, or if the character can be
|
||||
@ -166,7 +176,7 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
firstLayerCache[1] = 1;
|
||||
}
|
||||
|
||||
public int get(final char index) {
|
||||
public synchronized int get(final int index) {
|
||||
if (index < FIRST_LAYER_SIZE) {
|
||||
// catch common glyphcodes
|
||||
return firstLayerCache[index];
|
||||
@ -179,12 +189,12 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
}
|
||||
|
||||
if (generalCache == null) return 0;
|
||||
final Integer value = generalCache.get(new Integer(index));
|
||||
final Integer value = generalCache.get(index);
|
||||
if (value == null) return 0;
|
||||
return value.intValue();
|
||||
}
|
||||
|
||||
public void put(final char index, final int value) {
|
||||
public synchronized void put(final int index, final int value) {
|
||||
if (index < FIRST_LAYER_SIZE) {
|
||||
// catch common glyphcodes
|
||||
firstLayerCache[index] = value;
|
||||
@ -204,7 +214,7 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
generalCache = new HashMap<Integer, Integer>();
|
||||
}
|
||||
|
||||
generalCache.put(new Integer(index), new Integer(value));
|
||||
generalCache.put(index, value);
|
||||
}
|
||||
|
||||
private class SparseBitShiftingTwoLayerArray {
|
||||
@ -220,14 +230,14 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
this.secondLayerLength = size >> shift;
|
||||
}
|
||||
|
||||
public int get(final char index) {
|
||||
public int get(final int index) {
|
||||
final int firstIndex = index >> shift;
|
||||
final int[] firstLayerRow = cache[firstIndex];
|
||||
if (firstLayerRow == null) return 0;
|
||||
return firstLayerRow[index - (firstIndex * (1 << shift))];
|
||||
}
|
||||
|
||||
public void put(final char index, final int value) {
|
||||
public void put(final int index, final int value) {
|
||||
final int firstIndex = index >> shift;
|
||||
int[] firstLayerRow = cache[firstIndex];
|
||||
if (firstLayerRow == null) {
|
||||
@ -237,77 +247,81 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
}
|
||||
}
|
||||
|
||||
public void get(int count, char[] indicies, int[] values){
|
||||
public synchronized void get(int count, char[] indicies, int[] values)
|
||||
{
|
||||
// "missed" is the count of 'char' that are not mapped.
|
||||
// Surrogates count for 2.
|
||||
// unmappedChars is the unique list of these chars.
|
||||
// unmappedCharIndices is the location in the original array
|
||||
int missed = 0;
|
||||
for(int i = 0; i < count; i++){
|
||||
char code = indicies[i];
|
||||
char[] unmappedChars = null;
|
||||
int [] unmappedCharIndices = null;
|
||||
|
||||
for (int i = 0; i < count; i++){
|
||||
int code = indicies[i];
|
||||
if (code >= HI_SURROGATE_START &&
|
||||
code <= HI_SURROGATE_END && i < count - 1)
|
||||
{
|
||||
char low = indicies[i + 1];
|
||||
if (low >= LO_SURROGATE_START && low <= LO_SURROGATE_END) {
|
||||
code = (code - HI_SURROGATE_START) * 0x400 +
|
||||
low - LO_SURROGATE_START + 0x10000;
|
||||
}
|
||||
}
|
||||
|
||||
final int value = get(code);
|
||||
if(value != 0){
|
||||
if (value != 0 && value != -1) {
|
||||
values[i] = value;
|
||||
}else{
|
||||
// zero this element out, because the caller does not
|
||||
// promise to keep it clean
|
||||
if (code >= 0x10000) {
|
||||
values[i+1] = INVISIBLE_GLYPH_ID;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
values[i] = 0;
|
||||
put(code, -1);
|
||||
if (unmappedChars == null) {
|
||||
// This is likely to be longer than we need,
|
||||
// but is the simplest and cheapest option.
|
||||
unmappedChars = new char[indicies.length];
|
||||
unmappedCharIndices = new int[indicies.length];
|
||||
}
|
||||
unmappedChars[missed] = indicies[i];
|
||||
unmappedCharIndices[missed] = i;
|
||||
if (code >= 0x10000) { // was a surrogate pair
|
||||
unmappedChars[++missed] = indicies[++i];
|
||||
}
|
||||
missed++;
|
||||
}
|
||||
}
|
||||
|
||||
if (missed == 0) return; // horray! everything is already cached!
|
||||
|
||||
final char[] filteredCodes = new char[missed]; // all index codes requested (partially filled)
|
||||
final int[] filteredIndicies = new int[missed]; // local indicies into filteredCodes array (totally filled)
|
||||
|
||||
// scan, mark, and store the index codes again to send into native
|
||||
int j = 0;
|
||||
int dupes = 0;
|
||||
for (int i = 0; i < count; i++){
|
||||
if (values[i] != 0L) continue; // already filled
|
||||
|
||||
final char code = indicies[i];
|
||||
|
||||
// we have already promised to fill this code - this is a dupe
|
||||
if (get(code) == -1){
|
||||
filteredIndicies[j] = -1;
|
||||
dupes++;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// this is a code we have not obtained before
|
||||
// mark this one as "promise to get" in the global cache with a -1
|
||||
final int k = j - dupes;
|
||||
filteredCodes[k] = code;
|
||||
put(code, -1);
|
||||
filteredIndicies[j] = k;
|
||||
j++;
|
||||
if (missed == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int filteredRunLen = j - dupes;
|
||||
final int[] filteredValues = new int[filteredRunLen];
|
||||
final int[] glyphCodes = new int[missed];
|
||||
|
||||
// bulk call to fill in the distinct values
|
||||
nativeCharsToGlyphs(fFont.getNativeFontPtr(), filteredRunLen, filteredCodes, filteredValues);
|
||||
// bulk call to fill in the unmapped code points.
|
||||
nativeCharsToGlyphs(fFont.getNativeFontPtr(),
|
||||
missed, unmappedChars, glyphCodes);
|
||||
|
||||
// scan the requested list, and fill in values from our
|
||||
// distinct code list which has been filled from "getDistinct"
|
||||
j = 0;
|
||||
for (int i = 0; i < count; i++){
|
||||
if (values[i] != 0L && values[i] != -1L) continue; // already placed
|
||||
|
||||
final int k = filteredIndicies[j]; // index into filteredImages array
|
||||
final char code = indicies[i];
|
||||
if(k == -1L){
|
||||
// we should have already filled the cache with this value
|
||||
values[i] = get(code);
|
||||
}else{
|
||||
// fill the particular code request, and store in the cache
|
||||
final int ptr = filteredValues[k];
|
||||
values[i] = ptr;
|
||||
put(code, ptr);
|
||||
for (int m = 0; m < missed; m++){
|
||||
int i = unmappedCharIndices[m];
|
||||
int code = unmappedChars[m];
|
||||
if (code >= HI_SURROGATE_START &&
|
||||
code <= HI_SURROGATE_END && m < missed - 1)
|
||||
{
|
||||
char low = indicies[m + 1];
|
||||
if (low >= LO_SURROGATE_START && low <= LO_SURROGATE_END) {
|
||||
code = (code - HI_SURROGATE_START) * 0x400 +
|
||||
low - LO_SURROGATE_START + 0x10000;
|
||||
}
|
||||
}
|
||||
values[i] = glyphCodes[m];
|
||||
put(code, values[i]);
|
||||
if (code >= 0x10000) {
|
||||
m++;
|
||||
values[i + 1] = INVISIBLE_GLYPH_ID;
|
||||
}
|
||||
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,8 +77,20 @@ public final class LWCToolkit extends LWToolkit {
|
||||
if (!GraphicsEnvironment.isHeadless()) {
|
||||
initIDs();
|
||||
}
|
||||
inAWT = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean run() {
|
||||
return !Boolean.parseBoolean(System.getProperty("javafx.embed.singleThread", "false"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* If true we operate in normal mode and nested runloop is executed in JavaRunLoopMode
|
||||
* If false we operate in singleThreaded FX/AWT interop mode and nested loop uses NSDefaultRunLoopMode
|
||||
*/
|
||||
private static final boolean inAWT;
|
||||
|
||||
public LWCToolkit() {
|
||||
SunToolkit.setDataTransfererClassName("sun.lwawt.macosx.CDataTransferer");
|
||||
|
||||
@ -701,7 +713,10 @@ public final class LWCToolkit extends LWToolkit {
|
||||
*
|
||||
* if false - all events come after exit form the nested loop
|
||||
*/
|
||||
static native void doAWTRunLoop(long mediator, boolean processEvents);
|
||||
static void doAWTRunLoop(long mediator, boolean processEvents) {
|
||||
doAWTRunLoopImpl(mediator, processEvents, inAWT);
|
||||
}
|
||||
static private native void doAWTRunLoopImpl(long mediator, boolean processEvents, boolean inAWT);
|
||||
static native void stopAWTRunLoop(long mediator);
|
||||
|
||||
private native boolean nativeSyncQueue(long timeout);
|
||||
|
||||
@ -539,7 +539,7 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
AWTWindow *opposite = [AWTWindow lastKeyWindow];
|
||||
if (!IS(self.styleBits, IS_DIALOG)) {
|
||||
[CMenuBar activate:self.javaMenuBar modallyDisabled:NO];
|
||||
} else if (IS(self.styleBits, IS_MODAL)) {
|
||||
} else if ((opposite != NULL) && IS(self.styleBits, IS_MODAL)) {
|
||||
[CMenuBar activate:opposite->javaMenuBar modallyDisabled:YES];
|
||||
}
|
||||
[AWTWindow setLastKeyWindow:nil];
|
||||
|
||||
@ -61,7 +61,6 @@ static CDropTarget* GetCDropTarget(jlong jdroptarget) {
|
||||
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDropTargetContextPeer_startTransfer
|
||||
(JNIEnv *env, jobject jthis, jlong jdroptarget, jlong jformat)
|
||||
{
|
||||
AWT_ASSERT_NOT_APPKIT_THREAD;
|
||||
|
||||
jlong result = (jlong) 0L;
|
||||
|
||||
|
||||
@ -295,11 +295,11 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_LWCToolkit
|
||||
* Method: doAWTRunLoop
|
||||
* Method: doAWTRunLoopImpl
|
||||
* Signature: (JZZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_doAWTRunLoop
|
||||
(JNIEnv *env, jclass clz, jlong mediator, jboolean processEvents)
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_doAWTRunLoopImpl
|
||||
(JNIEnv *env, jclass clz, jlong mediator, jboolean processEvents, jboolean inAWT)
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
JNF_COCOA_ENTER(env);
|
||||
@ -311,7 +311,7 @@ JNF_COCOA_ENTER(env);
|
||||
// Don't use acceptInputForMode because that doesn't setup autorelease pools properly
|
||||
BOOL isRunning = true;
|
||||
while (![mediatorObject shouldEndRunLoop] && isRunning) {
|
||||
isRunning = [[NSRunLoop currentRunLoop] runMode:[JNFRunLoop javaRunLoopMode]
|
||||
isRunning = [[NSRunLoop currentRunLoop] runMode:(inAWT ? [JNFRunLoop javaRunLoopMode] : NSDefaultRunLoopMode)
|
||||
beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.010]];
|
||||
if (processEvents) {
|
||||
//We do not spin a runloop here as date is nil, so does not matter which mode to use
|
||||
@ -340,7 +340,6 @@ JNF_COCOA_EXIT(env);
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_stopAWTRunLoop
|
||||
(JNIEnv *env, jclass clz, jlong mediator)
|
||||
{
|
||||
AWT_ASSERT_NOT_APPKIT_THREAD;
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
AWTRunLoopObject* mediatorObject = (AWTRunLoopObject*)jlong_to_ptr(mediator);
|
||||
|
||||
@ -110,8 +110,14 @@
|
||||
|
||||
- (void)_handleOpenURLEvent:(NSAppleEventDescriptor *)openURLEvent withReplyEvent:(NSAppleEventDescriptor *)replyEvent
|
||||
{
|
||||
// Make an explicit copy of the passed events as they may be invalidated by the time they're processed
|
||||
NSAppleEventDescriptor *openURLEventCopy = [openURLEvent copy];
|
||||
NSAppleEventDescriptor *replyEventCopy = [replyEvent copy];
|
||||
|
||||
[self.queue addObject:[^(){
|
||||
[self.realDelegate _handleOpenURLEvent:openURLEvent withReplyEvent:replyEvent];
|
||||
[self.realDelegate _handleOpenURLEvent:openURLEventCopy withReplyEvent:replyEventCopy];
|
||||
[openURLEventCopy release];
|
||||
[replyEventCopy release];
|
||||
} copy]];
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -403,8 +403,9 @@ extends KeyAgreementSpi {
|
||||
}
|
||||
return skey;
|
||||
} else if (algorithm.equals("TlsPremasterSecret")) {
|
||||
// return entire secret
|
||||
return new SecretKeySpec(secret, "TlsPremasterSecret");
|
||||
// remove leading zero bytes per RFC 5246 Section 8.1.2
|
||||
return new SecretKeySpec(
|
||||
KeyUtil.trimZeroes(secret), "TlsPremasterSecret");
|
||||
} else {
|
||||
throw new NoSuchAlgorithmException("Unsupported secret key "
|
||||
+ "algorithm: "+ algorithm);
|
||||
|
||||
@ -86,12 +86,13 @@ public final class HmacPKCS12PBESHA1 extends HmacCore {
|
||||
throw new InvalidKeyException("SecretKey of PBE type required");
|
||||
}
|
||||
if (params == null) {
|
||||
// generate default for salt and iteration count if necessary
|
||||
if (salt == null) {
|
||||
salt = new byte[20];
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
// should not auto-generate default values since current
|
||||
// javax.crypto.Mac api does not have any method for caller to
|
||||
// retrieve the generated defaults.
|
||||
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)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("PBEParameterSpec type required");
|
||||
|
||||
@ -42,12 +42,10 @@ import java.security.spec.*;
|
||||
*/
|
||||
abstract class PBMAC1Core extends HmacCore {
|
||||
|
||||
private static final int DEFAULT_SALT_LENGTH = 20;
|
||||
private static final int DEFAULT_COUNT = 4096;
|
||||
|
||||
// NOTE: this class inherits the Cloneable interface from HmacCore
|
||||
// Need to override clone() if mutable fields are added.
|
||||
private final String kdfAlgo;
|
||||
private final String hashAlgo;
|
||||
private final PBKDF2Core kdf;
|
||||
private final int blockLength; // in octets
|
||||
|
||||
/**
|
||||
@ -56,13 +54,15 @@ abstract class PBMAC1Core extends HmacCore {
|
||||
*/
|
||||
PBMAC1Core(String kdfAlgo, String hashAlgo, int blockLength)
|
||||
throws NoSuchAlgorithmException {
|
||||
|
||||
super(hashAlgo, blockLength);
|
||||
this.kdfAlgo = kdfAlgo;
|
||||
this.hashAlgo = hashAlgo;
|
||||
this.blockLength = blockLength;
|
||||
}
|
||||
|
||||
switch(kdfAlgo) {
|
||||
private static PBKDF2Core getKDFImpl(String algo) {
|
||||
PBKDF2Core kdf = null;
|
||||
switch(algo) {
|
||||
case "HmacSHA1":
|
||||
kdf = new PBKDF2Core.HmacSHA1();
|
||||
break;
|
||||
@ -79,9 +79,10 @@ abstract class PBMAC1Core extends HmacCore {
|
||||
kdf = new PBKDF2Core.HmacSHA512();
|
||||
break;
|
||||
default:
|
||||
throw new NoSuchAlgorithmException(
|
||||
"No MAC implementation for " + kdfAlgo);
|
||||
throw new ProviderException(
|
||||
"No MAC implementation for " + algo);
|
||||
}
|
||||
return kdf;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,12 +121,13 @@ abstract class PBMAC1Core extends HmacCore {
|
||||
throw new InvalidKeyException("SecretKey of PBE type required");
|
||||
}
|
||||
if (params == null) {
|
||||
// generate default for salt and iteration count if necessary
|
||||
if (salt == null) {
|
||||
salt = new byte[DEFAULT_SALT_LENGTH];
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
// should not auto-generate default values since current
|
||||
// javax.crypto.Mac api does not have any method for caller to
|
||||
// retrieve the generated defaults.
|
||||
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)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("PBEParameterSpec type required");
|
||||
@ -168,7 +170,7 @@ abstract class PBMAC1Core extends HmacCore {
|
||||
java.util.Arrays.fill(passwdChars, ' ');
|
||||
|
||||
SecretKey s = null;
|
||||
|
||||
PBKDF2Core kdf = getKDFImpl(kdfAlgo);
|
||||
try {
|
||||
s = kdf.engineGenerateSecret(pbeSpec);
|
||||
|
||||
|
||||
@ -731,10 +731,11 @@ public final class SunJCE extends Provider {
|
||||
put("Mac.HmacSHA384 SupportedKeyFormats", "RAW");
|
||||
put("Mac.HmacSHA512 SupportedKeyFormats", "RAW");
|
||||
put("Mac.HmacPBESHA1 SupportedKeyFormats", "RAW");
|
||||
put("Mac.HmacPBESHA224 SupportedKeyFormats", "RAW");
|
||||
put("Mac.HmacPBESHA256 SupportedKeyFormats", "RAW");
|
||||
put("Mac.HmacPBESHA384 SupportedKeyFormats", "RAW");
|
||||
put("Mac.HmacPBESHA512 SupportedKeyFormats", "RAW");
|
||||
put("Mac.PBEWithHmacSHA1 SupportedKeyFormatS", "RAW");
|
||||
put("Mac.PBEWithHmacSHA224 SupportedKeyFormats", "RAW");
|
||||
put("Mac.PBEWithHmacSHA256 SupportedKeyFormats", "RAW");
|
||||
put("Mac.PBEWithHmacSHA384 SupportedKeyFormats", "RAW");
|
||||
put("Mac.PBEWithHmacSHA512 SupportedKeyFormats", "RAW");
|
||||
put("Mac.SslMacMD5 SupportedKeyFormats", "RAW");
|
||||
put("Mac.SslMacSHA1 SupportedKeyFormats", "RAW");
|
||||
|
||||
|
||||
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
|
||||
}
|
||||
@ -42,7 +42,7 @@ import sun.util.logging.PlatformLogger;
|
||||
* Component to focus. This behavior can be disabled using the
|
||||
* <code>setImplicitDownCycleTraversal</code> method.
|
||||
* <p>
|
||||
* By default, methods of this class with return a Component only if it is
|
||||
* By default, methods of this class will return a Component only if it is
|
||||
* visible, displayable, enabled, and focusable. Subclasses can modify this
|
||||
* behavior by overriding the <code>accept</code> method.
|
||||
* <p>
|
||||
|
||||
@ -559,6 +559,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
} else {
|
||||
restoreFocus(fe, newFocusedWindow);
|
||||
}
|
||||
setMostRecentFocusOwner(newFocusedWindow, null); // see: 8013773
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -37,16 +37,10 @@ import java.security.PrivilegedAction;
|
||||
|
||||
import java.util.EmptyStackException;
|
||||
|
||||
import sun.awt.*;
|
||||
import sun.awt.dnd.SunDropTargetEvent;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import sun.awt.AppContext;
|
||||
import sun.awt.AWTAutoShutdown;
|
||||
import sun.awt.PeerEvent;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.EventQueueItem;
|
||||
import sun.awt.AWTAccessor;
|
||||
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@ -181,6 +175,8 @@ public class EventQueue {
|
||||
|
||||
private final String name = "AWT-EventQueue-" + threadInitNumber.getAndIncrement();
|
||||
|
||||
private FwDispatcher fwDispatcher;
|
||||
|
||||
private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue");
|
||||
|
||||
static {
|
||||
@ -209,6 +205,10 @@ public class EventQueue {
|
||||
{
|
||||
EventQueue.invokeAndWait(source, r);
|
||||
}
|
||||
public void setFwDispatcher(EventQueue eventQueue,
|
||||
FwDispatcher dispatcher) {
|
||||
eventQueue.setFwDispatcher(dispatcher);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -684,7 +684,16 @@ public class EventQueue {
|
||||
final Object src = event.getSource();
|
||||
final PrivilegedAction<Void> action = new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
dispatchEventImpl(event, src);
|
||||
if (fwDispatcher == null) {
|
||||
dispatchEventImpl(event, src);
|
||||
} else {
|
||||
fwDispatcher.scheduleDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
dispatchEventImpl(event, src);
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@ -844,7 +853,9 @@ public class EventQueue {
|
||||
while (topQueue.nextQueue != null) {
|
||||
topQueue = topQueue.nextQueue;
|
||||
}
|
||||
|
||||
if (topQueue.fwDispatcher != null) {
|
||||
throw new RuntimeException("push() to queue with fwDispatcher");
|
||||
}
|
||||
if ((topQueue.dispatchThread != null) &&
|
||||
(topQueue.dispatchThread.getEventQueue() == this))
|
||||
{
|
||||
@ -975,6 +986,9 @@ public class EventQueue {
|
||||
// Forward the request to the top of EventQueue stack
|
||||
return nextQueue.createSecondaryLoop(cond, filter, interval);
|
||||
}
|
||||
if (fwDispatcher != null) {
|
||||
return fwDispatcher.createSecondaryLoop();
|
||||
}
|
||||
if (dispatchThread == null) {
|
||||
initDispatchThread();
|
||||
}
|
||||
@ -1018,6 +1032,9 @@ public class EventQueue {
|
||||
eq = next;
|
||||
next = eq.nextQueue;
|
||||
}
|
||||
if (eq.fwDispatcher != null) {
|
||||
return eq.fwDispatcher.isDispatchThread();
|
||||
}
|
||||
return (Thread.currentThread() == eq.dispatchThread);
|
||||
} finally {
|
||||
pushPopLock.unlock();
|
||||
@ -1303,6 +1320,15 @@ public class EventQueue {
|
||||
pushPopLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// The method is used by AWTAccessor for javafx/AWT single threaded mode.
|
||||
private void setFwDispatcher(FwDispatcher dispatcher) {
|
||||
if (nextQueue != null) {
|
||||
nextQueue.setFwDispatcher(dispatcher);
|
||||
} else {
|
||||
fwDispatcher = dispatcher;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1200,6 +1200,7 @@ public class Window extends Container implements Accessible {
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean fireWindowClosedEvent = isDisplayable();
|
||||
DisposeAction action = new DisposeAction();
|
||||
if (EventQueue.isDispatchThread()) {
|
||||
action.run();
|
||||
@ -1220,7 +1221,9 @@ public class Window extends Container implements Accessible {
|
||||
// Execute outside the Runnable because postWindowEvent is
|
||||
// synchronized on (this). We don't need to synchronize the call
|
||||
// on the EventQueue anyways.
|
||||
postWindowEvent(WindowEvent.WINDOW_CLOSED);
|
||||
if (fireWindowClosedEvent) {
|
||||
postWindowEvent(WindowEvent.WINDOW_CLOSED);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -487,6 +487,12 @@ public class XMLEncoder extends Encoder implements AutoCloseable {
|
||||
}
|
||||
indentation--;
|
||||
|
||||
Statement statement = getMissedStatement();
|
||||
while (statement != null) {
|
||||
outputStatement(statement, this, false);
|
||||
statement = getMissedStatement();
|
||||
}
|
||||
|
||||
try {
|
||||
out.flush();
|
||||
}
|
||||
@ -503,6 +509,17 @@ public class XMLEncoder extends Encoder implements AutoCloseable {
|
||||
targetToStatementList.clear();
|
||||
}
|
||||
|
||||
Statement getMissedStatement() {
|
||||
for (List<Statement> statements : this.targetToStatementList.values()) {
|
||||
for (int i = 0; i < statements.size(); i++) {
|
||||
if (Statement.class == statements.get(i).getClass()) {
|
||||
return statements.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method calls <code>flush</code>, writes the closing
|
||||
@ -597,7 +614,7 @@ public class XMLEncoder extends Encoder implements AutoCloseable {
|
||||
"methodName") + " should not be null");
|
||||
}
|
||||
|
||||
if (target instanceof Field && methodName.equals("get")) {
|
||||
if (isArgument && target instanceof Field && methodName.equals("get")) {
|
||||
Field f = (Field)target;
|
||||
writeln("<object class=" + quote(f.getDeclaringClass().getName()) +
|
||||
" field=" + quote(f.getName()) + "/>");
|
||||
|
||||
@ -26,7 +26,6 @@
|
||||
package java.lang;
|
||||
|
||||
import java.lang.annotation.Native;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* The {@code Integer} class wraps a value of the primitive type
|
||||
@ -185,7 +184,7 @@ public final class Integer extends Number implements Comparable<Integer> {
|
||||
* @since 1.8
|
||||
*/
|
||||
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> {
|
||||
/**
|
||||
* Convert the integer to an unsigned number.
|
||||
*/
|
||||
private static String toUnsignedString0(int i, int shift) {
|
||||
char[] buf = new char[32];
|
||||
int charPos = 32;
|
||||
private static String toUnsignedString0(int val, int shift) {
|
||||
// assert shift > 0 && shift <=5 : "Illegal shift value";
|
||||
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 mask = radix - 1;
|
||||
do {
|
||||
buf[--charPos] = digits[i & mask];
|
||||
i >>>= shift;
|
||||
} while (i != 0);
|
||||
buf[offset + --charPos] = Integer.digits[val & mask];
|
||||
val >>>= shift;
|
||||
} while (val != 0 && charPos > 0);
|
||||
|
||||
return new String(buf, charPos, (32 - charPos));
|
||||
return charPos;
|
||||
}
|
||||
|
||||
|
||||
final static char [] DigitTens = {
|
||||
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
|
||||
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
|
||||
@ -875,6 +893,7 @@ public final class Integer extends Number implements Comparable<Integer> {
|
||||
* Returns the value of this {@code Integer} as a {@code long}
|
||||
* after a widening primitive conversion.
|
||||
* @jls 5.1.2 Widening Primitive Conversions
|
||||
* @see Integer#toUnsignedLong(int)
|
||||
*/
|
||||
public long longValue() {
|
||||
return (long)value;
|
||||
|
||||
@ -28,6 +28,7 @@ package java.lang;
|
||||
import java.lang.annotation.Native;
|
||||
import java.math.*;
|
||||
|
||||
|
||||
/**
|
||||
* The {@code Long} class wraps a value of the primitive type {@code
|
||||
* 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> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
char[] buf = new char[64];
|
||||
int charPos = 64;
|
||||
static String toUnsignedString0(long val, int shift) {
|
||||
// assert shift > 0 && shift <=5 : "Illegal shift value";
|
||||
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;
|
||||
long mask = radix - 1;
|
||||
int mask = radix - 1;
|
||||
do {
|
||||
buf[--charPos] = Integer.digits[(int)(i & mask)];
|
||||
i >>>= shift;
|
||||
} while (i != 0);
|
||||
return new String(buf, charPos, (64 - charPos));
|
||||
buf[offset + --charPos] = Integer.digits[((int) val) & mask];
|
||||
val >>>= shift;
|
||||
} while (val != 0 && charPos > 0);
|
||||
|
||||
return charPos;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,7 +42,9 @@ import javax.management.StandardMBean;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.security.AccessController;
|
||||
import java.security.Permission;
|
||||
import java.security.PrivilegedAction;
|
||||
@ -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;
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,8 +128,7 @@ public final class HttpCookie implements Cloneable {
|
||||
* a {@code String} specifying the value of the cookie
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if the cookie name contains illegal characters or it is one of
|
||||
* the tokens reserved for use by the cookie protocol
|
||||
* if the cookie name contains illegal characters
|
||||
* @throws NullPointerException
|
||||
* if {@code name} is {@code null}
|
||||
*
|
||||
@ -142,7 +141,7 @@ public final class HttpCookie implements Cloneable {
|
||||
|
||||
private HttpCookie(String name, String value, String header) {
|
||||
name = name.trim();
|
||||
if (name.length() == 0 || !isToken(name)) {
|
||||
if (name.length() == 0 || !isToken(name) || name.charAt(0) == '$') {
|
||||
throw new IllegalArgumentException("Illegal cookie name");
|
||||
}
|
||||
|
||||
@ -170,9 +169,8 @@ public final class HttpCookie implements Cloneable {
|
||||
* @return a List of cookie parsed from header line string
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if header string violates the cookie specification's syntax, or
|
||||
* the cookie name contains illegal characters, or the cookie name
|
||||
* is one of the tokens reserved for use by the cookie protocol
|
||||
* if header string violates the cookie specification's syntax or
|
||||
* the cookie name contains illegal characters.
|
||||
* @throws NullPointerException
|
||||
* if the header string is {@code null}
|
||||
*/
|
||||
|
||||
@ -377,7 +377,7 @@ public final class HttpURLPermission extends Permission {
|
||||
throw new IllegalArgumentException ("unexpected URL scheme");
|
||||
}
|
||||
if (!u.getSchemeSpecificPart().equals("*")) {
|
||||
u = URI.create(scheme + "://" + u.getAuthority() + u.getPath());
|
||||
u = URI.create(scheme + "://" + u.getRawAuthority() + u.getRawPath());
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
package java.nio;
|
||||
|
||||
import java.util.Spliterator;
|
||||
|
||||
/**
|
||||
* A container for data of a specific primitive type.
|
||||
@ -173,6 +174,13 @@ package java.nio;
|
||||
|
||||
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
|
||||
private int mark = -1;
|
||||
private int position = 0;
|
||||
|
||||
@ -115,6 +115,12 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
||||
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]
|
||||
|
||||
public $Type$Buffer put($type$ x) {
|
||||
|
||||
96
jdk/src/share/classes/java/nio/CharBufferSpliterator.java
Normal file
96
jdk/src/share/classes/java/nio/CharBufferSpliterator.java
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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$
|
||||
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) {
|
||||
#if[rw]
|
||||
if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
|
||||
|
||||
@ -139,6 +139,12 @@ class Heap$Type$Buffer$RW$
|
||||
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) {
|
||||
checkBounds(offset, length, dst.length);
|
||||
if (length > remaining())
|
||||
|
||||
@ -77,6 +77,10 @@ class StringCharBuffer // package-private
|
||||
return str.charAt(checkIndex(index) + offset);
|
||||
}
|
||||
|
||||
char getUnchecked(int index) {
|
||||
return str.charAt(index + offset);
|
||||
}
|
||||
|
||||
// ## Override bulk get methods for better performance
|
||||
|
||||
public final CharBuffer put(char c) {
|
||||
|
||||
@ -30,6 +30,11 @@ package java.nio;
|
||||
#if[char]
|
||||
import java.io.IOException;
|
||||
#end[char]
|
||||
#if[streamableType]
|
||||
import java.util.Spliterator;
|
||||
import java.util.stream.StreamSupport;
|
||||
import java.util.stream.$Streamtype$Stream;
|
||||
#end[streamableType]
|
||||
|
||||
/**
|
||||
* $A$ $type$ buffer.
|
||||
@ -589,6 +594,19 @@ public abstract class $Type$Buffer
|
||||
*/
|
||||
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 <i>(optional operation)</i>.
|
||||
*
|
||||
@ -1458,4 +1476,16 @@ public abstract class $Type$Buffer
|
||||
|
||||
#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]
|
||||
|
||||
}
|
||||
|
||||
@ -85,6 +85,15 @@ public final class AccessControlContext {
|
||||
|
||||
private DomainCombiner combiner = null;
|
||||
|
||||
// limited privilege scope
|
||||
private Permission permissions[];
|
||||
private AccessControlContext parent;
|
||||
private boolean isWrapped;
|
||||
|
||||
// is constrained by limited privilege scope?
|
||||
private boolean isLimited;
|
||||
private ProtectionDomain limitedContext[];
|
||||
|
||||
private static boolean debugInit = false;
|
||||
private static Debug debug = null;
|
||||
|
||||
@ -178,14 +187,79 @@ public final class AccessControlContext {
|
||||
|
||||
/**
|
||||
* package private for AccessController
|
||||
*
|
||||
* This "argument wrapper" context will be passed as the actual context
|
||||
* parameter on an internal doPrivileged() call used in the implementation.
|
||||
*/
|
||||
AccessControlContext(ProtectionDomain context[], DomainCombiner combiner) {
|
||||
AccessControlContext(ProtectionDomain caller, DomainCombiner combiner,
|
||||
AccessControlContext parent, AccessControlContext context,
|
||||
Permission[] perms)
|
||||
{
|
||||
/*
|
||||
* Combine the domains from the doPrivileged() context into our
|
||||
* wrapper context, if necessary.
|
||||
*/
|
||||
ProtectionDomain[] callerPDs = null;
|
||||
if (caller != null) {
|
||||
callerPDs = new ProtectionDomain[] { caller };
|
||||
}
|
||||
if (context != null) {
|
||||
this.context = context.clone();
|
||||
if (combiner != null) {
|
||||
this.context = combiner.combine(callerPDs, context.context);
|
||||
} else {
|
||||
this.context = combine(callerPDs, context.context);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Call combiner even if there is seemingly nothing to combine.
|
||||
*/
|
||||
if (combiner != null) {
|
||||
this.context = combiner.combine(callerPDs, null);
|
||||
} else {
|
||||
this.context = combine(callerPDs, null);
|
||||
}
|
||||
}
|
||||
this.combiner = combiner;
|
||||
|
||||
Permission[] tmp = null;
|
||||
if (perms != null) {
|
||||
tmp = new Permission[perms.length];
|
||||
for (int i=0; i < perms.length; i++) {
|
||||
if (perms[i] == null) {
|
||||
throw new NullPointerException("permission can't be null");
|
||||
}
|
||||
|
||||
/*
|
||||
* An AllPermission argument is equivalent to calling
|
||||
* doPrivileged() without any limit permissions.
|
||||
*/
|
||||
if (perms[i].getClass() == AllPermission.class) {
|
||||
parent = null;
|
||||
}
|
||||
tmp[i] = perms[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For a doPrivileged() with limited privilege scope, initialize
|
||||
* the relevant fields.
|
||||
*
|
||||
* The limitedContext field contains the union of all domains which
|
||||
* are enclosed by this limited privilege scope. In other words,
|
||||
* it contains all of the domains which could potentially be checked
|
||||
* if none of the limiting permissions implied a requested permission.
|
||||
*/
|
||||
if (parent != null) {
|
||||
this.limitedContext = combine(parent.context, parent.limitedContext);
|
||||
this.isLimited = true;
|
||||
this.isWrapped = true;
|
||||
this.permissions = tmp;
|
||||
this.parent = parent;
|
||||
this.privilegedContext = context; // used in checkPermission2()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* package private constructor for AccessController.getContext()
|
||||
*/
|
||||
@ -260,6 +334,13 @@ public final class AccessControlContext {
|
||||
if (sm != null) {
|
||||
sm.checkPermission(SecurityConstants.GET_COMBINER_PERMISSION);
|
||||
}
|
||||
return getCombiner();
|
||||
}
|
||||
|
||||
/**
|
||||
* package private for AccessController
|
||||
*/
|
||||
DomainCombiner getCombiner() {
|
||||
return combiner;
|
||||
}
|
||||
|
||||
@ -335,8 +416,10 @@ public final class AccessControlContext {
|
||||
or the first domain was a Privileged system domain. This
|
||||
is to make the common case for system code very fast */
|
||||
|
||||
if (context == null)
|
||||
if (context == null) {
|
||||
checkPermission2(perm);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0; i< context.length; i++) {
|
||||
if (context[i] != null && !context[i].implies(perm)) {
|
||||
@ -370,20 +453,108 @@ public final class AccessControlContext {
|
||||
debug.println("access allowed "+perm);
|
||||
}
|
||||
|
||||
return;
|
||||
checkPermission2(perm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the domains associated with the limited privilege scope.
|
||||
*/
|
||||
private void checkPermission2(Permission perm) {
|
||||
if (!isLimited) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the doPrivileged() context parameter, if present.
|
||||
*/
|
||||
if (privilegedContext != null) {
|
||||
privilegedContext.checkPermission2(perm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore the limited permissions and parent fields of a wrapper
|
||||
* context since they were already carried down into the unwrapped
|
||||
* context.
|
||||
*/
|
||||
if (isWrapped) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to match any limited privilege scope.
|
||||
*/
|
||||
if (permissions != null) {
|
||||
Class<?> permClass = perm.getClass();
|
||||
for (int i=0; i < permissions.length; i++) {
|
||||
Permission limit = permissions[i];
|
||||
if (limit.getClass().equals(permClass) && limit.implies(perm)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the limited privilege scope up the call stack or the inherited
|
||||
* parent thread call stack of this ACC.
|
||||
*/
|
||||
if (parent != null) {
|
||||
/*
|
||||
* As an optimization, if the parent context is the inherited call
|
||||
* stack context from a parent thread then checking the protection
|
||||
* domains of the parent context is redundant since they have
|
||||
* already been merged into the child thread's context by
|
||||
* optimize(). When parent is set to an inherited context this
|
||||
* context was not directly created by a limited scope
|
||||
* doPrivileged() and it does not have its own limited permissions.
|
||||
*/
|
||||
if (permissions == null) {
|
||||
parent.checkPermission2(perm);
|
||||
} else {
|
||||
parent.checkPermission(perm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the stack-based context (this) and combine it with the
|
||||
* privileged or inherited context, if need be.
|
||||
* privileged or inherited context, if need be. Any limited
|
||||
* privilege scope is flagged regardless of whether the assigned
|
||||
* context comes from an immediately enclosing limited doPrivileged().
|
||||
* The limited privilege scope can indirectly flow from the inherited
|
||||
* parent thread or an assigned context previously captured by getContext().
|
||||
*/
|
||||
AccessControlContext optimize() {
|
||||
// the assigned (privileged or inherited) context
|
||||
AccessControlContext acc;
|
||||
DomainCombiner combiner = null;
|
||||
AccessControlContext parent = null;
|
||||
Permission[] permissions = null;
|
||||
|
||||
if (isPrivileged) {
|
||||
acc = privilegedContext;
|
||||
if (acc != null) {
|
||||
/*
|
||||
* If the context is from a limited scope doPrivileged() then
|
||||
* copy the permissions and parent fields out of the wrapper
|
||||
* context that was created to hold them.
|
||||
*/
|
||||
if (acc.isWrapped) {
|
||||
permissions = acc.permissions;
|
||||
parent = acc.parent;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
acc = AccessController.getInheritedAccessControlContext();
|
||||
if (acc != null) {
|
||||
/*
|
||||
* If the inherited context is constrained by a limited scope
|
||||
* doPrivileged() then set it as our parent so we will process
|
||||
* the non-domain-related state.
|
||||
*/
|
||||
if (acc.isLimited) {
|
||||
parent = acc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this.context could be null if only system code is on the stack;
|
||||
@ -393,53 +564,98 @@ public final class AccessControlContext {
|
||||
// acc.context could be null if only system code was involved;
|
||||
// in that case, ignore the assigned context
|
||||
boolean skipAssigned = (acc == null || acc.context == null);
|
||||
ProtectionDomain[] assigned = (skipAssigned) ? null : acc.context;
|
||||
ProtectionDomain[] pd;
|
||||
|
||||
// if there is no enclosing limited privilege scope on the stack or
|
||||
// inherited from a parent thread
|
||||
boolean skipLimited = ((acc == null || !acc.isWrapped) && parent == null);
|
||||
|
||||
if (acc != null && acc.combiner != null) {
|
||||
// let the assigned acc's combiner do its thing
|
||||
return goCombiner(context, acc);
|
||||
if (getDebug() != null) {
|
||||
debug.println("AccessControlContext invoking the Combiner");
|
||||
}
|
||||
|
||||
// No need to clone current and assigned.context
|
||||
// combine() will not update them
|
||||
combiner = acc.combiner;
|
||||
pd = combiner.combine(context, assigned);
|
||||
} else {
|
||||
if (skipStack) {
|
||||
if (skipAssigned) {
|
||||
calculateFields(acc, parent, permissions);
|
||||
return this;
|
||||
} else if (skipLimited) {
|
||||
return acc;
|
||||
}
|
||||
} else if (assigned != null) {
|
||||
if (skipLimited) {
|
||||
// optimization: if there is a single stack domain and
|
||||
// that domain is already in the assigned context; no
|
||||
// need to combine
|
||||
if (context.length == 1 && context[0] == assigned[0]) {
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pd = combine(context, assigned);
|
||||
if (skipLimited && !skipAssigned && pd == assigned) {
|
||||
return acc;
|
||||
} else if (skipAssigned && pd == context) {
|
||||
calculateFields(acc, parent, permissions);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
// optimization: if neither have contexts; return acc if possible
|
||||
// rather than this, because acc might have a combiner
|
||||
if (skipAssigned && skipStack) {
|
||||
return this;
|
||||
}
|
||||
// Reuse existing ACC
|
||||
this.context = pd;
|
||||
this.combiner = combiner;
|
||||
this.isPrivileged = false;
|
||||
|
||||
// optimization: if there is no stack context; there is no reason
|
||||
// to compress the assigned context, it already is compressed
|
||||
if (skipStack) {
|
||||
return acc;
|
||||
}
|
||||
calculateFields(acc, parent, permissions);
|
||||
return this;
|
||||
}
|
||||
|
||||
int slen = context.length;
|
||||
|
||||
/*
|
||||
* Combine the current (stack) and assigned domains.
|
||||
*/
|
||||
private static ProtectionDomain[] combine(ProtectionDomain[]current,
|
||||
ProtectionDomain[] assigned) {
|
||||
|
||||
// current could be null if only system code is on the stack;
|
||||
// in that case, ignore the stack context
|
||||
boolean skipStack = (current == null);
|
||||
|
||||
// assigned could be null if only system code was involved;
|
||||
// in that case, ignore the assigned context
|
||||
boolean skipAssigned = (assigned == null);
|
||||
|
||||
int slen = (skipStack) ? 0 : current.length;
|
||||
|
||||
// optimization: if there is no assigned context and the stack length
|
||||
// is less then or equal to two; there is no reason to compress the
|
||||
// stack context, it already is
|
||||
if (skipAssigned && slen <= 2) {
|
||||
return this;
|
||||
return current;
|
||||
}
|
||||
|
||||
// optimization: if there is a single stack domain and that domain
|
||||
// is already in the assigned context; no need to combine
|
||||
if ((slen == 1) && (context[0] == acc.context[0])) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
int n = (skipAssigned) ? 0 : acc.context.length;
|
||||
int n = (skipAssigned) ? 0 : assigned.length;
|
||||
|
||||
// now we combine both of them, and create a new context
|
||||
ProtectionDomain pd[] = new ProtectionDomain[slen + n];
|
||||
|
||||
// first copy in the assigned context domains, no need to compress
|
||||
if (!skipAssigned) {
|
||||
System.arraycopy(acc.context, 0, pd, 0, n);
|
||||
System.arraycopy(assigned, 0, pd, 0, n);
|
||||
}
|
||||
|
||||
// now add the stack context domains, discarding nulls and duplicates
|
||||
outer:
|
||||
for (int i = 0; i < context.length; i++) {
|
||||
ProtectionDomain sd = context[i];
|
||||
for (int i = 0; i < slen; i++) {
|
||||
ProtectionDomain sd = current[i];
|
||||
if (sd != null) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (sd == pd[j]) {
|
||||
@ -453,54 +669,48 @@ public final class AccessControlContext {
|
||||
// if length isn't equal, we need to shorten the array
|
||||
if (n != pd.length) {
|
||||
// optimization: if we didn't really combine anything
|
||||
if (!skipAssigned && n == acc.context.length) {
|
||||
return acc;
|
||||
if (!skipAssigned && n == assigned.length) {
|
||||
return assigned;
|
||||
} else if (skipAssigned && n == slen) {
|
||||
return this;
|
||||
return current;
|
||||
}
|
||||
ProtectionDomain tmp[] = new ProtectionDomain[n];
|
||||
System.arraycopy(pd, 0, tmp, 0, n);
|
||||
pd = tmp;
|
||||
}
|
||||
|
||||
// return new AccessControlContext(pd, false);
|
||||
|
||||
// Reuse existing ACC
|
||||
|
||||
this.context = pd;
|
||||
this.combiner = null;
|
||||
this.isPrivileged = false;
|
||||
|
||||
return this;
|
||||
return pd;
|
||||
}
|
||||
|
||||
private AccessControlContext goCombiner(ProtectionDomain[] current,
|
||||
AccessControlContext assigned) {
|
||||
|
||||
// the assigned ACC's combiner is not null --
|
||||
// let the combiner do its thing
|
||||
/*
|
||||
* Calculate the additional domains that could potentially be reached via
|
||||
* limited privilege scope. Mark the context as being subject to limited
|
||||
* privilege scope unless the reachable domains (if any) are already
|
||||
* contained in this domain context (in which case any limited
|
||||
* privilege scope checking would be redundant).
|
||||
*/
|
||||
private void calculateFields(AccessControlContext assigned,
|
||||
AccessControlContext parent, Permission[] permissions)
|
||||
{
|
||||
ProtectionDomain[] parentLimit = null;
|
||||
ProtectionDomain[] assignedLimit = null;
|
||||
ProtectionDomain[] newLimit;
|
||||
|
||||
// XXX we could add optimizations to 'current' here ...
|
||||
|
||||
if (getDebug() != null) {
|
||||
debug.println("AccessControlContext invoking the Combiner");
|
||||
parentLimit = (parent != null)? parent.limitedContext: null;
|
||||
assignedLimit = (assigned != null)? assigned.limitedContext: null;
|
||||
newLimit = combine(parentLimit, assignedLimit);
|
||||
if (newLimit != null) {
|
||||
if (context == null || !containsAllPDs(newLimit, context)) {
|
||||
this.limitedContext = newLimit;
|
||||
this.permissions = permissions;
|
||||
this.parent = parent;
|
||||
this.isLimited = true;
|
||||
}
|
||||
}
|
||||
|
||||
// No need to clone current and assigned.context
|
||||
// combine() will not update them
|
||||
ProtectionDomain[] combinedPds = assigned.combiner.combine(
|
||||
current, assigned.context);
|
||||
|
||||
// return new AccessControlContext(combinedPds, assigned.combiner);
|
||||
|
||||
// Reuse existing ACC
|
||||
this.context = combinedPds;
|
||||
this.combiner = assigned.combiner;
|
||||
this.isPrivileged = false;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks two AccessControlContext objects for equality.
|
||||
* Checks that <i>obj</i> is
|
||||
@ -520,31 +730,131 @@ public final class AccessControlContext {
|
||||
|
||||
AccessControlContext that = (AccessControlContext) obj;
|
||||
|
||||
|
||||
if (context == null) {
|
||||
return (that.context == null);
|
||||
}
|
||||
|
||||
if (that.context == null)
|
||||
if (!equalContext(that))
|
||||
return false;
|
||||
|
||||
if (!(this.containsAllPDs(that) && that.containsAllPDs(this)))
|
||||
return false;
|
||||
|
||||
if (this.combiner == null)
|
||||
return (that.combiner == null);
|
||||
|
||||
if (that.combiner == null)
|
||||
return false;
|
||||
|
||||
if (!this.combiner.equals(that.combiner))
|
||||
if (!equalLimitedContext(that))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean containsAllPDs(AccessControlContext that) {
|
||||
/*
|
||||
* Compare for equality based on state that is free of limited
|
||||
* privilege complications.
|
||||
*/
|
||||
private boolean equalContext(AccessControlContext that) {
|
||||
if (!equalPDs(this.context, that.context))
|
||||
return false;
|
||||
|
||||
if (this.combiner == null && that.combiner != null)
|
||||
return false;
|
||||
|
||||
if (this.combiner != null && !this.combiner.equals(that.combiner))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean equalPDs(ProtectionDomain[] a, ProtectionDomain[] b) {
|
||||
if (a == null) {
|
||||
return (b == null);
|
||||
}
|
||||
|
||||
if (b == null)
|
||||
return false;
|
||||
|
||||
if (!(containsAllPDs(a, b) && containsAllPDs(b, a)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare for equality based on state that is captured during a
|
||||
* call to AccessController.getContext() when a limited privilege
|
||||
* scope is in effect.
|
||||
*/
|
||||
private boolean equalLimitedContext(AccessControlContext that) {
|
||||
if (that == null)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If neither instance has limited privilege scope then we're done.
|
||||
*/
|
||||
if (!this.isLimited && !that.isLimited)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* If only one instance has limited privilege scope then we're done.
|
||||
*/
|
||||
if (!(this.isLimited && that.isLimited))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Wrapped instances should never escape outside the implementation
|
||||
* this class and AccessController so this will probably never happen
|
||||
* but it only makes any sense to compare if they both have the same
|
||||
* isWrapped state.
|
||||
*/
|
||||
if ((this.isWrapped && !that.isWrapped) ||
|
||||
(!this.isWrapped && that.isWrapped)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.permissions == null && that.permissions != null)
|
||||
return false;
|
||||
|
||||
if (this.permissions != null && that.permissions == null)
|
||||
return false;
|
||||
|
||||
if (!(this.containsAllLimits(that) && that.containsAllLimits(this)))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Skip through any wrapped contexts.
|
||||
*/
|
||||
AccessControlContext thisNextPC = getNextPC(this);
|
||||
AccessControlContext thatNextPC = getNextPC(that);
|
||||
|
||||
/*
|
||||
* The protection domains and combiner of a privilegedContext are
|
||||
* not relevant because they have already been included in the context
|
||||
* of this instance by optimize() so we only care about any limited
|
||||
* privilege state they may have.
|
||||
*/
|
||||
if (thisNextPC == null && thatNextPC != null && thatNextPC.isLimited)
|
||||
return false;
|
||||
|
||||
if (thisNextPC != null && !thisNextPC.equalLimitedContext(thatNextPC))
|
||||
return false;
|
||||
|
||||
if (this.parent == null && that.parent != null)
|
||||
return false;
|
||||
|
||||
if (this.parent != null && !this.parent.equals(that.parent))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Follow the privilegedContext link making our best effort to skip
|
||||
* through any wrapper contexts.
|
||||
*/
|
||||
private static AccessControlContext getNextPC(AccessControlContext acc) {
|
||||
while (acc != null && acc.privilegedContext != null) {
|
||||
acc = acc.privilegedContext;
|
||||
if (!acc.isWrapped)
|
||||
return acc;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean containsAllPDs(ProtectionDomain[] thisContext,
|
||||
ProtectionDomain[] thatContext) {
|
||||
boolean match = false;
|
||||
|
||||
//
|
||||
// ProtectionDomains within an ACC currently cannot be null
|
||||
// and this is enforced by the constructor and the various
|
||||
@ -552,17 +862,17 @@ public final class AccessControlContext {
|
||||
// to support the notion of a null PD and therefore this logic continues
|
||||
// to support that notion.
|
||||
ProtectionDomain thisPd;
|
||||
for (int i = 0; i < context.length; i++) {
|
||||
for (int i = 0; i < thisContext.length; i++) {
|
||||
match = false;
|
||||
if ((thisPd = context[i]) == null) {
|
||||
for (int j = 0; (j < that.context.length) && !match; j++) {
|
||||
match = (that.context[j] == null);
|
||||
if ((thisPd = thisContext[i]) == null) {
|
||||
for (int j = 0; (j < thatContext.length) && !match; j++) {
|
||||
match = (thatContext[j] == null);
|
||||
}
|
||||
} else {
|
||||
Class<?> thisPdClass = thisPd.getClass();
|
||||
ProtectionDomain thatPd;
|
||||
for (int j = 0; (j < that.context.length) && !match; j++) {
|
||||
thatPd = that.context[j];
|
||||
for (int j = 0; (j < thatContext.length) && !match; j++) {
|
||||
thatPd = thatContext[j];
|
||||
|
||||
// Class check required to avoid PD exposure (4285406)
|
||||
match = (thatPd != null &&
|
||||
@ -573,6 +883,29 @@ public final class AccessControlContext {
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
private boolean containsAllLimits(AccessControlContext that) {
|
||||
boolean match = false;
|
||||
Permission thisPerm;
|
||||
|
||||
if (this.permissions == null && that.permissions == null)
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < this.permissions.length; i++) {
|
||||
Permission limit = this.permissions[i];
|
||||
Class <?> limitClass = limit.getClass();
|
||||
match = false;
|
||||
for (int j = 0; (j < that.permissions.length) && !match; j++) {
|
||||
Permission perm = that.permissions[j];
|
||||
match = (limitClass.equals(perm.getClass()) &&
|
||||
limit.equals(perm));
|
||||
}
|
||||
if (!match) return false;
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this context. The hash code
|
||||
* is computed by exclusive or-ing the hash code of all the protection
|
||||
@ -591,6 +924,7 @@ public final class AccessControlContext {
|
||||
if (context[i] != null)
|
||||
hashCode ^= context[i].hashCode();
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,9 +82,15 @@ import sun.reflect.Reflection;
|
||||
* else if (caller i is marked as privileged) {
|
||||
* if (a context was specified in the call to doPrivileged)
|
||||
* 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.
|
||||
* // Whenever a new thread is created, the AccessControlContext at
|
||||
@ -101,11 +107,16 @@ import sun.reflect.Reflection;
|
||||
* was marked as "privileged" via a <code>doPrivileged</code>
|
||||
* call without a context argument (see below for information about a
|
||||
* 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>
|
||||
* returns quietly, indicating that the requested access is allowed.
|
||||
* 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
|
||||
* don't need to return a value from within the "privileged" block, do
|
||||
@ -180,6 +191,9 @@ import sun.reflect.Reflection;
|
||||
*
|
||||
* <p> Be *very* careful in your use of the "privileged" construct, and
|
||||
* 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
|
||||
* within the context of the currently executing thread.
|
||||
@ -215,7 +229,9 @@ import sun.reflect.Reflection;
|
||||
*
|
||||
* <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
|
||||
* 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
|
||||
* somemethod() {
|
||||
@ -223,12 +239,21 @@ import sun.reflect.Reflection;
|
||||
* public Object run() {
|
||||
* // Code goes here. Any permission checks within this
|
||||
* // run method will require that the intersection of the
|
||||
* // callers protection domain and the snapshot's
|
||||
* // context have the desired permission.
|
||||
* // caller's protection domain and the snapshot's
|
||||
* // 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...
|
||||
* }}</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
|
||||
*
|
||||
@ -334,6 +359,112 @@ public final class AccessController {
|
||||
public static native <T> T doPrivileged(PrivilegedAction<T> action,
|
||||
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
|
||||
* privileges enabled. The action is performed with <i>all</i> of the
|
||||
@ -408,6 +539,22 @@ public final class AccessController {
|
||||
private static AccessControlContext preserveCombiner(DomainCombiner combiner,
|
||||
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
|
||||
(new PrivilegedAction<ProtectionDomain>() {
|
||||
public ProtectionDomain run() {
|
||||
@ -415,18 +562,9 @@ public final class AccessController {
|
||||
}
|
||||
});
|
||||
|
||||
// perform 'combine' on the caller of doPrivileged,
|
||||
// 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);
|
||||
}
|
||||
return callerPd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs the specified <code>PrivilegedExceptionAction</code> with
|
||||
* privileges enabled and restricted by the specified
|
||||
@ -454,7 +592,7 @@ public final class AccessController {
|
||||
* @exception NullPointerException if the action is <code>null</code>
|
||||
*
|
||||
* @see #doPrivileged(PrivilegedAction)
|
||||
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
|
||||
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static native <T> T
|
||||
@ -462,6 +600,118 @@ public final class AccessController {
|
||||
AccessControlContext context)
|
||||
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
|
||||
* the protection domains of all the callers on the stack,
|
||||
@ -474,6 +724,7 @@ public final class AccessController {
|
||||
|
||||
private static native AccessControlContext getStackAccessControlContext();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the "inherited" AccessControl context. This is the context
|
||||
* that existed when the thread was created. Package private so
|
||||
@ -484,9 +735,9 @@ public final class AccessController {
|
||||
|
||||
/**
|
||||
* This method takes a "snapshot" of the current calling context, which
|
||||
* includes the current Thread's inherited AccessControlContext,
|
||||
* and places it in an AccessControlContext object. This context may then
|
||||
* be checked at a later point, possibly in another thread.
|
||||
* includes the current Thread's inherited AccessControlContext and any
|
||||
* limited privilege scope, and places it in an AccessControlContext object.
|
||||
* This context may then be checked at a later point, possibly in another thread.
|
||||
*
|
||||
* @see AccessControlContext
|
||||
*
|
||||
@ -524,7 +775,7 @@ public final class AccessController {
|
||||
*/
|
||||
|
||||
public static void checkPermission(Permission perm)
|
||||
throws AccessControlException
|
||||
throws AccessControlException
|
||||
{
|
||||
//System.err.println("checkPermission "+perm);
|
||||
//Thread.currentThread().dumpStack();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -112,10 +112,10 @@ public class DigestOutputStream extends FilterOutputStream {
|
||||
* @see MessageDigest#update(byte)
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
out.write(b);
|
||||
if (on) {
|
||||
digest.update((byte)b);
|
||||
}
|
||||
out.write(b);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,10 +142,10 @@ public class DigestOutputStream extends FilterOutputStream {
|
||||
* @see MessageDigest#update(byte[], int, int)
|
||||
*/
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
out.write(b, off, len);
|
||||
if (on) {
|
||||
digest.update(b, off, len);
|
||||
}
|
||||
out.write(b, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -180,13 +180,27 @@ public class Hashtable<K,V>
|
||||
*/
|
||||
static final long HASHSEED_OFFSET;
|
||||
|
||||
static final boolean USE_HASHSEED;
|
||||
|
||||
static {
|
||||
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);
|
||||
String hashSeedProp = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction(
|
||||
"jdk.map.useRandomSeed"));
|
||||
boolean localBool = (null != hashSeedProp)
|
||||
? Boolean.parseBoolean(hashSeedProp) : false;
|
||||
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>
|
||||
/**
|
||||
* A randomizing value associated with this instance that is applied to
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Return an initial value for the hashSeed, or 0 if the random seed is not
|
||||
* enabled.
|
||||
*/
|
||||
final int initHashSeed() {
|
||||
if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) {
|
||||
return sun.misc.Hashing.randomHashSeed(this);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int hash(Object k) {
|
||||
if (k instanceof String) {
|
||||
return ((String)k).hash32();
|
||||
}
|
||||
|
||||
int h = 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);
|
||||
return hashSeed ^ k.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -232,6 +249,7 @@ public class Hashtable<K,V>
|
||||
this.loadFactor = loadFactor;
|
||||
table = new Entry<?,?>[initialCapacity];
|
||||
threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
|
||||
hashSeed = initHashSeed();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1187,8 +1205,10 @@ public class Hashtable<K,V>
|
||||
s.defaultReadObject();
|
||||
|
||||
// set hashMask
|
||||
Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET,
|
||||
sun.misc.Hashing.randomHashSeed(this));
|
||||
if (Holder.USE_HASHSEED) {
|
||||
Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET,
|
||||
sun.misc.Hashing.randomHashSeed(this));
|
||||
}
|
||||
|
||||
// Read the original length of the array and number of elements
|
||||
int origlength = s.readInt();
|
||||
|
||||
@ -159,7 +159,7 @@ public class IntSummaryStatistics implements IntConsumer {
|
||||
*/
|
||||
public String toString() {
|
||||
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(),
|
||||
getCount(),
|
||||
getSum(),
|
||||
|
||||
@ -55,9 +55,9 @@ import java.io.*;
|
||||
* order they were presented.)
|
||||
*
|
||||
* <p>A special {@link #LinkedHashMap(int,float,boolean) constructor} is
|
||||
* provided to create a linked hash map whose order of iteration is the order
|
||||
* in which its entries were last accessed, from least-recently accessed to
|
||||
* most-recently (<i>access-order</i>). This kind of map is well-suited to
|
||||
* provided to create a <tt>LinkedHashMap</tt> whose order of iteration is the
|
||||
* order in which its entries were last accessed, from least-recently accessed
|
||||
* 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
|
||||
* results in an access to the corresponding entry (assuming it exists after
|
||||
* the invocation completes). The <tt>putAll</tt> method generates one entry
|
||||
@ -242,23 +242,6 @@ public class LinkedHashMap<K,V>
|
||||
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
|
||||
* specified value.
|
||||
@ -320,7 +303,7 @@ public class LinkedHashMap<K,V>
|
||||
// These fields comprise the doubly linked list used for iteration.
|
||||
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);
|
||||
}
|
||||
|
||||
@ -344,7 +327,7 @@ public class LinkedHashMap<K,V>
|
||||
|
||||
/**
|
||||
* 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
|
||||
* to the end of the list; otherwise, it does nothing.
|
||||
*/
|
||||
@ -422,8 +405,9 @@ public class LinkedHashMap<K,V>
|
||||
* allocated entry to get inserted at the end of the linked list and
|
||||
* removes the eldest entry if appropriate.
|
||||
*/
|
||||
void addEntry(int hash, K key, V value, int bucketIndex) {
|
||||
super.addEntry(hash, key, value, bucketIndex);
|
||||
@Override
|
||||
void addEntry(int hash, K key, V value, int bucketIndex, boolean checkIfNeedTree) {
|
||||
super.addEntry(hash, key, value, bucketIndex, checkIfNeedTree);
|
||||
|
||||
// Remove eldest entry if instructed
|
||||
Entry<K,V> eldest = header.after;
|
||||
@ -432,17 +416,14 @@ public class LinkedHashMap<K,V>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This override differs from addEntry in that it doesn't resize the
|
||||
* table or remove the eldest entry.
|
||||
/*
|
||||
* Create a new LinkedHashMap.Entry and setup the before/after pointers
|
||||
*/
|
||||
void createEntry(int hash, K key, V value, int bucketIndex) {
|
||||
@SuppressWarnings("unchecked")
|
||||
HashMap.Entry<K,V> old = (HashMap.Entry<K,V>)table[bucketIndex];
|
||||
Entry<K,V> e = new Entry<>(hash, key, value, old);
|
||||
table[bucketIndex] = e;
|
||||
e.addBefore(header);
|
||||
size++;
|
||||
@Override
|
||||
HashMap.Entry<K,V> newEntry(int hash, K key, V value, Object next) {
|
||||
Entry<K,V> newEntry = new Entry<>(hash, key, value, next);
|
||||
newEntry.addBefore(header);
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -171,7 +171,7 @@ public class LongSummaryStatistics implements LongConsumer, IntConsumer {
|
||||
*/
|
||||
public String toString() {
|
||||
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(),
|
||||
getCount(),
|
||||
getSum(),
|
||||
|
||||
@ -91,6 +91,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
||||
* @throws NullPointerException if the specified action is null
|
||||
*/
|
||||
default void forEachRemaining(IntConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
while (hasNext())
|
||||
action.accept(nextInt());
|
||||
}
|
||||
@ -123,6 +124,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
||||
forEachRemaining((IntConsumer) action);
|
||||
}
|
||||
else {
|
||||
// The method reference action::accept is never null
|
||||
Objects.requireNonNull(action);
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.forEachRemainingInt(action::accept)");
|
||||
forEachRemaining((IntConsumer) action::accept);
|
||||
@ -162,6 +165,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
||||
* @throws NullPointerException if the specified action is null
|
||||
*/
|
||||
default void forEachRemaining(LongConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
while (hasNext())
|
||||
action.accept(nextLong());
|
||||
}
|
||||
@ -194,6 +198,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
||||
forEachRemaining((LongConsumer) action);
|
||||
}
|
||||
else {
|
||||
// The method reference action::accept is never null
|
||||
Objects.requireNonNull(action);
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.forEachRemainingLong(action::accept)");
|
||||
forEachRemaining((LongConsumer) action::accept);
|
||||
@ -232,6 +238,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
||||
* @throws NullPointerException if the specified action is null
|
||||
*/
|
||||
default void forEachRemaining(DoubleConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
while (hasNext())
|
||||
action.accept(nextDouble());
|
||||
}
|
||||
@ -265,6 +272,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
||||
forEachRemaining((DoubleConsumer) action);
|
||||
}
|
||||
else {
|
||||
// The method reference action::accept is never null
|
||||
Objects.requireNonNull(action);
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.forEachRemainingDouble(action::accept)");
|
||||
forEachRemaining((DoubleConsumer) action::accept);
|
||||
|
||||
@ -394,9 +394,9 @@ public interface Spliterator<T> {
|
||||
* Convenience method that returns {@link #estimateSize()} if this
|
||||
* Spliterator is {@link #SIZED}, else {@code -1}.
|
||||
* @implSpec
|
||||
* The default returns the result of {@code estimateSize()} if the
|
||||
* Spliterator reports a characteristic of {@code SIZED}, and {@code -1}
|
||||
* otherwise.
|
||||
* The default implementation returns the result of {@code estimateSize()}
|
||||
* if the Spliterator reports a characteristic of {@code SIZED}, and
|
||||
* {@code -1} otherwise.
|
||||
*
|
||||
* @return the exact size, if known, else {@code -1}.
|
||||
*/
|
||||
|
||||
@ -29,14 +29,6 @@ package java.util;
|
||||
* by a delimiter and optionally starting with a supplied prefix
|
||||
* and ending with a supplied suffix.
|
||||
* <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
|
||||
* {@code sj.toString()} method will, by default, return {@code prefix + suffix}.
|
||||
* However, if the {@code setEmptyValue} method is called, the {@code emptyValue}
|
||||
@ -45,17 +37,28 @@ package java.util;
|
||||
* <code>"{}"</code>, where the {@code prefix} is <code>"{"</code>, the
|
||||
* {@code suffix} is <code>"}"</code> and nothing has been added to the
|
||||
* {@code StringJoiner}.
|
||||
* <p>
|
||||
* A {@code StringJoiner} may be employed to create formatted output from a
|
||||
* collection using lambda expressions as shown in the following example.
|
||||
*
|
||||
* @apiNote
|
||||
* <p>The String {@code "[George:Sally:Fred]"} may be constructed as follows:
|
||||
*
|
||||
* <pre> {@code
|
||||
* List<Person> people = ...
|
||||
* String commaSeparatedNames =
|
||||
* people.map(p -> p.getName()).into(new StringJoiner(", ")).toString();
|
||||
* StringJoiner sj = new StringJoiner(":", "[", "]");
|
||||
* sj.add("George").add("Sally").add("Fred");
|
||||
* String desiredString = sj.toString();
|
||||
* }</pre>
|
||||
* <p>
|
||||
* A {@code StringJoiner} may be employed to create formatted output from a
|
||||
* {@link java.util.stream.Stream} using
|
||||
* {@link java.util.stream.Collectors#toStringJoiner}. For example:
|
||||
*
|
||||
* <pre> {@code
|
||||
* List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
|
||||
* String commaSeparatedNumbers = numbers.stream()
|
||||
* .map(i -> i.toString())
|
||||
* .collect(Collectors.toStringJoiner(", ")).toString();
|
||||
* }</pre>
|
||||
*
|
||||
* @author Jim Gish
|
||||
* @see java.util.stream.Collectors#toStringJoiner
|
||||
* @since 1.8
|
||||
*/
|
||||
public final class StringJoiner {
|
||||
|
||||
@ -187,11 +187,37 @@ public class WeakHashMap<K,V>
|
||||
*/
|
||||
int modCount;
|
||||
|
||||
private static class Holder {
|
||||
static final boolean USE_HASHSEED;
|
||||
|
||||
static {
|
||||
String hashSeedProp = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction(
|
||||
"jdk.map.useRandomSeed"));
|
||||
boolean localBool = (null != hashSeedProp)
|
||||
? Boolean.parseBoolean(hashSeedProp) : false;
|
||||
USE_HASHSEED = localBool;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A randomizing value associated with this instance that is applied to
|
||||
* 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 int hashSeed;
|
||||
|
||||
/**
|
||||
* Initialize the hashing mask value.
|
||||
*/
|
||||
final void initHashSeed() {
|
||||
if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) {
|
||||
// Do not set hashSeed more than once!
|
||||
// assert hashSeed == 0;
|
||||
hashSeed = sun.misc.Hashing.randomHashSeed(this);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Entry<K,V>[] newTable(int n) {
|
||||
@ -223,6 +249,7 @@ public class WeakHashMap<K,V>
|
||||
table = newTable(capacity);
|
||||
this.loadFactor = loadFactor;
|
||||
threshold = (int)(capacity * loadFactor);
|
||||
initHashSeed();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -298,10 +325,7 @@ public class WeakHashMap<K,V>
|
||||
* in lower bits.
|
||||
*/
|
||||
final int hash(Object k) {
|
||||
if (k instanceof String) {
|
||||
return ((String) k).hash32();
|
||||
}
|
||||
int h = hashSeed ^ k.hashCode();
|
||||
int h = hashSeed ^ k.hashCode();
|
||||
|
||||
// This function ensures that hashCodes that differ only by
|
||||
// constant multiples at each bit position have a bounded
|
||||
@ -1076,9 +1100,10 @@ public class WeakHashMap<K,V>
|
||||
}
|
||||
else
|
||||
mc = expectedModCount;
|
||||
if (tab.length >= hi && (i = index) >= 0 && i < hi) {
|
||||
index = hi;
|
||||
if (tab.length >= hi && (i = index) >= 0 &&
|
||||
(i < (index = hi) || current != null)) {
|
||||
WeakHashMap.Entry<K,V> p = current;
|
||||
current = null; // exhaust
|
||||
do {
|
||||
if (p == null)
|
||||
p = tab[i++];
|
||||
@ -1155,9 +1180,10 @@ public class WeakHashMap<K,V>
|
||||
}
|
||||
else
|
||||
mc = expectedModCount;
|
||||
if (tab.length >= hi && (i = index) >= 0 && i < hi) {
|
||||
index = hi;
|
||||
if (tab.length >= hi && (i = index) >= 0 &&
|
||||
(i < (index = hi) || current != null)) {
|
||||
WeakHashMap.Entry<K,V> p = current;
|
||||
current = null; // exhaust
|
||||
do {
|
||||
if (p == null)
|
||||
p = tab[i++];
|
||||
@ -1232,9 +1258,10 @@ public class WeakHashMap<K,V>
|
||||
}
|
||||
else
|
||||
mc = expectedModCount;
|
||||
if (tab.length >= hi && (i = index) >= 0 && i < hi) {
|
||||
index = hi;
|
||||
if (tab.length >= hi && (i = index) >= 0 &&
|
||||
(i < (index = hi) || current != null)) {
|
||||
WeakHashMap.Entry<K,V> p = current;
|
||||
current = null; // exhaust
|
||||
do {
|
||||
if (p == null)
|
||||
p = tab[i++];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -128,6 +128,14 @@ import java.util.Locale;
|
||||
* installed SPI providers, and "JRE" represents the locale sensitive services
|
||||
* in the Java Runtime Environment, the locale sensitive services in the SPI
|
||||
* providers are looked up first.
|
||||
* <p>
|
||||
* There are two other possible locale sensitive service providers, i.e., "CLDR"
|
||||
* which is a provider based on Unicode Consortium's
|
||||
* <a href="http://cldr.unicode.org/">CLDR Project</a>, and "HOST" which is a
|
||||
* provider that reflects the user's custom settings in the underlying operating
|
||||
* system. These two providers may not be available, depending on the Java Runtime
|
||||
* Environment implementation. Specifying "JRE,SPI" is identical to the default
|
||||
* behavior, which is compatibile with the prior releases.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
@ -603,7 +603,7 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
/**
|
||||
* Returns an {@link OptionalDouble} describing the first element of this
|
||||
* stream (in the encounter order), or an empty {@code OptionalDouble} if
|
||||
* the stream is empty. If the stream has no encounter order, than any
|
||||
* the stream is empty. If the stream has no encounter order, then any
|
||||
* element may be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
|
||||
@ -588,7 +588,7 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
/**
|
||||
* Returns an {@link OptionalInt} describing the first element of this
|
||||
* stream (in the encounter order), or an empty {@code OptionalInt} if the
|
||||
* stream is empty. If the stream has no encounter order, than any element
|
||||
* stream is empty. If the stream has no encounter order, then any element
|
||||
* may be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
|
||||
@ -588,7 +588,7 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
/**
|
||||
* Returns an {@link OptionalLong} describing the first element of this
|
||||
* stream (in the encounter order), or an empty {@code OptionalLong} if the
|
||||
* stream is empty. If the stream has no encounter order, than any element
|
||||
* stream is empty. If the stream has no encounter order, then any element
|
||||
* may be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
|
||||
@ -754,7 +754,7 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
/**
|
||||
* Returns an {@link Optional} describing the first element of this stream
|
||||
* (in the encounter order), or an empty {@code Optional} if the stream is
|
||||
* empty. If the stream has no encounter order, than any element may be
|
||||
* empty. If the stream has no encounter order, then any element may be
|
||||
* returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
|
||||
@ -38,7 +38,7 @@ import java.util.function.LongConsumer;
|
||||
* <p>A {@code StreamBuilder} has a lifecycle, where it starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a built
|
||||
* phase, after which elements may not be added. The built phase begins
|
||||
* when the {@link #build()}} method is called, which creates an ordered
|
||||
* when the {@link #build()} method is called, which creates an ordered
|
||||
* {@code Stream} whose elements are the elements that were added to the stream
|
||||
* builder, in the order they were added.
|
||||
*
|
||||
@ -98,7 +98,7 @@ public interface StreamBuilder<T> extends Consumer<T> {
|
||||
* <p>A stream builder has a lifecycle, where it starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a
|
||||
* built phase, after which elements may not be added. The built phase
|
||||
* begins when the {@link #build()}} method is called, which creates an
|
||||
* begins when the {@link #build()} method is called, which creates an
|
||||
* ordered stream whose elements are the elements that were added to the
|
||||
* stream builder, in the order they were added.
|
||||
*
|
||||
@ -155,7 +155,7 @@ public interface StreamBuilder<T> extends Consumer<T> {
|
||||
* <p>A stream builder has a lifecycle, where it starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a
|
||||
* built phase, after which elements may not be added. The built phase
|
||||
* begins when the {@link #build()}} method is called, which creates an
|
||||
* begins when the {@link #build()} method is called, which creates an
|
||||
* ordered stream whose elements are the elements that were added to the
|
||||
* stream builder, in the order they were added.
|
||||
*
|
||||
@ -209,6 +209,13 @@ public interface StreamBuilder<T> extends Consumer<T> {
|
||||
/**
|
||||
* A mutable builder for a {@code DoubleStream}.
|
||||
*
|
||||
* <p>A stream builder has a lifecycle, where it starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a
|
||||
* built phase, after which elements may not be added. The built phase
|
||||
* begins when the {@link #build()} method is called, which creates an
|
||||
* ordered stream whose elements are the elements that were added to the
|
||||
* stream builder, in the order they were added.
|
||||
*
|
||||
* @see LongStream#builder()
|
||||
* @since 1.8
|
||||
*/
|
||||
@ -217,13 +224,6 @@ public interface StreamBuilder<T> extends Consumer<T> {
|
||||
/**
|
||||
* Adds an element to the stream being built.
|
||||
*
|
||||
* <p>A stream builder has a lifecycle, where it starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a
|
||||
* built phase, after which elements may not be added. The built phase
|
||||
* begins when the {@link #build()}} method is called, which creates an
|
||||
* ordered stream whose elements are the elements that were added to the
|
||||
* stream builder, in the order they were added.
|
||||
*
|
||||
* @throws IllegalStateException if the builder has already transitioned
|
||||
* to the built state
|
||||
*/
|
||||
|
||||
@ -41,7 +41,11 @@ import java.util.function.Supplier;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public class StreamSupport {
|
||||
public final class StreamSupport {
|
||||
|
||||
// Suppresses default constructor, ensuring non-instantiability.
|
||||
private StreamSupport() {}
|
||||
|
||||
/**
|
||||
* Creates a new sequential {@code Stream} from a {@code Spliterator}.
|
||||
*
|
||||
@ -50,7 +54,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
||||
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* {@link #stream(Supplier, int)} should be used to
|
||||
* reduce the scope of potential interference with the source. See
|
||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
||||
@ -75,7 +79,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
||||
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* {@link #stream(Supplier, int)} should be used to
|
||||
* reduce the scope of potential interference with the source. See
|
||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
||||
@ -102,7 +106,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
* or {@code CONCURRENT}, or that are
|
||||
* <a href="Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #stream(java.util.Spliterator)} instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
@ -138,7 +142,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
* or {@code CONCURRENT}, or that are
|
||||
* <a href="Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #stream(Spliterator)} instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
@ -172,7 +176,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
||||
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* {@link #stream(Supplier, int)}} should be used to
|
||||
* reduce the scope of potential interference with the source. See
|
||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
||||
@ -195,7 +199,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
||||
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* {@link #stream(Supplier, int)}} should be used to
|
||||
* reduce the scope of potential interference with the source. See
|
||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
||||
@ -220,7 +224,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
* or {@code CONCURRENT}, or that are
|
||||
* <a href="Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #intStream(Spliterator.OfInt)} instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
@ -254,7 +258,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
* or {@code CONCURRENT}, or that are
|
||||
* <a href="Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #intStream(Spliterator.OfInt)} instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
@ -286,7 +290,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
||||
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* {@link #stream(Supplier, int)} should be used to
|
||||
* reduce the scope of potential interference with the source. See
|
||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
||||
@ -310,7 +314,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
||||
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* {@link #stream(Supplier, int)} should be used to
|
||||
* reduce the scope of potential interference with the source. See
|
||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
||||
@ -335,7 +339,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
* or {@code CONCURRENT}, or that are
|
||||
* <a href="Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #longStream(Spliterator.OfLong)} instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
@ -369,7 +373,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
* or {@code CONCURRENT}, or that are
|
||||
* <a href="Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #longStream(Spliterator.OfLong)} instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
@ -402,7 +406,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
||||
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* {@link #stream(Supplier, int)} should be used to
|
||||
* reduce the scope of potential interference with the source. See
|
||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
||||
@ -426,7 +430,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
||||
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
|
||||
* {@link #stream(Supplier, int)} should be used to
|
||||
* reduce the scope of potential interference with the source. See
|
||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
||||
@ -451,7 +455,7 @@ public class StreamSupport {
|
||||
* <p>
|
||||
* For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
* or {@code CONCURRENT}, or that are
|
||||
* <a href="Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #doubleStream(Spliterator.OfDouble)} instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
@ -485,7 +489,7 @@ public class StreamSupport {
|
||||
*
|
||||
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
* or {@code CONCURRENT}, or that are
|
||||
* <a href="Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #doubleStream(Spliterator.OfDouble)} instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
|
||||
@ -68,6 +68,14 @@ interface ZipConstants {
|
||||
static final int EXTSIZ = 8; // compressed size
|
||||
static final int EXTLEN = 12; // uncompressed size
|
||||
|
||||
/*
|
||||
* Extra field header ID
|
||||
*/
|
||||
static final int EXTID_ZIP64 = 0x0001; // Zip64
|
||||
static final int EXTID_NTFS = 0x000a; // NTFS
|
||||
static final int EXTID_UNIX = 0x000d; // UNIX
|
||||
static final int EXTID_EXTT = 0x5455; // Info-ZIP Extended Timestamp
|
||||
|
||||
/*
|
||||
* Central directory (CEN) header field offsets
|
||||
*/
|
||||
|
||||
@ -25,8 +25,6 @@
|
||||
|
||||
package java.util.zip;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* This class is used to represent a ZIP file entry.
|
||||
*
|
||||
@ -35,7 +33,7 @@ import java.util.Date;
|
||||
public
|
||||
class ZipEntry implements ZipConstants, Cloneable {
|
||||
String name; // entry name
|
||||
long time = -1; // modification time (in DOS time)
|
||||
long mtime = -1; // last modification time
|
||||
long crc = -1; // crc-32 of entry data
|
||||
long size = -1; // uncompressed size of entry data
|
||||
long csize = -1; // compressed size of entry data
|
||||
@ -79,7 +77,7 @@ class ZipEntry implements ZipConstants, Cloneable {
|
||||
*/
|
||||
public ZipEntry(ZipEntry e) {
|
||||
name = e.name;
|
||||
time = e.time;
|
||||
mtime = e.mtime;
|
||||
crc = e.crc;
|
||||
size = e.size;
|
||||
csize = e.csize;
|
||||
@ -89,7 +87,7 @@ class ZipEntry implements ZipConstants, Cloneable {
|
||||
comment = e.comment;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Creates a new un-initialized zip entry
|
||||
*/
|
||||
ZipEntry() {}
|
||||
@ -103,22 +101,26 @@ class ZipEntry implements ZipConstants, Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the modification time of the entry.
|
||||
* @param time the entry modification time in number of milliseconds
|
||||
* since the epoch
|
||||
* Sets the last modification time of the entry.
|
||||
*
|
||||
* @param time the last modification time of the entry in milliseconds since the epoch
|
||||
* @see #getTime()
|
||||
*/
|
||||
public void setTime(long time) {
|
||||
this.time = javaToDosTime(time);
|
||||
this.mtime = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the modification time of the entry, or -1 if not specified.
|
||||
* @return the modification time of the entry, or -1 if not specified
|
||||
* Returns the last modification time of the entry.
|
||||
* <p> The last modificatin time may come from zip entry's extensible
|
||||
* data field {@code NTFS} or {@code Info-ZIP Extended Timestamp}, if
|
||||
* the entry is read from {@link ZipInputStream} or {@link ZipFile}.
|
||||
*
|
||||
* @return the last modification time of the entry, or -1 if not specified
|
||||
* @see #setTime(long)
|
||||
*/
|
||||
public long getTime() {
|
||||
return time != -1 ? dosToJavaTime(time) : -1;
|
||||
return mtime;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -277,35 +279,6 @@ class ZipEntry implements ZipConstants, Cloneable {
|
||||
return getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts DOS time to Java time (number of milliseconds since epoch).
|
||||
*/
|
||||
private static long dosToJavaTime(long dtime) {
|
||||
@SuppressWarnings("deprecation") // Use of date constructor.
|
||||
Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
|
||||
(int)(((dtime >> 21) & 0x0f) - 1),
|
||||
(int)((dtime >> 16) & 0x1f),
|
||||
(int)((dtime >> 11) & 0x1f),
|
||||
(int)((dtime >> 5) & 0x3f),
|
||||
(int)((dtime << 1) & 0x3e));
|
||||
return d.getTime();
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts Java time to DOS time.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Use of date methods
|
||||
private static long javaToDosTime(long time) {
|
||||
Date d = new Date(time);
|
||||
int year = d.getYear() + 1900;
|
||||
if (year < 1980) {
|
||||
return (1 << 21) | (1 << 16);
|
||||
}
|
||||
return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
|
||||
d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
|
||||
d.getSeconds() >> 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this entry.
|
||||
*/
|
||||
|
||||
@ -46,6 +46,7 @@ import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static java.util.zip.ZipConstants64.*;
|
||||
import static java.util.zip.ZipUtils.*;
|
||||
|
||||
/**
|
||||
* This class is used to read entries from a zip file.
|
||||
@ -564,12 +565,44 @@ class ZipFile implements ZipConstants, Closeable {
|
||||
e.name = zc.toString(bname, bname.length);
|
||||
}
|
||||
}
|
||||
e.time = getEntryTime(jzentry);
|
||||
e.crc = getEntryCrc(jzentry);
|
||||
e.size = getEntrySize(jzentry);
|
||||
e. csize = getEntryCSize(jzentry);
|
||||
e.method = getEntryMethod(jzentry);
|
||||
e.extra = getEntryBytes(jzentry, JZENTRY_EXTRA);
|
||||
if (e.extra != null) {
|
||||
byte[] extra = e.extra;
|
||||
int len = e.extra.length;
|
||||
int off = 0;
|
||||
while (off + 4 < len) {
|
||||
int pos = off;
|
||||
int tag = get16(extra, pos);
|
||||
int sz = get16(extra, pos + 2);
|
||||
pos += 4;
|
||||
if (pos + sz > len) // invalid data
|
||||
break;
|
||||
switch (tag) {
|
||||
case EXTID_NTFS:
|
||||
pos += 4; // reserved 4 bytes
|
||||
if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
|
||||
break;
|
||||
e.mtime = winToJavaTime(get64(extra, pos + 4));
|
||||
break;
|
||||
case EXTID_EXTT:
|
||||
int flag = Byte.toUnsignedInt(extra[pos++]);
|
||||
if ((flag & 0x1) != 0) {
|
||||
e.mtime = unixToJavaTime(get32(extra, pos));
|
||||
pos += 4;
|
||||
}
|
||||
break;
|
||||
default: // unknown tag
|
||||
}
|
||||
off += (sz + 4);
|
||||
}
|
||||
}
|
||||
if (e.mtime == -1) {
|
||||
e.mtime = dosToJavaTime(getEntryTime(jzentry));
|
||||
}
|
||||
byte[] bcomm = getEntryBytes(jzentry, JZENTRY_COMMENT);
|
||||
if (bcomm == null) {
|
||||
e.comment = null;
|
||||
|
||||
@ -32,6 +32,7 @@ import java.io.PushbackInputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import static java.util.zip.ZipConstants64.*;
|
||||
import static java.util.zip.ZipUtils.*;
|
||||
|
||||
/**
|
||||
* This class implements an input stream filter for reading files in the
|
||||
@ -302,7 +303,7 @@ class ZipInputStream extends InflaterInputStream implements ZipConstants {
|
||||
throw new ZipException("encrypted ZIP entry not supported");
|
||||
}
|
||||
e.method = get16(tmpbuf, LOCHOW);
|
||||
e.time = get32(tmpbuf, LOCTIM);
|
||||
e.mtime = dosToJavaTime(get32(tmpbuf, LOCTIM));
|
||||
if ((flag & 8) == 8) {
|
||||
/* "Data Descriptor" present */
|
||||
if (e.method != DEFLATED) {
|
||||
@ -316,32 +317,51 @@ class ZipInputStream extends InflaterInputStream implements ZipConstants {
|
||||
}
|
||||
len = get16(tmpbuf, LOCEXT);
|
||||
if (len > 0) {
|
||||
byte[] bb = new byte[len];
|
||||
readFully(bb, 0, len);
|
||||
e.setExtra(bb);
|
||||
byte[] extra = new byte[len];
|
||||
readFully(extra, 0, len);
|
||||
e.setExtra(extra);
|
||||
// extra fields are in "HeaderID(2)DataSize(2)Data... format
|
||||
if (e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL) {
|
||||
int off = 0;
|
||||
while (off + 4 < len) {
|
||||
int sz = get16(bb, off + 2);
|
||||
if (get16(bb, off) == ZIP64_EXTID) {
|
||||
off += 4;
|
||||
// LOC extra zip64 entry MUST include BOTH original and
|
||||
// compressed file size fields
|
||||
if (sz < 16 || (off + sz) > len ) {
|
||||
// Invalid zip64 extra fields, simply skip. Even it's
|
||||
// rare, it's possible the entry size happens to be
|
||||
// the magic value and it "accidnetly" has some bytes
|
||||
// in extra match the id.
|
||||
return e;
|
||||
}
|
||||
e.size = get64(bb, off);
|
||||
e.csize = get64(bb, off + 8);
|
||||
break;
|
||||
int off = 0;
|
||||
while (off + 4 < len) {
|
||||
int pos = off;
|
||||
int tag = get16(extra, pos);
|
||||
int sz = get16(extra, pos + 2);
|
||||
pos += 4;
|
||||
if (pos + sz > len) // invalid data
|
||||
break;
|
||||
switch (tag) {
|
||||
case EXTID_ZIP64 :
|
||||
// LOC extra zip64 entry MUST include BOTH original and
|
||||
// compressed file size fields.
|
||||
//
|
||||
// If invalid zip64 extra fields, simply skip. Even it's
|
||||
// rare, it's possible the entry size happens to be
|
||||
// the magic value and it "accidently" has some bytes
|
||||
// in extra match the id.
|
||||
if (sz >= 16 && (pos + sz) <= len ) {
|
||||
e.size = get64(extra, pos);
|
||||
e.csize = get64(extra, pos + 8);
|
||||
}
|
||||
off += (sz + 4);
|
||||
break;
|
||||
case EXTID_NTFS:
|
||||
pos += 4; // reserved 4 bytes
|
||||
if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
|
||||
break;
|
||||
// override the loc field, NTFS time has 'microsecond' granularity
|
||||
e.mtime = winToJavaTime(get64(extra, pos + 4));
|
||||
break;
|
||||
case EXTID_EXTT:
|
||||
int flag = Byte.toUnsignedInt(extra[pos++]);
|
||||
if ((flag & 0x1) != 0) {
|
||||
e.mtime = unixToJavaTime(get32(extra, pos));
|
||||
pos += 4;
|
||||
}
|
||||
break;
|
||||
default: // unknown tag
|
||||
}
|
||||
off += (sz + 4);
|
||||
}
|
||||
|
||||
}
|
||||
return e;
|
||||
}
|
||||
@ -430,27 +450,4 @@ class ZipInputStream extends InflaterInputStream implements ZipConstants {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetches unsigned 16-bit value from byte array at specified offset.
|
||||
* The bytes are assumed to be in Intel (little-endian) byte order.
|
||||
*/
|
||||
private static final int get16(byte b[], int off) {
|
||||
return Byte.toUnsignedInt(b[off]) | (Byte.toUnsignedInt(b[off+1]) << 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetches unsigned 32-bit value from byte array at specified offset.
|
||||
* The bytes are assumed to be in Intel (little-endian) byte order.
|
||||
*/
|
||||
private static final long get32(byte b[], int off) {
|
||||
return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetches signed 64-bit value from byte array at specified offset.
|
||||
* The bytes are assumed to be in Intel (little-endian) byte order.
|
||||
*/
|
||||
private static final long get64(byte b[], int off) {
|
||||
return get32(b, off) | (get32(b, off+4) << 32);
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.Vector;
|
||||
import java.util.HashSet;
|
||||
import static java.util.zip.ZipConstants64.*;
|
||||
import static java.util.zip.ZipUtils.*;
|
||||
|
||||
/**
|
||||
* This class implements an output stream filter for writing files in the
|
||||
@ -190,7 +191,7 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
||||
if (current != null) {
|
||||
closeEntry(); // close previous entry
|
||||
}
|
||||
if (e.time == -1) {
|
||||
if (e.mtime == -1) {
|
||||
e.setTime(System.currentTimeMillis());
|
||||
}
|
||||
if (e.method == -1) {
|
||||
@ -382,16 +383,25 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
||||
private void writeLOC(XEntry xentry) throws IOException {
|
||||
ZipEntry e = xentry.entry;
|
||||
int flag = e.flag;
|
||||
int elen = (e.extra != null) ? e.extra.length : 0;
|
||||
boolean hasZip64 = false;
|
||||
|
||||
int elen = (e.extra != null) ? e.extra.length : 0;
|
||||
int eoff = 0;
|
||||
boolean foundEXTT = false; // if EXTT already present
|
||||
// do nothing.
|
||||
while (eoff + 4 < elen) {
|
||||
int tag = get16(e.extra, eoff);
|
||||
int sz = get16(e.extra, eoff + 2);
|
||||
if (tag == EXTID_EXTT) {
|
||||
foundEXTT = true;
|
||||
}
|
||||
eoff += (4 + sz);
|
||||
}
|
||||
writeInt(LOCSIG); // LOC header signature
|
||||
|
||||
if ((flag & 8) == 8) {
|
||||
writeShort(version(e)); // version needed to extract
|
||||
writeShort(flag); // general purpose bit flag
|
||||
writeShort(e.method); // compression method
|
||||
writeInt(e.time); // last modification time
|
||||
writeInt(javaToDosTime(e.mtime)); // last modification time
|
||||
|
||||
// store size, uncompressed size, and crc-32 in data descriptor
|
||||
// immediately following compressed entry data
|
||||
@ -407,7 +417,7 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
||||
}
|
||||
writeShort(flag); // general purpose bit flag
|
||||
writeShort(e.method); // compression method
|
||||
writeInt(e.time); // last modification time
|
||||
writeInt(javaToDosTime(e.mtime)); // last modification time
|
||||
writeInt(e.crc); // crc-32
|
||||
if (hasZip64) {
|
||||
writeInt(ZIP64_MAGICVAL);
|
||||
@ -420,6 +430,8 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
||||
}
|
||||
byte[] nameBytes = zc.getBytes(e.name);
|
||||
writeShort(nameBytes.length);
|
||||
if (!foundEXTT)
|
||||
elen += 9; // use Info-ZIP's ext time in extra
|
||||
writeShort(elen);
|
||||
writeBytes(nameBytes, 0, nameBytes.length);
|
||||
if (hasZip64) {
|
||||
@ -428,6 +440,12 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
||||
writeLong(e.size);
|
||||
writeLong(e.csize);
|
||||
}
|
||||
if (!foundEXTT) {
|
||||
writeShort(EXTID_EXTT);
|
||||
writeShort(5); // size for the folowing data block
|
||||
writeByte(0x1); // flags byte, mtime only
|
||||
writeInt(javaToUnixTime(e.mtime));
|
||||
}
|
||||
if (e.extra != null) {
|
||||
writeBytes(e.extra, 0, e.extra.length);
|
||||
}
|
||||
@ -457,25 +475,25 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
||||
ZipEntry e = xentry.entry;
|
||||
int flag = e.flag;
|
||||
int version = version(e);
|
||||
|
||||
long csize = e.csize;
|
||||
long size = e.size;
|
||||
long offset = xentry.offset;
|
||||
int e64len = 0;
|
||||
int elenZIP64 = 0;
|
||||
boolean hasZip64 = false;
|
||||
|
||||
if (e.csize >= ZIP64_MAGICVAL) {
|
||||
csize = ZIP64_MAGICVAL;
|
||||
e64len += 8; // csize(8)
|
||||
elenZIP64 += 8; // csize(8)
|
||||
hasZip64 = true;
|
||||
}
|
||||
if (e.size >= ZIP64_MAGICVAL) {
|
||||
size = ZIP64_MAGICVAL; // size(8)
|
||||
e64len += 8;
|
||||
elenZIP64 += 8;
|
||||
hasZip64 = true;
|
||||
}
|
||||
if (xentry.offset >= ZIP64_MAGICVAL) {
|
||||
offset = ZIP64_MAGICVAL;
|
||||
e64len += 8; // offset(8)
|
||||
elenZIP64 += 8; // offset(8)
|
||||
hasZip64 = true;
|
||||
}
|
||||
writeInt(CENSIG); // CEN header signature
|
||||
@ -488,18 +506,32 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
||||
}
|
||||
writeShort(flag); // general purpose bit flag
|
||||
writeShort(e.method); // compression method
|
||||
writeInt(e.time); // last modification time
|
||||
writeInt(javaToDosTime(e.mtime)); // last modification time
|
||||
writeInt(e.crc); // crc-32
|
||||
writeInt(csize); // compressed size
|
||||
writeInt(size); // uncompressed size
|
||||
byte[] nameBytes = zc.getBytes(e.name);
|
||||
writeShort(nameBytes.length);
|
||||
|
||||
int elen = (e.extra != null) ? e.extra.length : 0;
|
||||
int eoff = 0;
|
||||
boolean foundEXTT = false; // if EXTT already present
|
||||
// do nothing.
|
||||
while (eoff + 4 < elen) {
|
||||
int tag = get16(e.extra, eoff);
|
||||
int sz = get16(e.extra, eoff + 2);
|
||||
if (tag == EXTID_EXTT) {
|
||||
foundEXTT = true;
|
||||
}
|
||||
eoff += (4 + sz);
|
||||
}
|
||||
if (hasZip64) {
|
||||
// + headid(2) + datasize(2)
|
||||
writeShort(e64len + 4 + (e.extra != null ? e.extra.length : 0));
|
||||
} else {
|
||||
writeShort(e.extra != null ? e.extra.length : 0);
|
||||
elen += (elenZIP64 + 4);
|
||||
}
|
||||
if (!foundEXTT)
|
||||
elen += 9; // Info-ZIP's Extended Timestamp
|
||||
writeShort(elen);
|
||||
byte[] commentBytes;
|
||||
if (e.comment != null) {
|
||||
commentBytes = zc.getBytes(e.comment);
|
||||
@ -515,7 +547,7 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
||||
writeBytes(nameBytes, 0, nameBytes.length);
|
||||
if (hasZip64) {
|
||||
writeShort(ZIP64_EXTID);// Zip64 extra
|
||||
writeShort(e64len);
|
||||
writeShort(elenZIP64);
|
||||
if (size == ZIP64_MAGICVAL)
|
||||
writeLong(e.size);
|
||||
if (csize == ZIP64_MAGICVAL)
|
||||
@ -523,6 +555,12 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
||||
if (offset == ZIP64_MAGICVAL)
|
||||
writeLong(xentry.offset);
|
||||
}
|
||||
if (!foundEXTT) {
|
||||
writeShort(EXTID_EXTT);
|
||||
writeShort(5);
|
||||
writeByte(0x1); // flags byte
|
||||
writeInt(javaToUnixTime(e.mtime));
|
||||
}
|
||||
if (e.extra != null) {
|
||||
writeBytes(e.extra, 0, e.extra.length);
|
||||
}
|
||||
@ -588,6 +626,15 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes a 8-bit byte to the output stream.
|
||||
*/
|
||||
private void writeByte(int v) throws IOException {
|
||||
OutputStream out = this.out;
|
||||
out.write(v & 0xff);
|
||||
written += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes a 16-bit short to the output stream in little-endian byte order.
|
||||
*/
|
||||
|
||||
120
jdk/src/share/classes/java/util/zip/ZipUtils.java
Normal file
120
jdk/src/share/classes/java/util/zip/ZipUtils.java
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.util.zip;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
class ZipUtils {
|
||||
|
||||
// used to adjust values between Windows and java epoch
|
||||
private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
|
||||
|
||||
/**
|
||||
* Converts Windows time (in microseconds, UTC/GMT) time to Java time.
|
||||
*/
|
||||
public static final long winToJavaTime(long wtime) {
|
||||
return TimeUnit.MILLISECONDS.convert(
|
||||
wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS, TimeUnit.MICROSECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Java time to Windows time.
|
||||
*/
|
||||
public static final long javaToWinTime(long time) {
|
||||
return (TimeUnit.MICROSECONDS.convert(time, TimeUnit.MILLISECONDS)
|
||||
- WINDOWS_EPOCH_IN_MICROSECONDS) * 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts "standard Unix time"(in seconds, UTC/GMT) to Java time
|
||||
*/
|
||||
public static final long unixToJavaTime(long utime) {
|
||||
return TimeUnit.MILLISECONDS.convert(utime, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Java time to "standard Unix time".
|
||||
*/
|
||||
public static final long javaToUnixTime(long time) {
|
||||
return TimeUnit.SECONDS.convert(time, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts DOS time to Java time (number of milliseconds since epoch).
|
||||
*/
|
||||
public static long dosToJavaTime(long dtime) {
|
||||
@SuppressWarnings("deprecation") // Use of date constructor.
|
||||
Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
|
||||
(int)(((dtime >> 21) & 0x0f) - 1),
|
||||
(int)((dtime >> 16) & 0x1f),
|
||||
(int)((dtime >> 11) & 0x1f),
|
||||
(int)((dtime >> 5) & 0x3f),
|
||||
(int)((dtime << 1) & 0x3e));
|
||||
return d.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Java time to DOS time.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Use of date methods
|
||||
public static long javaToDosTime(long time) {
|
||||
Date d = new Date(time);
|
||||
int year = d.getYear() + 1900;
|
||||
if (year < 1980) {
|
||||
return (1 << 21) | (1 << 16);
|
||||
}
|
||||
return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
|
||||
d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
|
||||
d.getSeconds() >> 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetches unsigned 16-bit value from byte array at specified offset.
|
||||
* The bytes are assumed to be in Intel (little-endian) byte order.
|
||||
*/
|
||||
public static final int get16(byte b[], int off) {
|
||||
return Byte.toUnsignedInt(b[off]) | (Byte.toUnsignedInt(b[off+1]) << 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches unsigned 32-bit value from byte array at specified offset.
|
||||
* The bytes are assumed to be in Intel (little-endian) byte order.
|
||||
*/
|
||||
public static final long get32(byte b[], int off) {
|
||||
return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches signed 64-bit value from byte array at specified offset.
|
||||
* The bytes are assumed to be in Intel (little-endian) byte order.
|
||||
*/
|
||||
public static final long get64(byte b[], int off) {
|
||||
return get32(b, off) | (get32(b, off+4) << 32);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1158,6 +1158,9 @@ public class Cipher {
|
||||
* determined from the given key, or if the given key has a keysize that
|
||||
* exceeds the maximum allowable keysize (as determined from the
|
||||
* configured jurisdiction policy files).
|
||||
* @throws UnsupportedOperationException if (@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
|
||||
* by the underlying {@code CipherSpi}.
|
||||
*/
|
||||
public final void init(int opmode, Key key) throws InvalidKeyException {
|
||||
init(opmode, key, JceSecurity.RANDOM);
|
||||
@ -1208,6 +1211,9 @@ public class Cipher {
|
||||
* determined from the given key, or if the given key has a keysize that
|
||||
* exceeds the maximum allowable keysize (as determined from the
|
||||
* configured jurisdiction policy files).
|
||||
* @throws UnsupportedOperationException if (@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
|
||||
* by the underlying {@code CipherSpi}.
|
||||
*/
|
||||
public final void init(int opmode, Key key, SecureRandom random)
|
||||
throws InvalidKeyException
|
||||
@ -1285,6 +1291,9 @@ public class Cipher {
|
||||
* algorithm parameters imply a cryptographic strength that would exceed
|
||||
* the legal limits (as determined from the configured jurisdiction
|
||||
* policy files).
|
||||
* @throws UnsupportedOperationException if (@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
|
||||
* by the underlying {@code CipherSpi}.
|
||||
*/
|
||||
public final void init(int opmode, Key key, AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException
|
||||
@ -1343,6 +1352,9 @@ public class Cipher {
|
||||
* algorithm parameters imply a cryptographic strength that would exceed
|
||||
* the legal limits (as determined from the configured jurisdiction
|
||||
* policy files).
|
||||
* @throws UnsupportedOperationException if (@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
|
||||
* by the underlying {@code CipherSpi}.
|
||||
*/
|
||||
public final void init(int opmode, Key key, AlgorithmParameterSpec params,
|
||||
SecureRandom random)
|
||||
@ -1416,6 +1428,9 @@ public class Cipher {
|
||||
* algorithm parameters imply a cryptographic strength that would exceed
|
||||
* the legal limits (as determined from the configured jurisdiction
|
||||
* policy files).
|
||||
* @throws UnsupportedOperationException if (@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
|
||||
* by the underlying {@code CipherSpi}.
|
||||
*/
|
||||
public final void init(int opmode, Key key, AlgorithmParameters params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException
|
||||
@ -1474,6 +1489,9 @@ public class Cipher {
|
||||
* algorithm parameters imply a cryptographic strength that would exceed
|
||||
* the legal limits (as determined from the configured jurisdiction
|
||||
* policy files).
|
||||
* @throws UnsupportedOperationException if (@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
|
||||
* by the underlying {@code CipherSpi}.
|
||||
*/
|
||||
public final void init(int opmode, Key key, AlgorithmParameters params,
|
||||
SecureRandom random)
|
||||
@ -1552,6 +1570,9 @@ public class Cipher {
|
||||
* in the given certificate has a keysize that exceeds the maximum
|
||||
* allowable keysize (as determined by the configured jurisdiction policy
|
||||
* files).
|
||||
* @throws UnsupportedOperationException if (@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
|
||||
* by the underlying {@code CipherSpi}.
|
||||
*/
|
||||
public final void init(int opmode, Certificate certificate)
|
||||
throws InvalidKeyException
|
||||
@ -1619,6 +1640,9 @@ public class Cipher {
|
||||
* in the given certificate has a keysize that exceeds the maximum
|
||||
* allowable keysize (as determined by the configured jurisdiction policy
|
||||
* files).
|
||||
* @throws UnsupportedOperationException if (@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
|
||||
* by the underlying {@code CipherSpi}.
|
||||
*/
|
||||
public final void init(int opmode, Certificate certificate,
|
||||
SecureRandom random)
|
||||
@ -2410,6 +2434,9 @@ public class Cipher {
|
||||
* @exception InvalidKeyException if it is impossible or unsafe to
|
||||
* wrap the key with this cipher (e.g., a hardware protected key is
|
||||
* being passed to a software-only cipher).
|
||||
*
|
||||
* @throws UnsupportedOperationException if the corresponding method in the
|
||||
* {@code CipherSpi} is not supported.
|
||||
*/
|
||||
public final byte[] wrap(Key key)
|
||||
throws IllegalBlockSizeException, InvalidKeyException {
|
||||
@ -2451,6 +2478,9 @@ public class Cipher {
|
||||
* @exception InvalidKeyException if <code>wrappedKey</code> does not
|
||||
* represent a wrapped key of type <code>wrappedKeyType</code> for
|
||||
* the <code>wrappedKeyAlgorithm</code>.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the corresponding method in the
|
||||
* {@code CipherSpi} is not supported.
|
||||
*/
|
||||
public final Key unwrap(byte[] wrappedKey,
|
||||
String wrappedKeyAlgorithm,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2007, 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -86,6 +86,8 @@ public class CipherInputStream extends FilterInputStream {
|
||||
private int ostart = 0;
|
||||
// the offset pointing to the last "new" byte
|
||||
private int ofinish = 0;
|
||||
// stream status
|
||||
private boolean closed = false;
|
||||
|
||||
/**
|
||||
* private convenience function.
|
||||
@ -293,14 +295,17 @@ public class CipherInputStream extends FilterInputStream {
|
||||
* @since JCE1.2
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
closed = true;
|
||||
input.close();
|
||||
try {
|
||||
// throw away the unprocessed data
|
||||
cipher.doFinal();
|
||||
}
|
||||
catch (BadPaddingException ex) {
|
||||
}
|
||||
catch (IllegalBlockSizeException ex) {
|
||||
catch (BadPaddingException | IllegalBlockSizeException ex) {
|
||||
}
|
||||
ostart = 0;
|
||||
ofinish = 0;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2007, 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -74,6 +74,9 @@ public class CipherOutputStream extends FilterOutputStream {
|
||||
// the buffer holding data ready to be written out
|
||||
private byte[] obuffer;
|
||||
|
||||
// stream status
|
||||
private boolean closed = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructs a CipherOutputStream from an OutputStream and a
|
||||
@ -198,11 +201,14 @@ public class CipherOutputStream extends FilterOutputStream {
|
||||
* @since JCE1.2
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
closed = true;
|
||||
try {
|
||||
obuffer = cipher.doFinal();
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
obuffer = null;
|
||||
} catch (BadPaddingException e) {
|
||||
} catch (IllegalBlockSizeException | BadPaddingException e) {
|
||||
obuffer = null;
|
||||
}
|
||||
try {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -347,6 +347,9 @@ public abstract class CipherSpi {
|
||||
* initializing this cipher, or requires
|
||||
* algorithm parameters that cannot be
|
||||
* determined from the given key.
|
||||
* @throws UnsupportedOperationException if {@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
|
||||
* by the cipher.
|
||||
*/
|
||||
protected abstract void engineInit(int opmode, Key key,
|
||||
SecureRandom random)
|
||||
@ -399,6 +402,9 @@ public abstract class CipherSpi {
|
||||
* parameters are inappropriate for this cipher,
|
||||
* or if this cipher requires
|
||||
* algorithm parameters and <code>params</code> is null.
|
||||
* @throws UnsupportedOperationException if {@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
|
||||
* by the cipher.
|
||||
*/
|
||||
protected abstract void engineInit(int opmode, Key key,
|
||||
AlgorithmParameterSpec params,
|
||||
@ -452,6 +458,9 @@ public abstract class CipherSpi {
|
||||
* parameters are inappropriate for this cipher,
|
||||
* or if this cipher requires
|
||||
* algorithm parameters and <code>params</code> is null.
|
||||
* @throws UnsupportedOperationException if {@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
|
||||
* by the cipher.
|
||||
*/
|
||||
protected abstract void engineInit(int opmode, Key key,
|
||||
AlgorithmParameters params,
|
||||
@ -863,6 +872,8 @@ public abstract class CipherSpi {
|
||||
* @exception InvalidKeyException if it is impossible or unsafe to
|
||||
* wrap the key with this cipher (e.g., a hardware protected key is
|
||||
* being passed to a software-only cipher).
|
||||
*
|
||||
* @throws UnsupportedOperationException if this method is not supported.
|
||||
*/
|
||||
protected byte[] engineWrap(Key key)
|
||||
throws IllegalBlockSizeException, InvalidKeyException
|
||||
@ -899,6 +910,8 @@ public abstract class CipherSpi {
|
||||
* @exception InvalidKeyException if <code>wrappedKey</code> does not
|
||||
* represent a wrapped key of type <code>wrappedKeyType</code> for
|
||||
* the <code>wrappedKeyAlgorithm</code>.
|
||||
*
|
||||
* @throws UnsupportedOperationException if this method is not supported.
|
||||
*/
|
||||
protected Key engineUnwrap(byte[] wrappedKey,
|
||||
String wrappedKeyAlgorithm,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -55,8 +55,7 @@ public class DefaultComboBoxModel<E> extends AbstractListModel<E> implements Mut
|
||||
* @param items an array of Object objects
|
||||
*/
|
||||
public DefaultComboBoxModel(final E items[]) {
|
||||
objects = new Vector<E>();
|
||||
objects.ensureCapacity( items.length );
|
||||
objects = new Vector<E>(items.length);
|
||||
|
||||
int i,c;
|
||||
for ( i=0,c=items.length;i<c;i++ )
|
||||
|
||||
@ -285,10 +285,11 @@ class KeyboardManager {
|
||||
while (iter.hasMoreElements()) {
|
||||
JMenuBar mb = (JMenuBar)iter.nextElement();
|
||||
if ( mb.isShowing() && mb.isEnabled() ) { // don't want to give these out
|
||||
if( !(ks.equals(ksE)) ) {
|
||||
boolean extended = (ksE != null) && !ksE.equals(ks);
|
||||
if (extended) {
|
||||
fireBinding(mb, ksE, e, pressed);
|
||||
}
|
||||
if(ks.equals(ksE) || !e.isConsumed()) {
|
||||
if (!extended || !e.isConsumed()) {
|
||||
fireBinding(mb, ks, e, pressed);
|
||||
}
|
||||
if (e.isConsumed()) {
|
||||
|
||||
@ -692,9 +692,9 @@ public class BasicComboBoxUI extends ComboBoxUI {
|
||||
*/
|
||||
protected void installComponents() {
|
||||
arrowButton = createArrowButton();
|
||||
comboBox.add( arrowButton );
|
||||
|
||||
if (arrowButton != null) {
|
||||
comboBox.add(arrowButton);
|
||||
configureArrowButton();
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2007, 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -419,7 +419,7 @@ public class BasicTableUI extends TableUI
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(table.getParent().getParent() instanceof
|
||||
if (!(SwingUtilities.getUnwrappedParent(table).getParent() instanceof
|
||||
JScrollPane)) {
|
||||
return;
|
||||
}
|
||||
@ -1431,7 +1431,7 @@ public class BasicTableUI extends TableUI
|
||||
}
|
||||
|
||||
// install the scrollpane border
|
||||
Container parent = table.getParent(); // should be viewport
|
||||
Container parent = SwingUtilities.getUnwrappedParent(table); // should be viewport
|
||||
if (parent != null) {
|
||||
parent = parent.getParent(); // should be the scrollpane
|
||||
if (parent != null && parent instanceof JScrollPane) {
|
||||
|
||||
@ -484,6 +484,11 @@ public final class AWTAccessor {
|
||||
*/
|
||||
void invokeAndWait(Object source, Runnable r)
|
||||
throws InterruptedException, InvocationTargetException;
|
||||
|
||||
/**
|
||||
* Sets the delegate for the EventQueue used by FX/AWT single threaded mode
|
||||
*/
|
||||
public void setFwDispatcher(EventQueue eventQueue, FwDispatcher dispatcher);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
59
jdk/src/share/classes/sun/awt/FwDispatcher.java
Normal file
59
jdk/src/share/classes/sun/awt/FwDispatcher.java
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 sun.awt;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* An interface for the EventQueue delegate.
|
||||
* This class is added to support JavaFX/AWT interop single threaded mode
|
||||
* The delegate should be set in EventQueue by {@link EventQueue#setFwDispatcher(FwDispatcher)}
|
||||
* If the delegate is not null, than it handles supported methods instead of the
|
||||
* event queue. If it is null than the behaviour of an event queue does not change.
|
||||
*
|
||||
* @see EventQueue
|
||||
*
|
||||
* @author Petr Pchelko
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface FwDispatcher {
|
||||
/**
|
||||
* Delegates the {@link EventQueue#isDispatchThread()} method
|
||||
*/
|
||||
boolean isDispatchThread();
|
||||
|
||||
/**
|
||||
* Forwards a runnable to the delegate, which executes it on an appropriate thread.
|
||||
* @param r - a runnable calling {@link EventQueue#dispatchEventImpl(java.awt.AWTEvent, Object)}
|
||||
*/
|
||||
void scheduleDispatch(Runnable r);
|
||||
|
||||
/**
|
||||
* Delegates the {@link java.awt.EventQueue#createSecondaryLoop()} method
|
||||
*/
|
||||
SecondaryLoop createSecondaryLoop();
|
||||
}
|
||||
@ -36,6 +36,7 @@ import sun.awt.image.BufImgSurfaceData;
|
||||
import sun.java2d.loops.GraphicsPrimitive;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.pipe.Region;
|
||||
|
||||
/**
|
||||
* MaskFill
|
||||
@ -194,10 +195,13 @@ public class MaskFill extends GraphicsPrimitive
|
||||
// REMIND: This is not pretty. It would be nicer if we
|
||||
// passed a "FillData" object to the Pixel loops, instead
|
||||
// of a SunGraphics2D parameter...
|
||||
Region clip = sg2d.clipRegion;
|
||||
sg2d.clipRegion = null;
|
||||
int pixel = sg2d.pixel;
|
||||
sg2d.pixel = tmpData.pixelFor(sg2d.getColor());
|
||||
fillop.FillRect(sg2d, tmpData, 0, 0, w, h);
|
||||
sg2d.pixel = pixel;
|
||||
sg2d.clipRegion = clip;
|
||||
|
||||
maskop.MaskBlit(tmpData, sData, comp, null,
|
||||
0, 0, x, y, w, h,
|
||||
|
||||
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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 sun.management;
|
||||
|
||||
/**
|
||||
* Diagnostic Command Argument information. It contains the description
|
||||
* of one parameter of the diagnostic command. A parameter can either be an
|
||||
* option or an argument. Options are identified by the option name while
|
||||
* arguments are identified by their position in the command line. The generic
|
||||
* syntax of a diagnostic command is:
|
||||
* <blockquote>
|
||||
* <command name> [<option>=<value>] [<argument_value>]
|
||||
* </blockquote>
|
||||
* Example:
|
||||
* <blockquote>
|
||||
* command_name option1=value1 option2=value argumentA argumentB argumentC
|
||||
* </blockquote>
|
||||
* In this command line, the diagnostic command receives five parameters, two
|
||||
* options named {@code option1} and {@code option2}, and three arguments.
|
||||
* argumentA's position is 0, argumentB's position is 1 and argumentC's
|
||||
* position is 2.
|
||||
*
|
||||
* @since 8
|
||||
*/
|
||||
|
||||
class DiagnosticCommandArgumentInfo {
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final String type;
|
||||
private final String defaultValue;
|
||||
private final boolean mandatory;
|
||||
private final boolean option;
|
||||
private final boolean multiple;
|
||||
private final int position;
|
||||
|
||||
/**
|
||||
* Returns the argument name.
|
||||
*
|
||||
* @return the argument name
|
||||
*/
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the argument description.
|
||||
*
|
||||
* @return the argument description
|
||||
*/
|
||||
String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the argument type.
|
||||
*
|
||||
* @return the argument type
|
||||
*/
|
||||
String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default value as a String if a default value
|
||||
* is defined, null otherwise.
|
||||
*
|
||||
* @return the default value as a String if a default value
|
||||
* is defined, null otherwise.
|
||||
*/
|
||||
String getDefault() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the argument is mandatory,
|
||||
* {@code false} otherwise.
|
||||
*
|
||||
* @return {@code true} if the argument is mandatory,
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
boolean isMandatory() {
|
||||
return mandatory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the argument is an option,
|
||||
* {@code false} otherwise. Options have to be specified using the
|
||||
* <key>=<value> syntax on the command line, while other
|
||||
* arguments are specified with a single <value> field and are
|
||||
* identified by their position on command line.
|
||||
*
|
||||
* @return {@code true} if the argument is an option,
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
boolean isOption() {
|
||||
return option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the argument can be specified multiple times,
|
||||
* {@code false} otherwise.
|
||||
*
|
||||
* @return {@code true} if the argument can be specified multiple times,
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
boolean isMultiple() {
|
||||
return multiple;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expected position of this argument if it is not an option,
|
||||
* -1 otherwise. Argument position if defined from left to right,
|
||||
* starting at zero and ignoring the diagnostic command name and
|
||||
* options.
|
||||
*
|
||||
* @return the expected position of this argument if it is not an option,
|
||||
* -1 otherwise.
|
||||
*/
|
||||
int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
DiagnosticCommandArgumentInfo(String name, String description,
|
||||
String type, String defaultValue,
|
||||
boolean mandatory, boolean option,
|
||||
boolean multiple, int position) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.type = type;
|
||||
this.defaultValue = defaultValue;
|
||||
this.mandatory = mandatory;
|
||||
this.option = option;
|
||||
this.multiple = multiple;
|
||||
this.position = position;
|
||||
}
|
||||
}
|
||||
380
jdk/src/share/classes/sun/management/DiagnosticCommandImpl.java
Normal file
380
jdk/src/share/classes/sun/management/DiagnosticCommandImpl.java
Normal file
@ -0,0 +1,380 @@
|
||||
/*
|
||||
* 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 sun.management;
|
||||
|
||||
import com.sun.management.DiagnosticCommandMBean;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.Permission;
|
||||
import java.util.*;
|
||||
import javax.management.*;
|
||||
|
||||
/**
|
||||
* Implementation class for the diagnostic commands subsystem.
|
||||
*
|
||||
* @since 8
|
||||
*/
|
||||
class DiagnosticCommandImpl extends NotificationEmitterSupport
|
||||
implements DiagnosticCommandMBean {
|
||||
|
||||
private final VMManagement jvm;
|
||||
private volatile Map<String, Wrapper> wrappers = null;
|
||||
private static final String strClassName = "".getClass().getName();
|
||||
private static final String strArrayClassName = String[].class.getName();
|
||||
private final boolean isSupported;
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String attribute) throws AttributeNotFoundException,
|
||||
MBeanException, ReflectionException {
|
||||
throw new AttributeNotFoundException(attribute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(Attribute attribute) throws AttributeNotFoundException,
|
||||
InvalidAttributeValueException, MBeanException, ReflectionException {
|
||||
throw new AttributeNotFoundException(attribute.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeList getAttributes(String[] attributes) {
|
||||
return new AttributeList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeList setAttributes(AttributeList attributes) {
|
||||
return new AttributeList();
|
||||
}
|
||||
|
||||
private class Wrapper {
|
||||
|
||||
String name;
|
||||
String cmd;
|
||||
DiagnosticCommandInfo info;
|
||||
Permission permission;
|
||||
|
||||
Wrapper(String name, String cmd, DiagnosticCommandInfo info)
|
||||
throws InstantiationException {
|
||||
this.name = name;
|
||||
this.cmd = cmd;
|
||||
this.info = info;
|
||||
this.permission = null;
|
||||
Exception cause = null;
|
||||
if (info.getPermissionClass() != null) {
|
||||
try {
|
||||
Class c = Class.forName(info.getPermissionClass());
|
||||
if (info.getPermissionAction() == null) {
|
||||
try {
|
||||
Constructor constructor = c.getConstructor(String.class);
|
||||
permission = (Permission) constructor.newInstance(info.getPermissionName());
|
||||
|
||||
} catch (InstantiationException | IllegalAccessException
|
||||
| IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException ex) {
|
||||
cause = ex;
|
||||
}
|
||||
}
|
||||
if (permission == null) {
|
||||
try {
|
||||
Constructor constructor = c.getConstructor(String.class, String.class);
|
||||
permission = (Permission) constructor.newInstance(
|
||||
info.getPermissionName(),
|
||||
info.getPermissionAction());
|
||||
} catch (InstantiationException | IllegalAccessException
|
||||
| IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException ex) {
|
||||
cause = ex;
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException ex) { }
|
||||
if (permission == null) {
|
||||
InstantiationException iex =
|
||||
new InstantiationException("Unable to instantiate required permission");
|
||||
iex.initCause(cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String execute(String[] args) {
|
||||
if (permission != null) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(permission);
|
||||
}
|
||||
}
|
||||
if(args == null) {
|
||||
return executeDiagnosticCommand(cmd);
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(cmd);
|
||||
for(int i=0; i<args.length; i++) {
|
||||
if(args[i] == null) {
|
||||
throw new IllegalArgumentException("Invalid null argument");
|
||||
}
|
||||
sb.append(" ");
|
||||
sb.append(args[i]);
|
||||
}
|
||||
return executeDiagnosticCommand(sb.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DiagnosticCommandImpl(VMManagement jvm) {
|
||||
this.jvm = jvm;
|
||||
isSupported = jvm.isRemoteDiagnosticCommandsSupported();
|
||||
}
|
||||
|
||||
private static class OperationInfoComparator implements Comparator<MBeanOperationInfo> {
|
||||
@Override
|
||||
public int compare(MBeanOperationInfo o1, MBeanOperationInfo o2) {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MBeanInfo getMBeanInfo() {
|
||||
SortedSet<MBeanOperationInfo> operations = new TreeSet<>(new OperationInfoComparator());
|
||||
Map<String, Wrapper> wrappersmap;
|
||||
if (!isSupported) {
|
||||
wrappersmap = (Map<String, Wrapper>) Collections.EMPTY_MAP;
|
||||
} else {
|
||||
try {
|
||||
String[] command = getDiagnosticCommands();
|
||||
DiagnosticCommandInfo[] info = getDiagnosticCommandInfo(command);
|
||||
MBeanParameterInfo stringArgInfo[] = new MBeanParameterInfo[]{
|
||||
new MBeanParameterInfo("arguments", strArrayClassName,
|
||||
"Array of Diagnostic Commands Arguments and Options")
|
||||
};
|
||||
wrappersmap = new HashMap<>();
|
||||
for (int i = 0; i < command.length; i++) {
|
||||
String name = transform(command[i]);
|
||||
try {
|
||||
Wrapper w = new Wrapper(name, command[i], info[i]);
|
||||
wrappersmap.put(name, w);
|
||||
operations.add(new MBeanOperationInfo(
|
||||
w.name,
|
||||
w.info.getDescription(),
|
||||
(w.info.getArgumentsInfo() == null
|
||||
|| w.info.getArgumentsInfo().isEmpty())
|
||||
? null : stringArgInfo,
|
||||
strClassName,
|
||||
MBeanOperationInfo.ACTION_INFO,
|
||||
commandDescriptor(w)));
|
||||
} catch (InstantiationException ex) {
|
||||
// If for some reasons the creation of a diagnostic command
|
||||
// wrappers fails, the diagnostic command is just ignored
|
||||
// and won't appear in the DynamicMBean
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException | UnsupportedOperationException e) {
|
||||
wrappersmap = (Map<String, Wrapper>) Collections.EMPTY_MAP;
|
||||
}
|
||||
}
|
||||
wrappers = Collections.unmodifiableMap(wrappersmap);
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("immutableInfo", "false");
|
||||
map.put("interfaceClassName","com.sun.management.DiagnosticCommandMBean");
|
||||
map.put("mxbean", "false");
|
||||
Descriptor desc = new ImmutableDescriptor(map);
|
||||
return new MBeanInfo(
|
||||
this.getClass().getName(),
|
||||
"Diagnostic Commands",
|
||||
null, // attributes
|
||||
null, // constructors
|
||||
operations.toArray(new MBeanOperationInfo[operations.size()]), // operations
|
||||
getNotificationInfo(), // notifications
|
||||
desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(String actionName, Object[] params, String[] signature)
|
||||
throws MBeanException, ReflectionException {
|
||||
if (!isSupported) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (wrappers == null) {
|
||||
getMBeanInfo();
|
||||
}
|
||||
Wrapper w = wrappers.get(actionName);
|
||||
if (w != null) {
|
||||
if (w.info.getArgumentsInfo().isEmpty()
|
||||
&& (params == null || params.length == 0)
|
||||
&& (signature == null || signature.length == 0)) {
|
||||
return w.execute(null);
|
||||
} else if((params != null && params.length == 1)
|
||||
&& (signature != null && signature.length == 1
|
||||
&& signature[0] != null
|
||||
&& signature[0].compareTo(strArrayClassName) == 0)) {
|
||||
return w.execute((String[]) params[0]);
|
||||
}
|
||||
}
|
||||
throw new ReflectionException(new NoSuchMethodException(actionName));
|
||||
}
|
||||
|
||||
private static String transform(String name) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean toLower = true;
|
||||
boolean toUpper = false;
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
char c = name.charAt(i);
|
||||
if (c == '.' || c == '_') {
|
||||
toLower = false;
|
||||
toUpper = true;
|
||||
} else {
|
||||
if (toUpper) {
|
||||
toUpper = false;
|
||||
sb.append(Character.toUpperCase(c));
|
||||
} else if(toLower) {
|
||||
sb.append(Character.toLowerCase(c));
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private Descriptor commandDescriptor(Wrapper w) throws IllegalArgumentException {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("dcmd.name", w.info.getName());
|
||||
map.put("dcmd.description", w.info.getDescription());
|
||||
map.put("dcmd.vmImpact", w.info.getImpact());
|
||||
map.put("dcmd.permissionClass", w.info.getPermissionClass());
|
||||
map.put("dcmd.permissionName", w.info.getPermissionName());
|
||||
map.put("dcmd.permissionAction", w.info.getPermissionAction());
|
||||
map.put("dcmd.enabled", w.info.isEnabled());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("help ");
|
||||
sb.append(w.info.getName());
|
||||
map.put("dcmd.help", executeDiagnosticCommand(sb.toString()));
|
||||
if (w.info.getArgumentsInfo() != null && !w.info.getArgumentsInfo().isEmpty()) {
|
||||
HashMap<String, Object> allargmap = new HashMap<>();
|
||||
for (DiagnosticCommandArgumentInfo arginfo : w.info.getArgumentsInfo()) {
|
||||
HashMap<String, Object> argmap = new HashMap<>();
|
||||
argmap.put("dcmd.arg.name", arginfo.getName());
|
||||
argmap.put("dcmd.arg.type", arginfo.getType());
|
||||
argmap.put("dcmd.arg.description", arginfo.getDescription());
|
||||
argmap.put("dcmd.arg.isMandatory", arginfo.isMandatory());
|
||||
argmap.put("dcmd.arg.isMultiple", arginfo.isMultiple());
|
||||
boolean isOption = arginfo.isOption();
|
||||
argmap.put("dcmd.arg.isOption", isOption);
|
||||
if(!isOption) {
|
||||
argmap.put("dcmd.arg.position", arginfo.getPosition());
|
||||
} else {
|
||||
argmap.put("dcmd.arg.position", -1);
|
||||
}
|
||||
allargmap.put(arginfo.getName(), new ImmutableDescriptor(argmap));
|
||||
}
|
||||
map.put("dcmd.arguments", new ImmutableDescriptor(allargmap));
|
||||
}
|
||||
return new ImmutableDescriptor(map);
|
||||
}
|
||||
|
||||
private final static String notifName =
|
||||
"javax.management.Notification";
|
||||
|
||||
private final static String[] diagFramNotifTypes = {
|
||||
"jmx.mbean.info.changed"
|
||||
};
|
||||
|
||||
private MBeanNotificationInfo[] notifInfo = null;
|
||||
|
||||
@Override
|
||||
public MBeanNotificationInfo[] getNotificationInfo() {
|
||||
synchronized (this) {
|
||||
if (notifInfo == null) {
|
||||
notifInfo = new MBeanNotificationInfo[1];
|
||||
notifInfo[0] =
|
||||
new MBeanNotificationInfo(diagFramNotifTypes,
|
||||
notifName,
|
||||
"Diagnostic Framework Notification");
|
||||
}
|
||||
}
|
||||
return notifInfo;
|
||||
}
|
||||
|
||||
private static long seqNumber = 0;
|
||||
private static long getNextSeqNumber() {
|
||||
return ++seqNumber;
|
||||
}
|
||||
|
||||
private void createDiagnosticFrameworkNotification() {
|
||||
|
||||
if (!hasListeners()) {
|
||||
return;
|
||||
}
|
||||
ObjectName on = null;
|
||||
try {
|
||||
on = ObjectName.getInstance(ManagementFactoryHelper.HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME);
|
||||
} catch (MalformedObjectNameException e) { }
|
||||
Notification notif = new Notification("jmx.mbean.info.changed",
|
||||
on,
|
||||
getNextSeqNumber());
|
||||
notif.setUserData(getMBeanInfo());
|
||||
sendNotification(notif);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void addNotificationListener(NotificationListener listener,
|
||||
NotificationFilter filter,
|
||||
Object handback) {
|
||||
boolean before = hasListeners();
|
||||
super.addNotificationListener(listener, filter, handback);
|
||||
boolean after = hasListeners();
|
||||
if (!before && after) {
|
||||
setNotificationEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeNotificationListener(NotificationListener listener)
|
||||
throws ListenerNotFoundException {
|
||||
boolean before = hasListeners();
|
||||
super.removeNotificationListener(listener);
|
||||
boolean after = hasListeners();
|
||||
if (before && !after) {
|
||||
setNotificationEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeNotificationListener(NotificationListener listener,
|
||||
NotificationFilter filter,
|
||||
Object handback)
|
||||
throws ListenerNotFoundException {
|
||||
boolean before = hasListeners();
|
||||
super.removeNotificationListener(listener, filter, handback);
|
||||
boolean after = hasListeners();
|
||||
if (before && !after) {
|
||||
setNotificationEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
private native void setNotificationEnabled(boolean enabled);
|
||||
private native String[] getDiagnosticCommands();
|
||||
private native DiagnosticCommandInfo[] getDiagnosticCommandInfo(String[] commands);
|
||||
private native String executeDiagnosticCommand(String command);
|
||||
|
||||
}
|
||||
151
jdk/src/share/classes/sun/management/DiagnosticCommandInfo.java
Normal file
151
jdk/src/share/classes/sun/management/DiagnosticCommandInfo.java
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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 sun.management;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Diagnostic command information. It contains the description of a
|
||||
* diagnostic command.
|
||||
*
|
||||
* @since 8
|
||||
*/
|
||||
|
||||
class DiagnosticCommandInfo {
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final String impact;
|
||||
private final String permissionClass;
|
||||
private final String permissionName;
|
||||
private final String permissionAction;
|
||||
private final boolean enabled;
|
||||
private final List<DiagnosticCommandArgumentInfo> arguments;
|
||||
|
||||
/**
|
||||
* Returns the diagnostic command name.
|
||||
*
|
||||
* @return the diagnostic command name
|
||||
*/
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the diagnostic command description.
|
||||
*
|
||||
* @return the diagnostic command description
|
||||
*/
|
||||
String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the potential impact of the diagnostic command execution
|
||||
* on the Java virtual machine behavior.
|
||||
*
|
||||
* @return the potential impact of the diagnostic command execution
|
||||
* on the Java virtual machine behavior
|
||||
*/
|
||||
String getImpact() {
|
||||
return impact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the permission class required to be allowed
|
||||
* to invoke the diagnostic command, or null if no permission
|
||||
* is required.
|
||||
*
|
||||
* @return the name of the permission class name required to be allowed
|
||||
* to invoke the diagnostic command, or null if no permission
|
||||
* is required
|
||||
*/
|
||||
String getPermissionClass() {
|
||||
return permissionClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the permission name required to be allowed to invoke the
|
||||
* diagnostic command, or null if no permission is required.
|
||||
*
|
||||
* @return the permission name required to be allowed to invoke the
|
||||
* diagnostic command, or null if no permission is required
|
||||
*/
|
||||
String getPermissionName() {
|
||||
return permissionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the permission action required to be allowed to invoke the
|
||||
* diagnostic command, or null if no permission is required or
|
||||
* if the permission has no action specified.
|
||||
*
|
||||
* @return the permission action required to be allowed to invoke the
|
||||
* diagnostic command, or null if no permission is required or
|
||||
* if the permission has no action specified
|
||||
*/
|
||||
String getPermissionAction() {
|
||||
return permissionAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the diagnostic command is enabled,
|
||||
* {@code false} otherwise. The enabled/disabled
|
||||
* status of a diagnostic command can evolve during
|
||||
* the lifetime of the Java virtual machine.
|
||||
*
|
||||
* @return {@code true} if the diagnostic command is enabled,
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of the diagnostic command arguments description.
|
||||
* If the diagnostic command has no arguments, it returns an empty list.
|
||||
*
|
||||
* @return a list of the diagnostic command arguments description
|
||||
*/
|
||||
List<DiagnosticCommandArgumentInfo> getArgumentsInfo() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
DiagnosticCommandInfo(String name, String description,
|
||||
String impact, String permissionClass,
|
||||
String permissionName, String permissionAction,
|
||||
boolean enabled,
|
||||
List<DiagnosticCommandArgumentInfo> arguments)
|
||||
{
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.impact = impact;
|
||||
this.permissionClass = permissionClass;
|
||||
this.permissionName = permissionName;
|
||||
this.permissionAction = permissionAction;
|
||||
this.enabled = enabled;
|
||||
this.arguments = arguments;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,7 @@ package sun.management;
|
||||
|
||||
import java.lang.management.*;
|
||||
|
||||
import javax.management.DynamicMBean;
|
||||
import javax.management.InstanceAlreadyExistsException;
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.MBeanServer;
|
||||
@ -42,7 +43,9 @@ import sun.util.logging.LoggingSupport;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import com.sun.management.DiagnosticCommandMBean;
|
||||
import com.sun.management.OSMBeanFactory;
|
||||
import com.sun.management.HotSpotDiagnosticMXBean;
|
||||
|
||||
@ -263,6 +266,7 @@ public class ManagementFactoryHelper {
|
||||
private static HotspotThread hsThreadMBean = null;
|
||||
private static HotspotCompilation hsCompileMBean = null;
|
||||
private static HotspotMemory hsMemoryMBean = null;
|
||||
private static DiagnosticCommandImpl hsDiagCommandMBean = null;
|
||||
|
||||
public static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() {
|
||||
if (hsDiagMBean == null) {
|
||||
@ -311,6 +315,14 @@ public class ManagementFactoryHelper {
|
||||
return hsMemoryMBean;
|
||||
}
|
||||
|
||||
public static synchronized DiagnosticCommandMBean getDiagnosticCommandMBean() {
|
||||
// Remote Diagnostic Commands may not be supported
|
||||
if (hsDiagCommandMBean == null && jvm.isRemoteDiagnosticCommandsSupported()) {
|
||||
hsDiagCommandMBean = new DiagnosticCommandImpl(jvm);
|
||||
}
|
||||
return hsDiagCommandMBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is for testing only.
|
||||
*/
|
||||
@ -365,6 +377,18 @@ public class ManagementFactoryHelper {
|
||||
private final static String HOTSPOT_THREAD_MBEAN_NAME =
|
||||
"sun.management:type=HotspotThreading";
|
||||
|
||||
final static String HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME =
|
||||
"com.sun.management:type=DiagnosticCommand";
|
||||
|
||||
public static HashMap<ObjectName, DynamicMBean> getPlatformDynamicMBeans() {
|
||||
HashMap<ObjectName, DynamicMBean> map = new HashMap<>();
|
||||
DiagnosticCommandMBean diagMBean = getDiagnosticCommandMBean();
|
||||
if (diagMBean != null) {
|
||||
map.put(Util.newObjectName(HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME), diagMBean);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
static void registerInternalMBeans(MBeanServer mbs) {
|
||||
// register all internal MBeans if not registered
|
||||
// No exception is thrown if a MBean with that object name
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -46,6 +46,7 @@ public interface VMManagement {
|
||||
public boolean isThreadAllocatedMemorySupported();
|
||||
public boolean isThreadAllocatedMemoryEnabled();
|
||||
public boolean isGcNotificationSupported();
|
||||
public boolean isRemoteDiagnosticCommandsSupported();
|
||||
|
||||
// Class Loading Subsystem
|
||||
public long getTotalClassCount();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -57,6 +57,7 @@ class VMManagementImpl implements VMManagement {
|
||||
private static boolean synchronizerUsageSupport;
|
||||
private static boolean threadAllocatedMemorySupport;
|
||||
private static boolean gcNotificationSupport;
|
||||
private static boolean remoteDiagnosticCommandsSupport;
|
||||
|
||||
|
||||
static {
|
||||
@ -106,6 +107,10 @@ class VMManagementImpl implements VMManagement {
|
||||
return gcNotificationSupport;
|
||||
}
|
||||
|
||||
public boolean isRemoteDiagnosticCommandsSupported() {
|
||||
return remoteDiagnosticCommandsSupport;
|
||||
}
|
||||
|
||||
public native boolean isThreadContentionMonitoringEnabled();
|
||||
public native boolean isThreadCpuTimeEnabled();
|
||||
public native boolean isThreadAllocatedMemoryEnabled();
|
||||
|
||||
@ -60,9 +60,12 @@ public final class JdpPacketWriter {
|
||||
*/
|
||||
public void addEntry(String entry)
|
||||
throws IOException {
|
||||
pkt.writeShort(entry.length());
|
||||
byte[] b = entry.getBytes("UTF-8");
|
||||
pkt.write(b);
|
||||
/* DataOutputStream.writeUTF() do essentially
|
||||
* the same as:
|
||||
* pkt.writeShort(entry.getBytes("UTF-8").length);
|
||||
* pkt.write(entry.getBytes("UTF-8"));
|
||||
*/
|
||||
pkt.writeUTF(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -31,7 +31,42 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This annotation marks classes and fields as considered to be contended.
|
||||
* <p>An annotation expressing that objects and/or their fields are
|
||||
* expected to encounter memory contention, generally in the form of
|
||||
* "false sharing". This annotation serves as a hint that such objects
|
||||
* and fields should reside in locations isolated from those of other
|
||||
* objects or fields. Susceptibility to memory contention is a
|
||||
* property of the intended usages of objects and fields, not their
|
||||
* types or qualifiers. The effects of this annotation will nearly
|
||||
* always add significant space overhead to objects. The use of
|
||||
* {@code @Contended} is warranted only when the performance impact of
|
||||
* this time/space tradeoff is intrinsically worthwhile; for example,
|
||||
* in concurrent contexts in which each instance of the annotated
|
||||
* class is often accessed by a different thread.
|
||||
*
|
||||
* <p>A {@code @Contended} field annotation may optionally include a
|
||||
* <i>contention group</i> tag. A contention group defines a set of one
|
||||
* or more fields that collectively must be isolated from all other
|
||||
* contention groups. The fields in the same contention group may not be
|
||||
* pairwise isolated. With no contention group tag (or with the default
|
||||
* empty tag: "") each {@code @Contended} field resides in its own
|
||||
* <i>distinct</i> and <i>anonymous</i> contention group.
|
||||
*
|
||||
* <p>When the annotation is used at the class level, the effect is
|
||||
* equivalent to grouping all the declared fields not already having the
|
||||
* {@code @Contended} annotation into the same anonymous group.
|
||||
* With the class level annotation, implementations may choose different
|
||||
* isolation techniques, such as isolating the entire object, rather than
|
||||
* isolating distinct fields. A contention group tag has no meaning
|
||||
* in a class level {@code @Contended} annotation, and is ignored.
|
||||
*
|
||||
* <p>The class level {@code @Contended} annotation is not inherited and has
|
||||
* no effect on the fields declared in any sub-classes. The effects of all
|
||||
* {@code @Contended} annotations, however, remain in force for all
|
||||
* subclass instances, providing isolation of all the defined contention
|
||||
* groups. Contention group tags are not inherited, and the same tag used
|
||||
* in a superclass and subclass, represent distinct contention groups.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ -39,7 +74,10 @@ import java.lang.annotation.Target;
|
||||
public @interface Contended {
|
||||
|
||||
/**
|
||||
Defines the contention group tag.
|
||||
* The (optional) contention group tag.
|
||||
* This tag is only meaningful for field level annotations.
|
||||
*
|
||||
* @return contention group tag.
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
*/
|
||||
package sun.misc;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* Hashing utilities.
|
||||
@ -207,28 +207,16 @@ public class Hashing {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds references to things that can't be initialized until after VM
|
||||
* is fully booted.
|
||||
* Return a non-zero 32-bit pseudo random value. The {@code instance} object
|
||||
* may be used as part of the value.
|
||||
*
|
||||
* @param instance an object to use if desired in choosing value.
|
||||
* @return a non-zero 32-bit pseudo random value.
|
||||
*/
|
||||
private static class Holder {
|
||||
|
||||
/**
|
||||
* Used for generating per-instance hash seeds.
|
||||
*
|
||||
* We try to improve upon the default seeding.
|
||||
*/
|
||||
static final Random SEED_MAKER = new Random(
|
||||
Double.doubleToRawLongBits(Math.random())
|
||||
^ System.identityHashCode(Hashing.class)
|
||||
^ System.currentTimeMillis()
|
||||
^ System.nanoTime()
|
||||
^ Runtime.getRuntime().freeMemory());
|
||||
}
|
||||
|
||||
public static int randomHashSeed(Object instance) {
|
||||
int seed;
|
||||
if (sun.misc.VM.isBooted()) {
|
||||
seed = Holder.SEED_MAKER.nextInt();
|
||||
seed = ThreadLocalRandom.current().nextInt();
|
||||
} else {
|
||||
// lower quality "random" seed value--still better than zero and not
|
||||
// not practically reversible.
|
||||
|
||||
@ -3158,6 +3158,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
private boolean marked = false;
|
||||
private int inCache = 0;
|
||||
private int markCount = 0;
|
||||
private boolean closed; // false
|
||||
|
||||
public HttpInputStream (InputStream is) {
|
||||
super (is);
|
||||
@ -3233,8 +3234,14 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureOpen() throws IOException {
|
||||
if (closed)
|
||||
throw new IOException("stream is closed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
ensureOpen();
|
||||
try {
|
||||
byte[] b = new byte[1];
|
||||
int ret = read(b);
|
||||
@ -3254,6 +3261,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
ensureOpen();
|
||||
try {
|
||||
int newLen = super.read(b, off, len);
|
||||
int nWrite;
|
||||
@ -3291,7 +3299,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
|
||||
@Override
|
||||
public long skip (long n) throws IOException {
|
||||
|
||||
ensureOpen();
|
||||
long remaining = n;
|
||||
int nr;
|
||||
if (skipBuffer == null)
|
||||
@ -3317,6 +3325,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
|
||||
@Override
|
||||
public void close () throws IOException {
|
||||
if (closed)
|
||||
return;
|
||||
|
||||
try {
|
||||
if (outputStream != null) {
|
||||
if (read() != -1) {
|
||||
@ -3332,6 +3343,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
}
|
||||
throw ioex;
|
||||
} finally {
|
||||
closed = true;
|
||||
HttpURLConnection.this.http = null;
|
||||
checkResponseCredentials (true);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -330,7 +330,7 @@ final class P11KeyAgreement extends KeyAgreementSpi {
|
||||
// as here we always retrieve the CKA_VALUE even for tokens
|
||||
// that do not have that bug.
|
||||
byte[] keyBytes = key.getEncoded();
|
||||
byte[] newBytes = P11Util.trimZeroes(keyBytes);
|
||||
byte[] newBytes = KeyUtil.trimZeroes(keyBytes);
|
||||
if (keyBytes != newBytes) {
|
||||
key = new SecretKeySpec(newBytes, algorithm);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,6 +41,7 @@ import sun.security.rsa.RSAPadding;
|
||||
|
||||
import sun.security.pkcs11.wrapper.*;
|
||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||
import sun.security.util.KeyUtil;
|
||||
|
||||
/**
|
||||
* Signature implementation class. This class currently supports the
|
||||
@ -697,8 +698,8 @@ final class P11Signature extends SignatureSpi {
|
||||
BigInteger r = values[0].getPositiveBigInteger();
|
||||
BigInteger s = values[1].getPositiveBigInteger();
|
||||
// trim leading zeroes
|
||||
byte[] br = P11Util.trimZeroes(r.toByteArray());
|
||||
byte[] bs = P11Util.trimZeroes(s.toByteArray());
|
||||
byte[] br = KeyUtil.trimZeroes(r.toByteArray());
|
||||
byte[] bs = KeyUtil.trimZeroes(s.toByteArray());
|
||||
int k = Math.max(br.length, bs.length);
|
||||
// r and s each occupy half the array
|
||||
byte[] res = new byte[k << 1];
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -131,20 +131,6 @@ public final class P11Util {
|
||||
return b;
|
||||
}
|
||||
|
||||
// trim leading (most significant) zeroes from the result
|
||||
static byte[] trimZeroes(byte[] b) {
|
||||
int i = 0;
|
||||
while ((i < b.length - 1) && (b[i] == 0)) {
|
||||
i++;
|
||||
}
|
||||
if (i == 0) {
|
||||
return b;
|
||||
}
|
||||
byte[] t = new byte[b.length - i];
|
||||
System.arraycopy(b, i, t, 0, t.length);
|
||||
return t;
|
||||
}
|
||||
|
||||
public static byte[] getMagnitude(BigInteger bi) {
|
||||
byte[] b = bi.toByteArray();
|
||||
if ((b.length > 1) && (b[0] == 0)) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -200,5 +200,24 @@ public final class KeyUtil {
|
||||
|
||||
// Don't bother to check against the y^q mod p if safe primes are used.
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim leading (most significant) zeroes from the result.
|
||||
*
|
||||
* @throws NullPointerException if {@code b} is null
|
||||
*/
|
||||
public static byte[] trimZeroes(byte[] b) {
|
||||
int i = 0;
|
||||
while ((i < b.length - 1) && (b[i] == 0)) {
|
||||
i++;
|
||||
}
|
||||
if (i == 0) {
|
||||
return b;
|
||||
}
|
||||
byte[] t = new byte[b.length - i];
|
||||
System.arraycopy(b, i, t, 0, t.length);
|
||||
return t;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -360,6 +360,8 @@ class SummaryTab extends Tab {
|
||||
Math.min(99F,
|
||||
elapsedCpu / (elapsedTime * 10000F * result.nCPUs));
|
||||
|
||||
cpuUsage = Math.max(0F, cpuUsage);
|
||||
|
||||
getPlotter().addValues(result.timeStamp,
|
||||
Math.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS)));
|
||||
getInfoLabel().setText(Resources.format(Messages.CPU_USAGE_FORMAT,
|
||||
|
||||
@ -25,6 +25,11 @@
|
||||
|
||||
package sun.util.locale.provider;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* FallbackProviderAdapter implementation.
|
||||
*
|
||||
@ -32,6 +37,18 @@ package sun.util.locale.provider;
|
||||
*/
|
||||
public class FallbackLocaleProviderAdapter extends JRELocaleProviderAdapter {
|
||||
|
||||
/**
|
||||
* Supported language tag set.
|
||||
*/
|
||||
private static final Set<String> rootTagSet =
|
||||
Collections.singleton(Locale.ROOT.toLanguageTag());
|
||||
|
||||
/**
|
||||
* Fallback provider only provides the ROOT locale data.
|
||||
*/
|
||||
private final LocaleResources rootLocaleResources =
|
||||
new LocaleResources(this, Locale.ROOT);
|
||||
|
||||
/**
|
||||
* Returns the type of this LocaleProviderAdapter
|
||||
*/
|
||||
@ -39,4 +56,14 @@ public class FallbackLocaleProviderAdapter extends JRELocaleProviderAdapter {
|
||||
public LocaleProviderAdapter.Type getAdapterType() {
|
||||
return Type.FALLBACK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocaleResources getLocaleResources(Locale locale) {
|
||||
return rootLocaleResources;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> createLanguageTagSet(String category) {
|
||||
return rootTagSet;
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,12 +34,10 @@ import java.text.spi.DateFormatProvider;
|
||||
import java.text.spi.DateFormatSymbolsProvider;
|
||||
import java.text.spi.DecimalFormatSymbolsProvider;
|
||||
import java.text.spi.NumberFormatProvider;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.spi.CalendarDataProvider;
|
||||
|
||||
@ -119,6 +119,12 @@ public abstract class LocaleProviderAdapter {
|
||||
*/
|
||||
private static LocaleProviderAdapter fallbackLocaleProviderAdapter = null;
|
||||
|
||||
/**
|
||||
* Default fallback adapter type, which should return something meaningful in any case.
|
||||
* This is either JRE or FALLBACK.
|
||||
*/
|
||||
static LocaleProviderAdapter.Type defaultLocaleProviderAdapter = null;
|
||||
|
||||
/**
|
||||
* Adapter lookup cache.
|
||||
*/
|
||||
@ -140,13 +146,19 @@ public abstract class LocaleProviderAdapter {
|
||||
// load adapter if necessary
|
||||
switch (aType) {
|
||||
case CLDR:
|
||||
cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter();
|
||||
if (cldrLocaleProviderAdapter == null) {
|
||||
cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter();
|
||||
}
|
||||
break;
|
||||
case HOST:
|
||||
hostLocaleProviderAdapter = new HostLocaleProviderAdapter();
|
||||
if (hostLocaleProviderAdapter == null) {
|
||||
hostLocaleProviderAdapter = new HostLocaleProviderAdapter();
|
||||
}
|
||||
break;
|
||||
}
|
||||
typeList.add(aType);
|
||||
if (!typeList.contains(aType)) {
|
||||
typeList.add(aType);
|
||||
}
|
||||
} catch (IllegalArgumentException | UnsupportedOperationException e) {
|
||||
// could be caused by the user specifying wrong
|
||||
// provider name or format in the system property
|
||||
@ -160,11 +172,15 @@ public abstract class LocaleProviderAdapter {
|
||||
// Append FALLBACK as the last resort.
|
||||
fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter();
|
||||
typeList.add(Type.FALLBACK);
|
||||
defaultLocaleProviderAdapter = Type.FALLBACK;
|
||||
} else {
|
||||
defaultLocaleProviderAdapter = Type.JRE;
|
||||
}
|
||||
} else {
|
||||
// Default preference list
|
||||
typeList.add(Type.JRE);
|
||||
typeList.add(Type.SPI);
|
||||
defaultLocaleProviderAdapter = Type.JRE;
|
||||
}
|
||||
|
||||
adapterPreference = Collections.unmodifiableList(typeList);
|
||||
|
||||
@ -127,32 +127,13 @@ public final class LocaleServiceProviderPool {
|
||||
private LocaleServiceProviderPool (final Class<? extends LocaleServiceProvider> c) {
|
||||
providerClass = c;
|
||||
|
||||
// Add the JRE Locale Data Adapter implementation.
|
||||
providers.putIfAbsent(LocaleProviderAdapter.Type.JRE,
|
||||
LocaleProviderAdapter.forJRE().getLocaleServiceProvider(c));
|
||||
|
||||
// Add the SPI Locale Data Adapter implementation.
|
||||
LocaleProviderAdapter lda = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.SPI);
|
||||
LocaleServiceProvider provider = lda.getLocaleServiceProvider(c);
|
||||
if (provider != null) {
|
||||
providers.putIfAbsent(LocaleProviderAdapter.Type.SPI, provider);
|
||||
}
|
||||
|
||||
// Add the CLDR Locale Data Adapter implementation, if needed.
|
||||
lda = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR);
|
||||
if (lda != null) {
|
||||
provider = lda.getLocaleServiceProvider(c);
|
||||
if (provider != null) {
|
||||
providers.putIfAbsent(LocaleProviderAdapter.Type.CLDR, provider);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the Host Locale Data Adapter implementation, if needed.
|
||||
lda = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.HOST);
|
||||
if (lda != null) {
|
||||
provider = lda.getLocaleServiceProvider(c);
|
||||
if (provider != null) {
|
||||
providers.putIfAbsent(LocaleProviderAdapter.Type.HOST, provider);
|
||||
for (LocaleProviderAdapter.Type type : LocaleProviderAdapter.getAdapterPreference()) {
|
||||
LocaleProviderAdapter lda = LocaleProviderAdapter.forType(type);
|
||||
if (lda != null) {
|
||||
LocaleServiceProvider provider = lda.getLocaleServiceProvider(c);
|
||||
if (provider != null) {
|
||||
providers.putIfAbsent(type, provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -246,7 +227,8 @@ public final class LocaleServiceProviderPool {
|
||||
*/
|
||||
boolean hasProviders() {
|
||||
return providers.size() != 1 ||
|
||||
providers.get(LocaleProviderAdapter.Type.JRE) == null;
|
||||
(providers.get(LocaleProviderAdapter.Type.JRE) == null &&
|
||||
providers.get(LocaleProviderAdapter.Type.FALLBACK) == null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -296,9 +278,8 @@ public final class LocaleServiceProviderPool {
|
||||
// Check whether JRE is the sole locale data provider or not,
|
||||
// and directly call it if it is.
|
||||
if (!hasProviders()) {
|
||||
return getter.getObject(
|
||||
(P)providers.get(LocaleProviderAdapter.Type.JRE),
|
||||
locale, key, params);
|
||||
return getter.getObject((P)providers.get(LocaleProviderAdapter.defaultLocaleProviderAdapter),
|
||||
locale, key, params);
|
||||
}
|
||||
|
||||
List<Locale> lookupLocales = getLookupLocales(locale);
|
||||
|
||||
@ -1818,7 +1818,7 @@ public class ZipFileSystem extends FileSystem {
|
||||
|
||||
Entry(byte[] name) {
|
||||
name(name);
|
||||
this.mtime = System.currentTimeMillis();
|
||||
this.mtime = this.ctime = this.atime = System.currentTimeMillis();
|
||||
this.crc = 0;
|
||||
this.size = 0;
|
||||
this.csize = 0;
|
||||
@ -1912,17 +1912,18 @@ public class ZipFileSystem extends FileSystem {
|
||||
{
|
||||
int written = CENHDR;
|
||||
int version0 = version();
|
||||
|
||||
long csize0 = csize;
|
||||
long size0 = size;
|
||||
long locoff0 = locoff;
|
||||
int elen64 = 0; // extra for ZIP64
|
||||
int elenNTFS = 0; // extra for NTFS (a/c/mtime)
|
||||
int elenEXTT = 0; // extra for Extended Timestamp
|
||||
boolean foundExtraTime = false; // if time stamp NTFS, EXTT present
|
||||
|
||||
// confirm size/length
|
||||
int nlen = (name != null) ? name.length : 0;
|
||||
int elen = (extra != null) ? extra.length : 0;
|
||||
int eoff = 0;
|
||||
int clen = (comment != null) ? comment.length : 0;
|
||||
if (csize >= ZIP64_MINVAL) {
|
||||
csize0 = ZIP64_MINVAL;
|
||||
@ -1936,14 +1937,24 @@ public class ZipFileSystem extends FileSystem {
|
||||
locoff0 = ZIP64_MINVAL;
|
||||
elen64 += 8; // offset(8)
|
||||
}
|
||||
if (elen64 != 0)
|
||||
if (elen64 != 0) {
|
||||
elen64 += 4; // header and data sz 4 bytes
|
||||
}
|
||||
|
||||
if (atime != -1) {
|
||||
if (isWindows) // use NTFS
|
||||
while (eoff + 4 < elen) {
|
||||
int tag = SH(extra, eoff);
|
||||
int sz = SH(extra, eoff + 2);
|
||||
if (tag == EXTID_EXTT || tag == EXTID_NTFS) {
|
||||
foundExtraTime = true;
|
||||
}
|
||||
eoff += (4 + sz);
|
||||
}
|
||||
if (!foundExtraTime) {
|
||||
if (isWindows) { // use NTFS
|
||||
elenNTFS = 36; // total 36 bytes
|
||||
else // Extended Timestamp otherwise
|
||||
} else { // Extended Timestamp otherwise
|
||||
elenEXTT = 9; // only mtime in cen
|
||||
}
|
||||
}
|
||||
writeInt(os, CENSIG); // CEN header signature
|
||||
if (elen64 != 0) {
|
||||
@ -2092,11 +2103,13 @@ public class ZipFileSystem extends FileSystem {
|
||||
{
|
||||
writeInt(os, LOCSIG); // LOC header signature
|
||||
int version = version();
|
||||
|
||||
int nlen = (name != null) ? name.length : 0;
|
||||
int elen = (extra != null) ? extra.length : 0;
|
||||
boolean foundExtraTime = false; // if extra timestamp present
|
||||
int eoff = 0;
|
||||
int elen64 = 0;
|
||||
int elenEXTT = 0;
|
||||
int elenNTFS = 0;
|
||||
if ((flag & FLAG_DATADESCR) != 0) {
|
||||
writeShort(os, version()); // version needed to extract
|
||||
writeShort(os, flag); // general purpose bit flag
|
||||
@ -2128,14 +2141,27 @@ public class ZipFileSystem extends FileSystem {
|
||||
writeInt(os, size); // uncompressed size
|
||||
}
|
||||
}
|
||||
if (atime != -1 && !isWindows) { // on unix use "ext time"
|
||||
if (ctime == -1)
|
||||
elenEXTT = 13;
|
||||
else
|
||||
elenEXTT = 17;
|
||||
while (eoff + 4 < elen) {
|
||||
int tag = SH(extra, eoff);
|
||||
int sz = SH(extra, eoff + 2);
|
||||
if (tag == EXTID_EXTT || tag == EXTID_NTFS) {
|
||||
foundExtraTime = true;
|
||||
}
|
||||
eoff += (4 + sz);
|
||||
}
|
||||
if (!foundExtraTime) {
|
||||
if (isWindows) {
|
||||
elenNTFS = 36; // NTFS, total 36 bytes
|
||||
} else { // on unix use "ext time"
|
||||
elenEXTT = 9;
|
||||
if (atime != -1)
|
||||
elenEXTT += 4;
|
||||
if (ctime != -1)
|
||||
elenEXTT += 4;
|
||||
}
|
||||
}
|
||||
writeShort(os, name.length);
|
||||
writeShort(os, elen + elen64 + elenEXTT);
|
||||
writeShort(os, elen + elen64 + elenNTFS + elenEXTT);
|
||||
writeBytes(os, name);
|
||||
if (elen64 != 0) {
|
||||
writeShort(os, EXTID_ZIP64);
|
||||
@ -2143,15 +2169,28 @@ public class ZipFileSystem extends FileSystem {
|
||||
writeLong(os, size);
|
||||
writeLong(os, csize);
|
||||
}
|
||||
if (elenNTFS != 0) {
|
||||
writeShort(os, EXTID_NTFS);
|
||||
writeShort(os, elenNTFS - 4);
|
||||
writeInt(os, 0); // reserved
|
||||
writeShort(os, 0x0001); // NTFS attr tag
|
||||
writeShort(os, 24);
|
||||
writeLong(os, javaToWinTime(mtime));
|
||||
writeLong(os, javaToWinTime(atime));
|
||||
writeLong(os, javaToWinTime(ctime));
|
||||
}
|
||||
if (elenEXTT != 0) {
|
||||
writeShort(os, EXTID_EXTT);
|
||||
writeShort(os, elenEXTT - 4);// size for the folowing data block
|
||||
if (ctime == -1)
|
||||
os.write(0x3); // mtime and atime
|
||||
else
|
||||
os.write(0x7); // mtime, atime and ctime
|
||||
int fbyte = 0x1;
|
||||
if (atime != -1) // mtime and atime
|
||||
fbyte |= 0x2;
|
||||
if (ctime != -1) // mtime, atime and ctime
|
||||
fbyte |= 0x4;
|
||||
os.write(fbyte); // flags byte
|
||||
writeInt(os, javaToUnixTime(mtime));
|
||||
writeInt(os, javaToUnixTime(atime));
|
||||
if (atime != -1)
|
||||
writeInt(os, javaToUnixTime(atime));
|
||||
if (ctime != -1)
|
||||
writeInt(os, javaToUnixTime(ctime));
|
||||
}
|
||||
|
||||
@ -214,7 +214,7 @@ public class ZipInfo {
|
||||
winToJavaTime(LL(extra, off + 24)));
|
||||
break;
|
||||
case EXTID_EXTT:
|
||||
print(" ->Inof-ZIP Extended Timestamp: flag=%x%n",extra[off]);
|
||||
print(" ->Info-ZIP Extended Timestamp: flag=%x%n",extra[off]);
|
||||
pos = off + 1 ;
|
||||
while (pos + 4 <= off + sz) {
|
||||
print(" *%tc%n",
|
||||
@ -223,6 +223,7 @@ public class ZipInfo {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
print(" ->[tag=%x, size=%d]%n", tag, sz);
|
||||
}
|
||||
off += sz;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -49,7 +49,8 @@ enum {
|
||||
JMM_VERSION_1_1 = 0x20010100, // JDK 6
|
||||
JMM_VERSION_1_2 = 0x20010200, // JDK 7
|
||||
JMM_VERSION_1_2_1 = 0x20010201, // JDK 7 GA
|
||||
JMM_VERSION = 0x20010202
|
||||
JMM_VERSION_1_2_2 = 0x20010202,
|
||||
JMM_VERSION = 0x20010203
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@ -62,7 +63,8 @@ typedef struct {
|
||||
unsigned int isObjectMonitorUsageSupported : 1;
|
||||
unsigned int isSynchronizerUsageSupported : 1;
|
||||
unsigned int isThreadAllocatedMemorySupported : 1;
|
||||
unsigned int : 23;
|
||||
unsigned int isRemoteDiagnosticCommandsSupported : 1;
|
||||
unsigned int : 22;
|
||||
} jmmOptionalSupport;
|
||||
|
||||
typedef enum {
|
||||
@ -190,21 +192,27 @@ typedef struct {
|
||||
} jmmGCStat;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
const char* description;
|
||||
const char* impact;
|
||||
int num_arguments;
|
||||
jboolean enabled;
|
||||
const char* name; /* Name of the diagnostic command */
|
||||
const char* description; /* Short description */
|
||||
const char* impact; /* Impact on the JVM */
|
||||
const char* permission_class; /* Class name of the required permission if any */
|
||||
const char* permission_name; /* Permission name of the required permission if any */
|
||||
const char* permission_action; /* Action name of the required permission if any*/
|
||||
int num_arguments; /* Number of supported options or arguments */
|
||||
jboolean enabled; /* True if the diagnostic command can be invoked, false otherwise*/
|
||||
} dcmdInfo;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
const char* description;
|
||||
const char* type;
|
||||
const char* default_string;
|
||||
jboolean mandatory;
|
||||
jboolean option;
|
||||
int position;
|
||||
const char* name; /* Option/Argument name*/
|
||||
const char* description; /* Short description */
|
||||
const char* type; /* Type: STRING, BOOLEAN, etc. */
|
||||
const char* default_string; /* Default value in a parsable string */
|
||||
jboolean mandatory; /* True if the option/argument is mandatory */
|
||||
jboolean option; /* True if it is an option, false if it is an argument */
|
||||
/* (see diagnosticFramework.hpp for option/argument definitions) */
|
||||
jboolean multiple; /* True is the option can be specified several time */
|
||||
int position; /* Expected position for this argument (this field is */
|
||||
/* meaningless for options) */
|
||||
} dcmdArgInfo;
|
||||
|
||||
typedef struct jmmInterface_1_ {
|
||||
@ -327,6 +335,9 @@ typedef struct jmmInterface_1_ {
|
||||
jstring (JNICALL *ExecuteDiagnosticCommand)
|
||||
(JNIEnv *env,
|
||||
jstring command);
|
||||
void (JNICALL *SetDiagnosticFrameworkNotificationEnabled)
|
||||
(JNIEnv *env,
|
||||
jboolean enabled);
|
||||
} JmmInterface;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
169
jdk/src/share/native/sun/management/DiagnosticCommandImpl.c
Normal file
169
jdk/src/share/native/sun/management/DiagnosticCommandImpl.c
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include "management.h"
|
||||
#include "sun_management_DiagnosticCommandImpl.h"
|
||||
|
||||
JNIEXPORT void JNICALL Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled
|
||||
(JNIEnv *env, jobject dummy, jboolean enabled) {
|
||||
if(jmm_version > JMM_VERSION_1_2_2) {
|
||||
jmm_interface->SetDiagnosticFrameworkNotificationEnabled(env, enabled);
|
||||
} else {
|
||||
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
|
||||
"JMX interface to diagnostic framework notifications is not supported by this VM");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands
|
||||
(JNIEnv *env, jobject dummy)
|
||||
{
|
||||
return jmm_interface->GetDiagnosticCommands(env);
|
||||
}
|
||||
|
||||
jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command,
|
||||
int num_arg) {
|
||||
int i;
|
||||
jobject obj;
|
||||
jobjectArray result;
|
||||
dcmdArgInfo* dcmd_arg_info_array;
|
||||
jclass dcmdArgInfoCls;
|
||||
jclass arraysCls;
|
||||
jmethodID mid;
|
||||
jobject resultList;
|
||||
|
||||
dcmd_arg_info_array = (dcmdArgInfo*) malloc(num_arg * sizeof(dcmdArgInfo));
|
||||
if (dcmd_arg_info_array == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
jmm_interface->GetDiagnosticCommandArgumentsInfo(env, command,
|
||||
dcmd_arg_info_array);
|
||||
dcmdArgInfoCls = (*env)->FindClass(env,
|
||||
"sun/management/DiagnosticCommandArgumentInfo");
|
||||
result = (*env)->NewObjectArray(env, num_arg, dcmdArgInfoCls, NULL);
|
||||
if (result == NULL) {
|
||||
free(dcmd_arg_info_array);
|
||||
return NULL;
|
||||
}
|
||||
for (i=0; i<num_arg; i++) {
|
||||
obj = JNU_NewObjectByName(env,
|
||||
"sun/management/DiagnosticCommandArgumentInfo",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZI)V",
|
||||
(*env)->NewStringUTF(env,dcmd_arg_info_array[i].name),
|
||||
(*env)->NewStringUTF(env,dcmd_arg_info_array[i].description),
|
||||
(*env)->NewStringUTF(env,dcmd_arg_info_array[i].type),
|
||||
dcmd_arg_info_array[i].default_string == NULL ? NULL:
|
||||
(*env)->NewStringUTF(env, dcmd_arg_info_array[i].default_string),
|
||||
dcmd_arg_info_array[i].mandatory,
|
||||
dcmd_arg_info_array[i].option,
|
||||
dcmd_arg_info_array[i].multiple,
|
||||
dcmd_arg_info_array[i].position);
|
||||
if (obj == NULL) {
|
||||
free(dcmd_arg_info_array);
|
||||
return NULL;
|
||||
}
|
||||
(*env)->SetObjectArrayElement(env, result, i, obj);
|
||||
}
|
||||
free(dcmd_arg_info_array);
|
||||
arraysCls = (*env)->FindClass(env, "java/util/Arrays");
|
||||
mid = (*env)->GetStaticMethodID(env, arraysCls,
|
||||
"asList", "([Ljava/lang/Object;)Ljava/util/List;");
|
||||
resultList = (*env)->CallStaticObjectMethod(env, arraysCls, mid, result);
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/* Throws IllegalArgumentException if at least one of the diagnostic command
|
||||
* passed in argument is not supported by the JVM
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo
|
||||
(JNIEnv *env, jobject dummy, jobjectArray commands)
|
||||
{
|
||||
int i;
|
||||
jclass dcmdInfoCls;
|
||||
jobject result;
|
||||
jobjectArray args;
|
||||
jobject obj;
|
||||
jmmOptionalSupport mos;
|
||||
jint ret = jmm_interface->GetOptionalSupport(env, &mos);
|
||||
jsize num_commands;
|
||||
dcmdInfo* dcmd_info_array;
|
||||
|
||||
if (commands == NULL) {
|
||||
JNU_ThrowNullPointerException(env, "Invalid String Array");
|
||||
return NULL;
|
||||
}
|
||||
num_commands = (*env)->GetArrayLength(env, commands);
|
||||
dcmd_info_array = (dcmdInfo*) malloc(num_commands *
|
||||
sizeof(dcmdInfo));
|
||||
if (dcmd_info_array == NULL) {
|
||||
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||
}
|
||||
jmm_interface->GetDiagnosticCommandInfo(env, commands, dcmd_info_array);
|
||||
dcmdInfoCls = (*env)->FindClass(env,
|
||||
"sun/management/DiagnosticCommandInfo");
|
||||
result = (*env)->NewObjectArray(env, num_commands, dcmdInfoCls, NULL);
|
||||
if (result == NULL) {
|
||||
free(dcmd_info_array);
|
||||
JNU_ThrowOutOfMemoryError(env, 0);
|
||||
}
|
||||
for (i=0; i<num_commands; i++) {
|
||||
args = getDiagnosticCommandArgumentInfoArray(env,
|
||||
(*env)->GetObjectArrayElement(env,commands,i),
|
||||
dcmd_info_array[i].num_arguments);
|
||||
if (args == NULL) {
|
||||
free(dcmd_info_array);
|
||||
JNU_ThrowOutOfMemoryError(env, 0);
|
||||
}
|
||||
obj = JNU_NewObjectByName(env,
|
||||
"sun/management/DiagnosticCommandInfo",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V",
|
||||
(*env)->NewStringUTF(env,dcmd_info_array[i].name),
|
||||
(*env)->NewStringUTF(env,dcmd_info_array[i].description),
|
||||
(*env)->NewStringUTF(env,dcmd_info_array[i].impact),
|
||||
dcmd_info_array[i].permission_class==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_class),
|
||||
dcmd_info_array[i].permission_name==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_name),
|
||||
dcmd_info_array[i].permission_action==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_action),
|
||||
dcmd_info_array[i].enabled,
|
||||
args);
|
||||
if (obj == NULL) {
|
||||
free(dcmd_info_array);
|
||||
JNU_ThrowOutOfMemoryError(env, 0);
|
||||
}
|
||||
(*env)->SetObjectArrayElement(env, result, i, obj);
|
||||
}
|
||||
free(dcmd_info_array);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Throws IllegalArgumentException if the diagnostic command
|
||||
* passed in argument is not supported by the JVM
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand
|
||||
(JNIEnv *env, jobject dummy, jstring command) {
|
||||
return jmm_interface->ExecuteDiagnosticCommand(env, command);
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include <stdlib.h>
|
||||
#include "jvm.h"
|
||||
#include "management.h"
|
||||
#include "sun_management_VMManagementImpl.h"
|
||||
@ -96,6 +97,9 @@ Java_sun_management_VMManagementImpl_initOptionalSupportFields
|
||||
value = mos.isThreadAllocatedMemorySupported;
|
||||
setStaticBooleanField(env, cls, "threadAllocatedMemorySupport", value);
|
||||
|
||||
value = mos.isRemoteDiagnosticCommandsSupported;
|
||||
setStaticBooleanField(env, cls, "remoteDiagnosticCommandsSupport", value);
|
||||
|
||||
if ((jmm_version > JMM_VERSION_1_2) ||
|
||||
(jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF) >= 1))) {
|
||||
setStaticBooleanField(env, cls, "gcNotificationSupport", JNI_TRUE);
|
||||
|
||||
@ -649,9 +649,9 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
&& (dmpath == NULL) /* data model specific variables not set */
|
||||
#endif /* __solaris__ */
|
||||
) {
|
||||
|
||||
JLI_MemFree(newargv);
|
||||
JLI_MemFree(new_runpath);
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -935,7 +935,7 @@ SetExecname(char **argv)
|
||||
char buf[PATH_MAX+1];
|
||||
int len = readlink(self, buf, PATH_MAX);
|
||||
if (len >= 0) {
|
||||
buf[len] = '\0'; /* readlink doesn't nul terminate */
|
||||
buf[len] = '\0'; /* readlink(2) doesn't NUL terminate */
|
||||
exec_path = JLI_StringDup(buf);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user