Merge
This commit is contained in:
commit
17b2b94a22
@ -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.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
FILES_export = \
|
FILES_export = \
|
||||||
sun/management/ClassLoadingImpl.java \
|
sun/management/ClassLoadingImpl.java \
|
||||||
|
sun/management/DiagnosticCommandImpl.java \
|
||||||
sun/management/FileSystemImpl.java \
|
sun/management/FileSystemImpl.java \
|
||||||
sun/management/Flag.java \
|
sun/management/Flag.java \
|
||||||
sun/management/GarbageCollectorImpl.java \
|
sun/management/GarbageCollectorImpl.java \
|
||||||
|
@ -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.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
FILES_c = \
|
FILES_c = \
|
||||||
ClassLoadingImpl.c \
|
ClassLoadingImpl.c \
|
||||||
|
DiagnosticCommandImpl.c \
|
||||||
FileSystemImpl.c \
|
FileSystemImpl.c \
|
||||||
Flag.c \
|
Flag.c \
|
||||||
GarbageCollectorImpl.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.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -39,6 +39,10 @@ SUNWprivate_1.1 {
|
|||||||
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
|
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
|
||||||
Java_com_sun_management_UnixOperatingSystem_initialize;
|
Java_com_sun_management_UnixOperatingSystem_initialize;
|
||||||
Java_sun_management_ClassLoadingImpl_setVerboseClass;
|
Java_sun_management_ClassLoadingImpl_setVerboseClass;
|
||||||
|
Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand;
|
||||||
|
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands;
|
||||||
|
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo;
|
||||||
|
Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled;
|
||||||
Java_sun_management_FileSystemImpl_isAccessUserOnly0;
|
Java_sun_management_FileSystemImpl_isAccessUserOnly0;
|
||||||
Java_sun_management_Flag_getAllFlagNames;
|
Java_sun_management_Flag_getAllFlagNames;
|
||||||
Java_sun_management_Flag_getFlags;
|
Java_sun_management_Flag_getFlags;
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
# (2)Added 2 new codepoints (KS X 1001:1998)
|
# (2)Added 2 new codepoints (KS X 1001:1998)
|
||||||
# 0xA2E6 0x20AC # EURO Sign
|
# 0xA2E6 0x20AC # EURO Sign
|
||||||
# 0xA2E7 0x00AE # Registered Sign
|
# 0xA2E7 0x00AE # Registered Sign
|
||||||
|
# (3) KS X 1001:2002
|
||||||
|
# 0xA2E8 0x327E # CIRCLED KOREAN CHARACTER JUEUI (Postal Code Mark)
|
||||||
#
|
#
|
||||||
0x00 0x0000
|
0x00 0x0000
|
||||||
0x01 0x0001
|
0x01 0x0001
|
||||||
@ -295,6 +297,7 @@
|
|||||||
#
|
#
|
||||||
0xA2E6 0x20AC # EURO Sign
|
0xA2E6 0x20AC # EURO Sign
|
||||||
0xA2E7 0x00AE # Registered Sign
|
0xA2E7 0x00AE # Registered Sign
|
||||||
|
0xA2E8 0x327E # CIRCLED KOREAN CHARACTER JUEUI
|
||||||
#
|
#
|
||||||
0xA2E0 0x2116 # NUMERO SIGN
|
0xA2E0 0x2116 # NUMERO SIGN
|
||||||
0xA2E1 0x33C7 # SQUARE CO
|
0xA2E1 0x33C7 # SQUARE CO
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
package build.tools.generatebreakiteratordata;
|
package build.tools.generatebreakiteratordata;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -701,7 +702,14 @@ class CharSet {
|
|||||||
* the exact same characters as this one
|
* the exact same characters as this one
|
||||||
*/
|
*/
|
||||||
public boolean equals(Object that) {
|
public boolean equals(Object that) {
|
||||||
return (that instanceof CharSet) && chars.equals(((CharSet)that).chars);
|
return (that instanceof CharSet) && Arrays.equals(chars, ((CharSet)that).chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hash code for this set of characters
|
||||||
|
*/
|
||||||
|
public int hashCode() {
|
||||||
|
return Arrays.hashCode(chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -342,7 +342,7 @@ $(eval $(call SetupJavaCompilation,BUILD_JOBJC,\
|
|||||||
DISABLE_SJAVAC:=true,\
|
DISABLE_SJAVAC:=true,\
|
||||||
SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
|
SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
|
||||||
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
|
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
|
||||||
$(JDK_OUTPUTDIR)/gensrc, \
|
$(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
|
||||||
INCLUDES := com/apple/jobjc,\
|
INCLUDES := com/apple/jobjc,\
|
||||||
EXCLUDES := tests/java/com/apple/jobjc,\
|
EXCLUDES := tests/java/com/apple/jobjc,\
|
||||||
BIN:=$(JDK_OUTPUTDIR)/jobjc_classes,\
|
BIN:=$(JDK_OUTPUTDIR)/jobjc_classes,\
|
||||||
@ -355,7 +355,7 @@ $(eval $(call SetupJavaCompilation,BUILD_JOBJC_HEADERS,\
|
|||||||
SETUP:=GENERATE_JDKBYTECODE,\
|
SETUP:=GENERATE_JDKBYTECODE,\
|
||||||
SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
|
SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
|
||||||
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
|
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
|
||||||
$(JDK_OUTPUTDIR)/gensrc, \
|
$(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
|
||||||
INCLUDES := com/apple/jobjc,\
|
INCLUDES := com/apple/jobjc,\
|
||||||
EXCLUDES := tests/java/com/apple/jobjc,\
|
EXCLUDES := tests/java/com/apple/jobjc,\
|
||||||
BIN:=$(JDK_OUTPUTDIR)/jobjc_classes_headers,\
|
BIN:=$(JDK_OUTPUTDIR)/jobjc_classes_headers,\
|
||||||
|
@ -69,6 +69,9 @@ define typesAndBits
|
|||||||
$1_fulltype := character
|
$1_fulltype := character
|
||||||
$1_Fulltype := Character
|
$1_Fulltype := Character
|
||||||
$1_category := integralType
|
$1_category := integralType
|
||||||
|
$1_streams := streamableType
|
||||||
|
$1_streamtype := int
|
||||||
|
$1_Streamtype := Int
|
||||||
$1_LBPV := 1
|
$1_LBPV := 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -97,7 +100,7 @@ define typesAndBits
|
|||||||
$1_Type := Long
|
$1_Type := Long
|
||||||
$1_fulltype := long
|
$1_fulltype := long
|
||||||
$1_Fulltype := Long
|
$1_Fulltype := Long
|
||||||
$1_category := integralType
|
$1_category := integralType
|
||||||
$1_LBPV := 3
|
$1_LBPV := 3
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -231,10 +234,13 @@ $$($1_DST) : $$($1_DEP) $(GENSRC_BUFFER_DST)/_the.buffer.dir
|
|||||||
$(TOOL_SPP) < $$($1_SRC) > $$($1_OUT).tmp \
|
$(TOOL_SPP) < $$($1_SRC) > $$($1_OUT).tmp \
|
||||||
-K$$($1_type) \
|
-K$$($1_type) \
|
||||||
-K$$($1_category) \
|
-K$$($1_category) \
|
||||||
|
-K$$($1_streams) \
|
||||||
-Dtype=$$($1_type) \
|
-Dtype=$$($1_type) \
|
||||||
-DType=$$($1_Type) \
|
-DType=$$($1_Type) \
|
||||||
-Dfulltype=$$($1_fulltype) \
|
-Dfulltype=$$($1_fulltype) \
|
||||||
-DFulltype=$$($1_Fulltype) \
|
-DFulltype=$$($1_Fulltype) \
|
||||||
|
-Dstreamtype=$$($1_streamtype) \
|
||||||
|
-DStreamtype=$$($1_Streamtype) \
|
||||||
-Dx=$$($1_x) \
|
-Dx=$$($1_x) \
|
||||||
-Dmemtype=$$($1_memtype) \
|
-Dmemtype=$$($1_memtype) \
|
||||||
-DMemtype=$$($1_Memtype) \
|
-DMemtype=$$($1_Memtype) \
|
||||||
|
@ -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.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -39,6 +39,10 @@ SUNWprivate_1.1 {
|
|||||||
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
|
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
|
||||||
Java_com_sun_management_UnixOperatingSystem_initialize;
|
Java_com_sun_management_UnixOperatingSystem_initialize;
|
||||||
Java_sun_management_ClassLoadingImpl_setVerboseClass;
|
Java_sun_management_ClassLoadingImpl_setVerboseClass;
|
||||||
|
Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand;
|
||||||
|
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands;
|
||||||
|
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo;
|
||||||
|
Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled;
|
||||||
Java_sun_management_FileSystemImpl_isAccessUserOnly0;
|
Java_sun_management_FileSystemImpl_isAccessUserOnly0;
|
||||||
Java_sun_management_Flag_getAllFlagNames;
|
Java_sun_management_Flag_getAllFlagNames;
|
||||||
Java_sun_management_Flag_getFlags;
|
Java_sun_management_Flag_getFlags;
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -403,8 +403,9 @@ extends KeyAgreementSpi {
|
|||||||
}
|
}
|
||||||
return skey;
|
return skey;
|
||||||
} else if (algorithm.equals("TlsPremasterSecret")) {
|
} else if (algorithm.equals("TlsPremasterSecret")) {
|
||||||
// return entire secret
|
// remove leading zero bytes per RFC 5246 Section 8.1.2
|
||||||
return new SecretKeySpec(secret, "TlsPremasterSecret");
|
return new SecretKeySpec(
|
||||||
|
KeyUtil.trimZeroes(secret), "TlsPremasterSecret");
|
||||||
} else {
|
} else {
|
||||||
throw new NoSuchAlgorithmException("Unsupported secret key "
|
throw new NoSuchAlgorithmException("Unsupported secret key "
|
||||||
+ "algorithm: "+ algorithm);
|
+ "algorithm: "+ algorithm);
|
||||||
|
@ -86,12 +86,13 @@ public final class HmacPKCS12PBESHA1 extends HmacCore {
|
|||||||
throw new InvalidKeyException("SecretKey of PBE type required");
|
throw new InvalidKeyException("SecretKey of PBE type required");
|
||||||
}
|
}
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
// generate default for salt and iteration count if necessary
|
// should not auto-generate default values since current
|
||||||
if (salt == null) {
|
// javax.crypto.Mac api does not have any method for caller to
|
||||||
salt = new byte[20];
|
// retrieve the generated defaults.
|
||||||
SunJCE.getRandom().nextBytes(salt);
|
if ((salt == null) || (iCount == 0)) {
|
||||||
|
throw new InvalidAlgorithmParameterException
|
||||||
|
("PBEParameterSpec required for salt and iteration count");
|
||||||
}
|
}
|
||||||
if (iCount == 0) iCount = 100;
|
|
||||||
} else if (!(params instanceof PBEParameterSpec)) {
|
} else if (!(params instanceof PBEParameterSpec)) {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
("PBEParameterSpec type required");
|
("PBEParameterSpec type required");
|
||||||
|
@ -42,12 +42,10 @@ import java.security.spec.*;
|
|||||||
*/
|
*/
|
||||||
abstract class PBMAC1Core extends HmacCore {
|
abstract class PBMAC1Core extends HmacCore {
|
||||||
|
|
||||||
private static final int DEFAULT_SALT_LENGTH = 20;
|
// NOTE: this class inherits the Cloneable interface from HmacCore
|
||||||
private static final int DEFAULT_COUNT = 4096;
|
// Need to override clone() if mutable fields are added.
|
||||||
|
|
||||||
private final String kdfAlgo;
|
private final String kdfAlgo;
|
||||||
private final String hashAlgo;
|
private final String hashAlgo;
|
||||||
private final PBKDF2Core kdf;
|
|
||||||
private final int blockLength; // in octets
|
private final int blockLength; // in octets
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,13 +54,15 @@ abstract class PBMAC1Core extends HmacCore {
|
|||||||
*/
|
*/
|
||||||
PBMAC1Core(String kdfAlgo, String hashAlgo, int blockLength)
|
PBMAC1Core(String kdfAlgo, String hashAlgo, int blockLength)
|
||||||
throws NoSuchAlgorithmException {
|
throws NoSuchAlgorithmException {
|
||||||
|
|
||||||
super(hashAlgo, blockLength);
|
super(hashAlgo, blockLength);
|
||||||
this.kdfAlgo = kdfAlgo;
|
this.kdfAlgo = kdfAlgo;
|
||||||
this.hashAlgo = hashAlgo;
|
this.hashAlgo = hashAlgo;
|
||||||
this.blockLength = blockLength;
|
this.blockLength = blockLength;
|
||||||
|
}
|
||||||
|
|
||||||
switch(kdfAlgo) {
|
private static PBKDF2Core getKDFImpl(String algo) {
|
||||||
|
PBKDF2Core kdf = null;
|
||||||
|
switch(algo) {
|
||||||
case "HmacSHA1":
|
case "HmacSHA1":
|
||||||
kdf = new PBKDF2Core.HmacSHA1();
|
kdf = new PBKDF2Core.HmacSHA1();
|
||||||
break;
|
break;
|
||||||
@ -79,9 +79,10 @@ abstract class PBMAC1Core extends HmacCore {
|
|||||||
kdf = new PBKDF2Core.HmacSHA512();
|
kdf = new PBKDF2Core.HmacSHA512();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new NoSuchAlgorithmException(
|
throw new ProviderException(
|
||||||
"No MAC implementation for " + kdfAlgo);
|
"No MAC implementation for " + algo);
|
||||||
}
|
}
|
||||||
|
return kdf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,12 +121,13 @@ abstract class PBMAC1Core extends HmacCore {
|
|||||||
throw new InvalidKeyException("SecretKey of PBE type required");
|
throw new InvalidKeyException("SecretKey of PBE type required");
|
||||||
}
|
}
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
// generate default for salt and iteration count if necessary
|
// should not auto-generate default values since current
|
||||||
if (salt == null) {
|
// javax.crypto.Mac api does not have any method for caller to
|
||||||
salt = new byte[DEFAULT_SALT_LENGTH];
|
// retrieve the generated defaults.
|
||||||
SunJCE.getRandom().nextBytes(salt);
|
if ((salt == null) || (iCount == 0)) {
|
||||||
|
throw new InvalidAlgorithmParameterException
|
||||||
|
("PBEParameterSpec required for salt and iteration count");
|
||||||
}
|
}
|
||||||
if (iCount == 0) iCount = DEFAULT_COUNT;
|
|
||||||
} else if (!(params instanceof PBEParameterSpec)) {
|
} else if (!(params instanceof PBEParameterSpec)) {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
("PBEParameterSpec type required");
|
("PBEParameterSpec type required");
|
||||||
@ -168,7 +170,7 @@ abstract class PBMAC1Core extends HmacCore {
|
|||||||
java.util.Arrays.fill(passwdChars, ' ');
|
java.util.Arrays.fill(passwdChars, ' ');
|
||||||
|
|
||||||
SecretKey s = null;
|
SecretKey s = null;
|
||||||
|
PBKDF2Core kdf = getKDFImpl(kdfAlgo);
|
||||||
try {
|
try {
|
||||||
s = kdf.engineGenerateSecret(pbeSpec);
|
s = kdf.engineGenerateSecret(pbeSpec);
|
||||||
|
|
||||||
|
@ -731,10 +731,11 @@ public final class SunJCE extends Provider {
|
|||||||
put("Mac.HmacSHA384 SupportedKeyFormats", "RAW");
|
put("Mac.HmacSHA384 SupportedKeyFormats", "RAW");
|
||||||
put("Mac.HmacSHA512 SupportedKeyFormats", "RAW");
|
put("Mac.HmacSHA512 SupportedKeyFormats", "RAW");
|
||||||
put("Mac.HmacPBESHA1 SupportedKeyFormats", "RAW");
|
put("Mac.HmacPBESHA1 SupportedKeyFormats", "RAW");
|
||||||
put("Mac.HmacPBESHA224 SupportedKeyFormats", "RAW");
|
put("Mac.PBEWithHmacSHA1 SupportedKeyFormatS", "RAW");
|
||||||
put("Mac.HmacPBESHA256 SupportedKeyFormats", "RAW");
|
put("Mac.PBEWithHmacSHA224 SupportedKeyFormats", "RAW");
|
||||||
put("Mac.HmacPBESHA384 SupportedKeyFormats", "RAW");
|
put("Mac.PBEWithHmacSHA256 SupportedKeyFormats", "RAW");
|
||||||
put("Mac.HmacPBESHA512 SupportedKeyFormats", "RAW");
|
put("Mac.PBEWithHmacSHA384 SupportedKeyFormats", "RAW");
|
||||||
|
put("Mac.PBEWithHmacSHA512 SupportedKeyFormats", "RAW");
|
||||||
put("Mac.SslMacMD5 SupportedKeyFormats", "RAW");
|
put("Mac.SslMacMD5 SupportedKeyFormats", "RAW");
|
||||||
put("Mac.SslMacSHA1 SupportedKeyFormats", "RAW");
|
put("Mac.SslMacSHA1 SupportedKeyFormats", "RAW");
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -26,7 +26,6 @@
|
|||||||
package java.lang;
|
package java.lang;
|
||||||
|
|
||||||
import java.lang.annotation.Native;
|
import java.lang.annotation.Native;
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code Integer} class wraps a value of the primitive type
|
* The {@code Integer} class wraps a value of the primitive type
|
||||||
@ -185,7 +184,7 @@ public final class Integer extends Number implements Comparable<Integer> {
|
|||||||
* @since 1.8
|
* @since 1.8
|
||||||
*/
|
*/
|
||||||
public static String toUnsignedString(int i, int radix) {
|
public static String toUnsignedString(int i, int radix) {
|
||||||
return Long.toString(toUnsignedLong(i), radix);
|
return Long.toUnsignedString(toUnsignedLong(i), radix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -307,20 +306,39 @@ public final class Integer extends Number implements Comparable<Integer> {
|
|||||||
/**
|
/**
|
||||||
* Convert the integer to an unsigned number.
|
* Convert the integer to an unsigned number.
|
||||||
*/
|
*/
|
||||||
private static String toUnsignedString0(int i, int shift) {
|
private static String toUnsignedString0(int val, int shift) {
|
||||||
char[] buf = new char[32];
|
// assert shift > 0 && shift <=5 : "Illegal shift value";
|
||||||
int charPos = 32;
|
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
|
||||||
|
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
|
||||||
|
char[] buf = new char[chars];
|
||||||
|
|
||||||
|
formatUnsignedInt(val, shift, buf, 0, chars);
|
||||||
|
|
||||||
|
// Use special constructor which takes over "buf".
|
||||||
|
return new String(buf, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a long (treated as unsigned) into a character buffer.
|
||||||
|
* @param val the unsigned int to format
|
||||||
|
* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
|
||||||
|
* @param buf the character buffer to write to
|
||||||
|
* @param offset the offset in the destination buffer to start at
|
||||||
|
* @param len the number of characters to write
|
||||||
|
* @return the lowest character location used
|
||||||
|
*/
|
||||||
|
static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
|
||||||
|
int charPos = len;
|
||||||
int radix = 1 << shift;
|
int radix = 1 << shift;
|
||||||
int mask = radix - 1;
|
int mask = radix - 1;
|
||||||
do {
|
do {
|
||||||
buf[--charPos] = digits[i & mask];
|
buf[offset + --charPos] = Integer.digits[val & mask];
|
||||||
i >>>= shift;
|
val >>>= shift;
|
||||||
} while (i != 0);
|
} while (val != 0 && charPos > 0);
|
||||||
|
|
||||||
return new String(buf, charPos, (32 - charPos));
|
return charPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
final static char [] DigitTens = {
|
final static char [] DigitTens = {
|
||||||
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
|
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
|
||||||
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
|
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
|
||||||
@ -875,6 +893,7 @@ public final class Integer extends Number implements Comparable<Integer> {
|
|||||||
* Returns the value of this {@code Integer} as a {@code long}
|
* Returns the value of this {@code Integer} as a {@code long}
|
||||||
* after a widening primitive conversion.
|
* after a widening primitive conversion.
|
||||||
* @jls 5.1.2 Widening Primitive Conversions
|
* @jls 5.1.2 Widening Primitive Conversions
|
||||||
|
* @see Integer#toUnsignedLong(int)
|
||||||
*/
|
*/
|
||||||
public long longValue() {
|
public long longValue() {
|
||||||
return (long)value;
|
return (long)value;
|
||||||
|
@ -28,6 +28,7 @@ package java.lang;
|
|||||||
import java.lang.annotation.Native;
|
import java.lang.annotation.Native;
|
||||||
import java.math.*;
|
import java.math.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code Long} class wraps a value of the primitive type {@code
|
* The {@code Long} class wraps a value of the primitive type {@code
|
||||||
* long} in an object. An object of type {@code Long} contains a
|
* long} in an object. An object of type {@code Long} contains a
|
||||||
@ -344,18 +345,39 @@ public final class Long extends Number implements Comparable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the integer to an unsigned number.
|
* Format a long (treated as unsigned) into a String.
|
||||||
|
* @param val the value to format
|
||||||
|
* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
|
||||||
*/
|
*/
|
||||||
private static String toUnsignedString0(long i, int shift) {
|
static String toUnsignedString0(long val, int shift) {
|
||||||
char[] buf = new char[64];
|
// assert shift > 0 && shift <=5 : "Illegal shift value";
|
||||||
int charPos = 64;
|
int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
|
||||||
|
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
|
||||||
|
char[] buf = new char[chars];
|
||||||
|
|
||||||
|
formatUnsignedLong(val, shift, buf, 0, chars);
|
||||||
|
return new String(buf, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a long (treated as unsigned) into a character buffer.
|
||||||
|
* @param val the unsigned long to format
|
||||||
|
* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
|
||||||
|
* @param buf the character buffer to write to
|
||||||
|
* @param offset the offset in the destination buffer to start at
|
||||||
|
* @param len the number of characters to write
|
||||||
|
* @return the lowest character location used
|
||||||
|
*/
|
||||||
|
static int formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {
|
||||||
|
int charPos = len;
|
||||||
int radix = 1 << shift;
|
int radix = 1 << shift;
|
||||||
long mask = radix - 1;
|
int mask = radix - 1;
|
||||||
do {
|
do {
|
||||||
buf[--charPos] = Integer.digits[(int)(i & mask)];
|
buf[offset + --charPos] = Integer.digits[((int) val) & mask];
|
||||||
i >>>= shift;
|
val >>>= shift;
|
||||||
} while (i != 0);
|
} while (val != 0 && charPos > 0);
|
||||||
return new String(buf, charPos, (64 - charPos));
|
|
||||||
|
return charPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -42,7 +42,9 @@ import javax.management.StandardMBean;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.Permission;
|
import java.security.Permission;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
@ -482,6 +484,11 @@ public class ManagementFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
HashMap<ObjectName, DynamicMBean> dynmbeans =
|
||||||
|
ManagementFactoryHelper.getPlatformDynamicMBeans();
|
||||||
|
for (Map.Entry<ObjectName, DynamicMBean> e : dynmbeans.entrySet()) {
|
||||||
|
addDynamicMBean(platformMBeanServer, e.getValue(), e.getKey());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return platformMBeanServer;
|
return platformMBeanServer;
|
||||||
}
|
}
|
||||||
@ -825,4 +832,24 @@ public class ManagementFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* a {@code String} specifying the value of the cookie
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* if the cookie name contains illegal characters or it is one of
|
* if the cookie name contains illegal characters
|
||||||
* the tokens reserved for use by the cookie protocol
|
|
||||||
* @throws NullPointerException
|
* @throws NullPointerException
|
||||||
* if {@code name} is {@code null}
|
* if {@code name} is {@code null}
|
||||||
*
|
*
|
||||||
@ -142,7 +141,7 @@ public final class HttpCookie implements Cloneable {
|
|||||||
|
|
||||||
private HttpCookie(String name, String value, String header) {
|
private HttpCookie(String name, String value, String header) {
|
||||||
name = name.trim();
|
name = name.trim();
|
||||||
if (name.length() == 0 || !isToken(name)) {
|
if (name.length() == 0 || !isToken(name) || name.charAt(0) == '$') {
|
||||||
throw new IllegalArgumentException("Illegal cookie name");
|
throw new IllegalArgumentException("Illegal cookie name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,9 +169,8 @@ public final class HttpCookie implements Cloneable {
|
|||||||
* @return a List of cookie parsed from header line string
|
* @return a List of cookie parsed from header line string
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* if header string violates the cookie specification's syntax, or
|
* if header string violates the cookie specification's syntax or
|
||||||
* the cookie name contains illegal characters, or the cookie name
|
* the cookie name contains illegal characters.
|
||||||
* is one of the tokens reserved for use by the cookie protocol
|
|
||||||
* @throws NullPointerException
|
* @throws NullPointerException
|
||||||
* if the header string is {@code null}
|
* if the header string is {@code null}
|
||||||
*/
|
*/
|
||||||
|
@ -377,7 +377,7 @@ public final class HttpURLPermission extends Permission {
|
|||||||
throw new IllegalArgumentException ("unexpected URL scheme");
|
throw new IllegalArgumentException ("unexpected URL scheme");
|
||||||
}
|
}
|
||||||
if (!u.getSchemeSpecificPart().equals("*")) {
|
if (!u.getSchemeSpecificPart().equals("*")) {
|
||||||
u = URI.create(scheme + "://" + u.getAuthority() + u.getPath());
|
u = URI.create(scheme + "://" + u.getRawAuthority() + u.getRawPath());
|
||||||
}
|
}
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
package java.nio;
|
package java.nio;
|
||||||
|
|
||||||
|
import java.util.Spliterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A container for data of a specific primitive type.
|
* A container for data of a specific primitive type.
|
||||||
@ -173,6 +174,13 @@ package java.nio;
|
|||||||
|
|
||||||
public abstract class Buffer {
|
public abstract class Buffer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The characteristics of Spliterators that traverse and split elements
|
||||||
|
* maintained in Buffers.
|
||||||
|
*/
|
||||||
|
static final int SPLITERATOR_CHARACTERISTICS =
|
||||||
|
Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
|
||||||
|
|
||||||
// Invariants: mark <= position <= limit <= capacity
|
// Invariants: mark <= position <= limit <= capacity
|
||||||
private int mark = -1;
|
private int mark = -1;
|
||||||
private int position = 0;
|
private int position = 0;
|
||||||
|
@ -115,6 +115,12 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||||||
return Bits.get$Type$$BO$(bb, ix(checkIndex(i)));
|
return Bits.get$Type$$BO$(bb, ix(checkIndex(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if[streamableType]
|
||||||
|
$type$ getUnchecked(int i) {
|
||||||
|
return Bits.get$Type$$BO$(bb, ix(i));
|
||||||
|
}
|
||||||
|
#end[streamableType]
|
||||||
|
|
||||||
#end[rw]
|
#end[rw]
|
||||||
|
|
||||||
public $Type$Buffer put($type$ x) {
|
public $Type$Buffer put($type$ x) {
|
||||||
|
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)))));
|
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if[streamableType]
|
||||||
|
$type$ getUnchecked(int i) {
|
||||||
|
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(i))));
|
||||||
|
}
|
||||||
|
#end[streamableType]
|
||||||
|
|
||||||
public $Type$Buffer get($type$[] dst, int offset, int length) {
|
public $Type$Buffer get($type$[] dst, int offset, int length) {
|
||||||
#if[rw]
|
#if[rw]
|
||||||
if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
|
if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
|
||||||
|
@ -139,6 +139,12 @@ class Heap$Type$Buffer$RW$
|
|||||||
return hb[ix(checkIndex(i))];
|
return hb[ix(checkIndex(i))];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if[streamableType]
|
||||||
|
$type$ getUnchecked(int i) {
|
||||||
|
return hb[ix(i)];
|
||||||
|
}
|
||||||
|
#end[streamableType]
|
||||||
|
|
||||||
public $Type$Buffer get($type$[] dst, int offset, int length) {
|
public $Type$Buffer get($type$[] dst, int offset, int length) {
|
||||||
checkBounds(offset, length, dst.length);
|
checkBounds(offset, length, dst.length);
|
||||||
if (length > remaining())
|
if (length > remaining())
|
||||||
|
@ -77,6 +77,10 @@ class StringCharBuffer // package-private
|
|||||||
return str.charAt(checkIndex(index) + offset);
|
return str.charAt(checkIndex(index) + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char getUnchecked(int index) {
|
||||||
|
return str.charAt(index + offset);
|
||||||
|
}
|
||||||
|
|
||||||
// ## Override bulk get methods for better performance
|
// ## Override bulk get methods for better performance
|
||||||
|
|
||||||
public final CharBuffer put(char c) {
|
public final CharBuffer put(char c) {
|
||||||
|
@ -30,6 +30,11 @@ package java.nio;
|
|||||||
#if[char]
|
#if[char]
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
#end[char]
|
#end[char]
|
||||||
|
#if[streamableType]
|
||||||
|
import java.util.Spliterator;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
import java.util.stream.$Streamtype$Stream;
|
||||||
|
#end[streamableType]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $A$ $type$ buffer.
|
* $A$ $type$ buffer.
|
||||||
@ -589,6 +594,19 @@ public abstract class $Type$Buffer
|
|||||||
*/
|
*/
|
||||||
public abstract $type$ get(int index);
|
public abstract $type$ get(int index);
|
||||||
|
|
||||||
|
#if[streamableType]
|
||||||
|
/**
|
||||||
|
* Absolute <i>get</i> method. Reads the $type$ at the given
|
||||||
|
* index without any validation of the index.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* The index from which the $type$ will be read
|
||||||
|
*
|
||||||
|
* @return The $type$ at the given index
|
||||||
|
*/
|
||||||
|
abstract $type$ getUnchecked(int index); // package-private
|
||||||
|
#end[streamableType]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Absolute <i>put</i> method <i>(optional operation)</i>.
|
* Absolute <i>put</i> method <i>(optional operation)</i>.
|
||||||
*
|
*
|
||||||
@ -1458,4 +1476,16 @@ public abstract class $Type$Buffer
|
|||||||
|
|
||||||
#end[byte]
|
#end[byte]
|
||||||
|
|
||||||
|
#if[streamableType]
|
||||||
|
|
||||||
|
#if[char]
|
||||||
|
@Override
|
||||||
|
#end[char]
|
||||||
|
public $Streamtype$Stream $type$s() {
|
||||||
|
return StreamSupport.$streamtype$Stream(() -> new $Type$BufferSpliterator(this),
|
||||||
|
Buffer.SPLITERATOR_CHARACTERISTICS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#end[streamableType]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,15 @@ public final class AccessControlContext {
|
|||||||
|
|
||||||
private DomainCombiner combiner = null;
|
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 boolean debugInit = false;
|
||||||
private static Debug debug = null;
|
private static Debug debug = null;
|
||||||
|
|
||||||
@ -178,14 +187,79 @@ public final class AccessControlContext {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* package private for AccessController
|
* 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) {
|
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;
|
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()
|
* package private constructor for AccessController.getContext()
|
||||||
*/
|
*/
|
||||||
@ -260,6 +334,13 @@ public final class AccessControlContext {
|
|||||||
if (sm != null) {
|
if (sm != null) {
|
||||||
sm.checkPermission(SecurityConstants.GET_COMBINER_PERMISSION);
|
sm.checkPermission(SecurityConstants.GET_COMBINER_PERMISSION);
|
||||||
}
|
}
|
||||||
|
return getCombiner();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* package private for AccessController
|
||||||
|
*/
|
||||||
|
DomainCombiner getCombiner() {
|
||||||
return combiner;
|
return combiner;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,8 +416,10 @@ public final class AccessControlContext {
|
|||||||
or the first domain was a Privileged system domain. This
|
or the first domain was a Privileged system domain. This
|
||||||
is to make the common case for system code very fast */
|
is to make the common case for system code very fast */
|
||||||
|
|
||||||
if (context == null)
|
if (context == null) {
|
||||||
|
checkPermission2(perm);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=0; i< context.length; i++) {
|
for (int i=0; i< context.length; i++) {
|
||||||
if (context[i] != null && !context[i].implies(perm)) {
|
if (context[i] != null && !context[i].implies(perm)) {
|
||||||
@ -370,20 +453,108 @@ public final class AccessControlContext {
|
|||||||
debug.println("access allowed "+perm);
|
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
|
* 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() {
|
AccessControlContext optimize() {
|
||||||
// the assigned (privileged or inherited) context
|
// the assigned (privileged or inherited) context
|
||||||
AccessControlContext acc;
|
AccessControlContext acc;
|
||||||
|
DomainCombiner combiner = null;
|
||||||
|
AccessControlContext parent = null;
|
||||||
|
Permission[] permissions = null;
|
||||||
|
|
||||||
if (isPrivileged) {
|
if (isPrivileged) {
|
||||||
acc = privilegedContext;
|
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 {
|
} else {
|
||||||
acc = AccessController.getInheritedAccessControlContext();
|
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;
|
// 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;
|
// acc.context could be null if only system code was involved;
|
||||||
// in that case, ignore the assigned context
|
// in that case, ignore the assigned context
|
||||||
boolean skipAssigned = (acc == null || acc.context == null);
|
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) {
|
if (acc != null && acc.combiner != null) {
|
||||||
// let the assigned acc's combiner do its thing
|
// 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
|
// Reuse existing ACC
|
||||||
// rather than this, because acc might have a combiner
|
this.context = pd;
|
||||||
if (skipAssigned && skipStack) {
|
this.combiner = combiner;
|
||||||
return this;
|
this.isPrivileged = false;
|
||||||
}
|
|
||||||
|
|
||||||
// optimization: if there is no stack context; there is no reason
|
calculateFields(acc, parent, permissions);
|
||||||
// to compress the assigned context, it already is compressed
|
return this;
|
||||||
if (skipStack) {
|
}
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
// 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
|
// is less then or equal to two; there is no reason to compress the
|
||||||
// stack context, it already is
|
// stack context, it already is
|
||||||
if (skipAssigned && slen <= 2) {
|
if (skipAssigned && slen <= 2) {
|
||||||
return this;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
// optimization: if there is a single stack domain and that domain
|
int n = (skipAssigned) ? 0 : assigned.length;
|
||||||
// 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;
|
|
||||||
|
|
||||||
// now we combine both of them, and create a new context
|
// now we combine both of them, and create a new context
|
||||||
ProtectionDomain pd[] = new ProtectionDomain[slen + n];
|
ProtectionDomain pd[] = new ProtectionDomain[slen + n];
|
||||||
|
|
||||||
// first copy in the assigned context domains, no need to compress
|
// first copy in the assigned context domains, no need to compress
|
||||||
if (!skipAssigned) {
|
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
|
// now add the stack context domains, discarding nulls and duplicates
|
||||||
outer:
|
outer:
|
||||||
for (int i = 0; i < context.length; i++) {
|
for (int i = 0; i < slen; i++) {
|
||||||
ProtectionDomain sd = context[i];
|
ProtectionDomain sd = current[i];
|
||||||
if (sd != null) {
|
if (sd != null) {
|
||||||
for (int j = 0; j < n; j++) {
|
for (int j = 0; j < n; j++) {
|
||||||
if (sd == pd[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 length isn't equal, we need to shorten the array
|
||||||
if (n != pd.length) {
|
if (n != pd.length) {
|
||||||
// optimization: if we didn't really combine anything
|
// optimization: if we didn't really combine anything
|
||||||
if (!skipAssigned && n == acc.context.length) {
|
if (!skipAssigned && n == assigned.length) {
|
||||||
return acc;
|
return assigned;
|
||||||
} else if (skipAssigned && n == slen) {
|
} else if (skipAssigned && n == slen) {
|
||||||
return this;
|
return current;
|
||||||
}
|
}
|
||||||
ProtectionDomain tmp[] = new ProtectionDomain[n];
|
ProtectionDomain tmp[] = new ProtectionDomain[n];
|
||||||
System.arraycopy(pd, 0, tmp, 0, n);
|
System.arraycopy(pd, 0, tmp, 0, n);
|
||||||
pd = tmp;
|
pd = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return new AccessControlContext(pd, false);
|
return pd;
|
||||||
|
|
||||||
// Reuse existing ACC
|
|
||||||
|
|
||||||
this.context = pd;
|
|
||||||
this.combiner = null;
|
|
||||||
this.isPrivileged = false;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 ...
|
parentLimit = (parent != null)? parent.limitedContext: null;
|
||||||
|
assignedLimit = (assigned != null)? assigned.limitedContext: null;
|
||||||
if (getDebug() != null) {
|
newLimit = combine(parentLimit, assignedLimit);
|
||||||
debug.println("AccessControlContext invoking the Combiner");
|
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 two AccessControlContext objects for equality.
|
||||||
* Checks that <i>obj</i> is
|
* Checks that <i>obj</i> is
|
||||||
@ -520,31 +730,131 @@ public final class AccessControlContext {
|
|||||||
|
|
||||||
AccessControlContext that = (AccessControlContext) obj;
|
AccessControlContext that = (AccessControlContext) obj;
|
||||||
|
|
||||||
|
if (!equalContext(that))
|
||||||
if (context == null) {
|
|
||||||
return (that.context == null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (that.context == null)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!(this.containsAllPDs(that) && that.containsAllPDs(this)))
|
if (!equalLimitedContext(that))
|
||||||
return false;
|
|
||||||
|
|
||||||
if (this.combiner == null)
|
|
||||||
return (that.combiner == null);
|
|
||||||
|
|
||||||
if (that.combiner == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!this.combiner.equals(that.combiner))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
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;
|
boolean match = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
// ProtectionDomains within an ACC currently cannot be null
|
// ProtectionDomains within an ACC currently cannot be null
|
||||||
// and this is enforced by the constructor and the various
|
// 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 the notion of a null PD and therefore this logic continues
|
||||||
// to support that notion.
|
// to support that notion.
|
||||||
ProtectionDomain thisPd;
|
ProtectionDomain thisPd;
|
||||||
for (int i = 0; i < context.length; i++) {
|
for (int i = 0; i < thisContext.length; i++) {
|
||||||
match = false;
|
match = false;
|
||||||
if ((thisPd = context[i]) == null) {
|
if ((thisPd = thisContext[i]) == null) {
|
||||||
for (int j = 0; (j < that.context.length) && !match; j++) {
|
for (int j = 0; (j < thatContext.length) && !match; j++) {
|
||||||
match = (that.context[j] == null);
|
match = (thatContext[j] == null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Class<?> thisPdClass = thisPd.getClass();
|
Class<?> thisPdClass = thisPd.getClass();
|
||||||
ProtectionDomain thatPd;
|
ProtectionDomain thatPd;
|
||||||
for (int j = 0; (j < that.context.length) && !match; j++) {
|
for (int j = 0; (j < thatContext.length) && !match; j++) {
|
||||||
thatPd = that.context[j];
|
thatPd = thatContext[j];
|
||||||
|
|
||||||
// Class check required to avoid PD exposure (4285406)
|
// Class check required to avoid PD exposure (4285406)
|
||||||
match = (thatPd != null &&
|
match = (thatPd != null &&
|
||||||
@ -573,6 +883,29 @@ public final class AccessControlContext {
|
|||||||
}
|
}
|
||||||
return match;
|
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
|
* Returns the hash code value for this context. The hash code
|
||||||
* is computed by exclusive or-ing the hash code of all the protection
|
* 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)
|
if (context[i] != null)
|
||||||
hashCode ^= context[i].hashCode();
|
hashCode ^= context[i].hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
return hashCode;
|
return hashCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,9 +82,15 @@ import sun.reflect.Reflection;
|
|||||||
* else if (caller i is marked as privileged) {
|
* else if (caller i is marked as privileged) {
|
||||||
* if (a context was specified in the call to doPrivileged)
|
* if (a context was specified in the call to doPrivileged)
|
||||||
* context.checkPermission(permission)
|
* context.checkPermission(permission)
|
||||||
* return;
|
* if (limited permissions were specified in the call to doPrivileged) {
|
||||||
|
* for (each limited permission) {
|
||||||
|
* if (the limited permission implies the requested permission)
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
* } else
|
||||||
|
* return;
|
||||||
* }
|
* }
|
||||||
* };
|
* }
|
||||||
*
|
*
|
||||||
* // Next, check the context inherited when the thread was created.
|
* // Next, check the context inherited when the thread was created.
|
||||||
* // Whenever a new thread is created, the AccessControlContext at
|
* // Whenever a new thread is created, the AccessControlContext at
|
||||||
@ -101,11 +107,16 @@ import sun.reflect.Reflection;
|
|||||||
* was marked as "privileged" via a <code>doPrivileged</code>
|
* was marked as "privileged" via a <code>doPrivileged</code>
|
||||||
* call without a context argument (see below for information about a
|
* call without a context argument (see below for information about a
|
||||||
* context argument). If that caller's domain has the
|
* context argument). If that caller's domain has the
|
||||||
* specified permission, no further checking is done and
|
* specified permission and at least one limiting permission argument (if any)
|
||||||
|
* implies the requested permission, no further checking is done and
|
||||||
* <code>checkPermission</code>
|
* <code>checkPermission</code>
|
||||||
* returns quietly, indicating that the requested access is allowed.
|
* returns quietly, indicating that the requested access is allowed.
|
||||||
* If that domain does not have the specified permission, an exception
|
* If that domain does not have the specified permission, an exception
|
||||||
* is thrown, as usual.
|
* is thrown, as usual. If the caller's domain had the specified permission
|
||||||
|
* but it was not implied by any limiting permission arguments given in the call
|
||||||
|
* to <code>doPrivileged</code> then the permission checking continues
|
||||||
|
* until there are no more callers or another <code>doPrivileged</code>
|
||||||
|
* call matches the requested permission and returns normally.
|
||||||
*
|
*
|
||||||
* <p> The normal use of the "privileged" feature is as follows. If you
|
* <p> The normal use of the "privileged" feature is as follows. If you
|
||||||
* don't need to return a value from within the "privileged" block, do
|
* don't need to return a value from within the "privileged" block, do
|
||||||
@ -180,6 +191,9 @@ import sun.reflect.Reflection;
|
|||||||
*
|
*
|
||||||
* <p> Be *very* careful in your use of the "privileged" construct, and
|
* <p> Be *very* careful in your use of the "privileged" construct, and
|
||||||
* always remember to make the privileged code section as small as possible.
|
* always remember to make the privileged code section as small as possible.
|
||||||
|
* You can pass <code>Permission</code> arguments to further limit the
|
||||||
|
* scope of the "privilege" (see below).
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* <p> Note that <code>checkPermission</code> always performs security checks
|
* <p> Note that <code>checkPermission</code> always performs security checks
|
||||||
* within the context of the currently executing thread.
|
* within the context of the currently executing thread.
|
||||||
@ -215,7 +229,9 @@ import sun.reflect.Reflection;
|
|||||||
*
|
*
|
||||||
* <p> There are also times where you don't know a priori which permissions
|
* <p> There are also times where you don't know a priori which permissions
|
||||||
* to check the context against. In these cases you can use the
|
* to check the context against. In these cases you can use the
|
||||||
* doPrivileged method that takes a context:
|
* doPrivileged method that takes a context. You can also limit the scope
|
||||||
|
* of the privileged code by passing additional <code>Permission</code>
|
||||||
|
* parameters.
|
||||||
*
|
*
|
||||||
* <pre> {@code
|
* <pre> {@code
|
||||||
* somemethod() {
|
* somemethod() {
|
||||||
@ -223,12 +239,21 @@ import sun.reflect.Reflection;
|
|||||||
* public Object run() {
|
* public Object run() {
|
||||||
* // Code goes here. Any permission checks within this
|
* // Code goes here. Any permission checks within this
|
||||||
* // run method will require that the intersection of the
|
* // run method will require that the intersection of the
|
||||||
* // callers protection domain and the snapshot's
|
* // caller's protection domain and the snapshot's
|
||||||
* // context have the desired permission.
|
* // context have the desired permission. If a requested
|
||||||
|
* // permission is not implied by the limiting FilePermission
|
||||||
|
* // argument then checking of the thread continues beyond the
|
||||||
|
* // caller of doPrivileged.
|
||||||
* }
|
* }
|
||||||
* }, acc);
|
* }, acc, new FilePermission("/temp/*", read));
|
||||||
* ...normal code here...
|
* ...normal code here...
|
||||||
* }}</pre>
|
* }}</pre>
|
||||||
|
* <p> Passing a limiting <code>Permission</code> argument of an instance of
|
||||||
|
* <code>AllPermission</code> is equivalent to calling the equivalent
|
||||||
|
* <code>doPrivileged</code> method without limiting <code>Permission</code>
|
||||||
|
* arguments. Passing a zero length array of <code>Permission</code> disables
|
||||||
|
* the code privileges so that checking always continues beyond the caller of
|
||||||
|
* that <code>doPrivileged</code> method.
|
||||||
*
|
*
|
||||||
* @see AccessControlContext
|
* @see AccessControlContext
|
||||||
*
|
*
|
||||||
@ -334,6 +359,112 @@ public final class AccessController {
|
|||||||
public static native <T> T doPrivileged(PrivilegedAction<T> action,
|
public static native <T> T doPrivileged(PrivilegedAction<T> action,
|
||||||
AccessControlContext context);
|
AccessControlContext context);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the specified <code>PrivilegedAction</code> with privileges
|
||||||
|
* enabled and restricted by the specified
|
||||||
|
* <code>AccessControlContext</code> and with a privilege scope limited
|
||||||
|
* by specified <code>Permission</code> arguments.
|
||||||
|
*
|
||||||
|
* The action is performed with the intersection of the permissions
|
||||||
|
* possessed by the caller's protection domain, and those possessed
|
||||||
|
* by the domains represented by the specified
|
||||||
|
* <code>AccessControlContext</code>.
|
||||||
|
* <p>
|
||||||
|
* If the action's <code>run</code> method throws an (unchecked) exception,
|
||||||
|
* it will propagate through this method.
|
||||||
|
*
|
||||||
|
* @param action the action to be performed.
|
||||||
|
* @param context an <i>access control context</i>
|
||||||
|
* representing the restriction to be applied to the
|
||||||
|
* caller's domain's privileges before performing
|
||||||
|
* the specified action. If the context is
|
||||||
|
* <code>null</code>,
|
||||||
|
* then no additional restriction is applied.
|
||||||
|
* @param perms the <code>Permission</code> arguments which limit the
|
||||||
|
* scope of the caller's privileges. The number of arguments
|
||||||
|
* is variable.
|
||||||
|
*
|
||||||
|
* @return the value returned by the action's <code>run</code> method.
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if action or perms or any element of
|
||||||
|
* perms is <code>null</code>
|
||||||
|
*
|
||||||
|
* @see #doPrivileged(PrivilegedAction)
|
||||||
|
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
|
||||||
|
*
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
@CallerSensitive
|
||||||
|
public static <T> T doPrivileged(PrivilegedAction<T> action,
|
||||||
|
AccessControlContext context, Permission... perms) {
|
||||||
|
|
||||||
|
AccessControlContext parent = getContext();
|
||||||
|
if (perms == null) {
|
||||||
|
throw new NullPointerException("null permissions parameter");
|
||||||
|
}
|
||||||
|
Class <?> caller = Reflection.getCallerClass();
|
||||||
|
return AccessController.doPrivileged(action, createWrapper(null,
|
||||||
|
caller, parent, context, perms));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the specified <code>PrivilegedAction</code> with privileges
|
||||||
|
* enabled and restricted by the specified
|
||||||
|
* <code>AccessControlContext</code> and with a privilege scope limited
|
||||||
|
* by specified <code>Permission</code> arguments.
|
||||||
|
*
|
||||||
|
* The action is performed with the intersection of the permissions
|
||||||
|
* possessed by the caller's protection domain, and those possessed
|
||||||
|
* by the domains represented by the specified
|
||||||
|
* <code>AccessControlContext</code>.
|
||||||
|
* <p>
|
||||||
|
* If the action's <code>run</code> method throws an (unchecked) exception,
|
||||||
|
* it will propagate through this method.
|
||||||
|
*
|
||||||
|
* <p> This method preserves the current AccessControlContext's
|
||||||
|
* DomainCombiner (which may be null) while the action is performed.
|
||||||
|
*
|
||||||
|
* @param action the action to be performed.
|
||||||
|
* @param context an <i>access control context</i>
|
||||||
|
* representing the restriction to be applied to the
|
||||||
|
* caller's domain's privileges before performing
|
||||||
|
* the specified action. If the context is
|
||||||
|
* <code>null</code>,
|
||||||
|
* then no additional restriction is applied.
|
||||||
|
* @param perms the <code>Permission</code> arguments which limit the
|
||||||
|
* scope of the caller's privileges. The number of arguments
|
||||||
|
* is variable.
|
||||||
|
*
|
||||||
|
* @return the value returned by the action's <code>run</code> method.
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if action or perms or any element of
|
||||||
|
* perms is <code>null</code>
|
||||||
|
*
|
||||||
|
* @see #doPrivileged(PrivilegedAction)
|
||||||
|
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
|
||||||
|
* @see java.security.DomainCombiner
|
||||||
|
*
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
@CallerSensitive
|
||||||
|
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action,
|
||||||
|
AccessControlContext context, Permission... perms) {
|
||||||
|
|
||||||
|
AccessControlContext parent = getContext();
|
||||||
|
DomainCombiner dc = parent.getCombiner();
|
||||||
|
if (dc == null && context != null) {
|
||||||
|
dc = context.getCombiner();
|
||||||
|
}
|
||||||
|
if (perms == null) {
|
||||||
|
throw new NullPointerException("null permissions parameter");
|
||||||
|
}
|
||||||
|
Class <?> caller = Reflection.getCallerClass();
|
||||||
|
return AccessController.doPrivileged(action, createWrapper(dc, caller,
|
||||||
|
parent, context, perms));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the specified <code>PrivilegedExceptionAction</code> with
|
* Performs the specified <code>PrivilegedExceptionAction</code> with
|
||||||
* privileges enabled. The action is performed with <i>all</i> of the
|
* privileges enabled. The action is performed with <i>all</i> of the
|
||||||
@ -408,6 +539,22 @@ public final class AccessController {
|
|||||||
private static AccessControlContext preserveCombiner(DomainCombiner combiner,
|
private static AccessControlContext preserveCombiner(DomainCombiner combiner,
|
||||||
Class<?> caller)
|
Class<?> caller)
|
||||||
{
|
{
|
||||||
|
return createWrapper(combiner, caller, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a wrapper to contain the limited privilege scope data.
|
||||||
|
*/
|
||||||
|
private static AccessControlContext
|
||||||
|
createWrapper(DomainCombiner combiner, Class<?> caller,
|
||||||
|
AccessControlContext parent, AccessControlContext context,
|
||||||
|
Permission[] perms)
|
||||||
|
{
|
||||||
|
return new AccessControlContext(getCallerPD(caller), combiner, parent,
|
||||||
|
context, perms);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ProtectionDomain getCallerPD(final Class <?> caller) {
|
||||||
ProtectionDomain callerPd = doPrivileged
|
ProtectionDomain callerPd = doPrivileged
|
||||||
(new PrivilegedAction<ProtectionDomain>() {
|
(new PrivilegedAction<ProtectionDomain>() {
|
||||||
public ProtectionDomain run() {
|
public ProtectionDomain run() {
|
||||||
@ -415,18 +562,9 @@ public final class AccessController {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// perform 'combine' on the caller of doPrivileged,
|
return callerPd;
|
||||||
// even if the caller is from the bootclasspath
|
|
||||||
ProtectionDomain[] pds = new ProtectionDomain[] {callerPd};
|
|
||||||
if (combiner == null) {
|
|
||||||
return new AccessControlContext(pds);
|
|
||||||
} else {
|
|
||||||
return new AccessControlContext(combiner.combine(pds, null),
|
|
||||||
combiner);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the specified <code>PrivilegedExceptionAction</code> with
|
* Performs the specified <code>PrivilegedExceptionAction</code> with
|
||||||
* privileges enabled and restricted by the specified
|
* privileges enabled and restricted by the specified
|
||||||
@ -454,7 +592,7 @@ public final class AccessController {
|
|||||||
* @exception NullPointerException if the action is <code>null</code>
|
* @exception NullPointerException if the action is <code>null</code>
|
||||||
*
|
*
|
||||||
* @see #doPrivileged(PrivilegedAction)
|
* @see #doPrivileged(PrivilegedAction)
|
||||||
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
|
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
@CallerSensitive
|
||||||
public static native <T> T
|
public static native <T> T
|
||||||
@ -462,6 +600,118 @@ public final class AccessController {
|
|||||||
AccessControlContext context)
|
AccessControlContext context)
|
||||||
throws PrivilegedActionException;
|
throws PrivilegedActionException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the specified <code>PrivilegedExceptionAction</code> with
|
||||||
|
* privileges enabled and restricted by the specified
|
||||||
|
* <code>AccessControlContext</code> and with a privilege scope limited by
|
||||||
|
* specified <code>Permission</code> arguments.
|
||||||
|
*
|
||||||
|
* The action is performed with the intersection of the permissions
|
||||||
|
* possessed by the caller's protection domain, and those possessed
|
||||||
|
* by the domains represented by the specified
|
||||||
|
* <code>AccessControlContext</code>.
|
||||||
|
* <p>
|
||||||
|
* If the action's <code>run</code> method throws an (unchecked) exception,
|
||||||
|
* it will propagate through this method.
|
||||||
|
*
|
||||||
|
* @param action the action to be performed.
|
||||||
|
* @param context an <i>access control context</i>
|
||||||
|
* representing the restriction to be applied to the
|
||||||
|
* caller's domain's privileges before performing
|
||||||
|
* the specified action. If the context is
|
||||||
|
* <code>null</code>,
|
||||||
|
* then no additional restriction is applied.
|
||||||
|
* @param perms the <code>Permission</code> arguments which limit the
|
||||||
|
* scope of the caller's privileges. The number of arguments
|
||||||
|
* is variable.
|
||||||
|
*
|
||||||
|
* @return the value returned by the action's <code>run</code> method.
|
||||||
|
*
|
||||||
|
* @throws PrivilegedActionException if the specified action's
|
||||||
|
* <code>run</code> method threw a <i>checked</i> exception
|
||||||
|
* @throws NullPointerException if action or perms or any element of
|
||||||
|
* perms is <code>null</code>
|
||||||
|
*
|
||||||
|
* @see #doPrivileged(PrivilegedAction)
|
||||||
|
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
|
||||||
|
*
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
@CallerSensitive
|
||||||
|
public static <T> T doPrivileged(PrivilegedExceptionAction<T> action,
|
||||||
|
AccessControlContext context, Permission... perms)
|
||||||
|
throws PrivilegedActionException
|
||||||
|
{
|
||||||
|
AccessControlContext parent = getContext();
|
||||||
|
if (perms == null) {
|
||||||
|
throw new NullPointerException("null permissions parameter");
|
||||||
|
}
|
||||||
|
Class <?> caller = Reflection.getCallerClass();
|
||||||
|
return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the specified <code>PrivilegedExceptionAction</code> with
|
||||||
|
* privileges enabled and restricted by the specified
|
||||||
|
* <code>AccessControlContext</code> and with a privilege scope limited by
|
||||||
|
* specified <code>Permission</code> arguments.
|
||||||
|
*
|
||||||
|
* The action is performed with the intersection of the permissions
|
||||||
|
* possessed by the caller's protection domain, and those possessed
|
||||||
|
* by the domains represented by the specified
|
||||||
|
* <code>AccessControlContext</code>.
|
||||||
|
* <p>
|
||||||
|
* If the action's <code>run</code> method throws an (unchecked) exception,
|
||||||
|
* it will propagate through this method.
|
||||||
|
*
|
||||||
|
* <p> This method preserves the current AccessControlContext's
|
||||||
|
* DomainCombiner (which may be null) while the action is performed.
|
||||||
|
*
|
||||||
|
* @param action the action to be performed.
|
||||||
|
* @param context an <i>access control context</i>
|
||||||
|
* representing the restriction to be applied to the
|
||||||
|
* caller's domain's privileges before performing
|
||||||
|
* the specified action. If the context is
|
||||||
|
* <code>null</code>,
|
||||||
|
* then no additional restriction is applied.
|
||||||
|
* @param perms the <code>Permission</code> arguments which limit the
|
||||||
|
* scope of the caller's privileges. The number of arguments
|
||||||
|
* is variable.
|
||||||
|
*
|
||||||
|
* @return the value returned by the action's <code>run</code> method.
|
||||||
|
*
|
||||||
|
* @throws PrivilegedActionException if the specified action's
|
||||||
|
* <code>run</code> method threw a <i>checked</i> exception
|
||||||
|
* @throws NullPointerException if action or perms or any element of
|
||||||
|
* perms is <code>null</code>
|
||||||
|
*
|
||||||
|
* @see #doPrivileged(PrivilegedAction)
|
||||||
|
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
|
||||||
|
* @see java.security.DomainCombiner
|
||||||
|
*
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
@CallerSensitive
|
||||||
|
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action,
|
||||||
|
AccessControlContext context,
|
||||||
|
Permission... perms)
|
||||||
|
throws PrivilegedActionException
|
||||||
|
{
|
||||||
|
AccessControlContext parent = getContext();
|
||||||
|
DomainCombiner dc = parent.getCombiner();
|
||||||
|
if (dc == null && context != null) {
|
||||||
|
dc = context.getCombiner();
|
||||||
|
}
|
||||||
|
if (perms == null) {
|
||||||
|
throw new NullPointerException("null permissions parameter");
|
||||||
|
}
|
||||||
|
Class <?> caller = Reflection.getCallerClass();
|
||||||
|
return AccessController.doPrivileged(action, createWrapper(dc, caller,
|
||||||
|
parent, context, perms));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the AccessControl context. i.e., it gets
|
* Returns the AccessControl context. i.e., it gets
|
||||||
* the protection domains of all the callers on the stack,
|
* the protection domains of all the callers on the stack,
|
||||||
@ -474,6 +724,7 @@ public final class AccessController {
|
|||||||
|
|
||||||
private static native AccessControlContext getStackAccessControlContext();
|
private static native AccessControlContext getStackAccessControlContext();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the "inherited" AccessControl context. This is the context
|
* Returns the "inherited" AccessControl context. This is the context
|
||||||
* that existed when the thread was created. Package private so
|
* that existed when the thread was created. Package private so
|
||||||
@ -484,9 +735,9 @@ public final class AccessController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method takes a "snapshot" of the current calling context, which
|
* This method takes a "snapshot" of the current calling context, which
|
||||||
* includes the current Thread's inherited AccessControlContext,
|
* includes the current Thread's inherited AccessControlContext and any
|
||||||
* and places it in an AccessControlContext object. This context may then
|
* limited privilege scope, and places it in an AccessControlContext object.
|
||||||
* be checked at a later point, possibly in another thread.
|
* This context may then be checked at a later point, possibly in another thread.
|
||||||
*
|
*
|
||||||
* @see AccessControlContext
|
* @see AccessControlContext
|
||||||
*
|
*
|
||||||
@ -524,7 +775,7 @@ public final class AccessController {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public static void checkPermission(Permission perm)
|
public static void checkPermission(Permission perm)
|
||||||
throws AccessControlException
|
throws AccessControlException
|
||||||
{
|
{
|
||||||
//System.err.println("checkPermission "+perm);
|
//System.err.println("checkPermission "+perm);
|
||||||
//Thread.currentThread().dumpStack();
|
//Thread.currentThread().dumpStack();
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -112,10 +112,10 @@ public class DigestOutputStream extends FilterOutputStream {
|
|||||||
* @see MessageDigest#update(byte)
|
* @see MessageDigest#update(byte)
|
||||||
*/
|
*/
|
||||||
public void write(int b) throws IOException {
|
public void write(int b) throws IOException {
|
||||||
|
out.write(b);
|
||||||
if (on) {
|
if (on) {
|
||||||
digest.update((byte)b);
|
digest.update((byte)b);
|
||||||
}
|
}
|
||||||
out.write(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -142,10 +142,10 @@ public class DigestOutputStream extends FilterOutputStream {
|
|||||||
* @see MessageDigest#update(byte[], int, int)
|
* @see MessageDigest#update(byte[], int, int)
|
||||||
*/
|
*/
|
||||||
public void write(byte[] b, int off, int len) throws IOException {
|
public void write(byte[] b, int off, int len) throws IOException {
|
||||||
|
out.write(b, off, len);
|
||||||
if (on) {
|
if (on) {
|
||||||
digest.update(b, off, len);
|
digest.update(b, off, len);
|
||||||
}
|
}
|
||||||
out.write(b, off, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
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 long HASHSEED_OFFSET;
|
||||||
|
|
||||||
|
static final boolean USE_HASHSEED;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
String hashSeedProp = java.security.AccessController.doPrivileged(
|
||||||
UNSAFE = sun.misc.Unsafe.getUnsafe();
|
new sun.security.action.GetPropertyAction(
|
||||||
HASHSEED_OFFSET = UNSAFE.objectFieldOffset(
|
"jdk.map.useRandomSeed"));
|
||||||
Hashtable.class.getDeclaredField("hashSeed"));
|
boolean localBool = (null != hashSeedProp)
|
||||||
} catch (NoSuchFieldException | SecurityException e) {
|
? Boolean.parseBoolean(hashSeedProp) : false;
|
||||||
throw new InternalError("Failed to record hashSeed offset", e);
|
USE_HASHSEED = localBool;
|
||||||
|
|
||||||
|
if (USE_HASHSEED) {
|
||||||
|
try {
|
||||||
|
UNSAFE = sun.misc.Unsafe.getUnsafe();
|
||||||
|
HASHSEED_OFFSET = UNSAFE.objectFieldOffset(
|
||||||
|
Hashtable.class.getDeclaredField("hashSeed"));
|
||||||
|
} catch (NoSuchFieldException | SecurityException e) {
|
||||||
|
throw new InternalError("Failed to record hashSeed offset", e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
UNSAFE = null;
|
||||||
|
HASHSEED_OFFSET = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,21 +208,24 @@ public class Hashtable<K,V>
|
|||||||
/**
|
/**
|
||||||
* A randomizing value associated with this instance that is applied to
|
* A randomizing value associated with this instance that is applied to
|
||||||
* hash code of keys to make hash collisions harder to find.
|
* hash code of keys to make hash collisions harder to find.
|
||||||
|
*
|
||||||
|
* Non-final so it can be set lazily, but be sure not to set more than once.
|
||||||
*/
|
*/
|
||||||
transient final int hashSeed = sun.misc.Hashing.randomHashSeed(this);
|
transient final int hashSeed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
private int hash(Object k) {
|
||||||
if (k instanceof String) {
|
return hashSeed ^ k.hashCode();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,6 +249,7 @@ public class Hashtable<K,V>
|
|||||||
this.loadFactor = loadFactor;
|
this.loadFactor = loadFactor;
|
||||||
table = new Entry<?,?>[initialCapacity];
|
table = new Entry<?,?>[initialCapacity];
|
||||||
threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
|
threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
|
||||||
|
hashSeed = initHashSeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1187,8 +1205,10 @@ public class Hashtable<K,V>
|
|||||||
s.defaultReadObject();
|
s.defaultReadObject();
|
||||||
|
|
||||||
// set hashMask
|
// set hashMask
|
||||||
Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET,
|
if (Holder.USE_HASHSEED) {
|
||||||
sun.misc.Hashing.randomHashSeed(this));
|
Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET,
|
||||||
|
sun.misc.Hashing.randomHashSeed(this));
|
||||||
|
}
|
||||||
|
|
||||||
// Read the original length of the array and number of elements
|
// Read the original length of the array and number of elements
|
||||||
int origlength = s.readInt();
|
int origlength = s.readInt();
|
||||||
|
@ -159,7 +159,7 @@ public class IntSummaryStatistics implements IntConsumer {
|
|||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format(
|
return String.format(
|
||||||
"%s{count=%d, sum=%d, min=%d, average=%d, max=%d}",
|
"%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
|
||||||
this.getClass().getSimpleName(),
|
this.getClass().getSimpleName(),
|
||||||
getCount(),
|
getCount(),
|
||||||
getSum(),
|
getSum(),
|
||||||
|
@ -55,9 +55,9 @@ import java.io.*;
|
|||||||
* order they were presented.)
|
* order they were presented.)
|
||||||
*
|
*
|
||||||
* <p>A special {@link #LinkedHashMap(int,float,boolean) constructor} is
|
* <p>A special {@link #LinkedHashMap(int,float,boolean) constructor} is
|
||||||
* provided to create a linked hash map whose order of iteration is the order
|
* provided to create a <tt>LinkedHashMap</tt> whose order of iteration is the
|
||||||
* in which its entries were last accessed, from least-recently accessed to
|
* order in which its entries were last accessed, from least-recently accessed
|
||||||
* most-recently (<i>access-order</i>). This kind of map is well-suited to
|
* to most-recently (<i>access-order</i>). This kind of map is well-suited to
|
||||||
* building LRU caches. Invoking the <tt>put</tt> or <tt>get</tt> method
|
* building LRU caches. Invoking the <tt>put</tt> or <tt>get</tt> method
|
||||||
* results in an access to the corresponding entry (assuming it exists after
|
* results in an access to the corresponding entry (assuming it exists after
|
||||||
* the invocation completes). The <tt>putAll</tt> method generates one entry
|
* the invocation completes). The <tt>putAll</tt> method generates one entry
|
||||||
@ -242,23 +242,6 @@ public class LinkedHashMap<K,V>
|
|||||||
header.before = header.after = header;
|
header.before = header.after = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Transfers all entries to new table array. This method is called
|
|
||||||
* by superclass resize. It is overridden for performance, as it is
|
|
||||||
* faster to iterate using our linked list.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
void transfer(HashMap.Entry[] newTable) {
|
|
||||||
int newCapacity = newTable.length;
|
|
||||||
for (Entry<K,V> e = header.after; e != header; e = e.after) {
|
|
||||||
int index = indexFor(e.hash, newCapacity);
|
|
||||||
e.next = (HashMap.Entry<K,V>)newTable[index];
|
|
||||||
newTable[index] = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns <tt>true</tt> if this map maps one or more keys to the
|
* Returns <tt>true</tt> if this map maps one or more keys to the
|
||||||
* specified value.
|
* specified value.
|
||||||
@ -320,7 +303,7 @@ public class LinkedHashMap<K,V>
|
|||||||
// These fields comprise the doubly linked list used for iteration.
|
// These fields comprise the doubly linked list used for iteration.
|
||||||
Entry<K,V> before, after;
|
Entry<K,V> before, after;
|
||||||
|
|
||||||
Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
|
Entry(int hash, K key, V value, Object next) {
|
||||||
super(hash, key, value, next);
|
super(hash, key, value, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +327,7 @@ public class LinkedHashMap<K,V>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is invoked by the superclass whenever the value
|
* This method is invoked by the superclass whenever the value
|
||||||
* of a pre-existing entry is read by Map.get or modified by Map.set.
|
* of a pre-existing entry is read by Map.get or modified by Map.put.
|
||||||
* If the enclosing Map is access-ordered, it moves the entry
|
* If the enclosing Map is access-ordered, it moves the entry
|
||||||
* to the end of the list; otherwise, it does nothing.
|
* to the end of the list; otherwise, it does nothing.
|
||||||
*/
|
*/
|
||||||
@ -422,8 +405,9 @@ public class LinkedHashMap<K,V>
|
|||||||
* allocated entry to get inserted at the end of the linked list and
|
* allocated entry to get inserted at the end of the linked list and
|
||||||
* removes the eldest entry if appropriate.
|
* removes the eldest entry if appropriate.
|
||||||
*/
|
*/
|
||||||
void addEntry(int hash, K key, V value, int bucketIndex) {
|
@Override
|
||||||
super.addEntry(hash, key, value, bucketIndex);
|
void addEntry(int hash, K key, V value, int bucketIndex, boolean checkIfNeedTree) {
|
||||||
|
super.addEntry(hash, key, value, bucketIndex, checkIfNeedTree);
|
||||||
|
|
||||||
// Remove eldest entry if instructed
|
// Remove eldest entry if instructed
|
||||||
Entry<K,V> eldest = header.after;
|
Entry<K,V> eldest = header.after;
|
||||||
@ -432,17 +416,14 @@ public class LinkedHashMap<K,V>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* This override differs from addEntry in that it doesn't resize the
|
* Create a new LinkedHashMap.Entry and setup the before/after pointers
|
||||||
* table or remove the eldest entry.
|
|
||||||
*/
|
*/
|
||||||
void createEntry(int hash, K key, V value, int bucketIndex) {
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
HashMap.Entry<K,V> newEntry(int hash, K key, V value, Object next) {
|
||||||
HashMap.Entry<K,V> old = (HashMap.Entry<K,V>)table[bucketIndex];
|
Entry<K,V> newEntry = new Entry<>(hash, key, value, next);
|
||||||
Entry<K,V> e = new Entry<>(hash, key, value, old);
|
newEntry.addBefore(header);
|
||||||
table[bucketIndex] = e;
|
return newEntry;
|
||||||
e.addBefore(header);
|
|
||||||
size++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,7 +171,7 @@ public class LongSummaryStatistics implements LongConsumer, IntConsumer {
|
|||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format(
|
return String.format(
|
||||||
"%s{count=%d, sum=%d, min=%d, average=%d, max=%d}",
|
"%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
|
||||||
this.getClass().getSimpleName(),
|
this.getClass().getSimpleName(),
|
||||||
getCount(),
|
getCount(),
|
||||||
getSum(),
|
getSum(),
|
||||||
|
@ -91,6 +91,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
|||||||
* @throws NullPointerException if the specified action is null
|
* @throws NullPointerException if the specified action is null
|
||||||
*/
|
*/
|
||||||
default void forEachRemaining(IntConsumer action) {
|
default void forEachRemaining(IntConsumer action) {
|
||||||
|
Objects.requireNonNull(action);
|
||||||
while (hasNext())
|
while (hasNext())
|
||||||
action.accept(nextInt());
|
action.accept(nextInt());
|
||||||
}
|
}
|
||||||
@ -123,6 +124,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
|||||||
forEachRemaining((IntConsumer) action);
|
forEachRemaining((IntConsumer) action);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// The method reference action::accept is never null
|
||||||
|
Objects.requireNonNull(action);
|
||||||
if (Tripwire.ENABLED)
|
if (Tripwire.ENABLED)
|
||||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.forEachRemainingInt(action::accept)");
|
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.forEachRemainingInt(action::accept)");
|
||||||
forEachRemaining((IntConsumer) action::accept);
|
forEachRemaining((IntConsumer) action::accept);
|
||||||
@ -162,6 +165,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
|||||||
* @throws NullPointerException if the specified action is null
|
* @throws NullPointerException if the specified action is null
|
||||||
*/
|
*/
|
||||||
default void forEachRemaining(LongConsumer action) {
|
default void forEachRemaining(LongConsumer action) {
|
||||||
|
Objects.requireNonNull(action);
|
||||||
while (hasNext())
|
while (hasNext())
|
||||||
action.accept(nextLong());
|
action.accept(nextLong());
|
||||||
}
|
}
|
||||||
@ -194,6 +198,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
|||||||
forEachRemaining((LongConsumer) action);
|
forEachRemaining((LongConsumer) action);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// The method reference action::accept is never null
|
||||||
|
Objects.requireNonNull(action);
|
||||||
if (Tripwire.ENABLED)
|
if (Tripwire.ENABLED)
|
||||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.forEachRemainingLong(action::accept)");
|
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.forEachRemainingLong(action::accept)");
|
||||||
forEachRemaining((LongConsumer) action::accept);
|
forEachRemaining((LongConsumer) action::accept);
|
||||||
@ -232,6 +238,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
|||||||
* @throws NullPointerException if the specified action is null
|
* @throws NullPointerException if the specified action is null
|
||||||
*/
|
*/
|
||||||
default void forEachRemaining(DoubleConsumer action) {
|
default void forEachRemaining(DoubleConsumer action) {
|
||||||
|
Objects.requireNonNull(action);
|
||||||
while (hasNext())
|
while (hasNext())
|
||||||
action.accept(nextDouble());
|
action.accept(nextDouble());
|
||||||
}
|
}
|
||||||
@ -265,6 +272,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
|
|||||||
forEachRemaining((DoubleConsumer) action);
|
forEachRemaining((DoubleConsumer) action);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// The method reference action::accept is never null
|
||||||
|
Objects.requireNonNull(action);
|
||||||
if (Tripwire.ENABLED)
|
if (Tripwire.ENABLED)
|
||||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.forEachRemainingDouble(action::accept)");
|
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.forEachRemainingDouble(action::accept)");
|
||||||
forEachRemaining((DoubleConsumer) action::accept);
|
forEachRemaining((DoubleConsumer) action::accept);
|
||||||
|
@ -394,9 +394,9 @@ public interface Spliterator<T> {
|
|||||||
* Convenience method that returns {@link #estimateSize()} if this
|
* Convenience method that returns {@link #estimateSize()} if this
|
||||||
* Spliterator is {@link #SIZED}, else {@code -1}.
|
* Spliterator is {@link #SIZED}, else {@code -1}.
|
||||||
* @implSpec
|
* @implSpec
|
||||||
* The default returns the result of {@code estimateSize()} if the
|
* The default implementation returns the result of {@code estimateSize()}
|
||||||
* Spliterator reports a characteristic of {@code SIZED}, and {@code -1}
|
* if the Spliterator reports a characteristic of {@code SIZED}, and
|
||||||
* otherwise.
|
* {@code -1} otherwise.
|
||||||
*
|
*
|
||||||
* @return the exact size, if known, else {@code -1}.
|
* @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
|
* by a delimiter and optionally starting with a supplied prefix
|
||||||
* and ending with a supplied suffix.
|
* and ending with a supplied suffix.
|
||||||
* <p>
|
* <p>
|
||||||
* For example, the String {@code "[George:Sally:Fred]"} may
|
|
||||||
* be constructed as follows:
|
|
||||||
* <pre> {@code
|
|
||||||
* StringJoiner sj = new StringJoiner(":", "[", "]");
|
|
||||||
* sj.add("George").add("Sally").add("Fred");
|
|
||||||
* String desiredString = sj.toString();
|
|
||||||
* }</pre>
|
|
||||||
* <p>
|
|
||||||
* Prior to adding something to the {@code StringJoiner}, its
|
* Prior to adding something to the {@code StringJoiner}, its
|
||||||
* {@code sj.toString()} method will, by default, return {@code prefix + suffix}.
|
* {@code sj.toString()} method will, by default, return {@code prefix + suffix}.
|
||||||
* However, if the {@code setEmptyValue} method is called, the {@code emptyValue}
|
* However, if the {@code setEmptyValue} method is called, the {@code emptyValue}
|
||||||
@ -45,17 +37,28 @@ package java.util;
|
|||||||
* <code>"{}"</code>, where the {@code prefix} is <code>"{"</code>, the
|
* <code>"{}"</code>, where the {@code prefix} is <code>"{"</code>, the
|
||||||
* {@code suffix} is <code>"}"</code> and nothing has been added to the
|
* {@code suffix} is <code>"}"</code> and nothing has been added to the
|
||||||
* {@code StringJoiner}.
|
* {@code StringJoiner}.
|
||||||
* <p>
|
*
|
||||||
* A {@code StringJoiner} may be employed to create formatted output from a
|
* @apiNote
|
||||||
* collection using lambda expressions as shown in the following example.
|
* <p>The String {@code "[George:Sally:Fred]"} may be constructed as follows:
|
||||||
*
|
*
|
||||||
* <pre> {@code
|
* <pre> {@code
|
||||||
* List<Person> people = ...
|
* StringJoiner sj = new StringJoiner(":", "[", "]");
|
||||||
* String commaSeparatedNames =
|
* sj.add("George").add("Sally").add("Fred");
|
||||||
* people.map(p -> p.getName()).into(new StringJoiner(", ")).toString();
|
* 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>
|
* }</pre>
|
||||||
*
|
*
|
||||||
* @author Jim Gish
|
* @see java.util.stream.Collectors#toStringJoiner
|
||||||
* @since 1.8
|
* @since 1.8
|
||||||
*/
|
*/
|
||||||
public final class StringJoiner {
|
public final class StringJoiner {
|
||||||
|
@ -187,11 +187,37 @@ public class WeakHashMap<K,V>
|
|||||||
*/
|
*/
|
||||||
int modCount;
|
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
|
* A randomizing value associated with this instance that is applied to
|
||||||
* hash code of keys to make hash collisions harder to find.
|
* hash code of keys to make hash collisions harder to find.
|
||||||
|
*
|
||||||
|
* Non-final so it can be set lazily, but be sure not to set more than once.
|
||||||
*/
|
*/
|
||||||
transient final int hashSeed = sun.misc.Hashing.randomHashSeed(this);
|
transient 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")
|
@SuppressWarnings("unchecked")
|
||||||
private Entry<K,V>[] newTable(int n) {
|
private Entry<K,V>[] newTable(int n) {
|
||||||
@ -223,6 +249,7 @@ public class WeakHashMap<K,V>
|
|||||||
table = newTable(capacity);
|
table = newTable(capacity);
|
||||||
this.loadFactor = loadFactor;
|
this.loadFactor = loadFactor;
|
||||||
threshold = (int)(capacity * loadFactor);
|
threshold = (int)(capacity * loadFactor);
|
||||||
|
initHashSeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -298,10 +325,7 @@ public class WeakHashMap<K,V>
|
|||||||
* in lower bits.
|
* in lower bits.
|
||||||
*/
|
*/
|
||||||
final int hash(Object k) {
|
final int hash(Object k) {
|
||||||
if (k instanceof String) {
|
int h = hashSeed ^ k.hashCode();
|
||||||
return ((String) k).hash32();
|
|
||||||
}
|
|
||||||
int h = hashSeed ^ k.hashCode();
|
|
||||||
|
|
||||||
// This function ensures that hashCodes that differ only by
|
// This function ensures that hashCodes that differ only by
|
||||||
// constant multiples at each bit position have a bounded
|
// constant multiples at each bit position have a bounded
|
||||||
@ -1076,9 +1100,10 @@ public class WeakHashMap<K,V>
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
mc = expectedModCount;
|
mc = expectedModCount;
|
||||||
if (tab.length >= hi && (i = index) >= 0 && i < hi) {
|
if (tab.length >= hi && (i = index) >= 0 &&
|
||||||
index = hi;
|
(i < (index = hi) || current != null)) {
|
||||||
WeakHashMap.Entry<K,V> p = current;
|
WeakHashMap.Entry<K,V> p = current;
|
||||||
|
current = null; // exhaust
|
||||||
do {
|
do {
|
||||||
if (p == null)
|
if (p == null)
|
||||||
p = tab[i++];
|
p = tab[i++];
|
||||||
@ -1155,9 +1180,10 @@ public class WeakHashMap<K,V>
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
mc = expectedModCount;
|
mc = expectedModCount;
|
||||||
if (tab.length >= hi && (i = index) >= 0 && i < hi) {
|
if (tab.length >= hi && (i = index) >= 0 &&
|
||||||
index = hi;
|
(i < (index = hi) || current != null)) {
|
||||||
WeakHashMap.Entry<K,V> p = current;
|
WeakHashMap.Entry<K,V> p = current;
|
||||||
|
current = null; // exhaust
|
||||||
do {
|
do {
|
||||||
if (p == null)
|
if (p == null)
|
||||||
p = tab[i++];
|
p = tab[i++];
|
||||||
@ -1232,9 +1258,10 @@ public class WeakHashMap<K,V>
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
mc = expectedModCount;
|
mc = expectedModCount;
|
||||||
if (tab.length >= hi && (i = index) >= 0 && i < hi) {
|
if (tab.length >= hi && (i = index) >= 0 &&
|
||||||
index = hi;
|
(i < (index = hi) || current != null)) {
|
||||||
WeakHashMap.Entry<K,V> p = current;
|
WeakHashMap.Entry<K,V> p = current;
|
||||||
|
current = null; // exhaust
|
||||||
do {
|
do {
|
||||||
if (p == null)
|
if (p == null)
|
||||||
p = tab[i++];
|
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
|
* installed SPI providers, and "JRE" represents the locale sensitive services
|
||||||
* in the Java Runtime Environment, the locale sensitive services in the SPI
|
* in the Java Runtime Environment, the locale sensitive services in the SPI
|
||||||
* providers are looked up first.
|
* 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
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
|
@ -603,7 +603,7 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
|||||||
/**
|
/**
|
||||||
* Returns an {@link OptionalDouble} describing the first element of this
|
* Returns an {@link OptionalDouble} describing the first element of this
|
||||||
* stream (in the encounter order), or an empty {@code OptionalDouble} if
|
* 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.
|
* element may be returned.
|
||||||
*
|
*
|
||||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
* <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
|
* Returns an {@link OptionalInt} describing the first element of this
|
||||||
* stream (in the encounter order), or an empty {@code OptionalInt} if the
|
* 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.
|
* may be returned.
|
||||||
*
|
*
|
||||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
* <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
|
* Returns an {@link OptionalLong} describing the first element of this
|
||||||
* stream (in the encounter order), or an empty {@code OptionalLong} if the
|
* 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.
|
* may be returned.
|
||||||
*
|
*
|
||||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
* <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
|
* Returns an {@link Optional} describing the first element of this stream
|
||||||
* (in the encounter order), or an empty {@code Optional} if the stream is
|
* (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.
|
* returned.
|
||||||
*
|
*
|
||||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
* <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
|
* <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, during which elements can be added, and then transitions to a built
|
||||||
* phase, after which elements may not be added. The built phase begins
|
* 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
|
* {@code Stream} whose elements are the elements that were added to the stream
|
||||||
* builder, in the order they were added.
|
* 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
|
* <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
|
* phase, during which elements can be added, and then transitions to a
|
||||||
* built phase, after which elements may not be added. The built phase
|
* 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
|
* ordered stream whose elements are the elements that were added to the
|
||||||
* stream builder, in the order they were added.
|
* 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
|
* <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
|
* phase, during which elements can be added, and then transitions to a
|
||||||
* built phase, after which elements may not be added. The built phase
|
* 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
|
* ordered stream whose elements are the elements that were added to the
|
||||||
* stream builder, in the order they were added.
|
* 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}.
|
* 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()
|
* @see LongStream#builder()
|
||||||
* @since 1.8
|
* @since 1.8
|
||||||
*/
|
*/
|
||||||
@ -217,13 +224,6 @@ public interface StreamBuilder<T> extends Consumer<T> {
|
|||||||
/**
|
/**
|
||||||
* Adds an element to the stream being built.
|
* 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
|
* @throws IllegalStateException if the builder has already transitioned
|
||||||
* to the built state
|
* to the built state
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +41,11 @@ import java.util.function.Supplier;
|
|||||||
*
|
*
|
||||||
* @since 1.8
|
* @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}.
|
* 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
|
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
* {@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
|
* {@link #stream(Supplier, int)} should be used to
|
||||||
* reduce the scope of potential interference with the source. See
|
* reduce the scope of potential interference with the source. See
|
||||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
* <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
|
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
* {@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
|
* {@link #stream(Supplier, int)} should be used to
|
||||||
* reduce the scope of potential interference with the source. See
|
* reduce the scope of potential interference with the source. See
|
||||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
* <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}
|
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||||
* or {@code CONCURRENT}, or that are
|
* 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.
|
* more efficient to use {@link #stream(java.util.Spliterator)} instead.
|
||||||
* The use of a {@code Supplier} in this form provides a level of
|
* The use of a {@code Supplier} in this form provides a level of
|
||||||
* indirection that reduces the scope of potential interference with the
|
* 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}
|
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||||
* or {@code CONCURRENT}, or that are
|
* 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.
|
* more efficient to use {@link #stream(Spliterator)} instead.
|
||||||
* The use of a {@code Supplier} in this form provides a level of
|
* The use of a {@code Supplier} in this form provides a level of
|
||||||
* indirection that reduces the scope of potential interference with the
|
* 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
|
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
* {@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
|
* {@link #stream(Supplier, int)}} should be used to
|
||||||
* reduce the scope of potential interference with the source. See
|
* reduce the scope of potential interference with the source. See
|
||||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
* <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
|
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
* {@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
|
* {@link #stream(Supplier, int)}} should be used to
|
||||||
* reduce the scope of potential interference with the source. See
|
* reduce the scope of potential interference with the source. See
|
||||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
* <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}
|
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||||
* or {@code CONCURRENT}, or that are
|
* 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.
|
* more efficient to use {@link #intStream(Spliterator.OfInt)} instead.
|
||||||
* The use of a {@code Supplier} in this form provides a level of
|
* The use of a {@code Supplier} in this form provides a level of
|
||||||
* indirection that reduces the scope of potential interference with the
|
* 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}
|
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||||
* or {@code CONCURRENT}, or that are
|
* 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.
|
* more efficient to use {@link #intStream(Spliterator.OfInt)} instead.
|
||||||
* The use of a {@code Supplier} in this form provides a level of
|
* The use of a {@code Supplier} in this form provides a level of
|
||||||
* indirection that reduces the scope of potential interference with the
|
* 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
|
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
* {@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
|
* {@link #stream(Supplier, int)} should be used to
|
||||||
* reduce the scope of potential interference with the source. See
|
* reduce the scope of potential interference with the source. See
|
||||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
* <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
|
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
* {@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
|
* {@link #stream(Supplier, int)} should be used to
|
||||||
* reduce the scope of potential interference with the source. See
|
* reduce the scope of potential interference with the source. See
|
||||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
* <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}
|
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||||
* or {@code CONCURRENT}, or that are
|
* 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.
|
* more efficient to use {@link #longStream(Spliterator.OfLong)} instead.
|
||||||
* The use of a {@code Supplier} in this form provides a level of
|
* The use of a {@code Supplier} in this form provides a level of
|
||||||
* indirection that reduces the scope of potential interference with the
|
* 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}
|
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||||
* or {@code CONCURRENT}, or that are
|
* 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.
|
* more efficient to use {@link #longStream(Spliterator.OfLong)} instead.
|
||||||
* The use of a {@code Supplier} in this form provides a level of
|
* The use of a {@code Supplier} in this form provides a level of
|
||||||
* indirection that reduces the scope of potential interference with the
|
* 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
|
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
* {@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
|
* {@link #stream(Supplier, int)} should be used to
|
||||||
* reduce the scope of potential interference with the source. See
|
* reduce the scope of potential interference with the source. See
|
||||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
* <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
|
* <p>It is strongly recommended the spliterator report a characteristic of
|
||||||
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
* {@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
|
* {@link #stream(Supplier, int)} should be used to
|
||||||
* reduce the scope of potential interference with the source. See
|
* reduce the scope of potential interference with the source. See
|
||||||
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for
|
||||||
@ -451,7 +455,7 @@ public class StreamSupport {
|
|||||||
* <p>
|
* <p>
|
||||||
* For spliterators that report a characteristic of {@code IMMUTABLE}
|
* For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||||
* or {@code CONCURRENT}, or that are
|
* 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.
|
* more efficient to use {@link #doubleStream(Spliterator.OfDouble)} instead.
|
||||||
* The use of a {@code Supplier} in this form provides a level of
|
* The use of a {@code Supplier} in this form provides a level of
|
||||||
* indirection that reduces the scope of potential interference with the
|
* 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}
|
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||||
* or {@code CONCURRENT}, or that are
|
* 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.
|
* more efficient to use {@link #doubleStream(Spliterator.OfDouble)} instead.
|
||||||
* The use of a {@code Supplier} in this form provides a level of
|
* The use of a {@code Supplier} in this form provides a level of
|
||||||
* indirection that reduces the scope of potential interference with the
|
* 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 EXTSIZ = 8; // compressed size
|
||||||
static final int EXTLEN = 12; // uncompressed 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
|
* Central directory (CEN) header field offsets
|
||||||
*/
|
*/
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
|
|
||||||
package java.util.zip;
|
package java.util.zip;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to represent a ZIP file entry.
|
* This class is used to represent a ZIP file entry.
|
||||||
*
|
*
|
||||||
@ -35,7 +33,7 @@ import java.util.Date;
|
|||||||
public
|
public
|
||||||
class ZipEntry implements ZipConstants, Cloneable {
|
class ZipEntry implements ZipConstants, Cloneable {
|
||||||
String name; // entry name
|
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 crc = -1; // crc-32 of entry data
|
||||||
long size = -1; // uncompressed size of entry data
|
long size = -1; // uncompressed size of entry data
|
||||||
long csize = -1; // compressed 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) {
|
public ZipEntry(ZipEntry e) {
|
||||||
name = e.name;
|
name = e.name;
|
||||||
time = e.time;
|
mtime = e.mtime;
|
||||||
crc = e.crc;
|
crc = e.crc;
|
||||||
size = e.size;
|
size = e.size;
|
||||||
csize = e.csize;
|
csize = e.csize;
|
||||||
@ -89,7 +87,7 @@ class ZipEntry implements ZipConstants, Cloneable {
|
|||||||
comment = e.comment;
|
comment = e.comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Creates a new un-initialized zip entry
|
* Creates a new un-initialized zip entry
|
||||||
*/
|
*/
|
||||||
ZipEntry() {}
|
ZipEntry() {}
|
||||||
@ -103,22 +101,26 @@ class ZipEntry implements ZipConstants, Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the modification time of the entry.
|
* Sets the last modification time of the entry.
|
||||||
* @param time the entry modification time in number of milliseconds
|
*
|
||||||
* since the epoch
|
* @param time the last modification time of the entry in milliseconds since the epoch
|
||||||
* @see #getTime()
|
* @see #getTime()
|
||||||
*/
|
*/
|
||||||
public void setTime(long time) {
|
public void setTime(long time) {
|
||||||
this.time = javaToDosTime(time);
|
this.mtime = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the modification time of the entry, or -1 if not specified.
|
* Returns the last modification time of the entry.
|
||||||
* @return the modification time of the entry, or -1 if not specified
|
* <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)
|
* @see #setTime(long)
|
||||||
*/
|
*/
|
||||||
public long getTime() {
|
public long getTime() {
|
||||||
return time != -1 ? dosToJavaTime(time) : -1;
|
return mtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -277,35 +279,6 @@ class ZipEntry implements ZipConstants, Cloneable {
|
|||||||
return getName();
|
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.
|
* Returns the hash code value for this entry.
|
||||||
*/
|
*/
|
||||||
|
@ -46,6 +46,7 @@ import java.util.stream.Stream;
|
|||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
import static java.util.zip.ZipConstants64.*;
|
import static java.util.zip.ZipConstants64.*;
|
||||||
|
import static java.util.zip.ZipUtils.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to read entries from a zip file.
|
* 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.name = zc.toString(bname, bname.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.time = getEntryTime(jzentry);
|
|
||||||
e.crc = getEntryCrc(jzentry);
|
e.crc = getEntryCrc(jzentry);
|
||||||
e.size = getEntrySize(jzentry);
|
e.size = getEntrySize(jzentry);
|
||||||
e. csize = getEntryCSize(jzentry);
|
e. csize = getEntryCSize(jzentry);
|
||||||
e.method = getEntryMethod(jzentry);
|
e.method = getEntryMethod(jzentry);
|
||||||
e.extra = getEntryBytes(jzentry, JZENTRY_EXTRA);
|
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);
|
byte[] bcomm = getEntryBytes(jzentry, JZENTRY_COMMENT);
|
||||||
if (bcomm == null) {
|
if (bcomm == null) {
|
||||||
e.comment = null;
|
e.comment = null;
|
||||||
|
@ -32,6 +32,7 @@ import java.io.PushbackInputStream;
|
|||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import static java.util.zip.ZipConstants64.*;
|
import static java.util.zip.ZipConstants64.*;
|
||||||
|
import static java.util.zip.ZipUtils.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class implements an input stream filter for reading files in the
|
* 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");
|
throw new ZipException("encrypted ZIP entry not supported");
|
||||||
}
|
}
|
||||||
e.method = get16(tmpbuf, LOCHOW);
|
e.method = get16(tmpbuf, LOCHOW);
|
||||||
e.time = get32(tmpbuf, LOCTIM);
|
e.mtime = dosToJavaTime(get32(tmpbuf, LOCTIM));
|
||||||
if ((flag & 8) == 8) {
|
if ((flag & 8) == 8) {
|
||||||
/* "Data Descriptor" present */
|
/* "Data Descriptor" present */
|
||||||
if (e.method != DEFLATED) {
|
if (e.method != DEFLATED) {
|
||||||
@ -316,32 +317,51 @@ class ZipInputStream extends InflaterInputStream implements ZipConstants {
|
|||||||
}
|
}
|
||||||
len = get16(tmpbuf, LOCEXT);
|
len = get16(tmpbuf, LOCEXT);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
byte[] bb = new byte[len];
|
byte[] extra = new byte[len];
|
||||||
readFully(bb, 0, len);
|
readFully(extra, 0, len);
|
||||||
e.setExtra(bb);
|
e.setExtra(extra);
|
||||||
// extra fields are in "HeaderID(2)DataSize(2)Data... format
|
// extra fields are in "HeaderID(2)DataSize(2)Data... format
|
||||||
if (e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL) {
|
int off = 0;
|
||||||
int off = 0;
|
while (off + 4 < len) {
|
||||||
while (off + 4 < len) {
|
int pos = off;
|
||||||
int sz = get16(bb, off + 2);
|
int tag = get16(extra, pos);
|
||||||
if (get16(bb, off) == ZIP64_EXTID) {
|
int sz = get16(extra, pos + 2);
|
||||||
off += 4;
|
pos += 4;
|
||||||
// LOC extra zip64 entry MUST include BOTH original and
|
if (pos + sz > len) // invalid data
|
||||||
// compressed file size fields
|
break;
|
||||||
if (sz < 16 || (off + sz) > len ) {
|
switch (tag) {
|
||||||
// Invalid zip64 extra fields, simply skip. Even it's
|
case EXTID_ZIP64 :
|
||||||
// rare, it's possible the entry size happens to be
|
// LOC extra zip64 entry MUST include BOTH original and
|
||||||
// the magic value and it "accidnetly" has some bytes
|
// compressed file size fields.
|
||||||
// in extra match the id.
|
//
|
||||||
return e;
|
// If invalid zip64 extra fields, simply skip. Even it's
|
||||||
}
|
// rare, it's possible the entry size happens to be
|
||||||
e.size = get64(bb, off);
|
// the magic value and it "accidently" has some bytes
|
||||||
e.csize = get64(bb, off + 8);
|
// in extra match the id.
|
||||||
break;
|
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;
|
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.Vector;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import static java.util.zip.ZipConstants64.*;
|
import static java.util.zip.ZipConstants64.*;
|
||||||
|
import static java.util.zip.ZipUtils.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class implements an output stream filter for writing files in the
|
* 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) {
|
if (current != null) {
|
||||||
closeEntry(); // close previous entry
|
closeEntry(); // close previous entry
|
||||||
}
|
}
|
||||||
if (e.time == -1) {
|
if (e.mtime == -1) {
|
||||||
e.setTime(System.currentTimeMillis());
|
e.setTime(System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
if (e.method == -1) {
|
if (e.method == -1) {
|
||||||
@ -382,16 +383,25 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
|||||||
private void writeLOC(XEntry xentry) throws IOException {
|
private void writeLOC(XEntry xentry) throws IOException {
|
||||||
ZipEntry e = xentry.entry;
|
ZipEntry e = xentry.entry;
|
||||||
int flag = e.flag;
|
int flag = e.flag;
|
||||||
int elen = (e.extra != null) ? e.extra.length : 0;
|
|
||||||
boolean hasZip64 = false;
|
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
|
writeInt(LOCSIG); // LOC header signature
|
||||||
|
|
||||||
if ((flag & 8) == 8) {
|
if ((flag & 8) == 8) {
|
||||||
writeShort(version(e)); // version needed to extract
|
writeShort(version(e)); // version needed to extract
|
||||||
writeShort(flag); // general purpose bit flag
|
writeShort(flag); // general purpose bit flag
|
||||||
writeShort(e.method); // compression method
|
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
|
// store size, uncompressed size, and crc-32 in data descriptor
|
||||||
// immediately following compressed entry data
|
// immediately following compressed entry data
|
||||||
@ -407,7 +417,7 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
|||||||
}
|
}
|
||||||
writeShort(flag); // general purpose bit flag
|
writeShort(flag); // general purpose bit flag
|
||||||
writeShort(e.method); // compression method
|
writeShort(e.method); // compression method
|
||||||
writeInt(e.time); // last modification time
|
writeInt(javaToDosTime(e.mtime)); // last modification time
|
||||||
writeInt(e.crc); // crc-32
|
writeInt(e.crc); // crc-32
|
||||||
if (hasZip64) {
|
if (hasZip64) {
|
||||||
writeInt(ZIP64_MAGICVAL);
|
writeInt(ZIP64_MAGICVAL);
|
||||||
@ -420,6 +430,8 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
|||||||
}
|
}
|
||||||
byte[] nameBytes = zc.getBytes(e.name);
|
byte[] nameBytes = zc.getBytes(e.name);
|
||||||
writeShort(nameBytes.length);
|
writeShort(nameBytes.length);
|
||||||
|
if (!foundEXTT)
|
||||||
|
elen += 9; // use Info-ZIP's ext time in extra
|
||||||
writeShort(elen);
|
writeShort(elen);
|
||||||
writeBytes(nameBytes, 0, nameBytes.length);
|
writeBytes(nameBytes, 0, nameBytes.length);
|
||||||
if (hasZip64) {
|
if (hasZip64) {
|
||||||
@ -428,6 +440,12 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
|||||||
writeLong(e.size);
|
writeLong(e.size);
|
||||||
writeLong(e.csize);
|
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) {
|
if (e.extra != null) {
|
||||||
writeBytes(e.extra, 0, e.extra.length);
|
writeBytes(e.extra, 0, e.extra.length);
|
||||||
}
|
}
|
||||||
@ -457,25 +475,25 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
|||||||
ZipEntry e = xentry.entry;
|
ZipEntry e = xentry.entry;
|
||||||
int flag = e.flag;
|
int flag = e.flag;
|
||||||
int version = version(e);
|
int version = version(e);
|
||||||
|
|
||||||
long csize = e.csize;
|
long csize = e.csize;
|
||||||
long size = e.size;
|
long size = e.size;
|
||||||
long offset = xentry.offset;
|
long offset = xentry.offset;
|
||||||
int e64len = 0;
|
int elenZIP64 = 0;
|
||||||
boolean hasZip64 = false;
|
boolean hasZip64 = false;
|
||||||
|
|
||||||
if (e.csize >= ZIP64_MAGICVAL) {
|
if (e.csize >= ZIP64_MAGICVAL) {
|
||||||
csize = ZIP64_MAGICVAL;
|
csize = ZIP64_MAGICVAL;
|
||||||
e64len += 8; // csize(8)
|
elenZIP64 += 8; // csize(8)
|
||||||
hasZip64 = true;
|
hasZip64 = true;
|
||||||
}
|
}
|
||||||
if (e.size >= ZIP64_MAGICVAL) {
|
if (e.size >= ZIP64_MAGICVAL) {
|
||||||
size = ZIP64_MAGICVAL; // size(8)
|
size = ZIP64_MAGICVAL; // size(8)
|
||||||
e64len += 8;
|
elenZIP64 += 8;
|
||||||
hasZip64 = true;
|
hasZip64 = true;
|
||||||
}
|
}
|
||||||
if (xentry.offset >= ZIP64_MAGICVAL) {
|
if (xentry.offset >= ZIP64_MAGICVAL) {
|
||||||
offset = ZIP64_MAGICVAL;
|
offset = ZIP64_MAGICVAL;
|
||||||
e64len += 8; // offset(8)
|
elenZIP64 += 8; // offset(8)
|
||||||
hasZip64 = true;
|
hasZip64 = true;
|
||||||
}
|
}
|
||||||
writeInt(CENSIG); // CEN header signature
|
writeInt(CENSIG); // CEN header signature
|
||||||
@ -488,18 +506,32 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
|||||||
}
|
}
|
||||||
writeShort(flag); // general purpose bit flag
|
writeShort(flag); // general purpose bit flag
|
||||||
writeShort(e.method); // compression method
|
writeShort(e.method); // compression method
|
||||||
writeInt(e.time); // last modification time
|
writeInt(javaToDosTime(e.mtime)); // last modification time
|
||||||
writeInt(e.crc); // crc-32
|
writeInt(e.crc); // crc-32
|
||||||
writeInt(csize); // compressed size
|
writeInt(csize); // compressed size
|
||||||
writeInt(size); // uncompressed size
|
writeInt(size); // uncompressed size
|
||||||
byte[] nameBytes = zc.getBytes(e.name);
|
byte[] nameBytes = zc.getBytes(e.name);
|
||||||
writeShort(nameBytes.length);
|
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) {
|
if (hasZip64) {
|
||||||
// + headid(2) + datasize(2)
|
// + headid(2) + datasize(2)
|
||||||
writeShort(e64len + 4 + (e.extra != null ? e.extra.length : 0));
|
elen += (elenZIP64 + 4);
|
||||||
} else {
|
|
||||||
writeShort(e.extra != null ? e.extra.length : 0);
|
|
||||||
}
|
}
|
||||||
|
if (!foundEXTT)
|
||||||
|
elen += 9; // Info-ZIP's Extended Timestamp
|
||||||
|
writeShort(elen);
|
||||||
byte[] commentBytes;
|
byte[] commentBytes;
|
||||||
if (e.comment != null) {
|
if (e.comment != null) {
|
||||||
commentBytes = zc.getBytes(e.comment);
|
commentBytes = zc.getBytes(e.comment);
|
||||||
@ -515,7 +547,7 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
|||||||
writeBytes(nameBytes, 0, nameBytes.length);
|
writeBytes(nameBytes, 0, nameBytes.length);
|
||||||
if (hasZip64) {
|
if (hasZip64) {
|
||||||
writeShort(ZIP64_EXTID);// Zip64 extra
|
writeShort(ZIP64_EXTID);// Zip64 extra
|
||||||
writeShort(e64len);
|
writeShort(elenZIP64);
|
||||||
if (size == ZIP64_MAGICVAL)
|
if (size == ZIP64_MAGICVAL)
|
||||||
writeLong(e.size);
|
writeLong(e.size);
|
||||||
if (csize == ZIP64_MAGICVAL)
|
if (csize == ZIP64_MAGICVAL)
|
||||||
@ -523,6 +555,12 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
|||||||
if (offset == ZIP64_MAGICVAL)
|
if (offset == ZIP64_MAGICVAL)
|
||||||
writeLong(xentry.offset);
|
writeLong(xentry.offset);
|
||||||
}
|
}
|
||||||
|
if (!foundEXTT) {
|
||||||
|
writeShort(EXTID_EXTT);
|
||||||
|
writeShort(5);
|
||||||
|
writeByte(0x1); // flags byte
|
||||||
|
writeInt(javaToUnixTime(e.mtime));
|
||||||
|
}
|
||||||
if (e.extra != null) {
|
if (e.extra != null) {
|
||||||
writeBytes(e.extra, 0, e.extra.length);
|
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.
|
* 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
|
* determined from the given key, or if the given key has a keysize that
|
||||||
* exceeds the maximum allowable keysize (as determined from the
|
* exceeds the maximum allowable keysize (as determined from the
|
||||||
* configured jurisdiction policy files).
|
* 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 {
|
public final void init(int opmode, Key key) throws InvalidKeyException {
|
||||||
init(opmode, key, JceSecurity.RANDOM);
|
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
|
* determined from the given key, or if the given key has a keysize that
|
||||||
* exceeds the maximum allowable keysize (as determined from the
|
* exceeds the maximum allowable keysize (as determined from the
|
||||||
* configured jurisdiction policy files).
|
* 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)
|
public final void init(int opmode, Key key, SecureRandom random)
|
||||||
throws InvalidKeyException
|
throws InvalidKeyException
|
||||||
@ -1285,6 +1291,9 @@ public class Cipher {
|
|||||||
* algorithm parameters imply a cryptographic strength that would exceed
|
* algorithm parameters imply a cryptographic strength that would exceed
|
||||||
* the legal limits (as determined from the configured jurisdiction
|
* the legal limits (as determined from the configured jurisdiction
|
||||||
* policy files).
|
* 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)
|
public final void init(int opmode, Key key, AlgorithmParameterSpec params)
|
||||||
throws InvalidKeyException, InvalidAlgorithmParameterException
|
throws InvalidKeyException, InvalidAlgorithmParameterException
|
||||||
@ -1343,6 +1352,9 @@ public class Cipher {
|
|||||||
* algorithm parameters imply a cryptographic strength that would exceed
|
* algorithm parameters imply a cryptographic strength that would exceed
|
||||||
* the legal limits (as determined from the configured jurisdiction
|
* the legal limits (as determined from the configured jurisdiction
|
||||||
* policy files).
|
* 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,
|
public final void init(int opmode, Key key, AlgorithmParameterSpec params,
|
||||||
SecureRandom random)
|
SecureRandom random)
|
||||||
@ -1416,6 +1428,9 @@ public class Cipher {
|
|||||||
* algorithm parameters imply a cryptographic strength that would exceed
|
* algorithm parameters imply a cryptographic strength that would exceed
|
||||||
* the legal limits (as determined from the configured jurisdiction
|
* the legal limits (as determined from the configured jurisdiction
|
||||||
* policy files).
|
* 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)
|
public final void init(int opmode, Key key, AlgorithmParameters params)
|
||||||
throws InvalidKeyException, InvalidAlgorithmParameterException
|
throws InvalidKeyException, InvalidAlgorithmParameterException
|
||||||
@ -1474,6 +1489,9 @@ public class Cipher {
|
|||||||
* algorithm parameters imply a cryptographic strength that would exceed
|
* algorithm parameters imply a cryptographic strength that would exceed
|
||||||
* the legal limits (as determined from the configured jurisdiction
|
* the legal limits (as determined from the configured jurisdiction
|
||||||
* policy files).
|
* 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,
|
public final void init(int opmode, Key key, AlgorithmParameters params,
|
||||||
SecureRandom random)
|
SecureRandom random)
|
||||||
@ -1552,6 +1570,9 @@ public class Cipher {
|
|||||||
* in the given certificate has a keysize that exceeds the maximum
|
* in the given certificate has a keysize that exceeds the maximum
|
||||||
* allowable keysize (as determined by the configured jurisdiction policy
|
* allowable keysize (as determined by the configured jurisdiction policy
|
||||||
* files).
|
* 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)
|
public final void init(int opmode, Certificate certificate)
|
||||||
throws InvalidKeyException
|
throws InvalidKeyException
|
||||||
@ -1619,6 +1640,9 @@ public class Cipher {
|
|||||||
* in the given certificate has a keysize that exceeds the maximum
|
* in the given certificate has a keysize that exceeds the maximum
|
||||||
* allowable keysize (as determined by the configured jurisdiction policy
|
* allowable keysize (as determined by the configured jurisdiction policy
|
||||||
* files).
|
* 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,
|
public final void init(int opmode, Certificate certificate,
|
||||||
SecureRandom random)
|
SecureRandom random)
|
||||||
@ -2410,6 +2434,9 @@ public class Cipher {
|
|||||||
* @exception InvalidKeyException if it is impossible or unsafe to
|
* @exception InvalidKeyException if it is impossible or unsafe to
|
||||||
* wrap the key with this cipher (e.g., a hardware protected key is
|
* wrap the key with this cipher (e.g., a hardware protected key is
|
||||||
* being passed to a software-only cipher).
|
* 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)
|
public final byte[] wrap(Key key)
|
||||||
throws IllegalBlockSizeException, InvalidKeyException {
|
throws IllegalBlockSizeException, InvalidKeyException {
|
||||||
@ -2451,6 +2478,9 @@ public class Cipher {
|
|||||||
* @exception InvalidKeyException if <code>wrappedKey</code> does not
|
* @exception InvalidKeyException if <code>wrappedKey</code> does not
|
||||||
* represent a wrapped key of type <code>wrappedKeyType</code> for
|
* represent a wrapped key of type <code>wrappedKeyType</code> for
|
||||||
* the <code>wrappedKeyAlgorithm</code>.
|
* the <code>wrappedKeyAlgorithm</code>.
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException if the corresponding method in the
|
||||||
|
* {@code CipherSpi} is not supported.
|
||||||
*/
|
*/
|
||||||
public final Key unwrap(byte[] wrappedKey,
|
public final Key unwrap(byte[] wrappedKey,
|
||||||
String wrappedKeyAlgorithm,
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -86,6 +86,8 @@ public class CipherInputStream extends FilterInputStream {
|
|||||||
private int ostart = 0;
|
private int ostart = 0;
|
||||||
// the offset pointing to the last "new" byte
|
// the offset pointing to the last "new" byte
|
||||||
private int ofinish = 0;
|
private int ofinish = 0;
|
||||||
|
// stream status
|
||||||
|
private boolean closed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* private convenience function.
|
* private convenience function.
|
||||||
@ -293,14 +295,17 @@ public class CipherInputStream extends FilterInputStream {
|
|||||||
* @since JCE1.2
|
* @since JCE1.2
|
||||||
*/
|
*/
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
|
if (closed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
closed = true;
|
||||||
input.close();
|
input.close();
|
||||||
try {
|
try {
|
||||||
// throw away the unprocessed data
|
// throw away the unprocessed data
|
||||||
cipher.doFinal();
|
cipher.doFinal();
|
||||||
}
|
}
|
||||||
catch (BadPaddingException ex) {
|
catch (BadPaddingException | IllegalBlockSizeException ex) {
|
||||||
}
|
|
||||||
catch (IllegalBlockSizeException ex) {
|
|
||||||
}
|
}
|
||||||
ostart = 0;
|
ostart = 0;
|
||||||
ofinish = 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -74,6 +74,9 @@ public class CipherOutputStream extends FilterOutputStream {
|
|||||||
// the buffer holding data ready to be written out
|
// the buffer holding data ready to be written out
|
||||||
private byte[] obuffer;
|
private byte[] obuffer;
|
||||||
|
|
||||||
|
// stream status
|
||||||
|
private boolean closed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Constructs a CipherOutputStream from an OutputStream and a
|
* Constructs a CipherOutputStream from an OutputStream and a
|
||||||
@ -198,11 +201,14 @@ public class CipherOutputStream extends FilterOutputStream {
|
|||||||
* @since JCE1.2
|
* @since JCE1.2
|
||||||
*/
|
*/
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
|
if (closed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
closed = true;
|
||||||
try {
|
try {
|
||||||
obuffer = cipher.doFinal();
|
obuffer = cipher.doFinal();
|
||||||
} catch (IllegalBlockSizeException e) {
|
} catch (IllegalBlockSizeException | BadPaddingException e) {
|
||||||
obuffer = null;
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
obuffer = null;
|
obuffer = null;
|
||||||
}
|
}
|
||||||
try {
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -347,6 +347,9 @@ public abstract class CipherSpi {
|
|||||||
* initializing this cipher, or requires
|
* initializing this cipher, or requires
|
||||||
* algorithm parameters that cannot be
|
* algorithm parameters that cannot be
|
||||||
* determined from the given key.
|
* 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,
|
protected abstract void engineInit(int opmode, Key key,
|
||||||
SecureRandom random)
|
SecureRandom random)
|
||||||
@ -399,6 +402,9 @@ public abstract class CipherSpi {
|
|||||||
* parameters are inappropriate for this cipher,
|
* parameters are inappropriate for this cipher,
|
||||||
* or if this cipher requires
|
* or if this cipher requires
|
||||||
* algorithm parameters and <code>params</code> is null.
|
* 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,
|
protected abstract void engineInit(int opmode, Key key,
|
||||||
AlgorithmParameterSpec params,
|
AlgorithmParameterSpec params,
|
||||||
@ -452,6 +458,9 @@ public abstract class CipherSpi {
|
|||||||
* parameters are inappropriate for this cipher,
|
* parameters are inappropriate for this cipher,
|
||||||
* or if this cipher requires
|
* or if this cipher requires
|
||||||
* algorithm parameters and <code>params</code> is null.
|
* 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,
|
protected abstract void engineInit(int opmode, Key key,
|
||||||
AlgorithmParameters params,
|
AlgorithmParameters params,
|
||||||
@ -863,6 +872,8 @@ public abstract class CipherSpi {
|
|||||||
* @exception InvalidKeyException if it is impossible or unsafe to
|
* @exception InvalidKeyException if it is impossible or unsafe to
|
||||||
* wrap the key with this cipher (e.g., a hardware protected key is
|
* wrap the key with this cipher (e.g., a hardware protected key is
|
||||||
* being passed to a software-only cipher).
|
* being passed to a software-only cipher).
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException if this method is not supported.
|
||||||
*/
|
*/
|
||||||
protected byte[] engineWrap(Key key)
|
protected byte[] engineWrap(Key key)
|
||||||
throws IllegalBlockSizeException, InvalidKeyException
|
throws IllegalBlockSizeException, InvalidKeyException
|
||||||
@ -899,6 +910,8 @@ public abstract class CipherSpi {
|
|||||||
* @exception InvalidKeyException if <code>wrappedKey</code> does not
|
* @exception InvalidKeyException if <code>wrappedKey</code> does not
|
||||||
* represent a wrapped key of type <code>wrappedKeyType</code> for
|
* represent a wrapped key of type <code>wrappedKeyType</code> for
|
||||||
* the <code>wrappedKeyAlgorithm</code>.
|
* the <code>wrappedKeyAlgorithm</code>.
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException if this method is not supported.
|
||||||
*/
|
*/
|
||||||
protected Key engineUnwrap(byte[] wrappedKey,
|
protected Key engineUnwrap(byte[] wrappedKey,
|
||||||
String wrappedKeyAlgorithm,
|
String wrappedKeyAlgorithm,
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,6 +27,7 @@ package sun.management;
|
|||||||
|
|
||||||
import java.lang.management.*;
|
import java.lang.management.*;
|
||||||
|
|
||||||
|
import javax.management.DynamicMBean;
|
||||||
import javax.management.InstanceAlreadyExistsException;
|
import javax.management.InstanceAlreadyExistsException;
|
||||||
import javax.management.InstanceNotFoundException;
|
import javax.management.InstanceNotFoundException;
|
||||||
import javax.management.MBeanServer;
|
import javax.management.MBeanServer;
|
||||||
@ -42,7 +43,9 @@ import sun.util.logging.LoggingSupport;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import com.sun.management.DiagnosticCommandMBean;
|
||||||
import com.sun.management.OSMBeanFactory;
|
import com.sun.management.OSMBeanFactory;
|
||||||
import com.sun.management.HotSpotDiagnosticMXBean;
|
import com.sun.management.HotSpotDiagnosticMXBean;
|
||||||
|
|
||||||
@ -263,6 +266,7 @@ public class ManagementFactoryHelper {
|
|||||||
private static HotspotThread hsThreadMBean = null;
|
private static HotspotThread hsThreadMBean = null;
|
||||||
private static HotspotCompilation hsCompileMBean = null;
|
private static HotspotCompilation hsCompileMBean = null;
|
||||||
private static HotspotMemory hsMemoryMBean = null;
|
private static HotspotMemory hsMemoryMBean = null;
|
||||||
|
private static DiagnosticCommandImpl hsDiagCommandMBean = null;
|
||||||
|
|
||||||
public static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() {
|
public static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() {
|
||||||
if (hsDiagMBean == null) {
|
if (hsDiagMBean == null) {
|
||||||
@ -311,6 +315,14 @@ public class ManagementFactoryHelper {
|
|||||||
return hsMemoryMBean;
|
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.
|
* This method is for testing only.
|
||||||
*/
|
*/
|
||||||
@ -365,6 +377,18 @@ public class ManagementFactoryHelper {
|
|||||||
private final static String HOTSPOT_THREAD_MBEAN_NAME =
|
private final static String HOTSPOT_THREAD_MBEAN_NAME =
|
||||||
"sun.management:type=HotspotThreading";
|
"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) {
|
static void registerInternalMBeans(MBeanServer mbs) {
|
||||||
// register all internal MBeans if not registered
|
// register all internal MBeans if not registered
|
||||||
// No exception is thrown if a MBean with that object name
|
// 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -46,6 +46,7 @@ public interface VMManagement {
|
|||||||
public boolean isThreadAllocatedMemorySupported();
|
public boolean isThreadAllocatedMemorySupported();
|
||||||
public boolean isThreadAllocatedMemoryEnabled();
|
public boolean isThreadAllocatedMemoryEnabled();
|
||||||
public boolean isGcNotificationSupported();
|
public boolean isGcNotificationSupported();
|
||||||
|
public boolean isRemoteDiagnosticCommandsSupported();
|
||||||
|
|
||||||
// Class Loading Subsystem
|
// Class Loading Subsystem
|
||||||
public long getTotalClassCount();
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -57,6 +57,7 @@ class VMManagementImpl implements VMManagement {
|
|||||||
private static boolean synchronizerUsageSupport;
|
private static boolean synchronizerUsageSupport;
|
||||||
private static boolean threadAllocatedMemorySupport;
|
private static boolean threadAllocatedMemorySupport;
|
||||||
private static boolean gcNotificationSupport;
|
private static boolean gcNotificationSupport;
|
||||||
|
private static boolean remoteDiagnosticCommandsSupport;
|
||||||
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -106,6 +107,10 @@ class VMManagementImpl implements VMManagement {
|
|||||||
return gcNotificationSupport;
|
return gcNotificationSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isRemoteDiagnosticCommandsSupported() {
|
||||||
|
return remoteDiagnosticCommandsSupport;
|
||||||
|
}
|
||||||
|
|
||||||
public native boolean isThreadContentionMonitoringEnabled();
|
public native boolean isThreadContentionMonitoringEnabled();
|
||||||
public native boolean isThreadCpuTimeEnabled();
|
public native boolean isThreadCpuTimeEnabled();
|
||||||
public native boolean isThreadAllocatedMemoryEnabled();
|
public native boolean isThreadAllocatedMemoryEnabled();
|
||||||
|
@ -60,9 +60,12 @@ public final class JdpPacketWriter {
|
|||||||
*/
|
*/
|
||||||
public void addEntry(String entry)
|
public void addEntry(String entry)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
pkt.writeShort(entry.length());
|
/* DataOutputStream.writeUTF() do essentially
|
||||||
byte[] b = entry.getBytes("UTF-8");
|
* the same as:
|
||||||
pkt.write(b);
|
* 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;
|
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
|
* @since 1.8
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@ -39,7 +74,10 @@ import java.lang.annotation.Target;
|
|||||||
public @interface Contended {
|
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 "";
|
String value() default "";
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
package sun.misc;
|
package sun.misc;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hashing utilities.
|
* Hashing utilities.
|
||||||
@ -207,28 +207,16 @@ public class Hashing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds references to things that can't be initialized until after VM
|
* Return a non-zero 32-bit pseudo random value. The {@code instance} object
|
||||||
* is fully booted.
|
* 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) {
|
public static int randomHashSeed(Object instance) {
|
||||||
int seed;
|
int seed;
|
||||||
if (sun.misc.VM.isBooted()) {
|
if (sun.misc.VM.isBooted()) {
|
||||||
seed = Holder.SEED_MAKER.nextInt();
|
seed = ThreadLocalRandom.current().nextInt();
|
||||||
} else {
|
} else {
|
||||||
// lower quality "random" seed value--still better than zero and not
|
// lower quality "random" seed value--still better than zero and not
|
||||||
// not practically reversible.
|
// not practically reversible.
|
||||||
|
@ -3158,6 +3158,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
|||||||
private boolean marked = false;
|
private boolean marked = false;
|
||||||
private int inCache = 0;
|
private int inCache = 0;
|
||||||
private int markCount = 0;
|
private int markCount = 0;
|
||||||
|
private boolean closed; // false
|
||||||
|
|
||||||
public HttpInputStream (InputStream is) {
|
public HttpInputStream (InputStream is) {
|
||||||
super (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
|
@Override
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
|
ensureOpen();
|
||||||
try {
|
try {
|
||||||
byte[] b = new byte[1];
|
byte[] b = new byte[1];
|
||||||
int ret = read(b);
|
int ret = read(b);
|
||||||
@ -3254,6 +3261,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] b, int off, int len) throws IOException {
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
|
ensureOpen();
|
||||||
try {
|
try {
|
||||||
int newLen = super.read(b, off, len);
|
int newLen = super.read(b, off, len);
|
||||||
int nWrite;
|
int nWrite;
|
||||||
@ -3291,7 +3299,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long skip (long n) throws IOException {
|
public long skip (long n) throws IOException {
|
||||||
|
ensureOpen();
|
||||||
long remaining = n;
|
long remaining = n;
|
||||||
int nr;
|
int nr;
|
||||||
if (skipBuffer == null)
|
if (skipBuffer == null)
|
||||||
@ -3317,6 +3325,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close () throws IOException {
|
public void close () throws IOException {
|
||||||
|
if (closed)
|
||||||
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (outputStream != null) {
|
if (outputStream != null) {
|
||||||
if (read() != -1) {
|
if (read() != -1) {
|
||||||
@ -3332,6 +3343,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
|||||||
}
|
}
|
||||||
throw ioex;
|
throw ioex;
|
||||||
} finally {
|
} finally {
|
||||||
|
closed = true;
|
||||||
HttpURLConnection.this.http = null;
|
HttpURLConnection.this.http = null;
|
||||||
checkResponseCredentials (true);
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -330,7 +330,7 @@ final class P11KeyAgreement extends KeyAgreementSpi {
|
|||||||
// as here we always retrieve the CKA_VALUE even for tokens
|
// as here we always retrieve the CKA_VALUE even for tokens
|
||||||
// that do not have that bug.
|
// that do not have that bug.
|
||||||
byte[] keyBytes = key.getEncoded();
|
byte[] keyBytes = key.getEncoded();
|
||||||
byte[] newBytes = P11Util.trimZeroes(keyBytes);
|
byte[] newBytes = KeyUtil.trimZeroes(keyBytes);
|
||||||
if (keyBytes != newBytes) {
|
if (keyBytes != newBytes) {
|
||||||
key = new SecretKeySpec(newBytes, algorithm);
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -41,6 +41,7 @@ import sun.security.rsa.RSAPadding;
|
|||||||
|
|
||||||
import sun.security.pkcs11.wrapper.*;
|
import sun.security.pkcs11.wrapper.*;
|
||||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||||
|
import sun.security.util.KeyUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signature implementation class. This class currently supports the
|
* Signature implementation class. This class currently supports the
|
||||||
@ -697,8 +698,8 @@ final class P11Signature extends SignatureSpi {
|
|||||||
BigInteger r = values[0].getPositiveBigInteger();
|
BigInteger r = values[0].getPositiveBigInteger();
|
||||||
BigInteger s = values[1].getPositiveBigInteger();
|
BigInteger s = values[1].getPositiveBigInteger();
|
||||||
// trim leading zeroes
|
// trim leading zeroes
|
||||||
byte[] br = P11Util.trimZeroes(r.toByteArray());
|
byte[] br = KeyUtil.trimZeroes(r.toByteArray());
|
||||||
byte[] bs = P11Util.trimZeroes(s.toByteArray());
|
byte[] bs = KeyUtil.trimZeroes(s.toByteArray());
|
||||||
int k = Math.max(br.length, bs.length);
|
int k = Math.max(br.length, bs.length);
|
||||||
// r and s each occupy half the array
|
// r and s each occupy half the array
|
||||||
byte[] res = new byte[k << 1];
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -131,20 +131,6 @@ public final class P11Util {
|
|||||||
return b;
|
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) {
|
public static byte[] getMagnitude(BigInteger bi) {
|
||||||
byte[] b = bi.toByteArray();
|
byte[] b = bi.toByteArray();
|
||||||
if ((b.length > 1) && (b[0] == 0)) {
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -200,5 +200,24 @@ public final class KeyUtil {
|
|||||||
|
|
||||||
// Don't bother to check against the y^q mod p if safe primes are used.
|
// 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,
|
Math.min(99F,
|
||||||
elapsedCpu / (elapsedTime * 10000F * result.nCPUs));
|
elapsedCpu / (elapsedTime * 10000F * result.nCPUs));
|
||||||
|
|
||||||
|
cpuUsage = Math.max(0F, cpuUsage);
|
||||||
|
|
||||||
getPlotter().addValues(result.timeStamp,
|
getPlotter().addValues(result.timeStamp,
|
||||||
Math.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS)));
|
Math.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS)));
|
||||||
getInfoLabel().setText(Resources.format(Messages.CPU_USAGE_FORMAT,
|
getInfoLabel().setText(Resources.format(Messages.CPU_USAGE_FORMAT,
|
||||||
|
@ -25,6 +25,11 @@
|
|||||||
|
|
||||||
package sun.util.locale.provider;
|
package sun.util.locale.provider;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FallbackProviderAdapter implementation.
|
* FallbackProviderAdapter implementation.
|
||||||
*
|
*
|
||||||
@ -32,6 +37,18 @@ package sun.util.locale.provider;
|
|||||||
*/
|
*/
|
||||||
public class FallbackLocaleProviderAdapter extends JRELocaleProviderAdapter {
|
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
|
* Returns the type of this LocaleProviderAdapter
|
||||||
*/
|
*/
|
||||||
@ -39,4 +56,14 @@ public class FallbackLocaleProviderAdapter extends JRELocaleProviderAdapter {
|
|||||||
public LocaleProviderAdapter.Type getAdapterType() {
|
public LocaleProviderAdapter.Type getAdapterType() {
|
||||||
return Type.FALLBACK;
|
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.DateFormatSymbolsProvider;
|
||||||
import java.text.spi.DecimalFormatSymbolsProvider;
|
import java.text.spi.DecimalFormatSymbolsProvider;
|
||||||
import java.text.spi.NumberFormatProvider;
|
import java.text.spi.NumberFormatProvider;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.spi.CalendarDataProvider;
|
import java.util.spi.CalendarDataProvider;
|
||||||
|
@ -119,6 +119,12 @@ public abstract class LocaleProviderAdapter {
|
|||||||
*/
|
*/
|
||||||
private static LocaleProviderAdapter fallbackLocaleProviderAdapter = null;
|
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.
|
* Adapter lookup cache.
|
||||||
*/
|
*/
|
||||||
@ -140,13 +146,19 @@ public abstract class LocaleProviderAdapter {
|
|||||||
// load adapter if necessary
|
// load adapter if necessary
|
||||||
switch (aType) {
|
switch (aType) {
|
||||||
case CLDR:
|
case CLDR:
|
||||||
cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter();
|
if (cldrLocaleProviderAdapter == null) {
|
||||||
|
cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case HOST:
|
case HOST:
|
||||||
hostLocaleProviderAdapter = new HostLocaleProviderAdapter();
|
if (hostLocaleProviderAdapter == null) {
|
||||||
|
hostLocaleProviderAdapter = new HostLocaleProviderAdapter();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
typeList.add(aType);
|
if (!typeList.contains(aType)) {
|
||||||
|
typeList.add(aType);
|
||||||
|
}
|
||||||
} catch (IllegalArgumentException | UnsupportedOperationException e) {
|
} catch (IllegalArgumentException | UnsupportedOperationException e) {
|
||||||
// could be caused by the user specifying wrong
|
// could be caused by the user specifying wrong
|
||||||
// provider name or format in the system property
|
// provider name or format in the system property
|
||||||
@ -160,11 +172,15 @@ public abstract class LocaleProviderAdapter {
|
|||||||
// Append FALLBACK as the last resort.
|
// Append FALLBACK as the last resort.
|
||||||
fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter();
|
fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter();
|
||||||
typeList.add(Type.FALLBACK);
|
typeList.add(Type.FALLBACK);
|
||||||
|
defaultLocaleProviderAdapter = Type.FALLBACK;
|
||||||
|
} else {
|
||||||
|
defaultLocaleProviderAdapter = Type.JRE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Default preference list
|
// Default preference list
|
||||||
typeList.add(Type.JRE);
|
typeList.add(Type.JRE);
|
||||||
typeList.add(Type.SPI);
|
typeList.add(Type.SPI);
|
||||||
|
defaultLocaleProviderAdapter = Type.JRE;
|
||||||
}
|
}
|
||||||
|
|
||||||
adapterPreference = Collections.unmodifiableList(typeList);
|
adapterPreference = Collections.unmodifiableList(typeList);
|
||||||
|
@ -127,32 +127,13 @@ public final class LocaleServiceProviderPool {
|
|||||||
private LocaleServiceProviderPool (final Class<? extends LocaleServiceProvider> c) {
|
private LocaleServiceProviderPool (final Class<? extends LocaleServiceProvider> c) {
|
||||||
providerClass = c;
|
providerClass = c;
|
||||||
|
|
||||||
// Add the JRE Locale Data Adapter implementation.
|
for (LocaleProviderAdapter.Type type : LocaleProviderAdapter.getAdapterPreference()) {
|
||||||
providers.putIfAbsent(LocaleProviderAdapter.Type.JRE,
|
LocaleProviderAdapter lda = LocaleProviderAdapter.forType(type);
|
||||||
LocaleProviderAdapter.forJRE().getLocaleServiceProvider(c));
|
if (lda != null) {
|
||||||
|
LocaleServiceProvider provider = lda.getLocaleServiceProvider(c);
|
||||||
// Add the SPI Locale Data Adapter implementation.
|
if (provider != null) {
|
||||||
LocaleProviderAdapter lda = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.SPI);
|
providers.putIfAbsent(type, provider);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,7 +227,8 @@ public final class LocaleServiceProviderPool {
|
|||||||
*/
|
*/
|
||||||
boolean hasProviders() {
|
boolean hasProviders() {
|
||||||
return providers.size() != 1 ||
|
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,
|
// Check whether JRE is the sole locale data provider or not,
|
||||||
// and directly call it if it is.
|
// and directly call it if it is.
|
||||||
if (!hasProviders()) {
|
if (!hasProviders()) {
|
||||||
return getter.getObject(
|
return getter.getObject((P)providers.get(LocaleProviderAdapter.defaultLocaleProviderAdapter),
|
||||||
(P)providers.get(LocaleProviderAdapter.Type.JRE),
|
locale, key, params);
|
||||||
locale, key, params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Locale> lookupLocales = getLookupLocales(locale);
|
List<Locale> lookupLocales = getLookupLocales(locale);
|
||||||
|
@ -1818,7 +1818,7 @@ public class ZipFileSystem extends FileSystem {
|
|||||||
|
|
||||||
Entry(byte[] name) {
|
Entry(byte[] name) {
|
||||||
name(name);
|
name(name);
|
||||||
this.mtime = System.currentTimeMillis();
|
this.mtime = this.ctime = this.atime = System.currentTimeMillis();
|
||||||
this.crc = 0;
|
this.crc = 0;
|
||||||
this.size = 0;
|
this.size = 0;
|
||||||
this.csize = 0;
|
this.csize = 0;
|
||||||
@ -1912,17 +1912,18 @@ public class ZipFileSystem extends FileSystem {
|
|||||||
{
|
{
|
||||||
int written = CENHDR;
|
int written = CENHDR;
|
||||||
int version0 = version();
|
int version0 = version();
|
||||||
|
|
||||||
long csize0 = csize;
|
long csize0 = csize;
|
||||||
long size0 = size;
|
long size0 = size;
|
||||||
long locoff0 = locoff;
|
long locoff0 = locoff;
|
||||||
int elen64 = 0; // extra for ZIP64
|
int elen64 = 0; // extra for ZIP64
|
||||||
int elenNTFS = 0; // extra for NTFS (a/c/mtime)
|
int elenNTFS = 0; // extra for NTFS (a/c/mtime)
|
||||||
int elenEXTT = 0; // extra for Extended Timestamp
|
int elenEXTT = 0; // extra for Extended Timestamp
|
||||||
|
boolean foundExtraTime = false; // if time stamp NTFS, EXTT present
|
||||||
|
|
||||||
// confirm size/length
|
// confirm size/length
|
||||||
int nlen = (name != null) ? name.length : 0;
|
int nlen = (name != null) ? name.length : 0;
|
||||||
int elen = (extra != null) ? extra.length : 0;
|
int elen = (extra != null) ? extra.length : 0;
|
||||||
|
int eoff = 0;
|
||||||
int clen = (comment != null) ? comment.length : 0;
|
int clen = (comment != null) ? comment.length : 0;
|
||||||
if (csize >= ZIP64_MINVAL) {
|
if (csize >= ZIP64_MINVAL) {
|
||||||
csize0 = ZIP64_MINVAL;
|
csize0 = ZIP64_MINVAL;
|
||||||
@ -1936,14 +1937,24 @@ public class ZipFileSystem extends FileSystem {
|
|||||||
locoff0 = ZIP64_MINVAL;
|
locoff0 = ZIP64_MINVAL;
|
||||||
elen64 += 8; // offset(8)
|
elen64 += 8; // offset(8)
|
||||||
}
|
}
|
||||||
if (elen64 != 0)
|
if (elen64 != 0) {
|
||||||
elen64 += 4; // header and data sz 4 bytes
|
elen64 += 4; // header and data sz 4 bytes
|
||||||
|
}
|
||||||
|
|
||||||
if (atime != -1) {
|
while (eoff + 4 < elen) {
|
||||||
if (isWindows) // use NTFS
|
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
|
elenNTFS = 36; // total 36 bytes
|
||||||
else // Extended Timestamp otherwise
|
} else { // Extended Timestamp otherwise
|
||||||
elenEXTT = 9; // only mtime in cen
|
elenEXTT = 9; // only mtime in cen
|
||||||
|
}
|
||||||
}
|
}
|
||||||
writeInt(os, CENSIG); // CEN header signature
|
writeInt(os, CENSIG); // CEN header signature
|
||||||
if (elen64 != 0) {
|
if (elen64 != 0) {
|
||||||
@ -2092,11 +2103,13 @@ public class ZipFileSystem extends FileSystem {
|
|||||||
{
|
{
|
||||||
writeInt(os, LOCSIG); // LOC header signature
|
writeInt(os, LOCSIG); // LOC header signature
|
||||||
int version = version();
|
int version = version();
|
||||||
|
|
||||||
int nlen = (name != null) ? name.length : 0;
|
int nlen = (name != null) ? name.length : 0;
|
||||||
int elen = (extra != null) ? extra.length : 0;
|
int elen = (extra != null) ? extra.length : 0;
|
||||||
|
boolean foundExtraTime = false; // if extra timestamp present
|
||||||
|
int eoff = 0;
|
||||||
int elen64 = 0;
|
int elen64 = 0;
|
||||||
int elenEXTT = 0;
|
int elenEXTT = 0;
|
||||||
|
int elenNTFS = 0;
|
||||||
if ((flag & FLAG_DATADESCR) != 0) {
|
if ((flag & FLAG_DATADESCR) != 0) {
|
||||||
writeShort(os, version()); // version needed to extract
|
writeShort(os, version()); // version needed to extract
|
||||||
writeShort(os, flag); // general purpose bit flag
|
writeShort(os, flag); // general purpose bit flag
|
||||||
@ -2128,14 +2141,27 @@ public class ZipFileSystem extends FileSystem {
|
|||||||
writeInt(os, size); // uncompressed size
|
writeInt(os, size); // uncompressed size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (atime != -1 && !isWindows) { // on unix use "ext time"
|
while (eoff + 4 < elen) {
|
||||||
if (ctime == -1)
|
int tag = SH(extra, eoff);
|
||||||
elenEXTT = 13;
|
int sz = SH(extra, eoff + 2);
|
||||||
else
|
if (tag == EXTID_EXTT || tag == EXTID_NTFS) {
|
||||||
elenEXTT = 17;
|
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, name.length);
|
||||||
writeShort(os, elen + elen64 + elenEXTT);
|
writeShort(os, elen + elen64 + elenNTFS + elenEXTT);
|
||||||
writeBytes(os, name);
|
writeBytes(os, name);
|
||||||
if (elen64 != 0) {
|
if (elen64 != 0) {
|
||||||
writeShort(os, EXTID_ZIP64);
|
writeShort(os, EXTID_ZIP64);
|
||||||
@ -2143,15 +2169,28 @@ public class ZipFileSystem extends FileSystem {
|
|||||||
writeLong(os, size);
|
writeLong(os, size);
|
||||||
writeLong(os, csize);
|
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) {
|
if (elenEXTT != 0) {
|
||||||
writeShort(os, EXTID_EXTT);
|
writeShort(os, EXTID_EXTT);
|
||||||
writeShort(os, elenEXTT - 4);// size for the folowing data block
|
writeShort(os, elenEXTT - 4);// size for the folowing data block
|
||||||
if (ctime == -1)
|
int fbyte = 0x1;
|
||||||
os.write(0x3); // mtime and atime
|
if (atime != -1) // mtime and atime
|
||||||
else
|
fbyte |= 0x2;
|
||||||
os.write(0x7); // mtime, atime and ctime
|
if (ctime != -1) // mtime, atime and ctime
|
||||||
|
fbyte |= 0x4;
|
||||||
|
os.write(fbyte); // flags byte
|
||||||
writeInt(os, javaToUnixTime(mtime));
|
writeInt(os, javaToUnixTime(mtime));
|
||||||
writeInt(os, javaToUnixTime(atime));
|
if (atime != -1)
|
||||||
|
writeInt(os, javaToUnixTime(atime));
|
||||||
if (ctime != -1)
|
if (ctime != -1)
|
||||||
writeInt(os, javaToUnixTime(ctime));
|
writeInt(os, javaToUnixTime(ctime));
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ public class ZipInfo {
|
|||||||
winToJavaTime(LL(extra, off + 24)));
|
winToJavaTime(LL(extra, off + 24)));
|
||||||
break;
|
break;
|
||||||
case EXTID_EXTT:
|
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 ;
|
pos = off + 1 ;
|
||||||
while (pos + 4 <= off + sz) {
|
while (pos + 4 <= off + sz) {
|
||||||
print(" *%tc%n",
|
print(" *%tc%n",
|
||||||
@ -223,6 +223,7 @@ public class ZipInfo {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
print(" ->[tag=%x, size=%d]%n", tag, sz);
|
||||||
}
|
}
|
||||||
off += 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -49,7 +49,8 @@ enum {
|
|||||||
JMM_VERSION_1_1 = 0x20010100, // JDK 6
|
JMM_VERSION_1_1 = 0x20010100, // JDK 6
|
||||||
JMM_VERSION_1_2 = 0x20010200, // JDK 7
|
JMM_VERSION_1_2 = 0x20010200, // JDK 7
|
||||||
JMM_VERSION_1_2_1 = 0x20010201, // JDK 7 GA
|
JMM_VERSION_1_2_1 = 0x20010201, // JDK 7 GA
|
||||||
JMM_VERSION = 0x20010202
|
JMM_VERSION_1_2_2 = 0x20010202,
|
||||||
|
JMM_VERSION = 0x20010203
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -62,7 +63,8 @@ typedef struct {
|
|||||||
unsigned int isObjectMonitorUsageSupported : 1;
|
unsigned int isObjectMonitorUsageSupported : 1;
|
||||||
unsigned int isSynchronizerUsageSupported : 1;
|
unsigned int isSynchronizerUsageSupported : 1;
|
||||||
unsigned int isThreadAllocatedMemorySupported : 1;
|
unsigned int isThreadAllocatedMemorySupported : 1;
|
||||||
unsigned int : 23;
|
unsigned int isRemoteDiagnosticCommandsSupported : 1;
|
||||||
|
unsigned int : 22;
|
||||||
} jmmOptionalSupport;
|
} jmmOptionalSupport;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -190,21 +192,27 @@ typedef struct {
|
|||||||
} jmmGCStat;
|
} jmmGCStat;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char* name;
|
const char* name; /* Name of the diagnostic command */
|
||||||
const char* description;
|
const char* description; /* Short description */
|
||||||
const char* impact;
|
const char* impact; /* Impact on the JVM */
|
||||||
int num_arguments;
|
const char* permission_class; /* Class name of the required permission if any */
|
||||||
jboolean enabled;
|
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;
|
} dcmdInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char* name;
|
const char* name; /* Option/Argument name*/
|
||||||
const char* description;
|
const char* description; /* Short description */
|
||||||
const char* type;
|
const char* type; /* Type: STRING, BOOLEAN, etc. */
|
||||||
const char* default_string;
|
const char* default_string; /* Default value in a parsable string */
|
||||||
jboolean mandatory;
|
jboolean mandatory; /* True if the option/argument is mandatory */
|
||||||
jboolean option;
|
jboolean option; /* True if it is an option, false if it is an argument */
|
||||||
int position;
|
/* (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;
|
} dcmdArgInfo;
|
||||||
|
|
||||||
typedef struct jmmInterface_1_ {
|
typedef struct jmmInterface_1_ {
|
||||||
@ -327,6 +335,9 @@ typedef struct jmmInterface_1_ {
|
|||||||
jstring (JNICALL *ExecuteDiagnosticCommand)
|
jstring (JNICALL *ExecuteDiagnosticCommand)
|
||||||
(JNIEnv *env,
|
(JNIEnv *env,
|
||||||
jstring command);
|
jstring command);
|
||||||
|
void (JNICALL *SetDiagnosticFrameworkNotificationEnabled)
|
||||||
|
(JNIEnv *env,
|
||||||
|
jboolean enabled);
|
||||||
} JmmInterface;
|
} JmmInterface;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,6 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "jvm.h"
|
#include "jvm.h"
|
||||||
#include "management.h"
|
#include "management.h"
|
||||||
#include "sun_management_VMManagementImpl.h"
|
#include "sun_management_VMManagementImpl.h"
|
||||||
@ -96,6 +97,9 @@ Java_sun_management_VMManagementImpl_initOptionalSupportFields
|
|||||||
value = mos.isThreadAllocatedMemorySupported;
|
value = mos.isThreadAllocatedMemorySupported;
|
||||||
setStaticBooleanField(env, cls, "threadAllocatedMemorySupport", value);
|
setStaticBooleanField(env, cls, "threadAllocatedMemorySupport", value);
|
||||||
|
|
||||||
|
value = mos.isRemoteDiagnosticCommandsSupported;
|
||||||
|
setStaticBooleanField(env, cls, "remoteDiagnosticCommandsSupport", value);
|
||||||
|
|
||||||
if ((jmm_version > JMM_VERSION_1_2) ||
|
if ((jmm_version > JMM_VERSION_1_2) ||
|
||||||
(jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF) >= 1))) {
|
(jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF) >= 1))) {
|
||||||
setStaticBooleanField(env, cls, "gcNotificationSupport", JNI_TRUE);
|
setStaticBooleanField(env, cls, "gcNotificationSupport", JNI_TRUE);
|
||||||
|
@ -649,9 +649,9 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
|||||||
&& (dmpath == NULL) /* data model specific variables not set */
|
&& (dmpath == NULL) /* data model specific variables not set */
|
||||||
#endif /* __solaris__ */
|
#endif /* __solaris__ */
|
||||||
) {
|
) {
|
||||||
|
JLI_MemFree(newargv);
|
||||||
|
JLI_MemFree(new_runpath);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -935,7 +935,7 @@ SetExecname(char **argv)
|
|||||||
char buf[PATH_MAX+1];
|
char buf[PATH_MAX+1];
|
||||||
int len = readlink(self, buf, PATH_MAX);
|
int len = readlink(self, buf, PATH_MAX);
|
||||||
if (len >= 0) {
|
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);
|
exec_path = JLI_StringDup(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,9 +658,9 @@ jobject createNetworkInterface(JNIEnv *env, netif *ifs) {
|
|||||||
if (ia2Obj) {
|
if (ia2Obj) {
|
||||||
setInetAddress_addr(env, ia2Obj, htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
|
setInetAddress_addr(env, ia2Obj, htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
|
||||||
(*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj);
|
(*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj);
|
||||||
(*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask);
|
||||||
(*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj);
|
(*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -887,15 +887,12 @@ netif *addif(JNIEnv *env, int sock, const char * if_name,
|
|||||||
addrP->mask = prefix;
|
addrP->mask = prefix;
|
||||||
addrP->next = 0;
|
addrP->next = 0;
|
||||||
if (family == AF_INET) {
|
if (family == AF_INET) {
|
||||||
/*
|
// Deal with broadcast addr & subnet mask
|
||||||
* Deal with broadcast addr & subnet mask
|
|
||||||
*/
|
|
||||||
struct sockaddr * brdcast_to = (struct sockaddr *) ((char *) addrP + sizeof(netaddr) + addr_size);
|
struct sockaddr * brdcast_to = (struct sockaddr *) ((char *) addrP + sizeof(netaddr) + addr_size);
|
||||||
addrP->brdcast = getBroadcast(env, sock, name, brdcast_to );
|
addrP->brdcast = getBroadcast(env, sock, name, brdcast_to );
|
||||||
|
|
||||||
if (addrP->brdcast && (mask = getSubnet(env, sock, name)) != -1) {
|
if ((mask = getSubnet(env, sock, name)) != -1)
|
||||||
addrP->mask = mask;
|
addrP->mask = mask;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -185,7 +185,6 @@ extern char *XSetIMValues(
|
|||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XAWT_HACK
|
|
||||||
/*
|
/*
|
||||||
* This function is stolen from /src/solaris/hpi/src/system_md.c
|
* This function is stolen from /src/solaris/hpi/src/system_md.c
|
||||||
* It is used in setting the time in Java-level InputEvents
|
* It is used in setting the time in Java-level InputEvents
|
||||||
@ -197,7 +196,6 @@ awt_util_nowMillisUTC()
|
|||||||
gettimeofday(&t, NULL);
|
gettimeofday(&t, NULL);
|
||||||
return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
|
return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
|
||||||
}
|
}
|
||||||
#endif /* XAWT_HACK */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Converts the wchar_t string to a multi-byte string calling wcstombs(). A
|
* Converts the wchar_t string to a multi-byte string calling wcstombs(). A
|
||||||
@ -546,11 +544,7 @@ awt_x11inputmethod_lookupString(XKeyPressedEvent *event, KeySym *keysymp)
|
|||||||
"dispatchCommittedText",
|
"dispatchCommittedText",
|
||||||
"(Ljava/lang/String;J)V",
|
"(Ljava/lang/String;J)V",
|
||||||
javastr,
|
javastr,
|
||||||
#ifndef XAWT_HACK
|
|
||||||
awt_util_nowMillisUTC_offset(event->time));
|
|
||||||
#else
|
|
||||||
event->time);
|
event->time);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -48,7 +48,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
import java.util.spi.CalendarDataProvider;
|
import java.util.spi.CalendarDataProvider;
|
||||||
import java.util.spi.CalendarNameProvider;
|
|
||||||
import java.util.spi.CurrencyNameProvider;
|
import java.util.spi.CurrencyNameProvider;
|
||||||
import java.util.spi.LocaleNameProvider;
|
import java.util.spi.LocaleNameProvider;
|
||||||
import sun.util.spi.CalendarProvider;
|
import sun.util.spi.CalendarProvider;
|
||||||
@ -364,32 +363,6 @@ public class HostLocaleProviderAdapterImpl {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CalendarNameProvider getCalendarNameProvider() {
|
|
||||||
return new CalendarNameProvider() {
|
|
||||||
@Override
|
|
||||||
public Locale[] getAvailableLocales() {
|
|
||||||
return getSupportedCalendarLocales();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSupportedLocale(Locale locale) {
|
|
||||||
return isSupportedCalendarLocale(locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDisplayName(String calType, int field, int value,
|
|
||||||
int style, Locale locale) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Integer> getDisplayNames(String calType,
|
|
||||||
int field, int style, Locale locale) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CalendarProvider getCalendarProvider() {
|
public static CalendarProvider getCalendarProvider() {
|
||||||
return new CalendarProvider() {
|
return new CalendarProvider() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -256,14 +256,14 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketRece
|
|||||||
packetBuffer = (*env)->GetObjectField(env, dpObj, dp_bufID);
|
packetBuffer = (*env)->GetObjectField(env, dpObj, dp_bufID);
|
||||||
packetBufferOffset = (*env)->GetIntField(env, dpObj, dp_offsetID);
|
packetBufferOffset = (*env)->GetIntField(env, dpObj, dp_offsetID);
|
||||||
packetBufferLen = (*env)->GetIntField(env, dpObj, dp_bufLengthID);
|
packetBufferLen = (*env)->GetIntField(env, dpObj, dp_bufLengthID);
|
||||||
|
/* Note: the buffer needn't be greater than 65,536 (0xFFFF)
|
||||||
|
* the max size of an IP packet. Anything bigger is truncated anyway.
|
||||||
|
*/
|
||||||
|
if (packetBufferLen > MAX_PACKET_LEN) {
|
||||||
|
packetBufferLen = MAX_PACKET_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
if (packetBufferLen > MAX_BUFFER_LEN) {
|
if (packetBufferLen > MAX_BUFFER_LEN) {
|
||||||
/* Note: the buffer needn't be greater than 65,536 (0xFFFF)
|
|
||||||
* the max size of an IP packet. Anything bigger is truncated anyway.
|
|
||||||
*/
|
|
||||||
if (packetBufferLen > MAX_PACKET_LEN) {
|
|
||||||
packetBufferLen = MAX_PACKET_LEN;
|
|
||||||
}
|
|
||||||
fullPacket = (char *)malloc(packetBufferLen);
|
fullPacket = (char *)malloc(packetBufferLen);
|
||||||
if (!fullPacket) {
|
if (!fullPacket) {
|
||||||
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
|
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
|
||||||
|
@ -145,7 +145,7 @@ static int getFD1(JNIEnv *env, jobject this) {
|
|||||||
/*
|
/*
|
||||||
* This function returns JNI_TRUE if the datagram size exceeds the underlying
|
* This function returns JNI_TRUE if the datagram size exceeds the underlying
|
||||||
* provider's ability to send to the target address. The following OS
|
* provider's ability to send to the target address. The following OS
|
||||||
* oddies have been observed :-
|
* oddities have been observed :-
|
||||||
*
|
*
|
||||||
* 1. On Windows 95/98 if we try to send a datagram > 12k to an application
|
* 1. On Windows 95/98 if we try to send a datagram > 12k to an application
|
||||||
* on the same machine then the send will fail silently.
|
* on the same machine then the send will fail silently.
|
||||||
@ -218,7 +218,7 @@ jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Step 3: On Windows 95/98 then enumerate the IP addresses on
|
* Step 3: On Windows 95/98 then enumerate the IP addresses on
|
||||||
* this machine. This is necesary because we need to check if the
|
* this machine. This is neccesary because we need to check if the
|
||||||
* datagram is being sent to an application on the same machine.
|
* datagram is being sent to an application on the same machine.
|
||||||
*/
|
*/
|
||||||
if (is95or98) {
|
if (is95or98) {
|
||||||
@ -565,8 +565,8 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_connect0(JNIEnv *env, jobject thi
|
|||||||
|
|
||||||
if (xp_or_later) {
|
if (xp_or_later) {
|
||||||
/* SIO_UDP_CONNRESET fixes a bug introduced in Windows 2000, which
|
/* SIO_UDP_CONNRESET fixes a bug introduced in Windows 2000, which
|
||||||
* returns connection reset errors un connected UDP sockets (as well
|
* returns connection reset errors on connected UDP sockets (as well
|
||||||
* as connected sockets. The solution is to only enable this feature
|
* as connected sockets). The solution is to only enable this feature
|
||||||
* when the socket is connected
|
* when the socket is connected
|
||||||
*/
|
*/
|
||||||
DWORD x1, x2; /* ignored result codes */
|
DWORD x1, x2; /* ignored result codes */
|
||||||
@ -690,6 +690,12 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_send(JNIEnv *env, jobject this,
|
|||||||
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
||||||
|
|
||||||
packetBufferLen = (*env)->GetIntField(env, packet, dp_lengthID);
|
packetBufferLen = (*env)->GetIntField(env, packet, dp_lengthID);
|
||||||
|
/* Note: the buffer needn't be greater than 65,536 (0xFFFF)...
|
||||||
|
* the maximum size of an IP packet. Anything bigger is truncated anyway.
|
||||||
|
*/
|
||||||
|
if (packetBufferLen > MAX_PACKET_LEN) {
|
||||||
|
packetBufferLen = MAX_PACKET_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
if (connected) {
|
if (connected) {
|
||||||
addrp = 0; /* arg to JVM_Sendto () null in this case */
|
addrp = 0; /* arg to JVM_Sendto () null in this case */
|
||||||
@ -728,7 +734,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_send(JNIEnv *env, jobject this,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* When JNI-ifying the JDK's IO routines, we turned
|
/* When JNI-ifying the JDK's IO routines, we turned
|
||||||
* read's and write's of byte arrays of size greater
|
* reads and writes of byte arrays of size greater
|
||||||
* than 2048 bytes into several operations of size 2048.
|
* than 2048 bytes into several operations of size 2048.
|
||||||
* This saves a malloc()/memcpy()/free() for big
|
* This saves a malloc()/memcpy()/free() for big
|
||||||
* buffers. This is OK for file IO and TCP, but that
|
* buffers. This is OK for file IO and TCP, but that
|
||||||
|
@ -122,9 +122,6 @@
|
|||||||
|
|
||||||
# jdk_lang
|
# jdk_lang
|
||||||
|
|
||||||
# 8009615
|
|
||||||
java/lang/instrument/IsModifiableClassAgent.java generic-all
|
|
||||||
|
|
||||||
# 6944188
|
# 6944188
|
||||||
java/lang/management/ThreadMXBean/ThreadStateTest.java generic-all
|
java/lang/management/ThreadMXBean/ThreadStateTest.java generic-all
|
||||||
|
|
||||||
@ -137,6 +134,9 @@ java/lang/management/MemoryMXBean/LowMemoryTest2.sh generic-all
|
|||||||
# 8008200
|
# 8008200
|
||||||
java/lang/Class/asSubclass/BasicUnit.java generic-all
|
java/lang/Class/asSubclass/BasicUnit.java generic-all
|
||||||
|
|
||||||
|
# 8015780
|
||||||
|
java/lang/reflect/Method/GenericStringTest.java generic-all
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
# jdk_management
|
# jdk_management
|
||||||
@ -199,12 +199,6 @@ java/net/MulticastSocket/Test.java macosx-all
|
|||||||
# 7143960
|
# 7143960
|
||||||
java/net/DatagramSocket/SendDatagramToBadAddress.java macosx-all
|
java/net/DatagramSocket/SendDatagramToBadAddress.java macosx-all
|
||||||
|
|
||||||
# 8014720
|
|
||||||
java/net/ResponseCache/B6181108.java generic-all
|
|
||||||
|
|
||||||
# 8014723
|
|
||||||
sun/misc/URLClassPath/ClassnameCharTest.java generic-all
|
|
||||||
|
|
||||||
# 8014719
|
# 8014719
|
||||||
sun/net/www/http/HttpClient/ProxyTest.java generic-all
|
sun/net/www/http/HttpClient/ProxyTest.java generic-all
|
||||||
|
|
||||||
@ -236,9 +230,6 @@ java/nio/channels/DatagramChannel/ChangingAddress.java macosx-all
|
|||||||
# 7132677
|
# 7132677
|
||||||
java/nio/channels/Selector/OutOfBand.java macosx-all
|
java/nio/channels/Selector/OutOfBand.java macosx-all
|
||||||
|
|
||||||
# 8003895
|
|
||||||
java/nio/channels/AsynchronousChannelGroup/Unbounded.java windows-amd64
|
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
# jdk_rmi
|
# jdk_rmi
|
||||||
@ -277,6 +268,13 @@ sun/security/pkcs11/ec/ReadCertificates.java solaris-all
|
|||||||
sun/security/pkcs11/ec/ReadPKCS12.java solaris-all
|
sun/security/pkcs11/ec/ReadPKCS12.java solaris-all
|
||||||
sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java solaris-all
|
sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java solaris-all
|
||||||
|
|
||||||
|
# 8005247
|
||||||
|
sun/security/pkcs11/ec/TestECDSA.java solaris-all
|
||||||
|
|
||||||
|
# 8009438
|
||||||
|
sun/security/pkcs11/Secmod/AddPrivateKey.java linux-all
|
||||||
|
sun/security/pkcs11/Secmod/TrustAnchors.java linux-all
|
||||||
|
|
||||||
# 7041639, Solaris DSA keypair generation bug (Note: jdk_util also affected)
|
# 7041639, Solaris DSA keypair generation bug (Note: jdk_util also affected)
|
||||||
java/security/KeyPairGenerator/SolarisShortDSA.java solaris-all
|
java/security/KeyPairGenerator/SolarisShortDSA.java solaris-all
|
||||||
sun/security/tools/jarsigner/onlymanifest.sh solaris-all
|
sun/security/tools/jarsigner/onlymanifest.sh solaris-all
|
||||||
@ -331,6 +329,8 @@ sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all
|
|||||||
# Tests take too long, on sparcs see 7143279
|
# Tests take too long, on sparcs see 7143279
|
||||||
tools/pack200/CommandLineTests.java solaris-all, macosx-all
|
tools/pack200/CommandLineTests.java solaris-all, macosx-all
|
||||||
tools/pack200/Pack200Test.java solaris-all, macosx-all
|
tools/pack200/Pack200Test.java solaris-all, macosx-all
|
||||||
|
# 8015666
|
||||||
|
tools/pack200/TimeStamp.java generic-all
|
||||||
|
|
||||||
# 8007410
|
# 8007410
|
||||||
tools/launcher/FXLauncherTest.java linux-all
|
tools/launcher/FXLauncherTest.java linux-all
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,8 +23,8 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @bug 4893959
|
* @bug 4893959 8013069
|
||||||
* @summary basic test for HmacPBESHA1
|
* @summary basic test for PBE MAC algorithms.
|
||||||
* @author Valerie Peng
|
* @author Valerie Peng
|
||||||
*/
|
*/
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
@ -68,8 +68,9 @@ public class HmacPBESHA1 {
|
|||||||
}
|
}
|
||||||
Mac mac = Mac.getInstance(algo, PROVIDER);
|
Mac mac = Mac.getInstance(algo, PROVIDER);
|
||||||
byte[] plainText = new byte[30];
|
byte[] plainText = new byte[30];
|
||||||
|
PBEParameterSpec spec =
|
||||||
mac.init(key);
|
new PBEParameterSpec("saltValue".getBytes(), 250);
|
||||||
|
mac.init(key, spec);
|
||||||
mac.update(plainText);
|
mac.update(plainText);
|
||||||
byte[] value1 = mac.doFinal();
|
byte[] value1 = mac.doFinal();
|
||||||
if (value1.length != length) {
|
if (value1.length != length) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2012, 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,12 +23,13 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 7087021
|
* @bug 7087021 8013069
|
||||||
* @summary MacClone
|
* @summary Clone tests for all MAC algorithms.
|
||||||
* @author Jan Luehe
|
* @author Jan Luehe
|
||||||
*/
|
*/
|
||||||
|
import java.security.spec.AlgorithmParameterSpec;
|
||||||
import javax.crypto.*;
|
import javax.crypto.*;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.*;
|
||||||
|
|
||||||
public class MacClone {
|
public class MacClone {
|
||||||
|
|
||||||
@ -39,18 +40,23 @@ public class MacClone {
|
|||||||
KeyGenerator kgen = KeyGenerator.getInstance("DES");
|
KeyGenerator kgen = KeyGenerator.getInstance("DES");
|
||||||
SecretKey skey = kgen.generateKey();
|
SecretKey skey = kgen.generateKey();
|
||||||
for (String algo : algos) {
|
for (String algo : algos) {
|
||||||
doTest(algo, skey);
|
doTest(algo, skey, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] algos2 = { "HmacPBESHA1" };
|
String[] algos2 = { "HmacPBESHA1", "PBEWithHmacSHA1",
|
||||||
|
"PBEWithHmacSHA224", "PBEWithHmacSHA256",
|
||||||
|
"PBEWithHmacSHA384", "PBEWithHmacSHA512" };
|
||||||
skey = new SecretKeySpec("whatever".getBytes(), "PBE");
|
skey = new SecretKeySpec("whatever".getBytes(), "PBE");
|
||||||
|
PBEParameterSpec params =
|
||||||
|
new PBEParameterSpec("1234567890".getBytes(), 500);
|
||||||
for (String algo : algos2) {
|
for (String algo : algos2) {
|
||||||
doTest(algo, skey);
|
doTest(algo, skey, params);
|
||||||
}
|
}
|
||||||
System.out.println("Test Passed");
|
System.out.println("Test Passed");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void doTest(String algo, SecretKey skey) throws Exception {
|
private static void doTest(String algo, SecretKey skey,
|
||||||
|
AlgorithmParameterSpec params) throws Exception {
|
||||||
//
|
//
|
||||||
// Clone an uninitialized Mac object
|
// Clone an uninitialized Mac object
|
||||||
//
|
//
|
||||||
@ -72,7 +78,7 @@ public class MacClone {
|
|||||||
// Clone an initialized Mac object
|
// Clone an initialized Mac object
|
||||||
//
|
//
|
||||||
mac = Mac.getInstance(algo, "SunJCE");
|
mac = Mac.getInstance(algo, "SunJCE");
|
||||||
mac.init(skey);
|
mac.init(skey, params);
|
||||||
macClone = (Mac)mac.clone();
|
macClone = (Mac)mac.clone();
|
||||||
System.out.println(macClone.getProvider().toString());
|
System.out.println(macClone.getProvider().toString());
|
||||||
System.out.println(macClone.getAlgorithm());
|
System.out.println(macClone.getAlgorithm());
|
||||||
|
420
jdk/test/com/sun/crypto/provider/TLS/TestLeadingZeroes.java
Normal file
420
jdk/test/com/sun/crypto/provider/TLS/TestLeadingZeroes.java
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8014618
|
||||||
|
* @summary Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
|
||||||
|
* @author Pasi Eronen
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.security.*;
|
||||||
|
import java.security.spec.*;
|
||||||
|
import java.security.interfaces.*;
|
||||||
|
import javax.crypto.*;
|
||||||
|
import javax.crypto.spec.*;
|
||||||
|
import javax.crypto.interfaces.*;
|
||||||
|
import com.sun.crypto.provider.SunJCE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that leading zeroes are stripped in TlsPremasterSecret case,
|
||||||
|
* but are left as-is in other cases.
|
||||||
|
*
|
||||||
|
* We use pre-generated keypairs, since with randomly generated keypairs,
|
||||||
|
* a leading zero happens only (roughly) 1 out of 256 cases.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TestLeadingZeroes {
|
||||||
|
|
||||||
|
private static final String SUNJCE = "SunJCE";
|
||||||
|
|
||||||
|
private TestLeadingZeroes() {}
|
||||||
|
|
||||||
|
public static void main(String argv[]) throws Exception {
|
||||||
|
// Add JCE to the list of providers
|
||||||
|
SunJCE jce = new SunJCE();
|
||||||
|
Security.addProvider(jce);
|
||||||
|
|
||||||
|
TestLeadingZeroes keyAgree = new TestLeadingZeroes();
|
||||||
|
keyAgree.run();
|
||||||
|
System.out.println("Test Passed");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void run() throws Exception {
|
||||||
|
|
||||||
|
// decode pre-generated keypairs
|
||||||
|
KeyFactory kfac = KeyFactory.getInstance("DH");
|
||||||
|
PublicKey alicePubKey =
|
||||||
|
kfac.generatePublic(new X509EncodedKeySpec(alicePubKeyEnc));
|
||||||
|
PublicKey bobPubKey =
|
||||||
|
kfac.generatePublic(new X509EncodedKeySpec(bobPubKeyEnc));
|
||||||
|
PrivateKey alicePrivKey =
|
||||||
|
kfac.generatePrivate(new PKCS8EncodedKeySpec(alicePrivKeyEnc));
|
||||||
|
PrivateKey bobPrivKey =
|
||||||
|
kfac.generatePrivate(new PKCS8EncodedKeySpec(bobPrivKeyEnc));
|
||||||
|
|
||||||
|
// generate normal shared secret
|
||||||
|
KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH", SUNJCE);
|
||||||
|
aliceKeyAgree.init(alicePrivKey);
|
||||||
|
aliceKeyAgree.doPhase(bobPubKey, true);
|
||||||
|
byte[] sharedSecret = aliceKeyAgree.generateSecret();
|
||||||
|
System.out.println("shared secret:\n" + toHexString(sharedSecret));
|
||||||
|
|
||||||
|
// verify that leading zero is present
|
||||||
|
if (sharedSecret.length != 128) {
|
||||||
|
throw new Exception("Unexpected shared secret length");
|
||||||
|
}
|
||||||
|
if (sharedSecret[0] != 0) {
|
||||||
|
throw new Exception("First byte is not zero as expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
// now, test TLS premaster secret
|
||||||
|
aliceKeyAgree.init(alicePrivKey);
|
||||||
|
aliceKeyAgree.doPhase(bobPubKey, true);
|
||||||
|
byte[] tlsPremasterSecret =
|
||||||
|
aliceKeyAgree.generateSecret("TlsPremasterSecret").getEncoded();
|
||||||
|
System.out.println(
|
||||||
|
"tls premaster secret:\n" + toHexString(tlsPremasterSecret));
|
||||||
|
|
||||||
|
// check that leading zero has been stripped
|
||||||
|
if (tlsPremasterSecret.length != 127) {
|
||||||
|
throw new Exception("Unexpected TLS premaster secret length");
|
||||||
|
}
|
||||||
|
if (tlsPremasterSecret[0] == 0) {
|
||||||
|
throw new Exception("First byte is zero");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < tlsPremasterSecret.length; i++) {
|
||||||
|
if (tlsPremasterSecret[i] != sharedSecret[i+1]) {
|
||||||
|
throw new Exception("Shared secrets differ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Converts a byte to hex digit and writes to the supplied buffer
|
||||||
|
*/
|
||||||
|
private void byte2hex(byte b, StringBuffer buf) {
|
||||||
|
char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||||
|
'9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||||
|
int high = ((b & 0xf0) >> 4);
|
||||||
|
int low = (b & 0x0f);
|
||||||
|
buf.append(hexChars[high]);
|
||||||
|
buf.append(hexChars[low]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Converts a byte array to hex string
|
||||||
|
*/
|
||||||
|
private String toHexString(byte[] block) {
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
|
||||||
|
int len = block.length;
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
byte2hex(block[i], buf);
|
||||||
|
if (i < len-1) {
|
||||||
|
buf.append(":");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final byte alicePubKeyEnc[] = {
|
||||||
|
(byte)0x30, (byte)0x82, (byte)0x01, (byte)0x24,
|
||||||
|
(byte)0x30, (byte)0x81, (byte)0x99, (byte)0x06,
|
||||||
|
(byte)0x09, (byte)0x2A, (byte)0x86, (byte)0x48,
|
||||||
|
(byte)0x86, (byte)0xF7, (byte)0x0D, (byte)0x01,
|
||||||
|
(byte)0x03, (byte)0x01, (byte)0x30, (byte)0x81,
|
||||||
|
(byte)0x8B, (byte)0x02, (byte)0x81, (byte)0x81,
|
||||||
|
(byte)0x00, (byte)0xF4, (byte)0x88, (byte)0xFD,
|
||||||
|
(byte)0x58, (byte)0x4E, (byte)0x49, (byte)0xDB,
|
||||||
|
(byte)0xCD, (byte)0x20, (byte)0xB4, (byte)0x9D,
|
||||||
|
(byte)0xE4, (byte)0x91, (byte)0x07, (byte)0x36,
|
||||||
|
(byte)0x6B, (byte)0x33, (byte)0x6C, (byte)0x38,
|
||||||
|
(byte)0x0D, (byte)0x45, (byte)0x1D, (byte)0x0F,
|
||||||
|
(byte)0x7C, (byte)0x88, (byte)0xB3, (byte)0x1C,
|
||||||
|
(byte)0x7C, (byte)0x5B, (byte)0x2D, (byte)0x8E,
|
||||||
|
(byte)0xF6, (byte)0xF3, (byte)0xC9, (byte)0x23,
|
||||||
|
(byte)0xC0, (byte)0x43, (byte)0xF0, (byte)0xA5,
|
||||||
|
(byte)0x5B, (byte)0x18, (byte)0x8D, (byte)0x8E,
|
||||||
|
(byte)0xBB, (byte)0x55, (byte)0x8C, (byte)0xB8,
|
||||||
|
(byte)0x5D, (byte)0x38, (byte)0xD3, (byte)0x34,
|
||||||
|
(byte)0xFD, (byte)0x7C, (byte)0x17, (byte)0x57,
|
||||||
|
(byte)0x43, (byte)0xA3, (byte)0x1D, (byte)0x18,
|
||||||
|
(byte)0x6C, (byte)0xDE, (byte)0x33, (byte)0x21,
|
||||||
|
(byte)0x2C, (byte)0xB5, (byte)0x2A, (byte)0xFF,
|
||||||
|
(byte)0x3C, (byte)0xE1, (byte)0xB1, (byte)0x29,
|
||||||
|
(byte)0x40, (byte)0x18, (byte)0x11, (byte)0x8D,
|
||||||
|
(byte)0x7C, (byte)0x84, (byte)0xA7, (byte)0x0A,
|
||||||
|
(byte)0x72, (byte)0xD6, (byte)0x86, (byte)0xC4,
|
||||||
|
(byte)0x03, (byte)0x19, (byte)0xC8, (byte)0x07,
|
||||||
|
(byte)0x29, (byte)0x7A, (byte)0xCA, (byte)0x95,
|
||||||
|
(byte)0x0C, (byte)0xD9, (byte)0x96, (byte)0x9F,
|
||||||
|
(byte)0xAB, (byte)0xD0, (byte)0x0A, (byte)0x50,
|
||||||
|
(byte)0x9B, (byte)0x02, (byte)0x46, (byte)0xD3,
|
||||||
|
(byte)0x08, (byte)0x3D, (byte)0x66, (byte)0xA4,
|
||||||
|
(byte)0x5D, (byte)0x41, (byte)0x9F, (byte)0x9C,
|
||||||
|
(byte)0x7C, (byte)0xBD, (byte)0x89, (byte)0x4B,
|
||||||
|
(byte)0x22, (byte)0x19, (byte)0x26, (byte)0xBA,
|
||||||
|
(byte)0xAB, (byte)0xA2, (byte)0x5E, (byte)0xC3,
|
||||||
|
(byte)0x55, (byte)0xE9, (byte)0x2F, (byte)0x78,
|
||||||
|
(byte)0xC7, (byte)0x02, (byte)0x01, (byte)0x02,
|
||||||
|
(byte)0x02, (byte)0x02, (byte)0x02, (byte)0x00,
|
||||||
|
(byte)0x03, (byte)0x81, (byte)0x85, (byte)0x00,
|
||||||
|
(byte)0x02, (byte)0x81, (byte)0x81, (byte)0x00,
|
||||||
|
(byte)0xEE, (byte)0xD6, (byte)0xB1, (byte)0xA3,
|
||||||
|
(byte)0xB4, (byte)0x78, (byte)0x2B, (byte)0x35,
|
||||||
|
(byte)0xEF, (byte)0xCD, (byte)0x17, (byte)0x86,
|
||||||
|
(byte)0x63, (byte)0x2B, (byte)0x97, (byte)0x0E,
|
||||||
|
(byte)0x7A, (byte)0xD1, (byte)0xFF, (byte)0x7A,
|
||||||
|
(byte)0xEB, (byte)0x57, (byte)0x61, (byte)0xA1,
|
||||||
|
(byte)0xF7, (byte)0x90, (byte)0x11, (byte)0xA7,
|
||||||
|
(byte)0x79, (byte)0x28, (byte)0x69, (byte)0xBA,
|
||||||
|
(byte)0xA7, (byte)0xB2, (byte)0x37, (byte)0x17,
|
||||||
|
(byte)0xAE, (byte)0x3C, (byte)0x92, (byte)0x89,
|
||||||
|
(byte)0x88, (byte)0xE5, (byte)0x7E, (byte)0x8E,
|
||||||
|
(byte)0xF0, (byte)0x24, (byte)0xD0, (byte)0xE1,
|
||||||
|
(byte)0xC4, (byte)0xB0, (byte)0x26, (byte)0x5A,
|
||||||
|
(byte)0x1E, (byte)0xBD, (byte)0xA0, (byte)0xCF,
|
||||||
|
(byte)0x3E, (byte)0x97, (byte)0x2A, (byte)0x13,
|
||||||
|
(byte)0x92, (byte)0x3B, (byte)0x39, (byte)0xD0,
|
||||||
|
(byte)0x1D, (byte)0xA3, (byte)0x6B, (byte)0x3E,
|
||||||
|
(byte)0xC2, (byte)0xBB, (byte)0x14, (byte)0xB6,
|
||||||
|
(byte)0xE2, (byte)0x4C, (byte)0x0E, (byte)0x5B,
|
||||||
|
(byte)0x4B, (byte)0xA4, (byte)0x9D, (byte)0xA6,
|
||||||
|
(byte)0x21, (byte)0xB0, (byte)0xF9, (byte)0xDE,
|
||||||
|
(byte)0x55, (byte)0xAE, (byte)0x5C, (byte)0x29,
|
||||||
|
(byte)0x0E, (byte)0xC1, (byte)0xFC, (byte)0xBA,
|
||||||
|
(byte)0x51, (byte)0xD3, (byte)0xB6, (byte)0x6D,
|
||||||
|
(byte)0x75, (byte)0x72, (byte)0xDF, (byte)0x43,
|
||||||
|
(byte)0xAB, (byte)0x94, (byte)0x21, (byte)0x6E,
|
||||||
|
(byte)0x0C, (byte)0xD1, (byte)0x93, (byte)0x54,
|
||||||
|
(byte)0x56, (byte)0x7D, (byte)0x4B, (byte)0x90,
|
||||||
|
(byte)0xF1, (byte)0x94, (byte)0x45, (byte)0xD4,
|
||||||
|
(byte)0x2A, (byte)0x71, (byte)0xA1, (byte)0xB8,
|
||||||
|
(byte)0xDD, (byte)0xAA, (byte)0x05, (byte)0xF0,
|
||||||
|
(byte)0x27, (byte)0x37, (byte)0xBD, (byte)0x44
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final byte alicePrivKeyEnc[] = {
|
||||||
|
(byte)0x30, (byte)0x81, (byte)0xE3, (byte)0x02,
|
||||||
|
(byte)0x01, (byte)0x00, (byte)0x30, (byte)0x81,
|
||||||
|
(byte)0x99, (byte)0x06, (byte)0x09, (byte)0x2A,
|
||||||
|
(byte)0x86, (byte)0x48, (byte)0x86, (byte)0xF7,
|
||||||
|
(byte)0x0D, (byte)0x01, (byte)0x03, (byte)0x01,
|
||||||
|
(byte)0x30, (byte)0x81, (byte)0x8B, (byte)0x02,
|
||||||
|
(byte)0x81, (byte)0x81, (byte)0x00, (byte)0xF4,
|
||||||
|
(byte)0x88, (byte)0xFD, (byte)0x58, (byte)0x4E,
|
||||||
|
(byte)0x49, (byte)0xDB, (byte)0xCD, (byte)0x20,
|
||||||
|
(byte)0xB4, (byte)0x9D, (byte)0xE4, (byte)0x91,
|
||||||
|
(byte)0x07, (byte)0x36, (byte)0x6B, (byte)0x33,
|
||||||
|
(byte)0x6C, (byte)0x38, (byte)0x0D, (byte)0x45,
|
||||||
|
(byte)0x1D, (byte)0x0F, (byte)0x7C, (byte)0x88,
|
||||||
|
(byte)0xB3, (byte)0x1C, (byte)0x7C, (byte)0x5B,
|
||||||
|
(byte)0x2D, (byte)0x8E, (byte)0xF6, (byte)0xF3,
|
||||||
|
(byte)0xC9, (byte)0x23, (byte)0xC0, (byte)0x43,
|
||||||
|
(byte)0xF0, (byte)0xA5, (byte)0x5B, (byte)0x18,
|
||||||
|
(byte)0x8D, (byte)0x8E, (byte)0xBB, (byte)0x55,
|
||||||
|
(byte)0x8C, (byte)0xB8, (byte)0x5D, (byte)0x38,
|
||||||
|
(byte)0xD3, (byte)0x34, (byte)0xFD, (byte)0x7C,
|
||||||
|
(byte)0x17, (byte)0x57, (byte)0x43, (byte)0xA3,
|
||||||
|
(byte)0x1D, (byte)0x18, (byte)0x6C, (byte)0xDE,
|
||||||
|
(byte)0x33, (byte)0x21, (byte)0x2C, (byte)0xB5,
|
||||||
|
(byte)0x2A, (byte)0xFF, (byte)0x3C, (byte)0xE1,
|
||||||
|
(byte)0xB1, (byte)0x29, (byte)0x40, (byte)0x18,
|
||||||
|
(byte)0x11, (byte)0x8D, (byte)0x7C, (byte)0x84,
|
||||||
|
(byte)0xA7, (byte)0x0A, (byte)0x72, (byte)0xD6,
|
||||||
|
(byte)0x86, (byte)0xC4, (byte)0x03, (byte)0x19,
|
||||||
|
(byte)0xC8, (byte)0x07, (byte)0x29, (byte)0x7A,
|
||||||
|
(byte)0xCA, (byte)0x95, (byte)0x0C, (byte)0xD9,
|
||||||
|
(byte)0x96, (byte)0x9F, (byte)0xAB, (byte)0xD0,
|
||||||
|
(byte)0x0A, (byte)0x50, (byte)0x9B, (byte)0x02,
|
||||||
|
(byte)0x46, (byte)0xD3, (byte)0x08, (byte)0x3D,
|
||||||
|
(byte)0x66, (byte)0xA4, (byte)0x5D, (byte)0x41,
|
||||||
|
(byte)0x9F, (byte)0x9C, (byte)0x7C, (byte)0xBD,
|
||||||
|
(byte)0x89, (byte)0x4B, (byte)0x22, (byte)0x19,
|
||||||
|
(byte)0x26, (byte)0xBA, (byte)0xAB, (byte)0xA2,
|
||||||
|
(byte)0x5E, (byte)0xC3, (byte)0x55, (byte)0xE9,
|
||||||
|
(byte)0x2F, (byte)0x78, (byte)0xC7, (byte)0x02,
|
||||||
|
(byte)0x01, (byte)0x02, (byte)0x02, (byte)0x02,
|
||||||
|
(byte)0x02, (byte)0x00, (byte)0x04, (byte)0x42,
|
||||||
|
(byte)0x02, (byte)0x40, (byte)0x36, (byte)0x4D,
|
||||||
|
(byte)0xD0, (byte)0x58, (byte)0x64, (byte)0x91,
|
||||||
|
(byte)0x78, (byte)0xA2, (byte)0x4B, (byte)0x79,
|
||||||
|
(byte)0x46, (byte)0xFE, (byte)0xC9, (byte)0xD9,
|
||||||
|
(byte)0xCA, (byte)0x5C, (byte)0xF9, (byte)0xFD,
|
||||||
|
(byte)0x6C, (byte)0x5D, (byte)0x76, (byte)0x3A,
|
||||||
|
(byte)0x41, (byte)0x6D, (byte)0x44, (byte)0x62,
|
||||||
|
(byte)0x75, (byte)0x93, (byte)0x81, (byte)0x93,
|
||||||
|
(byte)0x00, (byte)0x4C, (byte)0xB1, (byte)0xD8,
|
||||||
|
(byte)0x7D, (byte)0x9D, (byte)0xF3, (byte)0x16,
|
||||||
|
(byte)0x2C, (byte)0x6C, (byte)0x9F, (byte)0x7A,
|
||||||
|
(byte)0x84, (byte)0xA3, (byte)0x7A, (byte)0xC1,
|
||||||
|
(byte)0x4F, (byte)0x60, (byte)0xE3, (byte)0xB5,
|
||||||
|
(byte)0x86, (byte)0x28, (byte)0x08, (byte)0x4D,
|
||||||
|
(byte)0x94, (byte)0xB6, (byte)0x04, (byte)0x0D,
|
||||||
|
(byte)0xAC, (byte)0xBD, (byte)0x1F, (byte)0x42,
|
||||||
|
(byte)0x8F, (byte)0x1B
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final byte bobPubKeyEnc[] = {
|
||||||
|
(byte)0x30, (byte)0x82, (byte)0x01, (byte)0x23,
|
||||||
|
(byte)0x30, (byte)0x81, (byte)0x99, (byte)0x06,
|
||||||
|
(byte)0x09, (byte)0x2A, (byte)0x86, (byte)0x48,
|
||||||
|
(byte)0x86, (byte)0xF7, (byte)0x0D, (byte)0x01,
|
||||||
|
(byte)0x03, (byte)0x01, (byte)0x30, (byte)0x81,
|
||||||
|
(byte)0x8B, (byte)0x02, (byte)0x81, (byte)0x81,
|
||||||
|
(byte)0x00, (byte)0xF4, (byte)0x88, (byte)0xFD,
|
||||||
|
(byte)0x58, (byte)0x4E, (byte)0x49, (byte)0xDB,
|
||||||
|
(byte)0xCD, (byte)0x20, (byte)0xB4, (byte)0x9D,
|
||||||
|
(byte)0xE4, (byte)0x91, (byte)0x07, (byte)0x36,
|
||||||
|
(byte)0x6B, (byte)0x33, (byte)0x6C, (byte)0x38,
|
||||||
|
(byte)0x0D, (byte)0x45, (byte)0x1D, (byte)0x0F,
|
||||||
|
(byte)0x7C, (byte)0x88, (byte)0xB3, (byte)0x1C,
|
||||||
|
(byte)0x7C, (byte)0x5B, (byte)0x2D, (byte)0x8E,
|
||||||
|
(byte)0xF6, (byte)0xF3, (byte)0xC9, (byte)0x23,
|
||||||
|
(byte)0xC0, (byte)0x43, (byte)0xF0, (byte)0xA5,
|
||||||
|
(byte)0x5B, (byte)0x18, (byte)0x8D, (byte)0x8E,
|
||||||
|
(byte)0xBB, (byte)0x55, (byte)0x8C, (byte)0xB8,
|
||||||
|
(byte)0x5D, (byte)0x38, (byte)0xD3, (byte)0x34,
|
||||||
|
(byte)0xFD, (byte)0x7C, (byte)0x17, (byte)0x57,
|
||||||
|
(byte)0x43, (byte)0xA3, (byte)0x1D, (byte)0x18,
|
||||||
|
(byte)0x6C, (byte)0xDE, (byte)0x33, (byte)0x21,
|
||||||
|
(byte)0x2C, (byte)0xB5, (byte)0x2A, (byte)0xFF,
|
||||||
|
(byte)0x3C, (byte)0xE1, (byte)0xB1, (byte)0x29,
|
||||||
|
(byte)0x40, (byte)0x18, (byte)0x11, (byte)0x8D,
|
||||||
|
(byte)0x7C, (byte)0x84, (byte)0xA7, (byte)0x0A,
|
||||||
|
(byte)0x72, (byte)0xD6, (byte)0x86, (byte)0xC4,
|
||||||
|
(byte)0x03, (byte)0x19, (byte)0xC8, (byte)0x07,
|
||||||
|
(byte)0x29, (byte)0x7A, (byte)0xCA, (byte)0x95,
|
||||||
|
(byte)0x0C, (byte)0xD9, (byte)0x96, (byte)0x9F,
|
||||||
|
(byte)0xAB, (byte)0xD0, (byte)0x0A, (byte)0x50,
|
||||||
|
(byte)0x9B, (byte)0x02, (byte)0x46, (byte)0xD3,
|
||||||
|
(byte)0x08, (byte)0x3D, (byte)0x66, (byte)0xA4,
|
||||||
|
(byte)0x5D, (byte)0x41, (byte)0x9F, (byte)0x9C,
|
||||||
|
(byte)0x7C, (byte)0xBD, (byte)0x89, (byte)0x4B,
|
||||||
|
(byte)0x22, (byte)0x19, (byte)0x26, (byte)0xBA,
|
||||||
|
(byte)0xAB, (byte)0xA2, (byte)0x5E, (byte)0xC3,
|
||||||
|
(byte)0x55, (byte)0xE9, (byte)0x2F, (byte)0x78,
|
||||||
|
(byte)0xC7, (byte)0x02, (byte)0x01, (byte)0x02,
|
||||||
|
(byte)0x02, (byte)0x02, (byte)0x02, (byte)0x00,
|
||||||
|
(byte)0x03, (byte)0x81, (byte)0x84, (byte)0x00,
|
||||||
|
(byte)0x02, (byte)0x81, (byte)0x80, (byte)0x2C,
|
||||||
|
(byte)0x40, (byte)0xFA, (byte)0xF6, (byte)0xA6,
|
||||||
|
(byte)0xF8, (byte)0xAC, (byte)0xC2, (byte)0x4F,
|
||||||
|
(byte)0xCD, (byte)0xC7, (byte)0x37, (byte)0x93,
|
||||||
|
(byte)0xE5, (byte)0xE4, (byte)0x5E, (byte)0x18,
|
||||||
|
(byte)0x14, (byte)0xE6, (byte)0x50, (byte)0xDA,
|
||||||
|
(byte)0x55, (byte)0x38, (byte)0x5D, (byte)0x24,
|
||||||
|
(byte)0xF5, (byte)0x42, (byte)0x68, (byte)0x5F,
|
||||||
|
(byte)0xF5, (byte)0x15, (byte)0xC8, (byte)0x9B,
|
||||||
|
(byte)0x5D, (byte)0x06, (byte)0x3D, (byte)0xE1,
|
||||||
|
(byte)0x52, (byte)0x2F, (byte)0x98, (byte)0xFF,
|
||||||
|
(byte)0x37, (byte)0xBB, (byte)0x75, (byte)0x48,
|
||||||
|
(byte)0x48, (byte)0xE9, (byte)0x65, (byte)0x84,
|
||||||
|
(byte)0x37, (byte)0xBB, (byte)0xB3, (byte)0xE9,
|
||||||
|
(byte)0x36, (byte)0x01, (byte)0xB4, (byte)0x6A,
|
||||||
|
(byte)0x1C, (byte)0xB2, (byte)0x11, (byte)0x82,
|
||||||
|
(byte)0xCE, (byte)0x3D, (byte)0x65, (byte)0xE5,
|
||||||
|
(byte)0x3C, (byte)0x89, (byte)0xE9, (byte)0x52,
|
||||||
|
(byte)0x19, (byte)0xBD, (byte)0x58, (byte)0xF6,
|
||||||
|
(byte)0xA2, (byte)0x03, (byte)0xA8, (byte)0xB2,
|
||||||
|
(byte)0xA5, (byte)0xDB, (byte)0xEB, (byte)0xF5,
|
||||||
|
(byte)0x94, (byte)0xF9, (byte)0x46, (byte)0xBE,
|
||||||
|
(byte)0x45, (byte)0x4C, (byte)0x65, (byte)0xD2,
|
||||||
|
(byte)0xD1, (byte)0xCF, (byte)0xFF, (byte)0xFF,
|
||||||
|
(byte)0xFA, (byte)0x38, (byte)0xF1, (byte)0x72,
|
||||||
|
(byte)0xAB, (byte)0xB9, (byte)0x14, (byte)0x4E,
|
||||||
|
(byte)0xF5, (byte)0xF0, (byte)0x7A, (byte)0x8E,
|
||||||
|
(byte)0x45, (byte)0xFD, (byte)0x5B, (byte)0xF9,
|
||||||
|
(byte)0xA2, (byte)0x97, (byte)0x1B, (byte)0xAE,
|
||||||
|
(byte)0x2C, (byte)0x7B, (byte)0x6B, (byte)0x7C,
|
||||||
|
(byte)0x98, (byte)0xFE, (byte)0x58, (byte)0xDD,
|
||||||
|
(byte)0xBE, (byte)0xF6, (byte)0x1C, (byte)0x8E,
|
||||||
|
(byte)0xD0, (byte)0xA1, (byte)0x72
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final byte bobPrivKeyEnc[] = {
|
||||||
|
(byte)0x30, (byte)0x81, (byte)0xE4, (byte)0x02,
|
||||||
|
(byte)0x01, (byte)0x00, (byte)0x30, (byte)0x81,
|
||||||
|
(byte)0x99, (byte)0x06, (byte)0x09, (byte)0x2A,
|
||||||
|
(byte)0x86, (byte)0x48, (byte)0x86, (byte)0xF7,
|
||||||
|
(byte)0x0D, (byte)0x01, (byte)0x03, (byte)0x01,
|
||||||
|
(byte)0x30, (byte)0x81, (byte)0x8B, (byte)0x02,
|
||||||
|
(byte)0x81, (byte)0x81, (byte)0x00, (byte)0xF4,
|
||||||
|
(byte)0x88, (byte)0xFD, (byte)0x58, (byte)0x4E,
|
||||||
|
(byte)0x49, (byte)0xDB, (byte)0xCD, (byte)0x20,
|
||||||
|
(byte)0xB4, (byte)0x9D, (byte)0xE4, (byte)0x91,
|
||||||
|
(byte)0x07, (byte)0x36, (byte)0x6B, (byte)0x33,
|
||||||
|
(byte)0x6C, (byte)0x38, (byte)0x0D, (byte)0x45,
|
||||||
|
(byte)0x1D, (byte)0x0F, (byte)0x7C, (byte)0x88,
|
||||||
|
(byte)0xB3, (byte)0x1C, (byte)0x7C, (byte)0x5B,
|
||||||
|
(byte)0x2D, (byte)0x8E, (byte)0xF6, (byte)0xF3,
|
||||||
|
(byte)0xC9, (byte)0x23, (byte)0xC0, (byte)0x43,
|
||||||
|
(byte)0xF0, (byte)0xA5, (byte)0x5B, (byte)0x18,
|
||||||
|
(byte)0x8D, (byte)0x8E, (byte)0xBB, (byte)0x55,
|
||||||
|
(byte)0x8C, (byte)0xB8, (byte)0x5D, (byte)0x38,
|
||||||
|
(byte)0xD3, (byte)0x34, (byte)0xFD, (byte)0x7C,
|
||||||
|
(byte)0x17, (byte)0x57, (byte)0x43, (byte)0xA3,
|
||||||
|
(byte)0x1D, (byte)0x18, (byte)0x6C, (byte)0xDE,
|
||||||
|
(byte)0x33, (byte)0x21, (byte)0x2C, (byte)0xB5,
|
||||||
|
(byte)0x2A, (byte)0xFF, (byte)0x3C, (byte)0xE1,
|
||||||
|
(byte)0xB1, (byte)0x29, (byte)0x40, (byte)0x18,
|
||||||
|
(byte)0x11, (byte)0x8D, (byte)0x7C, (byte)0x84,
|
||||||
|
(byte)0xA7, (byte)0x0A, (byte)0x72, (byte)0xD6,
|
||||||
|
(byte)0x86, (byte)0xC4, (byte)0x03, (byte)0x19,
|
||||||
|
(byte)0xC8, (byte)0x07, (byte)0x29, (byte)0x7A,
|
||||||
|
(byte)0xCA, (byte)0x95, (byte)0x0C, (byte)0xD9,
|
||||||
|
(byte)0x96, (byte)0x9F, (byte)0xAB, (byte)0xD0,
|
||||||
|
(byte)0x0A, (byte)0x50, (byte)0x9B, (byte)0x02,
|
||||||
|
(byte)0x46, (byte)0xD3, (byte)0x08, (byte)0x3D,
|
||||||
|
(byte)0x66, (byte)0xA4, (byte)0x5D, (byte)0x41,
|
||||||
|
(byte)0x9F, (byte)0x9C, (byte)0x7C, (byte)0xBD,
|
||||||
|
(byte)0x89, (byte)0x4B, (byte)0x22, (byte)0x19,
|
||||||
|
(byte)0x26, (byte)0xBA, (byte)0xAB, (byte)0xA2,
|
||||||
|
(byte)0x5E, (byte)0xC3, (byte)0x55, (byte)0xE9,
|
||||||
|
(byte)0x2F, (byte)0x78, (byte)0xC7, (byte)0x02,
|
||||||
|
(byte)0x01, (byte)0x02, (byte)0x02, (byte)0x02,
|
||||||
|
(byte)0x02, (byte)0x00, (byte)0x04, (byte)0x43,
|
||||||
|
(byte)0x02, (byte)0x41, (byte)0x00, (byte)0xE0,
|
||||||
|
(byte)0x31, (byte)0xE7, (byte)0x77, (byte)0xB8,
|
||||||
|
(byte)0xD0, (byte)0x7E, (byte)0x0A, (byte)0x9B,
|
||||||
|
(byte)0x94, (byte)0xD5, (byte)0x3D, (byte)0x33,
|
||||||
|
(byte)0x62, (byte)0x32, (byte)0x51, (byte)0xCE,
|
||||||
|
(byte)0x74, (byte)0x5C, (byte)0xA5, (byte)0x72,
|
||||||
|
(byte)0xD9, (byte)0x36, (byte)0xF3, (byte)0x8A,
|
||||||
|
(byte)0x3F, (byte)0x8B, (byte)0xC6, (byte)0xFE,
|
||||||
|
(byte)0xEF, (byte)0x94, (byte)0x8B, (byte)0x50,
|
||||||
|
(byte)0x41, (byte)0x9B, (byte)0x14, (byte)0xC8,
|
||||||
|
(byte)0xE9, (byte)0x1F, (byte)0x24, (byte)0x1F,
|
||||||
|
(byte)0x65, (byte)0x8E, (byte)0xD3, (byte)0x85,
|
||||||
|
(byte)0xD0, (byte)0x68, (byte)0x6C, (byte)0xF1,
|
||||||
|
(byte)0x79, (byte)0x45, (byte)0xD0, (byte)0x06,
|
||||||
|
(byte)0xA4, (byte)0xB8, (byte)0xE0, (byte)0x64,
|
||||||
|
(byte)0xF5, (byte)0x38, (byte)0x72, (byte)0x97,
|
||||||
|
(byte)0x00, (byte)0x23, (byte)0x5F
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ import java.util.Arrays;
|
|||||||
* @bug 6937053 8005472
|
* @bug 6937053 8005472
|
||||||
*
|
*
|
||||||
* @run clean TestSerializationMismatch
|
* @run clean TestSerializationMismatch
|
||||||
* @run main TestSerializationMismatch
|
* @run main/othervm TestSerializationMismatch
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TestSerializationMismatch {
|
public class TestSerializationMismatch {
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 7150256
|
||||||
|
* @summary Basic Test for the DiagnosticCommandMBean
|
||||||
|
* @author Frederic Parain
|
||||||
|
*
|
||||||
|
* @run main/othervm -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8125 DcmdMBeanDoubleInvocationTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import javax.management.Descriptor;
|
||||||
|
import javax.management.InstanceNotFoundException;
|
||||||
|
import javax.management.IntrospectionException;
|
||||||
|
import javax.management.MBeanInfo;
|
||||||
|
import javax.management.MBeanOperationInfo;
|
||||||
|
import javax.management.MBeanServer;
|
||||||
|
import javax.management.MalformedObjectNameException;
|
||||||
|
import javax.management.ObjectName;
|
||||||
|
import javax.management.ReflectionException;
|
||||||
|
import javax.management.*;
|
||||||
|
import javax.management.remote.*;
|
||||||
|
|
||||||
|
public class DcmdMBeanDoubleInvocationTest {
|
||||||
|
|
||||||
|
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
|
||||||
|
"com.sun.management:type=DiagnosticCommand";
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
MBeanServerConnection mbs = null;
|
||||||
|
try {
|
||||||
|
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8125/jmxrmi");
|
||||||
|
JMXConnector connector = JMXConnectorFactory.connect(url);
|
||||||
|
mbs = connector.getMBeanServerConnection();
|
||||||
|
} catch(Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
ObjectName name;
|
||||||
|
try {
|
||||||
|
name = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
|
||||||
|
MBeanInfo info = mbs.getMBeanInfo(name);
|
||||||
|
String[] helpArgs = {"-all", "\n", "VM.version"};
|
||||||
|
Object[] dcmdArgs = {helpArgs};
|
||||||
|
String[] signature = {String[].class.getName()};
|
||||||
|
String result = (String) mbs.invoke(name, "help", dcmdArgs, signature);
|
||||||
|
System.out.println(result);
|
||||||
|
} catch (RuntimeMBeanException ex) {
|
||||||
|
if (ex.getCause() instanceof IllegalArgumentException) {
|
||||||
|
System.out.println("Test passed");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
ex.printStackTrace();
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
} catch (InstanceNotFoundException | IntrospectionException
|
||||||
|
| ReflectionException | MalformedObjectNameException
|
||||||
|
| MBeanException|IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
System.out.println("Double commands have not been detected");
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 7150256
|
||||||
|
* @summary Basic Test for the DiagnosticCommandMBean
|
||||||
|
* @author Frederic Parain
|
||||||
|
*
|
||||||
|
* @run main/othervm -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8129 DcmdMBeanInvocationTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import javax.management.Descriptor;
|
||||||
|
import javax.management.InstanceNotFoundException;
|
||||||
|
import javax.management.IntrospectionException;
|
||||||
|
import javax.management.MBeanInfo;
|
||||||
|
import javax.management.MBeanOperationInfo;
|
||||||
|
import javax.management.MBeanServer;
|
||||||
|
import javax.management.MalformedObjectNameException;
|
||||||
|
import javax.management.ObjectName;
|
||||||
|
import javax.management.ReflectionException;
|
||||||
|
import javax.management.*;
|
||||||
|
import javax.management.remote.*;
|
||||||
|
|
||||||
|
public class DcmdMBeanInvocationTest {
|
||||||
|
|
||||||
|
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
|
||||||
|
"com.sun.management:type=DiagnosticCommand";
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
MBeanServerConnection mbs = null;
|
||||||
|
try {
|
||||||
|
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8129/jmxrmi");
|
||||||
|
JMXConnector connector = JMXConnectorFactory.connect(url);
|
||||||
|
mbs = connector.getMBeanServerConnection();
|
||||||
|
} catch(Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
ObjectName name;
|
||||||
|
try {
|
||||||
|
name = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
|
||||||
|
MBeanInfo info = mbs.getMBeanInfo(name);
|
||||||
|
String[] helpArgs = {"-all"};
|
||||||
|
Object[] dcmdArgs = {helpArgs};
|
||||||
|
String[] signature = {String[].class.getName()};
|
||||||
|
String result = (String) mbs.invoke(name, "help", dcmdArgs, signature);
|
||||||
|
System.out.println(result);
|
||||||
|
} catch (InstanceNotFoundException | IntrospectionException
|
||||||
|
| ReflectionException | MalformedObjectNameException
|
||||||
|
| MBeanException|IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
System.out.println("Test passed");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 7150256
|
||||||
|
* @summary Permissions Tests for the DiagnosticCommandMBean
|
||||||
|
* @author Frederic Parain
|
||||||
|
*
|
||||||
|
* @run main/othervm DcmdMBeanPermissionsTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.ReflectPermission;
|
||||||
|
import java.security.Permission;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import javax.management.Descriptor;
|
||||||
|
import javax.management.InstanceNotFoundException;
|
||||||
|
import javax.management.IntrospectionException;
|
||||||
|
import javax.management.MBeanException;
|
||||||
|
import javax.management.MBeanInfo;
|
||||||
|
import javax.management.MBeanOperationInfo;
|
||||||
|
import javax.management.MBeanPermission;
|
||||||
|
import javax.management.MBeanServer;
|
||||||
|
import javax.management.MalformedObjectNameException;
|
||||||
|
import javax.management.ObjectName;
|
||||||
|
import javax.management.ReflectionException;
|
||||||
|
import javax.management.RuntimeMBeanException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author fparain
|
||||||
|
*/
|
||||||
|
public class DcmdMBeanPermissionsTest {
|
||||||
|
|
||||||
|
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
|
||||||
|
"com.sun.management:type=DiagnosticCommand";
|
||||||
|
|
||||||
|
static public class CustomSecurityManager extends SecurityManager {
|
||||||
|
|
||||||
|
private HashSet<Permission> grantedPermissions;
|
||||||
|
|
||||||
|
public CustomSecurityManager() {
|
||||||
|
grantedPermissions = new HashSet<Permission>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void grantPermission(final Permission perm) {
|
||||||
|
grantedPermissions.add(perm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void denyPermission(final Permission perm) {
|
||||||
|
Iterator<Permission> it = grantedPermissions.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Permission p = it.next();
|
||||||
|
if (p.equals(perm)) {
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void checkPermission(final Permission perm) {
|
||||||
|
for (Permission p : grantedPermissions) {
|
||||||
|
if (p.implies(perm)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new SecurityException(perm.toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static Permission createPermission(String classname, String name,
|
||||||
|
String action) {
|
||||||
|
Permission permission = null;
|
||||||
|
try {
|
||||||
|
Class c = Class.forName(classname);
|
||||||
|
if (action == null) {
|
||||||
|
try {
|
||||||
|
Constructor constructor = c.getConstructor(String.class);
|
||||||
|
permission = (Permission) constructor.newInstance(name);
|
||||||
|
|
||||||
|
} catch (InstantiationException | IllegalAccessException
|
||||||
|
| IllegalArgumentException | InvocationTargetException
|
||||||
|
| NoSuchMethodException | SecurityException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (permission == null) {
|
||||||
|
try {
|
||||||
|
Constructor constructor = c.getConstructor(String.class,
|
||||||
|
String.class);
|
||||||
|
permission = (Permission) constructor.newInstance(
|
||||||
|
name,
|
||||||
|
action);
|
||||||
|
} catch (InstantiationException | IllegalAccessException
|
||||||
|
| IllegalArgumentException | InvocationTargetException
|
||||||
|
| NoSuchMethodException | SecurityException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ClassNotFoundException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
if (permission == null) {
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
return permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return true if invokation triggered a SecurityException
|
||||||
|
static boolean invokeOperation(MBeanServer mbs, ObjectName on,
|
||||||
|
MBeanOperationInfo opInfo) {
|
||||||
|
try {
|
||||||
|
if (opInfo.getSignature().length == 0) {
|
||||||
|
mbs.invoke(on, opInfo.getName(),
|
||||||
|
new Object[0], new String[0]);
|
||||||
|
} else {
|
||||||
|
mbs.invoke(on, opInfo.getName(),
|
||||||
|
new Object[1], new String[]{ String[].class.getName()});
|
||||||
|
}
|
||||||
|
} catch (SecurityException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
return true;
|
||||||
|
} catch (RuntimeMBeanException ex) {
|
||||||
|
if (ex.getCause() instanceof SecurityException) {
|
||||||
|
//ex.printStackTrace();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (MBeanException | InstanceNotFoundException
|
||||||
|
| ReflectionException ex) {
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void testOperation(MBeanServer mbs, CustomSecurityManager sm,
|
||||||
|
ObjectName on, MBeanOperationInfo opInfo) {
|
||||||
|
System.out.println("Testing " + opInfo.getName());
|
||||||
|
Descriptor desc = opInfo.getDescriptor();
|
||||||
|
if (desc.getFieldValue("dcmd.permissionClass") == null) {
|
||||||
|
// No special permission required, execution should not trigger
|
||||||
|
// any security exception
|
||||||
|
if (invokeOperation(mbs, on, opInfo)) {
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Building the required permission
|
||||||
|
Permission reqPerm = createPermission(
|
||||||
|
(String)desc.getFieldValue("dcmd.permissionClass"),
|
||||||
|
(String)desc.getFieldValue("dcmd.permissionName"),
|
||||||
|
(String)desc.getFieldValue("dcmd.permissionAction"));
|
||||||
|
// Paranoid mode: check that the SecurityManager has not already
|
||||||
|
// been granted the permission
|
||||||
|
sm.denyPermission(reqPerm);
|
||||||
|
// A special permission is required for this operation,
|
||||||
|
// invoking it without the permission granted must trigger
|
||||||
|
// a security exception
|
||||||
|
if(!invokeOperation(mbs, on, opInfo)) {
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
// grant the permission and re-try invoking the operation
|
||||||
|
sm.grantPermission(reqPerm);
|
||||||
|
if(invokeOperation(mbs, on, opInfo)) {
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
// Clean up
|
||||||
|
sm.denyPermission(reqPerm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(final String[] args) {
|
||||||
|
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
||||||
|
ObjectName on = null;
|
||||||
|
try {
|
||||||
|
on = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
|
||||||
|
} catch (MalformedObjectNameException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
MBeanInfo info = null;
|
||||||
|
try {
|
||||||
|
info = mbs.getMBeanInfo(on);
|
||||||
|
} catch (InstanceNotFoundException | IntrospectionException
|
||||||
|
| ReflectionException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
throw new RuntimeException("TEST FAILED");
|
||||||
|
}
|
||||||
|
CustomSecurityManager sm = new CustomSecurityManager();
|
||||||
|
System.setSecurityManager(sm);
|
||||||
|
// Set of permission required to run the test cleanly
|
||||||
|
// Some permissions are required by the MBeanServer and other
|
||||||
|
// platform services (RuntimePermission("createClassLoader"),
|
||||||
|
// ReflectPermission("suppressAccessChecks"),
|
||||||
|
// java.util.logging.LoggingPermission("control"),
|
||||||
|
// RuntimePermission("exitVM.97")).
|
||||||
|
// Other permissions are required by commands being invoked
|
||||||
|
// in the test (for instance, RuntimePermission("modifyThreadGroup")
|
||||||
|
// and RuntimePermission("modifyThread") are checked when
|
||||||
|
// runFinalization() is invoked by the gcRunFinalization command.
|
||||||
|
sm.grantPermission(new RuntimePermission("createClassLoader"));
|
||||||
|
sm.grantPermission(new ReflectPermission("suppressAccessChecks"));
|
||||||
|
sm.grantPermission(new java.util.logging.LoggingPermission("control", ""));
|
||||||
|
sm.grantPermission(new java.lang.RuntimePermission("exitVM.97"));
|
||||||
|
sm.grantPermission(new java.lang.RuntimePermission("modifyThreadGroup"));
|
||||||
|
sm.grantPermission(new java.lang.RuntimePermission("modifyThread"));
|
||||||
|
for(MBeanOperationInfo opInfo : info.getOperations()) {
|
||||||
|
Permission opPermission = new MBeanPermission(info.getClassName(),
|
||||||
|
opInfo.getName(),
|
||||||
|
on,
|
||||||
|
"invoke");
|
||||||
|
sm.grantPermission(opPermission);
|
||||||
|
testOperation(mbs, sm, on, opInfo);
|
||||||
|
sm.denyPermission(opPermission);
|
||||||
|
}
|
||||||
|
System.out.println("TEST PASSED");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 7150256
|
||||||
|
* @summary Basic Test for the DiagnosticCommandMBean
|
||||||
|
* @author Frederic Parain
|
||||||
|
*
|
||||||
|
* @run main/othervm -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8127 DcmdMBeanTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import javax.management.Descriptor;
|
||||||
|
import javax.management.InstanceNotFoundException;
|
||||||
|
import javax.management.IntrospectionException;
|
||||||
|
import javax.management.MBeanInfo;
|
||||||
|
import javax.management.MBeanOperationInfo;
|
||||||
|
import javax.management.MBeanServer;
|
||||||
|
import javax.management.MalformedObjectNameException;
|
||||||
|
import javax.management.ObjectName;
|
||||||
|
import javax.management.ReflectionException;
|
||||||
|
import javax.management.*;
|
||||||
|
import javax.management.remote.*;
|
||||||
|
|
||||||
|
public class DcmdMBeanTest {
|
||||||
|
|
||||||
|
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
|
||||||
|
"com.sun.management:type=DiagnosticCommand";
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
MBeanServerConnection mbs = null;
|
||||||
|
try {
|
||||||
|
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8127/jmxrmi");
|
||||||
|
JMXConnector connector = JMXConnectorFactory.connect(url);
|
||||||
|
mbs = connector.getMBeanServerConnection();
|
||||||
|
} catch(Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
ObjectName name;
|
||||||
|
try {
|
||||||
|
name = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
|
||||||
|
MBeanInfo info = mbs.getMBeanInfo(name);
|
||||||
|
// the test should check that the MBean doesn't have any
|
||||||
|
// Attribute, notification or constructor. Current version only
|
||||||
|
// check operations
|
||||||
|
System.out.println("Class Name:"+info.getClassName());
|
||||||
|
System.out.println("Description:"+info.getDescription());
|
||||||
|
MBeanOperationInfo[] opInfo = info.getOperations();
|
||||||
|
System.out.println("Operations:");
|
||||||
|
for(int i=0; i<opInfo.length; i++) {
|
||||||
|
printOperation(opInfo[i]);
|
||||||
|
System.out.println("\n@@@@@@\n");
|
||||||
|
}
|
||||||
|
} catch (InstanceNotFoundException|IntrospectionException|ReflectionException
|
||||||
|
|MalformedObjectNameException|IOException ex) {
|
||||||
|
Logger.getLogger(DcmdMBeanTest.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printOperation(MBeanOperationInfo info) {
|
||||||
|
System.out.println("Name: "+info.getName());
|
||||||
|
System.out.println("Description: "+info.getDescription());
|
||||||
|
System.out.println("Return Type: "+info.getReturnType());
|
||||||
|
System.out.println("Impact: "+info.getImpact());
|
||||||
|
Descriptor desc = info.getDescriptor();
|
||||||
|
System.out.println("Descriptor");
|
||||||
|
for(int i=0; i<desc.getFieldNames().length; i++) {
|
||||||
|
if(desc.getFieldNames()[i].compareTo("dcmd.arguments") == 0) {
|
||||||
|
System.out.println("\t"+desc.getFieldNames()[i]+":");
|
||||||
|
Descriptor desc2 =
|
||||||
|
(Descriptor)desc.getFieldValue(desc.getFieldNames()[i]);
|
||||||
|
for(int j=0; j<desc2.getFieldNames().length; j++) {
|
||||||
|
System.out.println("\t\t"+desc2.getFieldNames()[j]+"=");
|
||||||
|
Descriptor desc3 =
|
||||||
|
(Descriptor)desc2.getFieldValue(desc2.getFieldNames()[j]);
|
||||||
|
for(int k=0; k<desc3.getFieldNames().length; k++) {
|
||||||
|
System.out.println("\t\t\t"+desc3.getFieldNames()[k]+"="
|
||||||
|
+desc3.getFieldValue(desc3.getFieldNames()[k]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("\t"+desc.getFieldNames()[i]+"="
|
||||||
|
+desc.getFieldValue(desc.getFieldNames()[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -29,6 +29,7 @@ import java.nio.file.spi.*;
|
|||||||
import java.nio.file.attribute.*;
|
import java.nio.file.attribute.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.zip.*;
|
import java.util.zip.*;
|
||||||
|
|
||||||
import static java.nio.file.StandardOpenOption.*;
|
import static java.nio.file.StandardOpenOption.*;
|
||||||
@ -48,6 +49,7 @@ public class ZipFSTester {
|
|||||||
test0(fs);
|
test0(fs);
|
||||||
test1(fs);
|
test1(fs);
|
||||||
test2(fs); // more tests
|
test2(fs); // more tests
|
||||||
|
testTime(Paths.get(args[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,6 +339,46 @@ public class ZipFSTester {
|
|||||||
Files.delete(fs3Path);
|
Files.delete(fs3Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test file stamp
|
||||||
|
static void testTime(Path src) throws Exception {
|
||||||
|
// create a new filesystem, copy this file into it
|
||||||
|
Map<String, Object> env = new HashMap<String, Object>();
|
||||||
|
env.put("create", "true");
|
||||||
|
Path fsPath = getTempPath();
|
||||||
|
FileSystem fs = newZipFileSystem(fsPath, env);
|
||||||
|
|
||||||
|
System.out.println("test copy with timestamps...");
|
||||||
|
// copyin
|
||||||
|
Path dst = getPathWithParents(fs, "me");
|
||||||
|
Files.copy(src, dst, COPY_ATTRIBUTES);
|
||||||
|
checkEqual(src, dst);
|
||||||
|
|
||||||
|
BasicFileAttributes attrs = Files
|
||||||
|
.getFileAttributeView(src, BasicFileAttributeView.class)
|
||||||
|
.readAttributes();
|
||||||
|
System.out.println("mtime: " + attrs.lastModifiedTime());
|
||||||
|
System.out.println("ctime: " + attrs.creationTime());
|
||||||
|
System.out.println("atime: " + attrs.lastAccessTime());
|
||||||
|
System.out.println(" ==============>");
|
||||||
|
BasicFileAttributes dstAttrs = Files
|
||||||
|
.getFileAttributeView(dst, BasicFileAttributeView.class)
|
||||||
|
.readAttributes();
|
||||||
|
System.out.println("mtime: " + dstAttrs.lastModifiedTime());
|
||||||
|
System.out.println("ctime: " + dstAttrs.creationTime());
|
||||||
|
System.out.println("atime: " + dstAttrs.lastAccessTime());
|
||||||
|
|
||||||
|
// 1-second granularity
|
||||||
|
if (attrs.lastModifiedTime().to(TimeUnit.SECONDS) !=
|
||||||
|
dstAttrs.lastModifiedTime().to(TimeUnit.SECONDS) ||
|
||||||
|
attrs.lastAccessTime().to(TimeUnit.SECONDS) !=
|
||||||
|
dstAttrs.lastAccessTime().to(TimeUnit.SECONDS) ||
|
||||||
|
attrs.creationTime().to(TimeUnit.SECONDS) !=
|
||||||
|
dstAttrs.creationTime().to(TimeUnit.SECONDS)) {
|
||||||
|
throw new RuntimeException("Timestamp Copy Failed!");
|
||||||
|
}
|
||||||
|
Files.delete(fsPath);
|
||||||
|
}
|
||||||
|
|
||||||
private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
|
private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#
|
#
|
||||||
# @test
|
# @test
|
||||||
# @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596
|
# @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596
|
||||||
# 7157656 8002390
|
# 7157656 8002390 7012868 7012856
|
||||||
# @summary Test ZipFileSystem demo
|
# @summary Test ZipFileSystem demo
|
||||||
# @build Basic PathOps ZipFSTester
|
# @build Basic PathOps ZipFSTester
|
||||||
# @run shell basic.sh
|
# @run shell basic.sh
|
||||||
|
@ -277,8 +277,8 @@ public class General {
|
|||||||
{
|
{
|
||||||
check(ans, ask + slash);
|
check(ans, ask + slash);
|
||||||
checkNames(depth, create,
|
checkNames(depth, create,
|
||||||
ans,
|
ans.endsWith(File.separator) ? ans : ans + File.separator,
|
||||||
ask);
|
ask + slash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -308,9 +308,6 @@ public class General {
|
|||||||
String ans, String ask)
|
String ans, String ask)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
ans = ans.endsWith(File.separator) ? ans : ans + File.separator;
|
|
||||||
ask = ask.endsWith(File.separator) ? ask : ask + File.separator;
|
|
||||||
|
|
||||||
int d = depth - 1;
|
int d = depth - 1;
|
||||||
File f = new File(ans);
|
File f = new File(ans);
|
||||||
String n;
|
String n;
|
||||||
|
@ -50,13 +50,13 @@ public class GeneralWin32 extends General {
|
|||||||
private static final int DEPTH = 2;
|
private static final int DEPTH = 2;
|
||||||
private static String baseDir = null;
|
private static String baseDir = null;
|
||||||
private static String userDir = null;
|
private static String userDir = null;
|
||||||
|
private static String relative = null;
|
||||||
|
|
||||||
/* Pathnames relative to working directory */
|
/* Pathnames relative to working directory */
|
||||||
|
|
||||||
private static void checkCaseLookup() throws IOException {
|
private static void checkCaseLookup() throws IOException {
|
||||||
/* Use long names here to avoid 8.3 format, which Samba servers often
|
/* Use long names here to avoid 8.3 format, which Samba servers often
|
||||||
force to lowercase */
|
force to lowercase */
|
||||||
String relative = baseDir.substring(userDir.length() + 1);
|
|
||||||
File d1 = new File(relative, "XyZzY0123");
|
File d1 = new File(relative, "XyZzY0123");
|
||||||
File d2 = new File(d1, "FOO_bar_BAZ");
|
File d2 = new File(d1, "FOO_bar_BAZ");
|
||||||
File f = new File(d2, "GLORPified");
|
File f = new File(d2, "GLORPified");
|
||||||
@ -79,9 +79,9 @@ public class GeneralWin32 extends General {
|
|||||||
case of filenames, rather than just using the input case */
|
case of filenames, rather than just using the input case */
|
||||||
File y = new File(userDir, f.getPath());
|
File y = new File(userDir, f.getPath());
|
||||||
String ans = y.getPath();
|
String ans = y.getPath();
|
||||||
check(ans, relative + "\\" + "XyZzY0123\\FOO_bar_BAZ\\GLORPified");
|
check(ans, relative + "XyZzY0123\\FOO_bar_BAZ\\GLORPified");
|
||||||
check(ans, relative + "\\" + "xyzzy0123\\foo_bar_baz\\glorpified");
|
check(ans, relative + "xyzzy0123\\foo_bar_baz\\glorpified");
|
||||||
check(ans, relative + "\\" + "XYZZY0123\\FOO_BAR_BAZ\\GLORPIFIED");
|
check(ans, relative + "XYZZY0123\\FOO_BAR_BAZ\\GLORPIFIED");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkWild(File f) throws Exception {
|
private static void checkWild(File f) throws Exception {
|
||||||
@ -103,8 +103,7 @@ public class GeneralWin32 extends General {
|
|||||||
private static void checkRelativePaths() throws Exception {
|
private static void checkRelativePaths() throws Exception {
|
||||||
checkCaseLookup();
|
checkCaseLookup();
|
||||||
checkWildCards();
|
checkWildCards();
|
||||||
String relative = baseDir.substring(userDir.length() + 1);
|
checkNames(3, true, baseDir, relative);
|
||||||
checkNames(3, true, baseDir.toString(), relative);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -136,7 +135,6 @@ public class GeneralWin32 extends General {
|
|||||||
String ans = exists ? df.getAbsolutePath() : d;
|
String ans = exists ? df.getAbsolutePath() : d;
|
||||||
if (!ans.endsWith("\\"))
|
if (!ans.endsWith("\\"))
|
||||||
ans = ans + "\\";
|
ans = ans + "\\";
|
||||||
String relative = baseDir.substring(userDir.length() + 1);
|
|
||||||
checkNames(depth, false, ans + relative, d + relative);
|
checkNames(depth, false, ans + relative, d + relative);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,15 +169,16 @@ public class GeneralWin32 extends General {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (args.length > 0) debug = true;
|
if (args.length > 0) debug = true;
|
||||||
userDir = System.getProperty("user.dir");
|
userDir = System.getProperty("user.dir") + '\\';
|
||||||
baseDir = initTestData(6);
|
baseDir = initTestData(6) + '\\';
|
||||||
|
relative = baseDir.substring(userDir.length());
|
||||||
checkRelativePaths();
|
checkRelativePaths();
|
||||||
checkDrivePaths();
|
checkDrivePaths();
|
||||||
checkUncPaths();
|
checkUncPaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String initTestData(int maxDepth) throws IOException {
|
private static String initTestData(int maxDepth) throws IOException {
|
||||||
File parent = new File(System.getProperty("user.dir"));
|
File parent = new File(userDir);
|
||||||
String baseDir = null;
|
String baseDir = null;
|
||||||
maxDepth = maxDepth < DEPTH + 2 ? DEPTH + 2 : maxDepth;
|
maxDepth = maxDepth < DEPTH + 2 ? DEPTH + 2 : maxDepth;
|
||||||
for (int i = 0; i < maxDepth; i ++) {
|
for (int i = 0; i < maxDepth; i ++) {
|
||||||
|
194
jdk/test/java/lang/IntegralPrimitiveToString.java
Normal file
194
jdk/test/java/lang/IntegralPrimitiveToString.java
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.testng.annotations.DataProvider;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.LongFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @run testng IntegralPrimitiveToString
|
||||||
|
* @summary test string conversions for primitive integral types.
|
||||||
|
* @author Mike Duigou
|
||||||
|
*/
|
||||||
|
public class IntegralPrimitiveToString {
|
||||||
|
|
||||||
|
@Test(dataProvider="numbers")
|
||||||
|
public <N extends Number> void testToString(String description,
|
||||||
|
Function<N, BigInteger> converter,
|
||||||
|
Function<N, BigInteger> unsignedConverter,
|
||||||
|
N[] values,
|
||||||
|
Stringifier<N>[] stringifiers) {
|
||||||
|
System.out.printf("%s : conversions: %d values: %d\n", description, stringifiers.length, values.length);
|
||||||
|
for( N value : values) {
|
||||||
|
BigInteger asBigInt = converter.apply(value);
|
||||||
|
BigInteger asUnsignedBigInt = unsignedConverter.apply(value);
|
||||||
|
for(Stringifier<N> stringifier : stringifiers) {
|
||||||
|
stringifier.assertMatchingToString(value, asBigInt, asUnsignedBigInt, description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Stringifier<N extends Number> {
|
||||||
|
final boolean signed;
|
||||||
|
final int radix;
|
||||||
|
final Function<N,String> toString;
|
||||||
|
Stringifier(boolean signed, int radix, Function<N,String> toString) {
|
||||||
|
this.signed = signed;
|
||||||
|
this.radix = radix;
|
||||||
|
this.toString = toString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertMatchingToString(N value, BigInteger asSigned, BigInteger asUnsigned, String description) {
|
||||||
|
String expected = signed
|
||||||
|
? asSigned.toString(radix)
|
||||||
|
: asUnsigned.toString(radix);
|
||||||
|
|
||||||
|
String actual = toString.apply(value);
|
||||||
|
|
||||||
|
assertEquals(actual, expected, description + " conversion should be the same");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@DataProvider(name="numbers", parallel=true)
|
||||||
|
public Iterator<Object[]> testSetProvider() {
|
||||||
|
|
||||||
|
return Arrays.asList(
|
||||||
|
new Object[] { "Byte",
|
||||||
|
(Function<Byte,BigInteger>) b -> BigInteger.valueOf((long) b),
|
||||||
|
(Function<Byte,BigInteger>) b -> BigInteger.valueOf(Integer.toUnsignedLong((byte) b)),
|
||||||
|
numberProvider((LongFunction<Byte>) l -> Byte.valueOf((byte) l), Byte.SIZE),
|
||||||
|
new Stringifier[] {
|
||||||
|
new Stringifier<Byte>(true, 10, b -> b.toString()),
|
||||||
|
new Stringifier<Byte>(true, 10, b -> Byte.toString(b))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Object[] { "Short",
|
||||||
|
(Function<Short,BigInteger>) s -> BigInteger.valueOf((long) s),
|
||||||
|
(Function<Short,BigInteger>) s -> BigInteger.valueOf(Integer.toUnsignedLong((short) s)),
|
||||||
|
numberProvider((LongFunction<Short>) l -> Short.valueOf((short) l), Short.SIZE),
|
||||||
|
new Stringifier[] {
|
||||||
|
new Stringifier<Short>(true, 10, s -> s.toString()),
|
||||||
|
new Stringifier<Short>(true, 10, s -> Short.toString( s))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Object[] { "Integer",
|
||||||
|
(Function<Integer,BigInteger>) i -> BigInteger.valueOf((long) i),
|
||||||
|
(Function<Integer,BigInteger>) i -> BigInteger.valueOf(Integer.toUnsignedLong(i)),
|
||||||
|
numberProvider((LongFunction<Integer>) l -> Integer.valueOf((int) l), Integer.SIZE),
|
||||||
|
new Stringifier[] {
|
||||||
|
new Stringifier<Integer>(true, 10, i -> i.toString()),
|
||||||
|
new Stringifier<Integer>(true, 10, i -> Integer.toString(i)),
|
||||||
|
new Stringifier<Integer>(false, 2, Integer::toBinaryString),
|
||||||
|
new Stringifier<Integer>(false, 16, Integer::toHexString),
|
||||||
|
new Stringifier<Integer>(false, 8, Integer::toOctalString),
|
||||||
|
new Stringifier<Integer>(true, 2, i -> Integer.toString(i, 2)),
|
||||||
|
new Stringifier<Integer>(true, 8, i -> Integer.toString(i, 8)),
|
||||||
|
new Stringifier<Integer>(true, 10, i -> Integer.toString(i, 10)),
|
||||||
|
new Stringifier<Integer>(true, 16, i -> Integer.toString(i, 16)),
|
||||||
|
new Stringifier<Integer>(true, Character.MAX_RADIX, i -> Integer.toString(i, Character.MAX_RADIX)),
|
||||||
|
new Stringifier<Integer>(false, 10, i -> Integer.toUnsignedString(i)),
|
||||||
|
new Stringifier<Integer>(false, 2, i -> Integer.toUnsignedString(i, 2)),
|
||||||
|
new Stringifier<Integer>(false, 8, i -> Integer.toUnsignedString(i, 8)),
|
||||||
|
new Stringifier<Integer>(false, 10, i -> Integer.toUnsignedString(i, 10)),
|
||||||
|
new Stringifier<Integer>(false, 16, i -> Integer.toUnsignedString(i, 16)),
|
||||||
|
new Stringifier<Integer>(false, Character.MAX_RADIX, i -> Integer.toUnsignedString(i, Character.MAX_RADIX))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Object[] { "Long",
|
||||||
|
(Function<Long, BigInteger>) BigInteger::valueOf,
|
||||||
|
(Function<Long, BigInteger>) l -> {
|
||||||
|
if (l >= 0) {
|
||||||
|
return BigInteger.valueOf((long) l);
|
||||||
|
} else {
|
||||||
|
int upper = (int)(l >>> 32);
|
||||||
|
int lower = (int) (long) l;
|
||||||
|
|
||||||
|
// return (upper << 32) + lower
|
||||||
|
return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
|
||||||
|
add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
numberProvider((LongFunction<Long>) Long::valueOf, Long.SIZE),
|
||||||
|
new Stringifier[] {
|
||||||
|
new Stringifier<Long>(true, 10, l -> l.toString()),
|
||||||
|
new Stringifier<Long>(true, 10, l -> Long.toString(l)),
|
||||||
|
new Stringifier<Long>(false, 2, Long::toBinaryString),
|
||||||
|
new Stringifier<Long>(false, 16, Long::toHexString),
|
||||||
|
new Stringifier<Long>(false, 8, Long::toOctalString),
|
||||||
|
new Stringifier<Long>(true, 2, l -> Long.toString(l, 2)),
|
||||||
|
new Stringifier<Long>(true, 8, l -> Long.toString(l, 8)),
|
||||||
|
new Stringifier<Long>(true, 10, l -> Long.toString(l, 10)),
|
||||||
|
new Stringifier<Long>(true, 16, l -> Long.toString(l, 16)),
|
||||||
|
new Stringifier<Long>(true, Character.MAX_RADIX, l -> Long.toString(l, Character.MAX_RADIX)),
|
||||||
|
new Stringifier<Long>(false, 10, Long::toUnsignedString),
|
||||||
|
new Stringifier<Long>(false, 2, l -> Long.toUnsignedString(l, 2)),
|
||||||
|
new Stringifier<Long>(false, 8, l-> Long.toUnsignedString(l, 8)),
|
||||||
|
new Stringifier<Long>(false, 10, l -> Long.toUnsignedString(l, 10)),
|
||||||
|
new Stringifier<Long>(false, 16, l -> Long.toUnsignedString(l, 16)),
|
||||||
|
new Stringifier<Long>(false, Character.MAX_RADIX, l -> Long.toUnsignedString(l, Character.MAX_RADIX))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).iterator();
|
||||||
|
}
|
||||||
|
private static final long[] SOME_PRIMES = {
|
||||||
|
3L, 5L, 7L, 11L, 13L, 17L, 19L, 23L, 29L, 31L, 37L, 41L, 43L, 47L, 53L,
|
||||||
|
59L, 61L, 71L, 73L, 79L, 83L, 89L, 97L, 101L, 103L, 107L, 109L, 113L,
|
||||||
|
5953L, 5981L, 5987L, 6007L, 6011L, 6029L, 6037L, 6043L, 6047L, 6053L,
|
||||||
|
16369L, 16381L, 16411L, 32749L, 32771L, 65521L, 65537L,
|
||||||
|
(long) Integer.MAX_VALUE };
|
||||||
|
|
||||||
|
public <N extends Number> N[] numberProvider(LongFunction<N> boxer, int bits, N... extras) {
|
||||||
|
List<N> numbers = new ArrayList<>();
|
||||||
|
|
||||||
|
for(int bitmag = 0; bitmag < bits; bitmag++) {
|
||||||
|
long value = 1L << bitmag;
|
||||||
|
numbers.add(boxer.apply(value));
|
||||||
|
numbers.add(boxer.apply(value - 1));
|
||||||
|
numbers.add(boxer.apply(value + 1));
|
||||||
|
numbers.add(boxer.apply(-value));
|
||||||
|
for(int divisor = 0; divisor < SOME_PRIMES.length && value < SOME_PRIMES[divisor]; divisor++) {
|
||||||
|
numbers.add(boxer.apply(value - SOME_PRIMES[divisor]));
|
||||||
|
numbers.add(boxer.apply(value + SOME_PRIMES[divisor]));
|
||||||
|
numbers.add(boxer.apply(value * SOME_PRIMES[divisor]));
|
||||||
|
numbers.add(boxer.apply(value / SOME_PRIMES[divisor]));
|
||||||
|
numbers.add(boxer.apply(value | SOME_PRIMES[divisor]));
|
||||||
|
numbers.add(boxer.apply(value & SOME_PRIMES[divisor]));
|
||||||
|
numbers.add(boxer.apply(value ^ SOME_PRIMES[divisor]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
numbers.addAll(Arrays.asList(extras));
|
||||||
|
|
||||||
|
return (N[]) numbers.toArray(new Number[numbers.size()]);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -36,6 +36,10 @@ import java.util.*;
|
|||||||
import javax.management.*;
|
import javax.management.*;
|
||||||
|
|
||||||
public class MXBeanBehavior {
|
public class MXBeanBehavior {
|
||||||
|
// Exclude list: list of platform MBeans that are not MXBeans
|
||||||
|
public static final HashSet<String> excludeList = new HashSet<>(
|
||||||
|
Arrays.asList("com.sun.management:type=DiagnosticCommand"));
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
||||||
|
|
||||||
@ -92,6 +96,10 @@ public class MXBeanBehavior {
|
|||||||
by generic MXBean tests.
|
by generic MXBean tests.
|
||||||
*/
|
*/
|
||||||
private static void test(MBeanServer mbs, ObjectName name) throws Exception {
|
private static void test(MBeanServer mbs, ObjectName name) throws Exception {
|
||||||
|
if(excludeList.contains(name.getCanonicalName())) {
|
||||||
|
// Skipping not MXBean objects.
|
||||||
|
return;
|
||||||
|
}
|
||||||
System.out.println("Testing: " + name);
|
System.out.println("Testing: " + name);
|
||||||
|
|
||||||
MBeanInfo mbi = mbs.getMBeanInfo(name);
|
MBeanInfo mbi = mbs.getMBeanInfo(name);
|
||||||
|
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