Merge
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,6 @@
|
||||
|
||||
SUNWprivate_1.1 {
|
||||
global:
|
||||
Java_com_sun_security_auth_module_SolarisSystem_getSolarisInfo;
|
||||
Java_com_sun_security_auth_module_UnixSystem_getUnixInfo;
|
||||
local:
|
||||
*;
|
||||
|
@ -24,7 +24,8 @@
|
||||
*/
|
||||
|
||||
package java.io;
|
||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
/**
|
||||
* A <code>BufferedInputStream</code> adds
|
||||
@ -60,23 +61,28 @@ class BufferedInputStream extends FilterInputStream {
|
||||
*/
|
||||
private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
|
||||
|
||||
/**
|
||||
* As this class is used early during bootstrap, it's motivated to use
|
||||
* Unsafe.compareAndSetObject instead of AtomicReferenceFieldUpdater
|
||||
* (or VarHandles) to reduce dependencies and improve startup time.
|
||||
*/
|
||||
private static final Unsafe U = Unsafe.getUnsafe();
|
||||
|
||||
private static final long BUF_OFFSET
|
||||
= U.objectFieldOffset(BufferedInputStream.class, "buf");
|
||||
|
||||
/**
|
||||
* The internal buffer array where the data is stored. When necessary,
|
||||
* it may be replaced by another array of
|
||||
* a different size.
|
||||
*/
|
||||
protected volatile byte buf[];
|
||||
|
||||
/**
|
||||
* Atomic updater to provide compareAndSet for buf. This is
|
||||
* necessary because closes can be asynchronous. We use nullness
|
||||
* of buf[] as primary indicator that this stream is closed. (The
|
||||
* "in" field is also nulled out on close.)
|
||||
/*
|
||||
* We null this out with a CAS on close(), which is necessary since
|
||||
* closes can be asynchronous. We use nullness of buf[] as primary
|
||||
* indicator that this stream is closed. (The "in" field is also
|
||||
* nulled out on close.)
|
||||
*/
|
||||
private static final
|
||||
AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> bufUpdater =
|
||||
AtomicReferenceFieldUpdater.newUpdater
|
||||
(BufferedInputStream.class, byte[].class, "buf");
|
||||
protected volatile byte[] buf;
|
||||
|
||||
/**
|
||||
* The index one greater than the index of the last valid byte in
|
||||
@ -230,9 +236,9 @@ class BufferedInputStream extends FilterInputStream {
|
||||
pos * 2 : MAX_BUFFER_SIZE;
|
||||
if (nsz > marklimit)
|
||||
nsz = marklimit;
|
||||
byte nbuf[] = new byte[nsz];
|
||||
byte[] nbuf = new byte[nsz];
|
||||
System.arraycopy(buffer, 0, nbuf, 0, pos);
|
||||
if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {
|
||||
if (!U.compareAndSetObject(this, BUF_OFFSET, buffer, nbuf)) {
|
||||
// Can't replace buf if there was an async close.
|
||||
// Note: This would need to be changed if fill()
|
||||
// is ever made accessible to multiple threads.
|
||||
@ -476,7 +482,7 @@ class BufferedInputStream extends FilterInputStream {
|
||||
public void close() throws IOException {
|
||||
byte[] buffer;
|
||||
while ( (buffer = buf) != null) {
|
||||
if (bufUpdater.compareAndSet(this, buffer, null)) {
|
||||
if (U.compareAndSetObject(this, BUF_OFFSET, buffer, null)) {
|
||||
InputStream input = in;
|
||||
in = null;
|
||||
if (input != null)
|
||||
|
@ -132,34 +132,37 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||
// newCompletion has just been installed successfully
|
||||
completion = newCompletion;
|
||||
// spawn a thread to wait for and deliver the exit value
|
||||
processReaperExecutor.execute(() -> {
|
||||
int exitValue = waitForProcessExit0(pid, shouldReap);
|
||||
if (exitValue == NOT_A_CHILD) {
|
||||
// pid not alive or not a child of this process
|
||||
// If it is alive wait for it to terminate
|
||||
long sleep = 300; // initial milliseconds to sleep
|
||||
int incr = 30; // increment to the sleep time
|
||||
processReaperExecutor.execute(new Runnable() {
|
||||
// Use inner class to avoid lambda stack overhead
|
||||
public void run() {
|
||||
int exitValue = waitForProcessExit0(pid, shouldReap);
|
||||
if (exitValue == NOT_A_CHILD) {
|
||||
// pid not alive or not a child of this process
|
||||
// If it is alive wait for it to terminate
|
||||
long sleep = 300; // initial milliseconds to sleep
|
||||
int incr = 30; // increment to the sleep time
|
||||
|
||||
long startTime = isAlive0(pid);
|
||||
long origStart = startTime;
|
||||
while (startTime >= 0) {
|
||||
try {
|
||||
Thread.sleep(Math.min(sleep, 5000L)); // no more than 5 sec
|
||||
sleep += incr;
|
||||
} catch (InterruptedException ie) {
|
||||
// ignore and retry
|
||||
}
|
||||
startTime = isAlive0(pid); // recheck if is alive
|
||||
if (origStart > 0 && startTime != origStart) {
|
||||
// start time changed, pid is not the same process
|
||||
break;
|
||||
long startTime = isAlive0(pid);
|
||||
long origStart = startTime;
|
||||
while (startTime >= 0) {
|
||||
try {
|
||||
Thread.sleep(Math.min(sleep, 5000L)); // no more than 5 sec
|
||||
sleep += incr;
|
||||
} catch (InterruptedException ie) {
|
||||
// ignore and retry
|
||||
}
|
||||
startTime = isAlive0(pid); // recheck if is alive
|
||||
if (origStart > 0 && startTime != origStart) {
|
||||
// start time changed, pid is not the same process
|
||||
break;
|
||||
}
|
||||
}
|
||||
exitValue = 0;
|
||||
}
|
||||
exitValue = 0;
|
||||
newCompletion.complete(exitValue);
|
||||
// remove from cache afterwards
|
||||
completions.remove(pid, newCompletion);
|
||||
}
|
||||
newCompletion.complete(exitValue);
|
||||
// remove from cache afterwards
|
||||
completions.remove(pid, newCompletion);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2488,12 +2488,8 @@ public final class String
|
||||
* <tr>
|
||||
* <td>(all)</td>
|
||||
* <th scope="row" style="font-weight:normal; text-align:left">
|
||||
* <img src="doc-files/capiota.gif" alt="capiota"><img src="doc-files/capchi.gif" alt="capchi">
|
||||
* <img src="doc-files/captheta.gif" alt="captheta"><img src="doc-files/capupsil.gif" alt="capupsil">
|
||||
* <img src="doc-files/capsigma.gif" alt="capsigma"></th>
|
||||
* <td><img src="doc-files/iota.gif" alt="iota"><img src="doc-files/chi.gif" alt="chi">
|
||||
* <img src="doc-files/theta.gif" alt="theta"><img src="doc-files/upsilon.gif" alt="upsilon">
|
||||
* <img src="doc-files/sigma1.gif" alt="sigma"></td>
|
||||
* ΙΧΘΥΣ</th>
|
||||
* <td>ιχθυσ</td>
|
||||
* <td>lowercased all chars in String</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Value-based Classes</title>
|
||||
|
Before Width: | Height: | Size: 144 B |
Before Width: | Height: | Size: 111 B |
Before Width: | Height: | Size: 131 B |
Before Width: | Height: | Size: 153 B |
Before Width: | Height: | Size: 140 B |
Before Width: | Height: | Size: 145 B |
Before Width: | Height: | Size: 112 B |
Before Width: | Height: | Size: 206 B |
Before Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 187 B |
Before Width: | Height: | Size: 191 B |
Before Width: | Height: | Size: 135 B |
Before Width: | Height: | Size: 144 B |
@ -1,3 +1,4 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -22,7 +23,6 @@
|
||||
or visit www.oracle.com if you need additional information or have any
|
||||
questions.
|
||||
-->
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Java Thread Primitive Deprecation</title>
|
||||
@ -30,7 +30,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<h2>Java Thread Primitive Deprecation</h2>
|
||||
<hr size="3" noshade="noshade" />
|
||||
<hr>
|
||||
<h3>Why is <code>Thread.stop</code> deprecated?</h3>
|
||||
<p>Because it is inherently unsafe. Stopping a thread causes it to
|
||||
unlock all the monitors that it has locked. (The monitors are
|
||||
@ -45,7 +45,7 @@ detect, or it may be pronounced. Unlike other unchecked exceptions,
|
||||
no warning that his program may be corrupted. The corruption can
|
||||
manifest itself at any time after the actual damage occurs, even
|
||||
hours or days in the future.</p>
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>Couldn't I just catch the <code>ThreadDeath</code> exception
|
||||
and fix the damaged object?</h3>
|
||||
<p>In theory, perhaps, but it would <em>vastly</em> complicate the
|
||||
@ -61,7 +61,7 @@ while cleaning up from the first (in the <code>catch</code> or
|
||||
it succeeded. The code to ensure this would be quite complex.</li>
|
||||
</ol>
|
||||
In sum, it just isn't practical.
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>What about <code>Thread.stop(Throwable)</code>?</h3>
|
||||
<p>In addition to all of the problems noted above, this method may
|
||||
be used to generate exceptions that its target thread is unprepared
|
||||
@ -76,7 +76,7 @@ the checked exceptions that it may throw:</p>
|
||||
Thread.currentThread().stop(t);
|
||||
}
|
||||
</pre>
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>What should I use instead of <code>Thread.stop</code>?</h3>
|
||||
<p>Most uses of <code>stop</code> should be replaced by code that
|
||||
simply modifies some variable to indicate that the target thread
|
||||
@ -84,7 +84,7 @@ should stop running. The target thread should check this variable
|
||||
regularly, and return from its run method in an orderly fashion if
|
||||
the variable indicates that it is to stop running. To ensure prompt
|
||||
communication of the stop-request, the variable must be
|
||||
<tt>volatile</tt> (or access to the variable must be
|
||||
<code>volatile</code> (or access to the variable must be
|
||||
synchronized).</p>
|
||||
<p>For example, suppose your applet contains the following
|
||||
<code>start</code>, <code>stop</code> and <code>run</code>
|
||||
@ -131,7 +131,7 @@ applet's <code>stop</code> and <code>run</code> methods with:
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>How do I stop a thread that waits for long periods (e.g., for
|
||||
input)?</h3>
|
||||
<p>That's what the <code>Thread.interrupt</code> method is for. The
|
||||
@ -159,7 +159,7 @@ following incantation:
|
||||
</pre>
|
||||
This ensures that the Thread will reraise the
|
||||
<code>InterruptedException</code> as soon as it is able.
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>What if a thread doesn't respond to
|
||||
<code>Thread.interrupt</code>?</h3>
|
||||
<p>In some cases, you can use application specific tricks. For
|
||||
@ -172,7 +172,7 @@ wouldn't respond to <code>Thread.stop</code> either.</em> Such
|
||||
cases include deliberate denial-of-service attacks, and I/O
|
||||
operations for which thread.stop and thread.interrupt do not work
|
||||
properly.</p>
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>Why are <code>Thread.suspend</code> and
|
||||
<code>Thread.resume</code> deprecated?</h3>
|
||||
<p><code>Thread.suspend</code> is inherently deadlock-prone. If the
|
||||
@ -182,7 +182,7 @@ resource until the target thread is resumed. If the thread that
|
||||
would resume the target thread attempts to lock this monitor prior
|
||||
to calling <code>resume</code>, deadlock results. Such deadlocks
|
||||
typically manifest themselves as "frozen" processes.</p>
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>What should I use instead of <code>Thread.suspend</code> and
|
||||
<code>Thread.resume</code>?</h3>
|
||||
<p>As with <code>Thread.stop</code>, the prudent approach is to
|
||||
@ -274,7 +274,7 @@ block only if the thread has actually been suspended:</p>
|
||||
}
|
||||
</pre>
|
||||
<p>In the absence of explicit synchronization,
|
||||
<tt>threadSuspended</tt> must be made <tt>volatile</tt> to ensure
|
||||
<code>threadSuspended</code> must be made <code>volatile</code> to ensure
|
||||
prompt communication of the suspend-request.</p>
|
||||
The resulting <code>run</code> method is:
|
||||
<pre>
|
||||
@ -302,17 +302,17 @@ The resulting <code>run</code> method is:
|
||||
be safely "stopped" or "suspended"?</h3>
|
||||
Yes, it's reasonably straightforward. The one subtlety is that the
|
||||
target thread may already be suspended at the time that another
|
||||
thread tries to stop it. If the <tt>stop</tt> method merely sets
|
||||
the state variable (<tt>blinker</tt>) to null, the target thread
|
||||
thread tries to stop it. If the <code>stop</code> method merely sets
|
||||
the state variable (<code>blinker</code>) to null, the target thread
|
||||
will remain suspended (waiting on the monitor), rather than exiting
|
||||
gracefully as it should. If the applet is restarted, multiple
|
||||
threads could end up waiting on the monitor at the same time,
|
||||
resulting in erratic behavior.
|
||||
<p>To rectify this situation, the <tt>stop</tt> method must ensure
|
||||
<p>To rectify this situation, the <code>stop</code> method must ensure
|
||||
that the target thread resumes immediately if it is suspended. Once
|
||||
the target thread resumes, it must recognize immediately that it
|
||||
has been stopped, and exit gracefully. Here's how the resulting
|
||||
<tt>run</tt> and <tt>stop</tt> methods look:</p>
|
||||
<code>run</code> and <code>stop</code> methods look:</p>
|
||||
<pre>
|
||||
public void run() {
|
||||
Thread thisThread = Thread.currentThread();
|
||||
@ -335,18 +335,18 @@ has been stopped, and exit gracefully. Here's how the resulting
|
||||
notify();
|
||||
}
|
||||
</pre>
|
||||
If the <tt>stop</tt> method calls <tt>Thread.interrupt</tt>, as
|
||||
described above, it needn't call <tt>notify</tt> as well, but it
|
||||
If the <code>stop</code> method calls <code>Thread.interrupt</code>, as
|
||||
described above, it needn't call <code>notify</code> as well, but it
|
||||
still must be synchronized. This ensures that the target thread
|
||||
won't miss an interrupt due to a race condition.
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>What about <code>Thread.destroy</code>?</h3>
|
||||
<code>Thread.destroy</code> was never implemented and has been
|
||||
deprecated. If it were implemented, it would be deadlock-prone in
|
||||
the manner of <code>Thread.suspend</code>. (In fact, it is roughly
|
||||
equivalent to <code>Thread.suspend</code> without the possibility
|
||||
of a subsequent <code>Thread.resume</code>.)
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>Why is <code>Runtime.runFinalizersOnExit</code>
|
||||
deprecated?</h3>
|
||||
Because it is inherently unsafe. It may result in finalizers being
|
||||
|
Before Width: | Height: | Size: 133 B |
@ -202,26 +202,26 @@ public class ChoiceFormat extends NumberFormat {
|
||||
segments[part].append(ch);
|
||||
} else if (ch == '<' || ch == '#' || ch == '\u2264') {
|
||||
if (segments[0].length() == 0) {
|
||||
throw new IllegalArgumentException();
|
||||
throw new IllegalArgumentException("Each interval must"
|
||||
+ " contain a number before a format");
|
||||
}
|
||||
try {
|
||||
String tempBuffer = segments[0].toString();
|
||||
if (tempBuffer.equals("\u221E")) {
|
||||
startValue = Double.POSITIVE_INFINITY;
|
||||
} else if (tempBuffer.equals("-\u221E")) {
|
||||
startValue = Double.NEGATIVE_INFINITY;
|
||||
} else {
|
||||
startValue = Double.valueOf(segments[0].toString()).doubleValue();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
String tempBuffer = segments[0].toString();
|
||||
if (tempBuffer.equals("\u221E")) {
|
||||
startValue = Double.POSITIVE_INFINITY;
|
||||
} else if (tempBuffer.equals("-\u221E")) {
|
||||
startValue = Double.NEGATIVE_INFINITY;
|
||||
} else {
|
||||
startValue = Double.valueOf(tempBuffer);
|
||||
}
|
||||
|
||||
if (ch == '<' && startValue != Double.POSITIVE_INFINITY &&
|
||||
startValue != Double.NEGATIVE_INFINITY) {
|
||||
startValue = nextDouble(startValue);
|
||||
}
|
||||
if (startValue <= oldStartValue) {
|
||||
throw new IllegalArgumentException();
|
||||
throw new IllegalArgumentException("Incorrect order of"
|
||||
+ " intervals, must be in ascending order");
|
||||
}
|
||||
segments[0].setLength(0);
|
||||
part = 1;
|
||||
|
@ -223,7 +223,7 @@ import java.util.Set;
|
||||
* <tr>
|
||||
* <th scope="row"> {@link #ISO_OFFSET_DATE_TIME}</th>
|
||||
* <td> Date Time with Offset
|
||||
* </td><td>2011-12-03T10:15:30+01:00'</td>
|
||||
* </td><td>'2011-12-03T10:15:30+01:00'</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row"> {@link #ISO_ZONED_DATE_TIME}</th>
|
||||
@ -243,7 +243,7 @@ import java.util.Set;
|
||||
* <tr>
|
||||
* <th scope="row"> {@link #ISO_WEEK_DATE}</th>
|
||||
* <td> Year and Week </td>
|
||||
* <td>2012-W48-6'</td></tr>
|
||||
* <td>'2012-W48-6'</td></tr>
|
||||
* <tr>
|
||||
* <th scope="row"> {@link #ISO_INSTANT}</th>
|
||||
* <td> Date and Time of an Instant </td>
|
||||
|
@ -56,41 +56,44 @@ package java.util;
|
||||
* <p>The twelve methods described above are summarized in the
|
||||
* following table:
|
||||
*
|
||||
* <table class="plain">
|
||||
* <table class="striped">
|
||||
* <caption>Summary of Deque methods</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td style="text-align:center" COLSPAN = 2> <b>First Element (Head)</b></td>
|
||||
* <td style="text-align:center" COLSPAN = 2> <b>Last Element (Tail)</b></td>
|
||||
* <td rowspan="2"></td>
|
||||
* <th scope="col" colspan="2"> First Element (Head)</th>
|
||||
* <th scope="col" colspan="2"> Last Element (Tail)</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td style="text-align:center"><em>Throws exception</em></td>
|
||||
* <td style="text-align:center"><em>Special value</em></td>
|
||||
* <td style="text-align:center"><em>Throws exception</em></td>
|
||||
* <td style="text-align:center"><em>Special value</em></td>
|
||||
* <th scope="col" style="font-weight:normal; font-style:italic">Throws exception</th>
|
||||
* <th scope="col" style="font-weight:normal; font-style:italic">Special value</th>
|
||||
* <th scope="col" style="font-weight:normal; font-style:italic">Throws exception</th>
|
||||
* <th scope="col" style="font-weight:normal; font-style:italic">Special value</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td><b>Insert</b></td>
|
||||
* <th scope="row">Insert</th>
|
||||
* <td>{@link #addFirst(Object) addFirst(e)}</td>
|
||||
* <td>{@link #offerFirst(Object) offerFirst(e)}</td>
|
||||
* <td>{@link #addLast(Object) addLast(e)}</td>
|
||||
* <td>{@link #offerLast(Object) offerLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Remove</b></td>
|
||||
* <th scope="row">Remove</th>
|
||||
* <td>{@link #removeFirst() removeFirst()}</td>
|
||||
* <td>{@link #pollFirst() pollFirst()}</td>
|
||||
* <td>{@link #removeLast() removeLast()}</td>
|
||||
* <td>{@link #pollLast() pollLast()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Examine</b></td>
|
||||
* <th scope="row">Examine</th>
|
||||
* <td>{@link #getFirst() getFirst()}</td>
|
||||
* <td>{@link #peekFirst() peekFirst()}</td>
|
||||
* <td>{@link #getLast() getLast()}</td>
|
||||
* <td>{@link #peekLast() peekLast()}</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* <p>This interface extends the {@link Queue} interface. When a deque is
|
||||
@ -99,36 +102,40 @@ package java.util;
|
||||
* inherited from the {@code Queue} interface are precisely equivalent to
|
||||
* {@code Deque} methods as indicated in the following table:
|
||||
*
|
||||
* <table class="plain">
|
||||
* <table class="striped">
|
||||
* <caption>Comparison of Queue and Deque methods</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <td style="text-align:center"> <b>{@code Queue} Method</b></td>
|
||||
* <td style="text-align:center"> <b>Equivalent {@code Deque} Method</b></td>
|
||||
* <th scope="col"> {@code Queue} Method</th>
|
||||
* <th scope="col"> Equivalent {@code Deque} Method</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td>{@link #add(Object) add(e)}</td>
|
||||
* <th scope="row">{@link #add(Object) add(e)}</th>
|
||||
* <td>{@link #addLast(Object) addLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #offer(Object) offer(e)}</td>
|
||||
* <th scope="row">{@link #offer(Object) offer(e)}</th>
|
||||
* <td>{@link #offerLast(Object) offerLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #remove() remove()}</td>
|
||||
* <th scope="row">{@link #remove() remove()}</th>
|
||||
* <td>{@link #removeFirst() removeFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #poll() poll()}</td>
|
||||
* <th scope="row">{@link #poll() poll()}</th>
|
||||
* <td>{@link #pollFirst() pollFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #element() element()}</td>
|
||||
* <th scope="row">{@link #element() element()}</th>
|
||||
* <td>{@link #getFirst() getFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #peek() peek()}</td>
|
||||
* <th scope="row">{@link #peek() peek()}</th>
|
||||
* <td>{@link #peekFirst() peekFirst()}</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* <p>Deques can also be used as LIFO (Last-In-First-Out) stacks. This
|
||||
@ -137,24 +144,28 @@ package java.util;
|
||||
* beginning of the deque. Stack methods are precisely equivalent to
|
||||
* {@code Deque} methods as indicated in the table below:
|
||||
*
|
||||
* <table class="plain">
|
||||
* <table class="striped">
|
||||
* <caption>Comparison of Stack and Deque methods</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <td style="text-align:center"> <b>Stack Method</b></td>
|
||||
* <td style="text-align:center"> <b>Equivalent {@code Deque} Method</b></td>
|
||||
* <th scope="col"> Stack Method</th>
|
||||
* <th scope="col"> Equivalent {@code Deque} Method</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td>{@link #push(Object) push(e)}</td>
|
||||
* <th scope="row">{@link #push(Object) push(e)}</th>
|
||||
* <td>{@link #addFirst(Object) addFirst(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #pop() pop()}</td>
|
||||
* <th scope="row">{@link #pop() pop()}</th>
|
||||
* <td>{@link #removeFirst() removeFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #peek() peek()}</td>
|
||||
* <th scope="row">{@link #peek() peek()}</th>
|
||||
* <td>{@link #peekFirst() peekFirst()}</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* <p>Note that the {@link #peek peek} method works equally well when
|
||||
|
@ -46,28 +46,32 @@ package java.util;
|
||||
* use with capacity-restricted {@code Queue} implementations; in most
|
||||
* implementations, insert operations cannot fail.
|
||||
*
|
||||
* <table class="plain">
|
||||
* <table class="striped">
|
||||
* <caption>Summary of Queue methods</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td style="text-align:center"><em>Throws exception</em></td>
|
||||
* <td style="text-align:center"><em>Returns special value</em></td>
|
||||
* <th scope="col" style="font-weight:normal; font-style:italic">Throws exception</th>
|
||||
* <th scope="col" style="font-weight:normal; font-style:italic">Returns special value</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td><b>Insert</b></td>
|
||||
* <th scope="row">Insert</th>
|
||||
* <td>{@link #add(Object) add(e)}</td>
|
||||
* <td>{@link #offer(Object) offer(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Remove</b></td>
|
||||
* <th scope="row">Remove</th>
|
||||
* <td>{@link #remove() remove()}</td>
|
||||
* <td>{@link #poll() poll()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Examine</b></td>
|
||||
* <th scope="row">Examine</th>
|
||||
* <td>{@link #element() element()}</td>
|
||||
* <td>{@link #peek() peek()}</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* <p>Queues typically, but do not necessarily, order elements in a
|
||||
|
@ -1210,15 +1210,15 @@ public abstract class ResourceBundle {
|
||||
* <strong>Example:</strong></a>
|
||||
* <p>
|
||||
* The following class and property files are provided:
|
||||
* <pre>
|
||||
* MyResources.class
|
||||
* MyResources.properties
|
||||
* MyResources_fr.properties
|
||||
* MyResources_fr_CH.class
|
||||
* MyResources_fr_CH.properties
|
||||
* MyResources_en.properties
|
||||
* MyResources_es_ES.class
|
||||
* </pre>
|
||||
* <ul>
|
||||
* <li>MyResources.class
|
||||
* <li>MyResources.properties
|
||||
* <li>MyResources_fr.properties
|
||||
* <li>MyResources_fr_CH.class
|
||||
* <li>MyResources_fr_CH.properties
|
||||
* <li>MyResources_en.properties
|
||||
* <li>MyResources_es_ES.class
|
||||
* </ul>
|
||||
*
|
||||
* The contents of all files are valid (that is, public non-abstract
|
||||
* subclasses of <code>ResourceBundle</code> for the ".class" files,
|
||||
@ -1228,14 +1228,17 @@ public abstract class ResourceBundle {
|
||||
* <p>Calling <code>getBundle</code> with the locale arguments below will
|
||||
* instantiate resource bundles as follows:
|
||||
*
|
||||
* <table class="borderless">
|
||||
* <table class="striped">
|
||||
* <caption style="display:none">getBundle() locale to resource bundle mapping</caption>
|
||||
* <thead>
|
||||
* <tr><th scope="col">Locale</th><th scope="col">Resource bundle</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td>Locale("fr", "CH")</td><td>MyResources_fr_CH.class, parent MyResources_fr.properties, parent MyResources.class</td></tr>
|
||||
* <tr><td>Locale("fr", "FR")</td><td>MyResources_fr.properties, parent MyResources.class</td></tr>
|
||||
* <tr><td>Locale("de", "DE")</td><td>MyResources_en.properties, parent MyResources.class</td></tr>
|
||||
* <tr><td>Locale("en", "US")</td><td>MyResources_en.properties, parent MyResources.class</td></tr>
|
||||
* <tr><td>Locale("es", "ES")</td><td>MyResources_es_ES.class, parent MyResources.class</td></tr>
|
||||
* <tr><th scope="row">Locale("fr", "CH")</th><td>MyResources_fr_CH.class, parent MyResources_fr.properties, parent MyResources.class</td></tr>
|
||||
* <tr><th scope="row">Locale("fr", "FR")</th><td>MyResources_fr.properties, parent MyResources.class</td></tr>
|
||||
* <tr><th scope="row">Locale("de", "DE")</th><td>MyResources_en.properties, parent MyResources.class</td></tr>
|
||||
* <tr><th scope="row">Locale("en", "US")</th><td>MyResources_en.properties, parent MyResources.class</td></tr>
|
||||
* <tr><th scope="row">Locale("es", "ES")</th><td>MyResources_es_ES.class, parent MyResources.class</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
@ -1324,42 +1327,41 @@ public abstract class ResourceBundle {
|
||||
* <caption style="display:none">locale-format combinations for newBundle</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <td
|
||||
* style="vertical-align: top; text-align: left; font-weight: bold; width: 50%;"><code>Locale</code><br>
|
||||
* </td>
|
||||
* <td
|
||||
* style="vertical-align: top; text-align: left; font-weight: bold; width: 50%;"><code>format</code><br>
|
||||
* </td>
|
||||
* <th scope="col">Index</th>
|
||||
* <th scope="col"><code>Locale</code></th>
|
||||
* <th scope="col"><code>format</code></th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>Locale("de", "DE")</code><br>
|
||||
* </td>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>java.class</code><br>
|
||||
* </td>
|
||||
* <th scope="row">1</th>
|
||||
* <td><code>Locale("de", "DE")</code></td>
|
||||
* <td><code>java.class</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>Locale("de", "DE")</code></td>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>java.properties</code><br>
|
||||
* </td>
|
||||
* <th scope="row">2</th>
|
||||
* <td><code>Locale("de", "DE")</code></td>
|
||||
* <td><code>java.properties</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>Locale("de")</code></td>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>java.class</code></td>
|
||||
* <th scope="row">3</th>
|
||||
* <td><code>Locale("de")</code></td>
|
||||
* <td><code>java.class</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>Locale("de")</code></td>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>java.properties</code></td>
|
||||
* <th scope="row">4</th>
|
||||
* <td><code>Locale("de")</code></td>
|
||||
* <td><code>java.properties</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>Locale("")</code><br>
|
||||
* </td>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>java.class</code></td>
|
||||
* <th scope="row">5</th>
|
||||
* <td><code>Locale("")</code></td>
|
||||
* <td><code>java.class</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>Locale("")</code></td>
|
||||
* <td style="vertical-align: top; width: 50%;"><code>java.properties</code></td>
|
||||
* <th scope="row">6</th>
|
||||
* <td><code>Locale("")</code></td>
|
||||
* <td><code>java.properties</code></td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
@ -3453,15 +3455,15 @@ public abstract class ResourceBundle {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given <code>bundleName</code> to the form required
|
||||
* Converts the given {@code bundleName} to the form required
|
||||
* by the {@link ClassLoader#getResource ClassLoader.getResource}
|
||||
* method by replacing all occurrences of <code>'.'</code> in
|
||||
* <code>bundleName</code> with <code>'/'</code> and appending a
|
||||
* <code>'.'</code> and the given file <code>suffix</code>. For
|
||||
* example, if <code>bundleName</code> is
|
||||
* <code>"foo.bar.MyResources_ja_JP"</code> and <code>suffix</code>
|
||||
* is <code>"properties"</code>, then
|
||||
* <code>"foo/bar/MyResources_ja_JP.properties"</code> is returned.
|
||||
* method by replacing all occurrences of {@code '.'} in
|
||||
* {@code bundleName} with {@code '/'} and appending a
|
||||
* {@code '.'} and the given file {@code suffix}. For
|
||||
* example, if {@code bundleName} is
|
||||
* {@code "foo.bar.MyResources_ja_JP"} and {@code suffix}
|
||||
* is {@code "properties"}, then
|
||||
* {@code "foo/bar/MyResources_ja_JP.properties"} is returned.
|
||||
*
|
||||
* @param bundleName
|
||||
* the bundle name
|
||||
@ -3469,8 +3471,8 @@ public abstract class ResourceBundle {
|
||||
* the file type suffix
|
||||
* @return the converted resource name
|
||||
* @exception NullPointerException
|
||||
* if <code>bundleName</code> or <code>suffix</code>
|
||||
* is <code>null</code>
|
||||
* if {@code bundleName} or {@code suffix}
|
||||
* is {@code null}
|
||||
*/
|
||||
public final String toResourceName(String bundleName, String suffix) {
|
||||
StringBuilder sb = new StringBuilder(bundleName.length() + 1 + suffix.length());
|
||||
|
@ -56,66 +56,66 @@ import java.util.NoSuchElementException;
|
||||
* <table class="plain">
|
||||
* <caption>Summary of BlockingDeque methods</caption>
|
||||
* <tr>
|
||||
* <td style="text-align:center" COLSPAN = 5> <b>First Element (Head)</b></td>
|
||||
* <th id="First" colspan="5"> First Element (Head)</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td style="text-align:center"><em>Throws exception</em></td>
|
||||
* <td style="text-align:center"><em>Special value</em></td>
|
||||
* <td style="text-align:center"><em>Blocks</em></td>
|
||||
* <td style="text-align:center"><em>Times out</em></td>
|
||||
* <th id="FThrow" style="font-weight:normal; font-style: italic">Throws exception</th>
|
||||
* <th id="FValue" style="font-weight:normal; font-style: italic">Special value</th>
|
||||
* <th id="FBlock" style="font-weight:normal; font-style: italic">Blocks</th>
|
||||
* <th id="FTimes" style="font-weight:normal; font-style: italic">Times out</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Insert</b></td>
|
||||
* <td>{@link #addFirst(Object) addFirst(e)}</td>
|
||||
* <td>{@link #offerFirst(Object) offerFirst(e)}</td>
|
||||
* <td>{@link #putFirst(Object) putFirst(e)}</td>
|
||||
* <td>{@link #offerFirst(Object, long, TimeUnit) offerFirst(e, time, unit)}</td>
|
||||
* <th id="FInsert" style="text-align:left">Insert</th>
|
||||
* <td headers="First FInsert FThrow">{@link #addFirst(Object) addFirst(e)}</td>
|
||||
* <td headers="First FInsert FValue">{@link #offerFirst(Object) offerFirst(e)}</td>
|
||||
* <td headers="First FInsert FBlock">{@link #putFirst(Object) putFirst(e)}</td>
|
||||
* <td headers="First FInsert FTimes">{@link #offerFirst(Object, long, TimeUnit) offerFirst(e, time, unit)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Remove</b></td>
|
||||
* <td>{@link #removeFirst() removeFirst()}</td>
|
||||
* <td>{@link #pollFirst() pollFirst()}</td>
|
||||
* <td>{@link #takeFirst() takeFirst()}</td>
|
||||
* <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td>
|
||||
* <th id="FRemove" style="text-align:left">Remove</th>
|
||||
* <td headers="First FRemove FThrow">{@link #removeFirst() removeFirst()}</td>
|
||||
* <td headers="First FRemove FValue">{@link #pollFirst() pollFirst()}</td>
|
||||
* <td headers="First FRemove FBlock">{@link #takeFirst() takeFirst()}</td>
|
||||
* <td headers="First FRemove FTimes">{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Examine</b></td>
|
||||
* <td>{@link #getFirst() getFirst()}</td>
|
||||
* <td>{@link #peekFirst() peekFirst()}</td>
|
||||
* <td><em>not applicable</em></td>
|
||||
* <td><em>not applicable</em></td>
|
||||
* <th id="FExamine" style="text-align:left">Examine</th>
|
||||
* <td headers="First FExamine FThrow">{@link #getFirst() getFirst()}</td>
|
||||
* <td headers="First FExamine FValue">{@link #peekFirst() peekFirst()}</td>
|
||||
* <td headers="First FExamine FBlock" style="font-style:italic">not applicable</td>
|
||||
* <td headers="First FExamine FTimes" style="font-style:italic">not applicable</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td style="text-align:center" COLSPAN = 5> <b>Last Element (Tail)</b></td>
|
||||
* <th id="Last" colspan="5"> Last Element (Tail)</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td style="text-align:center"><em>Throws exception</em></td>
|
||||
* <td style="text-align:center"><em>Special value</em></td>
|
||||
* <td style="text-align:center"><em>Blocks</em></td>
|
||||
* <td style="text-align:center"><em>Times out</em></td>
|
||||
* <th id="LThrow" style="font-weight:normal; font-style: italic">Throws exception</th>
|
||||
* <th id="LValue" style="font-weight:normal; font-style: italic">Special value</th>
|
||||
* <th id="LBlock" style="font-weight:normal; font-style: italic">Blocks</th>
|
||||
* <th id="LTimes" style="font-weight:normal; font-style: italic">Times out</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Insert</b></td>
|
||||
* <td>{@link #addLast(Object) addLast(e)}</td>
|
||||
* <td>{@link #offerLast(Object) offerLast(e)}</td>
|
||||
* <td>{@link #putLast(Object) putLast(e)}</td>
|
||||
* <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td>
|
||||
* <th id="LInsert" style="text-align:left">Insert</th>
|
||||
* <td headers="Last LInsert LThrow">{@link #addLast(Object) addLast(e)}</td>
|
||||
* <td headers="Last LInsert LValue">{@link #offerLast(Object) offerLast(e)}</td>
|
||||
* <td headers="Last LInsert LBlock">{@link #putLast(Object) putLast(e)}</td>
|
||||
* <td headers="Last LInsert LTimes">{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Remove</b></td>
|
||||
* <td>{@link #removeLast() removeLast()}</td>
|
||||
* <td>{@link #pollLast() pollLast()}</td>
|
||||
* <td>{@link #takeLast() takeLast()}</td>
|
||||
* <td>{@link #pollLast(long, TimeUnit) pollLast(time, unit)}</td>
|
||||
* <th id="LRemove" style="text-align:left">Remove</th>
|
||||
* <td headers="Last LRemove LThrow">{@link #removeLast() removeLast()}</td>
|
||||
* <td headers="Last LRemove LValue">{@link #pollLast() pollLast()}</td>
|
||||
* <td headers="Last LRemove LBlock">{@link #takeLast() takeLast()}</td>
|
||||
* <td headers="Last LRemove LTimes">{@link #pollLast(long, TimeUnit) pollLast(time, unit)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Examine</b></td>
|
||||
* <td>{@link #getLast() getLast()}</td>
|
||||
* <td>{@link #peekLast() peekLast()}</td>
|
||||
* <td><em>not applicable</em></td>
|
||||
* <td><em>not applicable</em></td>
|
||||
* <th id="LExamine" style="text-align:left">Examine</th>
|
||||
* <td headers="Last LExamine LThrow">{@link #getLast() getLast()}</td>
|
||||
* <td headers="Last LExamine LValue">{@link #peekLast() peekLast()}</td>
|
||||
* <td headers="Last LExamine LBlock" style="font-style:italic">not applicable</td>
|
||||
* <td headers="Last LExamine LTimes" style="font-style:italic">not applicable</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
@ -131,57 +131,52 @@ import java.util.NoSuchElementException;
|
||||
* <table class="plain">
|
||||
* <caption>Comparison of BlockingQueue and BlockingDeque methods</caption>
|
||||
* <tr>
|
||||
* <td style="text-align:center"> <b>{@code BlockingQueue} Method</b></td>
|
||||
* <td style="text-align:center"> <b>Equivalent {@code BlockingDeque} Method</b></td>
|
||||
* <td></td>
|
||||
* <th id="BQueue"> {@code BlockingQueue} Method</th>
|
||||
* <th id="BDeque"> Equivalent {@code BlockingDeque} Method</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td style="text-align:center" COLSPAN = 2> <b>Insert</b></td>
|
||||
* <th id="Insert" rowspan="4" style="text-align:left; vertical-align:top">Insert</th>
|
||||
* <th id="add" style="font-weight:normal; text-align:left">{@link #add(Object) add(e)}</th>
|
||||
* <td headers="Insert BDeque add">{@link #addLast(Object) addLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #add(Object) add(e)}</td>
|
||||
* <td>{@link #addLast(Object) addLast(e)}</td>
|
||||
* <th id="offer1" style="font-weight:normal; text-align:left">{@link #offer(Object) offer(e)}</th>
|
||||
* <td headers="Insert BDeque offer1">{@link #offerLast(Object) offerLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #offer(Object) offer(e)}</td>
|
||||
* <td>{@link #offerLast(Object) offerLast(e)}</td>
|
||||
* <th id="put" style="font-weight:normal; text-align:left">{@link #put(Object) put(e)}</th>
|
||||
* <td headers="Insert BDeque put">{@link #putLast(Object) putLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #put(Object) put(e)}</td>
|
||||
* <td>{@link #putLast(Object) putLast(e)}</td>
|
||||
* <th id="offer2" style="font-weight:normal; text-align:left">{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</th>
|
||||
* <td headers="Insert BDeque offer2">{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td>
|
||||
* <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td>
|
||||
* <th id="Remove" rowspan="4" style="text-align:left; vertical-align:top">Remove</th>
|
||||
* <th id="remove" style="font-weight:normal; text-align:left">{@link #remove() remove()}</th>
|
||||
* <td headers="Remove BDeque remove">{@link #removeFirst() removeFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td style="text-align:center" COLSPAN = 2> <b>Remove</b></td>
|
||||
* <th id="poll1" style="font-weight:normal; text-align:left">{@link #poll() poll()}</th>
|
||||
* <td headers="Remove BDeque poll1">{@link #pollFirst() pollFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #remove() remove()}</td>
|
||||
* <td>{@link #removeFirst() removeFirst()}</td>
|
||||
* <th id="take" style="font-weight:normal; text-align:left">{@link #take() take()}</th>
|
||||
* <td headers="Remove BDeque take">{@link #takeFirst() takeFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #poll() poll()}</td>
|
||||
* <td>{@link #pollFirst() pollFirst()}</td>
|
||||
* <th id="poll2" style="font-weight:normal; text-align:left">{@link #poll(long, TimeUnit) poll(time, unit)}</th>
|
||||
* <td headers="Remove BDeque poll2">{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #take() take()}</td>
|
||||
* <td>{@link #takeFirst() takeFirst()}</td>
|
||||
* <th id="Examine" rowspan="2" style="text-align:left; vertical-align:top">Examine</th>
|
||||
* <th id="element" style="font-weight:normal; text-align:left">{@link #element() element()}</th>
|
||||
* <td headers="Examine BDeque element">{@link #getFirst() getFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td>
|
||||
* <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td style="text-align:center" COLSPAN = 2> <b>Examine</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #element() element()}</td>
|
||||
* <td>{@link #getFirst() getFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #peek() peek()}</td>
|
||||
* <td>{@link #peekFirst() peekFirst()}</td>
|
||||
* <th id="peek" style="font-weight:normal; text-align:left">{@link #peek() peek()}</th>
|
||||
* <td headers="Examine BDeque peek">{@link #peekFirst() peekFirst()}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
|
@ -56,31 +56,31 @@ import java.util.Queue;
|
||||
* <caption>Summary of BlockingQueue methods</caption>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td style="text-align:center"><em>Throws exception</em></td>
|
||||
* <td style="text-align:center"><em>Special value</em></td>
|
||||
* <td style="text-align:center"><em>Blocks</em></td>
|
||||
* <td style="text-align:center"><em>Times out</em></td>
|
||||
* <th scope="col" style="font-weight:normal; font-style:italic">Throws exception</th>
|
||||
* <th scope="col" style="font-weight:normal; font-style:italic">Special value</th>
|
||||
* <th scope="col" style="font-weight:normal; font-style:italic">Blocks</th>
|
||||
* <th scope="col" style="font-weight:normal; font-style:italic">Times out</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Insert</b></td>
|
||||
* <th scope="row" style="text-align:left">Insert</th>
|
||||
* <td>{@link #add(Object) add(e)}</td>
|
||||
* <td>{@link #offer(Object) offer(e)}</td>
|
||||
* <td>{@link #put(Object) put(e)}</td>
|
||||
* <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Remove</b></td>
|
||||
* <th scope="row" style="text-align:left">Remove</th>
|
||||
* <td>{@link #remove() remove()}</td>
|
||||
* <td>{@link #poll() poll()}</td>
|
||||
* <td>{@link #take() take()}</td>
|
||||
* <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Examine</b></td>
|
||||
* <th scope="row" style="text-align:left">Examine</th>
|
||||
* <td>{@link #element() element()}</td>
|
||||
* <td>{@link #peek() peek()}</td>
|
||||
* <td><em>not applicable</em></td>
|
||||
* <td><em>not applicable</em></td>
|
||||
* <td style="font-style: italic">not applicable</td>
|
||||
* <td style="font-style: italic">not applicable</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
|
@ -113,21 +113,21 @@ import java.util.concurrent.locks.LockSupport;
|
||||
* <caption>Summary of task execution methods</caption>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td style="text-align:center"> <b>Call from non-fork/join clients</b></td>
|
||||
* <td style="text-align:center"> <b>Call from within fork/join computations</b></td>
|
||||
* <th scope="col"> Call from non-fork/join clients</th>
|
||||
* <th scope="col"> Call from within fork/join computations</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td> <b>Arrange async execution</b></td>
|
||||
* <th scope="row" style="text-align:left"> Arrange async execution</th>
|
||||
* <td> {@link #execute(ForkJoinTask)}</td>
|
||||
* <td> {@link ForkJoinTask#fork}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td> <b>Await and obtain result</b></td>
|
||||
* <th scope="row" style="text-align:left"> Await and obtain result</th>
|
||||
* <td> {@link #invoke(ForkJoinTask)}</td>
|
||||
* <td> {@link ForkJoinTask#invoke}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td> <b>Arrange exec and obtain Future</b></td>
|
||||
* <th scope="row" style="text-align:left"> Arrange exec and obtain Future</th>
|
||||
* <td> {@link #submit(ForkJoinTask)}</td>
|
||||
* <td> {@link ForkJoinTask#fork} (ForkJoinTasks <em>are</em> Futures)</td>
|
||||
* </tr>
|
||||
|
@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -26,16 +23,15 @@
|
||||
or visit www.oracle.com if you need additional information or have any
|
||||
questions.
|
||||
-->
|
||||
|
||||
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
|
||||
"en-US">
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Java Collections API Design FAQ</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<h2>Java Collections API Design FAQ</h2>
|
||||
<!-- Body text begins here -->
|
||||
<hr />
|
||||
<hr>
|
||||
This document answers frequently asked questions concerning the
|
||||
design of the Java collections framework. It is derived from the
|
||||
large volume of traffic on the collections-comments alias. It
|
||||
@ -105,10 +101,10 @@ aliasing.</b></a></li>
|
||||
collections that send out Events when they're
|
||||
modified?</b></a></li>
|
||||
</ol>
|
||||
<hr size="3" noshade="noshade" />
|
||||
<hr>
|
||||
<h3>Core Interfaces - General Questions</h3>
|
||||
<ol>
|
||||
<li><a name="a1" id="a1"><b>Why don't you support immutability
|
||||
<li><a id="a1"><b>Why don't you support immutability
|
||||
directly in the core collection interfaces so that you can do away
|
||||
with <em>optional operations</em> (and
|
||||
UnsupportedOperationException)?</b></a>
|
||||
@ -168,7 +164,7 @@ engineering compromise to sidestep the whole issue by providing a
|
||||
very small set of core interfaces that can throw a runtime
|
||||
exception.</p>
|
||||
</li>
|
||||
<li><a name="a2" id="a2"><b>Won't programmers have to surround any
|
||||
<li><a id="a2"><b>Won't programmers have to surround any
|
||||
code that calls optional operations with a try-catch clause in case
|
||||
they throw an UnsupportedOperationException?</b></a>
|
||||
<p>It was never our intention that programs should catch these
|
||||
@ -176,7 +172,7 @@ exceptions: that's why they're unchecked (runtime) exceptions. They
|
||||
should only arise as a result of programming errors, in which case,
|
||||
your program will halt due to the uncaught exception.</p>
|
||||
</li>
|
||||
<li><a name="a3" id="a3"><b>Why isn't there a core interface for
|
||||
<li><a id="a3"><b>Why isn't there a core interface for
|
||||
"bags" (AKA multisets)?</b></a>
|
||||
<p>The Collection interface provides this functionality. We are not
|
||||
providing any public implementations of this interface, as we think
|
||||
@ -185,7 +181,7 @@ occasionally return such Collections, which are implemented easily
|
||||
atop AbstractCollection (for example, the Collection returned by
|
||||
Map.values).</p>
|
||||
</li>
|
||||
<li><a name="a28" id="a28"><b>Why didn't you use "Beans-style
|
||||
<li><a id="a28"><b>Why didn't you use "Beans-style
|
||||
names" for consistency?</b></a>
|
||||
<p>While the names of the new collections methods do not adhere to
|
||||
the "Beans naming conventions", we believe that they are
|
||||
@ -207,10 +203,10 @@ a long expression. If we named the methods "getIterator",
|
||||
case. Thus, we adopted the "traditional" JDK style rather than the
|
||||
Beans style.</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>Collection Interface</h3>
|
||||
<ol>
|
||||
<li><a name="a5" id="a5"><b>Why doesn't Collection extend Cloneable
|
||||
<li><a id="a5"><b>Why doesn't Collection extend Cloneable
|
||||
and Serializable?</b></a>
|
||||
<p>Many Collection implementations (including all of the ones
|
||||
provided by the JDK) will have a public clone method, but it would
|
||||
@ -224,7 +220,7 @@ what type of Collection is desired, create an empty Collection of
|
||||
this type, and use the addAll method to copy the elements of the
|
||||
original collection into the new one.</p>
|
||||
</li>
|
||||
<li><a name="a6" id="a6"><b>Why don't you provide an "apply" method
|
||||
<li><a id="a6"><b>Why don't you provide an "apply" method
|
||||
in Collection to apply a given method ("upcall") to all the
|
||||
elements of the Collection?</b></a>
|
||||
<p>This is what is referred to as an "Internal Iterator" in the
|
||||
@ -235,7 +231,7 @@ for external iterators (with Enumerations). The "throw weight" of
|
||||
this functionality is increased by the fact that it requires a
|
||||
public interface to describe upcalls.</p>
|
||||
</li>
|
||||
<li><a name="a7" id="a7"><b>Why didn't you provide a "Predicate"
|
||||
<li><a id="a7"><b>Why didn't you provide a "Predicate"
|
||||
interface, and related methods (e.g., a method to find the first
|
||||
element in the Collection satisfying the predicate)?</b></a>
|
||||
<p>It's easy to implement this functionality atop Iterators, and
|
||||
@ -244,14 +240,14 @@ the predicate. Thus, it's not clear whether this facility pulls its
|
||||
weight. It could be added to the Collections class at a later date
|
||||
(implemented atop Iterator), if it's deemed useful.</p>
|
||||
</li>
|
||||
<li><a name="a8" id="a8"><b>Why don't you provide a form of the
|
||||
<li><a id="a8"><b>Why don't you provide a form of the
|
||||
addAll method that takes an Enumeration (or an Iterator)?</b></a>
|
||||
<p>Because we don't believe in using Enumerations (or Iterators) as
|
||||
"poor man's collections." This was occasionally done in prior
|
||||
releases, but now that we have the Collection interface, it is the
|
||||
preferred way to pass around abstract collections of objects.</p>
|
||||
</li>
|
||||
<li><a name="a9" id="a9"><b>Why don't the concrete implementations
|
||||
<li><a id="a9"><b>Why don't the concrete implementations
|
||||
in the JDK have Enumeration (or Iterator) constructors?</b></a>
|
||||
<p>Again, this is an instance of an Enumeration serving as a "poor
|
||||
man's collection" and we're trying to discourage that. Note
|
||||
@ -259,7 +255,7 @@ however, that we strongly suggest that all concrete implementations
|
||||
should have constructors that take a Collection (and create a new
|
||||
Collection with the same elements).</p>
|
||||
</li>
|
||||
<li><a name="a10" id="a10"><b>Why don't you provide an Iterator.add
|
||||
<li><a id="a10"><b>Why don't you provide an Iterator.add
|
||||
method?</b></a>
|
||||
<p>The semantics are unclear, given that the contract for Iterator
|
||||
makes no guarantees about the order of iteration. Note, however,
|
||||
@ -267,10 +263,10 @@ that ListIterator does provide an add operation, as it does
|
||||
guarantee the order of the iteration.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>List Interface</h3>
|
||||
<ol>
|
||||
<li><a name="a11" id="a11"><b>Why don't you rename the List
|
||||
<li><a id="a11"><b>Why don't you rename the List
|
||||
interface to Sequence; doesn't "list" generally suggest "linked
|
||||
list"? Also, doesn't it conflict with java.awt.List?</b></a>
|
||||
<p>People were evenly divided as to whether List suggests linked
|
||||
@ -285,16 +281,16 @@ naming conflict can be dealt with by the following incantation:</p>
|
||||
import java.awt.*;
|
||||
import java.util.List; // Dictates interpretation of "List"
|
||||
</pre></li>
|
||||
<li><a name="a12" id="a12"><b>Why don't you rename List's set
|
||||
<li><a id="a12"><b>Why don't you rename List's set
|
||||
method to replace, to avoid confusion with Set.</b></a>
|
||||
<p>It was decided that the "set/get" naming convention was strongly
|
||||
enough enshrined in the language that we'd stick with it.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>Map Interface</h3>
|
||||
<ol>
|
||||
<li><a name="a14" id="a14"><b>Why doesn't Map extend
|
||||
<li><a id="a14"><b>Why doesn't Map extend
|
||||
Collection?</b></a>
|
||||
<p>This was by design. We feel that mappings are not collections
|
||||
and collections are not mappings. Thus, it makes little sense for
|
||||
@ -317,10 +313,10 @@ deleted element. That's why we don't have a map view operation on
|
||||
Lists.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>Iterator Interface</h3>
|
||||
<ol>
|
||||
<li><a name="a18" id="a18"><b>Why doesn't Iterator extend
|
||||
<li><a id="a18"><b>Why doesn't Iterator extend
|
||||
Enumeration?</b></a>
|
||||
<p>We view the method names for Enumeration as unfortunate. They're
|
||||
very long, and very frequently used. Given that we were adding a
|
||||
@ -329,7 +325,7 @@ foolish not to take advantage of the opportunity to improve the
|
||||
names. Of course we could support the new and old names in
|
||||
Iterator, but it doesn't seem worthwhile.</p>
|
||||
</li>
|
||||
<li><a name="a19" id="a19"><b>Why don't you provide an
|
||||
<li><a id="a19"><b>Why don't you provide an
|
||||
Iterator.peek method that allows you to look at the next element in
|
||||
an iteration without advancing the iterator?</b></a>
|
||||
<p>It can be implemented atop the current Iterators (a similar
|
||||
@ -338,10 +334,10 @@ would be rare enough that it isn't worth including in the interface
|
||||
that everyone has to implement.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<hr>
|
||||
<h3>Miscellaneous</h3>
|
||||
<ol>
|
||||
<li><a name="a23" id="a23"><b>Why did you write a new collections
|
||||
<li><a id="a23"><b>Why did you write a new collections
|
||||
framework instead of adopting JGL (a preexisting collections
|
||||
package from ObjectSpace, Inc.) into the JDK?</b></a>
|
||||
<p>If you examine the goals for our Collections framework (in the
|
||||
@ -363,7 +359,7 @@ libraries mature, they inevitably grow, but we are trying as hard
|
||||
as we can to keep them small and manageable, so that Java continues
|
||||
to be an easy, fun language to learn and to use.</p>
|
||||
</li>
|
||||
<li><a name="a26" id="a26"><b>Why don't you eliminate all of the
|
||||
<li><a id="a26"><b>Why don't you eliminate all of the
|
||||
methods and classes that return "views" (Collections backed by
|
||||
other collection-like objects). This would greatly reduce
|
||||
aliasing.</b></a>
|
||||
@ -380,7 +376,7 @@ The existence of this method means that people who write methods
|
||||
taking List on input do not have to write secondary forms taking an
|
||||
offset and a length (as they do for arrays).</p>
|
||||
</li>
|
||||
<li><a name="a27" id="a27"><b>Why don't you provide for
|
||||
<li><a id="a27"><b>Why don't you provide for
|
||||
"observable" collections that send out Events when they're
|
||||
modified?</b></a>
|
||||
<p>Primarily, resource constraints. If we're going to commit to
|
||||
@ -390,9 +386,9 @@ some day. In the meantime, it's not difficult to implement such a
|
||||
facility on top of the public APIs.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<hr>
|
||||
<p style="font-size:smaller">
|
||||
Copyright © 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
|
||||
Copyright © 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br>
|
||||
Redwood Shores, CA 94065 USA. All rights reserved.</p>
|
||||
<!-- Body text ends here -->
|
||||
</body>
|
||||
|
@ -1,6 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<!DOCTYPE html>
|
||||
|
||||
<!--
|
||||
Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
@ -27,8 +25,7 @@
|
||||
questions.
|
||||
-->
|
||||
|
||||
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
|
||||
"en-US">
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org" />
|
||||
<title>The Collections Framework</title>
|
||||
@ -71,7 +68,7 @@ collections framework, with links into the API Specification.</li>
|
||||
frequently asked questions (FAQ) about the design of the
|
||||
collections framework.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<hr>
|
||||
<p style="font-size:smaller">
|
||||
Copyright © 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
|
||||
Redwood Shores, CA 94065 USA. All rights reserved.</p>
|
||||
|
@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -26,11 +23,29 @@
|
||||
or visit www.oracle.com if you need additional information or have any
|
||||
questions.
|
||||
-->
|
||||
|
||||
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
|
||||
"en-US">
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Collections Framework Overview</title>
|
||||
<style>
|
||||
#impls {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
margin: 0 auto;
|
||||
}
|
||||
#impls caption {
|
||||
font-weight: bold;
|
||||
font-size: smaller;
|
||||
}
|
||||
#impls, #impls th, #impls td {
|
||||
border: 1px solid black;
|
||||
padding: 2px .5em;
|
||||
}
|
||||
#impls tbody th {
|
||||
font-weight: normal;
|
||||
text-align:left;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Collections Framework Overview</h1>
|
||||
@ -73,7 +88,7 @@ interfaces form the basis of the framework.</li>
|
||||
<li><strong>General-purpose implementations</strong>. Primary
|
||||
implementations of the collection interfaces.</li>
|
||||
<li><strong>Legacy implementations</strong>. The collection classes
|
||||
from earlier releases, <tt>Vector</tt> and <tt>Hashtable</tt>, were
|
||||
from earlier releases, <code>Vector</code> and <code>Hashtable</code>, were
|
||||
retrofitted to implement the collection interfaces.</li>
|
||||
<li><strong>Special-purpose implementations</strong>.
|
||||
Implementations designed for use in special situations. These
|
||||
@ -101,57 +116,57 @@ relies on some of the same infrastructure.</li>
|
||||
<hr />
|
||||
<h2>Collection Interfaces</h2>
|
||||
<p>The <i>collection interfaces</i> are divided into two groups.
|
||||
The most basic interface, <tt><a href=
|
||||
"../Collection.html">java.util.Collection</a></tt>,
|
||||
The most basic interface, <code><a href=
|
||||
"../Collection.html">java.util.Collection</a></code>,
|
||||
has the following descendants:</p>
|
||||
<ul>
|
||||
<li><tt><a href=
|
||||
"../Set.html">java.util.Set</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../SortedSet.html">java.util.SortedSet</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../NavigableSet.html">java.util.NavigableSet</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../Queue.html">java.util.Queue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/BlockingQueue.html">java.util.concurrent.BlockingQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/TransferQueue.html">java.util.concurrent.TransferQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../Deque.html">java.util.Deque</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/BlockingDeque.html">java.util.concurrent.BlockingDeque</a></tt></li>
|
||||
<li><code><a href=
|
||||
"../Set.html">java.util.Set</a></code></li>
|
||||
<li><code><a href=
|
||||
"../SortedSet.html">java.util.SortedSet</a></code></li>
|
||||
<li><code><a href=
|
||||
"../NavigableSet.html">java.util.NavigableSet</a></code></li>
|
||||
<li><code><a href=
|
||||
"../Queue.html">java.util.Queue</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/BlockingQueue.html">java.util.concurrent.BlockingQueue</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/TransferQueue.html">java.util.concurrent.TransferQueue</a></code></li>
|
||||
<li><code><a href=
|
||||
"../Deque.html">java.util.Deque</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/BlockingDeque.html">java.util.concurrent.BlockingDeque</a></code></li>
|
||||
</ul>
|
||||
<p>The other collection interfaces are based on <tt><a href=
|
||||
"../Map.html">java.util.Map</a></tt> and are
|
||||
<p>The other collection interfaces are based on <code><a href=
|
||||
"../Map.html">java.util.Map</a></code> and are
|
||||
not true collections. However, these interfaces contain
|
||||
<i>collection-view</i> operations, which enable them to be
|
||||
manipulated as collections. <tt>Map</tt> has the following
|
||||
manipulated as collections. <code>Map</code> has the following
|
||||
offspring:</p>
|
||||
<ul>
|
||||
<li><tt><a href=
|
||||
"../SortedMap.html">java.util.SortedMap</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../NavigableMap.html">java.util.NavigableMap</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentMap.html">java.util.concurrent.ConcurrentMap</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentNavigableMap.html">java.util.concurrent.ConcurrentNavigableMap</a></tt></li>
|
||||
<li><code><a href=
|
||||
"../SortedMap.html">java.util.SortedMap</a></code></li>
|
||||
<li><code><a href=
|
||||
"../NavigableMap.html">java.util.NavigableMap</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/ConcurrentMap.html">java.util.concurrent.ConcurrentMap</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/ConcurrentNavigableMap.html">java.util.concurrent.ConcurrentNavigableMap</a></code></li>
|
||||
</ul>
|
||||
<p>Many of the modification methods in the collection interfaces
|
||||
are labeled <i>optional</i>. Implementations are permitted to not
|
||||
perform one or more of these operations, throwing a runtime
|
||||
exception (<tt>UnsupportedOperationException</tt>) if they are
|
||||
exception (<code>UnsupportedOperationException</code>) if they are
|
||||
attempted. The documentation for each implementation must specify
|
||||
which optional operations are supported. Several terms are
|
||||
introduced to aid in this specification:</p>
|
||||
<ul>
|
||||
<li>Collections that do not support modification operations (such
|
||||
as <tt>add</tt>, <tt>remove</tt> and <tt>clear</tt>) are referred
|
||||
as <code>add</code>, <code>remove</code> and <code>clear</code>) are referred
|
||||
to as <i>unmodifiable</i>. Collections that are not unmodifiable
|
||||
are <i>modifiable.</i></li>
|
||||
<li>Collections that additionally guarantee that no change in the
|
||||
<tt>Collection</tt> object will be visible are referred to as
|
||||
<code>Collection</code> object will be visible are referred to as
|
||||
<i>immutable</i>. Collections that are not immutable are
|
||||
<i>mutable</i>.</li>
|
||||
<li>Lists that guarantee that their size remains constant even
|
||||
@ -161,15 +176,15 @@ though the elements can change are referred to as
|
||||
<li>Lists that support fast (generally constant time) indexed
|
||||
element access are known as <i>random access</i> lists. Lists that
|
||||
do not support fast indexed element access are known as
|
||||
<i>sequential access</i> lists. The <tt><a href=
|
||||
"../RandomAccess.html">RandomAccess</a></tt>
|
||||
<i>sequential access</i> lists. The <code><a href=
|
||||
"../RandomAccess.html">RandomAccess</a></code>
|
||||
marker interface enables lists to advertise the fact that they
|
||||
support random access. This enables generic algorithms to change
|
||||
their behavior to provide good performance when applied to either
|
||||
random or sequential access lists.</li>
|
||||
</ul>
|
||||
<p>Some implementations restrict what elements (or in the case of
|
||||
<tt>Maps</tt>, keys and values) can be stored. Possible
|
||||
<code>Maps</code>, keys and values) can be stored. Possible
|
||||
restrictions include requiring elements to:</p>
|
||||
<ul>
|
||||
<li>Be of a particular type.</li>
|
||||
@ -178,77 +193,70 @@ restrictions include requiring elements to:</p>
|
||||
</ul>
|
||||
<p>Attempting to add an element that violates an implementation's
|
||||
restrictions results in a runtime exception, typically a
|
||||
<tt>ClassCastException</tt>, an <tt>IllegalArgumentException</tt>,
|
||||
or a <tt>NullPointerException</tt>. Attempting to remove or test
|
||||
<code>ClassCastException</code>, an <code>IllegalArgumentException</code>,
|
||||
or a <code>NullPointerException</code>. Attempting to remove or test
|
||||
for the presence of an element that violates an implementation's
|
||||
restrictions can result in an exception. Some restricted
|
||||
collections permit this usage.</p>
|
||||
<hr />
|
||||
<hr>
|
||||
<h2>Collection Implementations</h2>
|
||||
<p>Classes that implement the collection interfaces typically have
|
||||
names in the form of
|
||||
<<em>Implementation-style</em>><<em>Interface</em>>.
|
||||
The general purpose implementations are summarized in the following
|
||||
table:</p>
|
||||
<table border="2" summary=
|
||||
"general purpose implementations and interfaces" align="center">
|
||||
<table id="impls">
|
||||
<caption>General purpose implementations</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="interfaces">Interface</th>
|
||||
<th id="hashtable">Hash Table</th>
|
||||
<th id="resizablearray">Resizable Array</th>
|
||||
<th id="balancedtree">Balanced Tree</th>
|
||||
<th id="linkedlist">Linked List</th>
|
||||
<th id="hashtableandlinkedlist">Hash Table + Linked List</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="interfaces"><code>Set</code></td>
|
||||
<td headers="hashtable"><a href=
|
||||
"../HashSet.html"><tt>HashSet</tt></a></td>
|
||||
<td headers="resizablearray"> </td>
|
||||
<td headers="balancedtree"><a href=
|
||||
"../TreeSet.html"><tt>TreeSet</tt></a></td>
|
||||
<td headers="linkedlist"> </td>
|
||||
<td headers="hashtableandlinkedlist"><a href=
|
||||
"../LinkedHashSet.html"><tt>LinkedHashSet</tt></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="interfaces"><code>List</code></td>
|
||||
<td headers="hashtable"> </td>
|
||||
<td headers="resizablearray"><a href=
|
||||
"../ArrayList.html"><tt>ArrayList</tt></a></td>
|
||||
<td headers="balancedtree"> </td>
|
||||
<td headers="linkedlist"><a href=
|
||||
"../LinkedList.html"><tt>LinkedList</tt></a></td>
|
||||
<td headers="hashtableandlinkedlist"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="interfaces"><code>Deque</code></td>
|
||||
<td headers="hashtable"> </td>
|
||||
<td headers="resizablearray"><a href=
|
||||
"../ArrayDeque.html"><tt>ArrayDeque</tt></a></td>
|
||||
<td headers="balancedtree"> </td>
|
||||
<td headers="linkedlist"><a href=
|
||||
"../LinkedList.html"><tt>LinkedList</tt></a></td>
|
||||
<td headers="hashtableandlinkedlist"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="interfaces"><code>Map</code></td>
|
||||
<td headers="hashtable"><a href=
|
||||
"../HashMap.html"><tt>HashMap</tt></a></td>
|
||||
<td headers="resizablearray"> </td>
|
||||
<td headers="balancedtree"><a href=
|
||||
"../TreeMap.html"><tt>TreeMap</tt></a></td>
|
||||
<td headers="linkedlist"> </td>
|
||||
<td headers="hashtableandlinkedlist"><a href=
|
||||
"../LinkedHashMap.html"><tt>LinkedHashMap</tt></a></td>
|
||||
<th scope="col">Interface</th>
|
||||
<th scope="col">Hash Table</th>
|
||||
<th scope="col">Resizable Array</th>
|
||||
<th scope="col">Balanced Tree</th>
|
||||
<th scope="col">Linked List</th>
|
||||
<th scope="col">Hash Table + Linked List</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><code>Set</code></th>
|
||||
<td><a href="../HashSet.html"><code>HashSet</code></a></td>
|
||||
<td> </td>
|
||||
<td><a href="../TreeSet.html"><code>TreeSet</code></a></td>
|
||||
<td> </td>
|
||||
<td><a href=
|
||||
"../LinkedHashSet.html"><code>LinkedHashSet</code></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><code>List</code></th>
|
||||
<td> </td>
|
||||
<td><a href="../ArrayList.html"><code>ArrayList</code></a></td>
|
||||
<td> </td>
|
||||
<td><a href="../LinkedList.html"><code>LinkedList</code></a></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><code>Deque</code></th>
|
||||
<td> </td>
|
||||
<td><a href="../ArrayDeque.html"><code>ArrayDeque</code></a></td>
|
||||
<td> </td>
|
||||
<td><a href="../LinkedList.html"><code>LinkedList</code></a></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><code>Map</code></th>
|
||||
<td><a href="../HashMap.html"><code>HashMap</code></a></td>
|
||||
<td> </td>
|
||||
<td><a href="../TreeMap.html"><code>TreeMap</code></a></td>
|
||||
<td> </td>
|
||||
<td><a href="../LinkedHashMap.html"><code>LinkedHashMap</code></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The general-purpose implementations support all of the
|
||||
<i>optional operations</i> in the collection interfaces and have no
|
||||
restrictions on the elements they may contain. They are
|
||||
unsynchronized, but the <tt>Collections</tt> class contains static
|
||||
unsynchronized, but the <code>Collections</code> class contains static
|
||||
factories called <a href=
|
||||
"../Collections.html#synchronizedCollection-java.util.Collection-">
|
||||
<em>synchronization wrappers</em></a> that can be used to add
|
||||
@ -256,15 +264,15 @@ synchronization to many unsynchronized collections. All of the new
|
||||
implementations have <i>fail-fast iterators</i>, which detect
|
||||
invalid concurrent modification, and fail quickly and cleanly
|
||||
(rather than behaving erratically).</p>
|
||||
<p>The <tt>AbstractCollection</tt>, <tt>AbstractSet</tt>,
|
||||
<tt>AbstractList</tt>, <tt>AbstractSequentialList</tt> and
|
||||
<tt>AbstractMap</tt> classes provide basic implementations of the
|
||||
<p>The <code>AbstractCollection</code>, <code>AbstractSet</code>,
|
||||
<code>AbstractList</code>, <code>AbstractSequentialList</code> and
|
||||
<code>AbstractMap</code> classes provide basic implementations of the
|
||||
core collection interfaces, to minimize the effort required to
|
||||
implement them. The API documentation for these classes describes
|
||||
precisely how each method is implemented so the implementer knows
|
||||
which methods must be overridden, given the performance of the
|
||||
basic operations of a specific implementation.</p>
|
||||
<hr />
|
||||
<hr>
|
||||
<h2>Concurrent Collections</h2>
|
||||
<p>Applications that use collections from more than one thread must
|
||||
be carefully programmed. In general, this is known as <i>concurrent
|
||||
@ -279,47 +287,47 @@ discussed previously to provide features that are frequently needed
|
||||
in concurrent programming.</p>
|
||||
<p>These concurrent-aware interfaces are available:</p>
|
||||
<ul>
|
||||
<li><tt><a href=
|
||||
"../concurrent/BlockingQueue.html">BlockingQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/TransferQueue.html">TransferQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/BlockingDeque.html">BlockingDeque</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentMap.html">ConcurrentMap</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentNavigableMap.html">ConcurrentNavigableMap</a></tt></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/BlockingQueue.html">BlockingQueue</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/TransferQueue.html">TransferQueue</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/BlockingDeque.html">BlockingDeque</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/ConcurrentMap.html">ConcurrentMap</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/ConcurrentNavigableMap.html">ConcurrentNavigableMap</a></code></li>
|
||||
</ul>
|
||||
<p>The following concurrent-aware implementation classes are
|
||||
available. See the API documentation for the correct usage of these
|
||||
implementations.</p>
|
||||
<ul>
|
||||
<li><tt><a href=
|
||||
"../concurrent/LinkedBlockingQueue.html">LinkedBlockingQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ArrayBlockingQueue.html">ArrayBlockingQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/PriorityBlockingQueue.html">PriorityBlockingQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/DelayQueue.html">DelayQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/SynchronousQueue.html">SynchronousQueue</a></tt></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/LinkedBlockingQueue.html">LinkedBlockingQueue</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/ArrayBlockingQueue.html">ArrayBlockingQueue</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/PriorityBlockingQueue.html">PriorityBlockingQueue</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/DelayQueue.html">DelayQueue</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/SynchronousQueue.html">SynchronousQueue</a></code></li>
|
||||
<li><a href=
|
||||
"../concurrent/LinkedBlockingDeque.html"><tt>LinkedBlockingDeque</tt></a></li>
|
||||
"../concurrent/LinkedBlockingDeque.html"><code>LinkedBlockingDeque</code></a></li>
|
||||
<li><a href=
|
||||
"../concurrent/LinkedTransferQueue.html"><tt>LinkedTransferQueue</tt></a></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/CopyOnWriteArrayList.html">CopyOnWriteArrayList</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/CopyOnWriteArraySet.html">CopyOnWriteArraySet</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentSkipListSet.html">ConcurrentSkipListSet</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentHashMap.html">ConcurrentHashMap</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentSkipListMap.html">ConcurrentSkipListMap</a></tt></li>
|
||||
"../concurrent/LinkedTransferQueue.html"><code>LinkedTransferQueue</code></a></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/CopyOnWriteArrayList.html">CopyOnWriteArrayList</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/CopyOnWriteArraySet.html">CopyOnWriteArraySet</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/ConcurrentSkipListSet.html">ConcurrentSkipListSet</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/ConcurrentHashMap.html">ConcurrentHashMap</a></code></li>
|
||||
<li><code><a href=
|
||||
"../concurrent/ConcurrentSkipListMap.html">ConcurrentSkipListMap</a></code></li>
|
||||
</ul>
|
||||
<hr />
|
||||
<hr>
|
||||
<h2>Design Goals</h2>
|
||||
<p>The main design goal was to produce an API that was small in
|
||||
size and, more importantly, in "conceptual weight." It
|
||||
@ -332,7 +340,7 @@ previously.</p>
|
||||
not attempt to capture such subtle distinctions as mutability,
|
||||
modifiability, and resizability. Instead, certain calls in the core
|
||||
interfaces are <i>optional</i>, enabling implementations to throw
|
||||
an <tt>UnsupportedOperationException</tt> to indicate that they do
|
||||
an <code>UnsupportedOperationException</code> to indicate that they do
|
||||
not support a specified optional operation. Collection implementers
|
||||
must clearly document which optional operations are supported by an
|
||||
implementation.</p>
|
||||
@ -346,13 +354,13 @@ implementation would want to override it.</li>
|
||||
</ul>
|
||||
<p>It was critical that all reasonable representations of
|
||||
collections interoperate well. This included arrays, which cannot
|
||||
be made to implement the <tt>Collection</tt> interface directly
|
||||
be made to implement the <code>Collection</code> interface directly
|
||||
without changing the language. Thus, the framework includes methods
|
||||
to enable collections to be moved into arrays, arrays to be viewed
|
||||
as collections, and maps to be viewed as collections.</p>
|
||||
<hr />
|
||||
<hr>
|
||||
<p style="font-size:smaller">
|
||||
Copyright © 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
|
||||
Copyright © 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br>
|
||||
Redwood Shores, CA 94065 USA. All rights reserved.</p>
|
||||
<!-- Body text ends here -->
|
||||
</body>
|
||||
|
@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -27,10 +24,10 @@
|
||||
questions.
|
||||
-->
|
||||
|
||||
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
|
||||
"en-US">
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Outline of the Collections Framework</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Outline of the Collections Framework</h1>
|
||||
@ -48,21 +45,21 @@ elements.</li>
|
||||
<li><a href=
|
||||
"../Set.html"><strong>Set</strong></a> - The
|
||||
familiar set abstraction. No duplicate elements permitted. May or
|
||||
may not be ordered. Extends the <tt>Collection</tt> interface.</li>
|
||||
may not be ordered. Extends the <code>Collection</code> interface.</li>
|
||||
<li><a href=
|
||||
"../List.html"><strong>List</strong></a> -
|
||||
Ordered collection, also known as a <i>sequence</i>. Duplicates are
|
||||
generally permitted. Allows positional access. Extends the
|
||||
<tt>Collection</tt> interface.</li>
|
||||
<code>Collection</code> interface.</li>
|
||||
<li><a href=
|
||||
"../Queue.html"><strong>Queue</strong></a> - A
|
||||
collection designed for holding elements before processing. Besides
|
||||
basic <tt>Collection</tt> operations, queues provide additional
|
||||
basic <code>Collection</code> operations, queues provide additional
|
||||
insertion, extraction, and inspection operations.</li>
|
||||
<li><a href=
|
||||
"../Deque.html"><strong>Deque</strong></a> - A
|
||||
<em>double ended queue</em>, supporting element insertion and
|
||||
removal at both ends. Extends the <tt>Queue</tt> interface.</li>
|
||||
removal at both ends. Extends the <code>Queue</code> interface.</li>
|
||||
<li><a href=
|
||||
"../Map.html"><strong>Map</strong></a> - A
|
||||
mapping from keys to values. Each key can map to one value.</li>
|
||||
@ -70,62 +67,62 @@ mapping from keys to values. Each key can map to one value.</li>
|
||||
"../SortedSet.html"><strong>SortedSet</strong></a>
|
||||
- A set whose elements are automatically sorted, either in their
|
||||
<i>natural ordering</i> (see the <a href=
|
||||
"../../lang/Comparable.html"><tt>Comparable</tt></a>
|
||||
"../../lang/Comparable.html"><code>Comparable</code></a>
|
||||
interface) or by a <a href=
|
||||
"../Comparator.html"><tt>Comparator</tt></a>
|
||||
object provided when a <tt>SortedSet</tt> instance is created.
|
||||
Extends the <tt>Set</tt> interface.</li>
|
||||
"../Comparator.html"><code>Comparator</code></a>
|
||||
object provided when a <code>SortedSet</code> instance is created.
|
||||
Extends the <code>Set</code> interface.</li>
|
||||
<li><a href=
|
||||
"../SortedMap.html"><strong>SortedMap</strong></a>
|
||||
- A map whose mappings are automatically sorted by key, either
|
||||
using the <i>natural ordering</i> of the keys or by a comparator
|
||||
provided when a <tt>SortedMap</tt> instance is created. Extends the
|
||||
<tt>Map</tt> interface.</li>
|
||||
provided when a <code>SortedMap</code> instance is created. Extends the
|
||||
<code>Map</code> interface.</li>
|
||||
<li><a href=
|
||||
"../NavigableSet.html"><strong>NavigableSet</strong></a>
|
||||
- A <tt>SortedSet</tt> extended with navigation methods reporting
|
||||
closest matches for given search targets. A <tt>NavigableSet</tt>
|
||||
- A <code>SortedSet</code> extended with navigation methods reporting
|
||||
closest matches for given search targets. A <code>NavigableSet</code>
|
||||
may be accessed and traversed in either ascending or descending
|
||||
order.</li>
|
||||
<li><a href=
|
||||
"../NavigableMap.html"><strong>NavigableMap</strong></a>
|
||||
- A <tt>SortedMap</tt> extended with navigation methods returning
|
||||
- A <code>SortedMap</code> extended with navigation methods returning
|
||||
the closest matches for given search targets. A
|
||||
<tt>NavigableMap</tt> can be accessed and traversed in either
|
||||
<code>NavigableMap</code> can be accessed and traversed in either
|
||||
ascending or descending key order.</li>
|
||||
<li><a href=
|
||||
"../concurrent/BlockingQueue.html"><strong>BlockingQueue</strong></a>
|
||||
- A <tt>Queue</tt> with operations that wait for the queue to
|
||||
- A <code>Queue</code> with operations that wait for the queue to
|
||||
become nonempty when retrieving an element and that wait for space
|
||||
to become available in the queue when storing an element. (This
|
||||
interface is part of the <tt><a href=
|
||||
"../concurrent/package-summary.html">java.util.concurrent</a></tt>
|
||||
interface is part of the <code><a href=
|
||||
"../concurrent/package-summary.html">java.util.concurrent</a></code>
|
||||
package.)</li>
|
||||
<li><a href=
|
||||
"../concurrent/TransferQueue.html"><strong>TransferQueue</strong></a>
|
||||
- A <tt>BlockingQueue</tt> in which producers can wait for
|
||||
- A <code>BlockingQueue</code> in which producers can wait for
|
||||
consumers to receive elements. (This interface is part of the
|
||||
<tt><a href=
|
||||
"../concurrent/package-summary.html">java.util.concurrent</a></tt>
|
||||
<code><a href=
|
||||
"../concurrent/package-summary.html">java.util.concurrent</a></code>
|
||||
package.)</li>
|
||||
<li><a href=
|
||||
"../concurrent/BlockingDeque.html"><strong>BlockingDeque</strong></a>
|
||||
- A <tt>Deque</tt> with operations that wait for the deque to
|
||||
- A <code>Deque</code> with operations that wait for the deque to
|
||||
become nonempty when retrieving an element and wait for space to
|
||||
become available in the deque when storing an element. Extends both
|
||||
the <tt>Deque</tt> and <tt>BlockingQueue</tt> interfaces. (This
|
||||
interface is part of the <tt><a href=
|
||||
"../concurrent/package-summary.html">java.util.concurrent</a></tt>
|
||||
the <code>Deque</code> and <code>BlockingQueue</code> interfaces. (This
|
||||
interface is part of the <code><a href=
|
||||
"../concurrent/package-summary.html">java.util.concurrent</a></code>
|
||||
package.)</li>
|
||||
<li><a href=
|
||||
"../concurrent/ConcurrentMap.html"><strong>ConcurrentMap</strong></a>
|
||||
- A <tt>Map</tt> with atomic <tt>putIfAbsent</tt>, <tt>remove</tt>,
|
||||
and <tt>replace</tt> methods. (This interface is part of the
|
||||
<tt>java.util.concurrent</tt> package.)</li>
|
||||
- A <code>Map</code> with atomic <code>putIfAbsent</code>, <code>remove</code>,
|
||||
and <code>replace</code> methods. (This interface is part of the
|
||||
<code>java.util.concurrent</code> package.)</li>
|
||||
<li><a href=
|
||||
"../concurrent/ConcurrentNavigableMap.html"><strong>
|
||||
ConcurrentNavigableMap</strong></a> - A <tt>ConcurrentMap</tt> that
|
||||
is also a <tt>NavigableMap</tt>.</li>
|
||||
ConcurrentNavigableMap</strong></a> - A <code>ConcurrentMap</code> that
|
||||
is also a <code>NavigableMap</code>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>General-purpose implementations</strong> - The primary
|
||||
@ -133,52 +130,52 @@ implementations of the collection interfaces.
|
||||
<ul>
|
||||
<li><strong><a href=
|
||||
"../HashSet.html">HashSet</a></strong> - Hash
|
||||
table implementation of the <tt>Set</tt> interface. The best
|
||||
all-around implementation of the <tt>Set</tt> interface.</li>
|
||||
table implementation of the <code>Set</code> interface. The best
|
||||
all-around implementation of the <code>Set</code> interface.</li>
|
||||
<li><a href=
|
||||
"../TreeSet.html"><strong>TreeSet</strong></a>
|
||||
- Red-black tree implementation of the <tt>NavigableSet</tt>
|
||||
- Red-black tree implementation of the <code>NavigableSet</code>
|
||||
interface.</li>
|
||||
<li><strong><a href=
|
||||
"../LinkedHashSet.html">LinkedHashSet</a></strong>
|
||||
- Hash table and linked list implementation of the <tt>Set</tt>
|
||||
interface. An insertion-ordered <tt>Set</tt> implementation that
|
||||
runs nearly as fast as <tt>HashSet</tt>.</li>
|
||||
- Hash table and linked list implementation of the <code>Set</code>
|
||||
interface. An insertion-ordered <code>Set</code> implementation that
|
||||
runs nearly as fast as <code>HashSet</code>.</li>
|
||||
<li><strong><a href=
|
||||
"../ArrayList.html">ArrayList</a></strong> -
|
||||
Resizable array implementation of the <tt>List</tt> interface (an
|
||||
unsynchronized <tt>Vector</tt>). The best all-around implementation
|
||||
of the <tt>List</tt> interface.</li>
|
||||
Resizable array implementation of the <code>List</code> interface (an
|
||||
unsynchronized <code>Vector</code>). The best all-around implementation
|
||||
of the <code>List</code> interface.</li>
|
||||
<li><strong><a href=
|
||||
"../ArrayDeque.html">ArrayDeque</a></strong> -
|
||||
Efficient, resizable array implementation of the <tt>Deque</tt>
|
||||
Efficient, resizable array implementation of the <code>Deque</code>
|
||||
interface.</li>
|
||||
<li><a href=
|
||||
"../LinkedList.html"><strong>LinkedList</strong></a>
|
||||
- Doubly-linked list implementation of the <tt>List</tt> interface.
|
||||
Provides better performance than the <tt>ArrayList</tt>
|
||||
- Doubly-linked list implementation of the <code>List</code> interface.
|
||||
Provides better performance than the <code>ArrayList</code>
|
||||
implementation if elements are frequently inserted or deleted
|
||||
within the list. Also implements the <tt>Deque</tt> interface. When
|
||||
accessed through the <tt>Queue</tt> interface, <tt>LinkedList</tt>
|
||||
within the list. Also implements the <code>Deque</code> interface. When
|
||||
accessed through the <code>Queue</code> interface, <code>LinkedList</code>
|
||||
acts as a FIFO queue.</li>
|
||||
<li><strong><a href=
|
||||
"../PriorityQueue.html">PriorityQueue</a></strong>
|
||||
- Heap implementation of an unbounded priority queue.</li>
|
||||
<li><strong><a href=
|
||||
"../HashMap.html">HashMap</a></strong> - Hash
|
||||
table implementation of the <tt>Map</tt> interface (an
|
||||
unsynchronized <tt>Hashtable</tt> that supports <tt>null</tt> keys
|
||||
and values). The best all-around implementation of the <tt>Map</tt>
|
||||
table implementation of the <code>Map</code> interface (an
|
||||
unsynchronized <code>Hashtable</code> that supports <code>null</code> keys
|
||||
and values). The best all-around implementation of the <code>Map</code>
|
||||
interface.</li>
|
||||
<li><a href=
|
||||
"../TreeMap.html"><strong>TreeMap</strong></a>
|
||||
Red-black tree implementation of the <tt>NavigableMap</tt>
|
||||
Red-black tree implementation of the <code>NavigableMap</code>
|
||||
interface.</li>
|
||||
<li><strong><a href=
|
||||
"../LinkedHashMap.html">LinkedHashMap</a></strong>
|
||||
- Hash table and linked list implementation of the <tt>Map</tt>
|
||||
interface. An insertion-ordered <tt>Map</tt> implementation that
|
||||
runs nearly as fast as <tt>HashMap</tt>. Also useful for building
|
||||
- Hash table and linked list implementation of the <code>Map</code>
|
||||
interface. An insertion-ordered <code>Map</code> implementation that
|
||||
runs nearly as fast as <code>HashMap</code>. Also useful for building
|
||||
caches (see <a href=
|
||||
"../LinkedHashMap.html#removeEldestEntry-java.util.Map.Entry-">
|
||||
removeEldestEntry(Map.Entry)</a> ).</li>
|
||||
@ -192,9 +189,9 @@ implementations. Accessed solely through static factory methods.
|
||||
"../Collections.html#unmodifiableCollection-java.util.Collection-">
|
||||
<strong>Collections.unmodifiable<i>Interface</i></strong></a> -
|
||||
Returns an unmodifiable view of a specified collection that throws
|
||||
an <tt>UnsupportedOperationException</tt> if the user attempts to
|
||||
an <code>UnsupportedOperationException</code> if the user attempts to
|
||||
modify it.</li>
|
||||
<li><a name="synchWrappers" href=
|
||||
<li><a href=
|
||||
"../Collections.html#synchronizedCollection-java.util.Collection-"
|
||||
id=
|
||||
"synchWrappers"><strong>Collections.synchronized<i>Interface</i></strong></a>
|
||||
@ -206,7 +203,7 @@ safety is guaranteed.</li>
|
||||
"../Collections.html#checkedCollection-java.util.Collection-java.lang.Class-">
|
||||
<strong>Collections.checked<i>Interface</i></strong></a> - Returns
|
||||
a dynamically type-safe view of the specified collection, which
|
||||
throws a <tt>ClassCastException</tt> if a client attempts to add an
|
||||
throws a <code>ClassCastException</code> if a client attempts to add an
|
||||
element of the wrong type. The generics mechanism in the language
|
||||
provides compile-time (static) type checking, but it is possible to
|
||||
bypass this mechanism. Dynamically type-safe views eliminate this
|
||||
@ -219,12 +216,12 @@ adapt one collections interface to another:
|
||||
<li><strong><a href=
|
||||
"../Collections.html#newSetFromMap-java.util.Map-">
|
||||
newSetFromMap(Map)</a></strong> - Creates a general-purpose
|
||||
<tt>Set</tt> implementation from a general-purpose <tt>Map</tt>
|
||||
<code>Set</code> implementation from a general-purpose <code>Map</code>
|
||||
implementation.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#asLifoQueue-java.util.Deque-">
|
||||
asLifoQueue(Deque)</a></strong> - Returns a view of a
|
||||
<tt>Deque</tt> as a Last In First Out (LIFO) <tt>Queue</tt>.</li>
|
||||
<code>Deque</code> as a Last In First Out (LIFO) <code>Queue</code>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Convenience implementations</strong> - High-performance
|
||||
@ -259,12 +256,12 @@ classes were retrofitted to implement the collection interfaces.
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../Vector.html"><strong>Vector</strong></a> -
|
||||
Synchronized resizable array implementation of the <tt>List</tt>
|
||||
Synchronized resizable array implementation of the <code>List</code>
|
||||
interface with additional legacy methods.</li>
|
||||
<li><a href=
|
||||
"../Hashtable.html"><strong>Hashtable</strong></a>
|
||||
- Synchronized hash table implementation of the <tt>Map</tt>
|
||||
interface that does not allow <tt>null</tt> keys or values, plus
|
||||
- Synchronized hash table implementation of the <code>Map</code>
|
||||
interface that does not allow <code>null</code> keys or values, plus
|
||||
additional legacy methods.</li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -272,18 +269,18 @@ additional legacy methods.</li>
|
||||
<ul>
|
||||
<li><strong><a href=
|
||||
"../WeakHashMap.html">WeakHashMap</a></strong>
|
||||
- An implementation of the <tt>Map</tt> interface that stores only
|
||||
- An implementation of the <code>Map</code> interface that stores only
|
||||
<a href="../../lang/ref/WeakReference.html"><i>weak
|
||||
references</i></a> to its keys. Storing only weak references
|
||||
enables key-value pairs to be garbage collected when the key is no
|
||||
longer referenced outside of the <tt>WeakHashMap</tt>. This class
|
||||
longer referenced outside of the <code>WeakHashMap</code>. This class
|
||||
is the easiest way to use the power of weak references. It is
|
||||
useful for implementing registry-like data structures, where the
|
||||
utility of an entry vanishes when its key is no longer reachable by
|
||||
any thread.</li>
|
||||
<li><strong><a href=
|
||||
"../IdentityHashMap.html">IdentityHashMap</a></strong>
|
||||
- Identity-based <tt>Map</tt> implementation based on a hash table.
|
||||
- Identity-based <code>Map</code> implementation based on a hash table.
|
||||
This class is useful for topology-preserving object graph
|
||||
transformations (such as serialization or deep copying). To perform
|
||||
these transformations, you must maintain an identity-based "node
|
||||
@ -292,43 +289,43 @@ Identity-based maps are also used to maintain
|
||||
object-to-meta-information mappings in dynamic debuggers and
|
||||
similar systems. Finally, identity-based maps are useful in
|
||||
preventing "spoof attacks" resulting from intentionally perverse
|
||||
equals methods. (<tt>IdentityHashMap</tt> never invokes the equals
|
||||
equals methods. (<code>IdentityHashMap</code> never invokes the equals
|
||||
method on its keys.) An added benefit of this implementation is
|
||||
that it is fast.</li>
|
||||
<li><strong><a href=
|
||||
"../concurrent/CopyOnWriteArrayList.html">CopyOnWriteArrayList</a></strong>
|
||||
- A <tt>List</tt> implementation backed by an copy-on-write array.
|
||||
All mutative operations (such as <tt>add</tt>, <tt>set</tt>, and
|
||||
<tt>remove</tt>) are implemented by making a new copy of the array.
|
||||
- A <code>List</code> implementation backed by an copy-on-write array.
|
||||
All mutative operations (such as <code>add</code>, <code>set</code>, and
|
||||
<code>remove</code>) are implemented by making a new copy of the array.
|
||||
No synchronization is necessary, even during iteration, and
|
||||
iterators are guaranteed never to throw
|
||||
<tt>ConcurrentModificationException</tt>. This implementation is
|
||||
<code>ConcurrentModificationException</code>. This implementation is
|
||||
well-suited to maintaining event-handler lists (where change is
|
||||
infrequent, and traversal is frequent and potentially
|
||||
time-consuming).</li>
|
||||
<li><strong><a href=
|
||||
"../concurrent/CopyOnWriteArraySet.html">CopyOnWriteArraySet</a></strong>
|
||||
- A <tt>Set</tt> implementation backed by a copy-on-write array.
|
||||
This implementation is similar to <tt>CopyOnWriteArrayList</tt>.
|
||||
Unlike most <tt>Set</tt> implementations, the <tt>add</tt>,
|
||||
<tt>remove</tt>, and <tt>contains</tt> methods require time
|
||||
- A <code>Set</code> implementation backed by a copy-on-write array.
|
||||
This implementation is similar to <code>CopyOnWriteArrayList</code>.
|
||||
Unlike most <code>Set</code> implementations, the <code>add</code>,
|
||||
<code>remove</code>, and <code>contains</code> methods require time
|
||||
proportional to the size of the set. This implementation is well
|
||||
suited to maintaining event-handler lists that must prevent
|
||||
duplicates.</li>
|
||||
<li><strong><a href=
|
||||
"../EnumSet.html">EnumSet</a></strong> - A
|
||||
high-performance <tt>Set</tt> implementation backed by a bit
|
||||
vector. All elements of each <tt>EnumSet</tt> instance must be
|
||||
high-performance <code>Set</code> implementation backed by a bit
|
||||
vector. All elements of each <code>EnumSet</code> instance must be
|
||||
elements of a single enum type.</li>
|
||||
<li><strong><a href=
|
||||
"../EnumMap.html">EnumMap</a></strong> - A
|
||||
high-performance <tt>Map</tt> implementation backed by an array.
|
||||
All keys in each <tt>EnumMap</tt> instance must be elements of a
|
||||
high-performance <code>Map</code> implementation backed by an array.
|
||||
All keys in each <code>EnumMap</code> instance must be elements of a
|
||||
single enum type.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Concurrent implementations</strong> - These
|
||||
implementations are part of <tt>java.util.concurrent</tt>.
|
||||
implementations are part of <code>java.util.concurrent</code>.
|
||||
<ul>
|
||||
<li><strong><a href=
|
||||
"../concurrent/ConcurrentLinkedQueue.html">ConcurrentLinkedQueue</a></strong>
|
||||
@ -352,7 +349,7 @@ queue backed by a priority heap.</li>
|
||||
<li><a href=
|
||||
"../concurrent/SynchronousQueue.html"><strong>SynchronousQueue</strong></a>
|
||||
- A simple rendezvous mechanism that uses the
|
||||
<tt>BlockingQueue</tt> interface.</li>
|
||||
<code>BlockingQueue</code> interface.</li>
|
||||
<li><a href=
|
||||
"../concurrent/LinkedBlockingDeque.html"><strong>
|
||||
LinkedBlockingDeque</strong></a> - An optionally bounded FIFO
|
||||
@ -360,25 +357,25 @@ blocking deque backed by linked nodes.</li>
|
||||
<li><a href=
|
||||
"../concurrent/LinkedTransferQueue.html"><strong>
|
||||
LinkedTransferQueue</strong></a> - An unbounded
|
||||
<tt>TransferQueue</tt> backed by linked nodes.</li>
|
||||
<code>TransferQueue</code> backed by linked nodes.</li>
|
||||
<li><a href=
|
||||
"../concurrent/ConcurrentHashMap.html"><strong>ConcurrentHashMap</strong></a>
|
||||
- A highly concurrent, high-performance <tt>ConcurrentMap</tt>
|
||||
- A highly concurrent, high-performance <code>ConcurrentMap</code>
|
||||
implementation based on a hash table. This implementation never
|
||||
blocks when performing retrievals and enables the client to select
|
||||
the concurrency level for updates. It is intended as a drop-in
|
||||
replacement for <tt><a href=
|
||||
"../Hashtable.html">Hashtable</a></tt>. In
|
||||
addition to implementing <tt>ConcurrentMap</tt>, it supports all of
|
||||
the legacy methods of <tt>Hashtable</tt>.</li>
|
||||
replacement for <code><a href=
|
||||
"../Hashtable.html">Hashtable</a></code>. In
|
||||
addition to implementing <code>ConcurrentMap</code>, it supports all of
|
||||
the legacy methods of <code>Hashtable</code>.</li>
|
||||
<li><a href=
|
||||
"../concurrent/ConcurrentSkipListSet.html"><strong>
|
||||
ConcurrentSkipListSet</strong></a> - Skips list implementation of
|
||||
the <tt>NavigableSet</tt> interface.</li>
|
||||
the <code>NavigableSet</code> interface.</li>
|
||||
<li><a href=
|
||||
"../concurrent/ConcurrentSkipListMap.html"><strong>
|
||||
ConcurrentSkipListMap</strong></a> - Skips list implementation of
|
||||
the <tt>ConcurrentNavigableMap</tt> interface.</li>
|
||||
the <code>ConcurrentNavigableMap</code> interface.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Abstract implementations</strong> - Skeletal
|
||||
@ -387,25 +384,25 @@ implementations.
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../AbstractCollection.html"><strong>AbstractCollection</strong></a>
|
||||
- Skeletal <tt>Collection</tt> implementation that is neither a set
|
||||
- Skeletal <code>Collection</code> implementation that is neither a set
|
||||
nor a list (such as a "bag" or multiset).</li>
|
||||
<li><a href=
|
||||
"../AbstractSet.html"><strong>AbstractSet</strong></a>
|
||||
- Skeletal <tt>Set</tt> implementation.</li>
|
||||
- Skeletal <code>Set</code> implementation.</li>
|
||||
<li><a href=
|
||||
"../AbstractList.html"><strong>AbstractList</strong></a>
|
||||
- Skeletal <tt>List</tt> implementation backed by a random access
|
||||
- Skeletal <code>List</code> implementation backed by a random access
|
||||
data store (such as an array).</li>
|
||||
<li><a href=
|
||||
"../AbstractSequentialList.html"><strong>AbstractSequentialList</strong></a>
|
||||
- Skeletal <tt>List</tt> implementation backed by a sequential
|
||||
- Skeletal <code>List</code> implementation backed by a sequential
|
||||
access data store (such as a linked list).</li>
|
||||
<li><a href=
|
||||
"../AbstractQueue.html"><strong>AbstractQueue</strong></a>
|
||||
- Skeletal <tt>Queue</tt> implementation.</li>
|
||||
- Skeletal <code>Queue</code> implementation.</li>
|
||||
<li><a href=
|
||||
"../AbstractMap.html"><strong>AbstractMap</strong></a>
|
||||
- Skeletal <tt>Map</tt> implementation.</li>
|
||||
- Skeletal <code>Map</code> implementation.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Algorithms</strong> - The <a href=
|
||||
@ -491,13 +488,13 @@ interface, but more powerful, and with improved method names.
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../Iterator.html"><strong>Iterator</strong></a>
|
||||
- In addition to the functionality of the <tt>Enumeration</tt>
|
||||
- In addition to the functionality of the <code>Enumeration</code>
|
||||
interface, enables the user to remove elements from the backing
|
||||
collection with well-defined, useful semantics.</li>
|
||||
<li><a href=
|
||||
"../ListIterator.html"><strong>ListIterator</strong></a>
|
||||
- Iterator for use with lists. In addition to the functionality of
|
||||
the <tt>Iterator</tt> interface, supports bidirectional iteration,
|
||||
the <code>Iterator</code> interface, supports bidirectional iteration,
|
||||
element replacement, element insertion, and index retrieval.</li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -514,7 +511,7 @@ this interface.</li>
|
||||
- Represents an order relation, which can be used to sort a list or
|
||||
maintain order in a sorted set or map. Can override a type's
|
||||
natural ordering or order objects of a type that does not implement
|
||||
the <tt>Comparable</tt> interface.</li>
|
||||
the <code>Comparable</code> interface.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Runtime exceptions</strong>
|
||||
@ -536,7 +533,7 @@ unexpectedly.</li>
|
||||
<ul>
|
||||
<li><strong><a href=
|
||||
"../RandomAccess.html">RandomAccess</a></strong>
|
||||
- Marker interface that lets <tt>List</tt> implementations indicate
|
||||
- Marker interface that lets <code>List</code> implementations indicate
|
||||
that they support fast (generally constant time) random access.
|
||||
This lets generic algorithms change their behavior to provide good
|
||||
performance when applied to either random or sequential access
|
||||
@ -550,14 +547,14 @@ lists.</li>
|
||||
<li><a href=
|
||||
"../Arrays.html"><strong>Arrays</strong></a> -
|
||||
Contains static methods to sort, search, compare, hash, copy,
|
||||
resize, convert to <tt>String</tt>, and fill arrays of primitives
|
||||
resize, convert to <code>String</code>, and fill arrays of primitives
|
||||
and objects.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<hr>
|
||||
<p style="font-size:smaller">
|
||||
Copyright © 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
|
||||
Copyright © 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br>
|
||||
Redwood Shores, CA 94065 USA. All rights reserved.</p>
|
||||
<!-- Body text ends here -->
|
||||
</body>
|
||||
|
@ -25,21 +25,36 @@
|
||||
|
||||
package java.util.jar;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
import java.util.zip.*;
|
||||
import java.security.CodeSigner;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.CodeSource;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import sun.security.util.ManifestEntryVerifier;
|
||||
import sun.security.util.SignatureFileVerifier;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.net.URL;
|
||||
import java.security.CodeSigner;
|
||||
import java.security.CodeSource;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* The {@code JarFile} class is used to read the contents of a jar file
|
||||
* from any file that can be opened with {@code java.io.RandomAccessFile}.
|
||||
@ -848,7 +863,7 @@ class JarFile extends ZipFile {
|
||||
private static final byte[] MULTIRELEASE_OPTOSFT;
|
||||
|
||||
static {
|
||||
CLASSPATH_LASTOCC = new byte[64];
|
||||
CLASSPATH_LASTOCC = new byte[65];
|
||||
CLASSPATH_OPTOSFT = new byte[12];
|
||||
CLASSPATH_LASTOCC[(int)'C' - 32] = 1;
|
||||
CLASSPATH_LASTOCC[(int)'L' - 32] = 2;
|
||||
@ -865,7 +880,7 @@ class JarFile extends ZipFile {
|
||||
}
|
||||
CLASSPATH_OPTOSFT[11] = 1;
|
||||
|
||||
MULTIRELEASE_LASTOCC = new byte[64];
|
||||
MULTIRELEASE_LASTOCC = new byte[65];
|
||||
MULTIRELEASE_OPTOSFT = new byte[19];
|
||||
MULTIRELEASE_LASTOCC[(int)'M' - 32] = 1;
|
||||
MULTIRELEASE_LASTOCC[(int)'I' - 32] = 5;
|
||||
|
@ -81,309 +81,296 @@ import java.util.stream.StreamSupport;
|
||||
*
|
||||
* <table class="borderless">
|
||||
* <caption style="display:none">Regular expression constructs, and what they match</caption>
|
||||
* <thead>
|
||||
* <tr style="text-align:left">
|
||||
* <th style="text-align:left" id="construct">Construct</th>
|
||||
* <th style="text-align:left" id="matches">Matches</th>
|
||||
* <thead style="text-align:left">
|
||||
* <tr>
|
||||
* <th id="construct">Construct</th>
|
||||
* <th id="matches">Matches</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tbody style="text-align:left">
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="characters">Characters</th></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="characters">Characters</th></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top" headers="construct characters"><i>x</i></td>
|
||||
* <td headers="matches">The character <i>x</i></td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters">{@code \\}</td>
|
||||
* <td headers="matches">The backslash character</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters">{@code \0}<i>n</i></td>
|
||||
* <td headers="matches">The character with octal value {@code 0}<i>n</i>
|
||||
* <tr><th style="vertical-align:top; font-weight: normal" id="x"><i>x</i></th>
|
||||
* <td headers="matches characters x">The character <i>x</i></td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight: normal" id="backslash">{@code \\}</th>
|
||||
* <td headers="matches characters backslash">The backslash character</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight: normal" id="octal_n">{@code \0}<i>n</i></th>
|
||||
* <td headers="matches characters octal_n">The character with octal value {@code 0}<i>n</i>
|
||||
* (0 {@code <=} <i>n</i> {@code <=} 7)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters">{@code \0}<i>nn</i></td>
|
||||
* <td headers="matches">The character with octal value {@code 0}<i>nn</i>
|
||||
* <tr><th style="vertical-align:top; font-weight: normal" id="octal_nn">{@code \0}<i>nn</i></th>
|
||||
* <td headers="matches characters octal_nn">The character with octal value {@code 0}<i>nn</i>
|
||||
* (0 {@code <=} <i>n</i> {@code <=} 7)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters">{@code \0}<i>mnn</i></td>
|
||||
* <td headers="matches">The character with octal value {@code 0}<i>mnn</i>
|
||||
* <tr><th style="vertical-align:top; font-weight: normal" id="octal_nnn">{@code \0}<i>mnn</i></th>
|
||||
* <td headers="matches characters octal_nnn">The character with octal value {@code 0}<i>mnn</i>
|
||||
* (0 {@code <=} <i>m</i> {@code <=} 3,
|
||||
* 0 {@code <=} <i>n</i> {@code <=} 7)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters">{@code \x}<i>hh</i></td>
|
||||
* <td headers="matches">The character with hexadecimal value {@code 0x}<i>hh</i></td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters"><code>\u</code><i>hhhh</i></td>
|
||||
* <td headers="matches">The character with hexadecimal value {@code 0x}<i>hhhh</i></td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters"><code>\x</code><i>{h...h}</i></td>
|
||||
* <td headers="matches">The character with hexadecimal value {@code 0x}<i>h...h</i>
|
||||
* <tr><th style="vertical-align:top; font-weight: normal" id="hex_hh">{@code \x}<i>hh</i></th>
|
||||
* <td headers="matches characters hex_hh">The character with hexadecimal value {@code 0x}<i>hh</i></td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight: normal" id="hex_hhhh"><code>\u</code><i>hhhh</i></th>
|
||||
* <td headers="matches characters hex_hhhh">The character with hexadecimal value {@code 0x}<i>hhhh</i></td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight: normal" id="hex_h_h"><code>\x</code><i>{h...h}</i></th>
|
||||
* <td headers="matches characters hex_h_h">The character with hexadecimal value {@code 0x}<i>h...h</i>
|
||||
* ({@link java.lang.Character#MIN_CODE_POINT Character.MIN_CODE_POINT}
|
||||
* <= {@code 0x}<i>h...h</i> <=
|
||||
* {@link java.lang.Character#MAX_CODE_POINT Character.MAX_CODE_POINT})</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters"><code>\N{</code><i>name</i><code>}</code></td>
|
||||
* <td headers="matches">The character with Unicode character name <i>'name'</i></td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="matches">{@code \t}</td>
|
||||
* <td headers="matches">The tab character (<code>'\u0009'</code>)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters">{@code \n}</td>
|
||||
* <td headers="matches">The newline (line feed) character (<code>'\u000A'</code>)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters">{@code \r}</td>
|
||||
* <td headers="matches">The carriage-return character (<code>'\u000D'</code>)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters">{@code \f}</td>
|
||||
* <td headers="matches">The form-feed character (<code>'\u000C'</code>)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters">{@code \a}</td>
|
||||
* <td headers="matches">The alert (bell) character (<code>'\u0007'</code>)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters">{@code \e}</td>
|
||||
* <td headers="matches">The escape character (<code>'\u001B'</code>)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct characters">{@code \c}<i>x</i></td>
|
||||
* <td headers="matches">The control character corresponding to <i>x</i></td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight: normal" id="unicode_name"><code>\N{</code><i>name</i><code>}</code></th>
|
||||
* <td headers="matches characters unicode_name">The character with Unicode character name <i>'name'</i></td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="tab">{@code \t}</th>
|
||||
* <td headers="matches characters tab">The tab character (<code>'\u0009'</code>)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="newline">{@code \n}</th>
|
||||
* <td headers="matches characters newline">The newline (line feed) character (<code>'\u000A'</code>)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="return">{@code \r}</th>
|
||||
* <td headers="matches characters return">The carriage-return character (<code>'\u000D'</code>)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="form_feed">{@code \f}</th>
|
||||
* <td headers="matches characters form_feed">The form-feed character (<code>'\u000C'</code>)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="bell">{@code \a}</th>
|
||||
* <td headers="matches characters bell">The alert (bell) character (<code>'\u0007'</code>)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="escape">{@code \e}</th>
|
||||
* <td headers="matches characters escape">The escape character (<code>'\u001B'</code>)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="ctrl_x">{@code \c}<i>x</i></th>
|
||||
* <td headers="matches characters ctrl_x">The control character corresponding to <i>x</i></td></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="classes">Character classes</th></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="classes">Character classes</th></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top" headers="construct classes">{@code [abc]}</td>
|
||||
* <td headers="matches">{@code a}, {@code b}, or {@code c} (simple class)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct classes">{@code [^abc]}</td>
|
||||
* <td headers="matches">Any character except {@code a}, {@code b}, or {@code c} (negation)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct classes">{@code [a-zA-Z]}</td>
|
||||
* <td headers="matches">{@code a} through {@code z}
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="simple">{@code [abc]}</th>
|
||||
* <td headers="matches classes simple">{@code a}, {@code b}, or {@code c} (simple class)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="negation">{@code [^abc]}</th>
|
||||
* <td headers="matches classes negation">Any character except {@code a}, {@code b}, or {@code c} (negation)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="range">{@code [a-zA-Z]}</th>
|
||||
* <td headers="matches classes range">{@code a} through {@code z}
|
||||
* or {@code A} through {@code Z}, inclusive (range)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct classes">{@code [a-d[m-p]]}</td>
|
||||
* <td headers="matches">{@code a} through {@code d},
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="union">{@code [a-d[m-p]]}</th>
|
||||
* <td headers="matches classes union">{@code a} through {@code d},
|
||||
* or {@code m} through {@code p}: {@code [a-dm-p]} (union)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct classes">{@code [a-z&&[def]]}</td>
|
||||
* <td headers="matches">{@code d}, {@code e}, or {@code f} (intersection)</tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct classes">{@code [a-z&&[^bc]]}</td>
|
||||
* <td headers="matches">{@code a} through {@code z},
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="intersection">{@code [a-z&&[def]]}</th>
|
||||
* <td headers="matches classes intersection">{@code d}, {@code e}, or {@code f} (intersection)</tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="subtraction1">{@code [a-z&&[^bc]]}</th>
|
||||
* <td headers="matches classes subtraction1">{@code a} through {@code z},
|
||||
* except for {@code b} and {@code c}: {@code [ad-z]} (subtraction)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct classes">{@code [a-z&&[^m-p]]}</td>
|
||||
* <td headers="matches">{@code a} through {@code z},
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="subtraction2">{@code [a-z&&[^m-p]]}</th>
|
||||
* <td headers="matches classes subtraction2">{@code a} through {@code z},
|
||||
* and not {@code m} through {@code p}: {@code [a-lq-z]}(subtraction)</td></tr>
|
||||
* <tr><th> </th></tr>
|
||||
*
|
||||
* <tr style="text-align:left"><th colspan="2" id="predef">Predefined character classes</th></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="predef">Predefined character classes</th></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top" headers="construct predef">{@code .}</td>
|
||||
* <td headers="matches">Any character (may or may not match <a href="#lt">line terminators</a>)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct predef">{@code \d}</td>
|
||||
* <td headers="matches">A digit: {@code [0-9]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct predef">{@code \D}</td>
|
||||
* <td headers="matches">A non-digit: {@code [^0-9]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct predef">{@code \h}</td>
|
||||
* <td headers="matches">A horizontal whitespace character:
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="any">{@code .}</th>
|
||||
* <td headers="matches predef any">Any character (may or may not match <a href="#lt">line terminators</a>)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="digit">{@code \d}</th>
|
||||
* <td headers="matches predef digit">A digit: {@code [0-9]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="non_digit">{@code \D}</th>
|
||||
* <td headers="matches predef non_digit">A non-digit: {@code [^0-9]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="horiz_white">{@code \h}</th>
|
||||
* <td headers="matches predef horiz_white">A horizontal whitespace character:
|
||||
* <code>[ \t\xA0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000]</code></td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct predef">{@code \H}</td>
|
||||
* <td headers="matches">A non-horizontal whitespace character: {@code [^\h]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct predef">{@code \s}</td>
|
||||
* <td headers="matches">A whitespace character: {@code [ \t\n\x0B\f\r]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct predef">{@code \S}</td>
|
||||
* <td headers="matches">A non-whitespace character: {@code [^\s]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct predef">{@code \v}</td>
|
||||
* <td headers="matches">A vertical whitespace character: <code>[\n\x0B\f\r\x85\u2028\u2029]</code>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="non_horiz_white">{@code \H}</th>
|
||||
* <td headers="matches predef non_horiz_white">A non-horizontal whitespace character: {@code [^\h]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="white">{@code \s}</th>
|
||||
* <td headers="matches predef white">A whitespace character: {@code [ \t\n\x0B\f\r]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="non_white">{@code \S}</th>
|
||||
* <td headers="matches predef non_white">A non-whitespace character: {@code [^\s]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="vert_white">{@code \v}</th>
|
||||
* <td headers="matches predef vert_white">A vertical whitespace character: <code>[\n\x0B\f\r\x85\u2028\u2029]</code>
|
||||
* </td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct predef">{@code \V}</td>
|
||||
* <td headers="matches">A non-vertical whitespace character: {@code [^\v]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct predef">{@code \w}</td>
|
||||
* <td headers="matches">A word character: {@code [a-zA-Z_0-9]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct predef">{@code \W}</td>
|
||||
* <td headers="matches">A non-word character: {@code [^\w]}</td></tr>
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="posix"><b>POSIX character classes (US-ASCII only)</b></th></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="non_vert_white">{@code \V}</th>
|
||||
* <td headers="matches predef non_vert_white">A non-vertical whitespace character: {@code [^\v]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="word">{@code \w}</th>
|
||||
* <td headers="matches predef word">A word character: {@code [a-zA-Z_0-9]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="non_word">{@code \W}</th>
|
||||
* <td headers="matches predef non_word">A non-word character: {@code [^\w]}</td></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{Lower}}</td>
|
||||
* <td headers="matches">A lower-case alphabetic character: {@code [a-z]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{Upper}}</td>
|
||||
* <td headers="matches">An upper-case alphabetic character:{@code [A-Z]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{ASCII}}</td>
|
||||
* <td headers="matches">All ASCII:{@code [\x00-\x7F]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{Alpha}}</td>
|
||||
* <td headers="matches">An alphabetic character:{@code [\p{Lower}\p{Upper}]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{Digit}}</td>
|
||||
* <td headers="matches">A decimal digit: {@code [0-9]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{Alnum}}</td>
|
||||
* <td headers="matches">An alphanumeric character:{@code [\p{Alpha}\p{Digit}]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{Punct}}</td>
|
||||
* <td headers="matches">Punctuation: One of {@code !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~}</td></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="posix"><b>POSIX character classes (US-ASCII only)</b></th></tr>
|
||||
*
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Lower">{@code \p{Lower}}</th>
|
||||
* <td headers="matches posix Lower">A lower-case alphabetic character: {@code [a-z]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Upper">{@code \p{Upper}}</th>
|
||||
* <td headers="matches posix Upper">An upper-case alphabetic character:{@code [A-Z]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="ASCII">{@code \p{ASCII}}</th>
|
||||
* <td headers="matches posix ASCII">All ASCII:{@code [\x00-\x7F]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Alpha">{@code \p{Alpha}}</th>
|
||||
* <td headers="matches posix Alpha">An alphabetic character:{@code [\p{Lower}\p{Upper}]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Digit">{@code \p{Digit}}</th>
|
||||
* <td headers="matches posix Digit">A decimal digit: {@code [0-9]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Alnum">{@code \p{Alnum}}</th>
|
||||
* <td headers="matches posix Alnum">An alphanumeric character:{@code [\p{Alpha}\p{Digit}]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Punct">{@code \p{Punct}}</th>
|
||||
* <td headers="matches posix Punct">Punctuation: One of {@code !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~}</td></tr>
|
||||
* <!-- {@code [\!"#\$%&'\(\)\*\+,\-\./:;\<=\>\?@\[\\\]\^_`\{\|\}~]}
|
||||
* {@code [\X21-\X2F\X31-\X40\X5B-\X60\X7B-\X7E]} -->
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{Graph}}</td>
|
||||
* <td headers="matches">A visible character: {@code [\p{Alnum}\p{Punct}]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{Print}}</td>
|
||||
* <td headers="matches">A printable character: {@code [\p{Graph}\x20]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{Blank}}</td>
|
||||
* <td headers="matches">A space or a tab: {@code [ \t]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{Cntrl}}</td>
|
||||
* <td headers="matches">A control character: {@code [\x00-\x1F\x7F]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{XDigit}}</td>
|
||||
* <td headers="matches">A hexadecimal digit: {@code [0-9a-fA-F]}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct posix">{@code \p{Space}}</td>
|
||||
* <td headers="matches">A whitespace character: {@code [ \t\n\x0B\f\r]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Graph">{@code \p{Graph}}</th>
|
||||
* <td headers="matches posix Graph">A visible character: {@code [\p{Alnum}\p{Punct}]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Print">{@code \p{Print}}</th>
|
||||
* <td headers="matches posix Print">A printable character: {@code [\p{Graph}\x20]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Blank">{@code \p{Blank}}</th>
|
||||
* <td headers="matches posix Blank">A space or a tab: {@code [ \t]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Cntrl">{@code \p{Cntrl}}</th>
|
||||
* <td headers="matches posix Cntrl">A control character: {@code [\x00-\x1F\x7F]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="XDigit">{@code \p{XDigit}}</th>
|
||||
* <td headers="matches posix XDigit">A hexadecimal digit: {@code [0-9a-fA-F]}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Space">{@code \p{Space}}</th>
|
||||
* <td headers="matches posix Space">A whitespace character: {@code [ \t\n\x0B\f\r]}</td></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2">java.lang.Character classes (simple <a href="#jcc">java character type</a>)</th></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="java">java.lang.Character classes (simple <a href="#jcc">java character type</a>)</th></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top">{@code \p{javaLowerCase}}</td>
|
||||
* <td>Equivalent to java.lang.Character.isLowerCase()</td></tr>
|
||||
* <tr><td style="vertical-align:top">{@code \p{javaUpperCase}}</td>
|
||||
* <td>Equivalent to java.lang.Character.isUpperCase()</td></tr>
|
||||
* <tr><td style="vertical-align:top">{@code \p{javaWhitespace}}</td>
|
||||
* <td>Equivalent to java.lang.Character.isWhitespace()</td></tr>
|
||||
* <tr><td style="vertical-align:top">{@code \p{javaMirrored}}</td>
|
||||
* <td>Equivalent to java.lang.Character.isMirrored()</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="javaLowerCase">{@code \p{javaLowerCase}}</th>
|
||||
* <td headers="matches java javaLowerCase">Equivalent to java.lang.Character.isLowerCase()</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="javaUpperCase">{@code \p{javaUpperCase}}</th>
|
||||
* <td headers="matches java javaUpperCase">Equivalent to java.lang.Character.isUpperCase()</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="javaWhitespace">{@code \p{javaWhitespace}}</th>
|
||||
* <td headers="matches java javaWhitespace">Equivalent to java.lang.Character.isWhitespace()</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="javaMirrored">{@code \p{javaMirrored}}</th>
|
||||
* <td headers="matches java javaMirrored">Equivalent to java.lang.Character.isMirrored()</td></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="unicode">Classes for Unicode scripts, blocks, categories and binary properties</th></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct unicode">{@code \p{IsLatin}}</td>
|
||||
* <td headers="matches">A Latin script character (<a href="#usc">script</a>)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct unicode">{@code \p{InGreek}}</td>
|
||||
* <td headers="matches">A character in the Greek block (<a href="#ubc">block</a>)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct unicode">{@code \p{Lu}}</td>
|
||||
* <td headers="matches">An uppercase letter (<a href="#ucc">category</a>)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct unicode">{@code \p{IsAlphabetic}}</td>
|
||||
* <td headers="matches">An alphabetic character (<a href="#ubpc">binary property</a>)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct unicode">{@code \p{Sc}}</td>
|
||||
* <td headers="matches">A currency symbol</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct unicode">{@code \P{InGreek}}</td>
|
||||
* <td headers="matches">Any character except one in the Greek block (negation)</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct unicode">{@code [\p{L}&&[^\p{Lu}]]}</td>
|
||||
* <td headers="matches">Any letter except an uppercase letter (subtraction)</td></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="unicode">Classes for Unicode scripts, blocks, categories and binary properties</th></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="bounds">Boundary matchers</th></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="IsLatin">{@code \p{IsLatin}}</th>
|
||||
* <td headers="matches unicode IsLatin">A Latin script character (<a href="#usc">script</a>)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="InGreek">{@code \p{InGreek}}</th>
|
||||
* <td headers="matches unicode InGreek">A character in the Greek block (<a href="#ubc">block</a>)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Lu">{@code \p{Lu}}</th>
|
||||
* <td headers="matches unicode Lu">An uppercase letter (<a href="#ucc">category</a>)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="IsAlphabetic">{@code \p{IsAlphabetic}}</th>
|
||||
* <td headers="matches unicode IsAlphabetic">An alphabetic character (<a href="#ubpc">binary property</a>)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="Sc">{@code \p{Sc}}</th>
|
||||
* <td headers="matches unicode Sc">A currency symbol</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="not_InGreek">{@code \P{InGreek}}</th>
|
||||
* <td headers="matches unicode not_InGreek">Any character except one in the Greek block (negation)</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="not_uppercase">{@code [\p{L}&&[^\p{Lu}]]}</th>
|
||||
* <td headers="matches unicode not_uppercase">Any letter except an uppercase letter (subtraction)</td></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top" headers="construct bounds">{@code ^}</td>
|
||||
* <td headers="matches">The beginning of a line</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct bounds">{@code $}</td>
|
||||
* <td headers="matches">The end of a line</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct bounds">{@code \b}</td>
|
||||
* <td headers="matches">A word boundary</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct bounds">{@code \b{g}}</td>
|
||||
* <td headers="matches">A Unicode extended grapheme cluster boundary</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct bounds">{@code \B}</td>
|
||||
* <td headers="matches">A non-word boundary</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct bounds">{@code \A}</td>
|
||||
* <td headers="matches">The beginning of the input</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct bounds">{@code \G}</td>
|
||||
* <td headers="matches">The end of the previous match</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct bounds">{@code \Z}</td>
|
||||
* <td headers="matches">The end of the input but for the final
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="bounds">Boundary matchers</th></tr>
|
||||
*
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="begin_line">{@code ^}</th>
|
||||
* <td headers="matches bounds begin_line">The beginning of a line</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="end_line">{@code $}</th>
|
||||
* <td headers="matches bounds end_line">The end of a line</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="word_boundary">{@code \b}</th>
|
||||
* <td headers="matches bounds word_boundary">A word boundary</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="grapheme_cluster_boundary">{@code \b{g}}</th>
|
||||
* <td headers="matches bounds grapheme_cluster_boundary">A Unicode extended grapheme cluster boundary</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="non_word_boundary">{@code \B}</th>
|
||||
* <td headers="matches bounds non_word_boundary">A non-word boundary</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="begin_input">{@code \A}</th>
|
||||
* <td headers="matches bounds begin_input">The beginning of the input</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="end_prev_match">{@code \G}</th>
|
||||
* <td headers="matches bounds end_prev_match">The end of the previous match</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="end_input_except_term">{@code \Z}</th>
|
||||
* <td headers="matches bounds end_input_except_term">The end of the input but for the final
|
||||
* <a href="#lt">terminator</a>, if any</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct bounds">{@code \z}</td>
|
||||
* <td headers="matches">The end of the input</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="end_input">{@code \z}</th>
|
||||
* <td headers="matches bounds end_input">The end of the input</td></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="lineending">Linebreak matcher</th></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct lineending">{@code \R}</td>
|
||||
* <td headers="matches">Any Unicode linebreak sequence, is equivalent to
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="linebreak">Linebreak matcher</th></tr>
|
||||
*
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="any_unicode_linebreak">{@code \R}</th>
|
||||
* <td headers="matches linebreak any_unicode_linebreak">Any Unicode linebreak sequence, is equivalent to
|
||||
* <code>\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
|
||||
* </code></td></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="grapheme">Unicode Extended Grapheme matcher</th></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct grapheme">{@code \X}</td>
|
||||
* <td headers="matches">Any Unicode extended grapheme cluster</td></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="grapheme">Unicode Extended Grapheme matcher</th></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="greedy">Greedy quantifiers</th></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="grapheme_any">{@code \X}</th>
|
||||
* <td headers="matches grapheme grapheme_any">Any Unicode extended grapheme cluster</td></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top" headers="construct greedy"><i>X</i>{@code ?}</td>
|
||||
* <td headers="matches"><i>X</i>, once or not at all</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct greedy"><i>X</i>{@code *}</td>
|
||||
* <td headers="matches"><i>X</i>, zero or more times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct greedy"><i>X</i>{@code +}</td>
|
||||
* <td headers="matches"><i>X</i>, one or more times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct greedy"><i>X</i><code>{</code><i>n</i><code>}</code></td>
|
||||
* <td headers="matches"><i>X</i>, exactly <i>n</i> times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct greedy"><i>X</i><code>{</code><i>n</i>{@code ,}}</td>
|
||||
* <td headers="matches"><i>X</i>, at least <i>n</i> times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct greedy"><i>X</i><code>{</code><i>n</i>{@code ,}<i>m</i><code>}</code></td>
|
||||
* <td headers="matches"><i>X</i>, at least <i>n</i> but not more than <i>m</i> times</td></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="greedy">Greedy quantifiers</th></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="reluc">Reluctant quantifiers</th></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="greedy_once_or_not"><i>X</i>{@code ?}</th>
|
||||
* <td headers="matches greedy greedy_once_or_not"><i>X</i>, once or not at all</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="greedy_zero_or_more"><i>X</i>{@code *}</th>
|
||||
* <td headers="matches greedy greedy_zero_or_more"><i>X</i>, zero or more times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="greedy_one_or_more"><i>X</i>{@code +}</th>
|
||||
* <td headers="matches greedy greedy_one_or_more"><i>X</i>, one or more times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="greedy_exactly"><i>X</i><code>{</code><i>n</i><code>}</code></th>
|
||||
* <td headers="matches greedy greedy_exactly"><i>X</i>, exactly <i>n</i> times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="greedy_at_least"><i>X</i><code>{</code><i>n</i>{@code ,}}</th>
|
||||
* <td headers="matches greedy greedy_at_least"><i>X</i>, at least <i>n</i> times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="greedy_at_least_up_to"><i>X</i><code>{</code><i>n</i>{@code ,}<i>m</i><code>}</code></th>
|
||||
* <td headers="matches greedy greedy_at_least_up_to"><i>X</i>, at least <i>n</i> but not more than <i>m</i> times</td></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top" headers="construct reluc"><i>X</i>{@code ??}</td>
|
||||
* <td headers="matches"><i>X</i>, once or not at all</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct reluc"><i>X</i>{@code *?}</td>
|
||||
* <td headers="matches"><i>X</i>, zero or more times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct reluc"><i>X</i>{@code +?}</td>
|
||||
* <td headers="matches"><i>X</i>, one or more times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct reluc"><i>X</i><code>{</code><i>n</i><code>}?</code></td>
|
||||
* <td headers="matches"><i>X</i>, exactly <i>n</i> times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct reluc"><i>X</i><code>{</code><i>n</i><code>,}?</code></td>
|
||||
* <td headers="matches"><i>X</i>, at least <i>n</i> times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct reluc"><i>X</i><code>{</code><i>n</i>{@code ,}<i>m</i><code>}?</code></td>
|
||||
* <td headers="matches"><i>X</i>, at least <i>n</i> but not more than <i>m</i> times</td></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="reluc">Reluctant quantifiers</th></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="poss">Possessive quantifiers</th></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="reluc_once_or_not"><i>X</i>{@code ??}</th>
|
||||
* <td headers="matches reluc reluc_once_or_not"><i>X</i>, once or not at all</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="reluc_zero_or_more"><i>X</i>{@code *?}</th>
|
||||
* <td headers="matches reluc reluc_zero_or_more"><i>X</i>, zero or more times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="reluc_one_or_more"><i>X</i>{@code +?}</th>
|
||||
* <td headers="matches reluc reluc_one_or_more"><i>X</i>, one or more times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="reluc_exactly"><i>X</i><code>{</code><i>n</i><code>}?</code></th>
|
||||
* <td headers="matches reluc reluc_exactly"><i>X</i>, exactly <i>n</i> times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="reluc_at_least"><i>X</i><code>{</code><i>n</i><code>,}?</code></th>
|
||||
* <td headers="matches reluc reluc_at_least"><i>X</i>, at least <i>n</i> times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="reluc_at_least_up_to"><i>X</i><code>{</code><i>n</i>{@code ,}<i>m</i><code>}?</code></th>
|
||||
* <td headers="matches reluc reluc_at_least_up_to"><i>X</i>, at least <i>n</i> but not more than <i>m</i> times</td></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top" headers="construct poss"><i>X</i>{@code ?+}</td>
|
||||
* <td headers="matches"><i>X</i>, once or not at all</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct poss"><i>X</i>{@code *+}</td>
|
||||
* <td headers="matches"><i>X</i>, zero or more times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct poss"><i>X</i>{@code ++}</td>
|
||||
* <td headers="matches"><i>X</i>, one or more times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct poss"><i>X</i><code>{</code><i>n</i><code>}+</code></td>
|
||||
* <td headers="matches"><i>X</i>, exactly <i>n</i> times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct poss"><i>X</i><code>{</code><i>n</i><code>,}+</code></td>
|
||||
* <td headers="matches"><i>X</i>, at least <i>n</i> times</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct poss"><i>X</i><code>{</code><i>n</i>{@code ,}<i>m</i><code>}+</code></td>
|
||||
* <td headers="matches"><i>X</i>, at least <i>n</i> but not more than <i>m</i> times</td></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="poss">Possessive quantifiers</th></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="logical">Logical operators</th></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="poss_once_or_not"><i>X</i>{@code ?+}</th>
|
||||
* <td headers="matches poss poss_once_or_not"><i>X</i>, once or not at all</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="poss_zero_or_more"><i>X</i>{@code *+}</th>
|
||||
* <td headers="matches poss poss_zero_or_more"><i>X</i>, zero or more times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="poss_one_or_more"><i>X</i>{@code ++}</th>
|
||||
* <td headers="matches poss poss_one_or_more"><i>X</i>, one or more times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="poss_exactly"><i>X</i><code>{</code><i>n</i><code>}+</code></th>
|
||||
* <td headers="matches poss poss_exactly"><i>X</i>, exactly <i>n</i> times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="poss_at_least"><i>X</i><code>{</code><i>n</i><code>,}+</code></th>
|
||||
* <td headers="matches poss poss_at_least"><i>X</i>, at least <i>n</i> times</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="poss_at_least_up_to"><i>X</i><code>{</code><i>n</i>{@code ,}<i>m</i><code>}+</code></th>
|
||||
* <td headers="matches poss poss_at_least_up_to"><i>X</i>, at least <i>n</i> but not more than <i>m</i> times</td></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top" headers="construct logical"><i>XY</i></td>
|
||||
* <td headers="matches"><i>X</i> followed by <i>Y</i></td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct logical"><i>X</i>{@code |}<i>Y</i></td>
|
||||
* <td headers="matches">Either <i>X</i> or <i>Y</i></td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct logical">{@code (}<i>X</i>{@code )}</td>
|
||||
* <td headers="matches">X, as a <a href="#cg">capturing group</a></td></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="logical">Logical operators</th></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="backref">Back references</th></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="concat"><i>XY</i></th>
|
||||
* <td headers="matches logical concat"><i>X</i> followed by <i>Y</i></td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="alternate"><i>X</i>{@code |}<i>Y</i></th>
|
||||
* <td headers="matches logical alternate">Either <i>X</i> or <i>Y</i></td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="group">{@code (}<i>X</i>{@code )}</th>
|
||||
* <td headers="matches logical group">X, as a <a href="#cg">capturing group</a></td></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:bottom" headers="construct backref">{@code \}<i>n</i></td>
|
||||
* <td style="vertical-align:bottom" headers="matches">Whatever the <i>n</i><sup>th</sup>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="backref">Back references</th></tr>
|
||||
*
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="back_nth">{@code \}<i>n</i></th>
|
||||
* <td headers="matches backref back_nth">Whatever the <i>n</i><sup>th</sup>
|
||||
* <a href="#cg">capturing group</a> matched</td></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:bottom" headers="construct backref">{@code \}<i>k</i><<i>name</i>></td>
|
||||
* <td style="vertical-align:bottom" headers="matches">Whatever the
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="back_named">{@code \}<i>k</i><<i>name</i>></th>
|
||||
* <td headers="matches backref back_named">Whatever the
|
||||
* <a href="#groupname">named-capturing group</a> "name" matched</td></tr>
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="quot">Quotation</th></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="quote">Quotation</th></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top" headers="construct quot">{@code \}</td>
|
||||
* <td headers="matches">Nothing, but quotes the following character</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct quot">{@code \Q}</td>
|
||||
* <td headers="matches">Nothing, but quotes all characters until {@code \E}</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct quot">{@code \E}</td>
|
||||
* <td headers="matches">Nothing, but ends quoting started by {@code \Q}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="quote_follow">{@code \}</th>
|
||||
* <td headers="matches quote quote_follow">Nothing, but quotes the following character</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="quote_begin">{@code \Q}</th>
|
||||
* <td headers="matches quote quote_begin">Nothing, but quotes all characters until {@code \E}</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="quote_end">{@code \E}</th>
|
||||
* <td headers="matches quote quote_end">Nothing, but ends quoting started by {@code \Q}</td></tr>
|
||||
* <!-- Metachars: !$()*+.<>?[\]^{|} -->
|
||||
*
|
||||
* <tr><th> </th></tr>
|
||||
* <tr style="text-align:left"><th colspan="2" id="special">Special constructs (named-capturing and non-capturing)</th></tr>
|
||||
* <tr><th colspan="2" style="padding-top:20px" id="special">Special constructs (named-capturing and non-capturing)</th></tr>
|
||||
*
|
||||
* <tr><td style="vertical-align:top" headers="construct special"><code>(?<<a href="#groupname">name</a>></code><i>X</i>{@code )}</td>
|
||||
* <td headers="matches"><i>X</i>, as a named-capturing group</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct special">{@code (?:}<i>X</i>{@code )}</td>
|
||||
* <td headers="matches"><i>X</i>, as a non-capturing group</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct special"><code>(?idmsuxU-idmsuxU) </code></td>
|
||||
* <td headers="matches">Nothing, but turns match flags <a href="#CASE_INSENSITIVE">i</a>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="named_group"><code>(?<<a href="#groupname">name</a>></code><i>X</i>{@code )}</th>
|
||||
* <td headers="matches special named_group"><i>X</i>, as a named-capturing group</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="non_capture_group">{@code (?:}<i>X</i>{@code )}</th>
|
||||
* <td headers="matches special non_capture_group"><i>X</i>, as a non-capturing group</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="flags"><code>(?idmsuxU-idmsuxU) </code></th>
|
||||
* <td headers="matches special flags">Nothing, but turns match flags <a href="#CASE_INSENSITIVE">i</a>
|
||||
* <a href="#UNIX_LINES">d</a> <a href="#MULTILINE">m</a> <a href="#DOTALL">s</a>
|
||||
* <a href="#UNICODE_CASE">u</a> <a href="#COMMENTS">x</a> <a href="#UNICODE_CHARACTER_CLASS">U</a>
|
||||
* on - off</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct special"><code>(?idmsux-idmsux:</code><i>X</i>{@code )} </td>
|
||||
* <td headers="matches"><i>X</i>, as a <a href="#cg">non-capturing group</a> with the
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="non_capture_group_flags"><code>(?idmsux-idmsux:</code><i>X</i>{@code )} </th>
|
||||
* <td headers="matches special non_capture_group_flags"><i>X</i>, as a <a href="#cg">non-capturing group</a> with the
|
||||
* given flags <a href="#CASE_INSENSITIVE">i</a> <a href="#UNIX_LINES">d</a>
|
||||
* <a href="#MULTILINE">m</a> <a href="#DOTALL">s</a> <a href="#UNICODE_CASE">u</a >
|
||||
* <a href="#COMMENTS">x</a> on - off</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct special">{@code (?=}<i>X</i>{@code )}</td>
|
||||
* <td headers="matches"><i>X</i>, via zero-width positive lookahead</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct special">{@code (?!}<i>X</i>{@code )}</td>
|
||||
* <td headers="matches"><i>X</i>, via zero-width negative lookahead</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct special">{@code (?<=}<i>X</i>{@code )}</td>
|
||||
* <td headers="matches"><i>X</i>, via zero-width positive lookbehind</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct special">{@code (?<!}<i>X</i>{@code )}</td>
|
||||
* <td headers="matches"><i>X</i>, via zero-width negative lookbehind</td></tr>
|
||||
* <tr><td style="vertical-align:top" headers="construct special">{@code (?>}<i>X</i>{@code )}</td>
|
||||
* <td headers="matches"><i>X</i>, as an independent, non-capturing group</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="pos_lookahead">{@code (?=}<i>X</i>{@code )}</th>
|
||||
* <td headers="matches special pos_lookahead"><i>X</i>, via zero-width positive lookahead</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="neg_lookahead">{@code (?!}<i>X</i>{@code )}</th>
|
||||
* <td headers="matches special neg_lookahead"><i>X</i>, via zero-width negative lookahead</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="pos_lookbehind">{@code (?<=}<i>X</i>{@code )}</th>
|
||||
* <td headers="matches special pos_lookbehind"><i>X</i>, via zero-width positive lookbehind</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="neg_lookbehind">{@code (?<!}<i>X</i>{@code )}</th>
|
||||
* <td headers="matches special neg_lookbehind"><i>X</i>, via zero-width negative lookbehind</td></tr>
|
||||
* <tr><th style="vertical-align:top; font-weight:normal" id="indep_non_capture_group">{@code (?>}<i>X</i>{@code )}</th>
|
||||
* <td headers="matches special indep_non_capture_group"><i>X</i>, as an independent, non-capturing group</td></tr>
|
||||
*
|
||||
* </tbody>
|
||||
* </table>
|
||||
@ -432,26 +419,29 @@ import java.util.stream.StreamSupport;
|
||||
* <p> The precedence of character-class operators is as follows, from
|
||||
* highest to lowest:
|
||||
*
|
||||
* <blockquote><table>
|
||||
* <table class="striped" style="margin-left: 2em;">
|
||||
* <caption style="display:none">Precedence of character class operators.</caption>
|
||||
* <thead>
|
||||
* <tr><th scope="col">Precedence<th scope="col">Name<th scope="col">Example
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><th>1 </th>
|
||||
* <tr><th scope="row">1</th>
|
||||
* <td>Literal escape </td>
|
||||
* <td>{@code \x}</td></tr>
|
||||
* <tr><th>2 </th>
|
||||
* <tr><th scope="row">2</th>
|
||||
* <td>Grouping</td>
|
||||
* <td>{@code [...]}</td></tr>
|
||||
* <tr><th>3 </th>
|
||||
* <tr><th scope="row">3</th>
|
||||
* <td>Range</td>
|
||||
* <td>{@code a-z}</td></tr>
|
||||
* <tr><th>4 </th>
|
||||
* <tr><th scope="row">4</th>
|
||||
* <td>Union</td>
|
||||
* <td>{@code [a-e][i-u]}</td></tr>
|
||||
* <tr><th>5 </th>
|
||||
* <tr><th scope="row">5</th>
|
||||
* <td>Intersection</td>
|
||||
* <td>{@code [a-z&&[aeiou]]}</td></tr>
|
||||
* </tbody>
|
||||
* </table></blockquote>
|
||||
* </table>
|
||||
*
|
||||
* <p> Note that a different set of metacharacters are in effect inside
|
||||
* a character class than outside a character class. For instance, the
|
||||
@ -467,18 +457,18 @@ import java.util.stream.StreamSupport;
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li> A newline (line feed) character ({@code '\n'}),
|
||||
* <li> A newline (line feed) character ({@code '\n'}),
|
||||
*
|
||||
* <li> A carriage-return character followed immediately by a newline
|
||||
* character ({@code "\r\n"}),
|
||||
* character ({@code "\r\n"}),
|
||||
*
|
||||
* <li> A standalone carriage-return character ({@code '\r'}),
|
||||
* <li> A standalone carriage-return character ({@code '\r'}),
|
||||
*
|
||||
* <li> A next-line character (<code>'\u0085'</code>),
|
||||
* <li> A next-line character (<code>'\u0085'</code>),
|
||||
*
|
||||
* <li> A line-separator character (<code>'\u2028'</code>), or
|
||||
* <li> A line-separator character (<code>'\u2028'</code>), or
|
||||
*
|
||||
* <li> A paragraph-separator character (<code>'\u2029'</code>).
|
||||
* <li> A paragraph-separator character (<code>'\u2029'</code>).
|
||||
*
|
||||
* </ul>
|
||||
* <p>If {@link #UNIX_LINES} mode is activated, then the only line terminators
|
||||
@ -501,19 +491,12 @@ import java.util.stream.StreamSupport;
|
||||
* left to right. In the expression {@code ((A)(B(C)))}, for example, there
|
||||
* are four such groups: </p>
|
||||
*
|
||||
* <blockquote><table>
|
||||
* <caption style="display:none">Capturing group numberings</caption>
|
||||
* <tbody>
|
||||
* <tr><th>1 </th>
|
||||
* <td>{@code ((A)(B(C)))}</td></tr>
|
||||
* <tr><th>2 </th>
|
||||
* <td>{@code (A)}</td></tr>
|
||||
* <tr><th>3 </th>
|
||||
* <td>{@code (B(C))}</td></tr>
|
||||
* <tr><th>4 </th>
|
||||
* <td>{@code (C)}</td></tr>
|
||||
* </tbody>
|
||||
* </table></blockquote>
|
||||
* <ol style="margin-left:2em;">
|
||||
* <li> {@code ((A)(B(C)))}
|
||||
* <li> {@code (A)}
|
||||
* <li> {@code (B(C))}
|
||||
* <li> {@code (C)}
|
||||
* </ol>
|
||||
*
|
||||
* <p> Group zero always stands for the entire expression.
|
||||
*
|
||||
@ -649,52 +632,52 @@ import java.util.stream.StreamSupport;
|
||||
* of <a href="http://www.unicode.org/reports/tr18/"><i>Unicode Regular Expression
|
||||
* </i></a>, when {@link #UNICODE_CHARACTER_CLASS} flag is specified.
|
||||
*
|
||||
* <table>
|
||||
* <table class="striped">
|
||||
* <caption style="display:none">predefined and posix character classes in Unicode mode</caption>
|
||||
* <thead>
|
||||
* <tr style="text-align:left">
|
||||
* <th style="text-align:left" id="predef_classes">Classes</th>
|
||||
* <th style="text-align:left" id="predef_matches">Matches</th>
|
||||
* <tr>
|
||||
* <th scope="col" id="predef_classes">Classes</th>
|
||||
* <th scope="col" id="predef_matches">Matches</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td>{@code \p{Lower}}</td>
|
||||
* <tr><th scope="row">{@code \p{Lower}}</th>
|
||||
* <td>A lowercase character:{@code \p{IsLowercase}}</td></tr>
|
||||
* <tr><td>{@code \p{Upper}}</td>
|
||||
* <tr><th scope="row">{@code \p{Upper}}</th>
|
||||
* <td>An uppercase character:{@code \p{IsUppercase}}</td></tr>
|
||||
* <tr><td>{@code \p{ASCII}}</td>
|
||||
* <tr><th scope="row">{@code \p{ASCII}}</th>
|
||||
* <td>All ASCII:{@code [\x00-\x7F]}</td></tr>
|
||||
* <tr><td>{@code \p{Alpha}}</td>
|
||||
* <tr><th scope="row">{@code \p{Alpha}}</th>
|
||||
* <td>An alphabetic character:{@code \p{IsAlphabetic}}</td></tr>
|
||||
* <tr><td>{@code \p{Digit}}</td>
|
||||
* <tr><th scope="row">{@code \p{Digit}}</th>
|
||||
* <td>A decimal digit character:{@code \p{IsDigit}}</td></tr>
|
||||
* <tr><td>{@code \p{Alnum}}</td>
|
||||
* <tr><th scope="row">{@code \p{Alnum}}</th>
|
||||
* <td>An alphanumeric character:{@code [\p{IsAlphabetic}\p{IsDigit}]}</td></tr>
|
||||
* <tr><td>{@code \p{Punct}}</td>
|
||||
* <tr><th scope="row">{@code \p{Punct}}</th>
|
||||
* <td>A punctuation character:{@code \p{IsPunctuation}}</td></tr>
|
||||
* <tr><td>{@code \p{Graph}}</td>
|
||||
* <tr><th scope="row">{@code \p{Graph}}</th>
|
||||
* <td>A visible character: {@code [^\p{IsWhite_Space}\p{gc=Cc}\p{gc=Cs}\p{gc=Cn}]}</td></tr>
|
||||
* <tr><td>{@code \p{Print}}</td>
|
||||
* <tr><th scope="row">{@code \p{Print}}</th>
|
||||
* <td>A printable character: {@code [\p{Graph}\p{Blank}&&[^\p{Cntrl}]]}</td></tr>
|
||||
* <tr><td>{@code \p{Blank}}</td>
|
||||
* <tr><th scope="row">{@code \p{Blank}}</th>
|
||||
* <td>A space or a tab: {@code [\p{IsWhite_Space}&&[^\p{gc=Zl}\p{gc=Zp}\x0a\x0b\x0c\x0d\x85]]}</td></tr>
|
||||
* <tr><td>{@code \p{Cntrl}}</td>
|
||||
* <tr><th scope="row">{@code \p{Cntrl}}</th>
|
||||
* <td>A control character: {@code \p{gc=Cc}}</td></tr>
|
||||
* <tr><td>{@code \p{XDigit}}</td>
|
||||
* <tr><th scope="row">{@code \p{XDigit}}</th>
|
||||
* <td>A hexadecimal digit: {@code [\p{gc=Nd}\p{IsHex_Digit}]}</td></tr>
|
||||
* <tr><td>{@code \p{Space}}</td>
|
||||
* <tr><th scope="row">{@code \p{Space}}</th>
|
||||
* <td>A whitespace character:{@code \p{IsWhite_Space}}</td></tr>
|
||||
* <tr><td>{@code \d}</td>
|
||||
* <tr><th scope="row">{@code \d}</th>
|
||||
* <td>A digit: {@code \p{IsDigit}}</td></tr>
|
||||
* <tr><td>{@code \D}</td>
|
||||
* <tr><th scope="row">{@code \D}</th>
|
||||
* <td>A non-digit: {@code [^\d]}</td></tr>
|
||||
* <tr><td>{@code \s}</td>
|
||||
* <tr><th scope="row">{@code \s}</th>
|
||||
* <td>A whitespace character: {@code \p{IsWhite_Space}}</td></tr>
|
||||
* <tr><td>{@code \S}</td>
|
||||
* <tr><th scope="row">{@code \S}</th>
|
||||
* <td>A non-whitespace character: {@code [^\s]}</td></tr>
|
||||
* <tr><td>{@code \w}</td>
|
||||
* <tr><th scope="row">{@code \w}</th>
|
||||
* <td>A word character: {@code [\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}\p{IsJoin_Control}]}</td></tr>
|
||||
* <tr><td>{@code \W}</td>
|
||||
* <tr><th scope="row">{@code \W}</th>
|
||||
* <td>A non-word character: {@code [^\w]}</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
@ -1219,34 +1202,36 @@ public final class Pattern
|
||||
* <p> The input {@code "boo:and:foo"}, for example, yields the following
|
||||
* results with these parameters:
|
||||
*
|
||||
* <blockquote><table>
|
||||
* <caption>Split examples showing regex, limit, and result</caption>
|
||||
* <table class="plain" style="margin-left:2em;">
|
||||
* <caption style="display:none">Split example showing regex, limit, and result</caption>
|
||||
* <thead>
|
||||
* <tr><th style="text-align:left"><i>Regex </i></th>
|
||||
* <th style="text-align:left"><i>Limit </i></th>
|
||||
* <th style="text-align:left"><i>Result </i></th></tr>
|
||||
* <tr>
|
||||
* <th scope="col">Regex</th>
|
||||
* <th scope="col">Limit</th>
|
||||
* <th scope="col">Result</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td style="text-align:center">:</td>
|
||||
* <td style="text-align:center">2</td>
|
||||
* <tr><th scope="row" rowspan="3" style="font-weight:normal">:</th>
|
||||
* <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">2</th>
|
||||
* <td>{@code { "boo", "and:foo" }}</td></tr>
|
||||
* <tr><td style="text-align:center">:</td>
|
||||
* <td style="text-align:center">5</td>
|
||||
* <tr><!-- : -->
|
||||
* <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">5</th>
|
||||
* <td>{@code { "boo", "and", "foo" }}</td></tr>
|
||||
* <tr><td style="text-align:center">:</td>
|
||||
* <td style="text-align:center">-2</td>
|
||||
* <tr><!-- : -->
|
||||
* <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">-2</th>
|
||||
* <td>{@code { "boo", "and", "foo" }}</td></tr>
|
||||
* <tr><td style="text-align:center">o</td>
|
||||
* <td style="text-align:center">5</td>
|
||||
* <tr><th scope="row" rowspan="3" style="font-weight:normal">o</th>
|
||||
* <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">5</th>
|
||||
* <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
|
||||
* <tr><td style="text-align:center">o</td>
|
||||
* <td style="text-align:center">-2</td>
|
||||
* <tr><!-- o -->
|
||||
* <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">-2</th>
|
||||
* <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
|
||||
* <tr><td style="text-align:center">o</td>
|
||||
* <td style="text-align:center">0</td>
|
||||
* <tr><!-- o -->
|
||||
* <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">0</th>
|
||||
* <td>{@code { "b", "", ":and:f" }}</td></tr>
|
||||
* </tbody>
|
||||
* </table></blockquote>
|
||||
* </table>
|
||||
*
|
||||
* @param input
|
||||
* The character sequence to be split
|
||||
@ -1310,19 +1295,21 @@ public final class Pattern
|
||||
* <p> The input {@code "boo:and:foo"}, for example, yields the following
|
||||
* results with these expressions:
|
||||
*
|
||||
* <blockquote><table>
|
||||
* <table class="plain" style="margin-left:2em">
|
||||
* <caption style="display:none">Split examples showing regex and result</caption>
|
||||
* <thead>
|
||||
* <tr><th style="text-align:left"><i>Regex </i></th>
|
||||
* <th style="text-align:left"><i>Result</i></th></tr>
|
||||
* <tr>
|
||||
* <th scope="col">Regex</th>
|
||||
* <th scope="col">Result</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td style="text-align:center">:</td>
|
||||
* <tr><th scope="row" style="text-weight:normal">:</th>
|
||||
* <td>{@code { "boo", "and", "foo" }}</td></tr>
|
||||
* <tr><td style="text-align:center">o</td>
|
||||
* <tr><th scope="row" style="text-weight:normal">o</th>
|
||||
* <td>{@code { "b", "", ":and:f" }}</td></tr>
|
||||
* </tbody>
|
||||
* </table></blockquote>
|
||||
* </table>
|
||||
*
|
||||
*
|
||||
* @param input
|
||||
|
@ -46,18 +46,18 @@ import java.util.Map;
|
||||
* Calendar}. The following are calendar-common fields and their values to be
|
||||
* supported for each calendar system.
|
||||
*
|
||||
* <table class="plain">
|
||||
* <table class="striped">
|
||||
* <caption style="display:none">Field values</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <th>Field</th>
|
||||
* <th>Value</th>
|
||||
* <th>Description</th>
|
||||
* <th scope="col">Field</th>
|
||||
* <th scope="col">Value</th>
|
||||
* <th scope="col">Description</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td style="vertical-align:top">{@link Calendar#MONTH}</td>
|
||||
* <th scope="row" style="vertical-align:top">{@link Calendar#MONTH}</th>
|
||||
* <td style="vertical-align:top">{@link Calendar#JANUARY} to {@link Calendar#UNDECIMBER}</td>
|
||||
* <td>Month numbering is 0-based (e.g., 0 - January, ..., 11 -
|
||||
* December). Some calendar systems have 13 months. Month
|
||||
@ -67,13 +67,13 @@ import java.util.Map;
|
||||
* in both of the forms.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td style="vertical-align:top">{@link Calendar#DAY_OF_WEEK}</td>
|
||||
* <th scope="row" style="vertical-align:top">{@link Calendar#DAY_OF_WEEK}</th>
|
||||
* <td style="vertical-align:top">{@link Calendar#SUNDAY} to {@link Calendar#SATURDAY}</td>
|
||||
* <td>Day-of-week numbering is 1-based starting from Sunday (i.e., 1 - Sunday,
|
||||
* ..., 7 - Saturday).</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td style="vertical-align:top">{@link Calendar#AM_PM}</td>
|
||||
* <th scope="row" style="vertical-align:top">{@link Calendar#AM_PM}</th>
|
||||
* <td style="vertical-align:top">{@link Calendar#AM} to {@link Calendar#PM}</td>
|
||||
* <td>0 - AM, 1 - PM</td>
|
||||
* </tr>
|
||||
@ -86,81 +86,81 @@ import java.util.Map;
|
||||
* <caption style="display:none">Calendar type and field values</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <th>Calendar Type</th>
|
||||
* <th>Field</th>
|
||||
* <th>Value</th>
|
||||
* <th>Description</th>
|
||||
* <th scope="col">Calendar Type</th>
|
||||
* <th scope="col">Field</th>
|
||||
* <th scope="col">Value</th>
|
||||
* <th scope="col">Description</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td rowspan="2" style="vertical-align:top">{@code "gregory"}</td>
|
||||
* <td rowspan="2" style="vertical-align:top">{@link Calendar#ERA}</td>
|
||||
* <td>0</td>
|
||||
* <th scope="row"rowspan="2" style="font-weight:normal; text-align:left; vertical-align:top">{@code "gregory"}</th>
|
||||
* <th scope="row" rowspan="2" style="font-weight:normal; text-align:left; vertical-align:top">{@link Calendar#ERA}</th>
|
||||
* <th scope="row" style="font-weight:normal">0</th>
|
||||
* <td>{@link java.util.GregorianCalendar#BC} (BCE)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>1</td>
|
||||
* <th scope="row" style="font-weight:normal">1</th>
|
||||
* <td>{@link java.util.GregorianCalendar#AD} (CE)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td rowspan="2" style="vertical-align:top">{@code "buddhist"}</td>
|
||||
* <td rowspan="2" style="vertical-align:top">{@link Calendar#ERA}</td>
|
||||
* <td>0</td>
|
||||
* <th scope="row" rowspan="2" style="font-weight:normal; text-align:left; vertical-align:top">{@code "buddhist"}</th>
|
||||
* <th scope="row" rowspan="2" style="font-weight:normal; text-align:left; vertical-align:top">{@link Calendar#ERA}</th>
|
||||
* <th scope="row" style="font-weight:normal">0</th>
|
||||
* <td>BC (BCE)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>1</td>
|
||||
* <th scope="row" style="font-weight:normal">1</th>
|
||||
* <td>B.E. (Buddhist Era)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td rowspan="6" style="vertical-align:top">{@code "japanese"}</td>
|
||||
* <td rowspan="5" style="vertical-align:top">{@link Calendar#ERA}</td>
|
||||
* <td>0</td>
|
||||
* <th scope="row" rowspan="6" style="font-weight:normal; text-align:left; vertical-align:top">{@code "japanese"}</th>
|
||||
* <th scope="row" rowspan="5" style="font-weight:normal; text-align:left; vertical-align:top">{@link Calendar#ERA}</th>
|
||||
* <th scope="row" style="font-weight:normal">0</th>
|
||||
* <td>Seireki (Before Meiji)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>1</td>
|
||||
* <th scope="row" style="font-weight:normal">1</th>
|
||||
* <td>Meiji</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>2</td>
|
||||
* <th scope="row" style="font-weight:normal">2</th>
|
||||
* <td>Taisho</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>3</td>
|
||||
* <th scope="row" style="font-weight:normal">3</th>
|
||||
* <td>Showa</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>4</td>
|
||||
* <th scope="row" style="font-weight:normal">4</th>
|
||||
* <td >Heisei</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link Calendar#YEAR}</td>
|
||||
* <td>1</td>
|
||||
* <th scope="row" style="font-weight:normal; text-align:left; vertical-align:top">{@link Calendar#YEAR}</th>
|
||||
* <th scope="row" style="font-weight:normal">1</th>
|
||||
* <td>the first year in each era. It should be returned when a long
|
||||
* style ({@link Calendar#LONG_FORMAT} or {@link Calendar#LONG_STANDALONE}) is
|
||||
* specified. See also the <a href="../../text/SimpleDateFormat.html#year">
|
||||
* Year representation in {@code SimpleDateFormat}</a>.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td rowspan="2" style="vertical-align:top">{@code "roc"}</td>
|
||||
* <td rowspan="2" style="vertical-align:top">{@link Calendar#ERA}</td>
|
||||
* <td>0</td>
|
||||
* <th scope="row" rowspan="2" style="font-weight:normal; text-align:left; vertical-align:top">{@code "roc"}</th>
|
||||
* <th scope="row" rowspan="2" style="font-weight:normal; text-align:left; vertical-align:top">{@link Calendar#ERA}</th>
|
||||
* <th scope="row" style="font-weight:normal">0</th>
|
||||
* <td>Before R.O.C.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>1</td>
|
||||
* <th scope="row" style="font-weight:normal">1</th>
|
||||
* <td>R.O.C.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td rowspan="2" style="vertical-align:top">{@code "islamic"}</td>
|
||||
* <td rowspan="2" style="vertical-align:top">{@link Calendar#ERA}</td>
|
||||
* <td>0</td>
|
||||
* <th scope="row" rowspan="2" style="font-weight:normal; text-align:left; vertical-align:top">{@code "islamic"}</th>
|
||||
* <th scope="row" rowspan="2" style="font-weight:normal; text-align:left; vertical-align:top">{@link Calendar#ERA}</th>
|
||||
* <th scope="row" style="font-weight:normal">0</th>
|
||||
* <td>Before AH</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>1</td>
|
||||
* <th scope="row" style="font-weight:normal">1</th>
|
||||
* <td>Anno Hijrah (AH)</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
|
@ -82,13 +82,13 @@ import sun.security.util.Debug;
|
||||
*
|
||||
* <pre>
|
||||
* grant CodeBase "foo.com", Signedby "foo",
|
||||
* Principal com.sun.security.auth.SolarisPrincipal "duke" {
|
||||
* Principal com.sun.security.auth.UnixPrincipal "duke" {
|
||||
* permission java.io.FilePermission "/home/duke", "read, write";
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* This <b><i>grant</i></b> entry specifies that code from "foo.com",
|
||||
* signed by "foo', and running as a {@code SolarisPrincipal} with the
|
||||
* signed by "foo', and running as a {@code UnixPrincipal} with the
|
||||
* name, duke, has one {@code Permission}. This {@code Permission}
|
||||
* permits the executing code to read and write files in the directory,
|
||||
* "/home/duke".
|
||||
@ -107,8 +107,8 @@ import sun.security.util.Debug;
|
||||
* for that {@code Subject} to be granted the specified Permissions.
|
||||
*
|
||||
* <pre>
|
||||
* grant Principal com.sun.security.auth.SolarisPrincipal "duke",
|
||||
* Principal com.sun.security.auth.SolarisNumericUserPrincipal "0" {
|
||||
* grant Principal com.sun.security.auth.UnixPrincipal "duke",
|
||||
* Principal com.sun.security.auth.UnixNumericUserPrincipal "0" {
|
||||
* permission java.io.FilePermission "/home/duke", "read, write";
|
||||
* permission java.net.SocketPermission "duke.com", "connect";
|
||||
* };
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -95,51 +95,6 @@ public class AuthResources extends java.util.ListResourceBundle {
|
||||
"Kerberos username [{0}]: "},
|
||||
{"Kerberos.password.for.username.",
|
||||
"Kerberos password for {0}: "},
|
||||
|
||||
/*** EVERYTHING BELOW IS DEPRECATED ***/
|
||||
|
||||
// com.sun.security.auth.PolicyFile
|
||||
{".error.parsing.", ": error parsing "},
|
||||
{"COLON", ": "},
|
||||
{".error.adding.Permission.", ": error adding Permission "},
|
||||
{"SPACE", " "},
|
||||
{"NEWLINE", "\n"},
|
||||
{".error.adding.Entry.", ": error adding Entry "},
|
||||
{"LPARAM", "("},
|
||||
{"RPARAM", ")"},
|
||||
{"attempt.to.add.a.Permission.to.a.readonly.PermissionCollection",
|
||||
"attempt to add a Permission to a readonly PermissionCollection"},
|
||||
|
||||
// com.sun.security.auth.PolicyParser
|
||||
{"expected.keystore.type", "expected keystore type"},
|
||||
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
|
||||
"can not specify Principal with a wildcard class without a wildcard name"},
|
||||
{"expected.codeBase.or.SignedBy", "expected codeBase or SignedBy"},
|
||||
{"only.Principal.based.grant.entries.permitted",
|
||||
"only Principal-based grant entries permitted"},
|
||||
{"expected.permission.entry", "expected permission entry"},
|
||||
{"number.", "number "},
|
||||
{"expected.expect.read.end.of.file.",
|
||||
"expected {0}, read end of file"},
|
||||
{"expected.read.end.of.file", "expected ';', read end of file"},
|
||||
{"line.", "line "},
|
||||
{".expected.", ": expected '"},
|
||||
{".found.", "', found '"},
|
||||
{"QUOTE", "'"},
|
||||
|
||||
// SolarisPrincipals
|
||||
{"SolarisNumericGroupPrincipal.Primary.Group.",
|
||||
"SolarisNumericGroupPrincipal [Primary Group]: "},
|
||||
{"SolarisNumericGroupPrincipal.Supplementary.Group.",
|
||||
"SolarisNumericGroupPrincipal [Supplementary Group]: "},
|
||||
{"SolarisNumericUserPrincipal.",
|
||||
"SolarisNumericUserPrincipal: "},
|
||||
{"SolarisPrincipal.", "SolarisPrincipal: "},
|
||||
// provided.null.name is the NullPointerException message when a
|
||||
// developer incorrectly passes a null name to the constructor of
|
||||
// subclasses of java.security.Principal
|
||||
{"provided.null.name", "provided null name"}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -95,50 +95,6 @@ public class AuthResources_de extends java.util.ListResourceBundle {
|
||||
"Kerberos-Benutzername [{0}]: "},
|
||||
{"Kerberos.password.for.username.",
|
||||
"Kerberos-Kennwort f\u00FCr {0}: "},
|
||||
|
||||
/*** EVERYTHING BELOW IS DEPRECATED ***/
|
||||
|
||||
// com.sun.security.auth.PolicyFile
|
||||
{".error.parsing.", ": Parsefehler "},
|
||||
{"COLON", ": "},
|
||||
{".error.adding.Permission.", ": Fehler beim Hinzuf\u00FCgen der Berechtigung "},
|
||||
{"SPACE", " "},
|
||||
{".error.adding.Entry.", ": Fehler beim Hinzuf\u00FCgen des Eintrags "},
|
||||
{"LPARAM", "("},
|
||||
{"RPARAM", ")"},
|
||||
{"attempt.to.add.a.Permission.to.a.readonly.PermissionCollection",
|
||||
"Es wurde versucht, eine Berechtigung zu einer schreibgesch\u00FCtzten PermissionCollection hinzuzuf\u00FCgen"},
|
||||
|
||||
// com.sun.security.auth.PolicyParser
|
||||
{"expected.keystore.type", "Keystore-Typ erwartet"},
|
||||
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
|
||||
"Principal kann nicht mit einer Platzhalterklasse ohne Platzhalternamen angegeben werden"},
|
||||
{"expected.codeBase.or.SignedBy", "codeBase oder SignedBy erwartet"},
|
||||
{"only.Principal.based.grant.entries.permitted",
|
||||
"Nur Principal-basierte Berechtigungseintr\u00E4ge zul\u00E4ssig"},
|
||||
{"expected.permission.entry", "Berechtigungseintrag erwartet"},
|
||||
{"number.", "Nummer "},
|
||||
{"expected.expect.read.end.of.file.",
|
||||
"{0} erwartet, Dateiende gelesen"},
|
||||
{"expected.read.end.of.file", "\";\" erwartet, Dateiende gelesen"},
|
||||
{"line.", "Zeile "},
|
||||
{".expected.", ": erwartet: \""},
|
||||
{".found.", "\", gefunden: \""},
|
||||
{"QUOTE", "'"},
|
||||
|
||||
// SolarisPrincipals
|
||||
{"SolarisNumericGroupPrincipal.Primary.Group.",
|
||||
"SolarisNumericGroupPrincipal [Prim\u00E4rgruppe]: "},
|
||||
{"SolarisNumericGroupPrincipal.Supplementary.Group.",
|
||||
"SolarisNumericGroupPrincipal [Zusatzgruppe]: "},
|
||||
{"SolarisNumericUserPrincipal.",
|
||||
"SolarisNumericUserPrincipal: "},
|
||||
{"SolarisPrincipal.", "SolarisPrincipal: "},
|
||||
// provided.null.name is the NullPointerException message when a
|
||||
// developer incorrectly passes a null name to the constructor of
|
||||
// subclasses of java.security.Principal
|
||||
{"provided.null.name", "Nullname angegeben"}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -95,50 +95,6 @@ public class AuthResources_es extends java.util.ListResourceBundle {
|
||||
"Nombre de usuario de Kerberos [{0}]: "},
|
||||
{"Kerberos.password.for.username.",
|
||||
"Contrase\u00F1a de Kerberos de {0}: "},
|
||||
|
||||
/*** EVERYTHING BELOW IS DEPRECATED ***/
|
||||
|
||||
// com.sun.security.auth.PolicyFile
|
||||
{".error.parsing.", ": error de an\u00E1lisis "},
|
||||
{"COLON", ": "},
|
||||
{".error.adding.Permission.", ": error al agregar el permiso "},
|
||||
{"SPACE", " "},
|
||||
{".error.adding.Entry.", ": error al agregar la entrada "},
|
||||
{"LPARAM", "("},
|
||||
{"RPARAM", ")"},
|
||||
{"attempt.to.add.a.Permission.to.a.readonly.PermissionCollection",
|
||||
"se ha intentado agregar un permiso a una recopilaci\u00F3n de permisos de s\u00F3lo lectura"},
|
||||
|
||||
// com.sun.security.auth.PolicyParser
|
||||
{"expected.keystore.type", "se esperaba un tipo de almac\u00E9n de claves"},
|
||||
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
|
||||
"no se puede especificar Principal con una clase de comod\u00EDn sin un nombre de comod\u00EDn"},
|
||||
{"expected.codeBase.or.SignedBy", "se esperaba codeBase o SignedBy"},
|
||||
{"only.Principal.based.grant.entries.permitted",
|
||||
"s\u00F3lo se permite otorgar entradas basadas en Principal"},
|
||||
{"expected.permission.entry", "se esperaba un permiso de entrada"},
|
||||
{"number.", "n\u00FAmero "},
|
||||
{"expected.expect.read.end.of.file.",
|
||||
"se esperaba [{0}], se ha le\u00EDdo final de archivo"},
|
||||
{"expected.read.end.of.file", "se esperaba ';', se ha le\u00EDdo el final de archivo"},
|
||||
{"line.", "l\u00EDnea "},
|
||||
{".expected.", ": se esperaba '"},
|
||||
{".found.", "', se ha encontrado '"},
|
||||
{"QUOTE", "'"},
|
||||
|
||||
// SolarisPrincipals
|
||||
{"SolarisNumericGroupPrincipal.Primary.Group.",
|
||||
"SolarisNumericGroupPrincipal [Grupo Principal]: "},
|
||||
{"SolarisNumericGroupPrincipal.Supplementary.Group.",
|
||||
"SolarisNumericGroupPrincipal [Grupo Adicional]: "},
|
||||
{"SolarisNumericUserPrincipal.",
|
||||
"SolarisNumericUserPrincipal: "},
|
||||
{"SolarisPrincipal.", "SolarisPrincipal: "},
|
||||
// provided.null.name is the NullPointerException message when a
|
||||
// developer incorrectly passes a null name to the constructor of
|
||||
// subclasses of java.security.Principal
|
||||
{"provided.null.name", "se ha proporcionado un nombre nulo"}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -95,50 +95,6 @@ public class AuthResources_fr extends java.util.ListResourceBundle {
|
||||
"Nom utilisateur Kerberos [{0}] : "},
|
||||
{"Kerberos.password.for.username.",
|
||||
"Mot de passe Kerberos pour {0} : "},
|
||||
|
||||
/*** EVERYTHING BELOW IS DEPRECATED ***/
|
||||
|
||||
// com.sun.security.auth.PolicyFile
|
||||
{".error.parsing.", ": erreur d'analyse "},
|
||||
{"COLON", ": "},
|
||||
{".error.adding.Permission.", ": erreur d'ajout de droit "},
|
||||
{"SPACE", " "},
|
||||
{".error.adding.Entry.", ": erreur d'ajout d'entr\u00E9e "},
|
||||
{"LPARAM", "("},
|
||||
{"RPARAM", ")"},
|
||||
{"attempt.to.add.a.Permission.to.a.readonly.PermissionCollection",
|
||||
"tentative d'ajout de droit \u00E0 un ensemble de droits en lecture seule"},
|
||||
|
||||
// com.sun.security.auth.PolicyParser
|
||||
{"expected.keystore.type", "type de fichier de cl\u00E9s attendu"},
|
||||
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
|
||||
"impossible de sp\u00E9cifier le principal avec une classe g\u00E9n\u00E9rique sans nom g\u00E9n\u00E9rique"},
|
||||
{"expected.codeBase.or.SignedBy", "codeBase ou SignedBy attendu"},
|
||||
{"only.Principal.based.grant.entries.permitted",
|
||||
"seules les entr\u00E9es bas\u00E9es sur Principal sont autoris\u00E9es"},
|
||||
{"expected.permission.entry", "entr\u00E9e de droit attendue"},
|
||||
{"number.", "nombre "},
|
||||
{"expected.expect.read.end.of.file.",
|
||||
"attendu {0}, lecture de fin de fichier"},
|
||||
{"expected.read.end.of.file", "attendu ';', lecture de fin de fichier"},
|
||||
{"line.", "ligne "},
|
||||
{".expected.", ": attendu '"},
|
||||
{".found.", "', trouv\u00E9 '"},
|
||||
{"QUOTE", "'"},
|
||||
|
||||
// SolarisPrincipals
|
||||
{"SolarisNumericGroupPrincipal.Primary.Group.",
|
||||
"SolarisNumericGroupPrincipal [groupe principal] : "},
|
||||
{"SolarisNumericGroupPrincipal.Supplementary.Group.",
|
||||
"SolarisNumericGroupPrincipal [groupe suppl\u00E9mentaire] : "},
|
||||
{"SolarisNumericUserPrincipal.",
|
||||
"SolarisNumericUserPrincipal : "},
|
||||
{"SolarisPrincipal.", "SolarisPrincipal : "},
|
||||
// provided.null.name is the NullPointerException message when a
|
||||
// developer incorrectly passes a null name to the constructor of
|
||||
// subclasses of java.security.Principal
|
||||
{"provided.null.name", "nom NULL fourni"}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -95,50 +95,6 @@ public class AuthResources_it extends java.util.ListResourceBundle {
|
||||
"Nome utente Kerberos [{0}]: "},
|
||||
{"Kerberos.password.for.username.",
|
||||
"Password Kerberos per {0}: "},
|
||||
|
||||
/*** EVERYTHING BELOW IS DEPRECATED ***/
|
||||
|
||||
// com.sun.security.auth.PolicyFile
|
||||
{".error.parsing.", ": errore durante l'analisi "},
|
||||
{"COLON", ": "},
|
||||
{".error.adding.Permission.", ": errore durante l'aggiunta dell'autorizzazione "},
|
||||
{"SPACE", " "},
|
||||
{".error.adding.Entry.", ": errore durante l'aggiunta della voce "},
|
||||
{"LPARAM", "("},
|
||||
{"RPARAM", ")"},
|
||||
{"attempt.to.add.a.Permission.to.a.readonly.PermissionCollection",
|
||||
"tentativo di aggiungere un'autorizzazione a una PermissionCollection di sola lettura"},
|
||||
|
||||
// com.sun.security.auth.PolicyParser
|
||||
{"expected.keystore.type", "tipo keystore previsto"},
|
||||
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
|
||||
"impossibile specificare un principal con una classe carattere jolly senza un nome carattere jolly"},
|
||||
{"expected.codeBase.or.SignedBy", "previsto codeBase o SignedBy"},
|
||||
{"only.Principal.based.grant.entries.permitted",
|
||||
"sono consentiti solo valori garantiti basati sul principal"},
|
||||
{"expected.permission.entry", "prevista voce di autorizzazione"},
|
||||
{"number.", "numero "},
|
||||
{"expected.expect.read.end.of.file.",
|
||||
"previsto {0}, letto end of file"},
|
||||
{"expected.read.end.of.file", "previsto ';', letto end of file"},
|
||||
{"line.", "riga "},
|
||||
{".expected.", ": previsto '"},
|
||||
{".found.", "', trovato '"},
|
||||
{"QUOTE", "'"},
|
||||
|
||||
// SolarisPrincipals
|
||||
{"SolarisNumericGroupPrincipal.Primary.Group.",
|
||||
"SolarisNumericGroupPrincipal [gruppo primario]: "},
|
||||
{"SolarisNumericGroupPrincipal.Supplementary.Group.",
|
||||
"SolarisNumericGroupPrincipal [gruppo supplementare]: "},
|
||||
{"SolarisNumericUserPrincipal.",
|
||||
"SolarisNumericUserPrincipal: "},
|
||||
{"SolarisPrincipal.", "SolarisPrincipal: "},
|
||||
// provided.null.name is the NullPointerException message when a
|
||||
// developer incorrectly passes a null name to the constructor of
|
||||
// subclasses of java.security.Principal
|
||||
{"provided.null.name", "il nome fornito \u00E8 nullo"}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -95,50 +95,6 @@ public class AuthResources_ja extends java.util.ListResourceBundle {
|
||||
"Kerberos\u30E6\u30FC\u30B6\u30FC\u540D[{0}]: "},
|
||||
{"Kerberos.password.for.username.",
|
||||
"{0}\u306EKerberos\u30D1\u30B9\u30EF\u30FC\u30C9: "},
|
||||
|
||||
/*** EVERYTHING BELOW IS DEPRECATED ***/
|
||||
|
||||
// com.sun.security.auth.PolicyFile
|
||||
{".error.parsing.", ": \u89E3\u6790\u30A8\u30E9\u30FC "},
|
||||
{"COLON", ": "},
|
||||
{".error.adding.Permission.", ": \u30A2\u30AF\u30BB\u30B9\u6A29\u306E\u8FFD\u52A0\u30A8\u30E9\u30FC "},
|
||||
{"SPACE", " "},
|
||||
{".error.adding.Entry.", ": \u30A8\u30F3\u30C8\u30EA\u306E\u8FFD\u52A0\u30A8\u30E9\u30FC "},
|
||||
{"LPARAM", "("},
|
||||
{"RPARAM", ")"},
|
||||
{"attempt.to.add.a.Permission.to.a.readonly.PermissionCollection",
|
||||
"\u8AAD\u53D6\u308A\u5C02\u7528\u306EPermissionCollection\u306B\u30A2\u30AF\u30BB\u30B9\u6A29\u306E\u8FFD\u52A0\u304C\u8A66\u884C\u3055\u308C\u307E\u3057\u305F"},
|
||||
|
||||
// com.sun.security.auth.PolicyParser
|
||||
{"expected.keystore.type", "\u4E88\u60F3\u3055\u308C\u305F\u30AD\u30FC\u30B9\u30C8\u30A2\u30FB\u30BF\u30A4\u30D7"},
|
||||
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
|
||||
"\u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9\u540D\u306E\u306A\u3044\u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9\u30FB\u30AF\u30E9\u30B9\u3092\u4F7F\u7528\u3057\u3066\u3001\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u3092\u6307\u5B9A\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093"},
|
||||
{"expected.codeBase.or.SignedBy", "\u4E88\u60F3\u3055\u308C\u305FcodeBase\u307E\u305F\u306FSignedBy"},
|
||||
{"only.Principal.based.grant.entries.permitted",
|
||||
"\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u30FB\u30D9\u30FC\u30B9\u306E\u30A8\u30F3\u30C8\u30EA\u306E\u307F\u304C\u8A31\u53EF\u3055\u308C\u307E\u3059\u3002"},
|
||||
{"expected.permission.entry", "\u4E88\u60F3\u3055\u308C\u305F\u30A2\u30AF\u30BB\u30B9\u6A29\u30A8\u30F3\u30C8\u30EA"},
|
||||
{"number.", "\u6570 "},
|
||||
{"expected.expect.read.end.of.file.",
|
||||
"{0}\u3067\u306F\u306A\u304F\u30D5\u30A1\u30A4\u30EB\u306E\u7D42\u308F\u308A\u304C\u8AAD\u307F\u8FBC\u307E\u308C\u307E\u3057\u305F"},
|
||||
{"expected.read.end.of.file", "\u4E88\u60F3\u5024\u306F';'\u3067\u3059\u304C\u3001\u30D5\u30A1\u30A4\u30EB\u306E\u7D42\u308F\u308A\u304C\u8AAD\u307F\u8FBC\u307E\u308C\u307E\u3057\u305F"},
|
||||
{"line.", "\u884C\u756A\u53F7 "},
|
||||
{".expected.", ": \u4E88\u60F3\u5024'"},
|
||||
{".found.", "',\u691C\u51FA\u5024'"},
|
||||
{"QUOTE", "'"},
|
||||
|
||||
// SolarisPrincipals
|
||||
{"SolarisNumericGroupPrincipal.Primary.Group.",
|
||||
"SolarisNumericGroupPrincipal [\u4E3B\u30B0\u30EB\u30FC\u30D7]: "},
|
||||
{"SolarisNumericGroupPrincipal.Supplementary.Group.",
|
||||
"SolarisNumericGroupPrincipal [\u88DC\u52A9\u30B0\u30EB\u30FC\u30D7]: "},
|
||||
{"SolarisNumericUserPrincipal.",
|
||||
"SolarisNumericUserPrincipal: "},
|
||||
{"SolarisPrincipal.", "SolarisPrincipal: "},
|
||||
// provided.null.name is the NullPointerException message when a
|
||||
// developer incorrectly passes a null name to the constructor of
|
||||
// subclasses of java.security.Principal
|
||||
{"provided.null.name", "null\u306E\u540D\u524D\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F"}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -95,50 +95,6 @@ public class AuthResources_ko extends java.util.ListResourceBundle {
|
||||
"Kerberos \uC0AC\uC6A9\uC790 \uC774\uB984 [{0}]: "},
|
||||
{"Kerberos.password.for.username.",
|
||||
"{0}\uC758 Kerberos \uBE44\uBC00\uBC88\uD638: "},
|
||||
|
||||
/*** EVERYTHING BELOW IS DEPRECATED ***/
|
||||
|
||||
// com.sun.security.auth.PolicyFile
|
||||
{".error.parsing.", ": \uAD6C\uBB38\uBD84\uC11D \uC624\uB958 "},
|
||||
{"COLON", ": "},
|
||||
{".error.adding.Permission.", ": \uAD8C\uD55C \uCD94\uAC00 \uC624\uB958 "},
|
||||
{"SPACE", " "},
|
||||
{".error.adding.Entry.", ": \uD56D\uBAA9 \uCD94\uAC00 \uC624\uB958 "},
|
||||
{"LPARAM", "("},
|
||||
{"RPARAM", ")"},
|
||||
{"attempt.to.add.a.Permission.to.a.readonly.PermissionCollection",
|
||||
"\uC77D\uAE30 \uC804\uC6A9 PermissionCollection\uC5D0 \uAD8C\uD55C\uC744 \uCD94\uAC00\uD558\uB824\uACE0 \uC2DC\uB3C4\uD588\uC2B5\uB2C8\uB2E4."},
|
||||
|
||||
// com.sun.security.auth.PolicyParser
|
||||
{"expected.keystore.type", "\uD0A4 \uC800\uC7A5\uC18C \uC720\uD615\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
|
||||
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
|
||||
"\uC640\uC77C\uB4DC \uCE74\uB4DC \uBB38\uC790 \uC774\uB984 \uC5C6\uC774 \uC640\uC77C\uB4DC \uCE74\uB4DC \uBB38\uC790 \uD074\uB798\uC2A4\uB97C \uC0AC\uC6A9\uD558\uB294 \uC8FC\uCCB4\uB97C \uC9C0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
|
||||
{"expected.codeBase.or.SignedBy", "codeBase \uB610\uB294 SignedBy\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4."},
|
||||
{"only.Principal.based.grant.entries.permitted",
|
||||
"\uC8FC\uCCB4 \uAE30\uBC18 \uAD8C\uD55C \uBD80\uC5EC \uD56D\uBAA9\uB9CC \uD5C8\uC6A9\uB429\uB2C8\uB2E4."},
|
||||
{"expected.permission.entry", "\uAD8C\uD55C \uD56D\uBAA9\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
|
||||
{"number.", "\uC22B\uC790 "},
|
||||
{"expected.expect.read.end.of.file.",
|
||||
"{0}\uC774(\uAC00) \uD544\uC694\uD558\uC9C0\uB9CC \uD30C\uC77C\uC758 \uB05D\uC5D0 \uB3C4\uB2EC\uD588\uC2B5\uB2C8\uB2E4."},
|
||||
{"expected.read.end.of.file", "';'\uC774 \uD544\uC694\uD558\uC9C0\uB9CC \uD30C\uC77C\uC758 \uB05D\uC5D0 \uB3C4\uB2EC\uD588\uC2B5\uB2C8\uB2E4."},
|
||||
{"line.", "\uD589 "},
|
||||
{".expected.", ": \uD544\uC694\uD55C \uD56D\uBAA9: '"},
|
||||
{".found.", "', \uBC1C\uACAC\uB41C \uD56D\uBAA9: '"},
|
||||
{"QUOTE", "'"},
|
||||
|
||||
// SolarisPrincipals
|
||||
{"SolarisNumericGroupPrincipal.Primary.Group.",
|
||||
"SolarisNumericGroupPrincipal [\uAE30\uBCF8 \uADF8\uB8F9]: "},
|
||||
{"SolarisNumericGroupPrincipal.Supplementary.Group.",
|
||||
"SolarisNumericGroupPrincipal [\uBCF4\uC870 \uADF8\uB8F9]: "},
|
||||
{"SolarisNumericUserPrincipal.",
|
||||
"SolarisNumericUserPrincipal: "},
|
||||
{"SolarisPrincipal.", "SolarisPrincipal: "},
|
||||
// provided.null.name is the NullPointerException message when a
|
||||
// developer incorrectly passes a null name to the constructor of
|
||||
// subclasses of java.security.Principal
|
||||
{"provided.null.name", "\uB110 \uC774\uB984\uC744 \uC81C\uACF5\uD588\uC2B5\uB2C8\uB2E4."}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -95,50 +95,6 @@ public class AuthResources_pt_BR extends java.util.ListResourceBundle {
|
||||
"Nome do usu\u00E1rio de Kerberos [{0}]: "},
|
||||
{"Kerberos.password.for.username.",
|
||||
"Senha de Kerberos de {0}: "},
|
||||
|
||||
/*** EVERYTHING BELOW IS DEPRECATED ***/
|
||||
|
||||
// com.sun.security.auth.PolicyFile
|
||||
{".error.parsing.", ": erro de parsing "},
|
||||
{"COLON", ": "},
|
||||
{".error.adding.Permission.", ": erro ao adicionar a Permiss\u00E3o "},
|
||||
{"SPACE", " "},
|
||||
{".error.adding.Entry.", ": erro ao adicionar a Entrada "},
|
||||
{"LPARAM", "("},
|
||||
{"RPARAM", ")"},
|
||||
{"attempt.to.add.a.Permission.to.a.readonly.PermissionCollection",
|
||||
"tentativa de adicionar uma Permiss\u00E3o a um PermissionCollection somente para leitura"},
|
||||
|
||||
// com.sun.security.auth.PolicyParser
|
||||
{"expected.keystore.type", "tipo de armazenamento de chaves esperado"},
|
||||
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
|
||||
"n\u00E3o \u00E9 poss\u00EDvel especificar um principal com uma classe curinga sem um nome curinga"},
|
||||
{"expected.codeBase.or.SignedBy", "CodeBase ou SignedBy esperado"},
|
||||
{"only.Principal.based.grant.entries.permitted",
|
||||
"somente \u00E9 permitido conceder entradas com base no Principal"},
|
||||
{"expected.permission.entry", "entrada de permiss\u00E3o esperada"},
|
||||
{"number.", "n\u00FAmero "},
|
||||
{"expected.expect.read.end.of.file.",
|
||||
"esperado {0}, ler fim do arquivo"},
|
||||
{"expected.read.end.of.file", "esperado ';', fim de arquivo lido"},
|
||||
{"line.", "linha "},
|
||||
{".expected.", ": esperado '"},
|
||||
{".found.", "', encontrado '"},
|
||||
{"QUOTE", "'"},
|
||||
|
||||
// SolarisPrincipals
|
||||
{"SolarisNumericGroupPrincipal.Primary.Group.",
|
||||
"SolarisNumericGroupPrincipal [Grupo Principal]: "},
|
||||
{"SolarisNumericGroupPrincipal.Supplementary.Group.",
|
||||
"SolarisNumericGroupPrincipal [Grupo Complementar]: "},
|
||||
{"SolarisNumericUserPrincipal.",
|
||||
"SolarisNumericUserPrincipal: "},
|
||||
{"SolarisPrincipal.", "SolarisPrincipal: "},
|
||||
// provided.null.name is the NullPointerException message when a
|
||||
// developer incorrectly passes a null name to the constructor of
|
||||
// subclasses of java.security.Principal
|
||||
{"provided.null.name", "nome nulo fornecido"}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -95,50 +95,6 @@ public class AuthResources_sv extends java.util.ListResourceBundle {
|
||||
"Kerberos-anv\u00E4ndarnamn [{0}]: "},
|
||||
{"Kerberos.password.for.username.",
|
||||
"Kerberos-l\u00F6senord f\u00F6r {0}: "},
|
||||
|
||||
/*** EVERYTHING BELOW IS DEPRECATED ***/
|
||||
|
||||
// com.sun.security.auth.PolicyFile
|
||||
{".error.parsing.", ": tolkningsfel "},
|
||||
{"COLON", ": "},
|
||||
{".error.adding.Permission.", ": fel vid till\u00E4gg av beh\u00F6righet "},
|
||||
{"SPACE", " "},
|
||||
{".error.adding.Entry.", ": fel vid till\u00E4gg av post "},
|
||||
{"LPARAM", "("},
|
||||
{"RPARAM", ")"},
|
||||
{"attempt.to.add.a.Permission.to.a.readonly.PermissionCollection",
|
||||
"f\u00F6rs\u00F6k att l\u00E4gga till beh\u00F6righet till skrivskyddad PermissionCollection"},
|
||||
|
||||
// com.sun.security.auth.PolicyParser
|
||||
{"expected.keystore.type", "f\u00F6rv\u00E4ntad nyckellagertyp"},
|
||||
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
|
||||
"kan inte ange identitetshavare med en jokerteckenklass utan ett jokerteckennamn"},
|
||||
{"expected.codeBase.or.SignedBy", "f\u00F6rv\u00E4ntade codeBase eller SignedBy"},
|
||||
{"only.Principal.based.grant.entries.permitted",
|
||||
"endast identitetshavarbaserade poster till\u00E5ts"},
|
||||
{"expected.permission.entry", "f\u00F6rv\u00E4ntade beh\u00F6righetspost"},
|
||||
{"number.", "nummer"},
|
||||
{"expected.expect.read.end.of.file.",
|
||||
"f\u00F6rv\u00E4ntade {0}, l\u00E4ste filslut"},
|
||||
{"expected.read.end.of.file", "f\u00F6rv\u00E4ntade ';', l\u00E4ste filslut"},
|
||||
{"line.", "rad "},
|
||||
{".expected.", ": f\u00F6rv\u00E4ntade '"},
|
||||
{".found.", "', hittade '"},
|
||||
{"QUOTE", "'"},
|
||||
|
||||
// SolarisPrincipals
|
||||
{"SolarisNumericGroupPrincipal.Primary.Group.",
|
||||
"SolarisNumericGroupPrincipal [prim\u00E4r grupp]: "},
|
||||
{"SolarisNumericGroupPrincipal.Supplementary.Group.",
|
||||
"SolarisNumericGroupPrincipal [till\u00E4ggsgrupp]: "},
|
||||
{"SolarisNumericUserPrincipal.",
|
||||
"SolarisNumericUserPrincipal: "},
|
||||
{"SolarisPrincipal.", "SolarisPrincipal: "},
|
||||
// provided.null.name is the NullPointerException message when a
|
||||
// developer incorrectly passes a null name to the constructor of
|
||||
// subclasses of java.security.Principal
|
||||
{"provided.null.name", "null-namn angavs"}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -95,50 +95,6 @@ public class AuthResources_zh_CN extends java.util.ListResourceBundle {
|
||||
"Kerberos \u7528\u6237\u540D [{0}]: "},
|
||||
{"Kerberos.password.for.username.",
|
||||
"{0}\u7684 Kerberos \u53E3\u4EE4: "},
|
||||
|
||||
/*** EVERYTHING BELOW IS DEPRECATED ***/
|
||||
|
||||
// com.sun.security.auth.PolicyFile
|
||||
{".error.parsing.", ": \u89E3\u6790\u65F6\u51FA\u9519 "},
|
||||
{"COLON", ": "},
|
||||
{".error.adding.Permission.", ": \u6DFB\u52A0\u6743\u9650\u65F6\u51FA\u9519 "},
|
||||
{"SPACE", " "},
|
||||
{".error.adding.Entry.", ": \u6DFB\u52A0\u6761\u76EE\u65F6\u51FA\u9519 "},
|
||||
{"LPARAM", "("},
|
||||
{"RPARAM", ")"},
|
||||
{"attempt.to.add.a.Permission.to.a.readonly.PermissionCollection",
|
||||
"\u5C1D\u8BD5\u5C06\u6743\u9650\u6DFB\u52A0\u81F3\u53EA\u8BFB\u7684 PermissionCollection"},
|
||||
|
||||
// com.sun.security.auth.PolicyParser
|
||||
{"expected.keystore.type", "\u5E94\u4E3A\u5BC6\u94A5\u5E93\u7C7B\u578B"},
|
||||
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
|
||||
"\u6CA1\u6709\u901A\u914D\u7B26\u540D\u79F0, \u65E0\u6CD5\u4F7F\u7528\u901A\u914D\u7B26\u7C7B\u6307\u5B9A\u4E3B\u7528\u6237"},
|
||||
{"expected.codeBase.or.SignedBy", "\u5E94\u4E3A codeBase \u6216 SignedBy"},
|
||||
{"only.Principal.based.grant.entries.permitted",
|
||||
"\u53EA\u5141\u8BB8\u57FA\u4E8E\u4E3B\u7528\u6237\u7684\u6388\u6743\u6761\u76EE"},
|
||||
{"expected.permission.entry", "\u5E94\u4E3A\u6743\u9650\u6761\u76EE"},
|
||||
{"number.", "\u7F16\u53F7 "},
|
||||
{"expected.expect.read.end.of.file.",
|
||||
"\u5E94\u4E3A{0}, \u8BFB\u53D6\u7684\u662F\u6587\u4EF6\u7ED3\u5C3E"},
|
||||
{"expected.read.end.of.file", "\u5E94\u4E3A ';', \u8BFB\u53D6\u7684\u662F\u6587\u4EF6\u7ED3\u5C3E"},
|
||||
{"line.", "\u884C "},
|
||||
{".expected.", ": \u5E94\u4E3A '"},
|
||||
{".found.", "', \u627E\u5230 '"},
|
||||
{"QUOTE", "'"},
|
||||
|
||||
// SolarisPrincipals
|
||||
{"SolarisNumericGroupPrincipal.Primary.Group.",
|
||||
"SolarisNumericGroupPrincipal [\u4E3B\u7EC4]: "},
|
||||
{"SolarisNumericGroupPrincipal.Supplementary.Group.",
|
||||
"SolarisNumericGroupPrincipal [\u8865\u5145\u7EC4]: "},
|
||||
{"SolarisNumericUserPrincipal.",
|
||||
"SolarisNumericUserPrincipal: "},
|
||||
{"SolarisPrincipal.", "SolarisPrincipal: "},
|
||||
// provided.null.name is the NullPointerException message when a
|
||||
// developer incorrectly passes a null name to the constructor of
|
||||
// subclasses of java.security.Principal
|
||||
{"provided.null.name", "\u63D0\u4F9B\u7684\u540D\u79F0\u4E3A\u7A7A\u503C"}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -95,50 +95,6 @@ public class AuthResources_zh_TW extends java.util.ListResourceBundle {
|
||||
"Kerberos \u4F7F\u7528\u8005\u540D\u7A31 [{0}]: "},
|
||||
{"Kerberos.password.for.username.",
|
||||
"Kerberos \u5BC6\u78BC {0}: "},
|
||||
|
||||
/*** EVERYTHING BELOW IS DEPRECATED ***/
|
||||
|
||||
// com.sun.security.auth.PolicyFile
|
||||
{".error.parsing.", ": \u5256\u6790\u932F\u8AA4 "},
|
||||
{"COLON", ": "},
|
||||
{".error.adding.Permission.", ": \u65B0\u589E\u6B0A\u9650\u932F\u8AA4 "},
|
||||
{"SPACE", " "},
|
||||
{".error.adding.Entry.", ": \u65B0\u589E\u8F38\u5165\u932F\u8AA4 "},
|
||||
{"LPARAM", "("},
|
||||
{"RPARAM", ")"},
|
||||
{"attempt.to.add.a.Permission.to.a.readonly.PermissionCollection",
|
||||
"\u8A66\u8457\u65B0\u589E\u6B0A\u9650\u81F3\u552F\u8B80\u7684 PermissionCollection"},
|
||||
|
||||
// com.sun.security.auth.PolicyParser
|
||||
{"expected.keystore.type", "\u9810\u671F\u7684\u91D1\u9470\u5132\u5B58\u5EAB\u985E\u578B"},
|
||||
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
|
||||
"\u6C92\u6709\u842C\u7528\u5B57\u5143\u540D\u7A31\uFF0C\u7121\u6CD5\u6307\u5B9A\u542B\u6709\u842C\u7528\u5B57\u5143\u985E\u5225\u7684 Principal"},
|
||||
{"expected.codeBase.or.SignedBy", "\u9810\u671F\u7684 codeBase \u6216 SignedBy"},
|
||||
{"only.Principal.based.grant.entries.permitted",
|
||||
"\u53EA\u5141\u8A31\u4EE5 Principal \u70BA\u57FA\u790E\u7684\u6388\u6B0A\u9805\u76EE"},
|
||||
{"expected.permission.entry", "\u9810\u671F\u7684\u6B0A\u9650\u9805\u76EE"},
|
||||
{"number.", "\u865F\u78BC "},
|
||||
{"expected.expect.read.end.of.file.",
|
||||
"\u9810\u671F\u70BA {0}, \u8B80\u53D6\u6A94\u6848\u7D50\u5C3E"},
|
||||
{"expected.read.end.of.file", "\u9810\u671F\u7684 ';'\uFF0C\u8B80\u53D6\u6A94\u6848\u7D50\u5C3E"},
|
||||
{"line.", "\u884C "},
|
||||
{".expected.", ": \u9810\u671F '"},
|
||||
{".found.", "'\uFF0C\u767C\u73FE '"},
|
||||
{"QUOTE", "'"},
|
||||
|
||||
// SolarisPrincipals
|
||||
{"SolarisNumericGroupPrincipal.Primary.Group.",
|
||||
"SolarisNumericGroupPrincipal [\u4E3B\u7FA4\u7D44]: "},
|
||||
{"SolarisNumericGroupPrincipal.Supplementary.Group.",
|
||||
"SolarisNumericGroupPrincipal [\u9644\u52A0\u7FA4\u7D44]: "},
|
||||
{"SolarisNumericUserPrincipal.",
|
||||
"SolarisNumericUserPrincipal: "},
|
||||
{"SolarisPrincipal.", "SolarisPrincipal: "},
|
||||
// provided.null.name is the NullPointerException message when a
|
||||
// developer incorrectly passes a null name to the constructor of
|
||||
// subclasses of java.security.Principal
|
||||
{"provided.null.name", "\u63D0\u4F9B\u7A7A\u503C\u540D\u7A31"}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -38,12 +38,12 @@ package javax.transaction.xa;
|
||||
public interface Xid {
|
||||
|
||||
/**
|
||||
* Maximum number of bytes returned by getGtrid.
|
||||
* Maximum number of bytes returned by {@link #getGlobalTransactionId }.
|
||||
*/
|
||||
final static int MAXGTRIDSIZE = 64;
|
||||
|
||||
/**
|
||||
* Maximum number of bytes returned by getBqual.
|
||||
* Maximum number of bytes returned by {@link #getBranchQualifier }.
|
||||
*/
|
||||
final static int MAXBQUALSIZE = 64;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,7 +29,7 @@ import com.sun.tools.attach.spi.AttachProvider; // for javadoc
|
||||
|
||||
/**
|
||||
* Thrown by {@link com.sun.tools.attach.VirtualMachine#attach
|
||||
* VirtalMachine.attach} when attempting to attach to a Java virtual machine
|
||||
* VirtualMachine.attach} when attempting to attach to a Java virtual machine
|
||||
* for which a compatible {@link com.sun.tools.attach.spi.AttachProvider
|
||||
* AttachProvider} does not exist. It is also thrown by {@link
|
||||
* com.sun.tools.attach.spi.AttachProvider#attachVirtualMachine
|
||||
|
@ -28,7 +28,7 @@ package com.sun.tools.attach;
|
||||
/**
|
||||
* When a {@link java.lang.SecurityManager SecurityManager} set, this
|
||||
* is the permission which will be checked when code invokes {@link
|
||||
* VirtualMachine#attach VirtalMachine.attach} to attach to a target virtual
|
||||
* VirtualMachine#attach VirtualMachine.attach} to attach to a target virtual
|
||||
* machine.
|
||||
* This permission is also checked when an {@link
|
||||
* com.sun.tools.attach.spi.AttachProvider AttachProvider} is created.
|
||||
|
@ -29,6 +29,7 @@ import java.io.Writer;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@ -2338,8 +2339,6 @@ public class ConsoleReader
|
||||
out.flush();
|
||||
}
|
||||
|
||||
Stack<Character> pushBackChar = new Stack<Character>();
|
||||
|
||||
if (terminal.isAnsiSupported() && System.console() != null) {
|
||||
//detect the prompt length by reading the cursor position from the terminal
|
||||
//the real prompt length could differ from the simple prompt length due to
|
||||
@ -2357,9 +2356,11 @@ public class ConsoleReader
|
||||
if (m.matches()) {
|
||||
promptLen = Integer.parseInt(m.group("column")) - 1;
|
||||
String prefix = m.group("prefix");
|
||||
List<Character> chars = new ArrayList<>();
|
||||
for (int i = prefix.length() - 1; i >= 0; i--) {
|
||||
pushBackChar.push(prefix.charAt(i));
|
||||
chars.add(prefix.charAt(i));
|
||||
}
|
||||
pushBackChar.addAll(0, chars);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3224,6 +3225,7 @@ public class ConsoleReader
|
||||
//where:
|
||||
private Pattern CURSOR_COLUMN_PATTERN =
|
||||
Pattern.compile("(?<prefix>.*)\033\\[[0-9]+;(?<column>[0-9]+)R", Pattern.DOTALL);
|
||||
private Stack<Character> pushBackChar = new Stack<Character>();
|
||||
|
||||
/**
|
||||
* Read a line for unsupported terminals.
|
||||
|
@ -41,7 +41,7 @@ import com.sun.jdi.event.EventSet;
|
||||
|
||||
public class TargetVM implements Runnable {
|
||||
private Map<String, Packet> waitingQueue = new HashMap<>(32,0.75f);
|
||||
private boolean shouldListen = true;
|
||||
private volatile boolean shouldListen = true;
|
||||
private List<EventQueue> eventQueues = Collections.synchronizedList(new ArrayList<>(2));
|
||||
private VirtualMachineImpl vm;
|
||||
private Connection connection;
|
||||
@ -179,6 +179,9 @@ public class TargetVM implements Runnable {
|
||||
|
||||
// inform the VM mamager that this VM is history
|
||||
vm.vmManager.disposeVirtualMachine(vm);
|
||||
if (eventController != null) {
|
||||
eventController.release();
|
||||
}
|
||||
|
||||
// close down all the event queues
|
||||
// Closing a queue causes a VMDisconnectEvent to
|
||||
@ -237,7 +240,7 @@ public class TargetVM implements Runnable {
|
||||
|
||||
private EventController eventController() {
|
||||
if (eventController == null) {
|
||||
eventController = new EventController(vm);
|
||||
eventController = new EventController();
|
||||
}
|
||||
return eventController;
|
||||
}
|
||||
@ -326,13 +329,11 @@ public class TargetVM implements Runnable {
|
||||
} catch (IOException ioe) { }
|
||||
}
|
||||
|
||||
static private class EventController extends Thread {
|
||||
VirtualMachineImpl vm;
|
||||
private class EventController extends Thread {
|
||||
int controlRequest = 0;
|
||||
|
||||
EventController(VirtualMachineImpl vm) {
|
||||
EventController() {
|
||||
super(vm.threadGroupForJDI(), "JDI Event Control Thread");
|
||||
this.vm = vm;
|
||||
setDaemon(true);
|
||||
setPriority((MAX_PRIORITY + NORM_PRIORITY)/2);
|
||||
super.start();
|
||||
@ -354,6 +355,9 @@ public class TargetVM implements Runnable {
|
||||
synchronized(this) {
|
||||
while (controlRequest == 0) {
|
||||
try {wait();} catch (InterruptedException e) {}
|
||||
if (!shouldListen) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
currentRequest = controlRequest;
|
||||
controlRequest = 0;
|
||||
|
@ -1,300 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.security.auth;
|
||||
|
||||
import java.security.CodeSource;
|
||||
import java.security.PermissionCollection;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
/**
|
||||
* This class represents a default implementation for
|
||||
* {@code javax.security.auth.Policy}.
|
||||
*
|
||||
* <p> This object stores the policy for entire Java runtime,
|
||||
* and is the amalgamation of multiple static policy
|
||||
* configurations that resides in files.
|
||||
* The algorithm for locating the policy file(s) and reading their
|
||||
* information into this {@code Policy} object is:
|
||||
*
|
||||
* <ol>
|
||||
* <li>
|
||||
* Loop through the security properties,
|
||||
* <i>auth.policy.url.1</i>, <i>auth.policy.url.2</i>, ...,
|
||||
* <i>auth.policy.url.X</i>".
|
||||
* Each property value specifies a {@code URL} pointing to a
|
||||
* policy file to be loaded. Read in and load each policy.
|
||||
*
|
||||
* <li>
|
||||
* The {@code java.lang.System} property <i>java.security.auth.policy</i>
|
||||
* may also be set to a {@code URL} pointing to another policy file
|
||||
* (which is the case when a user uses the -D switch at runtime).
|
||||
* If this property is defined, and its use is allowed by the
|
||||
* security property file (the Security property,
|
||||
* <i>policy.allowSystemProperty</i> is set to <i>true</i>),
|
||||
* also load that policy.
|
||||
*
|
||||
* <li>
|
||||
* If the <i>java.security.auth.policy</i> property is defined using
|
||||
* "==" (rather than "="), then ignore all other specified
|
||||
* policies and only load this policy.
|
||||
* </ol>
|
||||
*
|
||||
* Each policy file consists of one or more grant entries, each of
|
||||
* which consists of a number of permission entries.
|
||||
*
|
||||
* <pre>
|
||||
* grant signedBy "<b>alias</b>", codeBase "<b>URL</b>",
|
||||
* principal <b>principalClass</b> "<b>principalName</b>",
|
||||
* principal <b>principalClass</b> "<b>principalName</b>",
|
||||
* ... {
|
||||
*
|
||||
* permission <b>Type</b> "<b>name</b> "<b>action</b>",
|
||||
* signedBy "<b>alias</b>";
|
||||
* permission <b>Type</b> "<b>name</b> "<b>action</b>",
|
||||
* signedBy "<b>alias</b>";
|
||||
* ....
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* All non-bold items above must appear as is (although case
|
||||
* doesn't matter and some are optional, as noted below).
|
||||
* Italicized items represent variable values.
|
||||
*
|
||||
* <p> A grant entry must begin with the word {@code grant}.
|
||||
* The {@code signedBy} and {@code codeBase}
|
||||
* name/value pairs are optional.
|
||||
* If they are not present, then any signer (including unsigned code)
|
||||
* will match, and any codeBase will match. Note that the
|
||||
* {@code principal} name/value pair is not optional.
|
||||
* This {@code Policy} implementation only permits
|
||||
* Principal-based grant entries. Note that the <i>principalClass</i>
|
||||
* may be set to the wildcard value, *, which allows it to match
|
||||
* any {@code Principal} class. In addition, the <i>principalName</i>
|
||||
* may also be set to the wildcard value, *, allowing it to match
|
||||
* any {@code Principal} name. When setting the <i>principalName</i>
|
||||
* to the *, do not surround the * with quotes.
|
||||
*
|
||||
* <p> A permission entry must begin with the word {@code permission}.
|
||||
* The word <i>{@code Type}</i> in the template above is
|
||||
* a specific permission type, such as {@code java.io.FilePermission}
|
||||
* or {@code java.lang.RuntimePermission}.
|
||||
*
|
||||
* <p> The "<i>action</i>" is required for
|
||||
* many permission types, such as {@code java.io.FilePermission}
|
||||
* (where it specifies what type of file access that is permitted).
|
||||
* It is not required for categories such as
|
||||
* {@code java.lang.RuntimePermission}
|
||||
* where it is not necessary - you either have the
|
||||
* permission specified by the "<i>{@code name}</i>"
|
||||
* value following the type name or you don't.
|
||||
*
|
||||
* <p> The {@code signedBy} name/value pair for a permission entry
|
||||
* is optional. If present, it indicates a signed permission. That is,
|
||||
* the permission class itself must be signed by the given alias in
|
||||
* order for it to be granted. For example,
|
||||
* suppose you have the following grant entry:
|
||||
*
|
||||
* <pre>
|
||||
* grant principal foo.com.Principal "Duke" {
|
||||
* permission Foo "foobar", signedBy "FooSoft";
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p> Then this permission of type <i>Foo</i> is granted if the
|
||||
* {@code Foo.class} permission has been signed by the
|
||||
* "FooSoft" alias, or if {@code Foo.class} is a
|
||||
* system class (i.e., is found on the CLASSPATH).
|
||||
*
|
||||
* <p> Items that appear in an entry must appear in the specified order
|
||||
* ({@code permission}, <i>Type</i>, "<i>name</i>", and
|
||||
* "<i>action</i>"). An entry is terminated with a semicolon.
|
||||
*
|
||||
* <p> Case is unimportant for the identifiers ({@code permission},
|
||||
* {@code signedBy}, {@code codeBase}, etc.) but is
|
||||
* significant for the <i>Type</i>
|
||||
* or for any string that is passed in as a value.
|
||||
*
|
||||
* <p> An example of two entries in a policy configuration file is
|
||||
* <pre>
|
||||
* // if the code is comes from "foo.com" and is running as "Duke",
|
||||
* // grant it read/write to all files in /tmp.
|
||||
*
|
||||
* grant codeBase "foo.com", principal foo.com.Principal "Duke" {
|
||||
* permission java.io.FilePermission "/tmp/*", "read,write";
|
||||
* };
|
||||
*
|
||||
* // grant any code running as "Duke" permission to read
|
||||
* // the "java.vendor" Property.
|
||||
*
|
||||
* grant principal foo.com.Principal "Duke" {
|
||||
* permission java.util.PropertyPermission "java.vendor";
|
||||
* </pre>
|
||||
*
|
||||
* <p> This {@code Policy} implementation supports
|
||||
* special handling for PrivateCredentialPermissions.
|
||||
* If a grant entry is configured with a
|
||||
* {@code PrivateCredentialPermission},
|
||||
* and the "Principal Class/Principal Name" for that
|
||||
* {@code PrivateCredentialPermission} is "self",
|
||||
* then the entry grants the specified {@code Subject} permission to
|
||||
* access its own private Credential. For example,
|
||||
* the following grants the {@code Subject} "Duke"
|
||||
* access to its own a.b.Credential.
|
||||
*
|
||||
* <pre>
|
||||
* grant principal foo.com.Principal "Duke" {
|
||||
* permission javax.security.auth.PrivateCredentialPermission
|
||||
* "a.b.Credential self",
|
||||
* "read";
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* The following grants the {@code Subject} "Duke"
|
||||
* access to all of its own private Credentials:
|
||||
*
|
||||
* <pre>
|
||||
* grant principal foo.com.Principal "Duke" {
|
||||
* permission javax.security.auth.PrivateCredentialPermission
|
||||
* "* self",
|
||||
* "read";
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* The following grants all Subjects authenticated as a
|
||||
* {@code SolarisPrincipal} (regardless of their respective names)
|
||||
* permission to access their own private Credentials:
|
||||
*
|
||||
* <pre>
|
||||
* grant principal com.sun.security.auth.SolarisPrincipal * {
|
||||
* permission javax.security.auth.PrivateCredentialPermission
|
||||
* "* self",
|
||||
* "read";
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* The following grants all Subjects permission to access their own
|
||||
* private Credentials:
|
||||
*
|
||||
* <pre>
|
||||
* grant principal * * {
|
||||
* permission javax.security.auth.PrivateCredentialPermission
|
||||
* "* self",
|
||||
* "read";
|
||||
* };
|
||||
* </pre>
|
||||
|
||||
* @deprecated As of JDK 1.4, replaced by
|
||||
* {@code sun.security.provider.PolicyFile}.
|
||||
* This class is entirely deprecated.
|
||||
* This class is subject to removal in a future version of Java SE.
|
||||
*
|
||||
* @see java.security.CodeSource
|
||||
* @see java.security.Permissions
|
||||
* @see java.security.ProtectionDomain
|
||||
* @see java.security.Security security properties
|
||||
*/
|
||||
@Deprecated(since="1.4", forRemoval=true)
|
||||
public class PolicyFile extends javax.security.auth.Policy {
|
||||
|
||||
private final sun.security.provider.AuthPolicyFile apf;
|
||||
|
||||
/**
|
||||
* Initializes the Policy object and reads the default policy
|
||||
* configuration file(s) into the Policy object.
|
||||
*/
|
||||
public PolicyFile() {
|
||||
apf = new sun.security.provider.AuthPolicyFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the policy object by re-reading all the policy files.
|
||||
*
|
||||
* @exception SecurityException if the caller doesn't have permission
|
||||
* to refresh the {@code Policy}.
|
||||
*/
|
||||
@Override
|
||||
public void refresh() {
|
||||
apf.refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Examines this {@code Policy} and returns the Permissions granted
|
||||
* to the specified {@code Subject} and {@code CodeSource}.
|
||||
*
|
||||
* <p> Permissions for a particular <i>grant</i> entry are returned
|
||||
* if the {@code CodeSource} constructed using the codebase and
|
||||
* signedby values specified in the entry {@code implies}
|
||||
* the {@code CodeSource} provided to this method, and if the
|
||||
* {@code Subject} provided to this method contains all of the
|
||||
* Principals specified in the entry.
|
||||
*
|
||||
* <p> The {@code Subject} provided to this method contains all
|
||||
* of the Principals specified in the entry if, for each
|
||||
* {@code Principal}, "P1", specified in the <i>grant</i> entry
|
||||
* one of the following two conditions is met:
|
||||
*
|
||||
* <ol>
|
||||
* <li> the {@code Subject} has a
|
||||
* {@code Principal}, "P2", where
|
||||
* {@code P2.getClass().getName()} equals the
|
||||
* P1's class name, and where
|
||||
* {@code P2.getName()} equals the P1's name.
|
||||
*
|
||||
* <li> P1 implements
|
||||
* {@code com.sun.security.auth.PrincipalComparator},
|
||||
* and {@code P1.implies} the provided {@code Subject}.
|
||||
* </ol>
|
||||
*
|
||||
* <p> Note that this {@code Policy} implementation has
|
||||
* special handling for PrivateCredentialPermissions.
|
||||
* When this method encounters a {@code PrivateCredentialPermission}
|
||||
* which specifies "self" as the {@code Principal} class and name,
|
||||
* it does not add that {@code Permission} to the returned
|
||||
* {@code PermissionCollection}. Instead, it builds
|
||||
* a new {@code PrivateCredentialPermission}
|
||||
* for each {@code Principal} associated with the provided
|
||||
* {@code Subject}. Each new {@code PrivateCredentialPermission}
|
||||
* contains the same Credential class as specified in the
|
||||
* originally granted permission, as well as the Class and name
|
||||
* for the respective {@code Principal}.
|
||||
*
|
||||
* @param subject the Permissions granted to this {@code Subject}
|
||||
* and the additionally provided {@code CodeSource}
|
||||
* are returned.
|
||||
*
|
||||
* @param codesource the Permissions granted to this {@code CodeSource}
|
||||
* and the additionally provided {@code Subject}
|
||||
* are returned.
|
||||
*
|
||||
* @return the Permissions granted to the provided {@code Subject}
|
||||
* {@code CodeSource}.
|
||||
*/
|
||||
@Override
|
||||
public PermissionCollection getPermissions(final Subject subject,
|
||||
final CodeSource codesource) {
|
||||
return apf.getPermissions(subject, codesource);
|
||||
}
|
||||
}
|
@ -1,193 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.security.auth;
|
||||
|
||||
import java.security.Principal;
|
||||
import static sun.security.util.ResourcesMgr.getAuthResourceString;
|
||||
|
||||
/**
|
||||
* This class implements the {@code Principal} interface
|
||||
* and represents a user's Solaris group identification number (GID).
|
||||
*
|
||||
* <p> Principals such as this {@code SolarisNumericGroupPrincipal}
|
||||
* may be associated with a particular {@code Subject}
|
||||
* to augment that {@code Subject} with an additional
|
||||
* identity. Refer to the {@code Subject} class for more information
|
||||
* on how to achieve this. Authorization decisions can then be based upon
|
||||
* the Principals associated with a {@code Subject}.
|
||||
|
||||
* @deprecated As of JDK 1.4, replaced by
|
||||
* {@link UnixNumericGroupPrincipal}.
|
||||
* This class is entirely deprecated.
|
||||
* This class is subject to removal in a future version of Java SE.
|
||||
*
|
||||
* @see java.security.Principal
|
||||
* @see javax.security.auth.Subject
|
||||
*/
|
||||
@Deprecated(since="1.4", forRemoval=true)
|
||||
public class SolarisNumericGroupPrincipal implements
|
||||
Principal,
|
||||
java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2345199581042573224L;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
private boolean primaryGroup;
|
||||
|
||||
/**
|
||||
* Create a {@code SolarisNumericGroupPrincipal} using a
|
||||
* {@code String} representation of the user's
|
||||
* group identification number (GID).
|
||||
*
|
||||
* @param name the user's group identification number (GID)
|
||||
* for this user.
|
||||
*
|
||||
* @param primaryGroup true if the specified GID represents the
|
||||
* primary group to which this user belongs.
|
||||
*
|
||||
* @exception NullPointerException if the {@code name}
|
||||
* is {@code null}.
|
||||
*/
|
||||
public SolarisNumericGroupPrincipal(String name, boolean primaryGroup) {
|
||||
if (name == null)
|
||||
throw new NullPointerException(getAuthResourceString("provided.null.name"));
|
||||
|
||||
this.name = name;
|
||||
this.primaryGroup = primaryGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code SolarisNumericGroupPrincipal} using a
|
||||
* long representation of the user's group identification number (GID).
|
||||
*
|
||||
* @param name the user's group identification number (GID) for this user
|
||||
* represented as a long.
|
||||
*
|
||||
* @param primaryGroup true if the specified GID represents the
|
||||
* primary group to which this user belongs.
|
||||
*
|
||||
*/
|
||||
public SolarisNumericGroupPrincipal(long name, boolean primaryGroup) {
|
||||
this.name = Long.toString(name);
|
||||
this.primaryGroup = primaryGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user's group identification number (GID) for this
|
||||
* {@code SolarisNumericGroupPrincipal}.
|
||||
*
|
||||
* @return the user's group identification number (GID) for this
|
||||
* {@code SolarisNumericGroupPrincipal}
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user's group identification number (GID) for this
|
||||
* {@code SolarisNumericGroupPrincipal} as a long.
|
||||
*
|
||||
* @return the user's group identification number (GID) for this
|
||||
* {@code SolarisNumericGroupPrincipal} as a long.
|
||||
*/
|
||||
public long longValue() {
|
||||
return Long.parseLong(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this group identification number (GID) represents
|
||||
* the primary group to which this user belongs.
|
||||
*
|
||||
* @return true if this group identification number (GID) represents
|
||||
* the primary group to which this user belongs,
|
||||
* or false otherwise.
|
||||
*/
|
||||
public boolean isPrimaryGroup() {
|
||||
return primaryGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of this
|
||||
* {@code SolarisNumericGroupPrincipal}.
|
||||
*
|
||||
* @return a string representation of this
|
||||
* {@code SolarisNumericGroupPrincipal}.
|
||||
*/
|
||||
public String toString() {
|
||||
return primaryGroup ?
|
||||
getAuthResourceString
|
||||
("SolarisNumericGroupPrincipal.Primary.Group.") + name :
|
||||
getAuthResourceString
|
||||
("SolarisNumericGroupPrincipal.Supplementary.Group.") + name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified Object with this
|
||||
* {@code SolarisNumericGroupPrincipal}
|
||||
* for equality. Returns true if the given object is also a
|
||||
* {@code SolarisNumericGroupPrincipal} and the two
|
||||
* SolarisNumericGroupPrincipals
|
||||
* have the same group identification number (GID).
|
||||
*
|
||||
* @param o Object to be compared for equality with this
|
||||
* {@code SolarisNumericGroupPrincipal}.
|
||||
*
|
||||
* @return true if the specified Object is equal to this
|
||||
* {@code SolarisNumericGroupPrincipal}.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (!(o instanceof SolarisNumericGroupPrincipal))
|
||||
return false;
|
||||
SolarisNumericGroupPrincipal that = (SolarisNumericGroupPrincipal)o;
|
||||
|
||||
if (this.getName().equals(that.getName()) &&
|
||||
this.isPrimaryGroup() == that.isPrimaryGroup())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hash code for this {@code SolarisNumericGroupPrincipal}.
|
||||
*
|
||||
* @return a hash code for this {@code SolarisNumericGroupPrincipal}.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.security.auth;
|
||||
|
||||
import java.security.Principal;
|
||||
import static sun.security.util.ResourcesMgr.getAuthResourceString;
|
||||
|
||||
/**
|
||||
* This class implements the {@code Principal} interface
|
||||
* and represents a user's Solaris identification number (UID).
|
||||
*
|
||||
* <p> Principals such as this {@code SolarisNumericUserPrincipal}
|
||||
* may be associated with a particular {@code Subject}
|
||||
* to augment that {@code Subject} with an additional
|
||||
* identity. Refer to the {@code Subject} class for more information
|
||||
* on how to achieve this. Authorization decisions can then be based upon
|
||||
* the Principals associated with a {@code Subject}.
|
||||
* @deprecated As of JDK 1.4, replaced by
|
||||
* {@link UnixNumericUserPrincipal}.
|
||||
* This class is entirely deprecated.
|
||||
* This class is subject to removal in a future version of Java SE.
|
||||
*
|
||||
* @see java.security.Principal
|
||||
* @see javax.security.auth.Subject
|
||||
*/
|
||||
@Deprecated(since="1.4", forRemoval=true)
|
||||
public class SolarisNumericUserPrincipal implements
|
||||
Principal,
|
||||
java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3178578484679887104L;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Create a {@code SolarisNumericUserPrincipal} using a
|
||||
* {@code String} representation of the
|
||||
* user's identification number (UID).
|
||||
*
|
||||
* @param name the user identification number (UID) for this user.
|
||||
*
|
||||
* @exception NullPointerException if the {@code name}
|
||||
* is {@code null}.
|
||||
*/
|
||||
public SolarisNumericUserPrincipal(String name) {
|
||||
if (name == null)
|
||||
throw new NullPointerException(getAuthResourceString("provided.null.name"));
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code SolarisNumericUserPrincipal} using a
|
||||
* long representation of the user's identification number (UID).
|
||||
*
|
||||
* @param name the user identification number (UID) for this user
|
||||
* represented as a long.
|
||||
*/
|
||||
public SolarisNumericUserPrincipal(long name) {
|
||||
this.name = Long.toString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user identification number (UID) for this
|
||||
* {@code SolarisNumericUserPrincipal}.
|
||||
*
|
||||
* @return the user identification number (UID) for this
|
||||
* {@code SolarisNumericUserPrincipal}
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user identification number (UID) for this
|
||||
* {@code SolarisNumericUserPrincipal} as a long.
|
||||
*
|
||||
* @return the user identification number (UID) for this
|
||||
* {@code SolarisNumericUserPrincipal} as a long.
|
||||
*/
|
||||
public long longValue() {
|
||||
return Long.parseLong(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of this
|
||||
* {@code SolarisNumericUserPrincipal}.
|
||||
*
|
||||
* @return a string representation of this
|
||||
* {@code SolarisNumericUserPrincipal}.
|
||||
*/
|
||||
public String toString() {
|
||||
return(getAuthResourceString("SolarisNumericUserPrincipal.") + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified Object with this
|
||||
* {@code SolarisNumericUserPrincipal}
|
||||
* for equality. Returns true if the given object is also a
|
||||
* {@code SolarisNumericUserPrincipal} and the two
|
||||
* SolarisNumericUserPrincipals
|
||||
* have the same user identification number (UID).
|
||||
*
|
||||
* @param o Object to be compared for equality with this
|
||||
* {@code SolarisNumericUserPrincipal}.
|
||||
*
|
||||
* @return true if the specified Object is equal to this
|
||||
* {@code SolarisNumericUserPrincipal}.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (!(o instanceof SolarisNumericUserPrincipal))
|
||||
return false;
|
||||
SolarisNumericUserPrincipal that = (SolarisNumericUserPrincipal)o;
|
||||
|
||||
if (this.getName().equals(that.getName()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hash code for this {@code SolarisNumericUserPrincipal}.
|
||||
*
|
||||
* @return a hash code for this {@code SolarisNumericUserPrincipal}.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.security.auth;
|
||||
|
||||
import java.security.Principal;
|
||||
import static sun.security.util.ResourcesMgr.getAuthResourceString;
|
||||
|
||||
|
||||
/**
|
||||
* This class implements the {@code Principal} interface
|
||||
* and represents a Solaris user.
|
||||
*
|
||||
* <p> Principals such as this {@code SolarisPrincipal}
|
||||
* may be associated with a particular {@code Subject}
|
||||
* to augment that {@code Subject} with an additional
|
||||
* identity. Refer to the {@code Subject} class for more information
|
||||
* on how to achieve this. Authorization decisions can then be based upon
|
||||
* the Principals associated with a {@code Subject}.
|
||||
*
|
||||
* @deprecated As of JDK 1.4, replaced by
|
||||
* {@link UnixPrincipal}.
|
||||
* This class is entirely deprecated.
|
||||
* This class is subject to removal in a future version of Java SE.
|
||||
* @see java.security.Principal
|
||||
* @see javax.security.auth.Subject
|
||||
*/
|
||||
@Deprecated(since="1.4", forRemoval=true)
|
||||
public class SolarisPrincipal implements Principal, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7840670002439379038L;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Create a SolarisPrincipal with a Solaris username.
|
||||
*
|
||||
* @param name the Unix username for this user.
|
||||
*
|
||||
* @exception NullPointerException if the {@code name}
|
||||
* is {@code null}.
|
||||
*/
|
||||
public SolarisPrincipal(String name) {
|
||||
if (name == null)
|
||||
throw new NullPointerException(getAuthResourceString("provided.null.name"));
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Unix username for this {@code SolarisPrincipal}.
|
||||
*
|
||||
* @return the Unix username for this {@code SolarisPrincipal}
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of this {@code SolarisPrincipal}.
|
||||
*
|
||||
* @return a string representation of this {@code SolarisPrincipal}.
|
||||
*/
|
||||
public String toString() {
|
||||
return(getAuthResourceString("SolarisPrincipal.") + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified Object with this {@code SolarisPrincipal}
|
||||
* for equality. Returns true if the given object is also a
|
||||
* {@code SolarisPrincipal} and the two SolarisPrincipals
|
||||
* have the same username.
|
||||
*
|
||||
* @param o Object to be compared for equality with this
|
||||
* {@code SolarisPrincipal}.
|
||||
*
|
||||
* @return true if the specified Object is equal to this
|
||||
* {@code SolarisPrincipal}.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (!(o instanceof SolarisPrincipal))
|
||||
return false;
|
||||
SolarisPrincipal that = (SolarisPrincipal)o;
|
||||
|
||||
if (this.getName().equals(that.getName()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hash code for this {@code SolarisPrincipal}.
|
||||
*
|
||||
* @return a hash code for this {@code SolarisPrincipal}.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
}
|
@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.security.auth;
|
||||
|
||||
import java.security.Principal;
|
||||
import sun.security.x509.X500Name;
|
||||
import static sun.security.util.ResourcesMgr.getAuthResourceString;
|
||||
|
||||
/**
|
||||
* This class represents an X.500 {@code Principal}.
|
||||
* X500Principals have names such as,
|
||||
* "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"
|
||||
* (RFC 1779 style).
|
||||
*
|
||||
* <p> Principals such as this {@code X500Principal}
|
||||
* may be associated with a particular {@code Subject}
|
||||
* to augment that {@code Subject} with an additional
|
||||
* identity. Refer to the {@code Subject} class for more information
|
||||
* on how to achieve this. Authorization decisions can then be based upon
|
||||
* the Principals associated with a {@code Subject}.
|
||||
*
|
||||
* @see java.security.Principal
|
||||
* @see javax.security.auth.Subject
|
||||
* @deprecated A new X500Principal class is available in the Java platform.
|
||||
* This X500Principal classs is entirely deprecated and
|
||||
* is here to allow for a smooth transition to the new
|
||||
* class.
|
||||
* This class is subject to removal in a future version of Java SE.
|
||||
* @see javax.security.auth.x500.X500Principal
|
||||
*/
|
||||
@Deprecated(since="1.4", forRemoval=true)
|
||||
public class X500Principal implements Principal, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8222422609431628648L;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
private String name;
|
||||
|
||||
transient private X500Name thisX500Name;
|
||||
|
||||
/**
|
||||
* Create a X500Principal with an X.500 Name,
|
||||
* such as "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"
|
||||
* (RFC 1779 style).
|
||||
*
|
||||
* @param name the X.500 name
|
||||
*
|
||||
* @exception NullPointerException if the {@code name}
|
||||
* is {@code null}.
|
||||
*
|
||||
* @exception IllegalArgumentException if the {@code name}
|
||||
* is improperly specified.
|
||||
*/
|
||||
public X500Principal(String name) {
|
||||
if (name == null)
|
||||
throw new NullPointerException(getAuthResourceString("provided.null.name"));
|
||||
|
||||
try {
|
||||
thisX500Name = new X500Name(name);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(e.toString());
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Unix username for this {@code X500Principal}.
|
||||
*
|
||||
* @return the Unix username for this {@code X500Principal}
|
||||
*/
|
||||
public String getName() {
|
||||
return thisX500Name.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of this {@code X500Principal}.
|
||||
*
|
||||
* @return a string representation of this {@code X500Principal}.
|
||||
*/
|
||||
public String toString() {
|
||||
return thisX500Name.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified Object with this {@code X500Principal}
|
||||
* for equality.
|
||||
*
|
||||
* @param o Object to be compared for equality with this
|
||||
* {@code X500Principal}.
|
||||
*
|
||||
* @return true if the specified Object is equal to this
|
||||
* {@code X500Principal}.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (o instanceof X500Principal) {
|
||||
X500Principal that = (X500Principal)o;
|
||||
try {
|
||||
X500Name thatX500Name = new X500Name(that.getName());
|
||||
return thisX500Name.equals(thatX500Name);
|
||||
} catch (Exception e) {
|
||||
// any parsing exceptions, return false
|
||||
return false;
|
||||
}
|
||||
} else if (o instanceof Principal) {
|
||||
// this will return 'true' if 'o' is a sun.security.x509.X500Name
|
||||
// and the X500Names are equal
|
||||
return o.equals(thisX500Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hash code for this {@code X500Principal}.
|
||||
*
|
||||
* @return a hash code for this {@code X500Principal}.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return thisX500Name.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads this object from a stream (i.e., deserializes it)
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream s) throws
|
||||
java.io.IOException,
|
||||
java.io.NotActiveException,
|
||||
ClassNotFoundException {
|
||||
|
||||
s.defaultReadObject();
|
||||
|
||||
// re-create thisX500Name
|
||||
thisX500Name = new X500Name(name);
|
||||
}
|
||||
}
|
@ -1,313 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.security.auth.module;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
import javax.security.auth.*;
|
||||
import javax.security.auth.callback.*;
|
||||
import javax.security.auth.login.*;
|
||||
import javax.security.auth.spi.*;
|
||||
import com.sun.security.auth.SolarisPrincipal;
|
||||
import com.sun.security.auth.SolarisNumericUserPrincipal;
|
||||
import com.sun.security.auth.SolarisNumericGroupPrincipal;
|
||||
|
||||
/**
|
||||
* This {@code LoginModule} imports a user's Solaris
|
||||
* {@code Principal} information ({@code SolarisPrincipal},
|
||||
* {@code SolarisNumericUserPrincipal},
|
||||
* and {@code SolarisNumericGroupPrincipal})
|
||||
* and associates them with the current {@code Subject}.
|
||||
*
|
||||
* <p> This LoginModule recognizes the debug option.
|
||||
* If set to true in the login Configuration,
|
||||
* debug messages will be output to the output stream, System.out.
|
||||
* @deprecated As of JDK1.4, replaced by
|
||||
* {@code com.sun.security.auth.module.UnixLoginModule}.
|
||||
* This LoginModule is entirely deprecated and
|
||||
* is here to allow for a smooth transition to the new
|
||||
* UnixLoginModule.
|
||||
* This class is subject to removal in a future version of Java SE.
|
||||
*
|
||||
*/
|
||||
@Deprecated(since="1.4", forRemoval=true)
|
||||
public class SolarisLoginModule implements LoginModule {
|
||||
|
||||
// initial state
|
||||
private Subject subject;
|
||||
private CallbackHandler callbackHandler;
|
||||
private Map<String, ?> sharedState;
|
||||
private Map<String, ?> options;
|
||||
|
||||
// configurable option
|
||||
private boolean debug = true;
|
||||
|
||||
// SolarisSystem to retrieve underlying system info
|
||||
@SuppressWarnings("removal")
|
||||
private SolarisSystem ss;
|
||||
|
||||
// the authentication status
|
||||
private boolean succeeded = false;
|
||||
private boolean commitSucceeded = false;
|
||||
|
||||
// Underlying system info
|
||||
@SuppressWarnings("removal")
|
||||
private SolarisPrincipal userPrincipal;
|
||||
@SuppressWarnings("removal")
|
||||
private SolarisNumericUserPrincipal UIDPrincipal;
|
||||
@SuppressWarnings("removal")
|
||||
private SolarisNumericGroupPrincipal GIDPrincipal;
|
||||
@SuppressWarnings("removal")
|
||||
private LinkedList<SolarisNumericGroupPrincipal> supplementaryGroups =
|
||||
new LinkedList<>();
|
||||
|
||||
/**
|
||||
* Initialize this {@code LoginModule}.
|
||||
*
|
||||
* @param subject the {@code Subject} to be authenticated.
|
||||
*
|
||||
* @param callbackHandler a {@code CallbackHandler} for communicating
|
||||
* with the end user (prompting for usernames and
|
||||
* passwords, for example).
|
||||
*
|
||||
* @param sharedState shared {@code LoginModule} state.
|
||||
*
|
||||
* @param options options specified in the login
|
||||
* {@code Configuration} for this particular
|
||||
* {@code LoginModule}.
|
||||
*/
|
||||
public void initialize(Subject subject, CallbackHandler callbackHandler,
|
||||
Map<String,?> sharedState,
|
||||
Map<String,?> options)
|
||||
{
|
||||
|
||||
this.subject = subject;
|
||||
this.callbackHandler = callbackHandler;
|
||||
this.sharedState = sharedState;
|
||||
this.options = options;
|
||||
|
||||
// initialize any configured options
|
||||
debug = "true".equalsIgnoreCase((String)options.get("debug"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the user (first phase).
|
||||
*
|
||||
* <p> The implementation of this method attempts to retrieve the user's
|
||||
* Solaris {@code Subject} information by making a native Solaris
|
||||
* system call.
|
||||
*
|
||||
* @exception FailedLoginException if attempts to retrieve the underlying
|
||||
* system information fail.
|
||||
*
|
||||
* @return true in all cases (this {@code LoginModule}
|
||||
* should not be ignored).
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public boolean login() throws LoginException {
|
||||
|
||||
long[] solarisGroups = null;
|
||||
|
||||
try {
|
||||
ss = new SolarisSystem();
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
succeeded = false;
|
||||
throw new FailedLoginException
|
||||
("Failed in attempt to import " +
|
||||
"the underlying system identity information" +
|
||||
" on " + System.getProperty("os.name"));
|
||||
}
|
||||
userPrincipal = new SolarisPrincipal(ss.getUsername());
|
||||
UIDPrincipal = new SolarisNumericUserPrincipal(ss.getUid());
|
||||
GIDPrincipal = new SolarisNumericGroupPrincipal(ss.getGid(), true);
|
||||
if (ss.getGroups() != null && ss.getGroups().length > 0)
|
||||
solarisGroups = ss.getGroups();
|
||||
for (int i = 0; i < solarisGroups.length; i++) {
|
||||
SolarisNumericGroupPrincipal ngp =
|
||||
new SolarisNumericGroupPrincipal
|
||||
(solarisGroups[i], false);
|
||||
if (!ngp.getName().equals(GIDPrincipal.getName()))
|
||||
supplementaryGroups.add(ngp);
|
||||
}
|
||||
if (debug) {
|
||||
System.out.println("\t\t[SolarisLoginModule]: " +
|
||||
"succeeded importing info: ");
|
||||
System.out.println("\t\t\tuid = " + ss.getUid());
|
||||
System.out.println("\t\t\tgid = " + ss.getGid());
|
||||
solarisGroups = ss.getGroups();
|
||||
for (int i = 0; i < solarisGroups.length; i++) {
|
||||
System.out.println("\t\t\tsupp gid = " + solarisGroups[i]);
|
||||
}
|
||||
}
|
||||
succeeded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the authentication (second phase).
|
||||
*
|
||||
* <p> This method is called if the LoginContext's
|
||||
* overall authentication succeeded
|
||||
* (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
|
||||
* succeeded).
|
||||
*
|
||||
* <p> If this LoginModule's own authentication attempt
|
||||
* succeeded (the importing of the Solaris authentication information
|
||||
* succeeded), then this method associates the Solaris Principals
|
||||
* with the {@code Subject} currently tied to the
|
||||
* {@code LoginModule}. If this LoginModule's
|
||||
* authentication attempted failed, then this method removes
|
||||
* any state that was originally saved.
|
||||
*
|
||||
* @exception LoginException if the commit fails
|
||||
*
|
||||
* @return true if this LoginModule's own login and commit attempts
|
||||
* succeeded, or false otherwise.
|
||||
*/
|
||||
public boolean commit() throws LoginException {
|
||||
if (succeeded == false) {
|
||||
if (debug) {
|
||||
System.out.println("\t\t[SolarisLoginModule]: " +
|
||||
"did not add any Principals to Subject " +
|
||||
"because own authentication failed.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (subject.isReadOnly()) {
|
||||
throw new LoginException ("Subject is Readonly");
|
||||
}
|
||||
if (!subject.getPrincipals().contains(userPrincipal))
|
||||
subject.getPrincipals().add(userPrincipal);
|
||||
if (!subject.getPrincipals().contains(UIDPrincipal))
|
||||
subject.getPrincipals().add(UIDPrincipal);
|
||||
if (!subject.getPrincipals().contains(GIDPrincipal))
|
||||
subject.getPrincipals().add(GIDPrincipal);
|
||||
for (int i = 0; i < supplementaryGroups.size(); i++) {
|
||||
if (!subject.getPrincipals().contains(supplementaryGroups.get(i)))
|
||||
subject.getPrincipals().add(supplementaryGroups.get(i));
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
System.out.println("\t\t[SolarisLoginModule]: " +
|
||||
"added SolarisPrincipal,");
|
||||
System.out.println("\t\t\t\tSolarisNumericUserPrincipal,");
|
||||
System.out.println("\t\t\t\tSolarisNumericGroupPrincipal(s),");
|
||||
System.out.println("\t\t\t to Subject");
|
||||
}
|
||||
|
||||
commitSucceeded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Abort the authentication (second phase).
|
||||
*
|
||||
* <p> This method is called if the LoginContext's
|
||||
* overall authentication failed.
|
||||
* (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
|
||||
* did not succeed).
|
||||
*
|
||||
* <p> This method cleans up any state that was originally saved
|
||||
* as part of the authentication attempt from the {@code login}
|
||||
* and {@code commit} methods.
|
||||
*
|
||||
* @exception LoginException if the abort fails
|
||||
*
|
||||
* @return false if this LoginModule's own login and/or commit attempts
|
||||
* failed, and true otherwise.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public boolean abort() throws LoginException {
|
||||
if (debug) {
|
||||
System.out.println("\t\t[SolarisLoginModule]: " +
|
||||
"aborted authentication attempt");
|
||||
}
|
||||
|
||||
if (succeeded == false) {
|
||||
return false;
|
||||
} else if (succeeded == true && commitSucceeded == false) {
|
||||
|
||||
// Clean out state
|
||||
succeeded = false;
|
||||
ss = null;
|
||||
userPrincipal = null;
|
||||
UIDPrincipal = null;
|
||||
GIDPrincipal = null;
|
||||
supplementaryGroups =
|
||||
new LinkedList<SolarisNumericGroupPrincipal>();
|
||||
} else {
|
||||
// overall authentication succeeded and commit succeeded,
|
||||
// but someone else's commit failed
|
||||
logout();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout the user
|
||||
*
|
||||
* <p> This method removes the Principals associated
|
||||
* with the {@code Subject}.
|
||||
*
|
||||
* @exception LoginException if the logout fails
|
||||
*
|
||||
* @return true in all cases (this {@code LoginModule}
|
||||
* should not be ignored).
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public boolean logout() throws LoginException {
|
||||
if (debug) {
|
||||
System.out.println("\t\t[SolarisLoginModule]: " +
|
||||
"Entering logout");
|
||||
}
|
||||
if (subject.isReadOnly()) {
|
||||
throw new LoginException ("Subject is Readonly");
|
||||
}
|
||||
// remove the added Principals from the Subject
|
||||
subject.getPrincipals().remove(userPrincipal);
|
||||
subject.getPrincipals().remove(UIDPrincipal);
|
||||
subject.getPrincipals().remove(GIDPrincipal);
|
||||
for (int i = 0; i < supplementaryGroups.size(); i++) {
|
||||
subject.getPrincipals().remove(supplementaryGroups.get(i));
|
||||
}
|
||||
|
||||
// clean out state
|
||||
ss = null;
|
||||
succeeded = false;
|
||||
commitSucceeded = false;
|
||||
userPrincipal = null;
|
||||
UIDPrincipal = null;
|
||||
GIDPrincipal = null;
|
||||
supplementaryGroups = new LinkedList<SolarisNumericGroupPrincipal>();
|
||||
|
||||
if (debug) {
|
||||
System.out.println("\t\t[SolarisLoginModule]: " +
|
||||
"logged out Subject");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.security.auth.module;
|
||||
|
||||
/**
|
||||
* This class implementation retrieves and makes available Solaris
|
||||
* UID/GID/groups information for the current user.
|
||||
*
|
||||
* @deprecated replaced by {@link UnixSystem}.
|
||||
* This class is subject to removal in a future version of Java SE.
|
||||
*/
|
||||
@Deprecated(since="1.4", forRemoval=true)
|
||||
public class SolarisSystem {
|
||||
|
||||
private native void getSolarisInfo();
|
||||
|
||||
protected String username;
|
||||
protected long uid;
|
||||
protected long gid;
|
||||
protected long[] groups;
|
||||
|
||||
/**
|
||||
* Instantiate a {@code SolarisSystem} and load
|
||||
* the native library to access the underlying system information.
|
||||
*/
|
||||
public SolarisSystem() {
|
||||
System.loadLibrary("jaas_unix");
|
||||
getSolarisInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the username for the current Solaris user.
|
||||
*
|
||||
* @return the username for the current Solaris user.
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UID for the current Solaris user.
|
||||
*
|
||||
* @return the UID for the current Solaris user.
|
||||
*/
|
||||
public long getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the GID for the current Solaris user.
|
||||
*
|
||||
* @return the GID for the current Solaris user.
|
||||
*/
|
||||
public long getGid() {
|
||||
return gid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the supplementary groups for the current Solaris user.
|
||||
*
|
||||
* @return the supplementary groups for the current Solaris user.
|
||||
*/
|
||||
public long[] getGroups() {
|
||||
return groups == null ? null : groups.clone();
|
||||
}
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include "com_sun_security_auth_module_SolarisSystem.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* For POSIX-compliant getpwuid_r on Solaris */
|
||||
#if defined(__solaris__)
|
||||
#define _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
|
||||
static void throwIllegalArgumentException(JNIEnv *env, const char *msg) {
|
||||
jclass clazz = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
|
||||
if (clazz != NULL)
|
||||
(*env)->ThrowNew(env, clazz, msg);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_sun_security_auth_module_SolarisSystem_getSolarisInfo
|
||||
(JNIEnv *env, jobject obj) {
|
||||
|
||||
int i;
|
||||
long pwd_bufsize;
|
||||
char *pwd_buf = NULL;
|
||||
struct passwd pwd;
|
||||
struct passwd* p = NULL;
|
||||
jsize numSuppGroups = getgroups(0, NULL);
|
||||
jfieldID fid;
|
||||
jstring jstr;
|
||||
jlongArray jgroups;
|
||||
jlong *jgroupsAsArray;
|
||||
gid_t *groups;
|
||||
jclass cls;
|
||||
|
||||
pwd_bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
if (pwd_bufsize == -1) {
|
||||
pwd_bufsize = 1024;
|
||||
}
|
||||
pwd_buf = (char *)malloc(pwd_bufsize);
|
||||
groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t));
|
||||
|
||||
if (pwd_buf == NULL || groups == NULL) {
|
||||
if (pwd_buf != NULL) {
|
||||
free(pwd_buf);
|
||||
}
|
||||
if (groups != NULL) {
|
||||
free(groups);
|
||||
}
|
||||
cls = (*env)->FindClass(env,"java/lang/OutOfMemoryError");
|
||||
if (cls != NULL) {
|
||||
(*env)->ThrowNew(env, cls, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cls = (*env)->GetObjectClass(env, obj);
|
||||
|
||||
if (getpwuid_r(getuid(), &pwd, pwd_buf, sizeof(pwd_buf), &p) != 0 &&
|
||||
p != NULL && getgroups(numSuppGroups, groups) != -1) {
|
||||
|
||||
/*
|
||||
* set username
|
||||
*/
|
||||
fid = (*env)->GetFieldID(env, cls, "username", "Ljava/lang/String;");
|
||||
if (fid == 0) {
|
||||
(*env)->ExceptionClear(env);
|
||||
throwIllegalArgumentException(env, "invalid field: username");
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
jstr = (*env)->NewStringUTF(env, pwd.pw_name);
|
||||
if (jstr == NULL) {
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
(*env)->SetObjectField(env, obj, fid, jstr);
|
||||
|
||||
/*
|
||||
* set uid
|
||||
*/
|
||||
fid = (*env)->GetFieldID(env, cls, "uid", "J");
|
||||
if (fid == 0) {
|
||||
(*env)->ExceptionClear(env);
|
||||
throwIllegalArgumentException(env, "invalid field: uid");
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
(*env)->SetLongField(env, obj, fid, pwd.pw_uid);
|
||||
|
||||
/*
|
||||
* set gid
|
||||
*/
|
||||
fid = (*env)->GetFieldID(env, cls, "gid", "J");
|
||||
if (fid == 0) {
|
||||
(*env)->ExceptionClear(env);
|
||||
throwIllegalArgumentException(env, "invalid field: gid");
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
(*env)->SetLongField(env, obj, fid, pwd.pw_gid);
|
||||
|
||||
/*
|
||||
* set supplementary groups
|
||||
*/
|
||||
fid = (*env)->GetFieldID(env, cls, "groups", "[J");
|
||||
if (fid == 0) {
|
||||
(*env)->ExceptionClear(env);
|
||||
throwIllegalArgumentException(env, "invalid field: groups");
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
|
||||
jgroups = (*env)->NewLongArray(env, numSuppGroups);
|
||||
if (jgroups == NULL) {
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
jgroupsAsArray = (*env)->GetLongArrayElements(env, jgroups, 0);
|
||||
if (jgroupsAsArray == NULL) {
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
for (i = 0; i < numSuppGroups; i++)
|
||||
jgroupsAsArray[i] = groups[i];
|
||||
(*env)->ReleaseLongArrayElements(env, jgroups, jgroupsAsArray, 0);
|
||||
(*env)->SetObjectField(env, obj, fid, jgroups);
|
||||
}
|
||||
cleanupAndReturn:
|
||||
free(pwd_buf);
|
||||
free(groups);
|
||||
return;
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
#
|
||||
# A "headful" test requires a graphical environment to meaningfully
|
||||
# run. Tests that are not headful are "headless".
|
||||
# A test flagged with key "printer" requires a printer to succeed, else
|
||||
# A test flagged with key "printer" requires a printer to succeed, else
|
||||
# throws a PrinterException or the like.
|
||||
|
||||
keys=2d dnd headful i18n intermittent printer randomness
|
||||
@ -28,8 +28,8 @@ groups=TEST.groups [closed/TEST.groups]
|
||||
# Allow querying of various System properties in @requires clauses
|
||||
requires.properties=sun.arch.data.model java.runtime.name
|
||||
|
||||
# Tests using jtreg 4.2 b07 features
|
||||
requiredVersion=4.2 b07
|
||||
# Minimum jtreg version
|
||||
requiredVersion=4.2 b08
|
||||
|
||||
# Path to libraries in the topmost test directory. This is needed so @library
|
||||
# does not need ../../ notation to reach them
|
||||
|
@ -24,318 +24,362 @@
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.security.Security;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import jdk.testlibrary.ProcessTools;
|
||||
import jdk.testlibrary.OutputAnalyzer;
|
||||
import jdk.test.lib.compiler.CompilerUtils;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import java.lang.module.ModuleDescriptor.Builder;
|
||||
import jdk.internal.module.ModuleInfoWriter;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
/**
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8130360
|
||||
* @library /lib/testlibrary
|
||||
* @library /java/security/modules
|
||||
* @library /test/lib
|
||||
* @bug 8130360 8183310
|
||||
* @summary Test security provider in different combination of modular option
|
||||
* defined with(out) service description.
|
||||
* @library /lib/testlibrary /test/lib
|
||||
* @modules java.base/jdk.internal.module
|
||||
* @build jdk.test.lib.compiler.CompilerUtils JarUtils
|
||||
* @summary Test custom security provider module with all possible modular
|
||||
* condition. The test includes different combination of security
|
||||
* client/provider modules interaction with or without service
|
||||
* description.
|
||||
* @run testng SecurityProviderModularTest
|
||||
* @build JarUtils TestProvider TestClient
|
||||
* @run main SecurityProviderModularTest CL true
|
||||
* @run main SecurityProviderModularTest CL false
|
||||
* @run main SecurityProviderModularTest SL true
|
||||
* @run main SecurityProviderModularTest SL false
|
||||
* @run main SecurityProviderModularTest SPN true
|
||||
* @run main SecurityProviderModularTest SPN false
|
||||
* @run main SecurityProviderModularTest SPT true
|
||||
* @run main SecurityProviderModularTest SPT false
|
||||
*/
|
||||
public class SecurityProviderModularTest extends ModularTest {
|
||||
public class SecurityProviderModularTest {
|
||||
|
||||
private static final Path S_SRC = SRC.resolve("TestSecurityProvider.java");
|
||||
private static final String S_PKG = "provider";
|
||||
private static final String S_JAR_NAME = S_PKG + JAR_EXTN;
|
||||
private static final String S_WITH_DESCR_JAR_NAME = S_PKG + DESCRIPTOR
|
||||
+ JAR_EXTN;
|
||||
private static final String MS_JAR_NAME = MODULAR + S_PKG + JAR_EXTN;
|
||||
private static final String MS_WITH_DESCR_JAR_NAME = MODULAR + S_PKG
|
||||
+ DESCRIPTOR + JAR_EXTN;
|
||||
|
||||
private static final Path C_SRC = SRC.resolve(
|
||||
"TestSecurityProviderClient.java");
|
||||
private static final String C_PKG = "client";
|
||||
private static final String C_JAR_NAME = C_PKG + JAR_EXTN;
|
||||
private static final String MCN_JAR_NAME = MODULAR + C_PKG + "N" + JAR_EXTN;
|
||||
private static final String MC_JAR_NAME = MODULAR + C_PKG + JAR_EXTN;
|
||||
|
||||
private static final Path BUILD_DIR = Paths.get(".").resolve("build");
|
||||
private static final Path COMPILE_DIR = BUILD_DIR.resolve("bin");
|
||||
private static final Path S_BUILD_DIR = COMPILE_DIR.resolve(S_PKG);
|
||||
private static final Path S_WITH_META_DESCR_BUILD_DIR = COMPILE_DIR.resolve(
|
||||
S_PKG + DESCRIPTOR);
|
||||
private static final Path C_BLD_DIR = COMPILE_DIR.resolve(C_PKG);
|
||||
private static final Path M_BASE_PATH = BUILD_DIR.resolve("mbase");
|
||||
private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts");
|
||||
|
||||
private static final Path S_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(S_PKG);
|
||||
private static final Path S_JAR = S_ARTIFACTS_DIR.resolve(S_JAR_NAME);
|
||||
private static final Path S_WITH_DESCRIPTOR_JAR = S_ARTIFACTS_DIR.resolve(
|
||||
S_WITH_DESCR_JAR_NAME);
|
||||
private static final Path MS_JAR = S_ARTIFACTS_DIR.resolve(
|
||||
MS_JAR_NAME);
|
||||
private static final Path MS_WITH_DESCR_JAR = S_ARTIFACTS_DIR.resolve(
|
||||
MS_WITH_DESCR_JAR_NAME);
|
||||
|
||||
private static final Path C_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(C_PKG);
|
||||
private static final Path C_JAR = C_ARTIFACTS_DIR.resolve(C_JAR_NAME);
|
||||
private static final Path MC_JAR = C_ARTIFACTS_DIR.resolve(MC_JAR_NAME);
|
||||
private static final Path MCN_JAR = C_ARTIFACTS_DIR.resolve(MCN_JAR_NAME);
|
||||
|
||||
private static final String MAIN = C_PKG + ".TestSecurityProviderClient";
|
||||
private static final String S_INTERFACE = "java.security.Provider";
|
||||
private static final String S_IMPL = S_PKG + ".TestSecurityProvider";
|
||||
private static final List<String> M_REQUIRED = Arrays.asList("java.base");
|
||||
private static final Path META_DESCR_PATH = Paths.get("META-INF")
|
||||
.resolve("services").resolve(S_INTERFACE);
|
||||
private static final Path S_META_DESCR_FPATH = S_WITH_META_DESCR_BUILD_DIR
|
||||
.resolve(META_DESCR_PATH);
|
||||
|
||||
private static final boolean WITH_S_DESCR = true;
|
||||
private static final boolean WITHOUT_S_DESCR = false;
|
||||
private static final String PROVIDER_NOT_FOUND_MSG = "Unable to find Test"
|
||||
+ " Security Provider";
|
||||
private static final String CAN_NOT_ACCESS_MSG = "cannot access class";
|
||||
private static final String NO_FAILURE = null;
|
||||
private static final String SERVICE_LOADER = "SERVICE_LOADER";
|
||||
private static final String CLASS_LOADER = "CLASS_LOADER";
|
||||
private static final String SECURITY_PROP = "SECURITY_PROP";
|
||||
private static final List<String> MECHANISMS = Arrays.asList(SERVICE_LOADER,
|
||||
CLASS_LOADER, SECURITY_PROP);
|
||||
private static final Path SECURE_PROP_EXTN = Paths.get("./java.secure.ext");
|
||||
private static final Path TEST_CLASSES
|
||||
= Paths.get(System.getProperty("test.classes"));
|
||||
private static final Path ARTIFACT_DIR = Paths.get("jars");
|
||||
private static final Path SEC_FILE = Paths.get("java.extn.security");
|
||||
private static final String PS = File.pathSeparator;
|
||||
private static final String P_TYPE = "p.TestProvider";
|
||||
private static final String C_TYPE = "c.TestClient";
|
||||
|
||||
/**
|
||||
* Generates Test specific input parameters.
|
||||
* Here is the naming convention followed.
|
||||
* Test runtime arguments,
|
||||
* CL - Provider class loaded through ClassLoader
|
||||
* SL - Provider class to be discovered by ServiceLoader
|
||||
* SPN - Provider name defined through "java.extn.security" file which
|
||||
* referred through system property "java.security.properties".
|
||||
* SPT - Provider type defined through "java.extn.security" file which
|
||||
* referred through system property "java.security.properties".
|
||||
*
|
||||
* For each jar file name,
|
||||
* p.jar - Unnamed provider jar.
|
||||
* pd.jar - Unnamed provider jar with META-INF provider descriptor.
|
||||
* mp.jar - Modular provider jar.
|
||||
* mpd.jar - Modular provider jar with META-INF provider descriptor.
|
||||
* msp.jar - Modular provider jar provides service through module-info.java
|
||||
* mspd.jar - Modular provider jar with META-INF provider descriptor and
|
||||
* provides service through module-info.java.
|
||||
* c.jar - Unnamed client jar.
|
||||
* mc.jar - Modular client jar.
|
||||
* mcs.jar - Modular client jar uses service through module-info.java.
|
||||
* amc.jar - Modular client used for automatic provider jar.
|
||||
* amcs.jar - Modular client used for automatic provider jar uses service
|
||||
* through module-info.java.
|
||||
*/
|
||||
@Override
|
||||
public Object[][] getTestInput() {
|
||||
private static final Path P_JAR = artifact("p.jar");
|
||||
private static final Path PD_JAR = artifact("pd.jar");
|
||||
private static final Path MP_JAR = artifact("mp.jar");
|
||||
private static final Path MPD_JAR = artifact("mpd.jar");
|
||||
private static final Path MSP_JAR = artifact("msp.jar");
|
||||
private static final Path MSPD_JAR = artifact("mspd.jar");
|
||||
private static final Path C_JAR = artifact("c.jar");
|
||||
private static final Path MC_JAR = artifact("mc.jar");
|
||||
private static final Path MCS_JAR = artifact("mcs.jar");
|
||||
private static final Path AMC_JAR = artifact("amc.jar");
|
||||
private static final Path AMCS_JAR = artifact("amcs.jar");
|
||||
private static final Map<String, String> MSG_MAP = new HashMap<>();
|
||||
|
||||
List<List<Object>> params = new ArrayList<>();
|
||||
MECHANISMS.stream().forEach((mechanism) -> {
|
||||
boolean useCLoader = CLASS_LOADER.equals(mechanism);
|
||||
boolean useSLoader = SERVICE_LOADER.equals(mechanism);
|
||||
String[] args = new String[]{mechanism};
|
||||
// PARAMETER ORDERS -
|
||||
// Client Module Type, Service Module Type,
|
||||
// If Service META Descriptor Required,
|
||||
// Expected Failure message, mechanism used to find the provider
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO,
|
||||
WITH_S_DESCR, ((useCLoader) ? CAN_NOT_ACCESS_MSG
|
||||
: NO_FAILURE), args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO,
|
||||
WITHOUT_S_DESCR, ((useCLoader) ? CAN_NOT_ACCESS_MSG
|
||||
: PROVIDER_NOT_FOUND_MSG), args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED,
|
||||
WITH_S_DESCR, ((useCLoader) ? CAN_NOT_ACCESS_MSG
|
||||
: NO_FAILURE), args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED,
|
||||
WITHOUT_S_DESCR, ((useCLoader) ? CAN_NOT_ACCESS_MSG
|
||||
: ((useSLoader) ? PROVIDER_NOT_FOUND_MSG
|
||||
: NO_FAILURE)), args));
|
||||
static {
|
||||
/*
|
||||
* This mapping help process finding expected message based
|
||||
* on the key passed as argument while executing java command.
|
||||
*/
|
||||
MSG_MAP.put("NoAccess", "cannot access class p.TestProvider");
|
||||
MSG_MAP.put("Success", "Client: found provider TestProvider");
|
||||
MSG_MAP.put("NoProvider", "Provider TestProvider not found");
|
||||
}
|
||||
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO,
|
||||
WITHOUT_S_DESCR,
|
||||
(useCLoader) ? NO_FAILURE : PROVIDER_NOT_FOUND_MSG, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED,
|
||||
WITHOUT_S_DESCR, ((useSLoader) ? PROVIDER_NOT_FOUND_MSG
|
||||
: NO_FAILURE), args));
|
||||
private final String addUNArg;
|
||||
private final String addNMArg;
|
||||
private final String cArg;
|
||||
private final String unnP;
|
||||
private final String modP;
|
||||
private final String unnC;
|
||||
private final String modC;
|
||||
private final String autoMC;
|
||||
private final String expModRes;
|
||||
private final String expAModRes;
|
||||
// Common set of VM arguments used in all test cases
|
||||
private final List<String> commonArgs;
|
||||
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO,
|
||||
WITHOUT_S_DESCR,
|
||||
(useCLoader) ? NO_FAILURE : PROVIDER_NOT_FOUND_MSG, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED,
|
||||
WITHOUT_S_DESCR, ((useSLoader) ? PROVIDER_NOT_FOUND_MSG
|
||||
: NO_FAILURE), args));
|
||||
});
|
||||
return params.stream().map(p -> p.toArray()).toArray(Object[][]::new);
|
||||
public SecurityProviderModularTest(String use, boolean metaDesc) {
|
||||
|
||||
List<String> argList = new LinkedList<>();
|
||||
argList.add("-Duser.language=en");
|
||||
argList.add("-Duser.region=US");
|
||||
final boolean useSL = "SL".equals(use) || "SPN".equals(use);
|
||||
final boolean useCL = "CL".equals(use);
|
||||
final boolean useSPT = "SPT".equals(use);
|
||||
final boolean useSP = use.startsWith("SP");
|
||||
/* Use Security property file when the provider expected to
|
||||
* loaded through Security property file. */
|
||||
if (useSP) {
|
||||
/* Create a java.security file to specify the new provider.
|
||||
* java.security file extension can be provided using
|
||||
* "-Djava.security.properties" VM argument at runtime.*/
|
||||
createJavaSecurityFileExtn("SPN".equals(use));
|
||||
argList.add("-Djava.security.properties=" + toAbsPath(SEC_FILE));
|
||||
}
|
||||
commonArgs = Collections.unmodifiableList(argList);
|
||||
cArg = (useCL) ? P_TYPE : "TestProvider";
|
||||
addUNArg = (useSL) ? "" : ("--add-modules="
|
||||
+ ((metaDesc) ? "pd" : "p"));
|
||||
addNMArg = (useSL) ? "" : "--add-modules=mp";
|
||||
|
||||
// Based on Testcase, select unnamed/modular jar files to use.
|
||||
unnP = toAbsPath((metaDesc) ? PD_JAR : P_JAR);
|
||||
modP = toAbsPath(useSL ? (metaDesc ? MSPD_JAR : MSP_JAR)
|
||||
: (metaDesc ? MPD_JAR : MP_JAR));
|
||||
unnC = toAbsPath(C_JAR);
|
||||
modC = toAbsPath(useSL ? MCS_JAR : MC_JAR);
|
||||
autoMC = toAbsPath(useSL ? AMCS_JAR : AMC_JAR);
|
||||
|
||||
expModRes = "Success";
|
||||
expAModRes = (useSPT | useCL) ? "Success"
|
||||
: (metaDesc) ? "Success" : "NoProvider";
|
||||
String loadByMsg = useSP ? "SecurityPropertyFile"
|
||||
: ((useCL) ? "ClassLoader" : "ServiceLoader");
|
||||
System.out.printf("%n*** Providers loaded through %s and includes"
|
||||
+ " META Descriptor: %s ***%n%n", loadByMsg, metaDesc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test cases are based on the following logic,
|
||||
* for (ProviderLoadedThrough : {"ServiceLoader", "ClassLoader",
|
||||
* "SecurityPropertyFile"}) {
|
||||
* for (definedWith : {"METAINFService", "WithoutMETAINFService"}) {
|
||||
* for (clientType : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
|
||||
* for (providerType : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
|
||||
* Create and run java command for each possible case
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// Generates unnamed and modular jars.
|
||||
setUp();
|
||||
boolean metaDesc = Boolean.valueOf(args[1]);
|
||||
SecurityProviderModularTest test
|
||||
= new SecurityProviderModularTest(args[0], metaDesc);
|
||||
test.process(args[0]);
|
||||
}
|
||||
|
||||
private void process(String use) throws Exception {
|
||||
|
||||
// Case: NAMED-NAMED, NAMED-AUTOMATIC, NAMED-UNNAMED
|
||||
System.out.printf("Case: Modular Client and Modular Provider");
|
||||
execute(String.format("--module-path %s%s%s -m mc/%s %s %s",
|
||||
modC, PS, modP, C_TYPE, use, cArg), expModRes);
|
||||
System.out.printf("Case: Modular Client and automatic Provider");
|
||||
execute(String.format("--module-path %s%s%s %s -m mc/%s %s %s", autoMC,
|
||||
PS, unnP, addUNArg, C_TYPE, use, cArg), expAModRes);
|
||||
System.out.printf("Case: Modular Client and unnamed Provider");
|
||||
execute(String.format("--module-path %s -cp %s -m mc/%s %s %s", autoMC,
|
||||
unnP, C_TYPE, use, cArg), expAModRes);
|
||||
|
||||
// Case: AUTOMATIC-NAMED, AUTOMATIC-AUTOMATIC, AUTOMATIC-UNNAMED
|
||||
System.out.printf("Case: Automatic Client and modular Provider");
|
||||
execute(String.format("--module-path %s%s%s %s -m c/%s %s %s", unnC,
|
||||
PS, modP, addNMArg, C_TYPE, use, cArg), expModRes);
|
||||
System.out.printf("Case: Automatic Client and automatic Provider");
|
||||
execute(String.format("--module-path %s%s%s %s -m c/%s %s %s", unnC,
|
||||
PS, unnP, addUNArg, C_TYPE, use, cArg), expAModRes);
|
||||
System.out.printf("Case: Automatic Client and unnamed Provider");
|
||||
execute(String.format("--module-path %s -cp %s -m c/%s %s %s", unnC,
|
||||
unnP, C_TYPE, use, cArg), expAModRes);
|
||||
|
||||
// Case: UNNAMED-NAMED, UNNAMED-AUTOMATIC, UNNAMED-UNNAMED
|
||||
System.out.printf("Case: Unnamed Client and modular Provider");
|
||||
execute(String.format("-cp %s --module-path %s %s %s %s %s", unnC,
|
||||
modP, addNMArg, C_TYPE, use, cArg), expModRes);
|
||||
System.out.printf("Case: Unnamed Client and automatic Provider");
|
||||
execute(String.format("-cp %s --module-path %s %s %s %s %s", unnC,
|
||||
unnP, addUNArg, C_TYPE, use, cArg), expAModRes);
|
||||
System.out.printf("Case: Unnamed Client and unnamed Provider");
|
||||
execute(String.format("-cp %s%s%s %s %s %s", unnC, PS, unnP, C_TYPE,
|
||||
use, cArg), expAModRes);
|
||||
|
||||
// Case: unnamed jars in --module-path and modular jars in -cp.
|
||||
System.out.printf(
|
||||
"Case: Unnamed Client and Unnamed Provider in modulepath");
|
||||
execute(String.format("--module-path %s%s%s %s -m c/%s %s %s", unnC,
|
||||
PS, unnP, addUNArg, C_TYPE, use, cArg), expAModRes);
|
||||
System.out.printf(
|
||||
"Case: Modular Client and Modular Provider in classpath");
|
||||
execute(String.format("-cp %s%s%s %s %s %s", modC, PS, modP, C_TYPE,
|
||||
use, cArg), expAModRes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-compile and generate the artifacts required to run this test before
|
||||
* running each test cases.
|
||||
* Execute with command arguments and process the result.
|
||||
*/
|
||||
@BeforeTest
|
||||
public void buildArtifacts() {
|
||||
private void execute(String args, String msgKey) throws Exception {
|
||||
|
||||
boolean done = true;
|
||||
try {
|
||||
|
||||
done &= CompilerUtils.compile(S_SRC, S_BUILD_DIR);
|
||||
done &= CompilerUtils.compile(S_SRC, S_WITH_META_DESCR_BUILD_DIR);
|
||||
done &= createMetaInfServiceDescriptor(S_META_DESCR_FPATH, S_IMPL);
|
||||
// Generate modular/regular jars with(out) META-INF
|
||||
// service descriptor
|
||||
generateJar(true, MODULE_TYPE.EXPLICIT, MS_JAR, S_BUILD_DIR, false);
|
||||
generateJar(true, MODULE_TYPE.EXPLICIT, MS_WITH_DESCR_JAR,
|
||||
S_WITH_META_DESCR_BUILD_DIR, false);
|
||||
generateJar(true, MODULE_TYPE.UNNAMED, S_JAR, S_BUILD_DIR, false);
|
||||
generateJar(true, MODULE_TYPE.UNNAMED, S_WITH_DESCRIPTOR_JAR,
|
||||
S_WITH_META_DESCR_BUILD_DIR, false);
|
||||
// Compile client source codes.
|
||||
done &= CompilerUtils.compile(C_SRC, C_BLD_DIR, "-cp",
|
||||
S_JAR.toFile().getCanonicalPath());
|
||||
// Generate modular client jar with explicit dependency
|
||||
generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BLD_DIR, true);
|
||||
// Generate modular client jar without any dependency
|
||||
generateJar(false, MODULE_TYPE.EXPLICIT, MCN_JAR, C_BLD_DIR, false);
|
||||
// Generate regular client jar
|
||||
generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BLD_DIR, false);
|
||||
System.out.format("%nArtifacts generated successfully? %s", done);
|
||||
if (!done) {
|
||||
throw new RuntimeException("Artifacts generation failed");
|
||||
String[] safeArgs = Stream.concat(commonArgs.stream(),
|
||||
Stream.of(args.split("\\s+"))).filter(s -> {
|
||||
if (s.contains(" ")) {
|
||||
throw new RuntimeException("No spaces in args");
|
||||
}
|
||||
return !s.isEmpty();
|
||||
}).toArray(String[]::new);
|
||||
String out = ProcessTools.executeTestJvm(safeArgs).getOutput();
|
||||
// Handle response.
|
||||
if ((msgKey != null && out.contains(MSG_MAP.get(msgKey)))) {
|
||||
System.out.printf("PASS: Expected Result: %s.%n",
|
||||
MSG_MAP.get(msgKey));
|
||||
} else if (out.contains("Exception") || out.contains("Error")) {
|
||||
System.out.printf("OUTPUT: %s", out);
|
||||
throw new RuntimeException("FAIL: Unknown Exception occured. "
|
||||
+ "Expected: " + MSG_MAP.get(msgKey));
|
||||
} else {
|
||||
System.out.printf("OUTPUT: %s", out);
|
||||
throw new RuntimeException("FAIL: Unknown Test case found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Unnamed/modular jar files for TestClient and TestClassLoader.
|
||||
*/
|
||||
private static void setUp() throws Exception {
|
||||
|
||||
if (ARTIFACT_DIR.toFile().exists()) {
|
||||
System.out.println("Skipping setup: Artifacts already exists.");
|
||||
return;
|
||||
}
|
||||
// Generate unnamed provider jar file.
|
||||
JarUtils.createJarFile(P_JAR, TEST_CLASSES, "p/TestProvider.class");
|
||||
// Generate unnamed client jar file.
|
||||
JarUtils.createJarFile(C_JAR, TEST_CLASSES, "c/TestClient.class");
|
||||
// Generate unnamed provider jar files with META-INF descriptor.
|
||||
generateJar(P_JAR, PD_JAR, null, true);
|
||||
|
||||
Builder mBuilder = ModuleDescriptor.newModule("mp").exports("p");
|
||||
// Modular provider defined as META-INF service.
|
||||
generateJar(P_JAR, MPD_JAR, mBuilder.build(), true);
|
||||
// Modular jar exports package to let the provider type accessible.
|
||||
generateJar(P_JAR, MP_JAR, mBuilder.build(), false);
|
||||
|
||||
mBuilder = ModuleDescriptor.newModule("mp")
|
||||
.provides("java.security.Provider", Arrays.asList(P_TYPE));
|
||||
// Modular provider Service in module-info does not need to export
|
||||
// its package.
|
||||
generateJar(P_JAR, MSP_JAR, mBuilder.build(), false);
|
||||
// Modular provider Service in module-info also have META-INF descriptor
|
||||
generateJar(P_JAR, MSPD_JAR, mBuilder.build(), true);
|
||||
|
||||
mBuilder = ModuleDescriptor.newModule("mc").exports("c");
|
||||
// Generate modular client jar file to use automatic provider jar.
|
||||
generateJar(C_JAR, AMC_JAR, mBuilder.build(), false);
|
||||
// Generate modular client jar file to use modular provider jar.
|
||||
generateJar(C_JAR, MC_JAR, mBuilder.requires("mp").build(), false);
|
||||
|
||||
mBuilder = ModuleDescriptor.newModule("mc").exports("c")
|
||||
.uses("java.security.Provider");
|
||||
// Generate modular client jar file to use automatic provider service.
|
||||
generateJar(C_JAR, AMCS_JAR, mBuilder.build(), false);
|
||||
// Generate modular client jar file using modular provider service.
|
||||
generateJar(C_JAR, MCS_JAR, mBuilder.requires("mp").build(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Unnamed jars and include descriptor files.
|
||||
*/
|
||||
private static void generateJar(Path sjar, Path djar,
|
||||
ModuleDescriptor mDesc, boolean metaDesc) throws Exception {
|
||||
|
||||
Files.copy(sjar, djar, StandardCopyOption.REPLACE_EXISTING);
|
||||
Path dir = Files.createTempDirectory("tmp");
|
||||
if (metaDesc) {
|
||||
write(dir.resolve(Paths.get("META-INF", "services",
|
||||
"java.security.Provider")), P_TYPE);
|
||||
}
|
||||
if (mDesc != null) {
|
||||
Path mi = dir.resolve("module-info.class");
|
||||
try (OutputStream out = Files.newOutputStream(mi)) {
|
||||
ModuleInfoWriter.write(mDesc, out);
|
||||
}
|
||||
System.out.format("Added 'module-info.class' in '%s'%n", djar);
|
||||
}
|
||||
JarUtils.updateJarFile(djar, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for file path in generated jars.
|
||||
*/
|
||||
private static Path artifact(String file) {
|
||||
return ARTIFACT_DIR.resolve(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to absolute file path.
|
||||
*/
|
||||
private static String toAbsPath(Path path) {
|
||||
return path.toFile().getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the parent directories if missing to ensure the path exist.
|
||||
*/
|
||||
private static Path ensurePath(Path at) throws IOException {
|
||||
Path parent = at.getParent();
|
||||
if (parent != null && !parent.toFile().exists()) {
|
||||
ensurePath(parent);
|
||||
}
|
||||
return Files.createDirectories(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates service descriptor inside META-INF folder.
|
||||
*/
|
||||
private static void write(Path at, String content) throws IOException {
|
||||
ensurePath(at);
|
||||
Files.write(at, content.getBytes("UTF-8"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new provider entry through java.security file extension.
|
||||
* New provider entry will be the last entry inside the JRE.
|
||||
*/
|
||||
private static void createJavaSecurityFileExtn(boolean useName) {
|
||||
int insertAt = Security.getProviders().length + 1;
|
||||
String provider = (useName ? "TestProvider" : P_TYPE);
|
||||
try {
|
||||
Files.write(SEC_FILE, String.format("security.provider.%s=%s",
|
||||
insertAt, provider).getBytes("UTF-8"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
System.out.printf("Security property file created at: %s with value:"
|
||||
+ " %s%n", SEC_FILE, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate modular/regular jar based on module type for this test.
|
||||
*/
|
||||
private void generateJar(boolean isService, MODULE_TYPE moduleType,
|
||||
Path jar, Path compilePath, boolean depends) throws IOException {
|
||||
|
||||
ModuleDescriptor mDescriptor = null;
|
||||
if (isService) {
|
||||
mDescriptor = generateModuleDescriptor(isService, moduleType, S_PKG,
|
||||
S_PKG, S_INTERFACE, S_IMPL, null, M_REQUIRED, depends);
|
||||
} else {
|
||||
mDescriptor = generateModuleDescriptor(isService, moduleType, C_PKG,
|
||||
C_PKG, S_INTERFACE, null, S_PKG, M_REQUIRED, depends);
|
||||
}
|
||||
generateJar(mDescriptor, jar, compilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds Logic for the test. This method will get called with each test
|
||||
* parameter.
|
||||
*/
|
||||
@Override
|
||||
public OutputAnalyzer executeTestClient(MODULE_TYPE cModuleType,
|
||||
Path cJarPath, MODULE_TYPE sModuletype, Path sJarPath,
|
||||
String... args) throws Exception {
|
||||
|
||||
OutputAnalyzer output = null;
|
||||
try {
|
||||
// For automated/explicit module types, copy the corresponding
|
||||
// jars to module base folder, which will be considered as
|
||||
// module base path during execution.
|
||||
if (!(cModuleType == MODULE_TYPE.UNNAMED
|
||||
&& sModuletype == MODULE_TYPE.UNNAMED)) {
|
||||
copyJarsToModuleBase(cModuleType, cJarPath, M_BASE_PATH);
|
||||
copyJarsToModuleBase(sModuletype, sJarPath, M_BASE_PATH);
|
||||
}
|
||||
|
||||
System.out.format("%nExecuting java client with required"
|
||||
+ " custom security provider in class/module path.");
|
||||
String mName = getModuleName(cModuleType, cJarPath, C_PKG);
|
||||
Path cmBasePath = (cModuleType != MODULE_TYPE.UNNAMED
|
||||
|| sModuletype != MODULE_TYPE.UNNAMED) ? M_BASE_PATH : null;
|
||||
String cPath = buildClassPath(cModuleType, cJarPath, sModuletype,
|
||||
sJarPath);
|
||||
|
||||
Map<String, String> vmArgs = getVMArgs(sModuletype,
|
||||
getModuleName(sModuletype, sJarPath, S_PKG), args);
|
||||
output = ProcessTools.executeTestJava(
|
||||
getJavaCommand(cmBasePath, cPath, mName, MAIN, vmArgs,
|
||||
args)).outputTo(System.out).errorTo(System.out);
|
||||
} finally {
|
||||
// Clean module path to hold required jars for next run.
|
||||
cleanModuleBasePath(M_BASE_PATH);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide the pre-generated client/service jar path for each test case
|
||||
* based on client/service module type.
|
||||
*/
|
||||
@Override
|
||||
public Path findJarPath(boolean isService, MODULE_TYPE moduleType,
|
||||
boolean addMetaDesc, boolean dependsOnServiceModule) {
|
||||
if (isService) {
|
||||
if (moduleType == MODULE_TYPE.EXPLICIT) {
|
||||
if (addMetaDesc) {
|
||||
return MS_WITH_DESCR_JAR;
|
||||
} else {
|
||||
return MS_JAR;
|
||||
}
|
||||
} else {
|
||||
if (addMetaDesc) {
|
||||
return S_WITH_DESCRIPTOR_JAR;
|
||||
} else {
|
||||
return S_JAR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Choose corresponding client jar to use dependent module
|
||||
if (moduleType == MODULE_TYPE.EXPLICIT) {
|
||||
if (dependsOnServiceModule) {
|
||||
return MC_JAR;
|
||||
} else {
|
||||
return MCN_JAR;
|
||||
}
|
||||
} else {
|
||||
return C_JAR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* VM argument required for the test.
|
||||
*/
|
||||
private Map<String, String> getVMArgs(MODULE_TYPE sModuletype,
|
||||
String addModName, String... args) throws IOException {
|
||||
final Map<String, String> vmArgs = new LinkedHashMap<>();
|
||||
vmArgs.put("-Duser.language=", "en");
|
||||
vmArgs.put("-Duser.region=", "US");
|
||||
if (addModName != null && sModuletype == MODULE_TYPE.AUTO) {
|
||||
vmArgs.put("--add-modules=", addModName);
|
||||
}
|
||||
// If mechanism selected to find the provider through
|
||||
// Security.getProvider() then use providerName/ProviderClassName based
|
||||
// on modular/regular provider jar in security configuration file.
|
||||
if (args != null && args.length > 0 && SECURITY_PROP.equals(args[0])) {
|
||||
if (sModuletype == MODULE_TYPE.UNNAMED) {
|
||||
Files.write(SECURE_PROP_EXTN, ("security.provider.10=" + S_IMPL)
|
||||
.getBytes());
|
||||
} else {
|
||||
Files.write(SECURE_PROP_EXTN, "security.provider.10=TEST"
|
||||
.getBytes());
|
||||
}
|
||||
vmArgs.put("-Djava.security.properties=", SECURE_PROP_EXTN.toFile()
|
||||
.getCanonicalPath());
|
||||
}
|
||||
return vmArgs;
|
||||
}
|
||||
|
||||
}
|
||||
|
77
jdk/test/java/security/Provider/TestClient.java
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2017 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.
|
||||
*/
|
||||
package c;
|
||||
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* A Test client using different mechanism to search the custom security
|
||||
* provider. It uses ClassLoader, ServiceLoader and default mechanism to find
|
||||
* a provider registered through "java.security" extension file.
|
||||
*/
|
||||
public class TestClient {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
Provider p = null;
|
||||
if (args != null && args.length > 1) {
|
||||
switch (args[0]) {
|
||||
case "CL":
|
||||
p = (Provider) Class.forName(args[1]).newInstance();
|
||||
if (Security.addProvider(p) == -1) {
|
||||
throw new RuntimeException("Failed to add provider");
|
||||
}
|
||||
break;
|
||||
case "SL":
|
||||
ServiceLoader<Provider> services
|
||||
= ServiceLoader.load(java.security.Provider.class);
|
||||
Iterator<Provider> iterator = services.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Provider spr = iterator.next();
|
||||
if (spr.getName().equals(args[1])) {
|
||||
p = spr;
|
||||
if (Security.addProvider(p) == -1) {
|
||||
throw new RuntimeException(
|
||||
"Failed to add provider");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "SPN":
|
||||
case "SPT":
|
||||
p = Security.getProvider(args[1]);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Invalid argument.");
|
||||
}
|
||||
}
|
||||
if (p == null) {
|
||||
throw new RuntimeException("Provider TestProvider not found");
|
||||
}
|
||||
System.out.printf("Client: found provider %s", p.getName());
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
* Copyright (c) 2015, 2016, 2017 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
|
||||
@ -20,26 +20,25 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package provider;
|
||||
package p;
|
||||
|
||||
import java.security.Provider;
|
||||
|
||||
/**
|
||||
* Custom Security provider for modular test.
|
||||
*/
|
||||
public final class TestSecurityProvider extends Provider {
|
||||
public final class TestProvider extends Provider {
|
||||
|
||||
public TestSecurityProvider() {
|
||||
super("TEST", "1.0", "Test Security provider");
|
||||
public TestProvider() {
|
||||
super("TestProvider", "1.0", "Test Security provider");
|
||||
System.out.println(String.format("TEST Security provider loaded"
|
||||
+ " successfully : %s", this.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TestSecurityProvider [getName()=" + getName()
|
||||
return "TestProvider [getName()=" + getName()
|
||||
+ ", getVersion()=" + getVersionStr() + ", getInfo()="
|
||||
+ getInfo() + ", toString()=" + super.toString() + "]";
|
||||
}
|
||||
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
package client;
|
||||
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* Modular test for client using different mechanism to find the custom security
|
||||
* provider. It uses ServiceLoader and ClassLoader to find the TEST provider
|
||||
* available in classPath/modulePath. It also tries to find, if the provider is
|
||||
* configured through "java.security" file.
|
||||
*/
|
||||
public class TestSecurityProviderClient {
|
||||
|
||||
private static final String CUSTOM_PROVIDER_NAME = "TEST";
|
||||
private static final String EXCEPTION_MESSAGE
|
||||
= "Unable to find Test Security Provider";
|
||||
private static final String SERVICE_LOADER = "SERVICE_LOADER";
|
||||
private static final String CLASS_LOADER = "CLASS_LOADER";
|
||||
|
||||
public static void main(String[] args) {
|
||||
Provider provider = null;
|
||||
//Try to find the TEST provider loaded by ServiceLoader.
|
||||
if (args != null && args.length > 0
|
||||
&& SERVICE_LOADER.equals(args[0])) {
|
||||
System.out.println(
|
||||
"Using service loader to find Security provider.");
|
||||
ServiceLoader<Provider> services
|
||||
= ServiceLoader.load(java.security.Provider.class);
|
||||
Iterator<Provider> iterator = services.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Provider p = iterator.next();
|
||||
if (p.getName().equals(CUSTOM_PROVIDER_NAME)) {
|
||||
provider = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (args != null && args.length > 0
|
||||
&& CLASS_LOADER.equals(args[0])) {
|
||||
System.out.println("Using class loader to find Security provider.");
|
||||
//Find the TEST provider loaded by ClassLoader.
|
||||
provider = new provider.TestSecurityProvider();
|
||||
} else {
|
||||
//Find the TEST provider configured through Security.getProvider().
|
||||
System.out.println("Finding Security provider through"
|
||||
+ " Security.getProvider().");
|
||||
provider = Security.getProvider(CUSTOM_PROVIDER_NAME);
|
||||
}
|
||||
|
||||
if (provider != null) {
|
||||
System.out.format("%nTest Security provider named '%s' loaded "
|
||||
+ "successfully", CUSTOM_PROVIDER_NAME);
|
||||
} else {
|
||||
throw new RuntimeException(EXCEPTION_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,279 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import jdk.testlibrary.OutputAnalyzer;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import jdk.internal.module.ModuleInfoWriter;
|
||||
import static java.lang.module.ModuleDescriptor.Builder;
|
||||
|
||||
/**
|
||||
* Base class need to be extended by modular test for security.
|
||||
*/
|
||||
public abstract class ModularTest {
|
||||
|
||||
/**
|
||||
* Enum represents all supported module types supported in JDK9. i.e.
|
||||
* EXPLICIT - Modules have module descriptor(module-info.java)
|
||||
* defining the module.
|
||||
* AUTO - Are regular jar files but provided in MODULE_PATH instead
|
||||
* of CLASS_PATH.
|
||||
* UNNAMED - Are regular jar but provided through CLASS_PATH.
|
||||
*/
|
||||
public enum MODULE_TYPE {
|
||||
|
||||
EXPLICIT, AUTO, UNNAMED;
|
||||
}
|
||||
|
||||
public static final String SPACE = " ";
|
||||
public static final Path SRC = Paths.get(System.getProperty("test.src"));
|
||||
public static final String DESCRIPTOR = "MetaService";
|
||||
public static final String MODULAR = "Modular";
|
||||
public static final String AUTO = "AutoServiceType";
|
||||
public static final String JAR_EXTN = ".jar";
|
||||
|
||||
/**
|
||||
* Setup test data for the test.
|
||||
*/
|
||||
@DataProvider(name = "TestParams")
|
||||
public Object[][] setUpTestData() {
|
||||
return getTestInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for TestNG.
|
||||
*/
|
||||
@Test(dataProvider = "TestParams")
|
||||
public void runTest(MODULE_TYPE cModuleType, MODULE_TYPE sModuletype,
|
||||
boolean addMetaDesc, String failureMsgExpected, String[] args)
|
||||
throws Exception {
|
||||
|
||||
String testName = new StringJoiner("_").add(cModuleType.toString())
|
||||
.add(sModuletype.toString()).add(
|
||||
(addMetaDesc) ? "WITH_SERVICE" : "NO_SERVICE")
|
||||
.toString();
|
||||
|
||||
System.out.format("%nStarting Test case: '%s'", testName);
|
||||
Path cJarPath = findJarPath(false, cModuleType, false,
|
||||
(sModuletype == MODULE_TYPE.EXPLICIT));
|
||||
Path sJarPath = findJarPath(true, sModuletype, addMetaDesc, false);
|
||||
System.out.format("%nClient jar path : %s ", cJarPath);
|
||||
System.out.format("%nService jar path : %s ", sJarPath);
|
||||
OutputAnalyzer output = executeTestClient(cModuleType, cJarPath,
|
||||
sModuletype, sJarPath, args);
|
||||
|
||||
if (output.getExitValue() != 0) {
|
||||
if (failureMsgExpected != null
|
||||
&& output.getOutput().contains(failureMsgExpected)) {
|
||||
System.out.println("PASS: Test is expected to fail here.");
|
||||
} else {
|
||||
System.out.format("%nUnexpected failure occured with exit code"
|
||||
+ " '%s'.", output.getExitValue());
|
||||
throw new RuntimeException("Unexpected failure occured.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method need to be implemented by each Test type to provide
|
||||
* test parameters.
|
||||
*/
|
||||
public abstract Object[][] getTestInput();
|
||||
|
||||
/**
|
||||
* Execute the test client to access required service.
|
||||
*/
|
||||
public abstract OutputAnalyzer executeTestClient(MODULE_TYPE cModuleType,
|
||||
Path cJarPath, MODULE_TYPE sModuletype, Path sJarPath,
|
||||
String... args) throws Exception;
|
||||
|
||||
/**
|
||||
* Find the Jar for service/client based on module type and if service
|
||||
* descriptor required.
|
||||
*/
|
||||
public abstract Path findJarPath(boolean service, MODULE_TYPE moduleType,
|
||||
boolean addMetaDesc, boolean dependsOnServiceModule);
|
||||
|
||||
/**
|
||||
* Constructs a Java Command line string based on modular structure followed
|
||||
* by modular client and service.
|
||||
*/
|
||||
public String[] getJavaCommand(Path modulePath, String classPath,
|
||||
String clientModuleName, String mainClass,
|
||||
Map<String, String> vmArgs, String... options) throws IOException {
|
||||
|
||||
final StringJoiner command = new StringJoiner(SPACE, SPACE, SPACE);
|
||||
vmArgs.forEach((key, value) -> command.add(key + value));
|
||||
if (modulePath != null) {
|
||||
command.add("--module-path").add(modulePath.toFile().getCanonicalPath());
|
||||
}
|
||||
if (classPath != null && classPath.length() > 0) {
|
||||
command.add("-cp").add(classPath);
|
||||
}
|
||||
if (clientModuleName != null && clientModuleName.length() > 0) {
|
||||
command.add("-m").add(clientModuleName + "/" + mainClass);
|
||||
} else {
|
||||
command.add(mainClass);
|
||||
}
|
||||
command.add(Arrays.stream(options).collect(Collectors.joining(SPACE)));
|
||||
return command.toString().trim().split("[\\s]+");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate ModuleDescriptor object for explicit/auto based client/Service
|
||||
* modules type.
|
||||
*/
|
||||
public ModuleDescriptor generateModuleDescriptor(boolean isService,
|
||||
MODULE_TYPE moduleType, String moduleName, String pkg,
|
||||
String serviceInterface, String serviceImpl,
|
||||
String serviceModuleName, List<String> requiredModules,
|
||||
boolean depends) {
|
||||
|
||||
final Builder builder;
|
||||
if (moduleType == MODULE_TYPE.EXPLICIT) {
|
||||
System.out.format(" %nGenerating ModuleDescriptor object");
|
||||
builder = ModuleDescriptor.newModule(moduleName).exports(pkg);
|
||||
if (isService && serviceInterface != null && serviceImpl != null) {
|
||||
builder.provides(serviceInterface, List.of(serviceImpl));
|
||||
} else {
|
||||
if (serviceInterface != null) {
|
||||
builder.uses(serviceInterface);
|
||||
}
|
||||
if (depends) {
|
||||
builder.requires(serviceModuleName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.format(" %nModuleDescriptor object not required.");
|
||||
return null;
|
||||
}
|
||||
requiredModules.stream().forEach(reqMod -> builder.requires(reqMod));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates service descriptor inside META-INF folder.
|
||||
*/
|
||||
public boolean createMetaInfServiceDescriptor(
|
||||
Path serviceDescriptorFile, String serviceImpl) {
|
||||
boolean created = true;
|
||||
System.out.format("%nCreating META-INF service descriptor for '%s' "
|
||||
+ "at path '%s'", serviceImpl, serviceDescriptorFile);
|
||||
try {
|
||||
Path parent = serviceDescriptorFile.getParent();
|
||||
if (parent != null) {
|
||||
Files.createDirectories(parent);
|
||||
}
|
||||
Files.write(serviceDescriptorFile, serviceImpl.getBytes("UTF-8"));
|
||||
System.out.println(
|
||||
"META-INF service descriptor generated successfully");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace(System.out);
|
||||
created = false;
|
||||
}
|
||||
return created;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate modular/regular jar file.
|
||||
*/
|
||||
public void generateJar(ModuleDescriptor mDescriptor, Path jar,
|
||||
Path compilePath) throws IOException {
|
||||
System.out.format("%nCreating jar file '%s'", jar);
|
||||
JarUtils.createJarFile(jar, compilePath);
|
||||
if (mDescriptor != null) {
|
||||
Path dir = Files.createTempDirectory("tmp");
|
||||
Path mi = dir.resolve("module-info.class");
|
||||
try (OutputStream out = Files.newOutputStream(mi)) {
|
||||
ModuleInfoWriter.write(mDescriptor, out);
|
||||
}
|
||||
System.out.format("%nAdding 'module-info.class' to jar '%s'", jar);
|
||||
JarUtils.updateJarFile(jar, dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy pre-generated jar files to the module base path.
|
||||
*/
|
||||
public void copyJarsToModuleBase(MODULE_TYPE moduleType, Path jar,
|
||||
Path mBasePath) throws IOException {
|
||||
if (mBasePath != null) {
|
||||
Files.createDirectories(mBasePath);
|
||||
}
|
||||
if (moduleType != MODULE_TYPE.UNNAMED) {
|
||||
Path artifactName = mBasePath.resolve(jar.getFileName());
|
||||
System.out.format("%nCopy jar path: '%s' to module base path: %s",
|
||||
jar, artifactName);
|
||||
Files.copy(jar, artifactName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct class path string.
|
||||
*/
|
||||
public String buildClassPath(MODULE_TYPE cModuleType,
|
||||
Path cJarPath, MODULE_TYPE sModuletype,
|
||||
Path sJarPath) throws IOException {
|
||||
StringJoiner classPath = new StringJoiner(File.pathSeparator);
|
||||
classPath.add((cModuleType == MODULE_TYPE.UNNAMED)
|
||||
? cJarPath.toFile().getCanonicalPath() : "");
|
||||
classPath.add((sModuletype == MODULE_TYPE.UNNAMED)
|
||||
? sJarPath.toFile().getCanonicalPath() : "");
|
||||
return classPath.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct executable module name for java. It is fixed for explicit
|
||||
* module type while it is same as jar file name for automated module type.
|
||||
*/
|
||||
public String getModuleName(MODULE_TYPE moduleType,
|
||||
Path jarPath, String mName) {
|
||||
String jarName = jarPath.toFile().getName();
|
||||
return (moduleType == MODULE_TYPE.EXPLICIT) ? mName
|
||||
: ((moduleType == MODULE_TYPE.AUTO) ? jarName.substring(0,
|
||||
jarName.indexOf(JAR_EXTN)) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the files inside the base module path.
|
||||
*/
|
||||
public void cleanModuleBasePath(Path mBasePath) {
|
||||
Arrays.asList(mBasePath.toFile().listFiles()).forEach(f -> {
|
||||
System.out.println("delete: " + f);
|
||||
f.delete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
67
jdk/test/java/util/jar/JarFile/JarBacktickManifest.java
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 8186334
|
||||
* @library /lib/testlibrary/java/util/jar
|
||||
* @build JarBuilder
|
||||
* @run testng JarBacktickManifest
|
||||
* @summary Make sure scanning manifest doesn't throw AIOOBE on certain strings
|
||||
* containing backticks.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class JarBacktickManifest {
|
||||
|
||||
public static final String VERIFY_MANIFEST_JAR = "verifyManifest.jar";
|
||||
|
||||
@BeforeClass
|
||||
public void initialize() throws Exception {
|
||||
JarBuilder jb = new JarBuilder(VERIFY_MANIFEST_JAR);
|
||||
jb.addAttribute("Test", " Class-`Path` ");
|
||||
jb.addAttribute("Test2", " Multi-`Release ");
|
||||
jb.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
try (JarFile jf = new JarFile(VERIFY_MANIFEST_JAR)) { // do not set runtime versioning
|
||||
Assert.assertFalse(jf.isMultiRelease(), "Shouldn't be multi-release");
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void close() throws IOException {
|
||||
Files.delete(new File(VERIFY_MANIFEST_JAR).toPath());
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import com.sun.security.auth.SolarisPrincipal;
|
||||
import com.sun.security.auth.UnixPrincipal;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
/*
|
||||
@ -46,7 +46,7 @@ import javax.security.auth.Subject;
|
||||
* permission javax.security.auth.AuthPermission \
|
||||
* "modifyPrivateCredentials";
|
||||
* permission javax.security.auth.PrivateCredentialPermission \
|
||||
* "java.lang.String com.sun.security.auth.SolarisPrincipal \"user"", "read";
|
||||
* "java.lang.String com.sun.security.auth.UnixPrincipal \"user"", "read";
|
||||
* };
|
||||
|
||||
* The test verifies the following:
|
||||
@ -71,7 +71,7 @@ public class Subset {
|
||||
HashSet creds = new HashSet();
|
||||
Subject emptys =
|
||||
new Subject(false, //readOnly
|
||||
Collections.singleton(new SolarisPrincipal("user")),
|
||||
Collections.singleton(new UnixPrincipal("user")),
|
||||
Collections.EMPTY_SET,
|
||||
creds);
|
||||
/* Test principals */
|
||||
@ -104,7 +104,7 @@ public class Subset {
|
||||
creds.add(Boolean.TRUE);
|
||||
Subject sremove =
|
||||
new Subject(false, //readOnly
|
||||
Collections.singleton(new SolarisPrincipal("user")),
|
||||
Collections.singleton(new UnixPrincipal("user")),
|
||||
Collections.EMPTY_SET,
|
||||
creds);
|
||||
Set p2 = sremove.getPrivateCredentials();
|
||||
@ -184,7 +184,7 @@ public class Subset {
|
||||
creds1.add(new String("Exists"));
|
||||
Subject scontain =
|
||||
new Subject(false, //readOnly
|
||||
Collections.singleton(new SolarisPrincipal("user")),
|
||||
Collections.singleton(new UnixPrincipal("user")),
|
||||
Collections.EMPTY_SET,
|
||||
creds1);
|
||||
p2 = scontain.getPrivateCredentials();
|
||||
@ -237,7 +237,7 @@ public class Subset {
|
||||
creds2.add("ghi");
|
||||
Subject sstring =
|
||||
new Subject(false, //readOnly
|
||||
Collections.singleton(new SolarisPrincipal("user")),
|
||||
Collections.singleton(new UnixPrincipal("user")),
|
||||
Collections.EMPTY_SET,
|
||||
creds2);
|
||||
p2 = sstring.getPrivateCredentials();
|
||||
@ -262,7 +262,7 @@ public class Subset {
|
||||
creds4.add("Exists");
|
||||
Subject scontain1 =
|
||||
new Subject(false, //readOnly
|
||||
Collections.singleton(new SolarisPrincipal("user")),
|
||||
Collections.singleton(new UnixPrincipal("user")),
|
||||
Collections.EMPTY_SET,
|
||||
creds4);
|
||||
Set p3 = scontain1.getPrivateCredentials();
|
||||
@ -462,7 +462,7 @@ public class Subset {
|
||||
creds.add(new Integer(1));
|
||||
Subject s =
|
||||
new Subject(false, //readOnly
|
||||
Collections.singleton(new SolarisPrincipal("user")),
|
||||
Collections.singleton(new UnixPrincipal("user")),
|
||||
Collections.EMPTY_SET,
|
||||
creds);
|
||||
try {
|
||||
|
@ -6,5 +6,5 @@ grant {
|
||||
grant {
|
||||
permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
|
||||
permission javax.security.auth.AuthPermission "modifyPublicCredentials";
|
||||
permission javax.security.auth.PrivateCredentialPermission "java.lang.String com.sun.security.auth.SolarisPrincipal \"user\"", "read";
|
||||
permission javax.security.auth.PrivateCredentialPermission "java.lang.String com.sun.security.auth.UnixPrincipal \"user\"", "read";
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2017, 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 javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import javax.security.auth.login.LoginContext;
|
||||
import com.sun.security.auth.UnixPrincipal;
|
||||
import com.sun.security.auth.UserPrincipal;
|
||||
|
||||
/**
|
||||
* JAAS client which will try to authenticate a user through a custom JAAS LOGIN
|
||||
@ -71,13 +71,13 @@ public class JaasClient {
|
||||
return;
|
||||
}
|
||||
for (Principal p : loginContext.getSubject().getPrincipals()) {
|
||||
if (p instanceof UnixPrincipal
|
||||
if (p instanceof UserPrincipal
|
||||
&& USER_NAME.equals(p.getName())) {
|
||||
//Proper principal was found, return.
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Test failed. UnixPrincipal "
|
||||
throw new RuntimeException("Test failed. UserPrincipal "
|
||||
+ USER_NAME + " expected.");
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,7 @@ package login;
|
||||
import java.security.Principal;
|
||||
import javax.security.auth.login.LoginContext;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import com.sun.security.auth.UnixPrincipal;
|
||||
import com.sun.security.auth.UserPrincipal;
|
||||
|
||||
public class JaasClientWithDefaultHandler {
|
||||
|
||||
@ -61,13 +61,13 @@ public class JaasClientWithDefaultHandler {
|
||||
return;
|
||||
}
|
||||
for (Principal p : loginContext.getSubject().getPrincipals()) {
|
||||
if (p instanceof UnixPrincipal
|
||||
if (p instanceof UserPrincipal
|
||||
&& USER_NAME.equals(p.getName())) {
|
||||
//Proper principal was found, return.
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Test failed. UnixPrincipal "
|
||||
throw new RuntimeException("Test failed. UserPrincipal "
|
||||
+ USER_NAME + " expected.");
|
||||
}
|
||||
|
||||
|
@ -21,280 +21,252 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.util.ArrayList;
|
||||
import jdk.testlibrary.ProcessTools;
|
||||
import jdk.testlibrary.OutputAnalyzer;
|
||||
import jdk.test.lib.compiler.CompilerUtils;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import java.lang.module.ModuleDescriptor.Builder;
|
||||
import jdk.internal.module.ModuleInfoWriter;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
/**
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8078813
|
||||
* @bug 8078813 8183310
|
||||
* @summary Test custom JAAS login module with all possible modular option.
|
||||
* @library /lib/testlibrary /test/lib
|
||||
* @library /java/security/modules
|
||||
* @build jdk.test.lib.compiler.CompilerUtils JarUtils
|
||||
* @summary Test custom JAAS module with all possible modular option. The test
|
||||
* includes different combination of JAAS client/login modules
|
||||
* interaction with or without service description.
|
||||
* @run testng JaasModularClientTest
|
||||
* @modules java.base/jdk.internal.module
|
||||
* @build JarUtils
|
||||
* @build TestLoginModule JaasClient
|
||||
* @run main JaasModularClientTest false
|
||||
* @run main JaasModularClientTest true
|
||||
*/
|
||||
public class JaasModularClientTest extends ModularTest {
|
||||
public class JaasModularClientTest {
|
||||
|
||||
private static final Path S_SRC = SRC.resolve("TestLoginModule.java");
|
||||
private static final String S_PKG = "login";
|
||||
private static final String S_JAR_NAME = S_PKG + JAR_EXTN;
|
||||
private static final String S_DESCR_JAR_NAME = S_PKG + DESCRIPTOR
|
||||
+ JAR_EXTN;
|
||||
private static final String MS_JAR_NAME = MODULAR + S_PKG + JAR_EXTN;
|
||||
private static final String MS_DESCR_JAR_NAME = MODULAR + S_PKG + DESCRIPTOR
|
||||
+ JAR_EXTN;
|
||||
|
||||
private static final Path C_SRC = SRC.resolve("JaasClient.java");
|
||||
private static final String C_PKG = "client";
|
||||
private static final String C_JAR_NAME = C_PKG + JAR_EXTN;
|
||||
private static final String MCN_JAR_NAME = MODULAR + C_PKG + "N" + JAR_EXTN;
|
||||
private static final String MC_JAR_NAME = MODULAR + C_PKG + JAR_EXTN;
|
||||
|
||||
private static final Path BUILD_DIR = Paths.get(".").resolve("build");
|
||||
private static final Path COMPILE_DIR = BUILD_DIR.resolve("bin");
|
||||
private static final Path S_BUILD_DIR = COMPILE_DIR.resolve(S_PKG);
|
||||
private static final Path S_WITH_META_DESCR_BUILD_DIR = COMPILE_DIR.resolve(
|
||||
S_PKG + DESCRIPTOR);
|
||||
private static final Path C_BLD_DIR = COMPILE_DIR.resolve(C_PKG);
|
||||
private static final Path M_BASE_PATH = BUILD_DIR.resolve("mbase");
|
||||
private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts");
|
||||
|
||||
private static final Path S_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(S_PKG);
|
||||
private static final Path S_JAR = S_ARTIFACTS_DIR.resolve(S_JAR_NAME);
|
||||
private static final Path S_WITH_DESCRIPTOR_JAR = S_ARTIFACTS_DIR.resolve(
|
||||
S_DESCR_JAR_NAME);
|
||||
private static final Path MS_JAR = S_ARTIFACTS_DIR.resolve(MS_JAR_NAME);
|
||||
private static final Path MS_WITH_DESCR_JAR = S_ARTIFACTS_DIR.resolve(
|
||||
MS_DESCR_JAR_NAME);
|
||||
|
||||
private static final Path C_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(C_PKG);
|
||||
private static final Path C_JAR = C_ARTIFACTS_DIR.resolve(C_JAR_NAME);
|
||||
private static final Path MC_JAR = C_ARTIFACTS_DIR.resolve(MC_JAR_NAME);
|
||||
private static final Path MCN_JAR = C_ARTIFACTS_DIR.resolve(MCN_JAR_NAME);
|
||||
|
||||
private static final String MAIN = C_PKG + ".JaasClient";
|
||||
private static final String S_INTERFACE
|
||||
= "javax.security.auth.spi.LoginModule";
|
||||
private static final String S_IMPL = S_PKG + ".TestLoginModule";
|
||||
private static final List<String> M_REQUIRED = Arrays.asList("java.base",
|
||||
"jdk.security.auth");
|
||||
private static final Path META_DESCR_PATH = Paths.get("META-INF")
|
||||
.resolve("services").resolve(S_INTERFACE);
|
||||
private static final Path S_META_DESCR_FPATH = S_WITH_META_DESCR_BUILD_DIR
|
||||
.resolve(META_DESCR_PATH);
|
||||
|
||||
private static final boolean WITH_S_DESCR = true;
|
||||
private static final boolean WITHOUT_S_DESCR = false;
|
||||
private static final String NO_FAILURE = null;
|
||||
private static final Path SRC = Paths.get(System.getProperty("test.src"));
|
||||
private static final Path TEST_CLASSES
|
||||
= Paths.get(System.getProperty("test.classes"));
|
||||
private static final Path ARTIFACT_DIR = Paths.get("jars");
|
||||
private static final String PS = File.pathSeparator;
|
||||
private static final String L_TYPE = "login.TestLoginModule";
|
||||
private static final String C_TYPE = "client.JaasClient";
|
||||
|
||||
/**
|
||||
* Generates Test specific input parameters.
|
||||
* Here is the naming convention followed.
|
||||
* l.jar - Unnamed login module jar.
|
||||
* ml.jar - Modular login module jar.
|
||||
* msl.jar - Modular login module jar provides login module service
|
||||
* through module-info
|
||||
* c.jar - Unnamed client jar.
|
||||
* mc.jar - Modular client jar.
|
||||
* mcs.jar - Modular client jar uses login module service through
|
||||
* module-info.
|
||||
* amc.jar - Modular client used for automatic login module jar.
|
||||
* amcs.jar - Modular client used for automatic login module jar and uses
|
||||
* login module service through module-info.
|
||||
*/
|
||||
@Override
|
||||
public Object[][] getTestInput() {
|
||||
private static final Path L_JAR = artifact("l.jar");
|
||||
private static final Path ML_JAR = artifact("ml.jar");
|
||||
private static final Path MSL_JAR = artifact("msl.jar");
|
||||
private static final Path C_JAR = artifact("c.jar");
|
||||
private static final Path MC_JAR = artifact("mc.jar");
|
||||
private static final Path MCS_JAR = artifact("mcs.jar");
|
||||
private static final Path AMC_JAR = artifact("amc.jar");
|
||||
private static final Path AMCS_JAR = artifact("amcs.jar");
|
||||
|
||||
List<List<Object>> params = new ArrayList<>();
|
||||
String[] args = new String[]{};
|
||||
// PARAMETER ORDERS -
|
||||
// Client Module Type, Service Module Type,
|
||||
// If Service META descriptor Required,
|
||||
// Expected Failure message, Client arguments
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
private final String unnL;
|
||||
private final String modL;
|
||||
private final String unnC;
|
||||
private final String modC;
|
||||
private final String autoMC;
|
||||
// Common set of VM arguments used in all test cases
|
||||
private final List<String> commonArgs;
|
||||
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
public JaasModularClientTest(boolean service) {
|
||||
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED,
|
||||
WITH_S_DESCR, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED,
|
||||
WITHOUT_S_DESCR, NO_FAILURE, args));
|
||||
return params.stream().map(p -> p.toArray()).toArray(Object[][]::new);
|
||||
System.out.printf("%n*** Login Module defined as service in "
|
||||
+ "module-info: %s ***%n%n", service);
|
||||
List<String> argList = new LinkedList<>();
|
||||
argList.add("-Djava.security.auth.login.config="
|
||||
+ toAbsPath(SRC.resolve("jaas.conf")));
|
||||
commonArgs = Collections.unmodifiableList(argList);
|
||||
|
||||
// Based on Testcase, select unnamed/modular jar files to use.
|
||||
unnL = toAbsPath(L_JAR);
|
||||
modL = toAbsPath(service ? MSL_JAR : ML_JAR);
|
||||
unnC = toAbsPath(C_JAR);
|
||||
modC = toAbsPath(service ? MCS_JAR : MC_JAR);
|
||||
autoMC = toAbsPath(service ? AMCS_JAR : AMC_JAR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test cases are based on the following logic,
|
||||
* for (definedAs : {"Service in module-info", "Class Type"}) {
|
||||
* for (clientType : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
|
||||
* for (loginModuleType : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
|
||||
* Create and run java command for each possible case
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// Generates unnamed and modular jars.
|
||||
setUp();
|
||||
boolean service = Boolean.valueOf(args[0]);
|
||||
JaasModularClientTest test = new JaasModularClientTest(service);
|
||||
test.process();
|
||||
}
|
||||
|
||||
private void process() throws Exception {
|
||||
|
||||
// Case: NAMED-NAMED, NAMED-AUTOMATIC, NAMED-UNNAMED
|
||||
System.out.println("Case: Modular Client and Modular Login module.");
|
||||
execute(String.format("--module-path %s%s%s -m mc/%s",
|
||||
modC, PS, modL, C_TYPE));
|
||||
System.out.println("Case: Modular Client and automatic Login module.");
|
||||
execute(String.format("--module-path %s%s%s --add-modules=l -m mc/%s",
|
||||
autoMC, PS, unnL, C_TYPE));
|
||||
System.out.println("Case: Modular Client and unnamed Login module.");
|
||||
execute(String.format("--module-path %s -cp %s -m mc/%s", autoMC,
|
||||
unnL, C_TYPE));
|
||||
|
||||
// Case: AUTOMATIC-NAMED, AUTOMATIC-AUTOMATIC, AUTOMATIC-UNNAMED
|
||||
System.out.println("Case: Automatic Client and modular Login module.");
|
||||
execute(String.format("--module-path %s%s%s --add-modules=ml -m c/%s",
|
||||
unnC, PS, modL, C_TYPE));
|
||||
System.out.println("Case: Automatic Client and automatic Login module");
|
||||
execute(String.format("--module-path %s%s%s --add-modules=l -m c/%s",
|
||||
unnC, PS, unnL, C_TYPE));
|
||||
System.out.println("Case: Automatic Client and unnamed Login module.");
|
||||
execute(String.format("--module-path %s -cp %s -m c/%s", unnC,
|
||||
unnL, C_TYPE));
|
||||
|
||||
// Case: UNNAMED-NAMED, UNNAMED-AUTOMATIC, UNNAMED-UNNAMED
|
||||
System.out.println("Case: Unnamed Client and modular Login module.");
|
||||
execute(String.format("-cp %s --module-path %s --add-modules=ml %s",
|
||||
unnC, modL, C_TYPE));
|
||||
System.out.println("Case: Unnamed Client and automatic Login module.");
|
||||
execute(String.format("-cp %s --module-path %s --add-modules=l %s",
|
||||
unnC, unnL, C_TYPE));
|
||||
System.out.println("Case: Unnamed Client and unnamed Login module.");
|
||||
execute(String.format("-cp %s%s%s %s", unnC, PS, unnL, C_TYPE));
|
||||
|
||||
// Case: unnamed jars in --module-path and modular jars in -cp.
|
||||
System.out.println(
|
||||
"Case: Unnamed Client and Login module from modulepath.");
|
||||
execute(String.format("--module-path %s%s%s --add-modules=l -m c/%s",
|
||||
unnC, PS, unnL, C_TYPE));
|
||||
System.out.println(
|
||||
"Case: Modular Client and Login module in classpath.");
|
||||
execute(String.format("-cp %s%s%s %s", modC, PS, modL, C_TYPE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-compile and generate the artifacts required to run this test before
|
||||
* running each test cases.
|
||||
* Execute with command arguments and process the result.
|
||||
*/
|
||||
@BeforeTest
|
||||
public void buildArtifacts() {
|
||||
private void execute(String args) throws Exception {
|
||||
|
||||
boolean done = true;
|
||||
try {
|
||||
done = CompilerUtils.compile(S_SRC, S_BUILD_DIR);
|
||||
done &= CompilerUtils.compile(S_SRC, S_WITH_META_DESCR_BUILD_DIR);
|
||||
done &= createMetaInfServiceDescriptor(S_META_DESCR_FPATH, S_IMPL);
|
||||
// Generate modular/regular jars with(out) META-INF
|
||||
// service descriptor
|
||||
generateJar(true, MODULE_TYPE.EXPLICIT, MS_JAR, S_BUILD_DIR, false);
|
||||
generateJar(true, MODULE_TYPE.EXPLICIT, MS_WITH_DESCR_JAR,
|
||||
S_WITH_META_DESCR_BUILD_DIR, false);
|
||||
generateJar(true, MODULE_TYPE.UNNAMED, S_JAR, S_BUILD_DIR, false);
|
||||
generateJar(true, MODULE_TYPE.UNNAMED, S_WITH_DESCRIPTOR_JAR,
|
||||
S_WITH_META_DESCR_BUILD_DIR, false);
|
||||
// Compile client source codes.
|
||||
done &= CompilerUtils.compile(C_SRC, C_BLD_DIR);
|
||||
// Generate modular client jar with explicit dependency
|
||||
generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BLD_DIR, true);
|
||||
// Generate modular client jar without any dependency
|
||||
generateJar(false, MODULE_TYPE.EXPLICIT, MCN_JAR, C_BLD_DIR, false);
|
||||
// Generate regular client jar
|
||||
generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BLD_DIR, false);
|
||||
System.out.format("%nArtifacts generated successfully? %s", done);
|
||||
if (!done) {
|
||||
throw new RuntimeException("Artifact generation failed");
|
||||
String[] safeArgs = Stream.concat(commonArgs.stream(),
|
||||
Stream.of(args.split("\\s+"))).filter(s -> {
|
||||
if (s.contains(" ")) {
|
||||
throw new RuntimeException("No spaces in args");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate modular/regular jar based on module type for this test.
|
||||
*/
|
||||
private void generateJar(boolean isService, MODULE_TYPE moduleType,
|
||||
Path jar, Path compilePath, boolean depends) throws IOException {
|
||||
|
||||
ModuleDescriptor mDescriptor = null;
|
||||
if (isService) {
|
||||
mDescriptor = generateModuleDescriptor(isService, moduleType, S_PKG,
|
||||
S_PKG, S_INTERFACE, S_IMPL, null, M_REQUIRED, depends);
|
||||
return !s.isEmpty();
|
||||
}).toArray(String[]::new);
|
||||
OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs);
|
||||
// Handle response.
|
||||
if (out.getExitValue() != 0) {
|
||||
System.out.printf("OUTPUT: %s", out.getOutput());
|
||||
throw new RuntimeException("FAIL: Unknown failure occured.");
|
||||
} else {
|
||||
mDescriptor = generateModuleDescriptor(isService, moduleType, C_PKG,
|
||||
C_PKG, S_INTERFACE, null, S_PKG, M_REQUIRED, depends);
|
||||
}
|
||||
generateJar(mDescriptor, jar, compilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds Logic for the test client. This method will get called with each
|
||||
* test parameter.
|
||||
*/
|
||||
@Override
|
||||
public OutputAnalyzer executeTestClient(MODULE_TYPE cModuleType,
|
||||
Path cJarPath, MODULE_TYPE sModuletype, Path sJarPath,
|
||||
String... args) throws Exception {
|
||||
|
||||
OutputAnalyzer output = null;
|
||||
try {
|
||||
// For automated/explicit module types, copy the corresponding
|
||||
// jars to module base folder, which will be considered as
|
||||
// module base path during execution.
|
||||
if (!(cModuleType == MODULE_TYPE.UNNAMED
|
||||
&& sModuletype == MODULE_TYPE.UNNAMED)) {
|
||||
copyJarsToModuleBase(cModuleType, cJarPath, M_BASE_PATH);
|
||||
copyJarsToModuleBase(sModuletype, sJarPath, M_BASE_PATH);
|
||||
}
|
||||
|
||||
System.out.format("%nExecuting java client with required"
|
||||
+ " custom service in class/module path.");
|
||||
String mName = getModuleName(cModuleType, cJarPath, C_PKG);
|
||||
Path cmBasePath = (cModuleType != MODULE_TYPE.UNNAMED
|
||||
|| sModuletype != MODULE_TYPE.UNNAMED) ? M_BASE_PATH : null;
|
||||
String cPath = buildClassPath(cModuleType, cJarPath, sModuletype,
|
||||
sJarPath);
|
||||
Map<String, String> vmArgs = getVMArgs(sModuletype,
|
||||
getModuleName(sModuletype, sJarPath, S_PKG));
|
||||
output = ProcessTools.executeTestJava(
|
||||
getJavaCommand(cmBasePath, cPath, mName, MAIN, vmArgs,
|
||||
args)).outputTo(System.out).errorTo(System.out);
|
||||
} finally {
|
||||
// Clean module path to hold required jars for next run.
|
||||
cleanModuleBasePath(M_BASE_PATH);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide the pre-generated client/service jar path for each test case
|
||||
* based on client/service module type.
|
||||
*/
|
||||
@Override
|
||||
public Path findJarPath(boolean isService, MODULE_TYPE moduleType,
|
||||
boolean addMetaDesc, boolean dependsOnServiceModule) {
|
||||
if (isService) {
|
||||
if (moduleType == MODULE_TYPE.EXPLICIT) {
|
||||
if (addMetaDesc) {
|
||||
return MS_WITH_DESCR_JAR;
|
||||
} else {
|
||||
return MS_JAR;
|
||||
}
|
||||
} else {
|
||||
if (addMetaDesc) {
|
||||
return S_WITH_DESCRIPTOR_JAR;
|
||||
} else {
|
||||
return S_JAR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Choose corresponding client jar using dependent module
|
||||
if (moduleType == MODULE_TYPE.EXPLICIT) {
|
||||
if (dependsOnServiceModule) {
|
||||
return MC_JAR;
|
||||
} else {
|
||||
return MCN_JAR;
|
||||
}
|
||||
} else {
|
||||
return C_JAR;
|
||||
}
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* VM argument required for the test.
|
||||
* Creates Unnamed/modular jar files for TestClient and TestClassLoader.
|
||||
*/
|
||||
private Map<String, String> getVMArgs(MODULE_TYPE sModuletype,
|
||||
String addModName) throws IOException {
|
||||
final Map<String, String> vmArgs = new LinkedHashMap<>();
|
||||
vmArgs.put("-Duser.language=", "en");
|
||||
vmArgs.put("-Duser.region=", "US");
|
||||
vmArgs.put("-Djava.security.auth.login.config=", SRC.resolve(
|
||||
"jaas.conf").toFile().getCanonicalPath());
|
||||
if (addModName != null && sModuletype == MODULE_TYPE.AUTO) {
|
||||
vmArgs.put("--add-modules ", addModName);
|
||||
private static void setUp() throws Exception {
|
||||
|
||||
if (ARTIFACT_DIR.toFile().exists()) {
|
||||
System.out.println("Skipping setup: Artifacts already exists.");
|
||||
return;
|
||||
}
|
||||
return vmArgs;
|
||||
// Generate unnamed login module jar file.
|
||||
JarUtils.createJarFile(L_JAR, TEST_CLASSES,
|
||||
"login/TestLoginModule.class");
|
||||
// Generate unnamed client jar.
|
||||
JarUtils.createJarFile(C_JAR, TEST_CLASSES, "client/JaasClient.class",
|
||||
"client/JaasClient$MyCallbackHandler.class");
|
||||
|
||||
Builder mBuilder = ModuleDescriptor.newModule("ml")
|
||||
.requires("jdk.security.auth");
|
||||
// Modular jar exports package to let the login module type accessible.
|
||||
generateJar(L_JAR, ML_JAR, mBuilder.exports("login").build());
|
||||
|
||||
mBuilder = ModuleDescriptor.newModule("ml")
|
||||
.requires("jdk.security.auth")
|
||||
.provides("javax.security.auth.spi.LoginModule",
|
||||
Arrays.asList(L_TYPE));
|
||||
// Modular login module as Service in module-info does not need to
|
||||
// export service package.
|
||||
generateJar(L_JAR, MSL_JAR, mBuilder.build());
|
||||
|
||||
mBuilder = ModuleDescriptor.newModule("mc").exports("client")
|
||||
.requires("jdk.security.auth");
|
||||
// Generate modular client jar to use automatic login module jar.
|
||||
generateJar(C_JAR, AMC_JAR, mBuilder.build());
|
||||
// Generate modular client jar to use modular login module jar.
|
||||
generateJar(C_JAR, MC_JAR, mBuilder.requires("ml").build());
|
||||
|
||||
mBuilder = ModuleDescriptor.newModule("mc").exports("client")
|
||||
.requires("jdk.security.auth")
|
||||
.uses("javax.security.auth.spi.LoginModule");
|
||||
// Generate modular client jar to use automatic login module service.
|
||||
generateJar(C_JAR, AMCS_JAR, mBuilder.build());
|
||||
// Generate modular client jar using modular login module service.
|
||||
generateJar(C_JAR, MCS_JAR, mBuilder.requires("ml").build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Unnamed jars and include module descriptor files.
|
||||
*/
|
||||
private static void generateJar(Path sjar, Path djar,
|
||||
ModuleDescriptor mDesc) throws Exception {
|
||||
|
||||
Files.copy(sjar, djar, StandardCopyOption.REPLACE_EXISTING);
|
||||
Path dir = Files.createTempDirectory("tmp");
|
||||
if (mDesc != null) {
|
||||
Path mi = dir.resolve("module-info.class");
|
||||
try (OutputStream out = Files.newOutputStream(mi)) {
|
||||
ModuleInfoWriter.write(mDesc, out);
|
||||
}
|
||||
System.out.format("Added 'module-info.class' in '%s'%n", djar);
|
||||
}
|
||||
JarUtils.updateJarFile(djar, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for file path in generated jars.
|
||||
*/
|
||||
private static Path artifact(String file) {
|
||||
return ARTIFACT_DIR.resolve(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to absolute file path.
|
||||
*/
|
||||
private static String toAbsPath(Path path) {
|
||||
return path.toFile().getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
@ -21,236 +21,219 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.util.ArrayList;
|
||||
import jdk.test.lib.compiler.CompilerUtils;
|
||||
import jdk.testlibrary.ProcessTools;
|
||||
import jdk.testlibrary.OutputAnalyzer;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import java.lang.module.ModuleDescriptor.Builder;
|
||||
import jdk.internal.module.ModuleInfoWriter;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
/**
|
||||
/*
|
||||
* @test
|
||||
* @bug 8151654
|
||||
* @bug 8151654 8183310
|
||||
* @summary Test default callback handler with all possible modular option.
|
||||
* @library /lib/testlibrary /test/lib
|
||||
* @library /java/security/modules
|
||||
* @build jdk.test.lib.compiler.CompilerUtils JarUtils
|
||||
* @summary Test custom JAAS callback handler with all possible modular option.
|
||||
* @run testng JaasModularDefaultHandlerTest
|
||||
* @modules java.base/jdk.internal.module
|
||||
* @build JarUtils
|
||||
* @build TestCallbackHandler TestLoginModule JaasClientWithDefaultHandler
|
||||
* @run main JaasModularDefaultHandlerTest
|
||||
*/
|
||||
public class JaasModularDefaultHandlerTest extends ModularTest {
|
||||
public class JaasModularDefaultHandlerTest {
|
||||
|
||||
private static final Path S_SRC = SRC.resolve("TestCallbackHandler.java");
|
||||
private static final String MODULAR = "M";
|
||||
private static final String S_PKG = "handler";
|
||||
private static final String S_JAR_NAME = S_PKG + JAR_EXTN;
|
||||
private static final String MS_JAR_NAME = MODULAR + S_PKG + JAR_EXTN;
|
||||
private static final String HANDLER = S_PKG + ".TestCallbackHandler";
|
||||
|
||||
private static final Path C_SRC
|
||||
= SRC.resolve("JaasClientWithDefaultHandler.java");
|
||||
private static final Path CL_SRC = SRC.resolve("TestLoginModule.java");
|
||||
private static final String C_PKG = "login";
|
||||
private static final String C_JAR_NAME = C_PKG + JAR_EXTN;
|
||||
private static final String MCN_JAR_NAME
|
||||
= MODULAR + C_PKG + "NoMUse" + JAR_EXTN;
|
||||
private static final String MC_JAR_NAME = MODULAR + C_PKG + JAR_EXTN;
|
||||
|
||||
private static final Path BUILD_DIR = Paths.get(".").resolve("build");
|
||||
private static final Path COMPILE_DIR = BUILD_DIR.resolve("bin");
|
||||
private static final Path S_BUILD_DIR = COMPILE_DIR.resolve(S_PKG);
|
||||
private static final Path C_BLD_DIR = COMPILE_DIR.resolve(C_PKG);
|
||||
private static final Path M_BASE_PATH = BUILD_DIR.resolve("mbase");
|
||||
private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts");
|
||||
|
||||
private static final Path S_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(S_PKG);
|
||||
private static final Path S_JAR = S_ARTIFACTS_DIR.resolve(S_JAR_NAME);
|
||||
private static final Path MS_JAR = S_ARTIFACTS_DIR.resolve(MS_JAR_NAME);
|
||||
|
||||
private static final Path C_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(C_PKG);
|
||||
private static final Path C_JAR = C_ARTIFACTS_DIR.resolve(C_JAR_NAME);
|
||||
private static final Path MC_JAR = C_ARTIFACTS_DIR.resolve(MC_JAR_NAME);
|
||||
private static final Path MCN_JAR = C_ARTIFACTS_DIR.resolve(MCN_JAR_NAME);
|
||||
|
||||
private static final String MAIN = C_PKG + ".JaasClientWithDefaultHandler";
|
||||
private static final List<String> M_REQUIRED = Arrays.asList("java.base",
|
||||
"jdk.security.auth");
|
||||
|
||||
private static final String CLASS_NOT_FOUND_MSG
|
||||
= "java.lang.ClassNotFoundException: handler.TestCallbackHandler";
|
||||
private static final String NO_FAILURE = null;
|
||||
private static final Path SRC = Paths.get(System.getProperty("test.src"));
|
||||
private static final Path TEST_CLASSES
|
||||
= Paths.get(System.getProperty("test.classes"));
|
||||
private static final Path ARTIFACT_DIR = Paths.get("jars");
|
||||
private static final String PS = File.pathSeparator;
|
||||
private static final String H_TYPE = "handler.TestCallbackHandler";
|
||||
private static final String C_TYPE = "login.JaasClientWithDefaultHandler";
|
||||
|
||||
/**
|
||||
* Generates Test specific input parameters.
|
||||
* Here is the naming convention followed for each jar.
|
||||
* h.jar - Unnamed handler jar.
|
||||
* mh.jar - Modular handler jar.
|
||||
* c.jar - Unnamed client jar.
|
||||
* mc.jar - Modular client jar.
|
||||
* amc.jar - Modular client used for automatic handler jar.
|
||||
*/
|
||||
@Override
|
||||
public Object[][] getTestInput() {
|
||||
private static final Path H_JAR = artifact("h.jar");
|
||||
private static final Path MH_JAR = artifact("mh.jar");
|
||||
private static final Path C_JAR = artifact("c.jar");
|
||||
private static final Path MC_JAR = artifact("mc.jar");
|
||||
private static final Path AMC_JAR = artifact("amc.jar");
|
||||
|
||||
List<List<Object>> params = new ArrayList<>();
|
||||
String[] args = new String[]{HANDLER};
|
||||
// PARAMETER ORDERS -
|
||||
// Client Module Type, Service Module Type,
|
||||
// Service META Descriptor Required,
|
||||
// Expected Failure message, Client arguments
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT,
|
||||
false, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO,
|
||||
false, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED,
|
||||
false, NO_FAILURE, args));
|
||||
private final String unnH;
|
||||
private final String modH;
|
||||
private final String unnC;
|
||||
private final String modC;
|
||||
private final String autoMC;
|
||||
// Common set of VM arguments used in all test cases
|
||||
private final List<String> commonArgs;
|
||||
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT,
|
||||
false, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO,
|
||||
false, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED,
|
||||
false, NO_FAILURE, args));
|
||||
public JaasModularDefaultHandlerTest() {
|
||||
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT,
|
||||
false, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO,
|
||||
false, NO_FAILURE, args));
|
||||
params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED,
|
||||
false, NO_FAILURE, args));
|
||||
return params.stream().map(p -> p.toArray()).toArray(Object[][]::new);
|
||||
List<String> argList = new LinkedList<>();
|
||||
argList.add("-Djava.security.auth.login.config="
|
||||
+ toAbsPath(SRC.resolve("jaas.conf")));
|
||||
commonArgs = Collections.unmodifiableList(argList);
|
||||
|
||||
// Based on Testcase, select unnamed/modular jar files to use.
|
||||
unnH = toAbsPath(H_JAR);
|
||||
modH = toAbsPath(MH_JAR);
|
||||
unnC = toAbsPath(C_JAR);
|
||||
modC = toAbsPath(MC_JAR);
|
||||
autoMC = toAbsPath(AMC_JAR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test cases are based on the following logic,
|
||||
* for (clientType : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
|
||||
* for (handlerType : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
|
||||
* Create and run java command for each possible case
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// Generates unnamed and modular jars.
|
||||
setUp();
|
||||
JaasModularDefaultHandlerTest jt = new JaasModularDefaultHandlerTest();
|
||||
jt.process();
|
||||
}
|
||||
|
||||
private void process() throws Exception {
|
||||
|
||||
// Case: NAMED-NAMED, NAMED-AUTOMATIC, NAMED-UNNAMED
|
||||
System.out.println("Case: Modular Client and Modular Handler");
|
||||
execute(String.format("--module-path %s%s%s -m mc/%s %s",
|
||||
modC, PS, modH, C_TYPE, H_TYPE));
|
||||
System.out.println("Case: Modular Client and automatic Handler");
|
||||
execute(String.format("--module-path %s%s%s --add-modules=h -m mc/%s %s",
|
||||
autoMC, PS, unnH, C_TYPE, H_TYPE));
|
||||
System.out.println("Case: Modular Client and unnamed Handler");
|
||||
execute(String.format("--module-path %s -cp %s -m mc/%s %s", autoMC,
|
||||
unnH, C_TYPE, H_TYPE));
|
||||
|
||||
// Case: AUTOMATIC-NAMED, AUTOMATIC-AUTOMATIC, AUTOMATIC-UNNAMED
|
||||
System.out.println("Case: Automatic Client and modular Handler");
|
||||
execute(String.format("--module-path %s%s%s --add-modules=mh -m c/%s %s",
|
||||
unnC, PS, modH, C_TYPE, H_TYPE));
|
||||
System.out.println("Case: Automatic Client and automatic Handler");
|
||||
execute(String.format("--module-path %s%s%s --add-modules=h -m c/%s %s",
|
||||
unnC, PS, unnH, C_TYPE, H_TYPE));
|
||||
System.out.println("Case: Automatic Client and unnamed Handler");
|
||||
execute(String.format("--module-path %s -cp %s -m c/%s %s", unnC,
|
||||
unnH, C_TYPE, H_TYPE));
|
||||
|
||||
// Case: UNNAMED-NAMED, UNNAMED-AUTOMATIC, UNNAMED-UNNAMED
|
||||
System.out.println("Case: Unnamed Client and modular Handler");
|
||||
execute(String.format("-cp %s --module-path %s --add-modules=mh %s %s",
|
||||
unnC, modH, C_TYPE, H_TYPE));
|
||||
System.out.println("Case: Unnamed Client and automatic Handler");
|
||||
execute(String.format("-cp %s --module-path %s --add-modules=h %s %s",
|
||||
unnC, unnH, C_TYPE, H_TYPE));
|
||||
System.out.println("Case: Unnamed Client and unnamed Handler");
|
||||
execute(String.format("-cp %s%s%s %s %s", unnC, PS, unnH, C_TYPE,
|
||||
H_TYPE));
|
||||
|
||||
// Case: unnamed jars in --module-path and modular jars in -cp.
|
||||
System.out.println("Case: Unnamed Client and Handler in modulepath");
|
||||
execute(String.format("--module-path %s%s%s --add-modules=h -m c/%s %s",
|
||||
unnC, PS, unnH, C_TYPE, H_TYPE));
|
||||
System.out.println("Case: Modular Client and Provider in classpath");
|
||||
execute(String.format("-cp %s%s%s %s %s",
|
||||
modC, PS, modH, C_TYPE, H_TYPE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-compile and generate the artifacts required to run this test before
|
||||
* running each test cases.
|
||||
* Execute with command arguments and process the result.
|
||||
*/
|
||||
@BeforeTest
|
||||
public void buildArtifacts() {
|
||||
private void execute(String args) throws Exception {
|
||||
|
||||
boolean done = true;
|
||||
try {
|
||||
done = CompilerUtils.compile(S_SRC, S_BUILD_DIR);
|
||||
// Generate modular/regular handler jars.
|
||||
generateJar(true, MODULE_TYPE.EXPLICIT, MS_JAR, S_BUILD_DIR, false);
|
||||
generateJar(true, MODULE_TYPE.UNNAMED, S_JAR, S_BUILD_DIR, false);
|
||||
// Compile client source codes.
|
||||
done &= CompilerUtils.compile(C_SRC, C_BLD_DIR);
|
||||
done &= CompilerUtils.compile(CL_SRC, C_BLD_DIR);
|
||||
// Generate modular client jar with explicit dependency
|
||||
generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BLD_DIR, true);
|
||||
// Generate modular client jar without any dependency
|
||||
generateJar(false, MODULE_TYPE.EXPLICIT, MCN_JAR, C_BLD_DIR, false);
|
||||
// Generate regular client jar
|
||||
generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BLD_DIR, false);
|
||||
System.out.format("%nArtifacts generated successfully? %s", done);
|
||||
if (!done) {
|
||||
throw new RuntimeException("Artifact generation failed");
|
||||
String[] safeArgs = Stream.concat(commonArgs.stream(),
|
||||
Stream.of(args.split("\\s+"))).filter(s -> {
|
||||
if (s.contains(" ")) {
|
||||
throw new RuntimeException("No spaces in args");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate modular/regular jar based on module type for this test.
|
||||
*/
|
||||
private void generateJar(boolean isService, MODULE_TYPE moduleType,
|
||||
Path jar, Path compilePath, boolean depends) throws IOException {
|
||||
|
||||
ModuleDescriptor mDescriptor = null;
|
||||
if (isService) {
|
||||
mDescriptor = generateModuleDescriptor(isService, moduleType, S_PKG,
|
||||
S_PKG, null, null, null, M_REQUIRED, depends);
|
||||
return !s.isEmpty();
|
||||
}).toArray(String[]::new);
|
||||
OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs);
|
||||
// Handle response.
|
||||
if (out.getExitValue() != 0) {
|
||||
System.out.printf("OUTPUT: %s", out.getOutput());
|
||||
throw new RuntimeException("FAIL: Unknown failure occured.");
|
||||
} else {
|
||||
mDescriptor = generateModuleDescriptor(isService, moduleType, C_PKG,
|
||||
C_PKG, null, null, S_PKG, M_REQUIRED, depends);
|
||||
}
|
||||
generateJar(mDescriptor, jar, compilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds Logic for the test client. This method will get called with each
|
||||
* test parameter.
|
||||
*/
|
||||
@Override
|
||||
public OutputAnalyzer executeTestClient(MODULE_TYPE cModuleType,
|
||||
Path cJarPath, MODULE_TYPE sModuletype, Path sJarPath,
|
||||
String... args) throws Exception {
|
||||
|
||||
OutputAnalyzer output = null;
|
||||
try {
|
||||
// For automated/explicit module types, copy the corresponding
|
||||
// jars to module base folder, which will be considered as
|
||||
// module base path during execution.
|
||||
if (!(cModuleType == MODULE_TYPE.UNNAMED
|
||||
&& sModuletype == MODULE_TYPE.UNNAMED)) {
|
||||
copyJarsToModuleBase(cModuleType, cJarPath, M_BASE_PATH);
|
||||
copyJarsToModuleBase(sModuletype, sJarPath, M_BASE_PATH);
|
||||
}
|
||||
|
||||
System.out.format("%nExecuting java client with required"
|
||||
+ " custom service in class/module path.");
|
||||
String mName = getModuleName(cModuleType, cJarPath, C_PKG);
|
||||
Path cmBasePath = (cModuleType != MODULE_TYPE.UNNAMED
|
||||
|| sModuletype != MODULE_TYPE.UNNAMED) ? M_BASE_PATH : null;
|
||||
String cPath = buildClassPath(cModuleType, cJarPath, sModuletype,
|
||||
sJarPath);
|
||||
Map<String, String> vmArgs = getVMArgs(sModuletype, cModuleType,
|
||||
getModuleName(sModuletype, sJarPath, S_PKG));
|
||||
output = ProcessTools.executeTestJava(
|
||||
getJavaCommand(cmBasePath, cPath, mName, MAIN, vmArgs,
|
||||
args)).outputTo(System.out).errorTo(System.out);
|
||||
} finally {
|
||||
// Clean module path to hold required jars for next run.
|
||||
cleanModuleBasePath(M_BASE_PATH);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide the pre-generated client/service jar path for each test case
|
||||
* based on client/service module type.
|
||||
*/
|
||||
@Override
|
||||
public Path findJarPath(boolean depends, MODULE_TYPE moduleType,
|
||||
boolean addMetaDesc, boolean dependsOnServiceModule) {
|
||||
if (depends) {
|
||||
if (moduleType == MODULE_TYPE.EXPLICIT) {
|
||||
return MS_JAR;
|
||||
} else {
|
||||
return S_JAR;
|
||||
}
|
||||
} else {
|
||||
// Choose corresponding client jar using dependent module
|
||||
if (moduleType == MODULE_TYPE.EXPLICIT) {
|
||||
if (dependsOnServiceModule) {
|
||||
return MC_JAR;
|
||||
} else {
|
||||
return MCN_JAR;
|
||||
}
|
||||
} else {
|
||||
return C_JAR;
|
||||
}
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* VM argument required for the test.
|
||||
* Creates Unnamed/modular jar files for TestClient and TestClassLoader.
|
||||
*/
|
||||
private Map<String, String> getVMArgs(MODULE_TYPE sModuletype,
|
||||
MODULE_TYPE cModuleType, String addModName) throws IOException {
|
||||
final Map<String, String> vmArgs = new LinkedHashMap<>();
|
||||
vmArgs.put("-Duser.language=", "en");
|
||||
vmArgs.put("-Duser.region=", "US");
|
||||
vmArgs.put("-Djava.security.auth.login.config=", SRC.resolve(
|
||||
"jaas.conf").toFile().getCanonicalPath());
|
||||
if (addModName != null
|
||||
&& !(cModuleType == MODULE_TYPE.EXPLICIT
|
||||
&& sModuletype == MODULE_TYPE.EXPLICIT)) {
|
||||
vmArgs.put("--add-modules=", addModName);
|
||||
private static void setUp() throws Exception {
|
||||
|
||||
if (ARTIFACT_DIR.toFile().exists()) {
|
||||
System.out.println("Skipping setup: Artifacts already exists.");
|
||||
return;
|
||||
}
|
||||
return vmArgs;
|
||||
// Generate unnamed handler jar file.
|
||||
JarUtils.createJarFile(H_JAR, TEST_CLASSES,
|
||||
"handler/TestCallbackHandler.class");
|
||||
// Generate unnamed client jar file.
|
||||
JarUtils.createJarFile(C_JAR, TEST_CLASSES,
|
||||
"login/TestLoginModule.class",
|
||||
"login/JaasClientWithDefaultHandler.class");
|
||||
|
||||
Builder mBuilder = ModuleDescriptor.newModule("mh");
|
||||
// Modular jar exports package to let the handler type accessible.
|
||||
generateJar(H_JAR, MH_JAR, mBuilder.exports("handler").build());
|
||||
|
||||
mBuilder = ModuleDescriptor.newModule("mc").exports("login")
|
||||
.requires("jdk.security.auth");
|
||||
// Generate modular client jar file to use automatic handler jar.
|
||||
generateJar(C_JAR, AMC_JAR, mBuilder.build());
|
||||
// Generate modular client jar file to use modular handler jar.
|
||||
generateJar(C_JAR, MC_JAR, mBuilder.requires("mh").build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Unnamed jars and include module descriptor files.
|
||||
*/
|
||||
private static void generateJar(Path sjar, Path djar,
|
||||
ModuleDescriptor mDesc) throws Exception {
|
||||
|
||||
Files.copy(sjar, djar, StandardCopyOption.REPLACE_EXISTING);
|
||||
Path dir = Files.createTempDirectory("tmp");
|
||||
if (mDesc != null) {
|
||||
Path mi = dir.resolve("module-info.class");
|
||||
try (OutputStream out = Files.newOutputStream(mi)) {
|
||||
ModuleInfoWriter.write(mDesc, out);
|
||||
}
|
||||
System.out.format("Added 'module-info.class' in '%s'%n", djar);
|
||||
}
|
||||
JarUtils.updateJarFile(djar, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for file path in generated jars.
|
||||
*/
|
||||
private static Path artifact(String file) {
|
||||
return ARTIFACT_DIR.resolve(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to absolute file path.
|
||||
*/
|
||||
private static String toAbsPath(Path path) {
|
||||
return path.toFile().getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
modules java.base/jdk.internal.module
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2017, 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,7 +32,7 @@ import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import javax.security.auth.spi.LoginModule;
|
||||
import com.sun.security.auth.UnixPrincipal;
|
||||
import com.sun.security.auth.UserPrincipal;
|
||||
|
||||
/**
|
||||
* Custom JAAS login module which will be loaded through Java LoginContext when
|
||||
@ -44,7 +44,7 @@ public class TestLoginModule implements LoginModule {
|
||||
private static final String PASSWORD = "testPassword";
|
||||
private Subject subject;
|
||||
private CallbackHandler callbackHandler;
|
||||
private UnixPrincipal userPrincipal;
|
||||
private UserPrincipal userPrincipal;
|
||||
private String username;
|
||||
private String password;
|
||||
private boolean succeeded = false;
|
||||
@ -99,7 +99,7 @@ public class TestLoginModule implements LoginModule {
|
||||
if (succeeded == false) {
|
||||
return false;
|
||||
}
|
||||
userPrincipal = new UnixPrincipal(username);
|
||||
userPrincipal = new UserPrincipal(username);
|
||||
if (!subject.getPrincipals().contains(userPrincipal)) {
|
||||
subject.getPrincipals().add(userPrincipal);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,7 +42,6 @@ import javax.security.auth.x500.X500Principal;
|
||||
import sun.security.provider.PolicyFile;
|
||||
import com.sun.security.auth.UnixPrincipal;
|
||||
import com.sun.security.auth.NTUserPrincipal;
|
||||
import com.sun.security.auth.SolarisPrincipal;
|
||||
|
||||
public class Comparator {
|
||||
|
||||
@ -88,7 +87,7 @@ public class Comparator {
|
||||
new X500Principal("cn=x500") };
|
||||
|
||||
private static final Principal[] badP = new Principal[] {
|
||||
new SolarisPrincipal("bad") };
|
||||
new UnixPrincipal("bad") };
|
||||
|
||||
public static class PCompare1 implements Principal {
|
||||
|
||||
|