Merge
This commit is contained in:
commit
80340c2a34
@ -64,7 +64,7 @@ endif
|
||||
BASE_LOCALES := en en-US
|
||||
|
||||
# Locales that don't have any resource files should be included here.
|
||||
ALL_NON_BASE_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH
|
||||
ALL_NON_BASE_LOCALES := ja-JP-JP th-TH-TH
|
||||
|
||||
SED_BASEARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
|
||||
SED_NONBASEARGS := $(SED_BASEARGS)
|
||||
@ -89,6 +89,10 @@ define CaptureLocale
|
||||
$1_NON_BASE_LOCALES := $$(subst zh-MO,zh-MO$$(SPACE)zh-Hant-MO, $$($1_NON_BASE_LOCALES))
|
||||
$1_NON_BASE_LOCALES := $$(subst zh-TW,zh-TW$$(SPACE)zh-Hant-TW, $$($1_NON_BASE_LOCALES))
|
||||
|
||||
# Adding implict locales nn-NO and nb-NO
|
||||
$1_NON_BASE_LOCALES += nn-NO nb-NO
|
||||
$1_NON_BASE_LOCALES := $$(sort $$($1_NON_BASE_LOCALES))
|
||||
|
||||
ALL_BASE_LOCALES += $$($1_BASE_LOCALES)
|
||||
ALL_NON_BASE_LOCALES += $$($1_NON_BASE_LOCALES)
|
||||
|
||||
|
@ -487,10 +487,43 @@ public class CLDRConverter {
|
||||
metaInfo.get("AvailableLocales").add(toLanguageTag(bundle.getID()));
|
||||
addLikelySubtags(metaInfo, "AvailableLocales", bundle.getID());
|
||||
}
|
||||
|
||||
addCldrImplicitLocales(metaInfo);
|
||||
bundleGenerator.generateMetaInfo(metaInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* These are the Locales that are implicitly supported by CLDR.
|
||||
* Adding them explicitly as likelySubtags here, will ensure that
|
||||
* COMPAT locales do not precede them during ResourceBundle search path.
|
||||
*/
|
||||
private static void addCldrImplicitLocales(Map<String, SortedSet<String>> metaInfo) {
|
||||
metaInfo.get("LocaleNames").add("zh-Hans-CN");
|
||||
metaInfo.get("LocaleNames").add("zh-Hans-SG");
|
||||
metaInfo.get("LocaleNames").add("zh-Hant-HK");
|
||||
metaInfo.get("LocaleNames").add("zh-Hant-MO");
|
||||
metaInfo.get("LocaleNames").add("zh-Hant-TW");
|
||||
metaInfo.get("CurrencyNames").add("zh-Hans-CN");
|
||||
metaInfo.get("CurrencyNames").add("zh-Hans-SG");
|
||||
metaInfo.get("CurrencyNames").add("zh-Hant-HK");
|
||||
metaInfo.get("CurrencyNames").add("zh-Hant-MO");
|
||||
metaInfo.get("CurrencyNames").add("zh-Hant-TW");
|
||||
metaInfo.get("TimeZoneNames").add("zh-Hans-CN");
|
||||
metaInfo.get("TimeZoneNames").add("zh-Hans-SG");
|
||||
metaInfo.get("TimeZoneNames").add("zh-Hant-HK");
|
||||
metaInfo.get("TimeZoneNames").add("zh-Hant-MO");
|
||||
metaInfo.get("TimeZoneNames").add("zh-Hant-TW");
|
||||
metaInfo.get("TimeZoneNames").add("zh-HK");
|
||||
metaInfo.get("CalendarData").add("zh-Hans-CN");
|
||||
metaInfo.get("CalendarData").add("zh-Hans-SG");
|
||||
metaInfo.get("CalendarData").add("zh-Hant-HK");
|
||||
metaInfo.get("CalendarData").add("zh-Hant-MO");
|
||||
metaInfo.get("CalendarData").add("zh-Hant-TW");
|
||||
metaInfo.get("FormatData").add("zh-Hans-CN");
|
||||
metaInfo.get("FormatData").add("zh-Hans-SG");
|
||||
metaInfo.get("FormatData").add("zh-Hant-HK");
|
||||
metaInfo.get("FormatData").add("zh-Hant-MO");
|
||||
metaInfo.get("FormatData").add("zh-Hant-TW");
|
||||
}
|
||||
static final Map<String, String> aliases = new HashMap<>();
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2016, 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
|
||||
@ -353,12 +353,13 @@ class FileTreeWalker implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
// no next entry so close and pop directory, creating corresponding event
|
||||
// no next entry so close and pop directory,
|
||||
// creating corresponding event
|
||||
if (entry == null) {
|
||||
try {
|
||||
top.stream().close();
|
||||
} catch (IOException e) {
|
||||
if (ioe != null) {
|
||||
if (ioe == null) {
|
||||
ioe = e;
|
||||
} else {
|
||||
ioe.addSuppressed(e);
|
||||
|
@ -758,16 +758,6 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
dfs = y;
|
||||
}
|
||||
}
|
||||
// If the bundle's locale isn't the target locale, put another cache
|
||||
// entry for the bundle's locale.
|
||||
Locale bundleLocale = resource.getLocale();
|
||||
if (!bundleLocale.equals(locale)) {
|
||||
SoftReference<DateFormatSymbols> z
|
||||
= cachedInstances.putIfAbsent(bundleLocale, ref);
|
||||
if (z != null && z.get() == null) {
|
||||
cachedInstances.replace(bundleLocale, z, ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the field values from dfs to this instance.
|
||||
|
@ -1407,8 +1407,8 @@ public final class LocalDateTime
|
||||
* </ol>
|
||||
* <p>
|
||||
* For example, 2008-02-29 (leap year) minus one year would result in the
|
||||
* invalid date 2009-02-29 (standard year). Instead of returning an invalid
|
||||
* result, the last valid day of the month, 2009-02-28, is selected instead.
|
||||
* invalid date 2007-02-29 (standard year). Instead of returning an invalid
|
||||
* result, the last valid day of the month, 2007-02-28, is selected instead.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
@ -1431,8 +1431,8 @@ public final class LocalDateTime
|
||||
* </ol>
|
||||
* <p>
|
||||
* For example, 2007-03-31 minus one month would result in the invalid date
|
||||
* 2007-04-31. Instead of returning an invalid result, the last valid day
|
||||
* of the month, 2007-04-30, is selected instead.
|
||||
* 2007-02-31. Instead of returning an invalid result, the last valid day
|
||||
* of the month, 2007-02-28, is selected instead.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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
|
||||
@ -1393,8 +1393,8 @@ public final class OffsetDateTime
|
||||
* </ol>
|
||||
* <p>
|
||||
* For example, 2008-02-29 (leap year) minus one year would result in the
|
||||
* invalid date 2009-02-29 (standard year). Instead of returning an invalid
|
||||
* result, the last valid day of the month, 2009-02-28, is selected instead.
|
||||
* invalid date 2007-02-29 (standard year). Instead of returning an invalid
|
||||
* result, the last valid day of the month, 2007-02-28, is selected instead.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
@ -1417,8 +1417,8 @@ public final class OffsetDateTime
|
||||
* </ol>
|
||||
* <p>
|
||||
* For example, 2007-03-31 minus one month would result in the invalid date
|
||||
* 2007-04-31. Instead of returning an invalid result, the last valid day
|
||||
* of the month, 2007-04-30, is selected instead.
|
||||
* 2007-02-31. Instead of returning an invalid result, the last valid day
|
||||
* of the month, 2007-02-28, is selected instead.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
@ -1437,7 +1437,7 @@ public final class OffsetDateTime
|
||||
* the month and year fields as necessary to ensure the result remains valid.
|
||||
* The result is only invalid if the maximum/minimum year is exceeded.
|
||||
* <p>
|
||||
* For example, 2008-12-31 minus one week would result in 2009-01-07.
|
||||
* For example, 2009-01-07 minus one week would result in 2008-12-31.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
@ -1456,7 +1456,7 @@ public final class OffsetDateTime
|
||||
* month and year fields as necessary to ensure the result remains valid.
|
||||
* The result is only invalid if the maximum/minimum year is exceeded.
|
||||
* <p>
|
||||
* For example, 2008-12-31 minus one day would result in 2009-01-01.
|
||||
* For example, 2009-01-01 minus one day would result in 2008-12-31.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
|
@ -1774,16 +1774,20 @@ public final class DateTimeFormatterBuilder {
|
||||
if (count > 1) {
|
||||
throw new IllegalArgumentException("Too many pattern letters: " + cur);
|
||||
}
|
||||
appendInternal(new WeekBasedFieldPrinterParser(cur, count));
|
||||
appendValue(new WeekBasedFieldPrinterParser(cur, count, count, count));
|
||||
} else if (cur == 'w') {
|
||||
// Fields defined by Locale
|
||||
if (count > 2) {
|
||||
throw new IllegalArgumentException("Too many pattern letters: " + cur);
|
||||
}
|
||||
appendInternal(new WeekBasedFieldPrinterParser(cur, count));
|
||||
appendValue(new WeekBasedFieldPrinterParser(cur, count, count, 2));
|
||||
} else if (cur == 'Y') {
|
||||
// Fields defined by Locale
|
||||
appendInternal(new WeekBasedFieldPrinterParser(cur, count));
|
||||
if (count == 2) {
|
||||
appendValue(new WeekBasedFieldPrinterParser(cur, count, count, 2));
|
||||
} else {
|
||||
appendValue(new WeekBasedFieldPrinterParser(cur, count, count, 19));
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown pattern letter: " + cur);
|
||||
}
|
||||
@ -1843,7 +1847,10 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
if (count == 2) {
|
||||
if (count == 1) {
|
||||
appendValue(new WeekBasedFieldPrinterParser(cur, count, count, count));
|
||||
break;
|
||||
} else if (count == 2) {
|
||||
throw new IllegalArgumentException("Invalid pattern \"cc\"");
|
||||
}
|
||||
/*fallthrough*/
|
||||
@ -1858,8 +1865,8 @@ public final class DateTimeFormatterBuilder {
|
||||
switch (count) {
|
||||
case 1:
|
||||
case 2:
|
||||
if (cur == 'c' || cur == 'e') {
|
||||
appendInternal(new WeekBasedFieldPrinterParser(cur, count));
|
||||
if (cur == 'e') {
|
||||
appendValue(new WeekBasedFieldPrinterParser(cur, count, count, count));
|
||||
} else if (cur == 'E') {
|
||||
appendText(field, TextStyle.SHORT);
|
||||
} else {
|
||||
@ -4770,8 +4777,9 @@ public final class DateTimeFormatterBuilder {
|
||||
* the field is to be printed or parsed.
|
||||
* The locale is needed to select the proper WeekFields from which
|
||||
* the field for day-of-week, week-of-month, or week-of-year is selected.
|
||||
* Hence the inherited field NumberPrinterParser.field is unused.
|
||||
*/
|
||||
static final class WeekBasedFieldPrinterParser implements DateTimePrinterParser {
|
||||
static final class WeekBasedFieldPrinterParser extends NumberPrinterParser {
|
||||
private char chr;
|
||||
private int count;
|
||||
|
||||
@ -4780,12 +4788,55 @@ public final class DateTimeFormatterBuilder {
|
||||
*
|
||||
* @param chr the pattern format letter that added this PrinterParser.
|
||||
* @param count the repeat count of the format letter
|
||||
* @param minWidth the minimum field width, from 1 to 19
|
||||
* @param maxWidth the maximum field width, from minWidth to 19
|
||||
*/
|
||||
WeekBasedFieldPrinterParser(char chr, int count) {
|
||||
WeekBasedFieldPrinterParser(char chr, int count, int minWidth, int maxWidth) {
|
||||
this(chr, count, minWidth, maxWidth, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param chr the pattern format letter that added this PrinterParser.
|
||||
* @param count the repeat count of the format letter
|
||||
* @param minWidth the minimum field width, from 1 to 19
|
||||
* @param maxWidth the maximum field width, from minWidth to 19
|
||||
* @param subsequentWidth the width of subsequent non-negative numbers, 0 or greater,
|
||||
* -1 if fixed width due to active adjacent parsing
|
||||
*/
|
||||
WeekBasedFieldPrinterParser(char chr, int count, int minWidth, int maxWidth,
|
||||
int subsequentWidth) {
|
||||
super(null, minWidth, maxWidth, SignStyle.NOT_NEGATIVE, subsequentWidth);
|
||||
this.chr = chr;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance with fixed width flag set.
|
||||
*
|
||||
* @return a new updated printer-parser, not null
|
||||
*/
|
||||
@Override
|
||||
WeekBasedFieldPrinterParser withFixedWidth() {
|
||||
if (subsequentWidth == -1) {
|
||||
return this;
|
||||
}
|
||||
return new WeekBasedFieldPrinterParser(chr, count, minWidth, maxWidth, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance with an updated subsequent width.
|
||||
*
|
||||
* @param subsequentWidth the width of subsequent non-negative numbers, 0 or greater
|
||||
* @return a new updated printer-parser, not null
|
||||
*/
|
||||
@Override
|
||||
WeekBasedFieldPrinterParser withSubsequentWidth(int subsequentWidth) {
|
||||
return new WeekBasedFieldPrinterParser(chr, count, minWidth, maxWidth,
|
||||
this.subsequentWidth + subsequentWidth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean format(DateTimePrintContext context, StringBuilder buf) {
|
||||
return printerParser(context.getLocale()).format(context, buf);
|
||||
@ -4810,10 +4861,12 @@ public final class DateTimeFormatterBuilder {
|
||||
case 'Y':
|
||||
field = weekDef.weekBasedYear();
|
||||
if (count == 2) {
|
||||
return new ReducedPrinterParser(field, 2, 2, 0, ReducedPrinterParser.BASE_DATE, 0);
|
||||
return new ReducedPrinterParser(field, 2, 2, 0, ReducedPrinterParser.BASE_DATE,
|
||||
this.subsequentWidth);
|
||||
} else {
|
||||
return new NumberPrinterParser(field, count, 19,
|
||||
(count < 4) ? SignStyle.NORMAL : SignStyle.EXCEEDS_PAD, -1);
|
||||
(count < 4) ? SignStyle.NORMAL : SignStyle.EXCEEDS_PAD,
|
||||
this.subsequentWidth);
|
||||
}
|
||||
case 'e':
|
||||
case 'c':
|
||||
@ -4828,7 +4881,8 @@ public final class DateTimeFormatterBuilder {
|
||||
default:
|
||||
throw new IllegalStateException("unreachable");
|
||||
}
|
||||
return new NumberPrinterParser(field, (count == 2 ? 2 : 1), 2, SignStyle.NOT_NEGATIVE);
|
||||
return new NumberPrinterParser(field, minWidth, maxWidth, SignStyle.NOT_NEGATIVE,
|
||||
this.subsequentWidth);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -146,16 +146,16 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
||||
if (jump < needed
|
||||
|| (newCapacity = (oldCapacity + jump)) - MAX_ARRAY_SIZE > 0)
|
||||
newCapacity = newCapacity(needed, jump);
|
||||
elements = Arrays.copyOf(elements, newCapacity);
|
||||
final Object[] es = elements = Arrays.copyOf(elements, newCapacity);
|
||||
// Exceptionally, here tail == head needs to be disambiguated
|
||||
if (tail < head || (tail == head && elements[head] != null)) {
|
||||
if (tail < head || (tail == head && es[head] != null)) {
|
||||
// wrap around; slide first leg forward to end of array
|
||||
int newSpace = newCapacity - oldCapacity;
|
||||
System.arraycopy(elements, head,
|
||||
elements, head + newSpace,
|
||||
System.arraycopy(es, head,
|
||||
es, head + newSpace,
|
||||
oldCapacity - head);
|
||||
Arrays.fill(elements, head, head + newSpace, null);
|
||||
head += newSpace;
|
||||
for (int i = head, to = (head += newSpace); i < to; i++)
|
||||
es[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -873,6 +873,9 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
final Object[] es = elements;
|
||||
@ -1035,11 +1038,14 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
||||
|
||||
/**
|
||||
* Nulls out slots starting at array index i, upto index end.
|
||||
* Condition i == end means "empty" - nothing to do.
|
||||
*/
|
||||
private static void circularClear(Object[] es, int i, int end) {
|
||||
// assert 0 <= i && i < es.length;
|
||||
// assert 0 <= end && end < es.length;
|
||||
for (int to = (i <= end) ? end : es.length;
|
||||
; i = 0, to = end) {
|
||||
Arrays.fill(es, i, to, null);
|
||||
for (; i < to; i++) es[i] = null;
|
||||
if (to == end) break;
|
||||
}
|
||||
}
|
||||
|
@ -576,8 +576,9 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
*/
|
||||
public void clear() {
|
||||
modCount++;
|
||||
Arrays.fill(elementData, 0, size, null);
|
||||
size = 0;
|
||||
final Object[] es = elementData;
|
||||
for (int to = size, i = size = 0; i < to; i++)
|
||||
es[i] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -665,10 +666,14 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
outOfBoundsMsg(fromIndex, toIndex));
|
||||
}
|
||||
modCount++;
|
||||
final Object[] es = elementData;
|
||||
final int oldSize = size;
|
||||
System.arraycopy(es, toIndex, es, fromIndex, oldSize - toIndex);
|
||||
Arrays.fill(es, size -= (toIndex - fromIndex), oldSize, null);
|
||||
shiftTailOverGap(elementData, fromIndex, toIndex);
|
||||
}
|
||||
|
||||
/** Erases the gap from lo to hi, by sliding down following elements. */
|
||||
private void shiftTailOverGap(Object[] es, int lo, int hi) {
|
||||
System.arraycopy(es, hi, es, lo, size - hi);
|
||||
for (int to = size, i = (size -= hi - lo); i < to; i++)
|
||||
es[i] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -756,25 +761,25 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
w += end - r;
|
||||
throw ex;
|
||||
} finally {
|
||||
final int oldSize = size, deleted = end - w;
|
||||
modCount += deleted;
|
||||
System.arraycopy(es, end, es, w, oldSize - end);
|
||||
Arrays.fill(es, size -= deleted, oldSize, null);
|
||||
modCount += end - w;
|
||||
shiftTailOverGap(es, w, end);
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the state of the {@code ArrayList} instance to a stream (that
|
||||
* is, serialize it).
|
||||
* Saves the state of the {@code ArrayList} instance to a stream
|
||||
* (that is, serializes it).
|
||||
*
|
||||
* @param s the stream
|
||||
* @throws java.io.IOException if an I/O error occurs
|
||||
* @serialData The length of the array backing the {@code ArrayList}
|
||||
* instance is emitted (int), followed by all of its elements
|
||||
* (each an {@code Object}) in the proper order.
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws java.io.IOException{
|
||||
throws java.io.IOException {
|
||||
// Write out element count, and any hidden stuff
|
||||
int expectedModCount = modCount;
|
||||
s.defaultWriteObject();
|
||||
@ -793,8 +798,12 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstitute the {@code ArrayList} instance from a stream (that is,
|
||||
* deserialize it).
|
||||
* Reconstitutes the {@code ArrayList} instance from a stream (that is,
|
||||
* deserializes it).
|
||||
* @param s the stream
|
||||
* @throws ClassNotFoundException if the class of a serialized object
|
||||
* could not be found
|
||||
* @throws java.io.IOException if an I/O error occurs
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException, ClassNotFoundException {
|
||||
@ -1285,9 +1294,8 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
public Spliterator<E> spliterator() {
|
||||
checkForComodification();
|
||||
|
||||
// ArrayListSpliterator is not used because late-binding logic
|
||||
// is different here
|
||||
return new Spliterator<>() {
|
||||
// ArrayListSpliterator not used here due to late-binding
|
||||
return new Spliterator<E>() {
|
||||
private int index = offset; // current index, modified on advance/split
|
||||
private int fence = -1; // -1 until used; then one past last index
|
||||
private int expectedModCount; // initialized when fence set
|
||||
@ -1301,12 +1309,11 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
return hi;
|
||||
}
|
||||
|
||||
public ArrayListSpliterator<E> trySplit() {
|
||||
public ArrayList<E>.ArrayListSpliterator trySplit() {
|
||||
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
|
||||
// ArrayListSpliterator could be used here as the source is already bound
|
||||
// ArrayListSpliterator can be used here as the source is already bound
|
||||
return (lo >= mid) ? null : // divide range in half unless too small
|
||||
new ArrayListSpliterator<>(root, lo, index = mid,
|
||||
expectedModCount);
|
||||
root.new ArrayListSpliterator(lo, index = mid, expectedModCount);
|
||||
}
|
||||
|
||||
public boolean tryAdvance(Consumer<? super E> action) {
|
||||
@ -1348,7 +1355,7 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
}
|
||||
|
||||
public long estimateSize() {
|
||||
return (long) (getFence() - index);
|
||||
return getFence() - index;
|
||||
}
|
||||
|
||||
public int characteristics() {
|
||||
@ -1358,6 +1365,9 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
@ -1385,11 +1395,11 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
*/
|
||||
@Override
|
||||
public Spliterator<E> spliterator() {
|
||||
return new ArrayListSpliterator<>(this, 0, -1, 0);
|
||||
return new ArrayListSpliterator(0, -1, 0);
|
||||
}
|
||||
|
||||
/** Index-based split-by-two, lazily initialized Spliterator */
|
||||
static final class ArrayListSpliterator<E> implements Spliterator<E> {
|
||||
final class ArrayListSpliterator implements Spliterator<E> {
|
||||
|
||||
/*
|
||||
* If ArrayLists were immutable, or structurally immutable (no
|
||||
@ -1423,15 +1433,12 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
* these streamlinings.
|
||||
*/
|
||||
|
||||
private final ArrayList<E> list;
|
||||
private int index; // current index, modified on advance/split
|
||||
private int fence; // -1 until used; then one past last index
|
||||
private int expectedModCount; // initialized when fence set
|
||||
|
||||
/** Create new spliterator covering the given range */
|
||||
ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
|
||||
int expectedModCount) {
|
||||
this.list = list; // OK if null unless traversed
|
||||
/** Creates new spliterator covering the given range. */
|
||||
ArrayListSpliterator(int origin, int fence, int expectedModCount) {
|
||||
this.index = origin;
|
||||
this.fence = fence;
|
||||
this.expectedModCount = expectedModCount;
|
||||
@ -1439,23 +1446,17 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
|
||||
private int getFence() { // initialize fence to size on first use
|
||||
int hi; // (a specialized variant appears in method forEach)
|
||||
ArrayList<E> lst;
|
||||
if ((hi = fence) < 0) {
|
||||
if ((lst = list) == null)
|
||||
hi = fence = 0;
|
||||
else {
|
||||
expectedModCount = lst.modCount;
|
||||
hi = fence = lst.size;
|
||||
}
|
||||
expectedModCount = modCount;
|
||||
hi = fence = size;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
|
||||
public ArrayListSpliterator<E> trySplit() {
|
||||
public ArrayListSpliterator trySplit() {
|
||||
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
|
||||
return (lo >= mid) ? null : // divide range in half unless too small
|
||||
new ArrayListSpliterator<>(list, lo, index = mid,
|
||||
expectedModCount);
|
||||
new ArrayListSpliterator(lo, index = mid, expectedModCount);
|
||||
}
|
||||
|
||||
public boolean tryAdvance(Consumer<? super E> action) {
|
||||
@ -1464,9 +1465,9 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
int hi = getFence(), i = index;
|
||||
if (i < hi) {
|
||||
index = i + 1;
|
||||
@SuppressWarnings("unchecked") E e = (E)list.elementData[i];
|
||||
@SuppressWarnings("unchecked") E e = (E)elementData[i];
|
||||
action.accept(e);
|
||||
if (list.modCount != expectedModCount)
|
||||
if (modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
return true;
|
||||
}
|
||||
@ -1475,13 +1476,13 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
int i, hi, mc; // hoist accesses and checks from loop
|
||||
ArrayList<E> lst; Object[] a;
|
||||
Object[] a;
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
if ((lst = list) != null && (a = lst.elementData) != null) {
|
||||
if ((a = elementData) != null) {
|
||||
if ((hi = fence) < 0) {
|
||||
mc = lst.modCount;
|
||||
hi = lst.size;
|
||||
mc = modCount;
|
||||
hi = size;
|
||||
}
|
||||
else
|
||||
mc = expectedModCount;
|
||||
@ -1490,7 +1491,7 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
@SuppressWarnings("unchecked") E e = (E) a[i];
|
||||
action.accept(e);
|
||||
}
|
||||
if (lst.modCount == mc)
|
||||
if (modCount == mc)
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1498,7 +1499,7 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
}
|
||||
|
||||
public long estimateSize() {
|
||||
return (long) (getFence() - index);
|
||||
return getFence() - index;
|
||||
}
|
||||
|
||||
public int characteristics() {
|
||||
@ -1518,6 +1519,9 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
return (bits[i >> 6] & (1L << i)) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean removeIf(Predicate<? super E> filter) {
|
||||
return removeIf(filter, 0, size);
|
||||
@ -1552,9 +1556,7 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
for (i = beg; i < end; i++)
|
||||
if (isClear(deathRow, i - beg))
|
||||
es[w++] = es[i];
|
||||
final int oldSize = size;
|
||||
System.arraycopy(es, end, es, w, oldSize - end);
|
||||
Arrays.fill(es, size -= (end - w), oldSize, null);
|
||||
shiftTailOverGap(es, w, end);
|
||||
return true;
|
||||
} else {
|
||||
if (modCount != expectedModCount)
|
||||
|
@ -522,6 +522,8 @@ public class PriorityQueue<E> extends AbstractQueue<E>
|
||||
*/
|
||||
private int expectedModCount = modCount;
|
||||
|
||||
Itr() {} // prevent access constructor creation
|
||||
|
||||
public boolean hasNext() {
|
||||
return cursor < size ||
|
||||
(forgetMeNot != null && !forgetMeNot.isEmpty());
|
||||
@ -631,7 +633,7 @@ public class PriorityQueue<E> extends AbstractQueue<E>
|
||||
* promoting x up the tree until it is greater than or equal to
|
||||
* its parent, or is the root.
|
||||
*
|
||||
* To simplify and speed up coercions and comparisons. the
|
||||
* To simplify and speed up coercions and comparisons, the
|
||||
* Comparable and Comparator versions are separated into different
|
||||
* methods that are otherwise identical. (Similarly for siftDown.)
|
||||
*
|
||||
@ -727,11 +729,18 @@ public class PriorityQueue<E> extends AbstractQueue<E>
|
||||
/**
|
||||
* Establishes the heap invariant (described above) in the entire tree,
|
||||
* assuming nothing about the order of the elements prior to the call.
|
||||
* This classic algorithm due to Floyd (1964) is known to be O(size).
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void heapify() {
|
||||
for (int i = (size >>> 1) - 1; i >= 0; i--)
|
||||
siftDown(i, (E) queue[i]);
|
||||
final Object[] es = queue;
|
||||
final int half = (size >>> 1) - 1;
|
||||
if (comparator == null)
|
||||
for (int i = half; i >= 0; i--)
|
||||
siftDownComparable(i, (E) es[i]);
|
||||
else
|
||||
for (int i = half; i >= 0; i--)
|
||||
siftDownUsingComparator(i, (E) es[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -812,23 +821,16 @@ public class PriorityQueue<E> extends AbstractQueue<E>
|
||||
* @since 1.8
|
||||
*/
|
||||
public final Spliterator<E> spliterator() {
|
||||
return new PriorityQueueSpliterator<>(this, 0, -1, 0);
|
||||
return new PriorityQueueSpliterator(0, -1, 0);
|
||||
}
|
||||
|
||||
static final class PriorityQueueSpliterator<E> implements Spliterator<E> {
|
||||
/*
|
||||
* This is very similar to ArrayList Spliterator, except for
|
||||
* extra null checks.
|
||||
*/
|
||||
private final PriorityQueue<E> pq;
|
||||
final class PriorityQueueSpliterator implements Spliterator<E> {
|
||||
private int index; // current index, modified on advance/split
|
||||
private int fence; // -1 until first use
|
||||
private int expectedModCount; // initialized when fence set
|
||||
|
||||
/** Creates new spliterator covering the given range. */
|
||||
PriorityQueueSpliterator(PriorityQueue<E> pq, int origin, int fence,
|
||||
int expectedModCount) {
|
||||
this.pq = pq;
|
||||
PriorityQueueSpliterator(int origin, int fence, int expectedModCount) {
|
||||
this.index = origin;
|
||||
this.fence = fence;
|
||||
this.expectedModCount = expectedModCount;
|
||||
@ -837,68 +839,54 @@ public class PriorityQueue<E> extends AbstractQueue<E>
|
||||
private int getFence() { // initialize fence to size on first use
|
||||
int hi;
|
||||
if ((hi = fence) < 0) {
|
||||
expectedModCount = pq.modCount;
|
||||
hi = fence = pq.size;
|
||||
expectedModCount = modCount;
|
||||
hi = fence = size;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
|
||||
public PriorityQueueSpliterator<E> trySplit() {
|
||||
public PriorityQueueSpliterator trySplit() {
|
||||
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
|
||||
return (lo >= mid) ? null :
|
||||
new PriorityQueueSpliterator<>(pq, lo, index = mid,
|
||||
expectedModCount);
|
||||
new PriorityQueueSpliterator(lo, index = mid, expectedModCount);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
int i, hi, mc; // hoist accesses and checks from loop
|
||||
PriorityQueue<E> q; Object[] a;
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
if ((q = pq) != null && (a = q.queue) != null) {
|
||||
if ((hi = fence) < 0) {
|
||||
mc = q.modCount;
|
||||
hi = q.size;
|
||||
}
|
||||
else
|
||||
mc = expectedModCount;
|
||||
if ((i = index) >= 0 && (index = hi) <= a.length) {
|
||||
for (E e;; ++i) {
|
||||
if (i < hi) {
|
||||
if ((e = (E) a[i]) == null) // must be CME
|
||||
break;
|
||||
action.accept(e);
|
||||
}
|
||||
else if (q.modCount != mc)
|
||||
break;
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (fence < 0) { fence = size; expectedModCount = modCount; }
|
||||
final Object[] a = queue;
|
||||
int i, hi; E e;
|
||||
for (i = index, index = hi = fence; i < hi; i++) {
|
||||
if ((e = (E) a[i]) == null)
|
||||
break; // must be CME
|
||||
action.accept(e);
|
||||
}
|
||||
throw new ConcurrentModificationException();
|
||||
if (modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean tryAdvance(Consumer<? super E> action) {
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
int hi = getFence(), lo = index;
|
||||
if (lo >= 0 && lo < hi) {
|
||||
index = lo + 1;
|
||||
@SuppressWarnings("unchecked") E e = (E)pq.queue[lo];
|
||||
if (e == null)
|
||||
if (fence < 0) { fence = size; expectedModCount = modCount; }
|
||||
int i;
|
||||
if ((i = index) < fence) {
|
||||
index = i + 1;
|
||||
E e;
|
||||
if ((e = (E) queue[i]) == null
|
||||
|| modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
action.accept(e);
|
||||
if (pq.modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public long estimateSize() {
|
||||
return (long) (getFence() - index);
|
||||
return getFence() - index;
|
||||
}
|
||||
|
||||
public int characteristics() {
|
||||
|
@ -2942,17 +2942,6 @@ public abstract class ResourceBundle {
|
||||
script = "Hans";
|
||||
break;
|
||||
}
|
||||
} else if (script.length() > 0 && region.length() == 0) {
|
||||
// Supply region(country) for users who still package Chinese
|
||||
// bundles using old convension.
|
||||
switch (script) {
|
||||
case "Hans":
|
||||
region = "CN";
|
||||
break;
|
||||
case "Hant":
|
||||
region = "TW";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2983,6 +2972,21 @@ public abstract class ResourceBundle {
|
||||
}
|
||||
if (script.length() > 0) {
|
||||
list.add(Locale.getInstance(language, script, "", "", null));
|
||||
// Special handling for Chinese
|
||||
if (language.equals("zh")) {
|
||||
if (region.length() == 0) {
|
||||
// Supply region(country) for users who still package Chinese
|
||||
// bundles using old convension.
|
||||
switch (script) {
|
||||
case "Hans":
|
||||
region = "CN";
|
||||
break;
|
||||
case "Hant":
|
||||
region = "TW";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// With script, after truncating variant, region and script,
|
||||
// start over without script.
|
||||
|
@ -375,7 +375,7 @@ public final class SplittableRandom {
|
||||
* may, and typically does, vary across program invocations.
|
||||
*/
|
||||
public SplittableRandom() { // emulate defaultGen.split()
|
||||
long s = defaultGen.getAndAdd(2 * GOLDEN_GAMMA);
|
||||
long s = defaultGen.getAndAdd(GOLDEN_GAMMA << 1);
|
||||
this.seed = mix64(s);
|
||||
this.gamma = mixGamma(s + GOLDEN_GAMMA);
|
||||
}
|
||||
|
@ -306,9 +306,9 @@ public class Vector<E>
|
||||
modCount++;
|
||||
if (newSize > elementData.length)
|
||||
grow(newSize);
|
||||
for (int i = newSize; i < elementCount; i++)
|
||||
elementData[i] = null;
|
||||
elementCount = newSize;
|
||||
final Object[] es = elementData;
|
||||
for (int to = elementCount, i = elementCount = newSize; i < to; i++)
|
||||
es[i] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -675,9 +675,10 @@ public class Vector<E>
|
||||
* method (which is part of the {@link List} interface).
|
||||
*/
|
||||
public synchronized void removeAllElements() {
|
||||
Arrays.fill(elementData, 0, elementCount, null);
|
||||
final Object[] es = elementData;
|
||||
for (int to = elementCount, i = elementCount = 0; i < to; i++)
|
||||
es[i] = null;
|
||||
modCount++;
|
||||
elementCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -980,6 +981,9 @@ public class Vector<E>
|
||||
return bulkRemove(e -> !c.contains(e));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean removeIf(Predicate<? super E> filter) {
|
||||
Objects.requireNonNull(filter);
|
||||
@ -1024,7 +1028,8 @@ public class Vector<E>
|
||||
for (i = beg; i < end; i++)
|
||||
if (isClear(deathRow, i - beg))
|
||||
es[w++] = es[i];
|
||||
Arrays.fill(es, elementCount = w, end, null);
|
||||
for (i = elementCount = w; i < end; i++)
|
||||
es[i] = null;
|
||||
return true;
|
||||
} else {
|
||||
if (modCount != expectedModCount)
|
||||
@ -1152,19 +1157,25 @@ public class Vector<E>
|
||||
* (If {@code toIndex==fromIndex}, this operation has no effect.)
|
||||
*/
|
||||
protected synchronized void removeRange(int fromIndex, int toIndex) {
|
||||
final Object[] es = elementData;
|
||||
final int oldSize = elementCount;
|
||||
System.arraycopy(es, toIndex, es, fromIndex, oldSize - toIndex);
|
||||
|
||||
modCount++;
|
||||
Arrays.fill(es, elementCount -= (toIndex - fromIndex), oldSize, null);
|
||||
shiftTailOverGap(elementData, fromIndex, toIndex);
|
||||
}
|
||||
|
||||
/** Erases the gap from lo to hi, by sliding down following elements. */
|
||||
private void shiftTailOverGap(Object[] es, int lo, int hi) {
|
||||
System.arraycopy(es, hi, es, lo, elementCount - hi);
|
||||
for (int to = elementCount, i = (elementCount -= hi - lo); i < to; i++)
|
||||
es[i] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the state of the {@code Vector} instance to a stream (that
|
||||
* is, serialize it).
|
||||
* Saves the state of the {@code Vector} instance to a stream
|
||||
* (that is, serializes it).
|
||||
* This method performs synchronization to ensure the consistency
|
||||
* of the serialized data.
|
||||
*
|
||||
* @param s the stream
|
||||
* @throws java.io.IOException if an I/O error occurs
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws java.io.IOException {
|
||||
@ -1337,6 +1348,9 @@ public class Vector<E>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public synchronized void forEach(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
@ -1349,6 +1363,9 @@ public class Vector<E>
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public synchronized void replaceAll(UnaryOperator<E> operator) {
|
||||
Objects.requireNonNull(operator);
|
||||
@ -1387,21 +1404,19 @@ public class Vector<E>
|
||||
*/
|
||||
@Override
|
||||
public Spliterator<E> spliterator() {
|
||||
return new VectorSpliterator<>(this, null, 0, -1, 0);
|
||||
return new VectorSpliterator(null, 0, -1, 0);
|
||||
}
|
||||
|
||||
/** Similar to ArrayList Spliterator */
|
||||
static final class VectorSpliterator<E> implements Spliterator<E> {
|
||||
private final Vector<E> list;
|
||||
final class VectorSpliterator implements Spliterator<E> {
|
||||
private Object[] array;
|
||||
private int index; // current index, modified on advance/split
|
||||
private int fence; // -1 until used; then one past last index
|
||||
private int expectedModCount; // initialized when fence set
|
||||
|
||||
/** Create new spliterator covering the given range */
|
||||
VectorSpliterator(Vector<E> list, Object[] array, int origin, int fence,
|
||||
/** Creates new spliterator covering the given range. */
|
||||
VectorSpliterator(Object[] array, int origin, int fence,
|
||||
int expectedModCount) {
|
||||
this.list = list;
|
||||
this.array = array;
|
||||
this.index = origin;
|
||||
this.fence = fence;
|
||||
@ -1411,10 +1426,10 @@ public class Vector<E>
|
||||
private int getFence() { // initialize on first use
|
||||
int hi;
|
||||
if ((hi = fence) < 0) {
|
||||
synchronized (list) {
|
||||
array = list.elementData;
|
||||
expectedModCount = list.modCount;
|
||||
hi = fence = list.elementCount;
|
||||
synchronized (Vector.this) {
|
||||
array = elementData;
|
||||
expectedModCount = modCount;
|
||||
hi = fence = elementCount;
|
||||
}
|
||||
}
|
||||
return hi;
|
||||
@ -1423,8 +1438,7 @@ public class Vector<E>
|
||||
public Spliterator<E> trySplit() {
|
||||
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
|
||||
return (lo >= mid) ? null :
|
||||
new VectorSpliterator<>(list, array, lo, index = mid,
|
||||
expectedModCount);
|
||||
new VectorSpliterator(array, lo, index = mid, expectedModCount);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -1435,7 +1449,7 @@ public class Vector<E>
|
||||
if (getFence() > (i = index)) {
|
||||
index = i + 1;
|
||||
action.accept((E)array[i]);
|
||||
if (list.modCount != expectedModCount)
|
||||
if (modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
return true;
|
||||
}
|
||||
@ -1444,28 +1458,15 @@ public class Vector<E>
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
int i, hi; // hoist accesses and checks from loop
|
||||
Vector<E> lst; Object[] a;
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
if ((lst = list) != null) {
|
||||
if ((hi = fence) < 0) {
|
||||
synchronized (lst) {
|
||||
expectedModCount = lst.modCount;
|
||||
a = array = lst.elementData;
|
||||
hi = fence = lst.elementCount;
|
||||
}
|
||||
}
|
||||
else
|
||||
a = array;
|
||||
if (a != null && (i = index) >= 0 && (index = hi) <= a.length) {
|
||||
while (i < hi)
|
||||
action.accept((E) a[i++]);
|
||||
if (lst.modCount == expectedModCount)
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new ConcurrentModificationException();
|
||||
final int hi = getFence();
|
||||
final Object[] a = array;
|
||||
int i;
|
||||
for (i = index, index = hi; i < hi; i++)
|
||||
action.accept((E) a[i]);
|
||||
if (modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
public long estimateSize() {
|
||||
|
@ -675,12 +675,14 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E>
|
||||
|
||||
/**
|
||||
* Nulls out slots starting at array index i, upto index end.
|
||||
* If i == end, the entire array is cleared!
|
||||
* Condition i == end means "full" - the entire array is cleared.
|
||||
*/
|
||||
private static void circularClear(Object[] items, int i, int end) {
|
||||
// assert 0 <= i && i < items.length;
|
||||
// assert 0 <= end && end < items.length;
|
||||
for (int to = (i < end) ? end : items.length;
|
||||
; i = 0, to = end) {
|
||||
Arrays.fill(items, i, to, null);
|
||||
for (; i < to; i++) items[i] = null;
|
||||
if (to == end) break;
|
||||
}
|
||||
}
|
||||
@ -1011,6 +1013,11 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E>
|
||||
* expected element to remove, in lastItem. Yes, we may fail to
|
||||
* remove lastItem from the queue if it moved due to an interleaved
|
||||
* interior remove while in detached mode.
|
||||
*
|
||||
* Method forEachRemaining, added in Java 8, is treated similarly
|
||||
* to hasNext returning false, in that we switch to detached mode,
|
||||
* but we regard it as an even stronger request to "close" this
|
||||
* iteration, and don't bother supporting subsequent remove().
|
||||
*/
|
||||
private class Itr implements Iterator<E> {
|
||||
/** Index to look for new nextItem; NONE at end */
|
||||
@ -1432,6 +1439,9 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E>
|
||||
Spliterator.CONCURRENT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
final ReentrantLock lock = this.lock;
|
||||
|
@ -48,6 +48,7 @@ import java.util.Queue;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
|
||||
@ -864,8 +865,8 @@ public class ConcurrentLinkedDeque<E>
|
||||
|
||||
public E peekFirst() {
|
||||
for (Node<E> p = first(); p != null; p = succ(p)) {
|
||||
E item = p.item;
|
||||
if (item != null)
|
||||
final E item;
|
||||
if ((item = p.item) != null)
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
@ -873,8 +874,8 @@ public class ConcurrentLinkedDeque<E>
|
||||
|
||||
public E peekLast() {
|
||||
for (Node<E> p = last(); p != null; p = pred(p)) {
|
||||
E item = p.item;
|
||||
if (item != null)
|
||||
final E item;
|
||||
if ((item = p.item) != null)
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
@ -896,8 +897,9 @@ public class ConcurrentLinkedDeque<E>
|
||||
|
||||
public E pollFirst() {
|
||||
for (Node<E> p = first(); p != null; p = succ(p)) {
|
||||
E item = p.item;
|
||||
if (item != null && ITEM.compareAndSet(p, item, null)) {
|
||||
final E item;
|
||||
if ((item = p.item) != null
|
||||
&& ITEM.compareAndSet(p, item, null)) {
|
||||
unlink(p);
|
||||
return item;
|
||||
}
|
||||
@ -907,8 +909,9 @@ public class ConcurrentLinkedDeque<E>
|
||||
|
||||
public E pollLast() {
|
||||
for (Node<E> p = last(); p != null; p = pred(p)) {
|
||||
E item = p.item;
|
||||
if (item != null && ITEM.compareAndSet(p, item, null)) {
|
||||
final E item;
|
||||
if ((item = p.item) != null
|
||||
&& ITEM.compareAndSet(p, item, null)) {
|
||||
unlink(p);
|
||||
return item;
|
||||
}
|
||||
@ -993,9 +996,10 @@ public class ConcurrentLinkedDeque<E>
|
||||
public boolean removeFirstOccurrence(Object o) {
|
||||
Objects.requireNonNull(o);
|
||||
for (Node<E> p = first(); p != null; p = succ(p)) {
|
||||
E item = p.item;
|
||||
if (item != null && o.equals(item) &&
|
||||
ITEM.compareAndSet(p, item, null)) {
|
||||
final E item;
|
||||
if ((item = p.item) != null
|
||||
&& o.equals(item)
|
||||
&& ITEM.compareAndSet(p, item, null)) {
|
||||
unlink(p);
|
||||
return true;
|
||||
}
|
||||
@ -1018,9 +1022,10 @@ public class ConcurrentLinkedDeque<E>
|
||||
public boolean removeLastOccurrence(Object o) {
|
||||
Objects.requireNonNull(o);
|
||||
for (Node<E> p = last(); p != null; p = pred(p)) {
|
||||
E item = p.item;
|
||||
if (item != null && o.equals(item) &&
|
||||
ITEM.compareAndSet(p, item, null)) {
|
||||
final E item;
|
||||
if ((item = p.item) != null
|
||||
&& o.equals(item)
|
||||
&& ITEM.compareAndSet(p, item, null)) {
|
||||
unlink(p);
|
||||
return true;
|
||||
}
|
||||
@ -1039,8 +1044,8 @@ public class ConcurrentLinkedDeque<E>
|
||||
public boolean contains(Object o) {
|
||||
if (o != null) {
|
||||
for (Node<E> p = first(); p != null; p = succ(p)) {
|
||||
E item = p.item;
|
||||
if (item != null && o.equals(item))
|
||||
final E item;
|
||||
if ((item = p.item) != null && o.equals(item))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1181,8 +1186,8 @@ public class ConcurrentLinkedDeque<E>
|
||||
int charLength = 0;
|
||||
int size = 0;
|
||||
for (Node<E> p = first(); p != null;) {
|
||||
E item = p.item;
|
||||
if (item != null) {
|
||||
final E item;
|
||||
if ((item = p.item) != null) {
|
||||
if (a == null)
|
||||
a = new String[4];
|
||||
else if (size == a.length)
|
||||
@ -1207,8 +1212,8 @@ public class ConcurrentLinkedDeque<E>
|
||||
restartFromHead: for (;;) {
|
||||
int size = 0;
|
||||
for (Node<E> p = first(); p != null;) {
|
||||
E item = p.item;
|
||||
if (item != null) {
|
||||
final E item;
|
||||
if ((item = p.item) != null) {
|
||||
if (x == null)
|
||||
x = new Object[4];
|
||||
else if (size == x.length)
|
||||
@ -1360,8 +1365,8 @@ public class ConcurrentLinkedDeque<E>
|
||||
nextItem = null;
|
||||
break;
|
||||
}
|
||||
E item = p.item;
|
||||
if (item != null) {
|
||||
final E item;
|
||||
if ((item = p.item) != null) {
|
||||
nextNode = p;
|
||||
nextItem = item;
|
||||
break;
|
||||
@ -1391,36 +1396,33 @@ public class ConcurrentLinkedDeque<E>
|
||||
|
||||
/** Forward iterator */
|
||||
private class Itr extends AbstractItr {
|
||||
Itr() {} // prevent access constructor creation
|
||||
Node<E> startNode() { return first(); }
|
||||
Node<E> nextNode(Node<E> p) { return succ(p); }
|
||||
}
|
||||
|
||||
/** Descending iterator */
|
||||
private class DescendingItr extends AbstractItr {
|
||||
DescendingItr() {} // prevent access constructor creation
|
||||
Node<E> startNode() { return last(); }
|
||||
Node<E> nextNode(Node<E> p) { return pred(p); }
|
||||
}
|
||||
|
||||
/** A customized variant of Spliterators.IteratorSpliterator */
|
||||
static final class CLDSpliterator<E> implements Spliterator<E> {
|
||||
final class CLDSpliterator implements Spliterator<E> {
|
||||
static final int MAX_BATCH = 1 << 25; // max batch array size;
|
||||
final ConcurrentLinkedDeque<E> queue;
|
||||
Node<E> current; // current node; null until initialized
|
||||
int batch; // batch size for splits
|
||||
boolean exhausted; // true when no more nodes
|
||||
CLDSpliterator(ConcurrentLinkedDeque<E> queue) {
|
||||
this.queue = queue;
|
||||
}
|
||||
|
||||
public Spliterator<E> trySplit() {
|
||||
Node<E> p;
|
||||
final ConcurrentLinkedDeque<E> q = this.queue;
|
||||
int b = batch;
|
||||
int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
|
||||
if (!exhausted &&
|
||||
((p = current) != null || (p = q.first()) != null)) {
|
||||
((p = current) != null || (p = first()) != null)) {
|
||||
if (p.item == null && p == (p = p.next))
|
||||
current = p = q.first();
|
||||
current = p = first();
|
||||
if (p != null && p.next != null) {
|
||||
Object[] a = new Object[n];
|
||||
int i = 0;
|
||||
@ -1428,7 +1430,7 @@ public class ConcurrentLinkedDeque<E>
|
||||
if ((a[i] = p.item) != null)
|
||||
++i;
|
||||
if (p == (p = p.next))
|
||||
p = q.first();
|
||||
p = first();
|
||||
} while (p != null && i < n);
|
||||
if ((current = p) == null)
|
||||
exhausted = true;
|
||||
@ -1447,14 +1449,13 @@ public class ConcurrentLinkedDeque<E>
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
Node<E> p;
|
||||
if (action == null) throw new NullPointerException();
|
||||
final ConcurrentLinkedDeque<E> q = this.queue;
|
||||
if (!exhausted &&
|
||||
((p = current) != null || (p = q.first()) != null)) {
|
||||
((p = current) != null || (p = first()) != null)) {
|
||||
exhausted = true;
|
||||
do {
|
||||
E e = p.item;
|
||||
if (p == (p = p.next))
|
||||
p = q.first();
|
||||
p = first();
|
||||
if (e != null)
|
||||
action.accept(e);
|
||||
} while (p != null);
|
||||
@ -1464,14 +1465,13 @@ public class ConcurrentLinkedDeque<E>
|
||||
public boolean tryAdvance(Consumer<? super E> action) {
|
||||
Node<E> p;
|
||||
if (action == null) throw new NullPointerException();
|
||||
final ConcurrentLinkedDeque<E> q = this.queue;
|
||||
if (!exhausted &&
|
||||
((p = current) != null || (p = q.first()) != null)) {
|
||||
((p = current) != null || (p = first()) != null)) {
|
||||
E e;
|
||||
do {
|
||||
e = p.item;
|
||||
if (p == (p = p.next))
|
||||
p = q.first();
|
||||
p = first();
|
||||
} while (e == null && p != null);
|
||||
if ((current = p) == null)
|
||||
exhausted = true;
|
||||
@ -1508,7 +1508,7 @@ public class ConcurrentLinkedDeque<E>
|
||||
* @since 1.8
|
||||
*/
|
||||
public Spliterator<E> spliterator() {
|
||||
return new CLDSpliterator<E>(this);
|
||||
return new CLDSpliterator();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1527,8 +1527,8 @@ public class ConcurrentLinkedDeque<E>
|
||||
|
||||
// Write out all elements in the proper order.
|
||||
for (Node<E> p = first(); p != null; p = succ(p)) {
|
||||
E item = p.item;
|
||||
if (item != null)
|
||||
final E item;
|
||||
if ((item = p.item) != null)
|
||||
s.writeObject(item);
|
||||
}
|
||||
|
||||
@ -1563,6 +1563,57 @@ public class ConcurrentLinkedDeque<E>
|
||||
initHeadTail(h, t);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean removeIf(Predicate<? super E> filter) {
|
||||
Objects.requireNonNull(filter);
|
||||
return bulkRemove(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
return bulkRemove(e -> c.contains(e));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
return bulkRemove(e -> !c.contains(e));
|
||||
}
|
||||
|
||||
/** Implementation of bulk remove methods. */
|
||||
private boolean bulkRemove(Predicate<? super E> filter) {
|
||||
boolean removed = false;
|
||||
for (Node<E> p = first(), succ; p != null; p = succ) {
|
||||
succ = succ(p);
|
||||
final E item;
|
||||
if ((item = p.item) != null
|
||||
&& filter.test(item)
|
||||
&& ITEM.compareAndSet(p, item, null)) {
|
||||
unlink(p);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
E item;
|
||||
for (Node<E> p = first(); p != null; p = succ(p))
|
||||
if ((item = p.item) != null)
|
||||
action.accept(item);
|
||||
}
|
||||
|
||||
// VarHandle mechanics
|
||||
private static final VarHandle HEAD;
|
||||
private static final VarHandle TAIL;
|
||||
|
@ -47,6 +47,7 @@ import java.util.Queue;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* An unbounded thread-safe {@linkplain Queue queue} based on linked nodes.
|
||||
@ -112,7 +113,7 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
/*
|
||||
* This is a modification of the Michael & Scott algorithm,
|
||||
* adapted for a garbage-collected environment, with support for
|
||||
* interior node deletion (to support remove(Object)). For
|
||||
* interior node deletion (to support e.g. remove(Object)). For
|
||||
* explanation, read the paper.
|
||||
*
|
||||
* Note that like most non-blocking algorithms in this package,
|
||||
@ -160,12 +161,13 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
* it is possible for tail to lag behind head (why not)?
|
||||
*
|
||||
* CASing a Node's item reference to null atomically removes the
|
||||
* element from the queue. Iterators skip over Nodes with null
|
||||
* items. Prior implementations of this class had a race between
|
||||
* poll() and remove(Object) where the same element would appear
|
||||
* to be successfully removed by two concurrent operations. The
|
||||
* method remove(Object) also lazily unlinks deleted Nodes, but
|
||||
* this is merely an optimization.
|
||||
* element from the queue, leaving a "dead" node that should later
|
||||
* be unlinked (but unlinking is merely an optimization).
|
||||
* Interior element removal methods (other than Iterator.remove())
|
||||
* keep track of the predecessor node during traversal so that the
|
||||
* node can be CAS-unlinked. Some traversal methods try to unlink
|
||||
* any deleted nodes encountered during traversal. See comments
|
||||
* in bulkRemove.
|
||||
*
|
||||
* When constructing a Node (before enqueuing it) we avoid paying
|
||||
* for a volatile write to item. This allows the cost of enqueue
|
||||
@ -289,6 +291,21 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
return (p == next) ? head : next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to CAS pred.next (or head, if pred is null) from c to p.
|
||||
*/
|
||||
private boolean tryCasSuccessor(Node<E> pred, Node<E> c, Node<E> p) {
|
||||
// assert c.item == null;
|
||||
// assert c != p;
|
||||
if (pred != null)
|
||||
return NEXT.compareAndSet(pred, c, p);
|
||||
if (HEAD.compareAndSet(this, c, p)) {
|
||||
NEXT.setRelease(c, c);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the tail of this queue.
|
||||
* As the queue is unbounded, this method will never return {@code false}.
|
||||
@ -326,12 +343,11 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
}
|
||||
|
||||
public E poll() {
|
||||
restartFromHead:
|
||||
for (;;) {
|
||||
for (Node<E> h = head, p = h, q;;) {
|
||||
E item = p.item;
|
||||
|
||||
if (item != null && ITEM.compareAndSet(p, item, null)) {
|
||||
restartFromHead: for (;;) {
|
||||
for (Node<E> h = head, p = h, q;; p = q) {
|
||||
final E item;
|
||||
if ((item = p.item) != null
|
||||
&& ITEM.compareAndSet(p, item, null)) {
|
||||
// Successful CAS is the linearization point
|
||||
// for item to be removed from this queue.
|
||||
if (p != h) // hop two nodes at a time
|
||||
@ -344,25 +360,21 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
}
|
||||
else if (p == q)
|
||||
continue restartFromHead;
|
||||
else
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public E peek() {
|
||||
restartFromHead:
|
||||
for (;;) {
|
||||
for (Node<E> h = head, p = h, q;;) {
|
||||
E item = p.item;
|
||||
if (item != null || (q = p.next) == null) {
|
||||
restartFromHead: for (;;) {
|
||||
for (Node<E> h = head, p = h, q;; p = q) {
|
||||
final E item;
|
||||
if ((item = p.item) != null
|
||||
|| (q = p.next) == null) {
|
||||
updateHead(h, p);
|
||||
return item;
|
||||
}
|
||||
else if (p == q)
|
||||
continue restartFromHead;
|
||||
else
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -376,9 +388,8 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
* of losing a race to a concurrent poll().
|
||||
*/
|
||||
Node<E> first() {
|
||||
restartFromHead:
|
||||
for (;;) {
|
||||
for (Node<E> h = head, p = h, q;;) {
|
||||
restartFromHead: for (;;) {
|
||||
for (Node<E> h = head, p = h, q;; p = q) {
|
||||
boolean hasItem = (p.item != null);
|
||||
if (hasItem || (q = p.next) == null) {
|
||||
updateHead(h, p);
|
||||
@ -386,8 +397,6 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
}
|
||||
else if (p == q)
|
||||
continue restartFromHead;
|
||||
else
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -440,14 +449,24 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
* @return {@code true} if this queue contains the specified element
|
||||
*/
|
||||
public boolean contains(Object o) {
|
||||
if (o != null) {
|
||||
for (Node<E> p = first(); p != null; p = succ(p)) {
|
||||
E item = p.item;
|
||||
if (item != null && o.equals(item))
|
||||
if (o == null) return false;
|
||||
restartFromHead: for (;;) {
|
||||
for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
|
||||
final E item;
|
||||
if ((item = p.item) != null && o.equals(item))
|
||||
return true;
|
||||
if (c != p && tryCasSuccessor(pred, c, p))
|
||||
c = p;
|
||||
q = p.next;
|
||||
if (item != null || c != p) {
|
||||
pred = p;
|
||||
c = q;
|
||||
}
|
||||
else if (p == q)
|
||||
continue restartFromHead;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -462,27 +481,28 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
* @return {@code true} if this queue changed as a result of the call
|
||||
*/
|
||||
public boolean remove(Object o) {
|
||||
if (o != null) {
|
||||
Node<E> next, pred = null;
|
||||
for (Node<E> p = first(); p != null; pred = p, p = next) {
|
||||
boolean removed = false;
|
||||
E item = p.item;
|
||||
if (item != null) {
|
||||
if (!o.equals(item)) {
|
||||
next = succ(p);
|
||||
continue;
|
||||
}
|
||||
removed = ITEM.compareAndSet(p, item, null);
|
||||
}
|
||||
|
||||
next = succ(p);
|
||||
if (pred != null && next != null) // unlink
|
||||
NEXT.weakCompareAndSet(pred, p, next);
|
||||
if (o == null) return false;
|
||||
restartFromHead: for (;;) {
|
||||
for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
|
||||
final E item;
|
||||
final boolean removed =
|
||||
(item = p.item) != null
|
||||
&& o.equals(item)
|
||||
&& ITEM.compareAndSet(p, item, null);
|
||||
if (c != p && tryCasSuccessor(pred, c, p))
|
||||
c = p;
|
||||
if (removed)
|
||||
return true;
|
||||
q = p.next;
|
||||
if (item != null || c != p) {
|
||||
pred = p;
|
||||
c = q;
|
||||
}
|
||||
else if (p == q)
|
||||
continue restartFromHead;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -553,8 +573,8 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
int charLength = 0;
|
||||
int size = 0;
|
||||
for (Node<E> p = first(); p != null;) {
|
||||
E item = p.item;
|
||||
if (item != null) {
|
||||
final E item;
|
||||
if ((item = p.item) != null) {
|
||||
if (a == null)
|
||||
a = new String[4];
|
||||
else if (size == a.length)
|
||||
@ -579,8 +599,8 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
restartFromHead: for (;;) {
|
||||
int size = 0;
|
||||
for (Node<E> p = first(); p != null;) {
|
||||
E item = p.item;
|
||||
if (item != null) {
|
||||
final E item;
|
||||
if ((item = p.item) != null) {
|
||||
if (x == null)
|
||||
x = new Object[4];
|
||||
else if (size == x.length)
|
||||
@ -697,7 +717,7 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
restartFromHead: for (;;) {
|
||||
Node<E> h, p, q;
|
||||
for (p = h = head;; p = q) {
|
||||
E item;
|
||||
final E item;
|
||||
if ((item = p.item) != null) {
|
||||
nextNode = p;
|
||||
nextItem = item;
|
||||
@ -762,8 +782,8 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
|
||||
// Write out all elements in the proper order.
|
||||
for (Node<E> p = first(); p != null; p = succ(p)) {
|
||||
Object item = p.item;
|
||||
if (item != null)
|
||||
final E item;
|
||||
if ((item = p.item) != null)
|
||||
s.writeObject(item);
|
||||
}
|
||||
|
||||
@ -801,23 +821,18 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
}
|
||||
|
||||
/** A customized variant of Spliterators.IteratorSpliterator */
|
||||
static final class CLQSpliterator<E> implements Spliterator<E> {
|
||||
final class CLQSpliterator implements Spliterator<E> {
|
||||
static final int MAX_BATCH = 1 << 25; // max batch array size;
|
||||
final ConcurrentLinkedQueue<E> queue;
|
||||
Node<E> current; // current node; null until initialized
|
||||
int batch; // batch size for splits
|
||||
boolean exhausted; // true when no more nodes
|
||||
CLQSpliterator(ConcurrentLinkedQueue<E> queue) {
|
||||
this.queue = queue;
|
||||
}
|
||||
|
||||
public Spliterator<E> trySplit() {
|
||||
Node<E> p;
|
||||
final ConcurrentLinkedQueue<E> q = this.queue;
|
||||
int b = batch;
|
||||
int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
|
||||
if (!exhausted &&
|
||||
((p = current) != null || (p = q.first()) != null) &&
|
||||
((p = current) != null || (p = first()) != null) &&
|
||||
p.next != null) {
|
||||
Object[] a = new Object[n];
|
||||
int i = 0;
|
||||
@ -825,7 +840,7 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
if ((a[i] = p.item) != null)
|
||||
++i;
|
||||
if (p == (p = p.next))
|
||||
p = q.first();
|
||||
p = first();
|
||||
} while (p != null && i < n);
|
||||
if ((current = p) == null)
|
||||
exhausted = true;
|
||||
@ -843,14 +858,13 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
Node<E> p;
|
||||
if (action == null) throw new NullPointerException();
|
||||
final ConcurrentLinkedQueue<E> q = this.queue;
|
||||
if (!exhausted &&
|
||||
((p = current) != null || (p = q.first()) != null)) {
|
||||
((p = current) != null || (p = first()) != null)) {
|
||||
exhausted = true;
|
||||
do {
|
||||
E e = p.item;
|
||||
if (p == (p = p.next))
|
||||
p = q.first();
|
||||
p = first();
|
||||
if (e != null)
|
||||
action.accept(e);
|
||||
} while (p != null);
|
||||
@ -860,14 +874,13 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
public boolean tryAdvance(Consumer<? super E> action) {
|
||||
Node<E> p;
|
||||
if (action == null) throw new NullPointerException();
|
||||
final ConcurrentLinkedQueue<E> q = this.queue;
|
||||
if (!exhausted &&
|
||||
((p = current) != null || (p = q.first()) != null)) {
|
||||
((p = current) != null || (p = first()) != null)) {
|
||||
E e;
|
||||
do {
|
||||
e = p.item;
|
||||
if (p == (p = p.next))
|
||||
p = q.first();
|
||||
p = first();
|
||||
} while (e == null && p != null);
|
||||
if ((current = p) == null)
|
||||
exhausted = true;
|
||||
@ -905,7 +918,100 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
*/
|
||||
@Override
|
||||
public Spliterator<E> spliterator() {
|
||||
return new CLQSpliterator<E>(this);
|
||||
return new CLQSpliterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean removeIf(Predicate<? super E> filter) {
|
||||
Objects.requireNonNull(filter);
|
||||
return bulkRemove(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
return bulkRemove(e -> c.contains(e));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
return bulkRemove(e -> !c.contains(e));
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
bulkRemove(e -> true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tolerate this many consecutive dead nodes before CAS-collapsing.
|
||||
* Amortized cost of clear() is (1 + 1/MAX_HOPS) CASes per element.
|
||||
*/
|
||||
private static final int MAX_HOPS = 8;
|
||||
|
||||
/** Implementation of bulk remove methods. */
|
||||
private boolean bulkRemove(Predicate<? super E> filter) {
|
||||
boolean removed = false;
|
||||
restartFromHead: for (;;) {
|
||||
int hops = MAX_HOPS;
|
||||
// c will be CASed to collapse intervening dead nodes between
|
||||
// pred (or head if null) and p.
|
||||
for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
|
||||
final E item; boolean pAlive;
|
||||
if (pAlive = ((item = p.item) != null)) {
|
||||
if (filter.test(item)) {
|
||||
if (ITEM.compareAndSet(p, item, null))
|
||||
removed = true;
|
||||
pAlive = false;
|
||||
}
|
||||
}
|
||||
if ((q = p.next) == null || pAlive || --hops == 0) {
|
||||
// p might already be self-linked here, but if so:
|
||||
// - CASing head will surely fail
|
||||
// - CASing pred's next will be useless but harmless.
|
||||
if (c != p && tryCasSuccessor(pred, c, p))
|
||||
c = p;
|
||||
// if c != p, CAS failed, so abandon old pred
|
||||
if (pAlive || c != p) {
|
||||
hops = MAX_HOPS;
|
||||
pred = p;
|
||||
c = q;
|
||||
}
|
||||
} else if (p == q)
|
||||
continue restartFromHead;
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
restartFromHead: for (;;) {
|
||||
for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
|
||||
final E item;
|
||||
if ((item = p.item) != null)
|
||||
action.accept(item);
|
||||
if (c != p && tryCasSuccessor(pred, c, p))
|
||||
c = p;
|
||||
q = p.next;
|
||||
if (item != null || c != p) {
|
||||
pred = p;
|
||||
c = q;
|
||||
}
|
||||
else if (p == q)
|
||||
continue restartFromHead;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// VarHandle mechanics
|
||||
|
@ -793,6 +793,9 @@ public class CopyOnWriteArrayList<E>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
if (action == null) throw new NullPointerException();
|
||||
for (Object x : getArray()) {
|
||||
@ -801,6 +804,9 @@ public class CopyOnWriteArrayList<E>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean removeIf(Predicate<? super E> filter) {
|
||||
if (filter == null) throw new NullPointerException();
|
||||
return bulkRemove(filter);
|
||||
|
@ -411,10 +411,16 @@ public class CopyOnWriteArraySet<E> extends AbstractSet<E>
|
||||
&& compareSets(al.getArray(), (Set<?>) o) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean removeIf(Predicate<? super E> filter) {
|
||||
return al.removeIf(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
al.forEach(action);
|
||||
}
|
||||
|
@ -149,7 +149,8 @@ public class CyclicBarrier {
|
||||
* but no subsequent reset.
|
||||
*/
|
||||
private static class Generation {
|
||||
boolean broken; // initially false
|
||||
Generation() {} // prevent access constructor creation
|
||||
boolean broken; // initially false
|
||||
}
|
||||
|
||||
/** The lock for guarding barrier entry */
|
||||
|
@ -547,8 +547,7 @@ public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
|
||||
public E next() {
|
||||
if (cursor >= array.length)
|
||||
throw new NoSuchElementException();
|
||||
lastRet = cursor;
|
||||
return (E)array[cursor++];
|
||||
return (E)array[lastRet = cursor++];
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
|
@ -39,6 +39,7 @@ import java.util.AbstractQueue;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
@ -740,8 +741,7 @@ public class LinkedBlockingDeque<E>
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
public int drainTo(Collection<? super E> c, int maxElements) {
|
||||
if (c == null)
|
||||
throw new NullPointerException();
|
||||
Objects.requireNonNull(c);
|
||||
if (c == this)
|
||||
throw new IllegalArgumentException();
|
||||
if (maxElements <= 0)
|
||||
@ -985,6 +985,16 @@ public class LinkedBlockingDeque<E>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for any element traversal that is not entirely under lock.
|
||||
* Such traversals must handle both:
|
||||
* - dequeued nodes (p.next == p)
|
||||
* - (possibly multiple) interior removed nodes (p.item == null)
|
||||
*/
|
||||
Node<E> succ(Node<E> p) {
|
||||
return (p == (p = p.next)) ? first : p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this deque in proper sequence.
|
||||
* The elements will be returned in order from first (head) to last (tail).
|
||||
@ -1024,8 +1034,8 @@ public class LinkedBlockingDeque<E>
|
||||
/**
|
||||
* nextItem holds on to item fields because once we claim that
|
||||
* an element exists in hasNext(), we must return item read
|
||||
* under lock (in advance()) even if it was in the process of
|
||||
* being removed when hasNext() was called.
|
||||
* under lock even if it was in the process of being removed
|
||||
* when hasNext() was called.
|
||||
*/
|
||||
E nextItem;
|
||||
|
||||
@ -1038,48 +1048,17 @@ public class LinkedBlockingDeque<E>
|
||||
abstract Node<E> firstNode();
|
||||
abstract Node<E> nextNode(Node<E> n);
|
||||
|
||||
private Node<E> succ(Node<E> p) {
|
||||
return (p == (p = nextNode(p))) ? firstNode() : p;
|
||||
}
|
||||
|
||||
AbstractItr() {
|
||||
// set to initial position
|
||||
final ReentrantLock lock = LinkedBlockingDeque.this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
next = firstNode();
|
||||
nextItem = (next == null) ? null : next.item;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the successor node of the given non-null, but
|
||||
* possibly previously deleted, node.
|
||||
*/
|
||||
private Node<E> succ(Node<E> n) {
|
||||
// Chains of deleted nodes ending in null or self-links
|
||||
// are possible if multiple interior nodes are removed.
|
||||
for (;;) {
|
||||
Node<E> s = nextNode(n);
|
||||
if (s == null)
|
||||
return null;
|
||||
else if (s.item != null)
|
||||
return s;
|
||||
else if (s == n)
|
||||
return firstNode();
|
||||
else
|
||||
n = s;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances next.
|
||||
*/
|
||||
void advance() {
|
||||
final ReentrantLock lock = LinkedBlockingDeque.this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
// assert next != null;
|
||||
next = succ(next);
|
||||
nextItem = (next == null) ? null : next.item;
|
||||
if ((next = firstNode()) != null)
|
||||
nextItem = next.item;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
@ -1090,14 +1069,65 @@ public class LinkedBlockingDeque<E>
|
||||
}
|
||||
|
||||
public E next() {
|
||||
if (next == null)
|
||||
Node<E> p;
|
||||
if ((p = next) == null)
|
||||
throw new NoSuchElementException();
|
||||
lastRet = next;
|
||||
lastRet = p;
|
||||
E x = nextItem;
|
||||
advance();
|
||||
final ReentrantLock lock = LinkedBlockingDeque.this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
E e = null;
|
||||
for (p = nextNode(p); p != null && (e = p.item) == null; )
|
||||
p = succ(p);
|
||||
next = p;
|
||||
nextItem = e;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
// A variant of forEachFrom
|
||||
Objects.requireNonNull(action);
|
||||
Node<E> p;
|
||||
if ((p = next) == null) return;
|
||||
lastRet = p;
|
||||
next = null;
|
||||
final ReentrantLock lock = LinkedBlockingDeque.this.lock;
|
||||
final int batchSize = 32;
|
||||
Object[] es = null;
|
||||
int n, len = 1;
|
||||
do {
|
||||
lock.lock();
|
||||
try {
|
||||
if (es == null) {
|
||||
p = nextNode(p);
|
||||
for (Node<E> q = p; q != null; q = succ(q))
|
||||
if (q.item != null && ++len == batchSize)
|
||||
break;
|
||||
es = new Object[len];
|
||||
es[0] = nextItem;
|
||||
nextItem = null;
|
||||
n = 1;
|
||||
} else
|
||||
n = 0;
|
||||
for (; p != null && n < len; p = succ(p))
|
||||
if ((es[n] = p.item) != null) {
|
||||
lastRet = p;
|
||||
n++;
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
@SuppressWarnings("unchecked") E e = (E) es[i];
|
||||
action.accept(e);
|
||||
}
|
||||
} while (n > 0 && p != null);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
Node<E> n = lastRet;
|
||||
if (n == null)
|
||||
@ -1116,25 +1146,30 @@ public class LinkedBlockingDeque<E>
|
||||
|
||||
/** Forward iterator */
|
||||
private class Itr extends AbstractItr {
|
||||
Itr() {} // prevent access constructor creation
|
||||
Node<E> firstNode() { return first; }
|
||||
Node<E> nextNode(Node<E> n) { return n.next; }
|
||||
}
|
||||
|
||||
/** Descending iterator */
|
||||
private class DescendingItr extends AbstractItr {
|
||||
DescendingItr() {} // prevent access constructor creation
|
||||
Node<E> firstNode() { return last; }
|
||||
Node<E> nextNode(Node<E> n) { return n.prev; }
|
||||
}
|
||||
|
||||
/** A customized variant of Spliterators.IteratorSpliterator */
|
||||
/**
|
||||
* A customized variant of Spliterators.IteratorSpliterator.
|
||||
* Keep this class in sync with (very similar) LBQSpliterator.
|
||||
*/
|
||||
private final class LBDSpliterator implements Spliterator<E> {
|
||||
static final int MAX_BATCH = 1 << 25; // max batch array size;
|
||||
Node<E> current; // current node; null until initialized
|
||||
int batch; // batch size for splits
|
||||
boolean exhausted; // true when no more nodes
|
||||
long est; // size estimate
|
||||
long est = size(); // size estimate
|
||||
|
||||
LBDSpliterator() { est = size(); }
|
||||
LBDSpliterator() {}
|
||||
|
||||
public long estimateSize() { return est; }
|
||||
|
||||
@ -1143,8 +1178,7 @@ public class LinkedBlockingDeque<E>
|
||||
int b = batch;
|
||||
int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
|
||||
if (!exhausted &&
|
||||
(((h = current) != null && h != h.next)
|
||||
|| (h = first) != null)
|
||||
((h = current) != null || (h = first) != null)
|
||||
&& h.next != null) {
|
||||
Object[] a = new Object[n];
|
||||
final ReentrantLock lock = LinkedBlockingDeque.this.lock;
|
||||
@ -1152,10 +1186,10 @@ public class LinkedBlockingDeque<E>
|
||||
Node<E> p = current;
|
||||
lock.lock();
|
||||
try {
|
||||
if (((p != null && p != p.next) || (p = first) != null)
|
||||
&& p.item != null)
|
||||
for (; p != null && i < n; p = p.next)
|
||||
a[i++] = p.item;
|
||||
if (p != null || (p = first) != null)
|
||||
for (; p != null && i < n; p = succ(p))
|
||||
if ((a[i] = p.item) != null)
|
||||
i++;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
@ -1176,51 +1210,39 @@ public class LinkedBlockingDeque<E>
|
||||
return null;
|
||||
}
|
||||
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
if (action == null) throw new NullPointerException();
|
||||
if (exhausted)
|
||||
return;
|
||||
exhausted = true;
|
||||
final ReentrantLock lock = LinkedBlockingDeque.this.lock;
|
||||
Node<E> p = current;
|
||||
current = null;
|
||||
do {
|
||||
public boolean tryAdvance(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
if (!exhausted) {
|
||||
E e = null;
|
||||
final ReentrantLock lock = LinkedBlockingDeque.this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if ((p != null && p != p.next) || (p = first) != null) {
|
||||
e = p.item;
|
||||
p = p.next;
|
||||
}
|
||||
Node<E> p;
|
||||
if ((p = current) != null || (p = first) != null)
|
||||
do {
|
||||
e = p.item;
|
||||
p = succ(p);
|
||||
} while (e == null && p != null);
|
||||
exhausted = ((current = p) == null);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
if (e != null)
|
||||
if (e != null) {
|
||||
action.accept(e);
|
||||
} while (p != null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean tryAdvance(Consumer<? super E> action) {
|
||||
if (action == null) throw new NullPointerException();
|
||||
if (exhausted)
|
||||
return false;
|
||||
final ReentrantLock lock = LinkedBlockingDeque.this.lock;
|
||||
Node<E> p = current;
|
||||
E e = null;
|
||||
lock.lock();
|
||||
try {
|
||||
if ((p != null && p != p.next) || (p = first) != null) {
|
||||
e = p.item;
|
||||
p = p.next;
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
if (!exhausted) {
|
||||
exhausted = true;
|
||||
Node<E> p = current;
|
||||
current = null;
|
||||
forEachFrom(action, p);
|
||||
}
|
||||
exhausted = ((current = p) == null);
|
||||
if (e == null)
|
||||
return false;
|
||||
action.accept(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
public int characteristics() {
|
||||
@ -1250,6 +1272,48 @@ public class LinkedBlockingDeque<E>
|
||||
return new LBDSpliterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
forEachFrom(action, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs action on each element found during a traversal starting at p.
|
||||
* If p is null, traversal starts at head.
|
||||
*/
|
||||
void forEachFrom(Consumer<? super E> action, Node<E> p) {
|
||||
// Extract batches of elements while holding the lock; then
|
||||
// run the action on the elements while not
|
||||
final ReentrantLock lock = this.lock;
|
||||
final int batchSize = 32; // max number of elements per batch
|
||||
Object[] es = null; // container for batch of elements
|
||||
int n, len = 0;
|
||||
do {
|
||||
lock.lock();
|
||||
try {
|
||||
if (es == null) {
|
||||
if (p == null) p = first;
|
||||
for (Node<E> q = p; q != null; q = succ(q))
|
||||
if (q.item != null && ++len == batchSize)
|
||||
break;
|
||||
es = new Object[len];
|
||||
}
|
||||
for (n = 0; p != null && n < len; p = succ(p))
|
||||
if ((es[n] = p.item) != null)
|
||||
n++;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
@SuppressWarnings("unchecked") E e = (E) es[i];
|
||||
action.accept(e);
|
||||
}
|
||||
} while (n > 0 && p != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this deque to a stream (that is, serializes it).
|
||||
*
|
||||
@ -1290,8 +1354,7 @@ public class LinkedBlockingDeque<E>
|
||||
last = null;
|
||||
// Read in all elements and place in queue
|
||||
for (;;) {
|
||||
@SuppressWarnings("unchecked")
|
||||
E item = (E)s.readObject();
|
||||
@SuppressWarnings("unchecked") E item = (E)s.readObject();
|
||||
if (item == null)
|
||||
break;
|
||||
add(item);
|
||||
|
@ -39,6 +39,7 @@ import java.util.AbstractQueue;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@ -234,14 +235,6 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
||||
putLock.unlock();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Tells whether both locks are held by current thread.
|
||||
// */
|
||||
// boolean isFullyLocked() {
|
||||
// return (putLock.isHeldByCurrentThread() &&
|
||||
// takeLock.isHeldByCurrentThread());
|
||||
// }
|
||||
|
||||
/**
|
||||
* Creates a {@code LinkedBlockingQueue} with a capacity of
|
||||
* {@link Integer#MAX_VALUE}.
|
||||
@ -517,7 +510,8 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
||||
* Unlinks interior Node p with predecessor trail.
|
||||
*/
|
||||
void unlink(Node<E> p, Node<E> trail) {
|
||||
// assert isFullyLocked();
|
||||
// assert putLock.isHeldByCurrentThread();
|
||||
// assert takeLock.isHeldByCurrentThread();
|
||||
// p.next is not changed, to allow iterators that are
|
||||
// traversing p to maintain their weak-consistency guarantee.
|
||||
p.item = null;
|
||||
@ -701,8 +695,7 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
public int drainTo(Collection<? super E> c, int maxElements) {
|
||||
if (c == null)
|
||||
throw new NullPointerException();
|
||||
Objects.requireNonNull(c);
|
||||
if (c == this)
|
||||
throw new IllegalArgumentException();
|
||||
if (maxElements <= 0)
|
||||
@ -740,6 +733,16 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for any element traversal that is not entirely under lock.
|
||||
* Such traversals must handle both:
|
||||
* - dequeued nodes (p.next == p)
|
||||
* - (possibly multiple) interior removed nodes (p.item == null)
|
||||
*/
|
||||
Node<E> succ(Node<E> p) {
|
||||
return (p == (p = p.next)) ? head.next : p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this queue in proper sequence.
|
||||
* The elements will be returned in order from first (head) to last (tail).
|
||||
@ -760,48 +763,80 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
||||
* still have it to return even if lost race with a take etc.
|
||||
*/
|
||||
|
||||
private Node<E> current;
|
||||
private Node<E> next;
|
||||
private E nextItem;
|
||||
private Node<E> lastRet;
|
||||
private E currentElement;
|
||||
|
||||
Itr() {
|
||||
fullyLock();
|
||||
try {
|
||||
current = head.next;
|
||||
if (current != null)
|
||||
currentElement = current.item;
|
||||
if ((next = head.next) != null)
|
||||
nextItem = next.item;
|
||||
} finally {
|
||||
fullyUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return current != null;
|
||||
return next != null;
|
||||
}
|
||||
|
||||
public E next() {
|
||||
Node<E> p;
|
||||
if ((p = next) == null)
|
||||
throw new NoSuchElementException();
|
||||
lastRet = p;
|
||||
E x = nextItem;
|
||||
fullyLock();
|
||||
try {
|
||||
if (current == null)
|
||||
throw new NoSuchElementException();
|
||||
lastRet = current;
|
||||
E item = null;
|
||||
// Unlike other traversal methods, iterators must handle both:
|
||||
// - dequeued nodes (p.next == p)
|
||||
// - (possibly multiple) interior removed nodes (p.item == null)
|
||||
for (Node<E> p = current, q;; p = q) {
|
||||
if ((q = p.next) == p)
|
||||
q = head.next;
|
||||
if (q == null || (item = q.item) != null) {
|
||||
current = q;
|
||||
E x = currentElement;
|
||||
currentElement = item;
|
||||
return x;
|
||||
}
|
||||
}
|
||||
E e = null;
|
||||
for (p = p.next; p != null && (e = p.item) == null; )
|
||||
p = succ(p);
|
||||
next = p;
|
||||
nextItem = e;
|
||||
} finally {
|
||||
fullyUnlock();
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
// A variant of forEachFrom
|
||||
Objects.requireNonNull(action);
|
||||
Node<E> p;
|
||||
if ((p = next) == null) return;
|
||||
lastRet = p;
|
||||
next = null;
|
||||
final int batchSize = 32;
|
||||
Object[] es = null;
|
||||
int n, len = 1;
|
||||
do {
|
||||
fullyLock();
|
||||
try {
|
||||
if (es == null) {
|
||||
p = p.next;
|
||||
for (Node<E> q = p; q != null; q = succ(q))
|
||||
if (q.item != null && ++len == batchSize)
|
||||
break;
|
||||
es = new Object[len];
|
||||
es[0] = nextItem;
|
||||
nextItem = null;
|
||||
n = 1;
|
||||
} else
|
||||
n = 0;
|
||||
for (; p != null && n < len; p = succ(p))
|
||||
if ((es[n] = p.item) != null) {
|
||||
lastRet = p;
|
||||
n++;
|
||||
}
|
||||
} finally {
|
||||
fullyUnlock();
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
@SuppressWarnings("unchecked") E e = (E) es[i];
|
||||
action.accept(e);
|
||||
}
|
||||
} while (n > 0 && p != null);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
@ -825,42 +860,39 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
||||
}
|
||||
}
|
||||
|
||||
/** A customized variant of Spliterators.IteratorSpliterator */
|
||||
static final class LBQSpliterator<E> implements Spliterator<E> {
|
||||
/**
|
||||
* A customized variant of Spliterators.IteratorSpliterator.
|
||||
* Keep this class in sync with (very similar) LBDSpliterator.
|
||||
*/
|
||||
private final class LBQSpliterator implements Spliterator<E> {
|
||||
static final int MAX_BATCH = 1 << 25; // max batch array size;
|
||||
final LinkedBlockingQueue<E> queue;
|
||||
Node<E> current; // current node; null until initialized
|
||||
int batch; // batch size for splits
|
||||
boolean exhausted; // true when no more nodes
|
||||
long est; // size estimate
|
||||
LBQSpliterator(LinkedBlockingQueue<E> queue) {
|
||||
this.queue = queue;
|
||||
this.est = queue.size();
|
||||
}
|
||||
long est = size(); // size estimate
|
||||
|
||||
LBQSpliterator() {}
|
||||
|
||||
public long estimateSize() { return est; }
|
||||
|
||||
public Spliterator<E> trySplit() {
|
||||
Node<E> h;
|
||||
final LinkedBlockingQueue<E> q = this.queue;
|
||||
int b = batch;
|
||||
int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
|
||||
if (!exhausted &&
|
||||
((h = current) != null || (h = q.head.next) != null) &&
|
||||
h.next != null) {
|
||||
((h = current) != null || (h = head.next) != null)
|
||||
&& h.next != null) {
|
||||
Object[] a = new Object[n];
|
||||
int i = 0;
|
||||
Node<E> p = current;
|
||||
q.fullyLock();
|
||||
fullyLock();
|
||||
try {
|
||||
if (p != null || (p = q.head.next) != null) {
|
||||
do {
|
||||
if (p != null || (p = head.next) != null)
|
||||
for (; p != null && i < n; p = succ(p))
|
||||
if ((a[i] = p.item) != null)
|
||||
++i;
|
||||
} while ((p = p.next) != null && i < n);
|
||||
}
|
||||
i++;
|
||||
} finally {
|
||||
q.fullyUnlock();
|
||||
fullyUnlock();
|
||||
}
|
||||
if ((current = p) == null) {
|
||||
est = 0L;
|
||||
@ -879,53 +911,22 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
||||
return null;
|
||||
}
|
||||
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
if (action == null) throw new NullPointerException();
|
||||
final LinkedBlockingQueue<E> q = this.queue;
|
||||
if (!exhausted) {
|
||||
exhausted = true;
|
||||
Node<E> p = current;
|
||||
do {
|
||||
E e = null;
|
||||
q.fullyLock();
|
||||
try {
|
||||
if (p == null)
|
||||
p = q.head.next;
|
||||
while (p != null) {
|
||||
e = p.item;
|
||||
p = p.next;
|
||||
if (e != null)
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
q.fullyUnlock();
|
||||
}
|
||||
if (e != null)
|
||||
action.accept(e);
|
||||
} while (p != null);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean tryAdvance(Consumer<? super E> action) {
|
||||
if (action == null) throw new NullPointerException();
|
||||
final LinkedBlockingQueue<E> q = this.queue;
|
||||
Objects.requireNonNull(action);
|
||||
if (!exhausted) {
|
||||
E e = null;
|
||||
q.fullyLock();
|
||||
fullyLock();
|
||||
try {
|
||||
if (current == null)
|
||||
current = q.head.next;
|
||||
while (current != null) {
|
||||
e = current.item;
|
||||
current = current.next;
|
||||
if (e != null)
|
||||
break;
|
||||
}
|
||||
Node<E> p;
|
||||
if ((p = current) != null || (p = head.next) != null)
|
||||
do {
|
||||
e = p.item;
|
||||
p = succ(p);
|
||||
} while (e == null && p != null);
|
||||
exhausted = ((current = p) == null);
|
||||
} finally {
|
||||
q.fullyUnlock();
|
||||
fullyUnlock();
|
||||
}
|
||||
if (current == null)
|
||||
exhausted = true;
|
||||
if (e != null) {
|
||||
action.accept(e);
|
||||
return true;
|
||||
@ -934,9 +935,20 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
||||
return false;
|
||||
}
|
||||
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
if (!exhausted) {
|
||||
exhausted = true;
|
||||
Node<E> p = current;
|
||||
current = null;
|
||||
forEachFrom(action, p);
|
||||
}
|
||||
}
|
||||
|
||||
public int characteristics() {
|
||||
return Spliterator.ORDERED | Spliterator.NONNULL |
|
||||
Spliterator.CONCURRENT;
|
||||
return (Spliterator.ORDERED |
|
||||
Spliterator.NONNULL |
|
||||
Spliterator.CONCURRENT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -957,7 +969,48 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
|
||||
* @since 1.8
|
||||
*/
|
||||
public Spliterator<E> spliterator() {
|
||||
return new LBQSpliterator<E>(this);
|
||||
return new LBQSpliterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
forEachFrom(action, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs action on each element found during a traversal starting at p.
|
||||
* If p is null, traversal starts at head.
|
||||
*/
|
||||
void forEachFrom(Consumer<? super E> action, Node<E> p) {
|
||||
// Extract batches of elements while holding the lock; then
|
||||
// run the action on the elements while not
|
||||
final int batchSize = 32; // max number of elements per batch
|
||||
Object[] es = null; // container for batch of elements
|
||||
int n, len = 0;
|
||||
do {
|
||||
fullyLock();
|
||||
try {
|
||||
if (es == null) {
|
||||
if (p == null) p = head.next;
|
||||
for (Node<E> q = p; q != null; q = succ(q))
|
||||
if (q.item != null && ++len == batchSize)
|
||||
break;
|
||||
es = new Object[len];
|
||||
}
|
||||
for (n = 0; p != null && n < len; p = succ(p))
|
||||
if ((es[n] = p.item) != null)
|
||||
n++;
|
||||
} finally {
|
||||
fullyUnlock();
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
@SuppressWarnings("unchecked") E e = (E) es[i];
|
||||
action.accept(e);
|
||||
}
|
||||
} while (n > 0 && p != null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -179,7 +179,7 @@ import java.util.concurrent.locks.LockSupport;
|
||||
* void startTasks(List<Runnable> tasks, int iterations) {
|
||||
* Phaser phaser = new Phaser() {
|
||||
* protected boolean onAdvance(int phase, int registeredParties) {
|
||||
* return phase >= iterations || registeredParties == 0;
|
||||
* return phase >= iterations - 1 || registeredParties == 0;
|
||||
* }
|
||||
* };
|
||||
* phaser.register();
|
||||
|
@ -345,11 +345,9 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E>
|
||||
* promoting x up the tree until it is greater than or equal to
|
||||
* its parent, or is the root.
|
||||
*
|
||||
* To simplify and speed up coercions and comparisons. the
|
||||
* To simplify and speed up coercions and comparisons, the
|
||||
* Comparable and Comparator versions are separated into different
|
||||
* methods that are otherwise identical. (Similarly for siftDown.)
|
||||
* These methods are static, with heap state as arguments, to
|
||||
* simplify use in light of possible comparator exceptions.
|
||||
*
|
||||
* @param k the position to fill
|
||||
* @param x the item to insert
|
||||
@ -435,6 +433,7 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E>
|
||||
/**
|
||||
* Establishes the heap invariant (described above) in the entire tree,
|
||||
* assuming nothing about the order of the elements prior to the call.
|
||||
* This classic algorithm due to Floyd (1964) is known to be O(size).
|
||||
*/
|
||||
private void heapify() {
|
||||
Object[] array = queue;
|
||||
@ -878,8 +877,7 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E>
|
||||
public E next() {
|
||||
if (cursor >= array.length)
|
||||
throw new NoSuchElementException();
|
||||
lastRet = cursor;
|
||||
return (E)array[cursor++];
|
||||
return (E)array[lastRet = cursor++];
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
@ -936,15 +934,12 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E>
|
||||
/**
|
||||
* Immutable snapshot spliterator that binds to elements "late".
|
||||
*/
|
||||
static final class PBQSpliterator<E> implements Spliterator<E> {
|
||||
final PriorityBlockingQueue<E> queue;
|
||||
final class PBQSpliterator implements Spliterator<E> {
|
||||
Object[] array;
|
||||
int index;
|
||||
int fence;
|
||||
|
||||
PBQSpliterator(PriorityBlockingQueue<E> queue, Object[] array,
|
||||
int index, int fence) {
|
||||
this.queue = queue;
|
||||
PBQSpliterator(Object[] array, int index, int fence) {
|
||||
this.array = array;
|
||||
this.index = index;
|
||||
this.fence = fence;
|
||||
@ -953,14 +948,14 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E>
|
||||
final int getFence() {
|
||||
int hi;
|
||||
if ((hi = fence) < 0)
|
||||
hi = fence = (array = queue.toArray()).length;
|
||||
hi = fence = (array = toArray()).length;
|
||||
return hi;
|
||||
}
|
||||
|
||||
public PBQSpliterator<E> trySplit() {
|
||||
public PBQSpliterator trySplit() {
|
||||
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
|
||||
return (lo >= mid) ? null :
|
||||
new PBQSpliterator<E>(queue, array, lo, index = mid);
|
||||
new PBQSpliterator(array, lo, index = mid);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -969,7 +964,7 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E>
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
if ((a = array) == null)
|
||||
fence = (a = queue.toArray()).length;
|
||||
fence = (a = toArray()).length;
|
||||
if ((hi = fence) <= a.length &&
|
||||
(i = index) >= 0 && i < (index = hi)) {
|
||||
do { action.accept((E)a[i]); } while (++i < hi);
|
||||
@ -987,7 +982,7 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E>
|
||||
return false;
|
||||
}
|
||||
|
||||
public long estimateSize() { return (long)(getFence() - index); }
|
||||
public long estimateSize() { return getFence() - index; }
|
||||
|
||||
public int characteristics() {
|
||||
return Spliterator.NONNULL | Spliterator.SIZED | Spliterator.SUBSIZED;
|
||||
@ -1012,7 +1007,7 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E>
|
||||
* @since 1.8
|
||||
*/
|
||||
public Spliterator<E> spliterator() {
|
||||
return new PBQSpliterator<E>(this, null, 0, -1);
|
||||
return new PBQSpliterator(null, 0, -1);
|
||||
}
|
||||
|
||||
// VarHandle mechanics
|
||||
|
@ -1306,8 +1306,7 @@ public class ScheduledThreadPoolExecutor
|
||||
public Runnable next() {
|
||||
if (cursor >= array.length)
|
||||
throw new NoSuchElementException();
|
||||
lastRet = cursor;
|
||||
return array[cursor++];
|
||||
return array[lastRet = cursor++];
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
|
@ -195,6 +195,7 @@ public class SubmissionPublisher<T> implements Flow.Publisher<T>,
|
||||
|
||||
/** Fallback if ForkJoinPool.commonPool() cannot support parallelism */
|
||||
private static final class ThreadPerTaskExecutor implements Executor {
|
||||
ThreadPerTaskExecutor() {} // prevent access constructor creation
|
||||
public void execute(Runnable r) { new Thread(r).start(); }
|
||||
}
|
||||
|
||||
@ -1454,7 +1455,17 @@ public class SubmissionPublisher<T> implements Flow.Publisher<T>,
|
||||
*/
|
||||
private boolean checkControl(Flow.Subscriber<? super T> s, int c) {
|
||||
boolean stat = true;
|
||||
if ((c & ERROR) != 0) {
|
||||
if ((c & SUBSCRIBE) != 0) {
|
||||
if (CTL.compareAndSet(this, c, c & ~SUBSCRIBE)) {
|
||||
try {
|
||||
if (s != null)
|
||||
s.onSubscribe(this);
|
||||
} catch (Throwable ex) {
|
||||
onError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((c & ERROR) != 0) {
|
||||
Throwable ex = pendingError;
|
||||
ctl = DISABLED; // no need for CAS
|
||||
if (ex != null) { // null if errorless cancel
|
||||
@ -1465,16 +1476,6 @@ public class SubmissionPublisher<T> implements Flow.Publisher<T>,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((c & SUBSCRIBE) != 0) {
|
||||
if (CTL.compareAndSet(this, c, c & ~SUBSCRIBE)) {
|
||||
try {
|
||||
if (s != null)
|
||||
s.onSubscribe(this);
|
||||
} catch (Throwable ex) {
|
||||
onError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
detach();
|
||||
stat = false;
|
||||
|
@ -138,7 +138,7 @@ import jdk.internal.vm.annotation.ReservedStackAccess;
|
||||
* <pre> {@code
|
||||
* class CachedData {
|
||||
* Object data;
|
||||
* volatile boolean cacheValid;
|
||||
* boolean cacheValid;
|
||||
* final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
|
||||
*
|
||||
* void processCachedData() {
|
||||
|
@ -1338,7 +1338,7 @@ public abstract class SSLEngine {
|
||||
/**
|
||||
* Registers a callback function that selects an application protocol
|
||||
* value for a SSL/TLS/DTLS handshake.
|
||||
* The function overrides any values set using
|
||||
* The function overrides any values supplied using
|
||||
* {@link SSLParameters#setApplicationProtocols
|
||||
* SSLParameters.setApplicationProtocols} and it supports the following
|
||||
* type parameters:
|
||||
@ -1354,6 +1354,8 @@ public abstract class SSLEngine {
|
||||
* <dt> {@code String}
|
||||
* <dd> The function's result is an application protocol name, or null to
|
||||
* indicate that none of the advertised names are acceptable.
|
||||
* If the return value is an empty {@code String} then application
|
||||
* protocol indications will not be used.
|
||||
* If the return value is null (no value chosen) or is a value that
|
||||
* was not advertised by the peer, the underlying protocol will
|
||||
* determine what action to take. (For example, ALPN will send a
|
||||
|
@ -749,7 +749,7 @@ public abstract class SSLSocket extends Socket
|
||||
/**
|
||||
* Registers a callback function that selects an application protocol
|
||||
* value for a SSL/TLS/DTLS handshake.
|
||||
* The function overrides any values set using
|
||||
* The function overrides any values supplied using
|
||||
* {@link SSLParameters#setApplicationProtocols
|
||||
* SSLParameters.setApplicationProtocols} and it supports the following
|
||||
* type parameters:
|
||||
@ -765,6 +765,8 @@ public abstract class SSLSocket extends Socket
|
||||
* <dt> {@code String}
|
||||
* <dd> The function's result is an application protocol name, or null to
|
||||
* indicate that none of the advertised names are acceptable.
|
||||
* If the return value is an empty {@code String} then application
|
||||
* protocol indications will not be used.
|
||||
* If the return value is null (no value chosen) or is a value that
|
||||
* was not advertised by the peer, the underlying protocol will
|
||||
* determine what action to take. (For example, ALPN will send a
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, 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
|
||||
@ -31,7 +31,7 @@ import java.nio.*;
|
||||
import java.nio.channels.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
// Make a socket channel look like a socket.
|
||||
//
|
||||
@ -99,17 +99,19 @@ public class SocketAdaptor
|
||||
try {
|
||||
if (sc.connect(remote))
|
||||
return;
|
||||
long to = timeout;
|
||||
long timeoutNanos =
|
||||
TimeUnit.NANOSECONDS.convert(timeout,
|
||||
TimeUnit.MILLISECONDS);
|
||||
for (;;) {
|
||||
if (!sc.isOpen())
|
||||
throw new ClosedChannelException();
|
||||
long st = System.currentTimeMillis();
|
||||
long startTime = System.nanoTime();
|
||||
|
||||
int result = sc.poll(Net.POLLCONN, to);
|
||||
int result = sc.poll(Net.POLLCONN, timeout);
|
||||
if (result > 0 && sc.finishConnect())
|
||||
break;
|
||||
to -= System.currentTimeMillis() - st;
|
||||
if (to <= 0) {
|
||||
timeoutNanos -= System.nanoTime() - startTime;
|
||||
if (timeoutNanos <= 0) {
|
||||
try {
|
||||
sc.close();
|
||||
} catch (IOException x) { }
|
||||
@ -194,18 +196,20 @@ public class SocketAdaptor
|
||||
int n;
|
||||
if ((n = sc.read(bb)) != 0)
|
||||
return n;
|
||||
long to = timeout;
|
||||
long timeoutNanos =
|
||||
TimeUnit.NANOSECONDS.convert(timeout,
|
||||
TimeUnit.MILLISECONDS);
|
||||
for (;;) {
|
||||
if (!sc.isOpen())
|
||||
throw new ClosedChannelException();
|
||||
long st = System.currentTimeMillis();
|
||||
int result = sc.poll(Net.POLLIN, to);
|
||||
long startTime = System.nanoTime();
|
||||
int result = sc.poll(Net.POLLIN, timeout);
|
||||
if (result > 0) {
|
||||
if ((n = sc.read(bb)) != 0)
|
||||
return n;
|
||||
}
|
||||
to -= System.currentTimeMillis() - st;
|
||||
if (to <= 0)
|
||||
timeoutNanos -= System.nanoTime() - startTime;
|
||||
if (timeoutNanos <= 0)
|
||||
throw new SocketTimeoutException();
|
||||
}
|
||||
} finally {
|
||||
|
@ -80,7 +80,7 @@ public class CtrDrbg extends AbstractDrbg {
|
||||
@Override
|
||||
protected void chooseAlgorithmAndStrength() {
|
||||
if (requestedAlgorithm != null) {
|
||||
algorithm = requestedAlgorithm.toUpperCase();
|
||||
algorithm = requestedAlgorithm.toUpperCase(Locale.ROOT);
|
||||
int supportedStrength = alg2strength(algorithm);
|
||||
if (requestedInstantiationSecurityStrength >= 0) {
|
||||
int tryStrength = getStandardStrength(
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2016, 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
|
||||
@ -1009,7 +1009,7 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||
* @return the default alg, might be null if unsupported
|
||||
*/
|
||||
public static String getDefaultSigAlgForKey(PrivateKey k) {
|
||||
switch (k.getAlgorithm().toUpperCase()) {
|
||||
switch (k.getAlgorithm().toUpperCase(Locale.ROOT)) {
|
||||
case "EC":
|
||||
return ecStrength(KeyUtil.getKeySize(k))
|
||||
+ "withECDSA";
|
||||
|
@ -183,9 +183,10 @@ public class PropertyDescriptor extends FeatureDescriptor {
|
||||
setShortDescription(description.toString());
|
||||
}
|
||||
Object values = info.get(PropertyInfo.Name.enumerationValues);
|
||||
if (values != null) {
|
||||
setValue(PropertyInfo.Name.enumerationValues.name(), values);
|
||||
if (values == null) {
|
||||
values = new Object[0];
|
||||
}
|
||||
setValue(PropertyInfo.Name.enumerationValues.name(), values);
|
||||
this.baseName = base;
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import javax.accessibility.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* An implementation of a two-state button.
|
||||
@ -208,6 +209,96 @@ public class JToggleButton extends AbstractButton implements Accessible {
|
||||
return true;
|
||||
}
|
||||
|
||||
private JToggleButton getGroupSelection(FocusEvent.Cause cause) {
|
||||
switch (cause) {
|
||||
case ACTIVATION:
|
||||
case TRAVERSAL:
|
||||
case TRAVERSAL_UP:
|
||||
case TRAVERSAL_DOWN:
|
||||
case TRAVERSAL_FORWARD:
|
||||
case TRAVERSAL_BACKWARD:
|
||||
ButtonModel model = getModel();
|
||||
JToggleButton selection = this;
|
||||
if (model instanceof DefaultButtonModel) {
|
||||
ButtonGroup group = ((DefaultButtonModel) model).getGroup();
|
||||
if (group != null && group.getSelection() != null
|
||||
&& !group.isSelected(model)) {
|
||||
Iterator<AbstractButton> iterator =
|
||||
group.getElements().asIterator();
|
||||
while (iterator.hasNext()) {
|
||||
AbstractButton member = iterator.next();
|
||||
if (group.isSelected(member.getModel())) {
|
||||
if (member instanceof JToggleButton &&
|
||||
member.isVisible() && member.isDisplayable() &&
|
||||
member.isEnabled() && member.isFocusable()) {
|
||||
selection = (JToggleButton) member;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return selection;
|
||||
default:
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If this toggle button is a member of the {@link ButtonGroup} which has
|
||||
* another toggle button which is selected and can be the focus owner,
|
||||
* and the focus cause argument denotes window activation or focus
|
||||
* traversal action of any direction the result of the method execution
|
||||
* is the same as calling
|
||||
* {@link Component#requestFocus(FocusEvent.Cause)} on the toggle button
|
||||
* selected in the group.
|
||||
* In all other cases the result of the method is the same as calling
|
||||
* {@link Component#requestFocus(FocusEvent.Cause)} on this toggle button.
|
||||
*
|
||||
* @param cause the cause why the focus is requested
|
||||
* @see ButtonGroup
|
||||
* @see Component#requestFocus(FocusEvent.Cause)
|
||||
* @see FocusEvent.Cause
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public void requestFocus(FocusEvent.Cause cause) {
|
||||
getGroupSelection(cause).requestFocusUnconditionally(cause);
|
||||
}
|
||||
|
||||
private void requestFocusUnconditionally(FocusEvent.Cause cause) {
|
||||
super.requestFocus(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* If this toggle button is a member of the {@link ButtonGroup} which has
|
||||
* another toggle button which is selected and can be the focus owner,
|
||||
* and the focus cause argument denotes window activation or focus
|
||||
* traversal action of any direction the result of the method execution
|
||||
* is the same as calling
|
||||
* {@link Component#requestFocusInWindow(FocusEvent.Cause)} on the toggle
|
||||
* button selected in the group.
|
||||
* In all other cases the result of the method is the same as calling
|
||||
* {@link Component#requestFocusInWindow(FocusEvent.Cause)} on this toggle
|
||||
* button.
|
||||
*
|
||||
* @param cause the cause why the focus is requested
|
||||
* @see ButtonGroup
|
||||
* @see Component#requestFocusInWindow(FocusEvent.Cause)
|
||||
* @see FocusEvent.Cause
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
public boolean requestFocusInWindow(FocusEvent.Cause cause) {
|
||||
return getGroupSelection(cause)
|
||||
.requestFocusInWindowUnconditionally(cause);
|
||||
}
|
||||
|
||||
private boolean requestFocusInWindowUnconditionally(FocusEvent.Cause cause) {
|
||||
return super.requestFocusInWindow(cause);
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
|
||||
/**
|
||||
|
@ -629,16 +629,7 @@ public class UIManager implements Serializable
|
||||
}
|
||||
else {
|
||||
Class<?> lnfClass = SwingUtilities.loadSystemClass(className);
|
||||
try {
|
||||
LookAndFeel laf =
|
||||
(LookAndFeel)lnfClass.newInstance();
|
||||
setLookAndFeel(laf);
|
||||
} catch (ReflectiveOperationException | IllegalArgumentException e) {
|
||||
InstantiationException ex =
|
||||
new InstantiationException("Wrapped Exception");
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}
|
||||
setLookAndFeel((LookAndFeel)(lnfClass.newInstance()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,11 +182,17 @@ public abstract class FontConfiguration {
|
||||
throw new Error("java.home property not set");
|
||||
}
|
||||
javaLib = javaHome + File.separator + "lib";
|
||||
String javaConfFonts = javaHome +
|
||||
File.separator + "conf" +
|
||||
File.separator + "fonts";
|
||||
String userConfigFile = System.getProperty("sun.awt.fontconfig");
|
||||
if (userConfigFile != null) {
|
||||
fontConfigFile = new File(userConfigFile);
|
||||
} else {
|
||||
fontConfigFile = findFontConfigFile(javaLib);
|
||||
fontConfigFile = findFontConfigFile(javaConfFonts);
|
||||
if (fontConfigFile == null) {
|
||||
fontConfigFile = findFontConfigFile(javaLib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,8 +281,11 @@ public abstract class FontConfiguration {
|
||||
return null;
|
||||
}
|
||||
|
||||
private File findFontConfigFile(String javaLib) {
|
||||
String baseName = javaLib + File.separator + "fontconfig";
|
||||
private File findFontConfigFile(String dir) {
|
||||
if (!(new File(dir)).exists()) {
|
||||
return null;
|
||||
}
|
||||
String baseName = dir + File.separator + "fontconfig";
|
||||
File configFile;
|
||||
String osMajorVersion = null;
|
||||
if (osVersion != null && osName != null) {
|
||||
|
@ -33,13 +33,14 @@
|
||||
* Generated on: 10/26/2010 02:53:33 PM PDT
|
||||
*/
|
||||
|
||||
#include "LEScripts.h"
|
||||
#include "LETypes.h"
|
||||
#include "ScriptAndLanguageTags.h"
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
const LETag OpenTypeLayoutEngine::scriptTags[] = {
|
||||
const LETag OpenTypeLayoutEngine::scriptTags[scriptCodeCount] = {
|
||||
zyyyScriptTag, /* 'zyyy' (COMMON) */
|
||||
zinhScriptTag, /* 'zinh' (INHERITED) */
|
||||
arabScriptTag, /* 'arab' (ARABIC) */
|
||||
|
@ -302,7 +302,7 @@ le_int32 ThaiShaping::compose(const LEUnicode *input, le_int32 offset, le_int32
|
||||
le_uint8 charClass;
|
||||
|
||||
// Decompose SARA AM into NIKHAHIT + SARA AA
|
||||
if (ch == CH_SARA_AM && isLegalHere(ch, state)) {
|
||||
if (ch == CH_SARA_AM && isLegalHere(ch, state) && conState < stateCount) {
|
||||
outputIndex = conOutput;
|
||||
state = getNextState(CH_NIKHAHIT, conState, inputIndex, glyphSet, errorChar, charClass,
|
||||
output, glyphStorage, outputIndex);
|
||||
|
@ -80,7 +80,8 @@ public:
|
||||
tG = 5,
|
||||
tH = 6,
|
||||
tR = 7,
|
||||
tS = 8
|
||||
tS = 8,
|
||||
stateCount = 52
|
||||
};
|
||||
|
||||
struct StateTransition
|
||||
@ -100,7 +101,7 @@ private:
|
||||
ThaiShaping();
|
||||
|
||||
static const le_uint8 classTable[];
|
||||
static const StateTransition thaiStateTable[][classCount];
|
||||
static const StateTransition thaiStateTable[stateCount][classCount];
|
||||
|
||||
inline static StateTransition getTransition(le_uint8 state, le_uint8 currClass);
|
||||
|
||||
|
@ -49,7 +49,7 @@ const le_uint8 ThaiShaping::classTable[] = {
|
||||
/*0E50*/ NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON
|
||||
};
|
||||
|
||||
const ThaiShaping::StateTransition ThaiShaping::thaiStateTable[][ThaiShaping::classCount] = {
|
||||
const ThaiShaping::StateTransition ThaiShaping::thaiStateTable[ThaiShaping::stateCount][ThaiShaping::classCount] = {
|
||||
//+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
//| N C C C L F F F B B B T A A A N A A A |
|
||||
//| O O O O V V V V V V D O D D D I V V V |
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2016, 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
|
||||
@ -385,6 +385,7 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
|
||||
int isStereo;
|
||||
char* type;
|
||||
snd_mixer_selem_channel_id_t channel;
|
||||
memset(controls, 0, sizeof(controls));
|
||||
|
||||
TRACE0("> PORT_GetControls\n");
|
||||
if (id == NULL) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2016, 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
|
||||
@ -385,6 +385,7 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
|
||||
int isStereo;
|
||||
char* type;
|
||||
snd_mixer_selem_channel_id_t channel;
|
||||
memset(controls, 0, sizeof(controls));
|
||||
|
||||
TRACE0("> PORT_GetControls\n");
|
||||
if (id == NULL) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2016, 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
|
||||
@ -390,6 +390,7 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
|
||||
int controlCount = 0;
|
||||
INT32 type;
|
||||
int selectable = 1;
|
||||
memset(controls, 0, sizeof(controls));
|
||||
|
||||
TRACE4(">PORT_GetControls(id=%p, portIndex=%d). controlIDs=%p, maxControlCount=%d\n",
|
||||
id, portIndex, info->controlIDs, info->maxControlCount);
|
||||
|
@ -28,6 +28,7 @@ package com.oracle.security.ucrypto;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Set;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.lang.ref.*;
|
||||
|
||||
@ -262,7 +263,7 @@ public class NativeCipherWithJavaPadding extends CipherSpi {
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException {
|
||||
this.nc = nc;
|
||||
this.blockSize = nc.engineGetBlockSize();
|
||||
if (paddingScheme.toUpperCase().equals("PKCS5PADDING")) {
|
||||
if (paddingScheme.toUpperCase(Locale.ROOT).equals("PKCS5PADDING")) {
|
||||
padding = new PKCS5Padding(blockSize);
|
||||
} else {
|
||||
throw new NoSuchAlgorithmException("Unsupported padding scheme: " + paddingScheme);
|
||||
|
@ -74,6 +74,7 @@ import java.util.MissingResourceException;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
@ -497,6 +498,7 @@ public class JmodTask {
|
||||
|
||||
// Add (or replace) the Packages attribute
|
||||
if (packages != null) {
|
||||
validatePackages(descriptor, packages);
|
||||
extender.packages(packages);
|
||||
}
|
||||
|
||||
@ -530,6 +532,24 @@ public class JmodTask {
|
||||
}
|
||||
}
|
||||
|
||||
private void validatePackages(ModuleDescriptor descriptor, Set<String> packages) {
|
||||
Set<String> nonExistPackages = new TreeSet<>();
|
||||
descriptor.exports().stream()
|
||||
.map(Exports::source)
|
||||
.filter(pn -> !packages.contains(pn))
|
||||
.forEach(nonExistPackages::add);
|
||||
|
||||
descriptor.opens().stream()
|
||||
.map(Opens::source)
|
||||
.filter(pn -> !packages.contains(pn))
|
||||
.forEach(nonExistPackages::add);
|
||||
|
||||
if (!nonExistPackages.isEmpty()) {
|
||||
throw new CommandException("err.missing.export.or.open.packages",
|
||||
descriptor.name(), nonExistPackages);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Hasher resolves a module graph using the --hash-modules PATTERN
|
||||
* as the roots.
|
||||
|
@ -107,6 +107,7 @@ err.missing.arg=no value given for {0}
|
||||
err.internal.error=internal error: {0} {1} {2}
|
||||
err.invalid.dryrun.option=--dry-run can only be used with hash mode
|
||||
err.module.descriptor.not.found=Module descriptor not found
|
||||
err.missing.export.or.open.packages=Packages that are exported or open in {0} are not present: {1}
|
||||
warn.invalid.arg=Invalid classname or pathname not exist: {0}
|
||||
warn.no.module.hashes=No hashes recorded: no module specified for hashing depends on {0}
|
||||
warn.module.resolution.fail=No hashes recorded: {0}
|
||||
|
@ -203,8 +203,6 @@ java/rmi/activation/Activatable/extLoadedImpl/ext.sh 8062724 generic-
|
||||
|
||||
sun/rmi/rmic/newrmic/equivalence/run.sh 8145980 generic-all
|
||||
|
||||
java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-all
|
||||
|
||||
java/rmi/registry/readTest/readTest.sh 7146543 generic-all
|
||||
|
||||
############################################################################
|
||||
@ -217,10 +215,6 @@ sun/security/tools/keytool/ListKeychainStore.sh 8156889 macosx-a
|
||||
|
||||
sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java 8026393 generic-all
|
||||
|
||||
sun/security/ssl/SSLSocketImpl/AsyncSSLSocketClose.java 8161232 macosx-all
|
||||
|
||||
sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java 8171043 windows-all
|
||||
|
||||
javax/net/ssl/DTLS/PacketLossRetransmission.java 8169086 macosx-x64
|
||||
|
||||
############################################################################
|
||||
@ -234,8 +228,6 @@ javax/sound/sampled/Clip/Drain/ClipDrain.java 7062792 generic-all
|
||||
|
||||
javax/sound/sampled/Mixers/DisabledAssertionCrash.java 7067310 generic-all
|
||||
|
||||
javax/sound/sampled/Clip/OpenNonIntegralNumberOfSampleframes.java 8168881 generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_imageio
|
||||
|
@ -23,12 +23,12 @@
|
||||
|
||||
/*
|
||||
@test
|
||||
@bug 4980592
|
||||
@bug 4980592 8171363
|
||||
@summary switching user in XP causes an NPE in
|
||||
sun.awt.windows.WWindowPeer.displayChanged
|
||||
@requires (os.family == "windows")
|
||||
@modules java.desktop/java.awt.peer
|
||||
@modules java.desktop/sun.awt.windows
|
||||
@modules java.desktop/sun.awt.windows:open
|
||||
@modules java.desktop/sun.awt
|
||||
@author son@sparc.spb.su: area=embedded
|
||||
@run main DisplayChangedTest
|
||||
|
@ -23,12 +23,12 @@
|
||||
|
||||
/*
|
||||
@test
|
||||
@bug 6345002
|
||||
@bug 6345003 8171363
|
||||
@summary grab problems with EmbeddedFrame
|
||||
@requires (os.family == "windows")
|
||||
@modules java.desktop/java.awt.peer
|
||||
@modules java.desktop/sun.awt
|
||||
@modules java.desktop/sun.awt.windows
|
||||
@modules java.desktop/sun.awt.windows:open
|
||||
@author Oleg.Semenov@sun.com area=EmbeddedFrame
|
||||
@run main EmbeddedFrameGrabTest
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 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
|
||||
@ -31,34 +31,57 @@ import javax.swing.TransferHandler;
|
||||
/*
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8130329
|
||||
* @bug 8130329 8134612 8133719
|
||||
* @summary Audit Core Reflection in module java.desktop AWT/Miscellaneous area
|
||||
* for places that will require changes to work with modules
|
||||
* @author Alexander Scherbatiy
|
||||
* @run main/othervm ConstructFlavoredObjectTest COPY
|
||||
* @run main/othervm ConstructFlavoredObjectTest PASTE
|
||||
*/
|
||||
public class ConstructFlavoredObjectTest {
|
||||
|
||||
private static final String TEST_MIME_TYPE = "text/plain;class="
|
||||
+ MyStringReader.class.getName();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
final DataFlavor dataFlavor = new DataFlavor(TEST_MIME_TYPE);
|
||||
SystemFlavorMap systemFlavorMap = (SystemFlavorMap) SystemFlavorMap.
|
||||
getDefaultFlavorMap();
|
||||
systemFlavorMap.addUnencodedNativeForFlavor(dataFlavor, "TEXT");
|
||||
systemFlavorMap.addFlavorForUnencodedNative("TEXT", dataFlavor);
|
||||
if (args[0].equals("COPY")) {
|
||||
|
||||
TransferHandler transferHandler = new TransferHandler("Test Handler");
|
||||
// Copy a simple text string on to the System clipboard
|
||||
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
transferHandler.exportToClipboard(new JLabel("Test"), clipboard,
|
||||
TransferHandler.COPY);
|
||||
final String TEXT_MIME_TYPE = DataFlavor.javaJVMLocalObjectMimeType +
|
||||
";class=" + String.class.getName();
|
||||
|
||||
Object clipboardData = clipboard.getData(dataFlavor);
|
||||
final DataFlavor dataFlavor = new DataFlavor(TEXT_MIME_TYPE);
|
||||
SystemFlavorMap systemFlavorMap =
|
||||
(SystemFlavorMap) SystemFlavorMap.getDefaultFlavorMap();
|
||||
systemFlavorMap.addUnencodedNativeForFlavor(dataFlavor, "TEXT");
|
||||
systemFlavorMap.addFlavorForUnencodedNative("TEXT", dataFlavor);
|
||||
|
||||
if (!(clipboardData instanceof MyStringReader)) {
|
||||
throw new RuntimeException("Wrong clipboard data!");
|
||||
TransferHandler transferHandler = new TransferHandler("text");
|
||||
|
||||
String text = "This is sample export text";
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
transferHandler.exportToClipboard(new JLabel(text), clipboard,
|
||||
TransferHandler.COPY);
|
||||
}
|
||||
else if (args[0].equals("PASTE")) {
|
||||
|
||||
// Try to read text data from the System clipboard
|
||||
|
||||
final String TEST_MIME_TYPE = "text/plain;class=" +
|
||||
MyStringReader.class.getName();
|
||||
|
||||
final DataFlavor dataFlavor = new DataFlavor(TEST_MIME_TYPE);
|
||||
SystemFlavorMap systemFlavorMap = (SystemFlavorMap) SystemFlavorMap.
|
||||
getDefaultFlavorMap();
|
||||
systemFlavorMap.addUnencodedNativeForFlavor(dataFlavor, "TEXT");
|
||||
systemFlavorMap.addFlavorForUnencodedNative("TEXT", dataFlavor);
|
||||
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
|
||||
Object clipboardData = clipboard.getData(dataFlavor);
|
||||
|
||||
if (!(clipboardData instanceof MyStringReader)) {
|
||||
throw new RuntimeException("Wrong clipboard data!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,3 +101,4 @@ public class ConstructFlavoredObjectTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2016, 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
|
||||
@ -28,7 +28,7 @@ import java.beans.PropertyDescriptor;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8130937
|
||||
* @bug 8130937 8131347
|
||||
* @summary Tests the booleans properties of the BeanProperty annotation
|
||||
* @library ..
|
||||
*/
|
||||
@ -76,6 +76,9 @@ public final class TestBooleanBeanProperties {
|
||||
if (getValue(pd, "visualUpdate") != isVS) {
|
||||
throw new RuntimeException("required should be: " + isVS);
|
||||
}
|
||||
if (pd.getValue("enumerationValues") == null) {
|
||||
throw new RuntimeException("enumerationValues should be empty array");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean getValue(PropertyDescriptor pd, String value) {
|
||||
@ -107,7 +110,8 @@ public final class TestBooleanBeanProperties {
|
||||
}
|
||||
|
||||
@BeanProperty(bound = true, expert = true, hidden = true,
|
||||
preferred = true, required = true, visualUpdate = true)
|
||||
preferred = true, required = true, visualUpdate = true,
|
||||
enumerationValues = {})
|
||||
public void setValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
@ -33,28 +33,48 @@ import java.io.IOException;
|
||||
*/
|
||||
public class REGISTRY extends JavaVM {
|
||||
|
||||
private static double startTimeout = 20_000 * TestLibrary.getTimeoutFactor();
|
||||
private static final double START_TIMEOUT =
|
||||
20_000 * TestLibrary.getTimeoutFactor();
|
||||
private static final String DEFAULT_RUNNER = "RegistryRunner";
|
||||
|
||||
private int port = -1;
|
||||
|
||||
private REGISTRY(OutputStream out, OutputStream err,
|
||||
private REGISTRY(String runner, OutputStream out, OutputStream err,
|
||||
String options, int port) {
|
||||
super("RegistryRunner", options, Integer.toString(port), out, err);
|
||||
super(runner, options, Integer.toString(port), out, err);
|
||||
try {
|
||||
Class runnerClass = Class.forName(runner);
|
||||
if (!RegistryRunner.class.isAssignableFrom(runnerClass)) {
|
||||
throw new RuntimeException("runner class must be RegistryRunner"
|
||||
+ " or its sub class");
|
||||
}
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public static REGISTRY createREGISTRY() {
|
||||
return createREGISTRY(System.out, System.err, "", 0);
|
||||
return createREGISTRYWithRunner(DEFAULT_RUNNER, System.out, System.err, "", 0);
|
||||
}
|
||||
|
||||
public static REGISTRY createREGISTRY(OutputStream out, OutputStream err,
|
||||
String options, int port) {
|
||||
return createREGISTRYWithRunner(DEFAULT_RUNNER, out, err, options, port);
|
||||
}
|
||||
|
||||
public static REGISTRY createREGISTRYWithRunner(String runner, String options) {
|
||||
return createREGISTRYWithRunner(runner, System.out, System.err, options, 0);
|
||||
}
|
||||
|
||||
public static REGISTRY createREGISTRYWithRunner(String runner, OutputStream out,
|
||||
OutputStream err, String options, int port) {
|
||||
options += " --add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED"
|
||||
+ " --add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED"
|
||||
+ " --add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED"
|
||||
+ " --add-exports=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED";
|
||||
REGISTRY reg = new REGISTRY(out, err, options, port);
|
||||
return reg;
|
||||
+ " --add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED"
|
||||
+ " --add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED"
|
||||
+ " --add-exports=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED";
|
||||
REGISTRY reg = new REGISTRY(runner, out, err, options, port);
|
||||
return reg;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,7 +85,7 @@ public class REGISTRY extends JavaVM {
|
||||
public void start() throws IOException {
|
||||
super.start();
|
||||
long startTime = System.currentTimeMillis();
|
||||
long deadline = TestLibrary.computeDeadline(startTime, (long)startTimeout);
|
||||
long deadline = TestLibrary.computeDeadline(startTime, (long)START_TIMEOUT);
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
|
@ -36,7 +36,7 @@ public class RegistryRunner extends UnicastRemoteObject
|
||||
implements RemoteExiter
|
||||
{
|
||||
private static final String PORT_LABEL_START = "RegistryRunner.port.start:";
|
||||
private static final String PORT_LABEL_END = "RegistryRunner.port.end";
|
||||
private static final String PORT_LABEL_END = ":RegistryRunner.port.end";
|
||||
|
||||
private static Registry registry = null;
|
||||
private static RemoteExiter exiter = null;
|
||||
@ -95,17 +95,17 @@ public class RegistryRunner extends UnicastRemoteObject
|
||||
return port;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
/**
|
||||
* port 0 means to use ephemeral port to start registry.
|
||||
*/
|
||||
protected static int init(String[] args) {
|
||||
try {
|
||||
if (args.length == 0) {
|
||||
System.err.println("Usage: <port>");
|
||||
System.exit(0);
|
||||
}
|
||||
int port = -1;
|
||||
try {
|
||||
port = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException ignore) { }
|
||||
port = Integer.parseInt(args[0]);
|
||||
|
||||
// create a registry
|
||||
registry = LocateRegistry.createRegistry(port);
|
||||
@ -118,14 +118,30 @@ public class RegistryRunner extends UnicastRemoteObject
|
||||
Naming.rebind("rmi://localhost:" + port +
|
||||
"/RemoteExiter", exiter);
|
||||
|
||||
// this output is important for REGISTRY to get the port
|
||||
// where rmiregistry is serving
|
||||
System.out.println(PORT_LABEL_START + port + PORT_LABEL_END);
|
||||
|
||||
return port;
|
||||
} catch (Exception e) {
|
||||
System.err.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
System.exit(-1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* REGISTRY.start() will filter the output of registry subprocess,
|
||||
* when valid port is detected, REGISTRY.start() returns.
|
||||
* So, for subclass, it's important to call this method after registry
|
||||
* is initialized and necessary remote objects have been bound.
|
||||
*/
|
||||
protected static void notify(int port) {
|
||||
// this output is important for REGISTRY to get the port
|
||||
// where rmiregistry is serving
|
||||
System.out.println(PORT_LABEL_START + port + PORT_LABEL_END);
|
||||
System.out.flush();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int port = init(args);
|
||||
notify(port);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -33,7 +33,7 @@
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary Test TestImpl TestImpl_Stub
|
||||
* @build TestLibrary Test TestImpl REGISTRY RegistryRunner
|
||||
* @run main/othervm/policy=security.policy/timeout=360 DGCDeadLock
|
||||
*/
|
||||
|
||||
@ -55,11 +55,12 @@ import java.rmi.*;
|
||||
import java.io.*;
|
||||
|
||||
public class DGCDeadLock implements Runnable {
|
||||
private static final int REGISTRY_PORT = TestLibrary.getUnusedRandomPort();
|
||||
final static public int HOLD_TARGET_TIME = 25000;
|
||||
public static int TEST_FAIL_TIME = HOLD_TARGET_TIME + 30000;
|
||||
public static boolean finished = false;
|
||||
static DGCDeadLock test = new DGCDeadLock();
|
||||
public static final double TEST_FAIL_TIME =
|
||||
(HOLD_TARGET_TIME + 30000) * TestLibrary.getTimeoutFactor();
|
||||
public static volatile boolean finished = false;
|
||||
static final DGCDeadLock test = new DGCDeadLock();
|
||||
static volatile int registryPort = -1;
|
||||
|
||||
static {
|
||||
System.setProperty("sun.rmi.transport.cleanInterval", "50");
|
||||
@ -67,7 +68,7 @@ public class DGCDeadLock implements Runnable {
|
||||
|
||||
static public void main(String[] args) {
|
||||
|
||||
JavaVM testImplVM = null;
|
||||
REGISTRY testImplVM = null;
|
||||
|
||||
System.err.println("\nregression test for 4118056\n");
|
||||
TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
|
||||
@ -75,18 +76,15 @@ public class DGCDeadLock implements Runnable {
|
||||
try {
|
||||
String options = " -Djava.security.policy=" +
|
||||
TestParams.defaultPolicy +
|
||||
" --add-exports java.rmi/sun.rmi.registry=ALL-UNNAMED" +
|
||||
" --add-exports java.rmi/sun.rmi.server=ALL-UNNAMED" +
|
||||
" --add-opens java.rmi/sun.rmi.transport=ALL-UNNAMED" +
|
||||
" --add-exports java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" +
|
||||
" -Djava.rmi.dgc.leaseValue=500000" +
|
||||
" -Dsun.rmi.dgc.checkInterval=" +
|
||||
" -Dsun.rmi.dgc.checkInterval=" +
|
||||
(HOLD_TARGET_TIME - 5000) +
|
||||
" -Drmi.registry.port=" + REGISTRY_PORT +
|
||||
"" ;
|
||||
|
||||
testImplVM = new JavaVM("TestImpl", options, "");
|
||||
testImplVM = REGISTRY.createREGISTRYWithRunner("TestImpl", options);
|
||||
testImplVM.start();
|
||||
registryPort = testImplVM.getPort();
|
||||
|
||||
synchronized (test) {
|
||||
Thread t = new Thread(test);
|
||||
@ -94,7 +92,7 @@ public class DGCDeadLock implements Runnable {
|
||||
t.start();
|
||||
|
||||
// wait for the remote calls to take place
|
||||
test.wait(TEST_FAIL_TIME);
|
||||
test.wait((long)TEST_FAIL_TIME);
|
||||
}
|
||||
|
||||
if (!finished) {
|
||||
@ -106,8 +104,12 @@ public class DGCDeadLock implements Runnable {
|
||||
"finished in time.");
|
||||
|
||||
} catch (Exception e) {
|
||||
testImplVM = null;
|
||||
TestLibrary.bomb("test failed", e);
|
||||
TestLibrary.bomb("test failed in main()", e);
|
||||
} finally {
|
||||
if (testImplVM != null) {
|
||||
testImplVM.shutdown();
|
||||
testImplVM = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,12 +117,9 @@ public class DGCDeadLock implements Runnable {
|
||||
try {
|
||||
String echo = null;
|
||||
|
||||
// give the test remote object time to initialize.
|
||||
Thread.currentThread().sleep(8000);
|
||||
|
||||
// create a test client
|
||||
Test foo = (Test) Naming.lookup("rmi://:" +
|
||||
REGISTRY_PORT +
|
||||
registryPort +
|
||||
"/Foo");
|
||||
echo = foo.echo("Hello world");
|
||||
System.err.println("Test object created.");
|
||||
@ -139,7 +138,7 @@ public class DGCDeadLock implements Runnable {
|
||||
|
||||
//import "Bar"
|
||||
Test bar = (Test) Naming.lookup("rmi://:" +
|
||||
REGISTRY_PORT +
|
||||
registryPort +
|
||||
"/Bar");
|
||||
|
||||
/* infinite loop to show the liveness of Client,
|
||||
@ -155,11 +154,16 @@ public class DGCDeadLock implements Runnable {
|
||||
finished = true;
|
||||
|
||||
} catch (RemoteException e) {
|
||||
System.err.println("catch RemoteException");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb("test failed", e);
|
||||
TestLibrary.bomb("test failed in run()", e);
|
||||
} finally {
|
||||
synchronized(this) {
|
||||
notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2016, 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
|
||||
@ -34,7 +34,7 @@ import java.util.*;
|
||||
import java.rmi.registry.*;
|
||||
import java.rmi.server.*;
|
||||
|
||||
public class TestImpl extends UnicastRemoteObject
|
||||
public class TestImpl extends RegistryRunner
|
||||
implements Test {
|
||||
static Thread locker = null;
|
||||
static TestImpl foo = null;
|
||||
@ -53,12 +53,8 @@ public class TestImpl extends UnicastRemoteObject
|
||||
}
|
||||
|
||||
static public void main(String[] args) {
|
||||
Registry registry = null;
|
||||
|
||||
try {
|
||||
int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
|
||||
registry = java.rmi.registry.LocateRegistry.
|
||||
createRegistry(registryPort);
|
||||
int registryPort = RegistryRunner.init(args);
|
||||
|
||||
//export "Foo"
|
||||
foo = new TestImpl();
|
||||
@ -75,16 +71,11 @@ public class TestImpl extends UnicastRemoteObject
|
||||
} catch (Exception e) {
|
||||
throw new RemoteException(e.getMessage());
|
||||
}
|
||||
Thread.sleep(DGCDeadLock.TEST_FAIL_TIME);
|
||||
System.err.println("object vm exiting...");
|
||||
System.exit(0);
|
||||
|
||||
RegistryRunner.notify(registryPort);
|
||||
} catch (Exception e) {
|
||||
System.err.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
TestLibrary.unexport(registry);
|
||||
registry = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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
|
||||
@ -66,9 +66,11 @@ import java.text.ParsePosition;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.time.temporal.TemporalField;
|
||||
import java.time.temporal.WeekFields;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
@ -79,12 +81,17 @@ import test.java.time.format.AbstractTestPrinterParser;
|
||||
*/
|
||||
@Test
|
||||
public class TCKLocalizedFieldParser extends AbstractTestPrinterParser {
|
||||
|
||||
public static final WeekFields WEEKDEF = WeekFields.of(Locale.US);
|
||||
public static final TemporalField WEEK_BASED_YEAR = WEEKDEF.weekBasedYear();
|
||||
public static final TemporalField WEEK_OF_WEEK_BASED_YEAR = WEEKDEF.weekOfWeekBasedYear();
|
||||
public static final TemporalField DAY_OF_WEEK = WEEKDEF.dayOfWeek();
|
||||
//-----------------------------------------------------------------------
|
||||
@DataProvider(name="FieldPatterns")
|
||||
Object[][] provider_fieldPatterns() {
|
||||
return new Object[][] {
|
||||
{"e", "6", 0, 1, 6},
|
||||
{"e", "6", 0, 1, 6},
|
||||
{"ee", "06", 0, 2, 6},
|
||||
{"c", "6", 0, 1 , 6},
|
||||
{"W", "3", 0, 1, 3},
|
||||
{"w", "29", 0, 2, 29},
|
||||
{"ww", "29", 0, 2, 29},
|
||||
@ -99,6 +106,7 @@ public class TCKLocalizedFieldParser extends AbstractTestPrinterParser {
|
||||
WeekFields weekDef = WeekFields.of(locale);
|
||||
TemporalField field = null;
|
||||
switch(pattern.charAt(0)) {
|
||||
case 'c' :
|
||||
case 'e' :
|
||||
field = weekDef.dayOfWeek();
|
||||
break;
|
||||
@ -176,9 +184,9 @@ public class TCKLocalizedFieldParser extends AbstractTestPrinterParser {
|
||||
{"Y-w-e", "2008-01-1", 0, 9, LocalDate.of(2007, 12, 30)},
|
||||
{"Y-w-e", "2008-52-1", 0, 9, LocalDate.of(2008, 12, 21)},
|
||||
{"Y-w-e", "2008-52-7", 0, 9, LocalDate.of(2008, 12, 27)},
|
||||
{"Y-w-e", "2009-01-01", 0, 10, LocalDate.of(2008, 12, 28)},
|
||||
{"Y-w-e", "2009-01-04", 0, 10, LocalDate.of(2008, 12, 31)},
|
||||
{"Y-w-e", "2009-01-05", 0, 10, LocalDate.of(2009, 1, 1)},
|
||||
{"Y-w-e", "2009-01-1", 0, 9, LocalDate.of(2008, 12, 28)},
|
||||
{"Y-w-e", "2009-01-4", 0, 9, LocalDate.of(2008, 12, 31)},
|
||||
{"Y-w-e", "2009-01-5", 0, 9, LocalDate.of(2009, 1, 1)},
|
||||
};
|
||||
}
|
||||
|
||||
@ -202,4 +210,77 @@ public class TCKLocalizedFieldParser extends AbstractTestPrinterParser {
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@DataProvider(name = "adjacentValuePatterns1")
|
||||
Object[][] provider_adjacentValuePatterns1() {
|
||||
return new Object[][] {
|
||||
{"YYww", WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, "1612", 2016, 12},
|
||||
{"YYYYww", WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, "201612", 2016, 12},
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "adjacentValuePatterns1")
|
||||
public void test_adjacentValuePatterns1(String pattern, TemporalField field1, TemporalField field2,
|
||||
String text, int expected1, int expected2) {
|
||||
DateTimeFormatter df = new DateTimeFormatterBuilder()
|
||||
.appendPattern(pattern).toFormatter(Locale.US);
|
||||
ParsePosition ppos = new ParsePosition(0);
|
||||
TemporalAccessor parsed = df.parseUnresolved(text, ppos);
|
||||
assertEquals(parsed.get(field1), expected1);
|
||||
assertEquals(parsed.get(field2), expected2);
|
||||
}
|
||||
|
||||
@DataProvider(name = "adjacentValuePatterns2")
|
||||
Object[][] provider_adjacentValuePatterns2() {
|
||||
return new Object[][] {
|
||||
{"YYYYwwc", WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, DAY_OF_WEEK,
|
||||
"2016121", 2016, 12, 1},
|
||||
{"YYYYwwee", WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, DAY_OF_WEEK,
|
||||
"20161201", 2016, 12, 1},
|
||||
{"YYYYwwe", WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, DAY_OF_WEEK,
|
||||
"2016121", 2016, 12, 1},
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "adjacentValuePatterns2")
|
||||
public void test_adjacentValuePatterns2(String pattern, TemporalField field1, TemporalField field2,
|
||||
TemporalField field3, String text, int expected1, int expected2, int expected3) {
|
||||
DateTimeFormatter df = new DateTimeFormatterBuilder()
|
||||
.appendPattern(pattern).toFormatter(Locale.US);
|
||||
ParsePosition ppos = new ParsePosition(0);
|
||||
TemporalAccessor parsed = df.parseUnresolved(text, ppos);
|
||||
assertEquals(parsed.get(field1), expected1);
|
||||
assertEquals(parsed.get(field2), expected2);
|
||||
assertEquals(parsed.get(field3), expected3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_adjacentValuePatterns3() {
|
||||
String pattern = "yyyyMMddwwc";
|
||||
String text = "20120720296";
|
||||
DateTimeFormatter df = new DateTimeFormatterBuilder()
|
||||
.appendPattern(pattern).toFormatter(Locale.US);
|
||||
ParsePosition ppos = new ParsePosition(0);
|
||||
TemporalAccessor parsed = df.parseUnresolved(text, ppos);
|
||||
assertEquals(parsed.get(DAY_OF_WEEK), 6);
|
||||
assertEquals(parsed.get(WEEK_OF_WEEK_BASED_YEAR), 29);
|
||||
LocalDate result = LocalDate.parse(text, df);
|
||||
LocalDate expectedValue = LocalDate.of(2012, 07, 20);
|
||||
assertEquals(result, expectedValue, "LocalDate incorrect for " + pattern);
|
||||
}
|
||||
|
||||
@DataProvider(name = "invalidPatterns")
|
||||
Object[][] provider_invalidPatterns() {
|
||||
return new Object[][] {
|
||||
{"W", "01"},
|
||||
{"c", "01"},
|
||||
{"e", "01"},
|
||||
{"yyyyMMddwwc", "201207202906"}, // 1 extra digit in the input
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "invalidPatterns", expectedExceptions = DateTimeParseException.class)
|
||||
public void test_invalidPatterns(String pattern, String value) {
|
||||
DateTimeFormatter.ofPattern(pattern).parse(value);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 4290801 4692419 4693631 5101540 5104960 6296410 6336600 6371531
|
||||
* 6488442 7036905 8008577 8039317 8074350 8074351 8150324
|
||||
* 6488442 7036905 8008577 8039317 8074350 8074351 8150324 8167143
|
||||
* @summary Basic tests for Currency class.
|
||||
* @modules java.base/java.util:open
|
||||
* jdk.localedata
|
||||
@ -188,7 +188,7 @@ public class CurrencyTest {
|
||||
static void testSymbols() {
|
||||
testSymbol("USD", Locale.US, "$");
|
||||
testSymbol("EUR", Locale.GERMANY, "\u20AC");
|
||||
testSymbol("USD", Locale.PRC, "USD");
|
||||
testSymbol("USD", Locale.PRC, "US$");
|
||||
}
|
||||
|
||||
static void testSymbol(String currencyCode, Locale locale, String expectedSymbol) {
|
||||
@ -262,7 +262,7 @@ public class CurrencyTest {
|
||||
testDisplayName("KRW", Locale.KOREAN, "\ub300\ud55c\ubbfc\uad6d \uc6d0");
|
||||
testDisplayName("SEK", new Locale("sv"), "svensk krona");
|
||||
testDisplayName("CNY", Locale.SIMPLIFIED_CHINESE, "\u4eba\u6c11\u5e01");
|
||||
testDisplayName("TWD", Locale.TRADITIONAL_CHINESE, "\u65b0\u81fa\u5e63");
|
||||
testDisplayName("TWD", Locale.TRADITIONAL_CHINESE, "\u65b0\u53f0\u5e63");
|
||||
}
|
||||
|
||||
static void testDisplayName(String currencyCode, Locale locale, String expectedName) {
|
||||
|
279
jdk/test/java/util/TimeZone/Bug8167143.java
Normal file
279
jdk/test/java/util/TimeZone/Bug8167143.java
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8167143
|
||||
* @summary Test
|
||||
* Timezone parsing works for all locales for default providers prefernce
|
||||
* as well as when prefernce list is [COMPAT, CLDR],
|
||||
* CLDR implict locales are correctly reflected,
|
||||
* th_TH bundle is not wrongly cached in DateFormatSymbols,
|
||||
* correct candidate locale list is retrieved for
|
||||
* zh_Hant and zh_Hans and
|
||||
* Implict COMPAT Locales nn-NO, nb-NO are reflected in available locales
|
||||
* for all Providers for COMPAT.
|
||||
* @modules java.base/sun.util.locale.provider
|
||||
* java.base/sun.util.spi
|
||||
* jdk.localedata
|
||||
* @run main/othervm -Djava.locale.providers=COMPAT,CLDR Bug8167143 testTimeZone
|
||||
* @run main/othervm Bug8167143 testTimeZone
|
||||
* @run main/othervm -Djava.locale.providers=CLDR Bug8167143 testCldr
|
||||
* @run main/othervm Bug8167143 testCache
|
||||
* @run main/othervm Bug8167143 testCandidateLocales
|
||||
* @run main/othervm -Djava.locale.providers=COMPAT Bug8167143 testCompat
|
||||
*/
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import sun.util.locale.provider.LocaleProviderAdapter;
|
||||
import sun.util.locale.provider.LocaleProviderAdapter.Type;
|
||||
|
||||
public class Bug8167143 {
|
||||
|
||||
private static final TimeZone REYKJAVIK = TimeZone.getTimeZone("Atlantic/Reykjavik");
|
||||
private static final TimeZone NEW_YORK = TimeZone.getTimeZone("America/New_York");
|
||||
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
|
||||
private static final List<Locale> CLDR_IMPLICIT_LOCS = List.of(Locale.forLanguageTag("zh-Hans-CN"),
|
||||
Locale.forLanguageTag("zh-Hans-SG"),
|
||||
Locale.forLanguageTag("zh-Hant-HK"),
|
||||
Locale.forLanguageTag("zh-Hant-TW"),
|
||||
Locale.forLanguageTag("zh-Hant-MO"));
|
||||
|
||||
private static final List<Locale> COMPAT_IMPLICIT_LOCS = List.of(Locale.forLanguageTag("nn-NO"),
|
||||
Locale.forLanguageTag("nb-NO"));
|
||||
/**
|
||||
* List of candidate locales for zh_Hant
|
||||
*/
|
||||
private static final List<Locale> ZH_HANT_CANDLOCS = List.of(
|
||||
Locale.forLanguageTag("zh-Hant"),
|
||||
Locale.forLanguageTag("zh-TW"),
|
||||
Locale.forLanguageTag("zh"),
|
||||
Locale.ROOT);
|
||||
/**
|
||||
* List of candidate locales for zh_Hans
|
||||
*/
|
||||
private static final List<Locale> ZH_HANS_CANDLOCS = List.of(
|
||||
Locale.forLanguageTag("zh-Hans"),
|
||||
Locale.forLanguageTag("zh-CN"),
|
||||
Locale.forLanguageTag("zh"),
|
||||
Locale.ROOT);
|
||||
|
||||
public static void main(String[] args) {
|
||||
switch (args[0]) {
|
||||
case "testTimeZone":
|
||||
testTimeZoneParsing();
|
||||
break;
|
||||
case "testCldr":
|
||||
testImplicitCldrLocales();
|
||||
break;
|
||||
case "testCache":
|
||||
testDateFormatSymbolsCache();
|
||||
break;
|
||||
case "testCandidateLocales":
|
||||
testCandidateLocales();
|
||||
break;
|
||||
case "testCompat":
|
||||
testImplicitCompatLocales();
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("no test was specified.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that if Locale Provider Preference list is Default, or if Locale
|
||||
* Provider Preference List is COMPAT,CLDR SimplDateFormat parsing works for
|
||||
* all Available Locales.
|
||||
*/
|
||||
private static void testTimeZoneParsing() {
|
||||
Set<Locale> locales = Set.of(Locale.forLanguageTag("zh-hant"), new Locale("no", "NO", "NY"));
|
||||
// Set<Locale> locales = Set.of(Locale.getAvailableLocales());
|
||||
locales.forEach((locale) -> {
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd z", locale);
|
||||
for (final TimeZone tz : new TimeZone[]{REYKJAVIK, GMT, NEW_YORK}) {
|
||||
try {
|
||||
sdf.parse("2000/02/10 " + tz.getDisplayName(locale));
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException("TimeZone Parsing failed with Locale "
|
||||
+ locale + " for TimeZone " + tz.getDisplayName(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that locales implicitly supported from CLDR are reflected in output
|
||||
* from getAvailbleLocales() for each bundle.
|
||||
*
|
||||
*/
|
||||
private static void testImplicitCldrLocales() {
|
||||
LocaleProviderAdapter cldr = LocaleProviderAdapter.forType(Type.CLDR);
|
||||
checkPresenceCldr("CurrencyNameProvider",
|
||||
cldr.getCurrencyNameProvider().getAvailableLocales());
|
||||
checkPresenceCldr("LocaleNameProvider",
|
||||
cldr.getLocaleNameProvider().getAvailableLocales());
|
||||
checkPresenceCldr("TimeZoneNameProvider",
|
||||
cldr.getTimeZoneNameProvider().getAvailableLocales());
|
||||
checkPresenceCldr("CalendarDataProvider",
|
||||
cldr.getCalendarDataProvider().getAvailableLocales());
|
||||
checkPresenceCldr("CalendarNameProvider",
|
||||
cldr.getCalendarProvider().getAvailableLocales());
|
||||
}
|
||||
|
||||
private static void checkPresenceCldr(String testName, Locale[] got) {
|
||||
List<Locale> gotLocalesList = Arrays.asList(got);
|
||||
List<Locale> gotList = new ArrayList<>(gotLocalesList);
|
||||
if (!testName.equals("TimeZoneNameProvider")) {
|
||||
if (!gotList.removeAll(CLDR_IMPLICIT_LOCS)) {
|
||||
// check which locale are not present in retrievedLocales List.
|
||||
List<Locale> expectedLocales = new ArrayList<>(CLDR_IMPLICIT_LOCS);
|
||||
expectedLocales.removeAll(gotList);
|
||||
throw new RuntimeException("Locales those not correctly reflected are "
|
||||
+ expectedLocales + " for test " + testName);
|
||||
}
|
||||
} else {
|
||||
// check one extra locale zh_HK for TimeZoneNameProvider
|
||||
Locale zh_HK = Locale.forLanguageTag("zh-HK");
|
||||
if (!gotList.removeAll(CLDR_IMPLICIT_LOCS) && gotList.remove(zh_HK)) {
|
||||
//check which locale are not present in retrievedLocales List
|
||||
List<Locale> expectedLocales = new ArrayList<>(CLDR_IMPLICIT_LOCS);
|
||||
expectedLocales.add(zh_HK);
|
||||
expectedLocales.removeAll(gotList);
|
||||
throw new RuntimeException("Locales those not correctly reflected are "
|
||||
+ expectedLocales + " for test " + testName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that if Locale Provider Preference list is default and if
|
||||
* SimpleDateFormat instance for th-TH-TH is created first, then JRE bundle
|
||||
* for th-TH should not be cached in cache of DateFormatSymbols class.
|
||||
*/
|
||||
private static void testDateFormatSymbolsCache() {
|
||||
Locale th_TH_TH = new Locale("th", "TH", "TH");
|
||||
Locale th_TH = new Locale("th", "TH");
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd z", th_TH_TH);
|
||||
String[][] thTHTHZoneStrings = sdf.getDateFormatSymbols().getZoneStrings();
|
||||
String[][] thTHZoneStrings = sdf.getDateFormatSymbols().getZoneStrings();
|
||||
if (Arrays.equals(thTHTHZoneStrings, thTHZoneStrings)) {
|
||||
throw new RuntimeException("th_TH bundle still cached with DateFormatSymbols"
|
||||
+ "cache for locale " + th_TH
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that candidate locales list retrieved for zh__Hant and for zh__Hans
|
||||
* do not have first candidate locale as zh_TW_Hant and zh_CN_Hans
|
||||
* respectively.
|
||||
*/
|
||||
private static void testCandidateLocales() {
|
||||
ResourceBundle.Control Control = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
|
||||
Locale zh_Hant = Locale.forLanguageTag("zh-Hant");
|
||||
Locale zh_Hans = Locale.forLanguageTag("zh-Hans");
|
||||
List<Locale> zhHantCandidateLocs = Control.getCandidateLocales("", zh_Hant);
|
||||
List<Locale> zhHansCandidateLocs = Control.getCandidateLocales("", zh_Hans);
|
||||
if (!zhHantCandidateLocs.equals(ZH_HANT_CANDLOCS)) {
|
||||
reportDifference(zhHantCandidateLocs, ZH_HANT_CANDLOCS, "zh_Hant");
|
||||
|
||||
}
|
||||
if (!zhHansCandidateLocs.equals(ZH_HANS_CANDLOCS)) {
|
||||
reportDifference(zhHansCandidateLocs, ZH_HANS_CANDLOCS, "zh_Hans");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void reportDifference(List<Locale> got, List<Locale> expected, String locale) {
|
||||
List<Locale> retrievedList = new ArrayList<>(got);
|
||||
List<Locale> expectedList = new ArrayList<>(expected);
|
||||
retrievedList.removeAll(expectedList);
|
||||
expectedList.removeAll(retrievedList);
|
||||
if ((retrievedList.size() > 0) && (expectedList.size() > 0)) {
|
||||
throw new RuntimeException(" retrievedList contain extra candidate locales " + retrievedList
|
||||
+ " and missing candidate locales " + expectedList
|
||||
+ "for locale " + locale);
|
||||
}
|
||||
if ((retrievedList.size() > 0)) {
|
||||
throw new RuntimeException(" retrievedList contain extra candidate locales " + retrievedList
|
||||
+ "for locale " + locale);
|
||||
}
|
||||
if ((expectedList.size() > 0)) {
|
||||
throw new RuntimeException(" retrievedList contain extra candidate locales " + expectedList
|
||||
+ "for locale " + locale);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* checks that locales nn-NO and nb-NO should be present in list of supported locales for
|
||||
* all Providers for COMPAT.
|
||||
*/
|
||||
private static void testImplicitCompatLocales() {
|
||||
LocaleProviderAdapter jre = LocaleProviderAdapter.forJRE();
|
||||
checkPresenceCompat("BreakIteratorProvider",
|
||||
jre.getBreakIteratorProvider().getAvailableLocales());
|
||||
checkPresenceCompat("CollatorProvider",
|
||||
jre.getCollatorProvider().getAvailableLocales());
|
||||
checkPresenceCompat("DateFormatProvider",
|
||||
jre.getDateFormatProvider().getAvailableLocales());
|
||||
checkPresenceCompat("DateFormatSymbolsProvider",
|
||||
jre.getDateFormatSymbolsProvider().getAvailableLocales());
|
||||
checkPresenceCompat("DecimalFormatSymbolsProvider",
|
||||
jre.getDecimalFormatSymbolsProvider().getAvailableLocales());
|
||||
checkPresenceCompat("NumberFormatProvider",
|
||||
jre.getNumberFormatProvider().getAvailableLocales());
|
||||
checkPresenceCompat("CurrencyNameProvider",
|
||||
jre.getCurrencyNameProvider().getAvailableLocales());
|
||||
checkPresenceCompat("LocaleNameProvider",
|
||||
jre.getLocaleNameProvider().getAvailableLocales());
|
||||
checkPresenceCompat("TimeZoneNameProvider",
|
||||
jre.getTimeZoneNameProvider().getAvailableLocales());
|
||||
checkPresenceCompat("CalendarDataProvider",
|
||||
jre.getCalendarDataProvider().getAvailableLocales());
|
||||
checkPresenceCompat("CalendarNameProvider",
|
||||
jre.getCalendarNameProvider().getAvailableLocales());
|
||||
checkPresenceCompat("CalendarProvider",
|
||||
jre.getCalendarProvider().getAvailableLocales());
|
||||
}
|
||||
|
||||
private static void checkPresenceCompat(String testName, Locale[] got) {
|
||||
List<Locale> gotLocalesList = Arrays.asList(got);
|
||||
List<Locale> gotList = new ArrayList<>(gotLocalesList);
|
||||
if (!gotList.removeAll(COMPAT_IMPLICIT_LOCS)) {
|
||||
// check which Implicit locale are not present in retrievedLocales List.
|
||||
List<Locale> implicitLocales = new ArrayList<>(COMPAT_IMPLICIT_LOCS);
|
||||
implicitLocales.removeAll(gotList);
|
||||
throw new RuntimeException("Locales those not correctly reflected are "
|
||||
+ implicitLocales + " for test " + testName);
|
||||
}
|
||||
}
|
||||
}
|
@ -39,6 +39,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Deque;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@ -368,10 +369,113 @@ public class Collection8Test extends JSR166TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All elements removed in the middle of CONCURRENT traversal.
|
||||
*/
|
||||
public void testElementRemovalDuringTraversal() {
|
||||
Collection c = impl.emptyCollection();
|
||||
ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||
int n = rnd.nextInt(6);
|
||||
ArrayList copy = new ArrayList();
|
||||
for (int i = 0; i < n; i++) {
|
||||
Object x = impl.makeElement(i);
|
||||
copy.add(x);
|
||||
c.add(x);
|
||||
}
|
||||
ArrayList iterated = new ArrayList();
|
||||
ArrayList spliterated = new ArrayList();
|
||||
Spliterator s = c.spliterator();
|
||||
Iterator it = c.iterator();
|
||||
for (int i = rnd.nextInt(n + 1); --i >= 0; ) {
|
||||
assertTrue(s.tryAdvance(spliterated::add));
|
||||
if (rnd.nextBoolean()) assertTrue(it.hasNext());
|
||||
iterated.add(it.next());
|
||||
}
|
||||
Consumer alwaysThrows = e -> { throw new AssertionError(); };
|
||||
if (s.hasCharacteristics(Spliterator.CONCURRENT)) {
|
||||
c.clear(); // TODO: many more removal methods
|
||||
if (testImplementationDetails
|
||||
&& !(c instanceof java.util.concurrent.ArrayBlockingQueue)) {
|
||||
if (rnd.nextBoolean())
|
||||
assertFalse(s.tryAdvance(alwaysThrows));
|
||||
else
|
||||
s.forEachRemaining(alwaysThrows);
|
||||
}
|
||||
if (it.hasNext()) iterated.add(it.next());
|
||||
if (rnd.nextBoolean()) assertIteratorExhausted(it);
|
||||
}
|
||||
assertTrue(copy.containsAll(iterated));
|
||||
assertTrue(copy.containsAll(spliterated));
|
||||
}
|
||||
|
||||
/**
|
||||
* Some elements randomly disappear in the middle of traversal.
|
||||
*/
|
||||
public void testRandomElementRemovalDuringTraversal() {
|
||||
Collection c = impl.emptyCollection();
|
||||
ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||
int n = rnd.nextInt(6);
|
||||
ArrayList copy = new ArrayList();
|
||||
for (int i = 0; i < n; i++) {
|
||||
Object x = impl.makeElement(i);
|
||||
copy.add(x);
|
||||
c.add(x);
|
||||
}
|
||||
ArrayList iterated = new ArrayList();
|
||||
ArrayList spliterated = new ArrayList();
|
||||
ArrayList removed = new ArrayList();
|
||||
Spliterator s = c.spliterator();
|
||||
Iterator it = c.iterator();
|
||||
if (! (s.hasCharacteristics(Spliterator.CONCURRENT) ||
|
||||
s.hasCharacteristics(Spliterator.IMMUTABLE)))
|
||||
return;
|
||||
for (int i = rnd.nextInt(n + 1); --i >= 0; ) {
|
||||
assertTrue(s.tryAdvance(e -> {}));
|
||||
if (rnd.nextBoolean()) assertTrue(it.hasNext());
|
||||
it.next();
|
||||
}
|
||||
Consumer alwaysThrows = e -> { throw new AssertionError(); };
|
||||
// TODO: many more removal methods
|
||||
if (rnd.nextBoolean()) {
|
||||
for (Iterator z = c.iterator(); z.hasNext(); ) {
|
||||
Object e = z.next();
|
||||
if (rnd.nextBoolean()) {
|
||||
try {
|
||||
z.remove();
|
||||
} catch (UnsupportedOperationException ok) { return; }
|
||||
removed.add(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Predicate randomlyRemove = e -> {
|
||||
if (rnd.nextBoolean()) { removed.add(e); return true; }
|
||||
else return false;
|
||||
};
|
||||
c.removeIf(randomlyRemove);
|
||||
}
|
||||
s.forEachRemaining(spliterated::add);
|
||||
while (it.hasNext())
|
||||
iterated.add(it.next());
|
||||
assertTrue(copy.containsAll(iterated));
|
||||
assertTrue(copy.containsAll(spliterated));
|
||||
assertTrue(copy.containsAll(removed));
|
||||
if (s.hasCharacteristics(Spliterator.CONCURRENT)) {
|
||||
ArrayList iteratedAndRemoved = new ArrayList(iterated);
|
||||
ArrayList spliteratedAndRemoved = new ArrayList(spliterated);
|
||||
iteratedAndRemoved.retainAll(removed);
|
||||
spliteratedAndRemoved.retainAll(removed);
|
||||
assertTrue(iteratedAndRemoved.size() <= 1);
|
||||
assertTrue(spliteratedAndRemoved.size() <= 1);
|
||||
if (testImplementationDetails
|
||||
&& !(c instanceof java.util.concurrent.ArrayBlockingQueue))
|
||||
assertTrue(spliteratedAndRemoved.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Various ways of traversing a collection yield same elements
|
||||
*/
|
||||
public void testIteratorEquivalence() {
|
||||
public void testTraversalEquivalence() {
|
||||
Collection c = impl.emptyCollection();
|
||||
ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||
int n = rnd.nextInt(6);
|
||||
@ -438,6 +542,43 @@ public class Collection8Test extends JSR166TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator.forEachRemaining has same behavior as Iterator's
|
||||
* default implementation.
|
||||
*/
|
||||
public void testForEachRemainingConsistentWithDefaultImplementation() {
|
||||
Collection c = impl.emptyCollection();
|
||||
if (!testImplementationDetails
|
||||
|| c.getClass() == java.util.LinkedList.class)
|
||||
return;
|
||||
ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||
int n = 1 + rnd.nextInt(3);
|
||||
for (int i = 0; i < n; i++) c.add(impl.makeElement(i));
|
||||
ArrayList iterated = new ArrayList();
|
||||
ArrayList iteratedForEachRemaining = new ArrayList();
|
||||
Iterator it1 = c.iterator();
|
||||
Iterator it2 = c.iterator();
|
||||
assertTrue(it1.hasNext());
|
||||
assertTrue(it2.hasNext());
|
||||
c.clear();
|
||||
Object r1, r2;
|
||||
try {
|
||||
while (it1.hasNext()) iterated.add(it1.next());
|
||||
r1 = iterated;
|
||||
} catch (ConcurrentModificationException ex) {
|
||||
r1 = ConcurrentModificationException.class;
|
||||
assertFalse(impl.isConcurrent());
|
||||
}
|
||||
try {
|
||||
it2.forEachRemaining(iteratedForEachRemaining::add);
|
||||
r2 = iteratedForEachRemaining;
|
||||
} catch (ConcurrentModificationException ex) {
|
||||
r2 = ConcurrentModificationException.class;
|
||||
assertFalse(impl.isConcurrent());
|
||||
}
|
||||
assertEquals(r1, r2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling Iterator#remove() after Iterator#forEachRemaining
|
||||
* should (maybe) remove last element
|
||||
@ -577,6 +718,41 @@ public class Collection8Test extends JSR166TestCase {
|
||||
assertTrue(found.isEmpty());
|
||||
}
|
||||
|
||||
/** TODO: promote to a common utility */
|
||||
static <T> T chooseOne(T ... ts) {
|
||||
return ts[ThreadLocalRandom.current().nextInt(ts.length)];
|
||||
}
|
||||
|
||||
/** TODO: more random adders and removers */
|
||||
static <E> Runnable adderRemover(Collection<E> c, E e) {
|
||||
return chooseOne(
|
||||
() -> {
|
||||
assertTrue(c.add(e));
|
||||
assertTrue(c.contains(e));
|
||||
assertTrue(c.remove(e));
|
||||
assertFalse(c.contains(e));
|
||||
},
|
||||
() -> {
|
||||
assertTrue(c.add(e));
|
||||
assertTrue(c.contains(e));
|
||||
assertTrue(c.removeIf(x -> x == e));
|
||||
assertFalse(c.contains(e));
|
||||
},
|
||||
() -> {
|
||||
assertTrue(c.add(e));
|
||||
assertTrue(c.contains(e));
|
||||
for (Iterator it = c.iterator();; )
|
||||
if (it.next() == e) {
|
||||
try { it.remove(); }
|
||||
catch (UnsupportedOperationException ok) {
|
||||
c.remove(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
assertFalse(c.contains(e));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Motley crew of threads concurrently randomly hammer the collection.
|
||||
*/
|
||||
@ -616,17 +792,20 @@ public class Collection8Test extends JSR166TestCase {
|
||||
() -> checkArraySanity.accept(c.toArray()),
|
||||
() -> checkArraySanity.accept(c.toArray(emptyArray)),
|
||||
() -> {
|
||||
assertTrue(c.add(one));
|
||||
assertTrue(c.contains(one));
|
||||
assertTrue(c.remove(one));
|
||||
assertFalse(c.contains(one));
|
||||
},
|
||||
() -> {
|
||||
assertTrue(c.add(two));
|
||||
assertTrue(c.contains(two));
|
||||
assertTrue(c.remove(two));
|
||||
assertFalse(c.contains(two));
|
||||
},
|
||||
Object[] a = new Object[5];
|
||||
Object three = impl.makeElement(3);
|
||||
Arrays.fill(a, 0, a.length, three);
|
||||
Object[] x = c.toArray(a);
|
||||
if (x == a)
|
||||
for (int i = 0; i < a.length && a[i] != null; i++)
|
||||
checkSanity.accept(a[i]);
|
||||
// A careful reading of the spec does not support:
|
||||
// for (i++; i < a.length; i++) assertSame(three, a[i]);
|
||||
else
|
||||
checkArraySanity.accept(x);
|
||||
},
|
||||
adderRemover(c, one),
|
||||
adderRemover(c, two),
|
||||
};
|
||||
final List<Runnable> tasks =
|
||||
Arrays.stream(frobbers)
|
||||
@ -684,6 +863,22 @@ public class Collection8Test extends JSR166TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spliterator.getComparator throws IllegalStateException iff the
|
||||
* spliterator does not report SORTED.
|
||||
*/
|
||||
public void testGetComparator_IllegalStateException() {
|
||||
Collection c = impl.emptyCollection();
|
||||
Spliterator s = c.spliterator();
|
||||
boolean reportsSorted = s.hasCharacteristics(Spliterator.SORTED);
|
||||
try {
|
||||
s.getComparator();
|
||||
assertTrue(reportsSorted);
|
||||
} catch (IllegalStateException ex) {
|
||||
assertFalse(reportsSorted);
|
||||
}
|
||||
}
|
||||
|
||||
// public void testCollection8DebugFail() {
|
||||
// fail(impl.klazz().getSimpleName());
|
||||
// }
|
||||
|
@ -35,13 +35,30 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary JSR-166 tck tests
|
||||
* @summary JSR-166 tck tests (conformance testing mode)
|
||||
* @build *
|
||||
* @modules java.management
|
||||
* @run junit/othervm/timeout=1000 JSR166TestCase
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary JSR-166 tck tests (whitebox tests allowed)
|
||||
* @build *
|
||||
* @modules java.base/java.util.concurrent:open
|
||||
* java.management
|
||||
* @build *
|
||||
* @run junit/othervm/timeout=1000 -Djsr166.testImplementationDetails=true JSR166TestCase
|
||||
* @run junit/othervm/timeout=1000 -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 -Djsr166.testImplementationDetails=true JSR166TestCase
|
||||
* @run junit/othervm/timeout=1000 -Djava.util.concurrent.ForkJoinPool.common.parallelism=1 -Djava.util.secureRandomSeed=true JSR166TestCase
|
||||
* @run junit/othervm/timeout=1000
|
||||
* -Djsr166.testImplementationDetails=true
|
||||
* JSR166TestCase
|
||||
* @run junit/othervm/timeout=1000
|
||||
* -Djsr166.testImplementationDetails=true
|
||||
* -Djava.util.concurrent.ForkJoinPool.common.parallelism=0
|
||||
* JSR166TestCase
|
||||
* @run junit/othervm/timeout=1000
|
||||
* -Djsr166.testImplementationDetails=true
|
||||
* -Djava.util.concurrent.ForkJoinPool.common.parallelism=1
|
||||
* -Djava.util.secureRandomSeed=true
|
||||
* JSR166TestCase
|
||||
*/
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
@ -543,6 +560,8 @@ public class JSR166TestCase extends TestCase {
|
||||
"DoubleAdderTest",
|
||||
"ForkJoinPool8Test",
|
||||
"ForkJoinTask8Test",
|
||||
"LinkedBlockingDeque8Test",
|
||||
"LinkedBlockingQueue8Test",
|
||||
"LongAccumulatorTest",
|
||||
"LongAdderTest",
|
||||
"SplittableRandomTest",
|
||||
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* Written by Doug Lea and Martin Buchholz with assistance from
|
||||
* members of JCP JSR-166 Expert Group and released to the public
|
||||
* domain, as explained at
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.Spliterator;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
public class LinkedBlockingDeque8Test extends JSR166TestCase {
|
||||
public static void main(String[] args) {
|
||||
main(suite(), args);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return newTestSuite(LinkedBlockingDeque8Test.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spliterator.getComparator always throws IllegalStateException
|
||||
*/
|
||||
public void testSpliterator_getComparator() {
|
||||
assertThrows(IllegalStateException.class,
|
||||
() -> new LinkedBlockingDeque().spliterator().getComparator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Spliterator characteristics are as advertised
|
||||
*/
|
||||
public void testSpliterator_characteristics() {
|
||||
LinkedBlockingDeque q = new LinkedBlockingDeque();
|
||||
Spliterator s = q.spliterator();
|
||||
int characteristics = s.characteristics();
|
||||
int required = Spliterator.CONCURRENT
|
||||
| Spliterator.NONNULL
|
||||
| Spliterator.ORDERED;
|
||||
assertEquals(required, characteristics & required);
|
||||
assertTrue(s.hasCharacteristics(required));
|
||||
assertEquals(0, characteristics
|
||||
& (Spliterator.DISTINCT
|
||||
| Spliterator.IMMUTABLE
|
||||
| Spliterator.SORTED));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* Written by Doug Lea and Martin Buchholz with assistance from
|
||||
* members of JCP JSR-166 Expert Group and released to the public
|
||||
* domain, as explained at
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.Spliterator;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
public class LinkedBlockingQueue8Test extends JSR166TestCase {
|
||||
public static void main(String[] args) {
|
||||
main(suite(), args);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return newTestSuite(LinkedBlockingQueue8Test.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spliterator.getComparator always throws IllegalStateException
|
||||
*/
|
||||
public void testSpliterator_getComparator() {
|
||||
assertThrows(IllegalStateException.class,
|
||||
() -> new LinkedBlockingQueue().spliterator().getComparator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Spliterator characteristics are as advertised
|
||||
*/
|
||||
public void testSpliterator_characteristics() {
|
||||
LinkedBlockingQueue q = new LinkedBlockingQueue();
|
||||
Spliterator s = q.spliterator();
|
||||
int characteristics = s.characteristics();
|
||||
int required = Spliterator.CONCURRENT
|
||||
| Spliterator.NONNULL
|
||||
| Spliterator.ORDERED;
|
||||
assertEquals(required, characteristics & required);
|
||||
assertTrue(s.hasCharacteristics(required));
|
||||
assertEquals(0, characteristics
|
||||
& (Spliterator.DISTINCT
|
||||
| Spliterator.IMMUTABLE
|
||||
| Spliterator.SORTED));
|
||||
}
|
||||
|
||||
}
|
@ -71,9 +71,9 @@ public class ScheduledExecutorSubclassTest extends JSR166TestCase {
|
||||
}
|
||||
|
||||
static class CustomTask<V> implements RunnableScheduledFuture<V> {
|
||||
RunnableScheduledFuture<V> task;
|
||||
private final RunnableScheduledFuture<V> task;
|
||||
volatile boolean ran;
|
||||
CustomTask(RunnableScheduledFuture<V> t) { task = t; }
|
||||
CustomTask(RunnableScheduledFuture<V> task) { this.task = task; }
|
||||
public boolean isPeriodic() { return task.isPeriodic(); }
|
||||
public void run() {
|
||||
ran = true;
|
||||
|
@ -402,6 +402,7 @@ public class SubmissionPublisherTest extends JSR166TestCase {
|
||||
|
||||
/**
|
||||
* Closing a publisher exceptionally causes onError to subscribers
|
||||
* after they are subscribed
|
||||
*/
|
||||
public void testCloseExceptionallyError() {
|
||||
SubmissionPublisher<Integer> p = basicPublisher();
|
||||
@ -412,9 +413,11 @@ public class SubmissionPublisherTest extends JSR166TestCase {
|
||||
p.submit(1);
|
||||
p.closeExceptionally(new SPException());
|
||||
assertTrue(p.isClosed());
|
||||
s1.awaitSubscribe();
|
||||
s1.awaitError();
|
||||
assertTrue(s1.nexts <= 1);
|
||||
assertEquals(1, s1.errors);
|
||||
s2.awaitSubscribe();
|
||||
s2.awaitError();
|
||||
assertTrue(s2.nexts <= 1);
|
||||
assertEquals(1, s2.errors);
|
||||
|
@ -85,32 +85,41 @@ public class ThreadLocalRandomTest extends JSR166TestCase {
|
||||
*/
|
||||
public void testNext() throws ReflectiveOperationException {
|
||||
ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||
final java.lang.reflect.Method m;
|
||||
try {
|
||||
java.lang.reflect.Method m
|
||||
= ThreadLocalRandom.class.getDeclaredMethod(
|
||||
m = ThreadLocalRandom.class.getDeclaredMethod(
|
||||
"next", new Class[] { int.class });
|
||||
m.setAccessible(true);
|
||||
} catch (SecurityException acceptable) {
|
||||
// Security manager may deny access
|
||||
return;
|
||||
} catch (Exception ex) {
|
||||
// jdk9 module system may deny access
|
||||
if (ex.getClass().getSimpleName()
|
||||
.equals("InaccessibleObjectException"))
|
||||
return;
|
||||
throw ex;
|
||||
}
|
||||
|
||||
int i;
|
||||
{
|
||||
int val = new java.util.Random().nextInt(4);
|
||||
for (i = 0; i < NCALLS; i++) {
|
||||
int q = (int) m.invoke(rnd, new Object[] { 2 });
|
||||
if (val == q) break;
|
||||
}
|
||||
assertTrue(i < NCALLS);
|
||||
int i;
|
||||
{
|
||||
int val = new java.util.Random().nextInt(4);
|
||||
for (i = 0; i < NCALLS; i++) {
|
||||
int q = (int) m.invoke(rnd, new Object[] { 2 });
|
||||
if (val == q) break;
|
||||
}
|
||||
assertTrue(i < NCALLS);
|
||||
}
|
||||
|
||||
{
|
||||
int r = (int) m.invoke(rnd, new Object[] { 3 });
|
||||
for (i = 0; i < NCALLS; i++) {
|
||||
int q = (int) m.invoke(rnd, new Object[] { 3 });
|
||||
assertTrue(q < (1<<3));
|
||||
if (r != q) break;
|
||||
}
|
||||
assertTrue(i < NCALLS);
|
||||
{
|
||||
int r = (int) m.invoke(rnd, new Object[] { 3 });
|
||||
for (i = 0; i < NCALLS; i++) {
|
||||
int q = (int) m.invoke(rnd, new Object[] { 3 });
|
||||
assertTrue(q < (1<<3));
|
||||
if (r != q) break;
|
||||
}
|
||||
} catch (SecurityException acceptable) {}
|
||||
assertTrue(i < NCALLS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,9 +58,22 @@ public class VectorTest extends JSR166TestCase {
|
||||
}
|
||||
}
|
||||
return newTestSuite(
|
||||
// VectorTest.class,
|
||||
VectorTest.class,
|
||||
CollectionTest.testSuite(new Implementation()),
|
||||
CollectionTest.testSuite(new SubListImplementation()));
|
||||
}
|
||||
|
||||
/**
|
||||
* tests for setSize()
|
||||
*/
|
||||
public void testSetSize() {
|
||||
Vector v = new Vector();
|
||||
for (int n : new int[] { 100, 5, 50 }) {
|
||||
v.setSize(n);
|
||||
assertEquals(n, v.size());
|
||||
assertNull(v.get(0));
|
||||
assertNull(v.get(n - 1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -175,6 +175,13 @@ public class SSLSocketTemplate {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure the server side socket.
|
||||
*/
|
||||
protected void configureServerSocket(SSLServerSocket socket) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* =============================================
|
||||
* Define the client and server side operations.
|
||||
@ -211,6 +218,7 @@ public class SSLSocketTemplate {
|
||||
SSLServerSocketFactory sslssf = context.getServerSocketFactory();
|
||||
SSLServerSocket sslServerSocket =
|
||||
(SSLServerSocket)sslssf.createServerSocket(serverPort);
|
||||
configureServerSocket(sslServerSocket);
|
||||
serverPort = sslServerSocket.getLocalPort();
|
||||
|
||||
// Signal the client, the server is ready to accept connection.
|
||||
|
@ -23,11 +23,11 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4847375
|
||||
* @bug 4847375 8171363
|
||||
* @summary JFileChooser Create New Folder button is disabled incorrectly
|
||||
* @author Pavel Porvatov
|
||||
* @modules java.desktop/sun.awt
|
||||
* java.desktop/sun.awt.shell
|
||||
* java.desktop/sun.awt.shell:+open
|
||||
*/
|
||||
|
||||
import sun.awt.OSInfo;
|
||||
|
@ -22,11 +22,11 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 6741890
|
||||
@bug 6741890 8171363
|
||||
@summary Deadlock in Win32ShellFolderManager2
|
||||
@author Pavel Porvatov
|
||||
@modules java.desktop/sun.awt
|
||||
java.desktop/sun.awt.shell
|
||||
java.desktop/sun.awt.shell:+open
|
||||
@run main bug6741890
|
||||
*/
|
||||
|
||||
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8074883
|
||||
* @summary Tab key should move to focused button in a button group
|
||||
* @run main ButtonGroupFocusTest
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
public class ButtonGroupFocusTest {
|
||||
|
||||
private static JRadioButton button1;
|
||||
private static JRadioButton button2;
|
||||
private static JRadioButton button3;
|
||||
private static JRadioButton button4;
|
||||
private static JRadioButton button5;
|
||||
private static Robot robot;
|
||||
private static JFrame frame;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
robot.setAutoDelay(100);
|
||||
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
frame = new JFrame();
|
||||
Container contentPane = frame.getContentPane();
|
||||
contentPane.setLayout(new FlowLayout());
|
||||
button1 = new JRadioButton("Button 1");
|
||||
contentPane.add(button1);
|
||||
button2 = new JRadioButton("Button 2");
|
||||
contentPane.add(button2);
|
||||
button3 = new JRadioButton("Button 3");
|
||||
contentPane.add(button3);
|
||||
button4 = new JRadioButton("Button 4");
|
||||
contentPane.add(button4);
|
||||
button5 = new JRadioButton("Button 5");
|
||||
contentPane.add(button5);
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
group.add(button1);
|
||||
group.add(button2);
|
||||
group.add(button3);
|
||||
|
||||
group = new ButtonGroup();
|
||||
group.add(button4);
|
||||
group.add(button5);
|
||||
|
||||
button2.setSelected(true);
|
||||
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
});
|
||||
|
||||
robot.waitForIdle();
|
||||
robot.delay(200);
|
||||
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
if( !button2.hasFocus() ) {
|
||||
frame.dispose();
|
||||
throw new RuntimeException(
|
||||
"Button 2 should get focus after activation");
|
||||
}
|
||||
});
|
||||
|
||||
robot.keyPress(KeyEvent.VK_TAB);
|
||||
robot.keyRelease(KeyEvent.VK_TAB);
|
||||
|
||||
robot.waitForIdle();
|
||||
robot.delay(200);
|
||||
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
if( !button4.hasFocus() ) {
|
||||
frame.dispose();
|
||||
throw new RuntimeException(
|
||||
"Button 4 should get focus");
|
||||
}
|
||||
button3.setSelected(true);
|
||||
});
|
||||
|
||||
robot.keyPress(KeyEvent.VK_TAB);
|
||||
robot.keyRelease(KeyEvent.VK_TAB);
|
||||
|
||||
robot.waitForIdle();
|
||||
robot.delay(200);
|
||||
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
if( !button3.hasFocus() ) {
|
||||
frame.dispose();
|
||||
throw new RuntimeException(
|
||||
"selected Button 3 should get focus");
|
||||
}
|
||||
});
|
||||
|
||||
SwingUtilities.invokeLater(frame::dispose);
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary JavaVM
|
||||
* @build TestLibrary REGISTRY RegistryRunner
|
||||
* @run main/othervm DeadCachedConnection
|
||||
*/
|
||||
|
||||
@ -60,73 +60,65 @@ import java.rmi.registry.*;
|
||||
import java.rmi.server.*;
|
||||
|
||||
public class DeadCachedConnection {
|
||||
static public final int regport = TestLibrary.getUnusedRandomPort();
|
||||
|
||||
static public void main(String[] argv)
|
||||
throws Exception {
|
||||
// establish the registry (we hope)
|
||||
System.err.println ("Starting registry on port " + regport);
|
||||
DeadCachedConnection.makeRegistry(regport);
|
||||
|
||||
// Get a handle to the registry
|
||||
Registry reg = null;
|
||||
System.err.println ("Locating just-started registry...");
|
||||
try {
|
||||
reg = LocateRegistry.getRegistry(regport);
|
||||
} catch (RemoteException e) {
|
||||
throw new InternalError ("Can't find registry after starting it.");
|
||||
}
|
||||
Registry reg = null;
|
||||
int port = makeRegistry(0);
|
||||
|
||||
// Contact the registry by invoking something on it.
|
||||
System.err.println ("Connecting to registry...");
|
||||
String[] junk = reg.list();
|
||||
// Get a handle to the registry
|
||||
System.err.println ("Locating just-started registry...");
|
||||
try {
|
||||
reg = LocateRegistry.getRegistry(port);
|
||||
} catch (RemoteException e) {
|
||||
throw new InternalError ("Can't find registry after starting it.");
|
||||
}
|
||||
|
||||
// Kill and restart the registry
|
||||
System.err.println("Killing registry...");
|
||||
DeadCachedConnection.killRegistry();
|
||||
System.err.println("Restarting registry...");
|
||||
DeadCachedConnection.makeRegistry(regport);
|
||||
// Contact the registry by invoking something on it.
|
||||
System.err.println ("Connecting to registry...");
|
||||
String[] junk = reg.list();
|
||||
|
||||
// Try again (this is the test)
|
||||
System.err.println("Trying to use registry in spite of stale cache...");
|
||||
junk = reg.list();
|
||||
// Kill and restart the registry
|
||||
System.err.println("Killing registry...");
|
||||
killRegistry();
|
||||
System.err.println("Restarting registry...");
|
||||
makeRegistry(port);
|
||||
|
||||
// we're happy
|
||||
System.err.println("Test succeeded.");
|
||||
try {
|
||||
DeadCachedConnection.killRegistry();
|
||||
} catch (Exception foo) {
|
||||
// Try again (this is the test)
|
||||
System.err.println("Trying to use registry in spite of stale cache...");
|
||||
junk = reg.list();
|
||||
|
||||
System.err.println("Test succeeded.");
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb(e);
|
||||
} finally {
|
||||
// dont leave the registry around to affect other tests.
|
||||
killRegistry();
|
||||
}
|
||||
}
|
||||
|
||||
public static void makeRegistry(int p) {
|
||||
// sadly, we can't kill a registry if we have too-close control
|
||||
// over it. We must make it in a subprocess, and then kill the
|
||||
// subprocess when it has served our needs.
|
||||
|
||||
public static int makeRegistry(int port) {
|
||||
try {
|
||||
JavaVM jvm =
|
||||
new JavaVM("sun.rmi.registry.RegistryImpl", "", Integer.toString(p));
|
||||
jvm.start();
|
||||
DeadCachedConnection.subreg = jvm;
|
||||
|
||||
subreg = REGISTRY.createREGISTRY(System.out, System.err, "", port);
|
||||
subreg.start();
|
||||
int regPort = subreg.getPort();
|
||||
System.out.println("Starting registry on port " + regPort);
|
||||
return regPort;
|
||||
} catch (IOException e) {
|
||||
// one of these is summarily dropped, can't remember which one
|
||||
System.out.println ("Test setup failed - cannot run rmiregistry");
|
||||
TestLibrary.bomb("Test setup failed - cannot run test", e);
|
||||
}
|
||||
// Slop - wait for registry to come up. This is stupid.
|
||||
try {
|
||||
Thread.sleep (5000);
|
||||
} catch (Exception whatever) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
private static JavaVM subreg = null;
|
||||
|
||||
private static REGISTRY subreg = null;
|
||||
|
||||
public static void killRegistry() throws InterruptedException {
|
||||
if (DeadCachedConnection.subreg != null) {
|
||||
DeadCachedConnection.subreg.terminate();
|
||||
if (subreg != null) {
|
||||
subreg.shutdown();
|
||||
subreg = null;
|
||||
}
|
||||
DeadCachedConnection.subreg = null;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,6 +32,7 @@
|
||||
* @test
|
||||
* @bug 7113275 8164846
|
||||
* @summary compatibility issue with MD2 trust anchor and old X509TrustManager
|
||||
* @library /javax/net/ssl/templates
|
||||
* @run main/othervm TrustTrustedCert PKIX TLSv1.1 true
|
||||
* @run main/othervm TrustTrustedCert PKIX TLSv1.1 false
|
||||
* @run main/othervm TrustTrustedCert SunX509 TLSv1.1 false
|
||||
@ -40,7 +41,6 @@
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import javax.net.ssl.*;
|
||||
import java.security.*;
|
||||
@ -49,21 +49,7 @@ import java.security.spec.*;
|
||||
import java.security.interfaces.*;
|
||||
import java.util.Base64;
|
||||
|
||||
|
||||
public class TrustTrustedCert {
|
||||
|
||||
/*
|
||||
* =============================================================
|
||||
* Set the various variables needed for the tests, then
|
||||
* specify what tests to run on each side.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Should we run the client or server in a separate thread?
|
||||
* Both sides can throw exceptions, but do you have a preference
|
||||
* as to which side should be the main thread.
|
||||
*/
|
||||
static boolean separateServerThread = false;
|
||||
public class TrustTrustedCert extends SSLSocketTemplate {
|
||||
|
||||
/*
|
||||
* Certificates and key used in the test.
|
||||
@ -124,89 +110,61 @@ public class TrustTrustedCert {
|
||||
"A5kokFb+E3Gplu29tJvCUpfwgBFRS+wmkvtiaU/tiyDcVgDO+An5DwedxxdVzqiE\n" +
|
||||
"njWHoKY3axDQ8OU=\n";
|
||||
|
||||
|
||||
static char passphrase[] = "passphrase".toCharArray();
|
||||
|
||||
/*
|
||||
* Is the server ready to serve?
|
||||
*/
|
||||
volatile static boolean serverReady = false;
|
||||
|
||||
/*
|
||||
* Turn on SSL debugging?
|
||||
*/
|
||||
static boolean debug = false;
|
||||
|
||||
/*
|
||||
* Define the server side of the test.
|
||||
*
|
||||
* If the server prematurely exits, serverReady will be set to true
|
||||
* to avoid infinite hangs.
|
||||
*/
|
||||
void doServerSide() throws Exception {
|
||||
SSLContext context = generateSSLContext();
|
||||
SSLServerSocketFactory sslssf = context.getServerSocketFactory();
|
||||
SSLServerSocket sslServerSocket =
|
||||
(SSLServerSocket)sslssf.createServerSocket(serverPort);
|
||||
sslServerSocket.setNeedClientAuth(true);
|
||||
serverPort = sslServerSocket.getLocalPort();
|
||||
|
||||
/*
|
||||
* Signal Client, we're ready for his connect.
|
||||
*/
|
||||
serverReady = true;
|
||||
|
||||
SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();
|
||||
InputStream sslIS = sslSocket.getInputStream();
|
||||
OutputStream sslOS = sslSocket.getOutputStream();
|
||||
|
||||
sslIS.read();
|
||||
sslOS.write('A');
|
||||
sslOS.flush();
|
||||
|
||||
sslSocket.close();
|
||||
@Override
|
||||
protected SSLContext createServerSSLContext() throws Exception {
|
||||
return generateSSLContext();
|
||||
}
|
||||
|
||||
/*
|
||||
* Define the client side of the test.
|
||||
*
|
||||
* If the server prematurely exits, serverReady will be set to true
|
||||
* to avoid infinite hangs.
|
||||
*/
|
||||
void doClientSide() throws Exception {
|
||||
@Override
|
||||
protected void configureServerSocket(SSLServerSocket socket) {
|
||||
socket.setNeedClientAuth(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for server to get started.
|
||||
*/
|
||||
while (!serverReady) {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
@Override
|
||||
protected void runServerApplication(SSLSocket socket) throws Exception {
|
||||
InputStream sslIS = socket.getInputStream();
|
||||
OutputStream sslOS = socket.getOutputStream();
|
||||
|
||||
SSLSocket sslSocket = null;
|
||||
try {
|
||||
SSLContext context = generateSSLContext();
|
||||
SSLSocketFactory sslsf = context.getSocketFactory();
|
||||
sslIS.read();
|
||||
sslOS.write('A');
|
||||
sslOS.flush();
|
||||
} catch (SSLHandshakeException e) {
|
||||
if (expectFail && !e.toString().contains("certificate_unknown")) {
|
||||
throw new RuntimeException(
|
||||
"Expected to see certificate_unknown in exception output",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sslSocket = (SSLSocket)sslsf.createSocket("localhost", serverPort);
|
||||
@Override
|
||||
protected SSLContext createClientSSLContext() throws Exception {
|
||||
return generateSSLContext();
|
||||
}
|
||||
|
||||
// enable the specified TLS protocol
|
||||
sslSocket.setEnabledProtocols(new String[] {tlsProtocol});
|
||||
@Override
|
||||
protected void runClientApplication(SSLSocket socket) throws Exception {
|
||||
// enable the specified TLS protocol
|
||||
socket.setEnabledProtocols(new String[] { tlsProtocol });
|
||||
|
||||
InputStream sslIS = sslSocket.getInputStream();
|
||||
OutputStream sslOS = sslSocket.getOutputStream();
|
||||
InputStream sslIS = socket.getInputStream();
|
||||
OutputStream sslOS = socket.getOutputStream();
|
||||
|
||||
try {
|
||||
sslOS.write('B');
|
||||
sslOS.flush();
|
||||
sslIS.read();
|
||||
} catch (SSLHandshakeException e) {
|
||||
// focus in on the CertPathValidatorException
|
||||
// focus on the CertPathValidatorException
|
||||
Throwable t = e.getCause().getCause();
|
||||
if ((t == null) || (expectFail &&
|
||||
!t.toString().contains("MD5withRSA"))) {
|
||||
if ((t == null)
|
||||
|| (expectFail && !t.toString().contains("MD5withRSA"))) {
|
||||
throw new RuntimeException(
|
||||
"Expected to see MD5withRSA in exception output " + t);
|
||||
"Expected to see MD5withRSA in exception output", t);
|
||||
}
|
||||
} finally {
|
||||
if (sslSocket != null) sslSocket.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,13 +301,6 @@ public class TrustTrustedCert {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// use any free port by default
|
||||
volatile int serverPort = 0;
|
||||
|
||||
volatile Exception serverException = null;
|
||||
volatile Exception clientException = null;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
/*
|
||||
* Get the customized arguments.
|
||||
@ -367,144 +318,9 @@ public class TrustTrustedCert {
|
||||
Security.setProperty("jdk.tls.disabledAlgorithms",
|
||||
"SSLv3, RC4, DH keySize < 768");
|
||||
|
||||
if (debug)
|
||||
System.setProperty("javax.net.debug", "all");
|
||||
|
||||
/*
|
||||
* Start the tests.
|
||||
*/
|
||||
new TrustTrustedCert();
|
||||
}
|
||||
|
||||
Thread clientThread = null;
|
||||
Thread serverThread = null;
|
||||
|
||||
/*
|
||||
* Primary constructor, used to drive remainder of the test.
|
||||
*
|
||||
* Fork off the other side, then do your work.
|
||||
*/
|
||||
TrustTrustedCert() throws Exception {
|
||||
try {
|
||||
if (separateServerThread) {
|
||||
startServer(true);
|
||||
startClient(false);
|
||||
} else {
|
||||
startClient(true);
|
||||
startServer(false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Unexpected exception: ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for other side to close down.
|
||||
*/
|
||||
if (separateServerThread) {
|
||||
serverThread.join();
|
||||
} else {
|
||||
clientThread.join();
|
||||
}
|
||||
|
||||
/*
|
||||
* When we get here, the test is pretty much over.
|
||||
* Which side threw the error?
|
||||
*/
|
||||
Exception local;
|
||||
Exception remote;
|
||||
String whichRemote;
|
||||
|
||||
if (separateServerThread) {
|
||||
remote = serverException;
|
||||
local = clientException;
|
||||
whichRemote = "server";
|
||||
} else {
|
||||
remote = clientException;
|
||||
local = serverException;
|
||||
whichRemote = "client";
|
||||
}
|
||||
|
||||
/*
|
||||
* If both failed, return the curthread's exception, but also
|
||||
* print the remote side Exception
|
||||
*/
|
||||
if ((local != null) && (remote != null)) {
|
||||
System.out.println(whichRemote + " also threw:");
|
||||
remote.printStackTrace();
|
||||
System.out.println();
|
||||
throw local;
|
||||
}
|
||||
|
||||
if (remote != null) {
|
||||
throw remote;
|
||||
}
|
||||
|
||||
if (local != null) {
|
||||
throw local;
|
||||
}
|
||||
}
|
||||
|
||||
void startServer(boolean newThread) throws Exception {
|
||||
if (newThread) {
|
||||
serverThread = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
doServerSide();
|
||||
} catch (Exception e) {
|
||||
/*
|
||||
* Our server thread just died.
|
||||
*
|
||||
* Release the client, if not active already...
|
||||
*/
|
||||
System.err.println("Server died...");
|
||||
serverReady = true;
|
||||
if (!expectFail) {
|
||||
// only record if we weren't expecting.
|
||||
// client side will record exception
|
||||
serverException = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
serverThread.start();
|
||||
} else {
|
||||
try {
|
||||
doServerSide();
|
||||
} catch (Exception e) {
|
||||
// only record if we weren't expecting.
|
||||
// client side will record exception
|
||||
if (!expectFail) {
|
||||
serverException = e;
|
||||
}
|
||||
} finally {
|
||||
serverReady = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void startClient(boolean newThread) throws Exception {
|
||||
if (newThread) {
|
||||
clientThread = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
doClientSide();
|
||||
} catch (Exception e) {
|
||||
/*
|
||||
* Our client thread just died.
|
||||
*/
|
||||
System.err.println("Client died...");
|
||||
clientException = e;
|
||||
}
|
||||
}
|
||||
};
|
||||
clientThread.start();
|
||||
} else {
|
||||
try {
|
||||
doClientSide();
|
||||
} catch (Exception e) {
|
||||
clientException = e;
|
||||
}
|
||||
}
|
||||
new TrustTrustedCert().run();
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8038436 8158504 8065555
|
||||
* @bug 8038436 8158504 8065555 8167143
|
||||
* @summary Test for changes in 8038436
|
||||
* @modules java.base/sun.util.locale.provider
|
||||
* java.base/sun.util.spi
|
||||
@ -120,7 +120,7 @@ public class Bug8038436 {
|
||||
"fi, fi-FI, fr, fr-BE, fr-CA, fr-CH, fr-FR, ga, ga-IE, he, he-IL, " +
|
||||
"hi-IN, hr, hr-HR, hu, hu-HU, id, id-ID, is, is-IS, it, it-CH, it-IT, " +
|
||||
"ja, ja-JP, ko, ko-KR, lt, lt-LT, lv, lv-LV, mk, mk-MK, ms, ms-MY, mt, " +
|
||||
"mt-MT, nl, nl-BE, nl-NL, no, no-NO, no-NO, pl, pl-PL, pt, pt-BR, " +
|
||||
"mt-MT, nb-NO, nl, nl-BE, nl-NL, nn-NO, no, no-NO, no-NO, pl, pl-PL, pt, pt-BR, " +
|
||||
"pt-PT, ro, ro-RO, ru, ru-RU, sk, sk-SK, sl, sl-SI, sq, sq-AL, sr, " +
|
||||
"sr-BA, sr-CS, sr-Latn, sr-Latn-ME, sr-ME, sr-RS, sv, sv-SE, th, th-TH, " +
|
||||
"tr, tr-TR, uk, uk-UA, und, vi, vi-VN, zh, zh-CN, zh-HK, zh-Hans-CN, " +
|
||||
@ -130,7 +130,7 @@ public class Bug8038436 {
|
||||
static final String[] decimalfspLocs = bipLocs;
|
||||
static final String[] calnpLocs = bipLocs;
|
||||
static final String[] cpLocs = ("ar, be, bg, ca, cs, da, el, es, et, fi, " +
|
||||
"fr, he, hi, hr, hu, is, ja, ko, lt, lv, mk, no, pl, ro, ru, sk, sl, " +
|
||||
"fr, he, hi, hr, hu, is, ja, ko, lt, lv, mk, nb-NO, nn-NO, no, pl, ro, ru, sk, sl, " +
|
||||
"sq, sr, sr-Latn, sv, th, tr, uk, und, vi, zh, zh-HK, zh-Hant-HK, " +
|
||||
"zh-Hant-TW, zh-TW, ").split(",\\s*");
|
||||
static final String[] nfpLocs = ("ar, ar-AE, ar-BH, ar-DZ, ar-EG, ar-IQ, " +
|
||||
@ -160,22 +160,22 @@ public class Bug8038436 {
|
||||
"es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, et-EE, fi-FI, " +
|
||||
"fr, fr-BE, fr-CA, fr-CH, fr-FR, fr-LU, ga-IE, he-IL, hi-IN, hr-HR, " +
|
||||
"hu-HU, id-ID, is-IS, it, it-CH, it-IT, ja, ja-JP, ko, ko-KR, lt-LT, " +
|
||||
"lv-LV, mk-MK, ms-MY, mt-MT, nl-BE, nl-NL, no-NO, pl-PL, pt, pt-BR, " +
|
||||
"lv-LV, mk-MK, ms-MY, mt-MT, nb-NO, nl-BE, nl-NL, nn-NO, no-NO, pl-PL, pt, pt-BR, " +
|
||||
"pt-PT, ro-RO, ru-RU, sk-SK, sl-SI, sq-AL, sr-BA, sr-CS, sr-Latn-BA, " +
|
||||
"sr-Latn-ME, sr-Latn-RS, sr-ME, sr-RS, sv, sv-SE, th-TH, tr-TR, uk-UA, " +
|
||||
"und, vi-VN, zh-CN, zh-HK, zh-Hans-CN, zh-Hans-SG, zh-Hant-HK, " +
|
||||
"zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
|
||||
static final String[] lnpLocs = ("ar, be, bg, ca, cs, da, de, el, el-CY, " +
|
||||
"en, en-MT, en-PH, en-SG, es, es-US, et, fi, fr, ga, he, hi, hr, hu, " +
|
||||
"id, is, it, ja, ko, lt, lv, mk, ms, mt, nl, no, no-NO, pl, pt, pt-BR, " +
|
||||
"id, is, it, ja, ko, lt, lv, mk, ms, mt, nb-NO, nl, nn-NO, no, no-NO, pl, pt, pt-BR, " +
|
||||
"pt-PT, ro, ru, sk, sl, sq, sr, sr-Latn, sv, th, tr, uk, und, vi, zh, " +
|
||||
"zh-HK, zh-Hans-SG, zh-Hant-HK, zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
|
||||
static final String[] tznpLocs = ("de, en, en-CA, en-GB, en-IE, es, fr, hi, " +
|
||||
"it, ja, ko, pt-BR, sv, und, zh-CN, zh-HK, zh-Hans-CN, zh-Hant-HK, " +
|
||||
"it, ja, ko, nb-NO, nn-NO, pt-BR, sv, und, zh-CN, zh-HK, zh-Hans-CN, zh-Hant-HK, " +
|
||||
"zh-Hant-TW, zh-TW, ").split(",\\s*");
|
||||
static final String[] caldpLocs = ("ar, be, bg, ca, cs, da, de, el, el-CY, " +
|
||||
"en, en-GB, en-IE, en-MT, es, es-ES, es-US, et, fi, fr, fr-CA, he, hi, " +
|
||||
"hr, hu, id-ID, is, it, ja, ko, lt, lv, mk, ms-MY, mt, mt-MT, nl, no, " +
|
||||
"hr, hu, id-ID, is, it, ja, ko, lt, lv, mk, ms-MY, mt, mt-MT, nb-NO, nl, nn-NO, no, " +
|
||||
"pl, pt, pt-BR, pt-PT, ro, ru, sk, sl, sq, sr, sr-Latn-BA, sr-Latn-ME, " +
|
||||
"sr-Latn-RS, sv, th, tr, uk, und, vi, zh, ").split(",\\s*");
|
||||
static final String[] calpLocs = caldpLocs;
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8142968 8166568
|
||||
* @bug 8142968 8166568 8166286 8170618
|
||||
* @summary Basic test for jmod
|
||||
* @library /lib/testlibrary
|
||||
* @modules jdk.compiler
|
||||
@ -114,6 +114,27 @@ public class JmodTest {
|
||||
.assertSuccess();
|
||||
}
|
||||
|
||||
// JDK-8170618 - jmod should validate if any exported or open package is missing
|
||||
@Test
|
||||
public void testMissingPackages() throws IOException {
|
||||
Path apaDir = EXPLODED_DIR.resolve("apa");
|
||||
Path classesDir = EXPLODED_DIR.resolve("apa").resolve("classes");
|
||||
if (Files.exists(classesDir))
|
||||
FileUtils.deleteFileTreeWithRetry(classesDir);
|
||||
assertTrue(compileModule("apa", classesDir));
|
||||
FileUtils.deleteFileTreeWithRetry(classesDir.resolve("jdk"));
|
||||
Path jmod = MODS_DIR.resolve("apa.jmod");
|
||||
jmod("create",
|
||||
"--class-path", classesDir.toString(),
|
||||
jmod.toString())
|
||||
.assertFailure()
|
||||
.resultChecker(r -> {
|
||||
assertContains(r.output, "Packages that are exported or open in apa are not present: [jdk.test.apa]");
|
||||
});
|
||||
if (Files.exists(classesDir))
|
||||
FileUtils.deleteFileTreeWithRetry(classesDir);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testList() throws IOException {
|
||||
String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
|
||||
|
Loading…
Reference in New Issue
Block a user