This commit is contained in:
Bob Vandette 2018-06-12 18:53:38 -04:00
commit deba30de16
2767 changed files with 221508 additions and 36593 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,213 @@
/*
* Copyright (c) 2018, 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.crypto.provider;
import java.io.IOException;
import java.security.AlgorithmParametersSpi;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import javax.crypto.spec.IvParameterSpec;
import sun.security.util.*;
/**
* This class implements the parameter set used with the ChaCha20-Poly1305
* algorithm. The parameter definition comes from
* <a href="https://tools.ietf.org/html/rfc8103"><i>RFC 8103</i></a>
* and is defined according to the following ASN.1:
*
* <pre>
* id-alg-AEADChaCha20Poly1305 OBJECT IDENTIFIER ::=
{ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
pkcs9(9) smime(16) alg(3) 18 }
* AEADChaCha20Poly1305Nonce ::= OCTET STRING (SIZE(12))
* </pre>
*
* The AlgorithmParameters may be instantiated either by its name
* ("ChaCha20-Poly1305") or via its OID (1.2.840.113549.1.9.16.3.18)
*/
public final class ChaCha20Poly1305Parameters extends AlgorithmParametersSpi {
private static final String DEFAULT_FMT = "ASN.1";
private byte[] nonce;
public ChaCha20Poly1305Parameters() {}
/**
* Initialize the ChaCha20Poly1305Parameters using an IvParameterSpec.
*
* @param paramSpec the {@code IvParameterSpec} used to configure
* this object.
*
* @throws InvalidParameterSpecException if an object of a type other
* than {@code IvParameterSpec} is used.
*/
@Override
protected void engineInit(AlgorithmParameterSpec paramSpec)
throws InvalidParameterSpecException {
if (!(paramSpec instanceof IvParameterSpec)) {
throw new InvalidParameterSpecException
("Inappropriate parameter specification");
}
IvParameterSpec ivps = (IvParameterSpec)paramSpec;
// Obtain the nonce
nonce = ivps.getIV();
if (nonce.length != 12) {
throw new InvalidParameterSpecException("ChaCha20-Poly1305 nonce" +
" must be 12 bytes in length");
}
}
/**
* Initialize the ChaCha20Poly1305Parameters from a DER encoded
* parameter block.
* @param encoded the DER encoding of the nonce as an OCTET STRING.
*
* @throws IOException if the encoded nonce is not 12 bytes long or a DER
* decoding error occurs.
*/
@Override
protected void engineInit(byte[] encoded) throws IOException {
DerValue val = new DerValue(encoded);
// Get the nonce value
nonce = val.getOctetString();
if (nonce.length != 12) {
throw new IOException(
"ChaCha20-Poly1305 nonce must be 12 bytes in length");
}
}
/**
* Initialize the ChaCha20Poly1305Parameters from a DER encoded
* parameter block.
*
* @param encoded the DER encoding of the nonce and initial block counter.
* @param decodingMethod the decoding method. The only currently accepted
* value is "ASN.1"
*
* @throws IOException if the encoded nonce is not 12 bytes long, a DER
* decoding error occurs, or an unsupported decoding method is
* provided.
*/
@Override
protected void engineInit(byte[] encoded, String decodingMethod)
throws IOException {
if (decodingMethod == null ||
decodingMethod.equalsIgnoreCase(DEFAULT_FMT)) {
engineInit(encoded);
} else {
throw new IOException("Unsupported parameter format: " +
decodingMethod);
}
}
/**
* Return an IvParameterSpec with the same parameters as those
* held in this object.
*
* @param paramSpec the class name of the spec. In this case it should
* be {@code IvParameterSpec.class}.
*
* @return a {@code IvParameterSpec} object containing the nonce
* value held in this object.
*
* @throws InvalidParameterSpecException if a class other than
* {@code IvParameterSpec.class} was specified in the paramSpec
* parameter.
*/
@Override
protected <T extends AlgorithmParameterSpec>
T engineGetParameterSpec(Class<T> paramSpec)
throws InvalidParameterSpecException {
if (IvParameterSpec.class.isAssignableFrom(paramSpec)) {
return paramSpec.cast(new IvParameterSpec(nonce));
} else {
throw new InvalidParameterSpecException
("Inappropriate parameter specification");
}
}
/**
* Return the encoded parameters in ASN.1 form.
*
* @return a byte array containing the DER-encoding for the
* ChaCha20-Poly1305 parameters. This will be the nonce
* encoded as a DER OCTET STRING.
*
* @throws IOException if any DER encoding error occurs.
*/
@Override
protected byte[] engineGetEncoded() throws IOException {
DerOutputStream out = new DerOutputStream();
out.write(DerValue.tag_OctetString, nonce);
return out.toByteArray();
}
/**
* Return the encoded parameters in ASN.1 form.
*
* @param encodingMethod the encoding method to be used. This parameter
* must be "ASN.1" as it is the only currently supported encoding
* format. If the parameter is {@code null} then the default
* encoding format will be used.
*
* @return a byte array containing the DER-encoding for the
* ChaCha20-Poly1305 parameters.
*
* @throws IOException if any DER encoding error occurs or an unsupported
* encoding method is provided.
*/
@Override
protected byte[] engineGetEncoded(String encodingMethod)
throws IOException {
if (encodingMethod == null ||
encodingMethod.equalsIgnoreCase(DEFAULT_FMT)) {
return engineGetEncoded();
} else {
throw new IOException("Unsupported encoding format: " +
encodingMethod);
}
}
/**
* Creates a formatted string describing the parameters.
*
* @return a string representation of the ChaCha20 parameters.
*/
@Override
protected String engineToString() {
String LINE_SEP = System.lineSeparator();
HexDumpEncoder encoder = new HexDumpEncoder();
StringBuilder sb = new StringBuilder(LINE_SEP + "nonce:" +
LINE_SEP + "[" + encoder.encodeBuffer(nonce) + "]");
return sb.toString();
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2018, 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
@ -111,16 +111,20 @@ final class KeyGeneratorCore {
protected HmacSHA2KG(String algoName, int len) {
core = new KeyGeneratorCore(algoName, len);
}
@Override
protected void engineInit(SecureRandom random) {
core.implInit(random);
}
@Override
protected void engineInit(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
core.implInit(params, random);
}
@Override
protected void engineInit(int keySize, SecureRandom random) {
core.implInit(keySize, random);
}
@Override
protected SecretKey engineGenerateKey() {
return core.implGenerateKey();
}
@ -153,13 +157,16 @@ final class KeyGeneratorCore {
public RC2KeyGenerator() {
core = new KeyGeneratorCore("RC2", 128);
}
@Override
protected void engineInit(SecureRandom random) {
core.implInit(random);
}
@Override
protected void engineInit(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
core.implInit(params, random);
}
@Override
protected void engineInit(int keySize, SecureRandom random) {
if ((keySize < 40) || (keySize > 1024)) {
throw new InvalidParameterException("Key length for RC2"
@ -167,6 +174,7 @@ final class KeyGeneratorCore {
}
core.implInit(keySize, random);
}
@Override
protected SecretKey engineGenerateKey() {
return core.implGenerateKey();
}
@ -178,13 +186,16 @@ final class KeyGeneratorCore {
public ARCFOURKeyGenerator() {
core = new KeyGeneratorCore("ARCFOUR", 128);
}
@Override
protected void engineInit(SecureRandom random) {
core.implInit(random);
}
@Override
protected void engineInit(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
core.implInit(params, random);
}
@Override
protected void engineInit(int keySize, SecureRandom random) {
if ((keySize < 40) || (keySize > 1024)) {
throw new InvalidParameterException("Key length for ARCFOUR"
@ -192,9 +203,38 @@ final class KeyGeneratorCore {
}
core.implInit(keySize, random);
}
@Override
protected SecretKey engineGenerateKey() {
return core.implGenerateKey();
}
}
// nested static class for the ChaCha20 key generator
public static final class ChaCha20KeyGenerator extends KeyGeneratorSpi {
private final KeyGeneratorCore core;
public ChaCha20KeyGenerator() {
core = new KeyGeneratorCore("ChaCha20", 256);
}
@Override
protected void engineInit(SecureRandom random) {
core.implInit(random);
}
@Override
protected void engineInit(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
core.implInit(params, random);
}
@Override
protected void engineInit(int keySize, SecureRandom random) {
if (keySize != 256) {
throw new InvalidParameterException(
"Key length for ChaCha20 must be 256 bits");
}
core.implInit(keySize, random);
}
@Override
protected SecretKey engineGenerateKey() {
return core.implGenerateKey();
}
}
}

View file

@ -0,0 +1,257 @@
/*
* Copyright (c) 2018, 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.crypto.provider;
import java.nio.ByteBuffer;
import java.security.Key;
import java.security.InvalidKeyException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
import java.util.Objects;
import sun.security.util.math.*;
import sun.security.util.math.intpoly.*;
/**
* This class represents the Poly1305 function defined in RFC 7539.
*
* This function is used in the implementation of ChaCha20/Poly1305
* AEAD mode.
*/
final class Poly1305 {
private static final int KEY_LENGTH = 32;
private static final int RS_LENGTH = KEY_LENGTH / 2;
private static final int BLOCK_LENGTH = 16;
private static final int TAG_LENGTH = 16;
private static final IntegerFieldModuloP ipl1305 =
new IntegerPolynomial1305();
private byte[] keyBytes;
private final byte[] block = new byte[BLOCK_LENGTH];
private int blockOffset;
private IntegerModuloP r;
private IntegerModuloP s;
private MutableIntegerModuloP a;
private final MutableIntegerModuloP n = ipl1305.get1().mutable();
Poly1305() { }
/**
* Initialize the Poly1305 object
*
* @param newKey the {@code Key} which will be used for the authentication.
* @param params this parameter is unused.
*
* @throws InvalidKeyException if {@code newKey} is {@code null} or is
* not 32 bytes in length.
*/
void engineInit(Key newKey, AlgorithmParameterSpec params)
throws InvalidKeyException {
Objects.requireNonNull(newKey, "Null key provided during init");
keyBytes = newKey.getEncoded();
if (keyBytes == null) {
throw new InvalidKeyException("Key does not support encoding");
} else if (keyBytes.length != KEY_LENGTH) {
throw new InvalidKeyException("Incorrect length for key: " +
keyBytes.length);
}
engineReset();
setRSVals();
}
/**
* Returns the length of the MAC (authentication tag).
*
* @return the length of the auth tag, which is always 16 bytes.
*/
int engineGetMacLength() {
return TAG_LENGTH;
}
/**
* Reset the Poly1305 object, discarding any current operation but
* maintaining the same key.
*/
void engineReset() {
// Clear the block and reset the offset
Arrays.fill(block, (byte)0);
blockOffset = 0;
// Discard any previous accumulator and start at zero
a = ipl1305.get0().mutable();
}
/**
* Update the MAC with bytes from a {@code ByteBuffer}
*
* @param buf the {@code ByteBuffer} containing the data to be consumed.
* Upon return the buffer's position will be equal to its limit.
*/
void engineUpdate(ByteBuffer buf) {
int remaining = buf.remaining();
while (remaining > 0) {
int bytesToWrite = Integer.min(remaining,
BLOCK_LENGTH - blockOffset);
if (bytesToWrite >= BLOCK_LENGTH) {
// If bytes to write == BLOCK_LENGTH, then we have no
// left-over data from previous updates and we can create
// the IntegerModuloP directly from the input buffer.
processBlock(buf, bytesToWrite);
} else {
// We have some left-over data from previous updates, so
// copy that into the holding block until we get a full block.
buf.get(block, blockOffset, bytesToWrite);
blockOffset += bytesToWrite;
if (blockOffset >= BLOCK_LENGTH) {
processBlock(block, 0, BLOCK_LENGTH);
blockOffset = 0;
}
}
remaining -= bytesToWrite;
}
}
/**
* Update the MAC with bytes from an array.
*
* @param input the input bytes.
* @param offset the starting index from which to update the MAC.
* @param len the number of bytes to process.
*/
void engineUpdate(byte[] input, int offset, int len) {
Objects.checkFromIndexSize(offset, len, input.length);
if (blockOffset > 0) {
// We have some left-over data from previous updates
int blockSpaceLeft = BLOCK_LENGTH - blockOffset;
if (len < blockSpaceLeft) {
System.arraycopy(input, offset, block, blockOffset, len);
blockOffset += len;
return; // block wasn't filled
} else {
System.arraycopy(input, offset, block, blockOffset,
blockSpaceLeft);
offset += blockSpaceLeft;
len -= blockSpaceLeft;
processBlock(block, 0, BLOCK_LENGTH);
blockOffset = 0;
}
}
while (len >= BLOCK_LENGTH) {
processBlock(input, offset, BLOCK_LENGTH);
offset += BLOCK_LENGTH;
len -= BLOCK_LENGTH;
}
if (len > 0) { // and len < BLOCK_LENGTH
System.arraycopy(input, offset, block, 0, len);
blockOffset = len;
}
}
/**
* Update the MAC with a single byte of input
*
* @param input the byte to update the MAC with.
*/
void engineUpdate(byte input) {
assert (blockOffset < BLOCK_LENGTH);
// we can't hold fully filled unprocessed block
block[blockOffset++] = input;
if (blockOffset == BLOCK_LENGTH) {
processBlock(block, 0, BLOCK_LENGTH);
blockOffset = 0;
}
}
/**
* Finish the authentication operation and reset the MAC for a new
* authentication operation.
*
* @return the authentication tag as a byte array.
*/
byte[] engineDoFinal() {
byte[] tag = new byte[BLOCK_LENGTH];
// Finish up: process any remaining data < BLOCK_SIZE, then
// create the tag from the resulting little-endian integer.
if (blockOffset > 0) {
processBlock(block, 0, blockOffset);
blockOffset = 0;
}
// Add in the s-half of the key to the accumulator
a.addModPowerTwo(s, tag);
// Reset for the next auth
engineReset();
return tag;
}
/**
* Process a single block of data. This should only be called
* when the block array is complete. That may not necessarily
* be a full 16 bytes if the last block has less than 16 bytes.
*/
private void processBlock(ByteBuffer buf, int len) {
n.setValue(buf, len, (byte)0x01);
a.setSum(n); // a += (n | 0x01)
a.setProduct(r); // a = (a * r) % p
}
private void processBlock(byte[] block, int offset, int length) {
Objects.checkFromIndexSize(offset, length, block.length);
n.setValue(block, offset, length, (byte)0x01);
a.setSum(n); // a += (n | 0x01)
a.setProduct(r); // a = (a * r) % p
}
/**
* Partition the authentication key into the R and S components, clamp
* the R value, and instantiate IntegerModuloP objects to R and S's
* numeric values.
*/
private void setRSVals() {
// Clamp the bytes in the "r" half of the key.
keyBytes[3] &= 15;
keyBytes[7] &= 15;
keyBytes[11] &= 15;
keyBytes[15] &= 15;
keyBytes[4] &= 252;
keyBytes[8] &= 252;
keyBytes[12] &= 252;
// Create IntegerModuloP elements from the r and s values
r = ipl1305.getElement(keyBytes, 0, RS_LENGTH, (byte)0);
s = ipl1305.getElement(keyBytes, RS_LENGTH, RS_LENGTH, (byte)0);
}
}

View file

@ -57,6 +57,8 @@ import static sun.security.util.SecurityConstants.PROVIDER_VER;
*
* - ARCFOUR (RC4 compatible)
*
* - ChaCha20 (Stream cipher only and in AEAD mode with Poly1305)
*
* - Cipher modes ECB, CBC, CFB, OFB, PCBC, CTR, and CTS for all block ciphers
* and mode GCM for AES cipher
*
@ -77,7 +79,7 @@ public final class SunJCE extends Provider {
private static final String info = "SunJCE Provider " +
"(implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, "
+ "Diffie-Hellman, HMAC)";
+ "Diffie-Hellman, HMAC, ChaCha20)";
private static final String OID_PKCS12_RC4_128 = "1.2.840.113549.1.12.1.1";
private static final String OID_PKCS12_RC4_40 = "1.2.840.113549.1.12.1.2";
@ -336,6 +338,15 @@ public final class SunJCE extends Provider {
put("Cipher.ARCFOUR SupportedPaddings", "NOPADDING");
put("Cipher.ARCFOUR SupportedKeyFormats", "RAW");
put("Cipher.ChaCha20",
"com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Only");
put("Cipher.ChaCha20 SupportedKeyFormats", "RAW");
put("Cipher.ChaCha20-Poly1305",
"com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305");
put("Cipher.ChaCha20-Poly1305 SupportedKeyFormats", "RAW");
put("Alg.Alias.Cipher.1.2.840.113549.1.9.16.3.18", "ChaCha20-Poly1305");
put("Alg.Alias.Cipher.OID.1.2.840.113549.1.9.16.3.18", "ChaCha20-Poly1305");
/*
* Key(pair) Generator engines
*/
@ -361,6 +372,10 @@ public final class SunJCE extends Provider {
"ARCFOURKeyGenerator");
put("Alg.Alias.KeyGenerator.RC4", "ARCFOUR");
put("KeyGenerator.ChaCha20",
"com.sun.crypto.provider.KeyGeneratorCore$" +
"ChaCha20KeyGenerator");
put("KeyGenerator.HmacMD5",
"com.sun.crypto.provider.HmacMD5KeyGenerator");
@ -541,6 +556,9 @@ public final class SunJCE extends Provider {
put("AlgorithmParameters.OAEP",
"com.sun.crypto.provider.OAEPParameters");
put("AlgorithmParameters.ChaCha20-Poly1305",
"com.sun.crypto.provider.ChaCha20Poly1305Parameters");
/*
* Key factories
*/

View file

@ -1419,7 +1419,8 @@ class Character implements java.io.Serializable, Comparable<Character> {
"YIRADICALS");
/**
* Constant for the "Cyrillic Supplementary" Unicode character block.
* Constant for the "Cyrillic Supplement" Unicode character block.
* This block was previously known as the "Cyrillic Supplementary" block.
* @since 1.5
*/
public static final UnicodeBlock CYRILLIC_SUPPLEMENTARY =

View file

@ -333,12 +333,12 @@ public class Object {
* by being <em>notified</em> or <em>interrupted</em>, or until a
* certain amount of real time has elapsed.
* <p>
* In all respects, this method behaves as if {@code wait(timeout, 0)}
* In all respects, this method behaves as if {@code wait(timeoutMillis, 0)}
* had been called. See the specification of the {@link #wait(long, int)} method
* for details.
*
* @param timeout the maximum time to wait, in milliseconds
* @throws IllegalArgumentException if the value of {@code timeout} is negative
* @param timeoutMillis the maximum time to wait, in milliseconds
* @throws IllegalArgumentException if {@code timeoutMillis} is negative
* @throws IllegalMonitorStateException if the current thread is not
* the owner of the object's monitor
* @throws InterruptedException if any thread interrupted the current thread before or
@ -349,7 +349,7 @@ public class Object {
* @see #wait()
* @see #wait(long, int)
*/
public final native void wait(long timeout) throws InterruptedException;
public final native void wait(long timeoutMillis) throws InterruptedException;
/**
* Causes the current thread to wait until it is awakened, typically
@ -378,7 +378,7 @@ public class Object {
* thread <var>T</var>.
* <li>The specified amount of real time has elapsed, more or less.
* The amount of real time, in nanoseconds, is given by the expression
* {@code 1000000 * timeout + nanos}. If {@code timeout} and {@code nanos}
* {@code 1000000 * timeoutMillis + nanos}. If {@code timeoutMillis} and {@code nanos}
* are both zero, then real time is not taken into consideration and the
* thread waits until awakened by one of the other causes.
* <li>Thread <var>T</var> is awakened spuriously. (See below.)
@ -423,17 +423,17 @@ public class Object {
* <pre>{@code
* synchronized (obj) {
* while (<condition does not hold> and <timeout not exceeded>) {
* long timeout = ... ; // recompute timeout values
* long timeoutMillis = ... ; // recompute timeout values
* int nanos = ... ;
* obj.wait(timeout, nanos);
* obj.wait(timeoutMillis, nanos);
* }
* ... // Perform action appropriate to condition or timeout
* }
* }</pre>
*
* @param timeout the maximum time to wait, in milliseconds
* @param timeoutMillis the maximum time to wait, in milliseconds
* @param nanos additional time, in nanoseconds, in the range range 0-999999 inclusive
* @throws IllegalArgumentException if the value of {@code timeout} is negative,
* @throws IllegalArgumentException if {@code timeoutMillis} is negative,
* or if the value of {@code nanos} is out of range
* @throws IllegalMonitorStateException if the current thread is not
* the owner of the object's monitor
@ -445,9 +445,9 @@ public class Object {
* @see #wait()
* @see #wait(long)
*/
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
if (timeoutMillis < 0) {
throw new IllegalArgumentException("timeoutMillis value is negative");
}
if (nanos < 0 || nanos > 999999) {
@ -456,10 +456,10 @@ public class Object {
}
if (nanos > 0) {
timeout++;
timeoutMillis++;
}
wait(timeout);
wait(timeoutMillis);
}
/**

View file

@ -607,8 +607,9 @@ public final class System {
* <tr><th scope="row">{@code java.home}</th>
* <td>Java installation directory</td></tr>
* <tr><th scope="row">{@code java.vm.specification.version}</th>
* <td>Java Virtual Machine specification version which may be
* interpreted as a {@link Runtime.Version}</td></tr>
* <td>Java Virtual Machine specification version, whose value is the
* {@linkplain Runtime.Version#feature feature} element of the
* {@linkplain Runtime#version() runtime version}</td></tr>
* <tr><th scope="row">{@code java.vm.specification.vendor}</th>
* <td>Java Virtual Machine specification vendor</td></tr>
* <tr><th scope="row">{@code java.vm.specification.name}</th>
@ -621,8 +622,9 @@ public final class System {
* <tr><th scope="row">{@code java.vm.name}</th>
* <td>Java Virtual Machine implementation name</td></tr>
* <tr><th scope="row">{@code java.specification.version}</th>
* <td>Java Runtime Environment specification version which may be
* interpreted as a {@link Runtime.Version}</td></tr>
* <td>Java Runtime Environment specification version, whose value is
* the {@linkplain Runtime.Version#feature feature} element of the
* {@linkplain Runtime#version() runtime version}</td></tr>
* <tr><th scope="row">{@code java.specification.vendor}</th>
* <td>Java Runtime Environment specification vendor</td></tr>
* <tr><th scope="row">{@code java.specification.name}</th>

View file

@ -937,26 +937,6 @@ class Thread implements Runnable {
stop0(new ThreadDeath());
}
/**
* Throws {@code UnsupportedOperationException}.
*
* @param obj ignored
*
* @deprecated This method was originally designed to force a thread to stop
* and throw a given {@code Throwable} as an exception. It was
* inherently unsafe (see {@link #stop()} for details), and furthermore
* could be used to generate exceptions that the target thread was
* not prepared to handle.
* For more information, see
* <a href="{@docRoot}/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html">Why
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
* This method is subject to removal in a future version of Java SE.
*/
@Deprecated(since="1.2", forRemoval=true)
public final synchronized void stop(Throwable obj) {
throw new UnsupportedOperationException();
}
/**
* Interrupts this thread.
*
@ -1061,29 +1041,6 @@ class Thread implements Runnable {
@HotSpotIntrinsicCandidate
private native boolean isInterrupted(boolean ClearInterrupted);
/**
* Throws {@link NoSuchMethodError}.
*
* @deprecated This method was originally designed to destroy this
* thread without any cleanup. Any monitors it held would have
* remained locked. However, the method was never implemented.
* If it were to be implemented, it would be deadlock-prone in
* much the manner of {@link #suspend}. If the target thread held
* a lock protecting a critical system resource when it was
* destroyed, no thread could ever access this resource again.
* If another thread ever attempted to lock this resource, deadlock
* would result. Such deadlocks typically manifest themselves as
* "frozen" processes. For more information, see
* <a href="{@docRoot}/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html">
* Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
* This method is subject to removal in a future version of Java SE.
* @throws NoSuchMethodError always
*/
@Deprecated(since="1.5", forRemoval=true)
public void destroy() {
throw new NoSuchMethodError();
}
/**
* Tests if this thread is alive. A thread is alive if it has
* been started and has not yet died.

View file

@ -62,21 +62,6 @@ it succeeded. The code to ensure this would be quite complex.</li>
</ol>
In sum, it just isn't practical.
<hr>
<h3>What about <code>Thread.stop(Throwable)</code>?</h3>
<p>In addition to all of the problems noted above, this method may
be used to generate exceptions that its target thread is unprepared
to handle (including checked exceptions that the thread could not
possibly throw, were it not for this method). For example, the
following method is behaviorally identical to Java's
<code>throw</code> operation, but circumvents the compiler's
attempts to guarantee that the calling method has declared all of
the checked exceptions that it may throw:</p>
<pre>
static void sneakyThrow(Throwable t) {
Thread.currentThread().stop(t);
}
</pre>
<hr>
<h3>What should I use instead of <code>Thread.stop</code>?</h3>
<p>Most uses of <code>stop</code> should be replaced by code that
simply modifies some variable to indicate that the target thread
@ -339,13 +324,6 @@ If the <code>stop</code> method calls <code>Thread.interrupt</code>, as
described above, it needn't call <code>notify</code> as well, but it
still must be synchronized. This ensures that the target thread
won't miss an interrupt due to a race condition.
<hr>
<h3>What about <code>Thread.destroy</code>?</h3>
<code>Thread.destroy</code> was never implemented and has been
deprecated. If it were implemented, it would be deadlock-prone in
the manner of <code>Thread.suspend</code>. (In fact, it is roughly
equivalent to <code>Thread.suspend</code> without the possibility
of a subsequent <code>Thread.resume</code>.)
<p><!-- Body text ends here --></p>
</body>
</html>

View file

@ -134,6 +134,8 @@ final class BootstrapMethodInvoker {
String recipe = (String)argv[0];
Object[] shiftedArgs = Arrays.copyOfRange(argv, 1, argv.length);
result = (CallSite)bootstrapMethod.invokeExact(caller, name, (MethodType)type, recipe, shiftedArgs);
} else if (isLambdaMetafactoryAltMetafactoryBSM(bsmType)) {
result = (CallSite)bootstrapMethod.invokeExact(caller, name, (MethodType)type, argv);
} else {
switch (argv.length) {
case 0:
@ -286,6 +288,9 @@ final class BootstrapMethodInvoker {
private static final MethodType LMF_INDY_MT = MethodType.methodType(CallSite.class,
Lookup.class, String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
private static final MethodType LMF_ALT_MT = MethodType.methodType(CallSite.class,
Lookup.class, String.class, MethodType.class, Object[].class);
private static final MethodType LMF_CONDY_MT = MethodType.methodType(Object.class,
Lookup.class, String.class, Class.class, MethodType.class, MethodHandle.class, MethodType.class);
@ -319,6 +324,15 @@ final class BootstrapMethodInvoker {
return bsmType == LMF_INDY_MT;
}
/**
* @return true iff the BSM method type exactly matches
* {@see java.lang.invoke.LambdaMetafactory#altMetafactory(
* MethodHandles.Lookup,String,MethodType,Object[])}
*/
private static boolean isLambdaMetafactoryAltMetafactoryBSM(MethodType bsmType) {
return bsmType == LMF_ALT_MT;
}
/** The JVM produces java.lang.Integer values to box
* CONSTANT_Integer boxes but does not intern them.
* Let's intern them. This is slightly wrong for

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2018, 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
@ -499,7 +499,6 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
super(type, target);
this.target = target;
this.arrayType = arrayType;
this.asCollectorCache = target.asCollector(arrayType, 0);
}
@Override

View file

@ -3483,6 +3483,11 @@ assert((int)twice.invokeExact(21) == 42);
* @return a method handle which inserts an additional argument,
* before calling the original method handle
* @throws NullPointerException if the target or the {@code values} array is null
* @throws IllegalArgumentException if (@code pos) is less than {@code 0} or greater than
* {@code N - L} where {@code N} is the arity of the target method handle and {@code L}
* is the length of the values array.
* @throws ClassCastException if an argument does not match the corresponding bound parameter
* type.
* @see MethodHandle#bindTo
*/
public static

View file

@ -43,17 +43,17 @@ public class ReferenceQueue<T> {
*/
public ReferenceQueue() { }
private static class Null<S> extends ReferenceQueue<S> {
boolean enqueue(Reference<? extends S> r) {
private static class Null extends ReferenceQueue<Object> {
boolean enqueue(Reference<?> r) {
return false;
}
}
static ReferenceQueue<Object> NULL = new Null<>();
static ReferenceQueue<Object> ENQUEUED = new Null<>();
static final ReferenceQueue<Object> NULL = new Null();
static final ReferenceQueue<Object> ENQUEUED = new Null();
private static class Lock { };
private Lock lock = new Lock();
private final Lock lock = new Lock();
private volatile Reference<? extends T> head;
private long queueLength = 0;

View file

@ -109,10 +109,6 @@ class SocketOutputStream extends FileOutputStream {
try {
socketWrite0(fd, b, off, len);
} catch (SocketException se) {
if (se instanceof sun.net.ConnectionResetException) {
impl.setConnectionReset();
se = new SocketException("Connection reset");
}
if (impl.isClosedOrPending()) {
throw new SocketException("Socket closed");
} else {

View file

@ -189,6 +189,83 @@ public abstract class SelectionKey {
*/
public abstract SelectionKey interestOps(int ops);
/**
* Atomically sets this key's interest set to the bitwise union ("or") of
* the existing interest set and the given value. This method is guaranteed
* to be atomic with respect to other concurrent calls to this method or to
* {@link #interestOpsAnd(int)}.
*
* <p> This method may be invoked at any time. If this method is invoked
* while a selection operation is in progress then it has no effect upon
* that operation; the change to the key's interest set will be seen by the
* next selection operation.
*
* @implSpec The default implementation synchronizes on this key and invokes
* {@code interestOps()} and {@code interestOps(int)} to retrieve and set
* this key's interest set.
*
* @param ops The interest set to apply
*
* @return The previous interest set
*
* @throws IllegalArgumentException
* If a bit in the set does not correspond to an operation that
* is supported by this key's channel, that is, if
* {@code (ops & ~channel().validOps()) != 0}
*
* @throws CancelledKeyException
* If this key has been cancelled
*
* @since 11
*/
public int interestOpsOr(int ops) {
synchronized (this) {
int oldVal = interestOps();
interestOps(oldVal | ops);
return oldVal;
}
}
/**
* Atomically sets this key's interest set to the bitwise intersection ("and")
* of the existing interest set and the given value. This method is guaranteed
* to be atomic with respect to other concurrent calls to this method or to
* {@link #interestOpsOr(int)}.
*
* <p> This method may be invoked at any time. If this method is invoked
* while a selection operation is in progress then it has no effect upon
* that operation; the change to the key's interest set will be seen by the
* next selection operation.
*
* @apiNote Unlike the {@code interestOps(int)} and {@code interestOpsOr(int)}
* methods, this method does not throw {@code IllegalArgumentException} when
* invoked with bits in the interest set that do not correspond to an
* operation that is supported by this key's channel. This is to allow
* operation bits in the interest set to be cleared using bitwise complement
* values, e.g., {@code interestOpsAnd(~SelectionKey.OP_READ)} will remove
* the {@code OP_READ} from the interest set without affecting other bits.
*
* @implSpec The default implementation synchronizes on this key and invokes
* {@code interestOps()} and {@code interestOps(int)} to retrieve and set
* this key's interest set.
*
* @param ops The interest set to apply
*
* @return The previous interest set
*
* @throws CancelledKeyException
* If this key has been cancelled
*
* @since 11
*/
public int interestOpsAnd(int ops) {
synchronized (this) {
int oldVal = interestOps();
interestOps(oldVal & ops);
return oldVal;
}
}
/**
* Retrieves this key's ready-operation set.
*

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2018, 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
@ -1391,8 +1391,9 @@ public final class Files {
* specific exception)</i>
* @throws DirectoryNotEmptyException
* the {@code REPLACE_EXISTING} option is specified but the file
* cannot be replaced because it is a non-empty directory
* <i>(optional specific exception)</i>
* cannot be replaced because it is a non-empty directory, or the
* source is a non-empty directory containing entries that would
* be required to be moved <i>(optional specific exceptions)</i>
* @throws AtomicMoveNotSupportedException
* if the options array contains the {@code ATOMIC_MOVE} option but
* the file cannot be moved as an atomic file system operation.

View file

@ -586,7 +586,7 @@ public abstract class Clock {
* This is typically used for testing.
*/
static final class FixedClock extends Clock implements Serializable {
private static final long serialVersionUID = 7430389292664866958L;
private static final long serialVersionUID = 7430389292664866958L;
private final Instant instant;
private final ZoneId zone;
@ -636,7 +636,7 @@ public abstract class Clock {
* Implementation of a clock that adds an offset to an underlying clock.
*/
static final class OffsetClock extends Clock implements Serializable {
private static final long serialVersionUID = 2007484719125426256L;
private static final long serialVersionUID = 2007484719125426256L;
private final Clock baseClock;
private final Duration offset;

View file

@ -231,7 +231,7 @@ public final class Duration
* This method allows an arbitrary number of nanoseconds to be passed in.
* The factory will alter the values of the second and nanosecond in order
* to ensure that the stored nanosecond is in the range 0 to 999,999,999.
* For example, the following will result in the exactly the same duration:
* For example, the following will result in exactly the same duration:
* <pre>
* Duration.ofSeconds(3, 1);
* Duration.ofSeconds(4, -999_999_999);
@ -1357,12 +1357,14 @@ public final class Duration
* Truncating the duration returns a copy of the original with conceptual fields
* smaller than the specified unit set to zero.
* For example, truncating with the {@link ChronoUnit#MINUTES MINUTES} unit will
* round down to the nearest minute, setting the seconds and nanoseconds to zero.
* round down towards zero to the nearest minute, setting the seconds and
* nanoseconds to zero.
* <p>
* The unit must have a {@linkplain TemporalUnit#getDuration() duration}
* that divides into the length of a standard day without remainder.
* This includes all supplied time units on {@link ChronoUnit} and
* {@link ChronoUnit#DAYS DAYS}. Other ChronoUnits throw an exception.
* This includes all
* {@linkplain ChronoUnit#isTimeBased() time-based units on {@code ChronoUnit}}
* and {@link ChronoUnit#DAYS DAYS}. Other ChronoUnits throw an exception.
* <p>
* This instance is immutable and unaffected by this method call.
*
@ -1388,7 +1390,7 @@ public final class Duration
throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder");
}
long nod = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos;
long result = (nod / dur) * dur ;
long result = (nod / dur) * dur;
return plusNanos(result - nod);
}

View file

@ -311,7 +311,7 @@ public final class Instant
* This method allows an arbitrary number of nanoseconds to be passed in.
* The factory will alter the values of the second and nanosecond in order
* to ensure that the stored nanosecond is in the range 0 to 999,999,999.
* For example, the following will result in the exactly the same instant:
* For example, the following will result in exactly the same instant:
* <pre>
* Instant.ofEpochSecond(3, 1);
* Instant.ofEpochSecond(4, -999_999_999);
@ -757,7 +757,7 @@ public final class Instant
throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder");
}
long nod = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos;
long result = Math.floorDiv(nod, dur) * dur ;
long result = Math.floorDiv(nod, dur) * dur;
return plusNanos(result - nod);
}

View file

@ -356,14 +356,14 @@ public final class LocalTime
* @return the local time, not null
* @since 9
*/
public static LocalTime ofInstant(Instant instant, ZoneId zone) {
Objects.requireNonNull(instant, "instant");
Objects.requireNonNull(zone, "zone");
ZoneOffset offset = zone.getRules().getOffset(instant);
long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();
int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY);
return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());
}
public static LocalTime ofInstant(Instant instant, ZoneId zone) {
Objects.requireNonNull(instant, "instant");
Objects.requireNonNull(zone, "zone");
ZoneOffset offset = zone.getRules().getOffset(instant);
long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();
int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY);
return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());
}
//-----------------------------------------------------------------------
/**

View file

@ -110,7 +110,7 @@ import java.util.Objects;
* int year = date.get(ChronoField.YEAR);
* System.out.printf(" Today is %s %s %d-%s-%d%n", date.getChronology().getID(),
* dow, day, month, year);
*
* // Print today's date and the last day of the year
* ChronoLocalDate now1 = Chronology.of("Hijrah").dateNow();
* ChronoLocalDate first = now1.with(ChronoField.DAY_OF_MONTH, 1)

View file

@ -201,7 +201,7 @@ public interface ChronoLocalDateTime<D extends ChronoLocalDate>
*
* @return the date part of this date-time, not null
*/
D toLocalDate() ;
D toLocalDate();
/**
* Gets the local time part of this date-time.

View file

@ -736,8 +736,8 @@ public interface Chronology extends Comparable<Chronology> {
* @throws DateTimeException if any of the values are out of range
* @since 9
*/
public default long epochSecond(int prolepticYear, int month, int dayOfMonth,
int hour, int minute, int second, ZoneOffset zoneOffset) {
public default long epochSecond(int prolepticYear, int month, int dayOfMonth,
int hour, int minute, int second, ZoneOffset zoneOffset) {
Objects.requireNonNull(zoneOffset, "zoneOffset");
HOUR_OF_DAY.checkValidValue(hour);
MINUTE_OF_HOUR.checkValidValue(minute);
@ -765,8 +765,8 @@ public interface Chronology extends Comparable<Chronology> {
* @throws DateTimeException if any of the values are out of range
* @since 9
*/
public default long epochSecond(Era era, int yearOfEra, int month, int dayOfMonth,
int hour, int minute, int second, ZoneOffset zoneOffset) {
public default long epochSecond(Era era, int yearOfEra, int month, int dayOfMonth,
int hour, int minute, int second, ZoneOffset zoneOffset) {
Objects.requireNonNull(era, "era");
return epochSecond(prolepticYear(era, yearOfEra), month, dayOfMonth, hour, minute, second, zoneOffset);
}

View file

@ -287,9 +287,9 @@ public final class IsoChronology extends AbstractChronology implements Serializa
* or if the day-of-month is invalid for the month-of-year
* @since 9
*/
@Override
public long epochSecond(int prolepticYear, int month, int dayOfMonth,
int hour, int minute, int second, ZoneOffset zoneOffset) {
@Override
public long epochSecond(int prolepticYear, int month, int dayOfMonth,
int hour, int minute, int second, ZoneOffset zoneOffset) {
YEAR.checkValidValue(prolepticYear);
MONTH_OF_YEAR.checkValidValue(month);
DAY_OF_MONTH.checkValidValue(dayOfMonth);

View file

@ -459,38 +459,38 @@ public final class JapaneseChronology extends AbstractChronology implements Seri
return era.getPrivateEra().getSinceDate().getYear() + yearOfEra - 1;
}
private ChronoLocalDate resolveYMD(JapaneseEra era, int yoe, Map<TemporalField,Long> fieldValues, ResolverStyle resolverStyle) {
fieldValues.remove(ERA);
fieldValues.remove(YEAR_OF_ERA);
if (resolverStyle == ResolverStyle.LENIENT) {
int y = prolepticYearLenient(era, yoe);
long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1);
long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1);
return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS);
}
int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR);
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH);
if (resolverStyle == ResolverStyle.SMART) { // previous valid
if (yoe < 1) {
throw new DateTimeException("Invalid YearOfEra: " + yoe);
}
int y = prolepticYearLenient(era, yoe);
JapaneseDate result;
try {
result = date(y, moy, dom);
} catch (DateTimeException ex) {
result = date(y, moy, 1).with(TemporalAdjusters.lastDayOfMonth());
}
// handle the era being changed
// only allow if the new date is in the same Jan-Dec as the era change
// determine by ensuring either original yoe or result yoe is 1
if (result.getEra() != era && result.get(YEAR_OF_ERA) > 1 && yoe > 1) {
throw new DateTimeException("Invalid YearOfEra for Era: " + era + " " + yoe);
}
return result;
}
return date(era, yoe, moy, dom);
}
private ChronoLocalDate resolveYMD(JapaneseEra era, int yoe, Map<TemporalField,Long> fieldValues, ResolverStyle resolverStyle) {
fieldValues.remove(ERA);
fieldValues.remove(YEAR_OF_ERA);
if (resolverStyle == ResolverStyle.LENIENT) {
int y = prolepticYearLenient(era, yoe);
long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1);
long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1);
return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS);
}
int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR);
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH);
if (resolverStyle == ResolverStyle.SMART) { // previous valid
if (yoe < 1) {
throw new DateTimeException("Invalid YearOfEra: " + yoe);
}
int y = prolepticYearLenient(era, yoe);
JapaneseDate result;
try {
result = date(y, moy, dom);
} catch (DateTimeException ex) {
result = date(y, moy, 1).with(TemporalAdjusters.lastDayOfMonth());
}
// handle the era being changed
// only allow if the new date is in the same Jan-Dec as the era change
// determine by ensuring either original yoe or result yoe is 1
if (result.getEra() != era && result.get(YEAR_OF_ERA) > 1 && yoe > 1) {
throw new DateTimeException("Invalid YearOfEra for Era: " + era + " " + yoe);
}
return result;
}
return date(era, yoe, moy, dom);
}
private ChronoLocalDate resolveYD(JapaneseEra era, int yoe, Map <TemporalField,Long> fieldValues, ResolverStyle resolverStyle) {
fieldValues.remove(ERA);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018, 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
@ -123,14 +123,19 @@ public final class JapaneseEra
*/
public static final JapaneseEra SHOWA = new JapaneseEra(1, LocalDate.of(1926, 12, 25));
/**
* The singleton instance for the 'Heisei' era (1989-01-08 - current)
* The singleton instance for the 'Heisei' era (1989-01-08 - 2019-04-30)
* which has the value 2.
*/
public static final JapaneseEra HEISEI = new JapaneseEra(2, LocalDate.of(1989, 1, 8));
/**
* The singleton instance for the 'NewEra' era (2019-05-01 - current)
* which has the value 3.
*/
private static final JapaneseEra NEWERA = new JapaneseEra(3, LocalDate.of(2019, 5, 1));
// The number of predefined JapaneseEra constants.
// There may be a supplemental era defined by the property.
private static final int N_ERA_CONSTANTS = HEISEI.getValue() + ERA_OFFSET;
private static final int N_ERA_CONSTANTS = NEWERA.getValue() + ERA_OFFSET;
/**
* Serialization version.
@ -148,6 +153,7 @@ public final class JapaneseEra
KNOWN_ERAS[1] = TAISHO;
KNOWN_ERAS[2] = SHOWA;
KNOWN_ERAS[3] = HEISEI;
KNOWN_ERAS[4] = NEWERA;
for (int i = N_ERA_CONSTANTS; i < ERA_CONFIG.length; i++) {
CalendarDate date = ERA_CONFIG[i].getSinceDate();
LocalDate isoDate = LocalDate.of(date.getYear(), date.getMonth(), date.getDayOfMonth());

View file

@ -3049,7 +3049,7 @@ public final class DateTimeFormatterBuilder {
* Prints and parses a numeric date-time field with optional padding.
*/
static final class FractionPrinterParser extends NumberPrinterParser {
private final boolean decimalPoint;
private final boolean decimalPoint;
/**
* Constructor.

View file

@ -216,7 +216,6 @@ public final class DecimalStyle {
*
* @param zeroDigit the character for zero
* @return a copy with a new character that represents zero, not null
*/
public DecimalStyle withZeroDigit(char zeroDigit) {
if (zeroDigit == this.zeroDigit) {

View file

@ -119,7 +119,7 @@ import java.util.Collections;
* Providers must ensure that once a rule has been seen by the application, the
* rule must continue to be available.
* <p>
* Providers are encouraged to implement a meaningful {@code toString} method.
* Providers are encouraged to implement a meaningful {@code toString} method.
* <p>
* Many systems would like to update time-zone rules dynamically without stopping the JVM.
* When examined in detail, this is a complex problem.

View file

@ -2914,7 +2914,7 @@ public final class Formatter implements Closeable, Flushable {
a.append(System.lineSeparator());
break;
case Conversion.PERCENT_SIGN:
a.append('%');
print("%", l);
break;
default:
assert false;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2018, 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
@ -50,6 +50,7 @@ import sun.util.calendar.ZoneInfo;
* 2 Taisho 1912-07-30T00:00:00 local time
* 3 Showa 1926-12-25T00:00:00 local time
* 4 Heisei 1989-01-08T00:00:00 local time
* 5 NewEra 2019-05-01T00:00:00 local time
* ------------------------------------------------------
* }</pre>
*
@ -71,8 +72,10 @@ import sun.util.calendar.ZoneInfo;
* </pre>
* where
* <dl>
* <dt>{@code <name>:}<dd>the full name of the new era (non-ASCII characters allowed)
* <dt>{@code <abbr>:}<dd>the abbreviation of the new era (non-ASCII characters allowed)
* <dt>{@code <name>:}<dd>the full name of the new era (non-ASCII characters allowed,
* either in platform's native encoding or in Unicode escape notation, {@code \\uXXXX})
* <dt>{@code <abbr>:}<dd>the abbreviation of the new era (non-ASCII characters allowed,
* either in platform's native encoding or in Unicode escape notation, {@code \\uXXXX})
* <dt>{@code <time['u']>:}<dd>the start time of the new era represented by
* milliseconds from 1970-01-01T00:00:00 local time or UTC if {@code 'u'} is
* appended to the milliseconds value. (ASCII digits only)
@ -125,6 +128,11 @@ class JapaneseImperialCalendar extends Calendar {
*/
public static final int HEISEI = 4;
/**
* The ERA constant designating the NewEra era.
*/
private static final int NEWERA = 5;
private static final int EPOCH_OFFSET = 719163; // Fixed date of January 1, 1970 (Gregorian)
// Useful millisecond constants. Although ONE_DAY and ONE_WEEK can fit
@ -155,6 +163,9 @@ class JapaneseImperialCalendar extends Calendar {
// Fixed date of the first date of each era.
private static final long[] sinceFixedDates;
// The current era
private static final int currentEra;
/*
* <pre>
* Greatest Least
@ -251,13 +262,18 @@ class JapaneseImperialCalendar extends Calendar {
// eras[BEFORE_MEIJI] and sinceFixedDate[BEFORE_MEIJI] are the
// same as Gregorian.
int index = BEFORE_MEIJI;
int current = index;
sinceFixedDates[index] = gcal.getFixedDate(BEFORE_MEIJI_ERA.getSinceDate());
eras[index++] = BEFORE_MEIJI_ERA;
for (Era e : es) {
if(e.getSince(TimeZone.NO_TIMEZONE) < System.currentTimeMillis()) {
current = index;
}
CalendarDate d = e.getSinceDate();
sinceFixedDates[index] = gcal.getFixedDate(d);
eras[index++] = e;
}
currentEra = current;
LEAST_MAX_VALUES[ERA] = MAX_VALUES[ERA] = eras.length - 1;
@ -1743,12 +1759,12 @@ class JapaneseImperialCalendar extends Calendar {
}
} else if (transitionYear) {
if (jdate.getYear() == 1) {
// As of Heisei (since Meiji) there's no case
// As of NewEra (since Meiji) there's no case
// that there are multiple transitions in a
// year. Historically there was such
// case. There might be such case again in the
// future.
if (era > HEISEI) {
if (era > NEWERA) {
CalendarDate pd = eras[era - 1].getSinceDate();
if (normalizedYear == pd.getYear()) {
d.setMonth(pd.getMonth()).setDayOfMonth(pd.getDayOfMonth());
@ -1883,7 +1899,7 @@ class JapaneseImperialCalendar extends Calendar {
year = isSet(YEAR) ? internalGet(YEAR) : 1;
} else {
if (isSet(YEAR)) {
era = eras.length - 1;
era = currentEra;
year = internalGet(YEAR);
} else {
// Equivalent to 1970 (Gregorian)
@ -2367,7 +2383,7 @@ class JapaneseImperialCalendar extends Calendar {
* default ERA is the current era, but a zero (unset) ERA means before Meiji.
*/
private int internalGetEra() {
return isSet(ERA) ? internalGet(ERA) : eras.length - 1;
return isSet(ERA) ? internalGet(ERA) : currentEra;
}
/**

View file

@ -35,6 +35,7 @@
package java.util.concurrent;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Objects;
@ -191,6 +192,50 @@ public enum TimeUnit {
}
}
/**
* Converts the given time duration to this unit.
*
* <p>For any TimeUnit {@code unit},
* {@code unit.convert(Duration.ofNanos(n))}
* is equivalent to
* {@code unit.convert(n, NANOSECONDS)}, and
* {@code unit.convert(Duration.of(n, unit.toChronoUnit()))}
* is equivalent to {@code n} (in the absence of overflow).
*
* @param duration the time duration
* @return the converted duration in this unit,
* or {@code Long.MIN_VALUE} if conversion would negatively overflow,
* or {@code Long.MAX_VALUE} if it would positively overflow.
* @throws NullPointerException if {@code duration} is null
* @see Duration#of(long,TemporalUnit)
* @since 11
*/
public long convert(Duration duration) {
long secs = duration.getSeconds();
int nano = duration.getNano();
if (secs < 0 && nano > 0) {
// use representation compatible with integer division
secs++;
nano -= SECOND_SCALE;
}
final long s, nanoVal;
// Optimize for the common case - NANOSECONDS without overflow
if (this == NANOSECONDS)
nanoVal = nano;
else if ((s = scale) < SECOND_SCALE)
nanoVal = nano / s;
else if (this == SECONDS)
return secs;
else
return secs / secRatio;
long val = secs * secRatio + nanoVal;
return ((secs < maxSecs && secs > -maxSecs) ||
(secs == maxSecs && val > 0) ||
(secs == -maxSecs && val < 0))
? val
: (secs > 0) ? Long.MAX_VALUE : Long.MIN_VALUE;
}
/**
* Equivalent to
* {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}.
@ -221,10 +266,8 @@ public enum TimeUnit {
*/
public long toMicros(long duration) {
long s, m;
if ((s = scale) == MICRO_SCALE)
return duration;
else if (s < MICRO_SCALE)
return duration / microRatio;
if ((s = scale) <= MICRO_SCALE)
return (s == MICRO_SCALE) ? duration : duration / microRatio;
else if (duration > (m = maxMicros))
return Long.MAX_VALUE;
else if (duration < -m)
@ -243,10 +286,8 @@ public enum TimeUnit {
*/
public long toMillis(long duration) {
long s, m;
if ((s = scale) == MILLI_SCALE)
return duration;
else if (s < MILLI_SCALE)
return duration / milliRatio;
if ((s = scale) <= MILLI_SCALE)
return (s == MILLI_SCALE) ? duration : duration / milliRatio;
else if (duration > (m = maxMillis))
return Long.MAX_VALUE;
else if (duration < -m)
@ -265,10 +306,8 @@ public enum TimeUnit {
*/
public long toSeconds(long duration) {
long s, m;
if ((s = scale) == SECOND_SCALE)
return duration;
else if (s < SECOND_SCALE)
return duration / secRatio;
if ((s = scale) <= SECOND_SCALE)
return (s == SECOND_SCALE) ? duration : duration / secRatio;
else if (duration > (m = maxSecs))
return Long.MAX_VALUE;
else if (duration < -m)

View file

@ -116,4 +116,20 @@ public interface Predicate<T> {
? Objects::isNull
: object -> targetRef.equals(object);
}
/**
* Returns a predicate that is the negation of the supplied predicate.
*
* @param <T> the type of arguments to the specified predicate
* @param target predicate to negate
*
* @return a predicate that negates the results of the supplied
* predicate
*
* @since 11
*/
@SuppressWarnings("unchecked")
static <T> Predicate<T> not(Predicate<? super T> target) {
return (Predicate<T>)target.negate();
}
}

View file

@ -377,7 +377,8 @@ public class Attributes implements Map<Object,Object>, Cloneable {
int len;
while ((len = is.readLine(lbuf)) != -1) {
boolean lineContinued = false;
if (lbuf[--len] != '\n') {
byte c = lbuf[--len];
if (c != '\n' && c != '\r') {
throw new IOException("line too long");
}
if (len > 0 && lbuf[len-1] == '\r') {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2018, 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
@ -93,10 +93,14 @@ import java.util.zip.ZipFile;
* argument. This assures that classes compatible with the major
* version of the running JVM are loaded from multi-release jar files.
*
* <p>If the verify flag is on when opening a signed jar file, the content of
* the file is verified against its signature embedded inside the file. Please
* note that the verification process does not include validating the signer's
* certificate. A caller should inspect the return value of
* <p> If the {@code verify} flag is on when opening a signed jar file, the content
* of the jar entry is verified against the signature embedded inside the manifest
* that is associated with its {@link JarEntry#getRealName() path name}. For a
* multi-release jar file, the content of a versioned entry is verfieid against
* its own signature and {@link JarEntry#getCodeSigners()} returns its own signers.
*
* Please note that the verification process does not include validating the
* signer's certificate. A caller should inspect the return value of
* {@link JarEntry#getCodeSigners()} to further determine if the signature
* can be trusted.
*

View file

@ -205,7 +205,8 @@ public class Manifest implements Cloneable {
byte[] lastline = null;
while ((len = fis.readLine(lbuf)) != -1) {
if (lbuf[--len] != '\n') {
byte c = lbuf[--len];
if (c != '\n' && c != '\r') {
throw new IOException("manifest line too long");
}
if (len > 0 && lbuf[len-1] == '\r') {
@ -381,13 +382,38 @@ public class Manifest implements Cloneable {
}
int tpos = pos;
int maxpos = tpos + n;
while (tpos < maxpos && tbuf[tpos++] != '\n') ;
byte c = 0;
// jar.spec.newline: CRLF | LF | CR (not followed by LF)
while (tpos < maxpos && (c = tbuf[tpos++]) != '\n' && c != '\r');
if (c == '\r' && tpos < maxpos && tbuf[tpos] == '\n') {
tpos++;
}
n = tpos - pos;
System.arraycopy(tbuf, pos, b, off, n);
off += n;
total += n;
pos = tpos;
if (tbuf[tpos-1] == '\n') {
c = tbuf[tpos-1];
if (c == '\n') {
break;
}
if (c == '\r') {
if (count == pos) {
// try to see if there is a trailing LF
fill();
if (pos < count && tbuf[pos] == '\n') {
if (total < len) {
b[off++] = '\n';
total++;
} else {
// we should always have big enough lbuf but
// just in case we don't, replace the last CR
// with LF.
b[off - 1] = '\n';
}
pos++;
}
}
break;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -37,8 +37,8 @@ import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* An engine that performs match operations on a {@linkplain java.lang.CharSequence
* character sequence} by interpreting a {@link Pattern}.
* An engine that performs match operations on a {@linkplain
* java.lang.CharSequence character sequence} by interpreting a {@link Pattern}.
*
* <p> A matcher is created from a pattern by invoking the pattern's {@link
* Pattern#matcher matcher} method. Once created, a matcher can be used to
@ -52,8 +52,8 @@ import java.util.stream.StreamSupport;
* <li><p> The {@link #lookingAt lookingAt} method attempts to match the
* input sequence, starting at the beginning, against the pattern. </p></li>
*
* <li><p> The {@link #find find} method scans the input sequence looking for
* the next subsequence that matches the pattern. </p></li>
* <li><p> The {@link #find find} method scans the input sequence looking
* for the next subsequence that matches the pattern. </p></li>
*
* </ul>
*
@ -63,12 +63,12 @@ import java.util.stream.StreamSupport;
*
* <p> A matcher finds matches in a subset of its input called the
* <i>region</i>. By default, the region contains all of the matcher's input.
* The region can be modified via the {@link #region region} method and queried
* via the {@link #regionStart regionStart} and {@link #regionEnd regionEnd}
* methods. The way that the region boundaries interact with some pattern
* constructs can be changed. See {@link #useAnchoringBounds
* useAnchoringBounds} and {@link #useTransparentBounds useTransparentBounds}
* for more details.
* The region can be modified via the {@link #region(int, int) region} method
* and queried via the {@link #regionStart() regionStart} and {@link
* #regionEnd() regionEnd} methods. The way that the region boundaries interact
* with some pattern constructs can be changed. See {@link
* #useAnchoringBounds(boolean) useAnchoringBounds} and {@link
* #useTransparentBounds(boolean) useTransparentBounds} for more details.
*
* <p> This class also defines methods for replacing matched subsequences with
* new strings whose contents can, if desired, be computed from the match
@ -586,8 +586,8 @@ public final class Matcher implements MatchResult {
*
* <p> For a matcher <i>m</i> with input sequence <i>s</i>,
* the expressions <i>m.</i>{@code group()} and
* <i>s.</i>{@code substring(}<i>m.</i>{@code start(),}&nbsp;<i>m.</i>{@code end())}
* are equivalent. </p>
* <i>s.</i>{@code substring(}<i>m.</i>{@code start(),}&nbsp;<i>m.</i>
* {@code end())} are equivalent. </p>
*
* <p> Note that some patterns, for example {@code a*}, match the empty
* string. This method will return the empty string when the pattern
@ -652,8 +652,8 @@ public final class Matcher implements MatchResult {
/**
* Returns the input subsequence captured by the given
* <a href="Pattern.html#groupname">named-capturing group</a> during the previous
* match operation.
* <a href="Pattern.html#groupname">named-capturing group</a> during the
* previous match operation.
*
* <p> If the match was successful but the group specified failed to match
* any part of the input sequence, then {@code null} is returned. Note
@ -866,9 +866,9 @@ public final class Matcher implements MatchResult {
* string.
*
* <p> This method is intended to be used in a loop together with the
* {@link #appendTail appendTail} and {@link #find find} methods. The
* following code, for example, writes {@code one dog two dogs in the
* yard} to the standard-output stream: </p>
* {@link #appendTail(StringBuffer) appendTail} and {@link #find() find}
* methods. The following code, for example, writes {@code one dog two dogs
* in the yard} to the standard-output stream: </p>
*
* <blockquote><pre>
* Pattern p = Pattern.compile("cat");
@ -959,9 +959,9 @@ public final class Matcher implements MatchResult {
* string.
*
* <p> This method is intended to be used in a loop together with the
* {@link #appendTail appendTail} and {@link #find find} methods. The
* following code, for example, writes {@code one dog two dogs in the
* yard} to the standard-output stream: </p>
* {@link #appendTail(StringBuilder) appendTail} and
* {@link #find() find} methods. The following code, for example, writes
* {@code one dog two dogs in the yard} to the standard-output stream: </p>
*
* <blockquote><pre>
* Pattern p = Pattern.compile("cat");
@ -1104,8 +1104,8 @@ public final class Matcher implements MatchResult {
* <p> This method reads characters from the input sequence, starting at
* the append position, and appends them to the given string buffer. It is
* intended to be invoked after one or more invocations of the {@link
* #appendReplacement appendReplacement} method in order to copy the
* remainder of the input sequence. </p>
* #appendReplacement(StringBuffer, String) appendReplacement} method in
* order to copy the remainder of the input sequence. </p>
*
* @param sb
* The target string buffer
@ -1123,8 +1123,9 @@ public final class Matcher implements MatchResult {
* <p> This method reads characters from the input sequence, starting at
* the append position, and appends them to the given string builder. It is
* intended to be invoked after one or more invocations of the {@link
* #appendReplacement appendReplacement} method in order to copy the
* remainder of the input sequence. </p>
* #appendReplacement(StringBuilder, String)
* appendReplacement} method in order to copy the remainder of the input
* sequence. </p>
*
* @param sb
* The target string builder
@ -1490,10 +1491,10 @@ public final class Matcher implements MatchResult {
* index specified by the {@code end} parameter.
*
* <p>Depending on the transparency and anchoring being used (see
* {@link #useTransparentBounds useTransparentBounds} and
* {@link #useAnchoringBounds useAnchoringBounds}), certain constructs such
* as anchors may behave differently at or around the boundaries of the
* region.
* {@link #useTransparentBounds(boolean) useTransparentBounds} and
* {@link #useAnchoringBounds(boolean) useAnchoringBounds}), certain
* constructs such as anchors may behave differently at or around the
* boundaries of the region.
*
* @param start
* The index to start searching at (inclusive)
@ -1523,8 +1524,8 @@ public final class Matcher implements MatchResult {
/**
* Reports the start index of this matcher's region. The
* searches this matcher conducts are limited to finding matches
* within {@link #regionStart regionStart} (inclusive) and
* {@link #regionEnd regionEnd} (exclusive).
* within {@link #regionStart() regionStart} (inclusive) and
* {@link #regionEnd() regionEnd} (exclusive).
*
* @return The starting point of this matcher's region
* @since 1.5
@ -1536,8 +1537,8 @@ public final class Matcher implements MatchResult {
/**
* Reports the end index (exclusive) of this matcher's region.
* The searches this matcher conducts are limited to finding matches
* within {@link #regionStart regionStart} (inclusive) and
* {@link #regionEnd regionEnd} (exclusive).
* within {@link #regionStart() regionStart} (inclusive) and
* {@link #regionEnd() regionEnd} (exclusive).
*
* @return the ending point of this matcher's region
* @since 1.5
@ -1553,7 +1554,7 @@ public final class Matcher implements MatchResult {
* <i>transparent</i> bounds, {@code false} if it uses <i>opaque</i>
* bounds.
*
* <p> See {@link #useTransparentBounds useTransparentBounds} for a
* <p> See {@link #useTransparentBounds(boolean) useTransparentBounds} for a
* description of transparent and opaque bounds.
*
* <p> By default, a matcher uses opaque region boundaries.
@ -1604,7 +1605,7 @@ public final class Matcher implements MatchResult {
* <p> This method returns {@code true} if this matcher uses
* <i>anchoring</i> bounds, {@code false} otherwise.
*
* <p> See {@link #useAnchoringBounds useAnchoringBounds} for a
* <p> See {@link #useAnchoringBounds(boolean) useAnchoringBounds} for a
* description of anchoring bounds.
*
* <p> By default, a matcher uses anchoring region boundaries.
@ -1770,18 +1771,18 @@ public final class Matcher implements MatchResult {
}
/**
* Generates a String from this Matcher's input in the specified range.
* Generates a String from this matcher's input in the specified range.
*
* @param beginIndex the beginning index, inclusive
* @param endIndex the ending index, exclusive
* @return A String generated from this Matcher's input
* @return A String generated from this matcher's input
*/
CharSequence getSubSequence(int beginIndex, int endIndex) {
return text.subSequence(beginIndex, endIndex);
}
/**
* Returns this Matcher's input character at index i.
* Returns this matcher's input character at index i.
*
* @return A char from the specified index
*/
@ -1802,4 +1803,4 @@ public final class Matcher implements MatchResult {
throw new IllegalArgumentException("No group with name <" + name + ">");
return parentPattern.namedGroups().get(name);
}
}
}

View file

@ -111,7 +111,7 @@ import sun.security.jca.*;
* encryption with a given key. When IVs are repeated for GCM
* encryption, such usages are subject to forgery attacks. Thus, after
* each encryption operation using GCM mode, callers should re-initialize
* the cipher objects with GCM parameters which has a different IV value.
* the cipher objects with GCM parameters which have a different IV value.
* <pre>
* GCMParameterSpec s = ...;
* cipher.init(..., s);
@ -131,6 +131,13 @@ import sun.security.jca.*;
* ...
*
* </pre>
* The ChaCha20 and ChaCha20-Poly1305 algorithms have a similar requirement
* for unique nonces with a given key. After each encryption or decryption
* operation, callers should re-initialize their ChaCha20 or ChaCha20-Poly1305
* ciphers with parameters that specify a different nonce value. Please
* see <a href="https://tools.ietf.org/html/rfc7539">RFC 7539</a> for more
* information on the ChaCha20 and ChaCha20-Poly1305 algorithms.
* <p>
* Every implementation of the Java platform is required to support
* the following standard {@code Cipher} transformations with the keysizes
* in parentheses:

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2018, 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
@ -755,6 +755,7 @@ public abstract class CipherSpi {
return 0;
}
int outLenNeeded = engineGetOutputSize(inLen);
if (output.remaining() < outLenNeeded) {
throw new ShortBufferException("Need at least " + outLenNeeded
+ " bytes of space in output buffer");
@ -762,98 +763,77 @@ public abstract class CipherSpi {
boolean a1 = input.hasArray();
boolean a2 = output.hasArray();
int total = 0;
byte[] inArray, outArray;
if (a2) { // output has an accessible byte[]
outArray = output.array();
int outPos = output.position();
int outOfs = output.arrayOffset() + outPos;
if (a1 && a2) {
byte[] inArray = input.array();
int inOfs = input.arrayOffset() + inPos;
byte[] outArray = output.array();
int outPos = output.position();
int outOfs = output.arrayOffset() + outPos;
int n;
if (isUpdate) {
n = engineUpdate(inArray, inOfs, inLen, outArray, outOfs);
} else {
n = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs);
}
input.position(inLimit);
output.position(outPos + n);
return n;
} else if (!a1 && a2) {
int outPos = output.position();
byte[] outArray = output.array();
int outOfs = output.arrayOffset() + outPos;
byte[] inArray = new byte[getTempArraySize(inLen)];
int total = 0;
do {
int chunk = Math.min(inLen, inArray.length);
if (chunk > 0) {
input.get(inArray, 0, chunk);
}
int n;
if (isUpdate || (inLen != chunk)) {
n = engineUpdate(inArray, 0, chunk, outArray, outOfs);
} else {
n = engineDoFinal(inArray, 0, chunk, outArray, outOfs);
}
total += n;
outOfs += n;
inLen -= chunk;
} while (inLen > 0);
output.position(outPos + total);
return total;
} else { // output is not backed by an accessible byte[]
byte[] inArray;
int inOfs;
if (a1) {
if (a1) { // input also has an accessible byte[]
inArray = input.array();
inOfs = input.arrayOffset() + inPos;
} else {
inArray = new byte[getTempArraySize(inLen)];
inOfs = 0;
}
byte[] outArray = new byte[getTempArraySize(outLenNeeded)];
int outSize = outArray.length;
int total = 0;
boolean resized = false;
do {
int chunk =
Math.min(inLen, (outSize == 0? inArray.length : outSize));
if (!a1 && !resized && chunk > 0) {
input.get(inArray, 0, chunk);
inOfs = 0;
int inOfs = input.arrayOffset() + inPos;
if (isUpdate) {
total = engineUpdate(inArray, inOfs, inLen, outArray, outOfs);
} else {
total = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs);
}
try {
int n;
if (isUpdate || (inLen != chunk)) {
n = engineUpdate(inArray, inOfs, chunk, outArray, 0);
} else {
n = engineDoFinal(inArray, inOfs, chunk, outArray, 0);
}
resized = false;
inOfs += chunk;
inLen -= chunk;
if (n > 0) {
output.put(outArray, 0, n);
total += n;
}
} catch (ShortBufferException e) {
if (resized) {
// we just resized the output buffer, but it still
// did not work. Bug in the provider, abort
throw (ProviderException)new ProviderException
("Could not determine buffer size").initCause(e);
}
// output buffer is too small, realloc and try again
resized = true;
outSize = engineGetOutputSize(chunk);
outArray = new byte[outSize];
}
} while (inLen > 0);
if (a1) {
input.position(inLimit);
} else { // input does not have accessible byte[]
inArray = new byte[getTempArraySize(inLen)];
do {
int chunk = Math.min(inLen, inArray.length);
if (chunk > 0) {
input.get(inArray, 0, chunk);
}
int n;
if (isUpdate || (inLen > chunk)) {
n = engineUpdate(inArray, 0, chunk, outArray, outOfs);
} else {
n = engineDoFinal(inArray, 0, chunk, outArray, outOfs);
}
total += n;
outOfs += n;
inLen -= chunk;
} while (inLen > 0);
}
output.position(outPos + total);
} else { // output does not have an accessible byte[]
if (a1) { // but input has an accessible byte[]
inArray = input.array();
int inOfs = input.arrayOffset() + inPos;
if (isUpdate) {
outArray = engineUpdate(inArray, inOfs, inLen);
} else {
outArray = engineDoFinal(inArray, inOfs, inLen);
}
input.position(inLimit);
if (outArray != null && outArray.length != 0) {
output.put(outArray);
total = outArray.length;
}
} else { // input also does not have an accessible byte[]
inArray = new byte[getTempArraySize(inLen)];
do {
int chunk = Math.min(inLen, inArray.length);
if (chunk > 0) {
input.get(inArray, 0, chunk);
}
int n;
if (isUpdate || (inLen > chunk)) {
outArray = engineUpdate(inArray, 0, chunk);
} else {
outArray = engineDoFinal(inArray, 0, chunk);
}
if (outArray != null && outArray.length != 0) {
output.put(outArray);
total += outArray.length;
}
inLen -= chunk;
} while (inLen > 0);
}
return total;
}
return total;
}
/**

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2018, 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 javax.crypto.spec;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Objects;
/**
* This class specifies the parameters used with the
* <a href="https://tools.ietf.org/html/rfc7539"><i>ChaCha20</i></a>
* algorithm.
*
* <p> The parameters consist of a 12-byte nonce and an initial
* counter value expressed as a 32-bit integer.
*
* <p> This class can be used to initialize a {@code Cipher} object that
* implements the <i>ChaCha20</i> algorithm.
*
* @since 11
*/
public final class ChaCha20ParameterSpec implements AlgorithmParameterSpec {
// The nonce length is defined by the spec as 96 bits (12 bytes) in length.
private static final int NONCE_LENGTH = 12;
private final byte[] nonce;
private final int counter;
/**
* Constructs a parameter set for ChaCha20 from the given nonce
* and counter.
*
* @param nonce a 12-byte nonce value
* @param counter the initial counter value
*
* @throws NullPointerException if {@code nonce} is {@code null}
* @throws IllegalArgumentException if {@code nonce} is not 12 bytes
* in length
*/
public ChaCha20ParameterSpec(byte[] nonce, int counter) {
this.counter = counter;
Objects.requireNonNull(nonce, "Nonce must be non-null");
this.nonce = nonce.clone();
if (this.nonce.length != NONCE_LENGTH) {
throw new IllegalArgumentException(
"Nonce must be 12-bytes in length");
}
}
/**
* Returns the nonce value.
*
* @return the nonce value. This method returns a new array each time
* this method is called.
*/
public byte[] getNonce() {
return nonce.clone();
}
/**
* Returns the configured counter value.
*
* @return the counter value
*/
public int getCounter() {
return counter;
}
}

View file

@ -609,12 +609,13 @@ public final class LauncherHelper {
}
// From src/share/bin/java.c:
// enum LaunchMode { LM_UNKNOWN = 0, LM_CLASS, LM_JAR, LM_MODULE }
// enum LaunchMode { LM_UNKNOWN = 0, LM_CLASS, LM_JAR, LM_MODULE, LM_SOURCE }
private static final int LM_UNKNOWN = 0;
private static final int LM_CLASS = 1;
private static final int LM_JAR = 2;
private static final int LM_MODULE = 3;
private static final int LM_SOURCE = 4;
static void abort(Throwable t, String msgKey, Object... args) {
if (msgKey != null) {
@ -645,13 +646,21 @@ public final class LauncherHelper {
*
* @return the application's main class
*/
@SuppressWarnings("fallthrough")
public static Class<?> checkAndLoadMain(boolean printToStderr,
int mode,
String what) {
initOutput(printToStderr);
Class<?> mainClass = (mode == LM_MODULE) ? loadModuleMainClass(what)
: loadMainClass(mode, what);
Class<?> mainClass = null;
switch (mode) {
case LM_MODULE: case LM_SOURCE:
mainClass = loadModuleMainClass(what);
break;
default:
mainClass = loadMainClass(mode, what);
break;
}
// record the real main class for UI purposes
// neither method above can return null, they will abort()

View file

@ -25,13 +25,17 @@
# Translators please note do not translate the options themselves
java.launcher.opt.header = Usage: {0} [options] <mainclass> [args...]\n\
\ (to execute a class)\n or {0} [options] -jar <jarfile> [args...]\n\
\ (to execute a class)\n\
\ or {0} [options] -jar <jarfile> [args...]\n\
\ (to execute a jar file)\n\
\ or {0} [options] -m <module>[/<mainclass>] [args...]\n\
\ {0} [options] --module <module>[/<mainclass>] [args...]\n\
\ (to execute the main class in a module)\n\n\
\ Arguments following the main class, -jar <jarfile>, -m or --module\n\
\ <module>/<mainclass> are passed as the arguments to main class.\n\n\
\ (to execute the main class in a module)\n\
\ or {0} [options] <sourcefile> [args]\n\
\ (to execute a single source-file program)\n\n\
\ Arguments following the main class, source file, -jar <jarfile>,\n\
\ -m or --module <module>/<mainclass> are passed as the arguments to\n\
\ main class.\n\n\
\ where options include:\n\n
java.launcher.opt.vmselect =\ {0}\t to select the "{1}" VM\n
@ -114,7 +118,7 @@ java.launcher.opt.footer = \
\ -disable-@files\n\
\ prevent further argument file expansion\n\
\ --enable-preview\n\
\ allow classes to depend on preview features of this release
\ allow classes to depend on preview features of this release\n\
\To specify an argument for a long option, you can use --<name>=<value> or\n\
\--<name> <value>.\n
@ -180,7 +184,9 @@ java.launcher.X.usage=\n\
\ --patch-module <module>=<file>({0}<file>)*\n\
\ override or augment a module with classes and resources\n\
\ in JAR files or directories.\n\
\ --disable-@files disable further argument file expansion\n\n\
\ --disable-@files disable further argument file expansion\n\
\ --source <version>\n\
\ set the version of the source in source-file mode.\n\n\
These extra options are subject to change without notice.\n
# Translators please note do not translate the options themselves

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2018, 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
@ -30,6 +30,7 @@ import java.net.SocketException;
import java.net.SocketOption;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Defines the infrastructure to support extended socket options, beyond those
@ -40,6 +41,9 @@ import java.util.Set;
*/
public abstract class ExtendedSocketOptions {
public static final short SOCK_STREAM = 1;
public static final short SOCK_DGRAM = 2;
private final Set<SocketOption<?>> options;
/** Tells whether or not the option is supported. */
@ -50,6 +54,30 @@ public abstract class ExtendedSocketOptions {
/** Return the, possibly empty, set of extended socket options available. */
public final Set<SocketOption<?>> options() { return options; }
public static final Set<SocketOption<?>> options(short type) {
return getInstance().options0(type);
}
private Set<SocketOption<?>> options0(short type) {
Set<SocketOption<?>> extOptions = null;
switch (type) {
case SOCK_DGRAM:
extOptions = options.stream()
.filter((option) -> !option.name().startsWith("TCP_"))
.collect(Collectors.toUnmodifiableSet());
break;
case SOCK_STREAM:
extOptions = options.stream()
.filter((option) -> !option.name().startsWith("UDP_"))
.collect(Collectors.toUnmodifiableSet());
break;
default:
//this will never happen
throw new IllegalArgumentException("Invalid socket option type");
}
return extOptions;
}
/** Sets the value of a socket option, for the given socket. */
public abstract void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
throws SocketException;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -39,6 +39,8 @@ import java.util.concurrent.Future;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import sun.net.NetHooks;
import sun.net.ext.ExtendedSocketOptions;
import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
/**
* Base implementation of AsynchronousServerSocketChannel.
@ -234,6 +236,7 @@ abstract class AsynchronousServerSocketChannelImpl
if (Net.isReusePortAvailable()) {
set.add(StandardSocketOptions.SO_REUSEPORT);
}
set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
return Collections.unmodifiableSet(set);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2018, 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
@ -40,6 +40,7 @@ import java.util.concurrent.*;
import java.util.concurrent.locks.*;
import sun.net.NetHooks;
import sun.net.ext.ExtendedSocketOptions;
import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
/**
* Base implementation of AsynchronousSocketChannel
@ -512,9 +513,7 @@ abstract class AsynchronousSocketChannelImpl
set.add(StandardSocketOptions.SO_REUSEPORT);
}
set.add(StandardSocketOptions.TCP_NODELAY);
ExtendedSocketOptions extendedOptions =
ExtendedSocketOptions.getInstance();
set.addAll(extendedOptions.options());
set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
return Collections.unmodifiableSet(set);
}
}

View file

@ -57,6 +57,7 @@ import java.util.concurrent.locks.ReentrantLock;
import sun.net.ResourceManager;
import sun.net.ext.ExtendedSocketOptions;
import static sun.net.ext.ExtendedSocketOptions.SOCK_DGRAM;
/**
* An implementation of DatagramChannels.
@ -334,7 +335,7 @@ class DatagramChannelImpl
set.add(StandardSocketOptions.IP_MULTICAST_IF);
set.add(StandardSocketOptions.IP_MULTICAST_TTL);
set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
set.addAll(ExtendedSocketOptions.getInstance().options());
set.addAll(ExtendedSocketOptions.options(SOCK_DGRAM));
return Collections.unmodifiableSet(set);
}
}

View file

@ -25,6 +25,9 @@
package sun.nio.ch;
import java.lang.invoke.ConstantBootstraps;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
@ -39,6 +42,13 @@ import java.nio.channels.spi.AbstractSelectionKey;
public final class SelectionKeyImpl
extends AbstractSelectionKey
{
private static final VarHandle INTERESTOPS =
ConstantBootstraps.fieldVarHandle(
MethodHandles.lookup(),
"interestOps",
VarHandle.class,
SelectionKeyImpl.class, int.class);
private final SelChImpl channel;
private final SelectorImpl selector;
@ -84,7 +94,35 @@ public final class SelectionKeyImpl
@Override
public SelectionKey interestOps(int ops) {
ensureValid();
return nioInterestOps(ops);
if ((ops & ~channel().validOps()) != 0)
throw new IllegalArgumentException();
int oldOps = (int) INTERESTOPS.getAndSet(this, ops);
if (ops != oldOps) {
selector.setEventOps(this);
}
return this;
}
@Override
public int interestOpsOr(int ops) {
ensureValid();
if ((ops & ~channel().validOps()) != 0)
throw new IllegalArgumentException();
int oldVal = (int) INTERESTOPS.getAndBitwiseOr(this, ops);
if (oldVal != (oldVal | ops)) {
selector.setEventOps(this);
}
return oldVal;
}
@Override
public int interestOpsAnd(int ops) {
ensureValid();
int oldVal = (int) INTERESTOPS.getAndBitwiseAnd(this, ops);
if (oldVal != (oldVal & ops)) {
selector.setEventOps(this);
}
return oldVal;
}
@Override

View file

@ -49,6 +49,8 @@ import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import sun.net.NetHooks;
import sun.net.ext.ExtendedSocketOptions;
import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
/**
* An implementation of ServerSocketChannels
@ -199,6 +201,7 @@ class ServerSocketChannelImpl
set.add(StandardSocketOptions.SO_REUSEPORT);
}
set.add(StandardSocketOptions.IP_TOS);
set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
return Collections.unmodifiableSet(set);
}
}

View file

@ -54,6 +54,7 @@ import java.util.concurrent.locks.ReentrantLock;
import sun.net.NetHooks;
import sun.net.ext.ExtendedSocketOptions;
import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
/**
* An implementation of SocketChannels
@ -280,7 +281,7 @@ class SocketChannelImpl
// additional options required by socket adaptor
set.add(StandardSocketOptions.IP_TOS);
set.add(ExtendedSocketOption.SO_OOBINLINE);
set.addAll(ExtendedSocketOptions.getInstance().options());
set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
return Collections.unmodifiableSet(set);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2018, 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
@ -106,6 +106,7 @@ public class FormatData extends ParallelListResourceBundle {
"T",
"S",
"H",
"N", // NewEra
};
// Japanese imperial calendar era strings
@ -115,6 +116,7 @@ public class FormatData extends ParallelListResourceBundle {
"Taisho",
"Showa",
"Heisei",
"NewEra", // NewEra
};
return new Object[][] {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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
@ -159,6 +159,7 @@ public class JavaTimeSupplementary extends OpenListResourceBundle {
"Taisho",
"Showa",
"Heisei",
"NewEra", // New Era
};
final String[] sharedShortEras = {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -48,6 +48,7 @@ import java.util.TimeZone;
* Taisho 1912-07-30T00:00:00 local time
* Showa 1926-12-25T00:00:00 local time
* Heisei 1989-01-08T00:00:00 local time
* NewEra 2019-05-01T00:00:00 local time
* -----------------------------------------------------------------------
* }</pre>
*

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,8 @@ package sun.util.calendar;
import java.security.AccessController;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import sun.security.action.GetPropertyAction;
/**
@ -41,11 +43,12 @@ public class LocalGregorianCalendar extends BaseCalendar {
new Era("Taisho", "T", -1812153600000L, true),
new Era("Showa", "S", -1357603200000L, true),
new Era("Heisei", "H", 600220800000L, true),
new Era("NewEra", "N", 1556668800000L, true),
};
private static boolean isValidEra(Era newEra, Era[] eras) {
Era last = eras[eras.length - 1];
if (last.getSinceDate().getYear() >= newEra.getSinceDate().getYear()) {
if (last.getSince(null) >= newEra.getSince(null)) {
return false;
}
// The new era name should be unique. Its abbr may not.
@ -173,7 +176,7 @@ public class LocalGregorianCalendar extends BaseCalendar {
return null;
}
String key = keyvalue[0].trim();
String value = keyvalue[1].trim();
String value = convertUnicodeEscape(keyvalue[1].trim());
switch (key) {
case "name":
eraName = value;
@ -203,6 +206,17 @@ public class LocalGregorianCalendar extends BaseCalendar {
return new Era(eraName, abbr, since, localTime);
}
private static String convertUnicodeEscape(String src) {
Matcher m = Pattern.compile("\\\\u([0-9a-fA-F]{4})").matcher(src);
StringBuilder sb = new StringBuilder();
while (m.find()) {
m.appendReplacement(sb,
Character.toString((char)Integer.parseUnsignedInt(m.group(1), 16)));
}
m.appendTail(sb);
return sb.toString();
}
private LocalGregorianCalendar(String name, Era[] eras) {
this.name = name;
this.eras = eras;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018, 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
@ -35,8 +35,8 @@ import sun.util.calendar.CalendarSystem;
import sun.util.calendar.Era;
/**
* Concrete implementation of the {@link java.util.spi.CalendarDataProvider
* CalendarDataProvider} class for the JRE LocaleProviderAdapter.
* Concrete implementation of the {@link java.util.spi.CalendarNameProvider
* CalendarNameProvider} class for the JRE LocaleProviderAdapter.
*
* @author Masayoshi Okutsu
* @author Naoto Sato
@ -77,28 +77,43 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
if (field == DAY_OF_WEEK || field == YEAR) {
--value;
}
if (value < 0 || value > strings.length) {
if (value < 0) {
return null;
} else if (value == strings.length) {
} else if (value >= strings.length) {
if (field == ERA && "japanese".equals(calendarType)) {
// get the supplemental era, if any, specified through
// the property "jdk.calendar.japanese.supplemental.era"
// which is always the last element.
Era[] jeras = CalendarSystem.forName("japanese").getEras();
if (jeras.length == value) {
Era supEra = jeras[value - 1]; // 0-based index
if (javatime) {
return getBaseStyle(style) == NARROW_FORMAT ?
supEra.getAbbreviation() :
supEra.getName();
} else {
return (style & LONG) != 0 ?
supEra.getName() :
supEra.getAbbreviation();
if (value <= jeras.length) {
// Localized era name could not be retrieved from this provider.
// This can occur either for NewEra or SupEra.
//
// If it's CLDR provider, try COMPAT first, which is guaranteed to have
// the name for NewEra.
if (type == LocaleProviderAdapter.Type.CLDR) {
lr = LocaleProviderAdapter.forJRE().getLocaleResources(locale);
key = getResourceKeyFor(LocaleProviderAdapter.Type.JRE,
calendarType, field, style, javatime);
strings =
javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
}
if (strings == null || value >= strings.length) {
// Get the default name for SupEra
Era supEra = jeras[value - 1]; // 0-based index
if (javatime) {
return getBaseStyle(style) == NARROW_FORMAT ?
supEra.getAbbreviation() :
supEra.getName();
} else {
return (style & LONG) != 0 ?
supEra.getName() :
supEra.getAbbreviation();
}
}
} else {
return null;
}
} else {
return null;
}
return null;
}
name = strings[value];
// If name is empty in standalone, try its `format' style.
@ -180,7 +195,7 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
return map;
}
private int getBaseStyle(int style) {
private static int getBaseStyle(int style) {
return style & ~(SHORT_STANDALONE - SHORT_FORMAT);
}
@ -261,6 +276,11 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
}
private String getResourceKey(String type, int field, int style, boolean javatime) {
return getResourceKeyFor(this.type, type, field, style, javatime);
}
private static String getResourceKeyFor(LocaleProviderAdapter.Type adapterType,
String type, int field, int style, boolean javatime) {
int baseStyle = getBaseStyle(style);
boolean isStandalone = (style != baseStyle);
@ -284,7 +304,7 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
// JRE and CLDR use different resource key conventions
// due to historical reasons. (JRE DateFormatSymbols.getEras returns
// abbreviations while other getShort*() return abbreviations.)
if (this.type == LocaleProviderAdapter.Type.JRE) {
if (adapterType == LocaleProviderAdapter.Type.JRE) {
if (javatime) {
if (baseStyle == LONG) {
key.append("long.");
@ -336,7 +356,7 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
return key.length() > 0 ? key.toString() : null;
}
private String toStyleName(int baseStyle) {
private static String toStyleName(int baseStyle) {
switch (baseStyle) {
case SHORT:
return "Abbreviations";

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2005, 2018, 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
@ -178,6 +178,7 @@ MMK=MMK
MNT=MNT
MOP=MOP
MRO=MRO
MRU=MRU
MTL=MTL
MUR=MUR
MVR=MVR
@ -399,6 +400,7 @@ mmk=Myanma Kyat
mnt=Mongolian Tugrik
mop=Macanese Pataca
mro=Mauritanian Ouguiya
mru=Mauritanian Ouguiya
mtl=Maltese Lira
mur=Mauritian Rupee
mvr=Maldivian Rufiyaa