feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.util.Comparator;
/** Implements a locale and case insensitive comparator suitable for
strings that are known to only contain ASCII characters. Some
tables internal to the JDK contain only ASCII data and are using
the "generalized" java.lang.String case-insensitive comparator
which converts each character to both upper and lower case. */
public class ASCIICaseInsensitiveComparator implements Comparator<String> {
public static final Comparator<String> CASE_INSENSITIVE_ORDER =
new ASCIICaseInsensitiveComparator();
public int compare(String s1, String s2) {
int n1=s1.length(), n2=s2.length();
int minLen = n1 < n2 ? n1 : n2;
for (int i=0; i < minLen; i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
assert c1 <= '\u007F' && c2 <= '\u007F';
if (c1 != c2) {
c1 = (char)toLower(c1);
c2 = (char)toLower(c2);
if (c1 != c2) {
return c1 - c2;
}
}
}
return n1 - n2;
}
/**
* A case insensitive hash code method to go with the case insensitive
* compare() method.
*
* Returns a hash code for this ASCII string as if it were lower case.
*
* returns same answer as:<p>
* <code>s.toLowerCase(Locale.US).hashCode();</code><p>
* but does not allocate memory (it does NOT have the special
* case Turkish rules).
*
* @param s a String to compute the hashcode on.
* @return a hash code value for this object.
*/
public static int lowerCaseHashCode(String s) {
int h = 0;
int len = s.length();
for (int i = 0; i < len; i++) {
h = 31*h + toLower(s.charAt(i));
}
return h;
}
/* If java.util.regex.ASCII ever becomes public or sun.*, use its code instead:*/
static boolean isLower(int ch) {
return ((ch-'a')|('z'-ch)) >= 0;
}
static boolean isUpper(int ch) {
return ((ch-'A')|('Z'-ch)) >= 0;
}
static int toLower(int ch) {
return isUpper(ch) ? (ch + 0x20) : ch;
}
static int toUpper(int ch) {
return isLower(ch) ? (ch - 0x20) : ch;
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.io.PrintStream;
/**
* This class implements a BASE64 Character decoder as specified in RFC1521.
*
* This RFC is part of the MIME specification which is published by the
* Internet Engineering Task Force (IETF). Unlike some other encoding
* schemes there is nothing in this encoding that tells the decoder
* where a buffer starts or stops, so to use it you will need to isolate
* your encoded data into a single chunk and then feed them this decoder.
* The simplest way to do that is to read all of the encoded data into a
* string and then use:
* <pre>
* byte mydata[];
* BASE64Decoder base64 = new BASE64Decoder();
*
* mydata = base64.decodeBuffer(bufferString);
* </pre>
* This will decode the String in <i>bufferString</i> and give you an array
* of bytes in the array <i>myData</i>.
*
* On errors, this class throws a CEFormatException with the following detail
* strings:
* <pre>
* "BASE64Decoder: Not enough bytes for an atom."
* </pre>
*
* @author Chuck McManis
* @see CharacterEncoder
* @see BASE64Decoder
*/
public class BASE64Decoder extends CharacterDecoder {
/** This class has 4 bytes per atom */
protected int bytesPerAtom() {
return (4);
}
/** Any multiple of 4 will do, 72 might be common */
protected int bytesPerLine() {
return (72);
}
/**
* This character array provides the character to value map
* based on RFC1521.
*/
private final static char pem_array[] = {
// 0 1 2 3 4 5 6 7
'A','B','C','D','E','F','G','H', // 0
'I','J','K','L','M','N','O','P', // 1
'Q','R','S','T','U','V','W','X', // 2
'Y','Z','a','b','c','d','e','f', // 3
'g','h','i','j','k','l','m','n', // 4
'o','p','q','r','s','t','u','v', // 5
'w','x','y','z','0','1','2','3', // 6
'4','5','6','7','8','9','+','/' // 7
};
private final static byte pem_convert_array[] = new byte[256];
static {
for (int i = 0; i < 255; i++) {
pem_convert_array[i] = -1;
}
for (int i = 0; i < pem_array.length; i++) {
pem_convert_array[pem_array[i]] = (byte) i;
}
}
byte decode_buffer[] = new byte[4];
/**
* Decode one BASE64 atom into 1, 2, or 3 bytes of data.
*/
@SuppressWarnings("fallthrough")
protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int rem)
throws java.io.IOException
{
int i;
byte a = -1, b = -1, c = -1, d = -1;
if (rem < 2) {
throw new CEFormatException("BASE64Decoder: Not enough bytes for an atom.");
}
do {
i = inStream.read();
if (i == -1) {
throw new CEStreamExhausted();
}
} while (i == '\n' || i == '\r');
decode_buffer[0] = (byte) i;
i = readFully(inStream, decode_buffer, 1, rem-1);
if (i == -1) {
throw new CEStreamExhausted();
}
if (rem > 3 && decode_buffer[3] == '=') {
rem = 3;
}
if (rem > 2 && decode_buffer[2] == '=') {
rem = 2;
}
switch (rem) {
case 4:
d = pem_convert_array[decode_buffer[3] & 0xff];
// NOBREAK
case 3:
c = pem_convert_array[decode_buffer[2] & 0xff];
// NOBREAK
case 2:
b = pem_convert_array[decode_buffer[1] & 0xff];
a = pem_convert_array[decode_buffer[0] & 0xff];
break;
}
switch (rem) {
case 2:
outStream.write( (byte)(((a << 2) & 0xfc) | ((b >>> 4) & 3)) );
break;
case 3:
outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) );
outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) );
break;
case 4:
outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) );
outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) );
outStream.write( (byte) (((c << 6) & 0xc0) | (d & 0x3f)) );
break;
}
return;
}
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 1995, 1997, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.IOException;
/**
* This class implements a BASE64 Character encoder as specified in RFC1521.
* This RFC is part of the MIME specification as published by the Internet
* Engineering Task Force (IETF). Unlike some other encoding schemes there
* is nothing in this encoding that indicates
* where a buffer starts or ends.
*
* This means that the encoded text will simply start with the first line
* of encoded text and end with the last line of encoded text.
*
* @author Chuck McManis
* @see CharacterEncoder
* @see BASE64Decoder
*/
public class BASE64Encoder extends CharacterEncoder {
/** this class encodes three bytes per atom. */
protected int bytesPerAtom() {
return (3);
}
/**
* this class encodes 57 bytes per line. This results in a maximum
* of 57/3 * 4 or 76 characters per output line. Not counting the
* line termination.
*/
protected int bytesPerLine() {
return (57);
}
/** This array maps the characters to their 6 bit values */
private final static char pem_array[] = {
// 0 1 2 3 4 5 6 7
'A','B','C','D','E','F','G','H', // 0
'I','J','K','L','M','N','O','P', // 1
'Q','R','S','T','U','V','W','X', // 2
'Y','Z','a','b','c','d','e','f', // 3
'g','h','i','j','k','l','m','n', // 4
'o','p','q','r','s','t','u','v', // 5
'w','x','y','z','0','1','2','3', // 6
'4','5','6','7','8','9','+','/' // 7
};
/**
* encodeAtom - Take three bytes of input and encode it as 4
* printable characters. Note that if the length in len is less
* than three is encodes either one or two '=' signs to indicate
* padding characters.
*/
protected void encodeAtom(OutputStream outStream, byte data[], int offset, int len)
throws IOException {
byte a, b, c;
if (len == 1) {
a = data[offset];
b = 0;
c = 0;
outStream.write(pem_array[(a >>> 2) & 0x3F]);
outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
outStream.write('=');
outStream.write('=');
} else if (len == 2) {
a = data[offset];
b = data[offset+1];
c = 0;
outStream.write(pem_array[(a >>> 2) & 0x3F]);
outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]);
outStream.write('=');
} else {
a = data[offset];
b = data[offset+1];
c = data[offset+2];
outStream.write(pem_array[(a >>> 2) & 0x3F]);
outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]);
outStream.write(pem_array[c & 0x3F]);
}
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.IOException;
public class CEFormatException extends IOException {
static final long serialVersionUID = -7139121221067081482L;
public CEFormatException(String s) {
super(s);
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.IOException;
/** This exception is thrown when EOF is reached */
public class CEStreamExhausted extends IOException {
static final long serialVersionUID = -5889118049525891904L;
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* The CRC-16 class calculates a 16 bit cyclic redundancy check of a set
* of bytes. This error detecting code is used to determine if bit rot
* has occurred in a byte stream.
*/
public class CRC16 {
/** value contains the currently computed CRC, set it to 0 initally */
public int value;
public CRC16() {
value = 0;
}
/** update CRC with byte b */
public void update(byte aByte) {
int a, b;
a = (int) aByte;
for (int count = 7; count >=0; count--) {
a = a << 1;
b = (a >>> 8) & 1;
if ((value & 0x8000) != 0) {
value = ((value << 1) + b) ^ 0x1021;
} else {
value = (value << 1) + b;
}
}
value = value & 0xffff;
return;
}
/** reset CRC value to 0 */
public void reset() {
value = 0;
}
}

View File

@@ -0,0 +1,346 @@
/*
* Copyright (c) 1995, 1996, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.NoSuchElementException;
/**
* Caches the collision list.
*/
class CacheEntry extends Ref {
int hash;
Object key;
CacheEntry next;
public Object reconstitute() {
return null;
}
}
/**
* The Cache class. Maps keys to values. Any object can be used as
* a key and/or value. This is very similar to the Hashtable
* class, except that after putting an object into the Cache,
* it is not guaranteed that a subsequent get will return it.
* The Cache will automatically remove entries if memory is
* getting tight and if the entry is not referenced from outside
* the Cache.<p>
*
* To sucessfully store and retrieve objects from a hash table the
* object used as the key must implement the hashCode() and equals()
* methods.<p>
*
* This example creates a Cache of numbers. It uses the names of
* the numbers as keys:
* <pre>
* Cache numbers = new Cache();
* numbers.put("one", new Integer(1));
* numbers.put("two", new Integer(1));
* numbers.put("three", new Integer(1));
* </pre>
* To retrieve a number use:
* <pre>
* Integer n = (Integer)numbers.get("two");
* if (n != null) {
* System.out.println("two = " + n);
* }
* </pre>
*
* @see java.lang.Object#hashCode
* @see java.lang.Object#equals
* @see sun.misc.Ref
*/
public
class Cache extends Dictionary {
/**
* The hash table data.
*/
private CacheEntry table[];
/**
* The total number of entries in the hash table.
*/
private int count;
/**
* Rehashes the table when count exceeds this threshold.
*/
private int threshold;
/**
* The load factor for the hashtable.
*/
private float loadFactor;
private void init(int initialCapacity, float loadFactor) {
if ((initialCapacity <= 0) || (loadFactor <= 0.0)) {
throw new IllegalArgumentException();
}
this.loadFactor = loadFactor;
table = new CacheEntry[initialCapacity];
threshold = (int) (initialCapacity * loadFactor);
}
/**
* Constructs a new, empty Cache with the specified initial
* capacity and the specified load factor.
* @param initialCapacity the initial number of buckets
* @param loadFactor a number between 0.0 and 1.0, it defines
* the threshold for rehashing the Cache into
* a bigger one.
* @exception IllegalArgumentException If the initial capacity
* is less than or equal to zero.
* @exception IllegalArgumentException If the load factor is
* less than or equal to zero.
*/
public Cache (int initialCapacity, float loadFactor) {
init(initialCapacity, loadFactor);
}
/**
* Constructs a new, empty Cache with the specified initial
* capacity.
* @param initialCapacity the initial number of buckets
*/
public Cache (int initialCapacity) {
init(initialCapacity, 0.75f);
}
/**
* Constructs a new, empty Cache. A default capacity and load factor
* is used. Note that the Cache will automatically grow when it gets
* full.
*/
public Cache () {
try {
init(101, 0.75f);
} catch (IllegalArgumentException ex) {
// This should never happen
throw new Error("panic");
}
}
/**
* Returns the number of elements contained within the Cache.
*/
public int size() {
return count;
}
/**
* Returns true if the Cache contains no elements.
*/
public boolean isEmpty() {
return count == 0;
}
/**
* Returns an enumeration of the Cache's keys.
* @see Cache#elements
* @see Enumeration
*/
public synchronized Enumeration keys() {
return new CacheEnumerator(table, true);
}
/**
* Returns an enumeration of the elements. Use the Enumeration methods
* on the returned object to fetch the elements sequentially.
* @see Cache#keys
* @see Enumeration
*/
public synchronized Enumeration elements() {
return new CacheEnumerator(table, false);
}
/**
* Gets the object associated with the specified key in the Cache.
* @param key the key in the hash table
* @returns the element for the key or null if the key
* is not defined in the hash table.
* @see Cache#put
*/
public synchronized Object get(Object key) {
CacheEntry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (CacheEntry e = tab[index]; e != null; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
return e.check();
}
}
return null;
}
/**
* Rehashes the contents of the table into a bigger table.
* This is method is called automatically when the Cache's
* size exceeds the threshold.
*/
protected void rehash() {
int oldCapacity = table.length;
CacheEntry oldTable[] = table;
int newCapacity = oldCapacity * 2 + 1;
CacheEntry newTable[] = new CacheEntry[newCapacity];
threshold = (int) (newCapacity * loadFactor);
table = newTable;
// System.out.println("rehash old=" + oldCapacity + ", new=" +
// newCapacity + ", thresh=" + threshold + ", count=" + count);
for (int i = oldCapacity; i-- > 0;) {
for (CacheEntry old = oldTable[i]; old != null;) {
CacheEntry e = old;
old = old.next;
if (e.check() != null) {
int index = (e.hash & 0x7FFFFFFF) % newCapacity;
e.next = newTable[index];
newTable[index] = e;
} else
count--; /* remove entries that have disappeared */
}
}
}
/**
* Puts the specified element into the Cache, using the specified
* key. The element may be retrieved by doing a get() with the same
* key. The key and the element cannot be null.
* @param key the specified hashtable key
* @param value the specified element
* @return the old value of the key, or null if it did not have one.
* @exception NullPointerException If the value of the specified
* element is null.
* @see Cache#get
*/
public synchronized Object put(Object key, Object value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the cache.
CacheEntry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
CacheEntry ne = null;
for (CacheEntry e = tab[index]; e != null; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
Object old = e.check();
e.setThing(value);
return old;
} else if (e.check() == null)
ne = e; /* reuse old flushed value */
}
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
return put(key, value);
}
// Creates the new entry.
if (ne == null) {
ne = new CacheEntry ();
ne.next = tab[index];
tab[index] = ne;
count++;
}
ne.hash = hash;
ne.key = key;
ne.setThing(value);
return null;
}
/**
* Removes the element corresponding to the key. Does nothing if the
* key is not present.
* @param key the key that needs to be removed
* @return the value of key, or null if the key was not found.
*/
public synchronized Object remove(Object key) {
CacheEntry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (CacheEntry e = tab[index], prev = null; e != null; prev = e, e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
return e.check();
}
}
return null;
}
}
/**
* A Cache enumerator class. This class should remain opaque
* to the client. It will use the Enumeration interface.
*/
class CacheEnumerator implements Enumeration {
boolean keys;
int index;
CacheEntry table[];
CacheEntry entry;
CacheEnumerator (CacheEntry table[], boolean keys) {
this.table = table;
this.keys = keys;
this.index = table.length;
}
public boolean hasMoreElements() {
while (index >= 0) {
while (entry != null)
if (entry.check() != null)
return true;
else
entry = entry.next;
while (--index >= 0 && (entry = table[index]) == null) ;
}
return false;
}
public Object nextElement() {
while (index >= 0) {
if (entry == null)
while (--index >= 0 && (entry = table[index]) == null) ;
if (entry != null) {
CacheEntry e = entry;
entry = e.next;
if (e.check() != null)
return keys ? e.key : e.check();
}
}
throw new NoSuchElementException("CacheEnumerator");
}
}

View File

@@ -0,0 +1,222 @@
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* This class defines the decoding half of character encoders.
* A character decoder is an algorithim for transforming 8 bit
* binary data that has been encoded into text by a character
* encoder, back into original binary form.
*
* The character encoders, in general, have been structured
* around a central theme that binary data can be encoded into
* text that has the form:
*
* <pre>
* [Buffer Prefix]
* [Line Prefix][encoded data atoms][Line Suffix]
* [Buffer Suffix]
* </pre>
*
* Of course in the simplest encoding schemes, the buffer has no
* distinct prefix of suffix, however all have some fixed relationship
* between the text in an 'atom' and the binary data itself.
*
* In the CharacterEncoder and CharacterDecoder classes, one complete
* chunk of data is referred to as a <i>buffer</i>. Encoded buffers
* are all text, and decoded buffers (sometimes just referred to as
* buffers) are binary octets.
*
* To create a custom decoder, you must, at a minimum, overide three
* abstract methods in this class.
* <DL>
* <DD>bytesPerAtom which tells the decoder how many bytes to
* expect from decodeAtom
* <DD>decodeAtom which decodes the bytes sent to it as text.
* <DD>bytesPerLine which tells the encoder the maximum number of
* bytes per line.
* </DL>
*
* In general, the character decoders return error in the form of a
* CEFormatException. The syntax of the detail string is
* <pre>
* DecoderClassName: Error message.
* </pre>
*
* Several useful decoders have already been written and are
* referenced in the See Also list below.
*
* @author Chuck McManis
* @see CEFormatException
* @see CharacterEncoder
* @see UCDecoder
* @see UUDecoder
* @see BASE64Decoder
*/
public abstract class CharacterDecoder {
/** Return the number of bytes per atom of decoding */
abstract protected int bytesPerAtom();
/** Return the maximum number of bytes that can be encoded per line */
abstract protected int bytesPerLine();
/** decode the beginning of the buffer, by default this is a NOP. */
protected void decodeBufferPrefix(PushbackInputStream aStream, OutputStream bStream) throws IOException { }
/** decode the buffer suffix, again by default it is a NOP. */
protected void decodeBufferSuffix(PushbackInputStream aStream, OutputStream bStream) throws IOException { }
/**
* This method should return, if it knows, the number of bytes
* that will be decoded. Many formats such as uuencoding provide
* this information. By default we return the maximum bytes that
* could have been encoded on the line.
*/
protected int decodeLinePrefix(PushbackInputStream aStream, OutputStream bStream) throws IOException {
return (bytesPerLine());
}
/**
* This method post processes the line, if there are error detection
* or correction codes in a line, they are generally processed by
* this method. The simplest version of this method looks for the
* (newline) character.
*/
protected void decodeLineSuffix(PushbackInputStream aStream, OutputStream bStream) throws IOException { }
/**
* This method does an actual decode. It takes the decoded bytes and
* writes them to the OutputStream. The integer <i>l</i> tells the
* method how many bytes are required. This is always <= bytesPerAtom().
*/
protected void decodeAtom(PushbackInputStream aStream, OutputStream bStream, int l) throws IOException {
throw new CEStreamExhausted();
}
/**
* This method works around the bizarre semantics of BufferedInputStream's
* read method.
*/
protected int readFully(InputStream in, byte buffer[], int offset, int len)
throws java.io.IOException {
for (int i = 0; i < len; i++) {
int q = in.read();
if (q == -1)
return ((i == 0) ? -1 : i);
buffer[i+offset] = (byte)q;
}
return len;
}
/**
* Decode the text from the InputStream and write the decoded
* octets to the OutputStream. This method runs until the stream
* is exhausted.
* @exception CEFormatException An error has occurred while decoding
* @exception CEStreamExhausted The input stream is unexpectedly out of data
*/
public void decodeBuffer(InputStream aStream, OutputStream bStream) throws IOException {
int i;
int totalBytes = 0;
PushbackInputStream ps = new PushbackInputStream (aStream);
decodeBufferPrefix(ps, bStream);
while (true) {
int length;
try {
length = decodeLinePrefix(ps, bStream);
for (i = 0; (i+bytesPerAtom()) < length; i += bytesPerAtom()) {
decodeAtom(ps, bStream, bytesPerAtom());
totalBytes += bytesPerAtom();
}
if ((i + bytesPerAtom()) == length) {
decodeAtom(ps, bStream, bytesPerAtom());
totalBytes += bytesPerAtom();
} else {
decodeAtom(ps, bStream, length - i);
totalBytes += (length - i);
}
decodeLineSuffix(ps, bStream);
} catch (CEStreamExhausted e) {
break;
}
}
decodeBufferSuffix(ps, bStream);
}
/**
* Alternate decode interface that takes a String containing the encoded
* buffer and returns a byte array containing the data.
* @exception CEFormatException An error has occurred while decoding
*/
public byte decodeBuffer(String inputString)[] throws IOException {
byte inputBuffer[] = new byte[inputString.length()];
ByteArrayInputStream inStream;
ByteArrayOutputStream outStream;
inputString.getBytes(0, inputString.length(), inputBuffer, 0);
inStream = new ByteArrayInputStream(inputBuffer);
outStream = new ByteArrayOutputStream();
decodeBuffer(inStream, outStream);
return (outStream.toByteArray());
}
/**
* Decode the contents of the inputstream into a buffer.
*/
public byte decodeBuffer(InputStream in)[] throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
decodeBuffer(in, outStream);
return (outStream.toByteArray());
}
/**
* Decode the contents of the String into a ByteBuffer.
*/
public ByteBuffer decodeBufferToByteBuffer(String inputString)
throws IOException {
return ByteBuffer.wrap(decodeBuffer(inputString));
}
/**
* Decode the contents of the inputStream into a ByteBuffer.
*/
public ByteBuffer decodeBufferToByteBuffer(InputStream in)
throws IOException {
return ByteBuffer.wrap(decodeBuffer(in));
}
}

View File

@@ -0,0 +1,354 @@
/*
* Copyright (c) 1995, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* This class defines the encoding half of character encoders.
* A character encoder is an algorithim for transforming 8 bit binary
* data into text (generally 7 bit ASCII or 8 bit ISO-Latin-1 text)
* for transmition over text channels such as e-mail and network news.
*
* The character encoders have been structured around a central theme
* that, in general, the encoded text has the form:
*
* <pre>
* [Buffer Prefix]
* [Line Prefix][encoded data atoms][Line Suffix]
* [Buffer Suffix]
* </pre>
*
* In the CharacterEncoder and CharacterDecoder classes, one complete
* chunk of data is referred to as a <i>buffer</i>. Encoded buffers
* are all text, and decoded buffers (sometimes just referred to as
* buffers) are binary octets.
*
* To create a custom encoder, you must, at a minimum, overide three
* abstract methods in this class.
* <DL>
* <DD>bytesPerAtom which tells the encoder how many bytes to
* send to encodeAtom
* <DD>encodeAtom which encodes the bytes sent to it as text.
* <DD>bytesPerLine which tells the encoder the maximum number of
* bytes per line.
* </DL>
*
* Several useful encoders have already been written and are
* referenced in the See Also list below.
*
* @author Chuck McManis
* @see CharacterDecoder;
* @see UCEncoder
* @see UUEncoder
* @see BASE64Encoder
*/
public abstract class CharacterEncoder {
/** Stream that understands "printing" */
protected PrintStream pStream;
/** Return the number of bytes per atom of encoding */
abstract protected int bytesPerAtom();
/** Return the number of bytes that can be encoded per line */
abstract protected int bytesPerLine();
/**
* Encode the prefix for the entire buffer. By default is simply
* opens the PrintStream for use by the other functions.
*/
protected void encodeBufferPrefix(OutputStream aStream) throws IOException {
pStream = new PrintStream(aStream);
}
/**
* Encode the suffix for the entire buffer.
*/
protected void encodeBufferSuffix(OutputStream aStream) throws IOException {
}
/**
* Encode the prefix that starts every output line.
*/
protected void encodeLinePrefix(OutputStream aStream, int aLength)
throws IOException {
}
/**
* Encode the suffix that ends every output line. By default
* this method just prints a <newline> into the output stream.
*/
protected void encodeLineSuffix(OutputStream aStream) throws IOException {
pStream.println();
}
/** Encode one "atom" of information into characters. */
abstract protected void encodeAtom(OutputStream aStream, byte someBytes[],
int anOffset, int aLength) throws IOException;
/**
* This method works around the bizarre semantics of BufferedInputStream's
* read method.
*/
protected int readFully(InputStream in, byte buffer[])
throws java.io.IOException {
for (int i = 0; i < buffer.length; i++) {
int q = in.read();
if (q == -1)
return i;
buffer[i] = (byte)q;
}
return buffer.length;
}
/**
* Encode bytes from the input stream, and write them as text characters
* to the output stream. This method will run until it exhausts the
* input stream, but does not print the line suffix for a final
* line that is shorter than bytesPerLine().
*/
public void encode(InputStream inStream, OutputStream outStream)
throws IOException {
int j;
int numBytes;
byte tmpbuffer[] = new byte[bytesPerLine()];
encodeBufferPrefix(outStream);
while (true) {
numBytes = readFully(inStream, tmpbuffer);
if (numBytes == 0) {
break;
}
encodeLinePrefix(outStream, numBytes);
for (j = 0; j < numBytes; j += bytesPerAtom()) {
if ((j + bytesPerAtom()) <= numBytes) {
encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
} else {
encodeAtom(outStream, tmpbuffer, j, (numBytes)- j);
}
}
if (numBytes < bytesPerLine()) {
break;
} else {
encodeLineSuffix(outStream);
}
}
encodeBufferSuffix(outStream);
}
/**
* Encode the buffer in <i>aBuffer</i> and write the encoded
* result to the OutputStream <i>aStream</i>.
*/
public void encode(byte aBuffer[], OutputStream aStream)
throws IOException {
ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
encode(inStream, aStream);
}
/**
* A 'streamless' version of encode that simply takes a buffer of
* bytes and returns a string containing the encoded buffer.
*/
public String encode(byte aBuffer[]) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
String retVal = null;
try {
encode(inStream, outStream);
// explicit ascii->unicode conversion
retVal = outStream.toString("8859_1");
} catch (Exception IOException) {
// This should never happen.
throw new Error("CharacterEncoder.encode internal error");
}
return (retVal);
}
/**
* Return a byte array from the remaining bytes in this ByteBuffer.
* <P>
* The ByteBuffer's position will be advanced to ByteBuffer's limit.
* <P>
* To avoid an extra copy, the implementation will attempt to return the
* byte array backing the ByteBuffer. If this is not possible, a
* new byte array will be created.
*/
private byte [] getBytes(ByteBuffer bb) {
/*
* This should never return a BufferOverflowException, as we're
* careful to allocate just the right amount.
*/
byte [] buf = null;
/*
* If it has a usable backing byte buffer, use it. Use only
* if the array exactly represents the current ByteBuffer.
*/
if (bb.hasArray()) {
byte [] tmp = bb.array();
if ((tmp.length == bb.capacity()) &&
(tmp.length == bb.remaining())) {
buf = tmp;
bb.position(bb.limit());
}
}
if (buf == null) {
/*
* This class doesn't have a concept of encode(buf, len, off),
* so if we have a partial buffer, we must reallocate
* space.
*/
buf = new byte[bb.remaining()];
/*
* position() automatically updated
*/
bb.get(buf);
}
return buf;
}
/**
* Encode the <i>aBuffer</i> ByteBuffer and write the encoded
* result to the OutputStream <i>aStream</i>.
* <P>
* The ByteBuffer's position will be advanced to ByteBuffer's limit.
*/
public void encode(ByteBuffer aBuffer, OutputStream aStream)
throws IOException {
byte [] buf = getBytes(aBuffer);
encode(buf, aStream);
}
/**
* A 'streamless' version of encode that simply takes a ByteBuffer
* and returns a string containing the encoded buffer.
* <P>
* The ByteBuffer's position will be advanced to ByteBuffer's limit.
*/
public String encode(ByteBuffer aBuffer) {
byte [] buf = getBytes(aBuffer);
return encode(buf);
}
/**
* Encode bytes from the input stream, and write them as text characters
* to the output stream. This method will run until it exhausts the
* input stream. It differs from encode in that it will add the
* line at the end of a final line that is shorter than bytesPerLine().
*/
public void encodeBuffer(InputStream inStream, OutputStream outStream)
throws IOException {
int j;
int numBytes;
byte tmpbuffer[] = new byte[bytesPerLine()];
encodeBufferPrefix(outStream);
while (true) {
numBytes = readFully(inStream, tmpbuffer);
if (numBytes == 0) {
break;
}
encodeLinePrefix(outStream, numBytes);
for (j = 0; j < numBytes; j += bytesPerAtom()) {
if ((j + bytesPerAtom()) <= numBytes) {
encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
} else {
encodeAtom(outStream, tmpbuffer, j, (numBytes)- j);
}
}
encodeLineSuffix(outStream);
if (numBytes < bytesPerLine()) {
break;
}
}
encodeBufferSuffix(outStream);
}
/**
* Encode the buffer in <i>aBuffer</i> and write the encoded
* result to the OutputStream <i>aStream</i>.
*/
public void encodeBuffer(byte aBuffer[], OutputStream aStream)
throws IOException {
ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
encodeBuffer(inStream, aStream);
}
/**
* A 'streamless' version of encode that simply takes a buffer of
* bytes and returns a string containing the encoded buffer.
*/
public String encodeBuffer(byte aBuffer[]) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
try {
encodeBuffer(inStream, outStream);
} catch (Exception IOException) {
// This should never happen.
throw new Error("CharacterEncoder.encodeBuffer internal error");
}
return (outStream.toString());
}
/**
* Encode the <i>aBuffer</i> ByteBuffer and write the encoded
* result to the OutputStream <i>aStream</i>.
* <P>
* The ByteBuffer's position will be advanced to ByteBuffer's limit.
*/
public void encodeBuffer(ByteBuffer aBuffer, OutputStream aStream)
throws IOException {
byte [] buf = getBytes(aBuffer);
encodeBuffer(buf, aStream);
}
/**
* A 'streamless' version of encode that simply takes a ByteBuffer
* and returns a string containing the encoded buffer.
* <P>
* The ByteBuffer's position will be advanced to ByteBuffer's limit.
*/
public String encodeBuffer(ByteBuffer aBuffer) {
byte [] buf = getBytes(aBuffer);
return encodeBuffer(buf);
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.util.ArrayList;
import java.util.List;
/**
* This is an abstract base class originally intended to be called by
* {@code java.lang.ClassLoader} when {@code ClassFormatError} is
* thrown inside {@code defineClass()}. It is no longer hooked into
* {@code ClassLoader} and will be removed in a future release.
*
* @author Stanley Man-Kit Ho
*/
@Deprecated
public abstract class ClassFileTransformer {
private static final List<ClassFileTransformer> transformers
= new ArrayList<ClassFileTransformer>();
/**
* Add the class file transformer object.
*
* @param t Class file transformer instance
*/
public static void add(ClassFileTransformer t) {
synchronized (transformers) {
transformers.add(t);
}
}
/**
* Get the array of ClassFileTransformer object.
*
* @return ClassFileTransformer object array
*/
public static ClassFileTransformer[] getTransformers() {
synchronized (transformers) {
ClassFileTransformer[] result = new ClassFileTransformer[transformers.size()];
return transformers.toArray(result);
}
}
/**
* Transform a byte array from one to the other.
*
* @param b Byte array
* @param off Offset
* @param len Length of byte array
* @return Transformed byte array
*/
public abstract byte[] transform(byte[] b, int off, int len)
throws ClassFormatError;
}

View File

@@ -0,0 +1,172 @@
/*
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* Provides utility functions related to URLClassLoaders or subclasses of it.
*
* W A R N I N G
*
* This class uses undocumented, unpublished, private data structures inside
* java.net.URLClassLoader and sun.misc.URLClassPath. Use with extreme caution.
*
* @author tjquinn
*/
import java.io.IOException;
import java.net.URLClassLoader;
import java.util.*;
import java.util.jar.JarFile;
public class ClassLoaderUtil {
/**
* Releases resources held by a URLClassLoader. A new classloader must
* be created before the underlying resources can be accessed again.
* @param classLoader the instance of URLClassLoader (or a subclass)
*/
public static void releaseLoader(URLClassLoader classLoader) {
releaseLoader(classLoader, null);
}
/**
* Releases resources held by a URLClassLoader. Notably, close the jars
* opened by the loader. Initializes and updates the List of
* jars that have been successfully closed.
* <p>
* @param classLoader the instance of URLClassLoader (or a subclass)
* @param jarsClosed a List of Strings that will contain the names of jars
* successfully closed; can be null if the caller does not need the information returned
* @return a List of IOExceptions reporting jars that failed to close; null
* indicates that an error other than an IOException occurred attempting to
* release the loader; empty indicates a successful release; non-empty
* indicates at least one error attempting to close an open jar.
*/
public static List<IOException> releaseLoader(URLClassLoader classLoader, List<String> jarsClosed) {
List<IOException> ioExceptions = new LinkedList<IOException>();
try {
/* Records all IOExceptions thrown while closing jar files. */
if (jarsClosed != null) {
jarsClosed.clear();
}
URLClassPath ucp = SharedSecrets.getJavaNetAccess()
.getURLClassPath(classLoader);
ArrayList<?> loaders = ucp.loaders;
Stack<?> urls = ucp.urls;
HashMap<?,?> lmap = ucp.lmap;
/*
*The urls variable in the URLClassPath object holds URLs that have not yet
*been used to resolve a resource or load a class and, therefore, do
*not yet have a loader associated with them. Clear the stack so any
*future requests that might incorrectly reach the loader cannot be
*resolved and cannot open a jar file after we think we've closed
*them all.
*/
synchronized(urls) {
urls.clear();
}
/*
*Also clear the map of URLs to loaders so the class loader cannot use
*previously-opened jar files - they are about to be closed.
*/
synchronized(lmap) {
lmap.clear();
}
/*
*The URLClassPath object's path variable records the list of all URLs that are on
*the URLClassPath's class path. Leave that unchanged. This might
*help someone trying to debug why a released class loader is still used.
*Because the stack and lmap are now clear, code that incorrectly uses a
*the released class loader will trigger an exception if the
*class or resource would have been resolved by the class
*loader (and no other) if it had not been released.
*
*The list of URLs might provide some hints to the person as to where
*in the code the class loader was set up, which might in turn suggest
*where in the code the class loader needs to stop being used.
*The URLClassPath does not use the path variable to open new jar
*files - it uses the urls Stack for that - so leaving the path variable
*will not by itself allow the class loader to continue handling requests.
*/
/*
*For each loader, close the jar file associated with that loader.
*
*The URLClassPath's use of loaders is sync-ed on the entire URLClassPath
*object.
*/
synchronized (ucp) {
for (Object o : loaders) {
if (o != null) {
/*
*If the loader is a JarLoader inner class and its jarFile
*field is non-null then try to close that jar file. Add
*it to the list of closed files if successful.
*/
if (o instanceof URLClassPath.JarLoader) {
URLClassPath.JarLoader jl = (URLClassPath.JarLoader)o;
JarFile jarFile = jl.getJarFile();
try {
if (jarFile != null) {
jarFile.close();
if (jarsClosed != null) {
jarsClosed.add(jarFile.getName());
}
}
} catch (IOException ioe) {
/*
*Wrap the IOException to identify which jar
*could not be closed and add it to the list
*of IOExceptions to be returned to the caller.
*/
String jarFileName = (jarFile == null) ? "filename not available":jarFile.getName();
String msg = "Error closing JAR file: " + jarFileName;
IOException newIOE = new IOException(msg);
newIOE.initCause(ioe);
ioExceptions.add(newIOE);
}
}
}
}
/*
*Now clear the loaders ArrayList.
*/
loaders.clear();
}
} catch (Throwable t) {
throw new RuntimeException (t);
}
return ioExceptions;
}
}

View File

@@ -0,0 +1,156 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.lang.ref.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* General-purpose phantom-reference-based cleaners.
*
* <p> Cleaners are a lightweight and more robust alternative to finalization.
* They are lightweight because they are not created by the VM and thus do not
* require a JNI upcall to be created, and because their cleanup code is
* invoked directly by the reference-handler thread rather than by the
* finalizer thread. They are more robust because they use phantom references,
* the weakest type of reference object, thereby avoiding the nasty ordering
* problems inherent to finalization.
*
* <p> A cleaner tracks a referent object and encapsulates a thunk of arbitrary
* cleanup code. Some time after the GC detects that a cleaner's referent has
* become phantom-reachable, the reference-handler thread will run the cleaner.
* Cleaners may also be invoked directly; they are thread safe and ensure that
* they run their thunks at most once.
*
* <p> Cleaners are not a replacement for finalization. They should be used
* only when the cleanup code is extremely simple and straightforward.
* Nontrivial cleaners are inadvisable since they risk blocking the
* reference-handler thread and delaying further cleanup and finalization.
*
*
* @author Mark Reinhold
*/
public class Cleaner
extends PhantomReference<Object>
{
// Dummy reference queue, needed because the PhantomReference constructor
// insists that we pass a queue. Nothing will ever be placed on this queue
// since the reference handler invokes cleaners explicitly.
//
private static final ReferenceQueue<Object> dummyQueue = new ReferenceQueue<>();
// Doubly-linked list of live cleaners, which prevents the cleaners
// themselves from being GC'd before their referents
//
static private Cleaner first = null;
private Cleaner
next = null,
prev = null;
private static synchronized Cleaner add(Cleaner cl) {
if (first != null) {
cl.next = first;
first.prev = cl;
}
first = cl;
return cl;
}
private static synchronized boolean remove(Cleaner cl) {
// If already removed, do nothing
if (cl.next == cl)
return false;
// Update list
if (first == cl) {
if (cl.next != null)
first = cl.next;
else
first = cl.prev;
}
if (cl.next != null)
cl.next.prev = cl.prev;
if (cl.prev != null)
cl.prev.next = cl.next;
// Indicate removal by pointing the cleaner to itself
cl.next = cl;
cl.prev = cl;
return true;
}
private final Runnable thunk;
private Cleaner(Object referent, Runnable thunk) {
super(referent, dummyQueue);
this.thunk = thunk;
}
/**
* Creates a new cleaner.
*
* @param ob the referent object to be cleaned
* @param thunk
* The cleanup code to be run when the cleaner is invoked. The
* cleanup code is run directly from the reference-handler thread,
* so it should be as simple and straightforward as possible.
*
* @return The new cleaner
*/
public static Cleaner create(Object ob, Runnable thunk) {
if (thunk == null)
return null;
return add(new Cleaner(ob, thunk));
}
/**
* Runs this cleaner, if it has not been run before.
*/
public void clean() {
if (!remove(this))
return;
try {
thunk.run();
} catch (final Throwable x) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
if (System.err != null)
new Error("Cleaner terminated abnormally", x)
.printStackTrace();
System.exit(1);
return null;
}});
}
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.util.Enumeration;
import java.util.NoSuchElementException;
/*
* A useful utility class that will enumerate over an array of
* enumerations.
*/
public class CompoundEnumeration<E> implements Enumeration<E> {
private Enumeration<E>[] enums;
private int index = 0;
public CompoundEnumeration(Enumeration<E>[] enums) {
this.enums = enums;
}
private boolean next() {
while (index < enums.length) {
if (enums[index] != null && enums[index].hasMoreElements()) {
return true;
}
index++;
}
return false;
}
public boolean hasMoreElements() {
return next();
}
public E nextElement() {
if (!next()) {
throw new NoSuchElementException();
}
return enums[index].nextElement();
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) 1994, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* ConditionLock is a Lock with a built in state variable. This class
* provides the ability to wait for the state variable to be set to a
* desired value and then acquire the lock.<p>
*
* The lockWhen() and unlockWith() methods can be safely intermixed
* with the lock() and unlock() methods. However if there is a thread
* waiting for the state variable to become a particular value and you
* simply call Unlock(), that thread will not be able to acquire the
* lock until the state variable equals its desired value. <p>
*
* @author Peter King
*/
public final
class ConditionLock extends Lock {
private int state = 0;
/**
* Creates a ConditionLock.
*/
public ConditionLock () {
}
/**
* Creates a ConditionLock in an initialState.
*/
public ConditionLock (int initialState) {
state = initialState;
}
/**
* Acquires the lock when the state variable equals the desired state.
*
* @param desiredState the desired state
* @exception java.lang.InterruptedException if any thread has
* interrupted this thread.
*/
public synchronized void lockWhen(int desiredState)
throws InterruptedException
{
while (state != desiredState) {
wait();
}
lock();
}
/**
* Releases the lock, and sets the state to a new value.
* @param newState the new state
*/
public synchronized void unlockWith(int newState) {
state = newState;
unlock();
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>An annotation expressing that objects and/or their fields are
* expected to encounter memory contention, generally in the form of
* "false sharing". This annotation serves as a hint that such objects
* and fields should reside in locations isolated from those of other
* objects or fields. Susceptibility to memory contention is a
* property of the intended usages of objects and fields, not their
* types or qualifiers. The effects of this annotation will nearly
* always add significant space overhead to objects. The use of
* {@code @Contended} is warranted only when the performance impact of
* this time/space tradeoff is intrinsically worthwhile; for example,
* in concurrent contexts in which each instance of the annotated
* class is often accessed by a different thread.
*
* <p>A {@code @Contended} field annotation may optionally include a
* <i>contention group</i> tag. A contention group defines a set of one
* or more fields that collectively must be isolated from all other
* contention groups. The fields in the same contention group may not be
* pairwise isolated. With no contention group tag (or with the default
* empty tag: "") each {@code @Contended} field resides in its own
* <i>distinct</i> and <i>anonymous</i> contention group.
*
* <p>When the annotation is used at the class level, the effect is
* equivalent to grouping all the declared fields not already having the
* {@code @Contended} annotation into the same anonymous group.
* With the class level annotation, implementations may choose different
* isolation techniques, such as isolating the entire object, rather than
* isolating distinct fields. A contention group tag has no meaning
* in a class level {@code @Contended} annotation, and is ignored.
*
* <p>The class level {@code @Contended} annotation is not inherited and has
* no effect on the fields declared in any sub-classes. The effects of all
* {@code @Contended} annotations, however, remain in force for all
* subclass instances, providing isolation of all the defined contention
* groups. Contention group tags are not inherited, and the same tag used
* in a superclass and subclass, represent distinct contention groups.
*
* @since 1.8
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface Contended {
/**
* The (optional) contention group tag.
* This tag is only meaningful for field level annotations.
*
* @return contention group tag.
*/
String value() default "";
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* This class contains additional constants documenting limits of the
* <code>double</code> type.
*
* @author Joseph D. Darcy
*/
public class DoubleConsts {
/**
* Don't let anyone instantiate this class.
*/
private DoubleConsts() {}
public static final double POSITIVE_INFINITY = java.lang.Double.POSITIVE_INFINITY;
public static final double NEGATIVE_INFINITY = java.lang.Double.NEGATIVE_INFINITY;
public static final double NaN = java.lang.Double.NaN;
public static final double MAX_VALUE = java.lang.Double.MAX_VALUE;
public static final double MIN_VALUE = java.lang.Double.MIN_VALUE;
/**
* A constant holding the smallest positive normal value of type
* <code>double</code>, 2<sup>-1022</sup>. It is equal to the
* value returned by
* <code>Double.longBitsToDouble(0x0010000000000000L)</code>.
*
* @since 1.5
*/
public static final double MIN_NORMAL = 2.2250738585072014E-308;
/**
* The number of logical bits in the significand of a
* <code>double</code> number, including the implicit bit.
*/
public static final int SIGNIFICAND_WIDTH = 53;
/**
* Maximum exponent a finite <code>double</code> number may have.
* It is equal to the value returned by
* <code>Math.ilogb(Double.MAX_VALUE)</code>.
*/
public static final int MAX_EXPONENT = 1023;
/**
* Minimum exponent a normalized <code>double</code> number may
* have. It is equal to the value returned by
* <code>Math.ilogb(Double.MIN_NORMAL)</code>.
*/
public static final int MIN_EXPONENT = -1022;
/**
* The exponent the smallest positive <code>double</code>
* subnormal value would have if it could be normalized. It is
* equal to the value returned by
* <code>FpUtils.ilogb(Double.MIN_VALUE)</code>.
*/
public static final int MIN_SUB_EXPONENT = MIN_EXPONENT -
(SIGNIFICAND_WIDTH - 1);
/**
* Bias used in representing a <code>double</code> exponent.
*/
public static final int EXP_BIAS = 1023;
/**
* Bit mask to isolate the sign bit of a <code>double</code>.
*/
public static final long SIGN_BIT_MASK = 0x8000000000000000L;
/**
* Bit mask to isolate the exponent field of a
* <code>double</code>.
*/
public static final long EXP_BIT_MASK = 0x7FF0000000000000L;
/**
* Bit mask to isolate the significand field of a
* <code>double</code>.
*/
public static final long SIGNIF_BIT_MASK = 0x000FFFFFFFFFFFFFL;
static {
// verify bit masks cover all bit positions and that the bit
// masks are non-overlapping
assert(((SIGN_BIT_MASK | EXP_BIT_MASK | SIGNIF_BIT_MASK) == ~0L) &&
(((SIGN_BIT_MASK & EXP_BIT_MASK) == 0L) &&
((SIGN_BIT_MASK & SIGNIF_BIT_MASK) == 0L) &&
((EXP_BIT_MASK & SIGNIF_BIT_MASK) == 0L)));
}
}

View File

@@ -0,0 +1,570 @@
/*
* 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 sun.misc;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.Enumeration;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.jar.Attributes;
import java.util.jar.Attributes.Name;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import java.net.URL;
import java.net.MalformedURLException;
import sun.net.www.ParseUtil;
/**
* <p>
* This class checks dependent extensions a particular jar file may have
* declared through its manifest attributes.
* </p>
* Jar file declared dependent extensions through the extension-list
* attribute. The extension-list contains a list of keys used to
* fetch the other attributes describing the required extension.
* If key is the extension key declared in the extension-list
* attribute, the following describing attribute can be found in
* the manifest :
* key-Extension-Name: (Specification package name)
* key-Specification-Version: (Specification-Version)
* key-Implementation-Version: (Implementation-Version)
* key-Implementation-Vendor-Id: (Imlementation-Vendor-Id)
* key-Implementation-Version: (Implementation version)
* key-Implementation-URL: (URL to download the requested extension)
* <p>
* This class also maintain versioning consistency of installed
* extensions dependencies declared in jar file manifest.
* </p>
* @author Jerome Dochez
*/
public class ExtensionDependency {
/* Callbak interfaces to delegate installation of missing extensions */
private static Vector<ExtensionInstallationProvider> providers;
/**
* <p>
* Register an ExtensionInstallationProvider. The provider is responsible
* for handling the installation (upgrade) of any missing extensions.
* </p>
* @param eip ExtensionInstallationProvider implementation
*/
public synchronized static void addExtensionInstallationProvider
(ExtensionInstallationProvider eip)
{
if (providers == null) {
providers = new Vector<>();
}
providers.add(eip);
}
/**
* <p>
* Unregister a previously installed installation provider
* </p>
*/
public synchronized static void removeExtensionInstallationProvider
(ExtensionInstallationProvider eip)
{
providers.remove(eip);
}
/**
* <p>
* Checks the dependencies of the jar file on installed extension.
* </p>
* @param jarFile containing the attriutes declaring the dependencies
*/
public static boolean checkExtensionsDependencies(JarFile jar)
{
if (providers == null) {
// no need to bother, nobody is registered to install missing
// extensions
return true;
}
try {
ExtensionDependency extDep = new ExtensionDependency();
return extDep.checkExtensions(jar);
} catch (ExtensionInstallationException e) {
debug(e.getMessage());
}
return false;
}
/*
* Check for all declared required extensions in the jar file
* manifest.
*/
protected boolean checkExtensions(JarFile jar)
throws ExtensionInstallationException
{
Manifest man;
try {
man = jar.getManifest();
} catch (IOException e) {
return false;
}
if (man == null) {
// The applet does not define a manifest file, so
// we just assume all dependencies are satisfied.
return true;
}
boolean result = true;
Attributes attr = man.getMainAttributes();
if (attr != null) {
// Let's get the list of declared dependencies
String value = attr.getValue(Name.EXTENSION_LIST);
if (value != null) {
StringTokenizer st = new StringTokenizer(value);
// Iterate over all declared dependencies
while (st.hasMoreTokens()) {
String extensionName = st.nextToken();
debug("The file " + jar.getName() +
" appears to depend on " + extensionName);
// Sanity Check
String extName = extensionName + "-" +
Name.EXTENSION_NAME.toString();
if (attr.getValue(extName) == null) {
debug("The jar file " + jar.getName() +
" appers to depend on "
+ extensionName + " but does not define the " +
extName + " attribute in its manifest ");
} else {
if (!checkExtension(extensionName, attr)) {
debug("Failed installing " + extensionName);
result = false;
}
}
}
} else {
debug("No dependencies for " + jar.getName());
}
}
return result;
}
/*
* <p>
* Check that a particular dependency on an extension is satisfied.
* </p>
* @param extensionName is the key used for the attributes in the manifest
* @param attr is the attributes of the manifest file
*
* @return true if the dependency is satisfied by the installed extensions
*/
protected synchronized boolean checkExtension(final String extensionName,
final Attributes attr)
throws ExtensionInstallationException
{
debug("Checking extension " + extensionName);
if (checkExtensionAgainstInstalled(extensionName, attr))
return true;
debug("Extension not currently installed ");
ExtensionInfo reqInfo = new ExtensionInfo(extensionName, attr);
return installExtension(reqInfo, null);
}
/*
* <p>
* Check if a particular extension is part of the currently installed
* extensions.
* </p>
* @param extensionName is the key for the attributes in the manifest
* @param attr is the attributes of the manifest
*
* @return true if the requested extension is already installed
*/
boolean checkExtensionAgainstInstalled(String extensionName,
Attributes attr)
throws ExtensionInstallationException
{
File fExtension = checkExtensionExists(extensionName);
if (fExtension != null) {
// Extension already installed, just check against this one
try {
if (checkExtensionAgainst(extensionName, attr, fExtension))
return true;
} catch (FileNotFoundException e) {
debugException(e);
} catch (IOException e) {
debugException(e);
}
return false;
} else {
// Not sure if extension is already installed, so check all the
// installed extension jar files to see if we get a match
File[] installedExts;
try {
// Get the list of installed extension jar files so we can
// compare the installed versus the requested extension
installedExts = getInstalledExtensions();
} catch(IOException e) {
debugException(e);
return false;
}
for (int i=0;i<installedExts.length;i++) {
try {
if (checkExtensionAgainst(extensionName, attr, installedExts[i]))
return true;
} catch (FileNotFoundException e) {
debugException(e);
} catch (IOException e) {
debugException(e);
// let's continue with the next installed extension
}
}
}
return false;
}
/*
* <p>
* Check if the requested extension described by the attributes
* in the manifest under the key extensionName is compatible with
* the jar file.
* </p>
*
* @param extensionName key in the attribute list
* @param attr manifest file attributes
* @param file installed extension jar file to compare the requested
* extension against.
*/
protected boolean checkExtensionAgainst(String extensionName,
Attributes attr,
final File file)
throws IOException,
FileNotFoundException,
ExtensionInstallationException
{
debug("Checking extension " + extensionName +
" against " + file.getName());
// Load the jar file ...
Manifest man;
try {
man = AccessController.doPrivileged(
new PrivilegedExceptionAction<Manifest>() {
public Manifest run()
throws IOException, FileNotFoundException {
if (!file.exists())
throw new FileNotFoundException(file.getName());
JarFile jarFile = new JarFile(file);
return jarFile.getManifest();
}
});
} catch(PrivilegedActionException e) {
if (e.getException() instanceof FileNotFoundException)
throw (FileNotFoundException) e.getException();
throw (IOException) e.getException();
}
// Construct the extension information object
ExtensionInfo reqInfo = new ExtensionInfo(extensionName, attr);
debug("Requested Extension : " + reqInfo);
int isCompatible = ExtensionInfo.INCOMPATIBLE;
ExtensionInfo instInfo = null;
if (man != null) {
Attributes instAttr = man.getMainAttributes();
if (instAttr != null) {
instInfo = new ExtensionInfo(null, instAttr);
debug("Extension Installed " + instInfo);
isCompatible = instInfo.isCompatibleWith(reqInfo);
switch(isCompatible) {
case ExtensionInfo.COMPATIBLE:
debug("Extensions are compatible");
return true;
case ExtensionInfo.INCOMPATIBLE:
debug("Extensions are incompatible");
return false;
default:
// everything else
debug("Extensions require an upgrade or vendor switch");
return installExtension(reqInfo, instInfo);
}
}
}
return false;
}
/*
* <p>
* An required extension is missing, if an ExtensionInstallationProvider is
* registered, delegate the installation of that particular extension to it.
* </p>
*
* @param reqInfo Missing extension information
* @param instInfo Older installed version information
*
* @return true if the installation is successful
*/
protected boolean installExtension(ExtensionInfo reqInfo,
ExtensionInfo instInfo)
throws ExtensionInstallationException
{
Vector<ExtensionInstallationProvider> currentProviders;
synchronized(providers) {
@SuppressWarnings("unchecked")
Vector<ExtensionInstallationProvider> tmp =
(Vector<ExtensionInstallationProvider>) providers.clone();
currentProviders = tmp;
}
for (Enumeration<ExtensionInstallationProvider> e = currentProviders.elements();
e.hasMoreElements();) {
ExtensionInstallationProvider eip = e.nextElement();
if (eip!=null) {
// delegate the installation to the provider
if (eip.installExtension(reqInfo, instInfo)) {
debug(reqInfo.name + " installation successful");
Launcher.ExtClassLoader cl = (Launcher.ExtClassLoader)
Launcher.getLauncher().getClassLoader().getParent();
addNewExtensionsToClassLoader(cl);
return true;
}
}
}
// We have tried all of our providers, noone could install this
// extension, we just return failure at this point
debug(reqInfo.name + " installation failed");
return false;
}
/**
* <p>
* Checks if the extension, that is specified in the extension-list in
* the applet jar manifest, is already installed (i.e. exists in the
* extension directory).
* </p>
*
* @param extensionName extension name in the extension-list
*
* @return the extension if it exists in the extension directory
*/
private File checkExtensionExists(String extensionName) {
// Function added to fix bug 4504166
final String extName = extensionName;
final String[] fileExt = {".jar", ".zip"};
return AccessController.doPrivileged(
new PrivilegedAction<File>() {
public File run() {
try {
File fExtension;
File[] dirs = getExtDirs();
// Search the extension directories for the extension that is specified
// in the attribute extension-list in the applet jar manifest
for (int i=0;i<dirs.length;i++) {
for (int j=0;j<fileExt.length;j++) {
if (extName.toLowerCase().endsWith(fileExt[j])) {
fExtension = new File(dirs[i], extName);
} else {
fExtension = new File(dirs[i], extName+fileExt[j]);
}
debug("checkExtensionExists:fileName " + fExtension.getName());
if (fExtension.exists()) {
return fExtension;
}
}
}
return null;
} catch(Exception e) {
debugException(e);
return null;
}
}
});
}
/**
* <p>
* @return the java.ext.dirs property as a list of directory
* </p>
*/
private static File[] getExtDirs() {
String s = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("java.ext.dirs"));
File[] dirs;
if (s != null) {
StringTokenizer st =
new StringTokenizer(s, File.pathSeparator);
int count = st.countTokens();
debug("getExtDirs count " + count);
dirs = new File[count];
for (int i = 0; i < count; i++) {
dirs[i] = new File(st.nextToken());
debug("getExtDirs dirs["+i+"] "+ dirs[i]);
}
} else {
dirs = new File[0];
debug("getExtDirs dirs " + dirs);
}
debug("getExtDirs dirs.length " + dirs.length);
return dirs;
}
/*
* <p>
* Scan the directories and return all files installed in those
* </p>
* @param dirs list of directories to scan
*
* @return the list of files installed in all the directories
*/
private static File[] getExtFiles(File[] dirs) throws IOException {
Vector<File> urls = new Vector<File>();
for (int i = 0; i < dirs.length; i++) {
String[] files = dirs[i].list(new JarFilter());
if (files != null) {
debug("getExtFiles files.length " + files.length);
for (int j = 0; j < files.length; j++) {
File f = new File(dirs[i], files[j]);
urls.add(f);
debug("getExtFiles f["+j+"] "+ f);
}
}
}
File[] ua = new File[urls.size()];
urls.copyInto(ua);
debug("getExtFiles ua.length " + ua.length);
return ua;
}
/*
* <p>
* @return the list of installed extensions jar files
* </p>
*/
private File[] getInstalledExtensions() throws IOException {
return AccessController.doPrivileged(
new PrivilegedAction<File[]>() {
public File[] run() {
try {
return getExtFiles(getExtDirs());
} catch(IOException e) {
debug("Cannot get list of installed extensions");
debugException(e);
return new File[0];
}
}
});
}
/*
* <p>
* Add the newly installed jar file to the extension class loader.
* </p>
*
* @param cl the current installed extension class loader
*
* @return true if successful
*/
private Boolean addNewExtensionsToClassLoader(Launcher.ExtClassLoader cl) {
try {
File[] installedExts = getInstalledExtensions();
for (int i=0;i<installedExts.length;i++) {
final File instFile = installedExts[i];
URL instURL = AccessController.doPrivileged(
new PrivilegedAction<URL>() {
public URL run() {
try {
return ParseUtil.fileToEncodedURL(instFile);
} catch (MalformedURLException e) {
debugException(e);
return null;
}
}
});
if (instURL != null) {
URL[] urls = cl.getURLs();
boolean found=false;
for (int j = 0; j<urls.length; j++) {
debug("URL["+j+"] is " + urls[j] + " looking for "+
instURL);
if (urls[j].toString().compareToIgnoreCase(
instURL.toString())==0) {
found=true;
debug("Found !");
}
}
if (!found) {
debug("Not Found ! adding to the classloader " +
instURL);
cl.addExtURL(instURL);
}
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
// let's continue with the next installed extension
}
return Boolean.TRUE;
}
// True to display all debug and trace messages
static final boolean DEBUG = false;
private static void debug(String s) {
if (DEBUG) {
System.err.println(s);
}
}
private void debugException(Throwable e) {
if (DEBUG) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,416 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.Attributes.Name;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
import java.text.MessageFormat;
import java.lang.Character.*;
/**
* This class holds all necessary information to install or
* upgrade a extension on the user's disk
*
* @author Jerome Dochez
*/
public class ExtensionInfo {
/**
* <p>
* public static values returned by the isCompatible method
* </p>
*/
public static final int COMPATIBLE = 0;
public static final int REQUIRE_SPECIFICATION_UPGRADE = 1;
public static final int REQUIRE_IMPLEMENTATION_UPGRADE = 2;
public static final int REQUIRE_VENDOR_SWITCH = 3;
public static final int INCOMPATIBLE = 4;
/**
* <p>
* attributes fully describer an extension. The underlying described
* extension may be installed and requested.
* <p>
*/
public String title;
public String name;
public String specVersion;
public String specVendor;
public String implementationVersion;
public String vendor;
public String vendorId;
public String url;
// For I18N support
private static final ResourceBundle rb =
ResourceBundle.getBundle("sun.misc.resources.Messages");
/**
* <p>
* Create a new uninitialized extension information object
* </p>
*/
public ExtensionInfo() {
}
/**
* <p>
* Create and initialize an extension information object.
* The initialization uses the attributes passed as being
* the content of a manifest file to load the extension
* information from.
* Since manifest file may contain information on several
* extension they may depend on, the extension key parameter
* is prepanded to the attribute name to make the key used
* to retrieve the attribute from the manifest file
* <p>
* @param extensionKey unique extension key in the manifest
* @param attr Attributes of a manifest file
*/
public ExtensionInfo(String extensionKey, Attributes attr)
throws NullPointerException
{
String s;
if (extensionKey!=null) {
s = extensionKey + "-";
} else {
s ="";
}
String attrKey = s + Name.EXTENSION_NAME.toString();
name = attr.getValue(attrKey);
if (name != null)
name = name.trim();
attrKey = s + Name.SPECIFICATION_TITLE.toString();
title = attr.getValue(attrKey);
if (title != null)
title = title.trim();
attrKey = s + Name.SPECIFICATION_VERSION.toString();
specVersion = attr.getValue(attrKey);
if (specVersion != null)
specVersion = specVersion.trim();
attrKey = s + Name.SPECIFICATION_VENDOR.toString();
specVendor = attr.getValue(attrKey);
if (specVendor != null)
specVendor = specVendor.trim();
attrKey = s + Name.IMPLEMENTATION_VERSION.toString();
implementationVersion = attr.getValue(attrKey);
if (implementationVersion != null)
implementationVersion = implementationVersion.trim();
attrKey = s + Name.IMPLEMENTATION_VENDOR.toString();
vendor = attr.getValue(attrKey);
if (vendor != null)
vendor = vendor.trim();
attrKey = s + Name.IMPLEMENTATION_VENDOR_ID.toString();
vendorId = attr.getValue(attrKey);
if (vendorId != null)
vendorId = vendorId.trim();
attrKey =s + Name.IMPLEMENTATION_URL.toString();
url = attr.getValue(attrKey);
if (url != null)
url = url.trim();
}
/**
* <p>
* @return true if the extension described by this extension information
* is compatible with the extension described by the extension
* information passed as a parameter
* </p>
*
* @param the requested extension information to compare to
*/
public int isCompatibleWith(ExtensionInfo ei) {
if (name == null || ei.name == null)
return INCOMPATIBLE;
if (name.compareTo(ei.name)==0) {
// is this true, if not spec version is specified, we consider
// the value as being "any".
if (specVersion == null || ei.specVersion == null)
return COMPATIBLE;
int version = compareExtensionVersion(specVersion, ei.specVersion);
if (version<0) {
// this extension specification is "older"
if (vendorId != null && ei.vendorId !=null) {
if (vendorId.compareTo(ei.vendorId)!=0) {
return REQUIRE_VENDOR_SWITCH;
}
}
return REQUIRE_SPECIFICATION_UPGRADE;
} else {
// the extension spec is compatible, let's look at the
// implementation attributes
if (vendorId != null && ei.vendorId != null) {
// They care who provides the extension
if (vendorId.compareTo(ei.vendorId)!=0) {
// They want to use another vendor implementation
return REQUIRE_VENDOR_SWITCH;
} else {
// Vendor matches, let's see the implementation version
if (implementationVersion != null && ei.implementationVersion != null) {
// they care about the implementation version
version = compareExtensionVersion(implementationVersion, ei.implementationVersion);
if (version<0) {
// This extension is an older implementation
return REQUIRE_IMPLEMENTATION_UPGRADE;
}
}
}
}
// All othe cases, we consider the extensions to be compatible
return COMPATIBLE;
}
}
return INCOMPATIBLE;
}
/**
* <p>
* helper method to print sensible information on the undelying described
* extension
* </p>
*/
public String toString() {
return "Extension : title(" + title + "), name(" + name + "), spec vendor(" +
specVendor + "), spec version(" + specVersion + "), impl vendor(" +
vendor + "), impl vendor id(" + vendorId + "), impl version(" +
implementationVersion + "), impl url(" + url + ")";
}
/*
* <p>
* helper method to compare two versions.
* version are in the x.y.z.t pattern.
* </p>
* @param source version to compare to
* @param target version used to compare against
* @return < 0 if source < version
* > 0 if source > version
* = 0 if source = version
*/
private int compareExtensionVersion(String source, String target)
throws NumberFormatException
{
source = source.toLowerCase();
target = target.toLowerCase();
return strictCompareExtensionVersion(source, target);
}
/*
* <p>
* helper method to compare two versions.
* version are in the x.y.z.t pattern.
* </p>
* @param source version to compare to
* @param target version used to compare against
* @return < 0 if source < version
* > 0 if source > version
* = 0 if source = version
*/
private int strictCompareExtensionVersion(String source, String target)
throws NumberFormatException
{
if (source.equals(target))
return 0;
StringTokenizer stk = new StringTokenizer(source, ".,");
StringTokenizer ttk = new StringTokenizer(target, ".,");
// Compare number
int n = 0, m = 0, result = 0;
// Convert token into meaning number for comparision
if (stk.hasMoreTokens())
n = convertToken(stk.nextToken().toString());
// Convert token into meaning number for comparision
if (ttk.hasMoreTokens())
m = convertToken(ttk.nextToken().toString());
if (n > m)
return 1;
else if (m > n)
return -1;
else
{
// Look for index of "." in the string
int sIdx = source.indexOf(".");
int tIdx = target.indexOf(".");
if (sIdx == -1)
sIdx = source.length() - 1;
if (tIdx == -1)
tIdx = target.length() - 1;
return strictCompareExtensionVersion(source.substring(sIdx + 1),
target.substring(tIdx + 1));
}
}
private int convertToken(String token)
{
if (token == null || token.equals(""))
return 0;
int charValue = 0;
int charVersion = 0;
int patchVersion = 0;
int strLength = token.length();
int endIndex = strLength;
char lastChar;
Object[] args = {name};
MessageFormat mf = new MessageFormat(rb.getString("optpkg.versionerror"));
String versionError = mf.format(args);
// Look for "-" for pre-release
int prIndex = token.indexOf("-");
// Look for "_" for patch release
int patchIndex = token.indexOf("_");
if (prIndex == -1 && patchIndex == -1)
{
// This is a FCS release
try {
return Integer.parseInt(token) * 100;
} catch (NumberFormatException e) {
System.out.println(versionError);
return 0;
}
}
else if (patchIndex != -1)
{
// This is a patch (update) release
int prversion;
try {
// Obtain the version
prversion = Integer.parseInt(token.substring(0, patchIndex));
// Check to see if the patch version is in the n.n.n_nnl format (special release)
lastChar = token.charAt(strLength-1);
if (Character.isLetter(lastChar)) {
// letters a-z have values from 10-35
charValue = Character.getNumericValue(lastChar);
endIndex = strLength-1;
// Obtain the patch version id
patchVersion = Integer.parseInt(token.substring(patchIndex+1, endIndex));
if (charValue >= Character.getNumericValue('a') && charValue <= Character.getNumericValue('z')) {
// This is a special release
charVersion = (patchVersion * 100) + charValue;
} else {
// character is not a a-z letter, ignore
charVersion = 0;
System.out.println(versionError);
}
} else {
// This is a regular update release. Obtain the patch version id
patchVersion = Integer.parseInt(token.substring(patchIndex+1, endIndex));
}
} catch (NumberFormatException e) {
System.out.println(versionError);
return 0;
}
return prversion * 100 + (patchVersion + charVersion);
}
else
{
//This is a milestone release, either a early access, alpha, beta, or RC
// Obtain the version
int mrversion;
try {
mrversion = Integer.parseInt(token.substring(0, prIndex));
} catch (NumberFormatException e) {
System.out.println(versionError);
return 0;
}
// Obtain the patch version string, including the milestone + version
String prString = token.substring(prIndex + 1);
// Milestone version
String msVersion = "";
int delta = 0;
if (prString.indexOf("ea") != -1)
{
msVersion = prString.substring(2);
delta = 50;
}
else if (prString.indexOf("alpha") != -1)
{
msVersion = prString.substring(5);
delta = 40;
}
else if (prString.indexOf("beta") != -1)
{
msVersion = prString.substring(4);
delta = 30;
}
else if (prString.indexOf("rc") != -1)
{
msVersion = prString.substring(2);
delta = 20;
}
if (msVersion == null || msVersion.equals(""))
{
// No version after the milestone, assume 0
return mrversion * 100 - delta ;
}
else
{
// Convert the milestone version
try {
return mrversion * 100 - delta + Integer.parseInt(msVersion);
} catch (NumberFormatException e) {
System.out.println(versionError);
return 0;
}
}
}
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/*
* Exception when installation of an extension has failed for
* any reason
*
* @author Jerome Dochez
*/
public class ExtensionInstallationException extends Exception {
static final long serialVersionUID = 3139688306909345924L;
/*
* <p>
* Construct a new exception with an exception reason
* </p>
*/
public ExtensionInstallationException(String s) {
super(s);
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* This interface defines the contract a extension installation capable
* provided to the extension installation dependency mechanism to
* install new extensions on the user's disk
*
* @author Jerome Dochez
*/
public interface ExtensionInstallationProvider {
/*
* <p>
* Request the installation of an extension in the extension directory
* </p>
*
* @param requestExtInfo information on the extension that need to be
* installed
* @param installedExtInfo information on the current compatible installed
* extension. Can be null if no current installation has been found.
* @return true if the installation is successful, false if the
* installation could not be attempted.
* @exception ExtensionInstallationException if an installation was
* attempted but did not succeed.
*/
boolean installExtension(ExtensionInfo requestExtInfo,
ExtensionInfo installedExtInfo)
throws ExtensionInstallationException;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.net.URL;
import java.io.File;
import sun.net.www.ParseUtil;
/**
* (Windows) Platform specific handling for file: URLs . In particular deals
* with network paths mapping them to UNCs.
*
* @author Michael McMahon
*/
public class FileURLMapper {
URL url;
String file;
public FileURLMapper (URL url) {
this.url = url;
}
/**
* @returns the platform specific path corresponding to the URL, and in particular
* returns a UNC when the authority contains a hostname
*/
public String getPath () {
if (file != null) {
return file;
}
String host = url.getHost();
if (host != null && !host.equals("") &&
!"localhost".equalsIgnoreCase(host)) {
String rest = url.getFile();
String s = host + ParseUtil.decode (url.getFile());
file = "\\\\"+ s.replace('/', '\\');
return file;
}
String path = url.getFile().replace('/', '\\');
file = ParseUtil.decode(path);
return file;
}
public boolean exists() {
String path = getPath();
File f = new File (path);
return f.exists();
}
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* This class contains additional constants documenting limits of the
* <code>float</code> type.
*
* @author Joseph D. Darcy
*/
public class FloatConsts {
/**
* Don't let anyone instantiate this class.
*/
private FloatConsts() {}
public static final float POSITIVE_INFINITY = java.lang.Float.POSITIVE_INFINITY;
public static final float NEGATIVE_INFINITY = java.lang.Float.NEGATIVE_INFINITY;
public static final float NaN = java.lang.Float.NaN;
public static final float MAX_VALUE = java.lang.Float.MAX_VALUE;
public static final float MIN_VALUE = java.lang.Float.MIN_VALUE;
/**
* A constant holding the smallest positive normal value of type
* <code>float</code>, 2<sup>-126</sup>. It is equal to the value
* returned by <code>Float.intBitsToFloat(0x00800000)</code>.
*/
public static final float MIN_NORMAL = 1.17549435E-38f;
/**
* The number of logical bits in the significand of a
* <code>float</code> number, including the implicit bit.
*/
public static final int SIGNIFICAND_WIDTH = 24;
/**
* Maximum exponent a finite <code>float</code> number may have.
* It is equal to the value returned by
* <code>Math.ilogb(Float.MAX_VALUE)</code>.
*/
public static final int MAX_EXPONENT = 127;
/**
* Minimum exponent a normalized <code>float</code> number may
* have. It is equal to the value returned by
* <code>Math.ilogb(Float.MIN_NORMAL)</code>.
*/
public static final int MIN_EXPONENT = -126;
/**
* The exponent the smallest positive <code>float</code> subnormal
* value would have if it could be normalized. It is equal to the
* value returned by <code>FpUtils.ilogb(Float.MIN_VALUE)</code>.
*/
public static final int MIN_SUB_EXPONENT = MIN_EXPONENT -
(SIGNIFICAND_WIDTH - 1);
/**
* Bias used in representing a <code>float</code> exponent.
*/
public static final int EXP_BIAS = 127;
/**
* Bit mask to isolate the sign bit of a <code>float</code>.
*/
public static final int SIGN_BIT_MASK = 0x80000000;
/**
* Bit mask to isolate the exponent field of a
* <code>float</code>.
*/
public static final int EXP_BIT_MASK = 0x7F800000;
/**
* Bit mask to isolate the significand field of a
* <code>float</code>.
*/
public static final int SIGNIF_BIT_MASK = 0x007FFFFF;
static {
// verify bit masks cover all bit positions and that the bit
// masks are non-overlapping
assert(((SIGN_BIT_MASK | EXP_BIT_MASK | SIGNIF_BIT_MASK) == ~0) &&
(((SIGN_BIT_MASK & EXP_BIT_MASK) == 0) &&
((SIGN_BIT_MASK & SIGNIF_BIT_MASK) == 0) &&
((EXP_BIT_MASK & SIGNIF_BIT_MASK) == 0)));
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,349 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.util.Arrays;
public class FormattedFloatingDecimal{
public enum Form { SCIENTIFIC, COMPATIBLE, DECIMAL_FLOAT, GENERAL };
public static FormattedFloatingDecimal valueOf(double d, int precision, Form form){
FloatingDecimal.BinaryToASCIIConverter fdConverter =
FloatingDecimal.getBinaryToASCIIConverter(d, form == Form.COMPATIBLE);
return new FormattedFloatingDecimal(precision,form, fdConverter);
}
private int decExponentRounded;
private char[] mantissa;
private char[] exponent;
private static final ThreadLocal<Object> threadLocalCharBuffer =
new ThreadLocal<Object>() {
@Override
protected Object initialValue() {
return new char[20];
}
};
private static char[] getBuffer(){
return (char[]) threadLocalCharBuffer.get();
}
private FormattedFloatingDecimal(int precision, Form form, FloatingDecimal.BinaryToASCIIConverter fdConverter) {
if (fdConverter.isExceptional()) {
this.mantissa = fdConverter.toJavaFormatString().toCharArray();
this.exponent = null;
return;
}
char[] digits = getBuffer();
int nDigits = fdConverter.getDigits(digits);
int decExp = fdConverter.getDecimalExponent();
int exp;
boolean isNegative = fdConverter.isNegative();
switch (form) {
case COMPATIBLE:
exp = decExp;
this.decExponentRounded = exp;
fillCompatible(precision, digits, nDigits, exp, isNegative);
break;
case DECIMAL_FLOAT:
exp = applyPrecision(decExp, digits, nDigits, decExp + precision);
fillDecimal(precision, digits, nDigits, exp, isNegative);
this.decExponentRounded = exp;
break;
case SCIENTIFIC:
exp = applyPrecision(decExp, digits, nDigits, precision + 1);
fillScientific(precision, digits, nDigits, exp, isNegative);
this.decExponentRounded = exp;
break;
case GENERAL:
exp = applyPrecision(decExp, digits, nDigits, precision);
// adjust precision to be the number of digits to right of decimal
// the real exponent to be output is actually exp - 1, not exp
if (exp - 1 < -4 || exp - 1 >= precision) {
// form = Form.SCIENTIFIC;
precision--;
fillScientific(precision, digits, nDigits, exp, isNegative);
} else {
// form = Form.DECIMAL_FLOAT;
precision = precision - exp;
fillDecimal(precision, digits, nDigits, exp, isNegative);
}
this.decExponentRounded = exp;
break;
default:
assert false;
}
}
// returns the exponent after rounding has been done by applyPrecision
public int getExponentRounded() {
return decExponentRounded - 1;
}
public char[] getMantissa(){
return mantissa;
}
public char[] getExponent(){
return exponent;
}
/**
* Returns new decExp in case of overflow.
*/
private static int applyPrecision(int decExp, char[] digits, int nDigits, int prec) {
if (prec >= nDigits || prec < 0) {
// no rounding necessary
return decExp;
}
if (prec == 0) {
// only one digit (0 or 1) is returned because the precision
// excludes all significant digits
if (digits[0] >= '5') {
digits[0] = '1';
Arrays.fill(digits, 1, nDigits, '0');
return decExp + 1;
} else {
Arrays.fill(digits, 0, nDigits, '0');
return decExp;
}
}
int q = digits[prec];
if (q >= '5') {
int i = prec;
q = digits[--i];
if ( q == '9' ) {
while ( q == '9' && i > 0 ){
q = digits[--i];
}
if ( q == '9' ){
// carryout! High-order 1, rest 0s, larger exp.
digits[0] = '1';
Arrays.fill(digits, 1, nDigits, '0');
return decExp+1;
}
}
digits[i] = (char)(q + 1);
Arrays.fill(digits, i+1, nDigits, '0');
} else {
Arrays.fill(digits, prec, nDigits, '0');
}
return decExp;
}
/**
* Fills mantissa and exponent char arrays for compatible format.
*/
private void fillCompatible(int precision, char[] digits, int nDigits, int exp, boolean isNegative) {
int startIndex = isNegative ? 1 : 0;
if (exp > 0 && exp < 8) {
// print digits.digits.
if (nDigits < exp) {
int extraZeros = exp - nDigits;
mantissa = create(isNegative, nDigits + extraZeros + 2);
System.arraycopy(digits, 0, mantissa, startIndex, nDigits);
Arrays.fill(mantissa, startIndex + nDigits, startIndex + nDigits + extraZeros, '0');
mantissa[startIndex + nDigits + extraZeros] = '.';
mantissa[startIndex + nDigits + extraZeros+1] = '0';
} else if (exp < nDigits) {
int t = Math.min(nDigits - exp, precision);
mantissa = create(isNegative, exp + 1 + t);
System.arraycopy(digits, 0, mantissa, startIndex, exp);
mantissa[startIndex + exp ] = '.';
System.arraycopy(digits, exp, mantissa, startIndex+exp+1, t);
} else { // exp == digits.length
mantissa = create(isNegative, nDigits + 2);
System.arraycopy(digits, 0, mantissa, startIndex, nDigits);
mantissa[startIndex + nDigits ] = '.';
mantissa[startIndex + nDigits +1] = '0';
}
} else if (exp <= 0 && exp > -3) {
int zeros = Math.max(0, Math.min(-exp, precision));
int t = Math.max(0, Math.min(nDigits, precision + exp));
// write '0' s before the significant digits
if (zeros > 0) {
mantissa = create(isNegative, zeros + 2 + t);
mantissa[startIndex] = '0';
mantissa[startIndex+1] = '.';
Arrays.fill(mantissa, startIndex + 2, startIndex + 2 + zeros, '0');
if (t > 0) {
// copy only when significant digits are within the precision
System.arraycopy(digits, 0, mantissa, startIndex + 2 + zeros, t);
}
} else if (t > 0) {
mantissa = create(isNegative, zeros + 2 + t);
mantissa[startIndex] = '0';
mantissa[startIndex + 1] = '.';
// copy only when significant digits are within the precision
System.arraycopy(digits, 0, mantissa, startIndex + 2, t);
} else {
this.mantissa = create(isNegative, 1);
this.mantissa[startIndex] = '0';
}
} else {
if (nDigits > 1) {
mantissa = create(isNegative, nDigits + 1);
mantissa[startIndex] = digits[0];
mantissa[startIndex + 1] = '.';
System.arraycopy(digits, 1, mantissa, startIndex + 2, nDigits - 1);
} else {
mantissa = create(isNegative, 3);
mantissa[startIndex] = digits[0];
mantissa[startIndex + 1] = '.';
mantissa[startIndex + 2] = '0';
}
int e, expStartIntex;
boolean isNegExp = (exp <= 0);
if (isNegExp) {
e = -exp + 1;
expStartIntex = 1;
} else {
e = exp - 1;
expStartIntex = 0;
}
// decExponent has 1, 2, or 3, digits
if (e <= 9) {
exponent = create(isNegExp,1);
exponent[expStartIntex] = (char) (e + '0');
} else if (e <= 99) {
exponent = create(isNegExp,2);
exponent[expStartIntex] = (char) (e / 10 + '0');
exponent[expStartIntex+1] = (char) (e % 10 + '0');
} else {
exponent = create(isNegExp,3);
exponent[expStartIntex] = (char) (e / 100 + '0');
e %= 100;
exponent[expStartIntex+1] = (char) (e / 10 + '0');
exponent[expStartIntex+2] = (char) (e % 10 + '0');
}
}
}
private static char[] create(boolean isNegative, int size) {
if(isNegative) {
char[] r = new char[size +1];
r[0] = '-';
return r;
} else {
return new char[size];
}
}
/*
* Fills mantissa char arrays for DECIMAL_FLOAT format.
* Exponent should be equal to null.
*/
private void fillDecimal(int precision, char[] digits, int nDigits, int exp, boolean isNegative) {
int startIndex = isNegative ? 1 : 0;
if (exp > 0) {
// print digits.digits.
if (nDigits < exp) {
mantissa = create(isNegative,exp);
System.arraycopy(digits, 0, mantissa, startIndex, nDigits);
Arrays.fill(mantissa, startIndex + nDigits, startIndex + exp, '0');
// Do not append ".0" for formatted floats since the user
// may request that it be omitted. It is added as necessary
// by the Formatter.
} else {
int t = Math.min(nDigits - exp, precision);
mantissa = create(isNegative, exp + (t > 0 ? (t + 1) : 0));
System.arraycopy(digits, 0, mantissa, startIndex, exp);
// Do not append ".0" for formatted floats since the user
// may request that it be omitted. It is added as necessary
// by the Formatter.
if (t > 0) {
mantissa[startIndex + exp] = '.';
System.arraycopy(digits, exp, mantissa, startIndex + exp + 1, t);
}
}
} else if (exp <= 0) {
int zeros = Math.max(0, Math.min(-exp, precision));
int t = Math.max(0, Math.min(nDigits, precision + exp));
// write '0' s before the significant digits
if (zeros > 0) {
mantissa = create(isNegative, zeros + 2 + t);
mantissa[startIndex] = '0';
mantissa[startIndex+1] = '.';
Arrays.fill(mantissa, startIndex + 2, startIndex + 2 + zeros, '0');
if (t > 0) {
// copy only when significant digits are within the precision
System.arraycopy(digits, 0, mantissa, startIndex + 2 + zeros, t);
}
} else if (t > 0) {
mantissa = create(isNegative, zeros + 2 + t);
mantissa[startIndex] = '0';
mantissa[startIndex + 1] = '.';
// copy only when significant digits are within the precision
System.arraycopy(digits, 0, mantissa, startIndex + 2, t);
} else {
this.mantissa = create(isNegative, 1);
this.mantissa[startIndex] = '0';
}
}
}
/**
* Fills mantissa and exponent char arrays for SCIENTIFIC format.
*/
private void fillScientific(int precision, char[] digits, int nDigits, int exp, boolean isNegative) {
int startIndex = isNegative ? 1 : 0;
int t = Math.max(0, Math.min(nDigits - 1, precision));
if (t > 0) {
mantissa = create(isNegative, t + 2);
mantissa[startIndex] = digits[0];
mantissa[startIndex + 1] = '.';
System.arraycopy(digits, 1, mantissa, startIndex + 2, t);
} else {
mantissa = create(isNegative, 1);
mantissa[startIndex] = digits[0];
}
char expSign;
int e;
if (exp <= 0) {
expSign = '-';
e = -exp + 1;
} else {
expSign = '+' ;
e = exp - 1;
}
// decExponent has 1, 2, or 3, digits
if (e <= 9) {
exponent = new char[] { expSign,
'0', (char) (e + '0') };
} else if (e <= 99) {
exponent = new char[] { expSign,
(char) (e / 10 + '0'), (char) (e % 10 + '0') };
} else {
char hiExpChar = (char) (e / 100 + '0');
e %= 100;
exponent = new char[] { expSign,
hiExpChar, (char) (e / 10 + '0'), (char) (e % 10 + '0') };
}
}
}

View File

@@ -0,0 +1,931 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import sun.misc.FloatConsts;
import sun.misc.DoubleConsts;
/**
* The class {@code FpUtils} contains static utility methods for
* manipulating and inspecting {@code float} and
* {@code double} floating-point numbers. These methods include
* functionality recommended or required by the IEEE 754
* floating-point standard.
*
* @author Joseph D. Darcy
*/
public class FpUtils {
/*
* The methods in this class are reasonably implemented using
* direct or indirect bit-level manipulation of floating-point
* values. However, having access to the IEEE 754 recommended
* functions would obviate the need for most programmers to engage
* in floating-point bit-twiddling.
*
* An IEEE 754 number has three fields, from most significant bit
* to to least significant, sign, exponent, and significand.
*
* msb lsb
* [sign|exponent| fractional_significand]
*
* Using some encoding cleverness, explained below, the high order
* bit of the logical significand does not need to be explicitly
* stored, thus "fractional_significand" instead of simply
* "significand" in the figure above.
*
* For finite normal numbers, the numerical value encoded is
*
* (-1)^sign * 2^(exponent)*(1.fractional_significand)
*
* Most finite floating-point numbers are normalized; the exponent
* value is reduced until the leading significand bit is 1.
* Therefore, the leading 1 is redundant and is not explicitly
* stored. If a numerical value is so small it cannot be
* normalized, it has a subnormal representation. Subnormal
* numbers don't have a leading 1 in their significand; subnormals
* are encoding using a special exponent value. In other words,
* the high-order bit of the logical significand can be elided in
* from the representation in either case since the bit's value is
* implicit from the exponent value.
*
* The exponent field uses a biased representation; if the bits of
* the exponent are interpreted as a unsigned integer E, the
* exponent represented is E - E_bias where E_bias depends on the
* floating-point format. E can range between E_min and E_max,
* constants which depend on the floating-point format. E_min and
* E_max are -126 and +127 for float, -1022 and +1023 for double.
*
* The 32-bit float format has 1 sign bit, 8 exponent bits, and 23
* bits for the significand (which is logically 24 bits wide
* because of the implicit bit). The 64-bit double format has 1
* sign bit, 11 exponent bits, and 52 bits for the significand
* (logically 53 bits).
*
* Subnormal numbers and zero have the special exponent value
* E_min -1; the numerical value represented by a subnormal is:
*
* (-1)^sign * 2^(E_min)*(0.fractional_significand)
*
* Zero is represented by all zero bits in the exponent and all
* zero bits in the significand; zero can have either sign.
*
* Infinity and NaN are encoded using the exponent value E_max +
* 1. Signed infinities have all significand bits zero; NaNs have
* at least one non-zero significand bit.
*
* The details of IEEE 754 floating-point encoding will be used in
* the methods below without further comment. For further
* exposition on IEEE 754 numbers, see "IEEE Standard for Binary
* Floating-Point Arithmetic" ANSI/IEEE Std 754-1985 or William
* Kahan's "Lecture Notes on the Status of IEEE Standard 754 for
* Binary Floating-Point Arithmetic",
* http://www.cs.berkeley.edu/~wkahan/ieee754status/ieee754.ps.
*
* Many of this class's methods are members of the set of IEEE 754
* recommended functions or similar functions recommended or
* required by IEEE 754R. Discussion of various implementation
* techniques for these functions have occurred in:
*
* W.J. Cody and Jerome T. Coonen, "Algorithm 772 Functions to
* Support the IEEE Standard for Binary Floating-Point
* Arithmetic," ACM Transactions on Mathematical Software,
* vol. 19, no. 4, December 1993, pp. 443-451.
*
* Joseph D. Darcy, "Writing robust IEEE recommended functions in
* ``100% Pure Java''(TM)," University of California, Berkeley
* technical report UCB//CSD-98-1009.
*/
/**
* Don't let anyone instantiate this class.
*/
private FpUtils() {}
// Helper Methods
// The following helper methods are used in the implementation of
// the public recommended functions; they generally omit certain
// tests for exception cases.
/**
* Returns unbiased exponent of a {@code double}.
* @deprecated Use Math.getExponent.
*/
@Deprecated
public static int getExponent(double d){
return Math.getExponent(d);
}
/**
* Returns unbiased exponent of a {@code float}.
* @deprecated Use Math.getExponent.
*/
@Deprecated
public static int getExponent(float f){
return Math.getExponent(f);
}
/**
* Returns the first floating-point argument with the sign of the
* second floating-point argument. Note that unlike the {@link
* FpUtils#copySign(double, double) copySign} method, this method
* does not require NaN {@code sign} arguments to be treated
* as positive values; implementations are permitted to treat some
* NaN arguments as positive and other NaN arguments as negative
* to allow greater performance.
*
* @param magnitude the parameter providing the magnitude of the result
* @param sign the parameter providing the sign of the result
* @return a value with the magnitude of {@code magnitude}
* and the sign of {@code sign}.
* @author Joseph D. Darcy
* @deprecated Use Math.copySign.
*/
@Deprecated
public static double rawCopySign(double magnitude, double sign) {
return Math.copySign(magnitude, sign);
}
/**
* Returns the first floating-point argument with the sign of the
* second floating-point argument. Note that unlike the {@link
* FpUtils#copySign(float, float) copySign} method, this method
* does not require NaN {@code sign} arguments to be treated
* as positive values; implementations are permitted to treat some
* NaN arguments as positive and other NaN arguments as negative
* to allow greater performance.
*
* @param magnitude the parameter providing the magnitude of the result
* @param sign the parameter providing the sign of the result
* @return a value with the magnitude of {@code magnitude}
* and the sign of {@code sign}.
* @author Joseph D. Darcy
* @deprecated Use Math.copySign.
*/
@Deprecated
public static float rawCopySign(float magnitude, float sign) {
return Math.copySign(magnitude, sign);
}
/* ***************************************************************** */
/**
* Returns {@code true} if the argument is a finite
* floating-point value; returns {@code false} otherwise (for
* NaN and infinity arguments).
*
* @param d the {@code double} value to be tested
* @return {@code true} if the argument is a finite
* floating-point value, {@code false} otherwise.
* @deprecated Use Double.isFinite.
*/
@Deprecated
public static boolean isFinite(double d) {
return Double.isFinite(d);
}
/**
* Returns {@code true} if the argument is a finite
* floating-point value; returns {@code false} otherwise (for
* NaN and infinity arguments).
*
* @param f the {@code float} value to be tested
* @return {@code true} if the argument is a finite
* floating-point value, {@code false} otherwise.
* @deprecated Use Float.isFinite.
*/
@Deprecated
public static boolean isFinite(float f) {
return Float.isFinite(f);
}
/**
* Returns {@code true} if the specified number is infinitely
* large in magnitude, {@code false} otherwise.
*
* <p>Note that this method is equivalent to the {@link
* Double#isInfinite(double) Double.isInfinite} method; the
* functionality is included in this class for convenience.
*
* @param d the value to be tested.
* @return {@code true} if the value of the argument is positive
* infinity or negative infinity; {@code false} otherwise.
*/
public static boolean isInfinite(double d) {
return Double.isInfinite(d);
}
/**
* Returns {@code true} if the specified number is infinitely
* large in magnitude, {@code false} otherwise.
*
* <p>Note that this method is equivalent to the {@link
* Float#isInfinite(float) Float.isInfinite} method; the
* functionality is included in this class for convenience.
*
* @param f the value to be tested.
* @return {@code true} if the argument is positive infinity or
* negative infinity; {@code false} otherwise.
*/
public static boolean isInfinite(float f) {
return Float.isInfinite(f);
}
/**
* Returns {@code true} if the specified number is a
* Not-a-Number (NaN) value, {@code false} otherwise.
*
* <p>Note that this method is equivalent to the {@link
* Double#isNaN(double) Double.isNaN} method; the functionality is
* included in this class for convenience.
*
* @param d the value to be tested.
* @return {@code true} if the value of the argument is NaN;
* {@code false} otherwise.
*/
public static boolean isNaN(double d) {
return Double.isNaN(d);
}
/**
* Returns {@code true} if the specified number is a
* Not-a-Number (NaN) value, {@code false} otherwise.
*
* <p>Note that this method is equivalent to the {@link
* Float#isNaN(float) Float.isNaN} method; the functionality is
* included in this class for convenience.
*
* @param f the value to be tested.
* @return {@code true} if the argument is NaN;
* {@code false} otherwise.
*/
public static boolean isNaN(float f) {
return Float.isNaN(f);
}
/**
* Returns {@code true} if the unordered relation holds
* between the two arguments. When two floating-point values are
* unordered, one value is neither less than, equal to, nor
* greater than the other. For the unordered relation to be true,
* at least one argument must be a {@code NaN}.
*
* @param arg1 the first argument
* @param arg2 the second argument
* @return {@code true} if at least one argument is a NaN,
* {@code false} otherwise.
*/
public static boolean isUnordered(double arg1, double arg2) {
return isNaN(arg1) || isNaN(arg2);
}
/**
* Returns {@code true} if the unordered relation holds
* between the two arguments. When two floating-point values are
* unordered, one value is neither less than, equal to, nor
* greater than the other. For the unordered relation to be true,
* at least one argument must be a {@code NaN}.
*
* @param arg1 the first argument
* @param arg2 the second argument
* @return {@code true} if at least one argument is a NaN,
* {@code false} otherwise.
*/
public static boolean isUnordered(float arg1, float arg2) {
return isNaN(arg1) || isNaN(arg2);
}
/**
* Returns unbiased exponent of a {@code double}; for
* subnormal values, the number is treated as if it were
* normalized. That is for all finite, non-zero, positive numbers
* <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is
* always in the range [1, 2).
* <p>
* Special cases:
* <ul>
* <li> If the argument is NaN, then the result is 2<sup>30</sup>.
* <li> If the argument is infinite, then the result is 2<sup>28</sup>.
* <li> If the argument is zero, then the result is -(2<sup>28</sup>).
* </ul>
*
* @param d floating-point number whose exponent is to be extracted
* @return unbiased exponent of the argument.
* @author Joseph D. Darcy
*/
public static int ilogb(double d) {
int exponent = getExponent(d);
switch (exponent) {
case DoubleConsts.MAX_EXPONENT+1: // NaN or infinity
if( isNaN(d) )
return (1<<30); // 2^30
else // infinite value
return (1<<28); // 2^28
case DoubleConsts.MIN_EXPONENT-1: // zero or subnormal
if(d == 0.0) {
return -(1<<28); // -(2^28)
}
else {
long transducer = Double.doubleToRawLongBits(d);
/*
* To avoid causing slow arithmetic on subnormals,
* the scaling to determine when d's significand
* is normalized is done in integer arithmetic.
* (there must be at least one "1" bit in the
* significand since zero has been screened out.
*/
// isolate significand bits
transducer &= DoubleConsts.SIGNIF_BIT_MASK;
assert(transducer != 0L);
// This loop is simple and functional. We might be
// able to do something more clever that was faster;
// e.g. number of leading zero detection on
// (transducer << (# exponent and sign bits).
while (transducer <
(1L << (DoubleConsts.SIGNIFICAND_WIDTH - 1))) {
transducer *= 2;
exponent--;
}
exponent++;
assert( exponent >=
DoubleConsts.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1) &&
exponent < DoubleConsts.MIN_EXPONENT);
return exponent;
}
default:
assert( exponent >= DoubleConsts.MIN_EXPONENT &&
exponent <= DoubleConsts.MAX_EXPONENT);
return exponent;
}
}
/**
* Returns unbiased exponent of a {@code float}; for
* subnormal values, the number is treated as if it were
* normalized. That is for all finite, non-zero, positive numbers
* <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is
* always in the range [1, 2).
* <p>
* Special cases:
* <ul>
* <li> If the argument is NaN, then the result is 2<sup>30</sup>.
* <li> If the argument is infinite, then the result is 2<sup>28</sup>.
* <li> If the argument is zero, then the result is -(2<sup>28</sup>).
* </ul>
*
* @param f floating-point number whose exponent is to be extracted
* @return unbiased exponent of the argument.
* @author Joseph D. Darcy
*/
public static int ilogb(float f) {
int exponent = getExponent(f);
switch (exponent) {
case FloatConsts.MAX_EXPONENT+1: // NaN or infinity
if( isNaN(f) )
return (1<<30); // 2^30
else // infinite value
return (1<<28); // 2^28
case FloatConsts.MIN_EXPONENT-1: // zero or subnormal
if(f == 0.0f) {
return -(1<<28); // -(2^28)
}
else {
int transducer = Float.floatToRawIntBits(f);
/*
* To avoid causing slow arithmetic on subnormals,
* the scaling to determine when f's significand
* is normalized is done in integer arithmetic.
* (there must be at least one "1" bit in the
* significand since zero has been screened out.
*/
// isolate significand bits
transducer &= FloatConsts.SIGNIF_BIT_MASK;
assert(transducer != 0);
// This loop is simple and functional. We might be
// able to do something more clever that was faster;
// e.g. number of leading zero detection on
// (transducer << (# exponent and sign bits).
while (transducer <
(1 << (FloatConsts.SIGNIFICAND_WIDTH - 1))) {
transducer *= 2;
exponent--;
}
exponent++;
assert( exponent >=
FloatConsts.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1) &&
exponent < FloatConsts.MIN_EXPONENT);
return exponent;
}
default:
assert( exponent >= FloatConsts.MIN_EXPONENT &&
exponent <= FloatConsts.MAX_EXPONENT);
return exponent;
}
}
/*
* The scalb operation should be reasonably fast; however, there
* are tradeoffs in writing a method to minimize the worst case
* performance and writing a method to minimize the time for
* expected common inputs. Some processors operate very slowly on
* subnormal operands, taking hundreds or thousands of cycles for
* one floating-point add or multiply as opposed to, say, four
* cycles for normal operands. For processors with very slow
* subnormal execution, scalb would be fastest if written entirely
* with integer operations; in other words, scalb would need to
* include the logic of performing correct rounding of subnormal
* values. This could be reasonably done in at most a few hundred
* cycles. However, this approach may penalize normal operations
* since at least the exponent of the floating-point argument must
* be examined.
*
* The approach taken in this implementation is a compromise.
* Floating-point multiplication is used to do most of the work;
* but knowingly multiplying by a subnormal scaling factor is
* avoided. However, the floating-point argument is not examined
* to see whether or not it is subnormal since subnormal inputs
* are assumed to be rare. At most three multiplies are needed to
* scale from the largest to smallest exponent ranges (scaling
* down, at most two multiplies are needed if subnormal scaling
* factors are allowed). However, in this implementation an
* expensive integer remainder operation is avoided at the cost of
* requiring five floating-point multiplies in the worst case,
* which should still be a performance win.
*
* If scaling of entire arrays is a concern, it would probably be
* more efficient to provide a double[] scalb(double[], int)
* version of scalb to avoid having to recompute the needed
* scaling factors for each floating-point value.
*/
/**
* Return {@code d} &times;
* 2<sup>{@code scale_factor}</sup> rounded as if performed
* by a single correctly rounded floating-point multiply to a
* member of the double value set. See section 4.2.3 of
* <cite>The Java&trade; Language Specification</cite>
* for a discussion of floating-point
* value sets. If the exponent of the result is between the
* {@code double}'s minimum exponent and maximum exponent,
* the answer is calculated exactly. If the exponent of the
* result would be larger than {@code doubles}'s maximum
* exponent, an infinity is returned. Note that if the result is
* subnormal, precision may be lost; that is, when {@code scalb(x,
* n)} is subnormal, {@code scalb(scalb(x, n), -n)} may
* not equal <i>x</i>. When the result is non-NaN, the result has
* the same sign as {@code d}.
*
*<p>
* Special cases:
* <ul>
* <li> If the first argument is NaN, NaN is returned.
* <li> If the first argument is infinite, then an infinity of the
* same sign is returned.
* <li> If the first argument is zero, then a zero of the same
* sign is returned.
* </ul>
*
* @param d number to be scaled by a power of two.
* @param scale_factor power of 2 used to scale {@code d}
* @return {@code d * }2<sup>{@code scale_factor}</sup>
* @author Joseph D. Darcy
* @deprecated Use Math.scalb.
*/
@Deprecated
public static double scalb(double d, int scale_factor) {
return Math.scalb(d, scale_factor);
}
/**
* Return {@code f} &times;
* 2<sup>{@code scale_factor}</sup> rounded as if performed
* by a single correctly rounded floating-point multiply to a
* member of the float value set. See section 4.2.3 of
* <cite>The Java&trade; Language Specification</cite>
* for a discussion of floating-point
* value sets. If the exponent of the result is between the
* {@code float}'s minimum exponent and maximum exponent, the
* answer is calculated exactly. If the exponent of the result
* would be larger than {@code float}'s maximum exponent, an
* infinity is returned. Note that if the result is subnormal,
* precision may be lost; that is, when {@code scalb(x, n)}
* is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
* <i>x</i>. When the result is non-NaN, the result has the same
* sign as {@code f}.
*
*<p>
* Special cases:
* <ul>
* <li> If the first argument is NaN, NaN is returned.
* <li> If the first argument is infinite, then an infinity of the
* same sign is returned.
* <li> If the first argument is zero, then a zero of the same
* sign is returned.
* </ul>
*
* @param f number to be scaled by a power of two.
* @param scale_factor power of 2 used to scale {@code f}
* @return {@code f * }2<sup>{@code scale_factor}</sup>
* @author Joseph D. Darcy
* @deprecated Use Math.scalb.
*/
@Deprecated
public static float scalb(float f, int scale_factor) {
return Math.scalb(f, scale_factor);
}
/**
* Returns the floating-point number adjacent to the first
* argument in the direction of the second argument. If both
* arguments compare as equal the second argument is returned.
*
* <p>
* Special cases:
* <ul>
* <li> If either argument is a NaN, then NaN is returned.
*
* <li> If both arguments are signed zeros, {@code direction}
* is returned unchanged (as implied by the requirement of
* returning the second argument if the arguments compare as
* equal).
*
* <li> If {@code start} is
* &plusmn;{@code Double.MIN_VALUE} and {@code direction}
* has a value such that the result should have a smaller
* magnitude, then a zero with the same sign as {@code start}
* is returned.
*
* <li> If {@code start} is infinite and
* {@code direction} has a value such that the result should
* have a smaller magnitude, {@code Double.MAX_VALUE} with the
* same sign as {@code start} is returned.
*
* <li> If {@code start} is equal to &plusmn;
* {@code Double.MAX_VALUE} and {@code direction} has a
* value such that the result should have a larger magnitude, an
* infinity with same sign as {@code start} is returned.
* </ul>
*
* @param start starting floating-point value
* @param direction value indicating which of
* {@code start}'s neighbors or {@code start} should
* be returned
* @return The floating-point number adjacent to {@code start} in the
* direction of {@code direction}.
* @author Joseph D. Darcy
* @deprecated Use Math.nextAfter
*/
@Deprecated
public static double nextAfter(double start, double direction) {
return Math.nextAfter(start, direction);
}
/**
* Returns the floating-point number adjacent to the first
* argument in the direction of the second argument. If both
* arguments compare as equal, the second argument is returned.
*
* <p>
* Special cases:
* <ul>
* <li> If either argument is a NaN, then NaN is returned.
*
* <li> If both arguments are signed zeros, a {@code float}
* zero with the same sign as {@code direction} is returned
* (as implied by the requirement of returning the second argument
* if the arguments compare as equal).
*
* <li> If {@code start} is
* &plusmn;{@code Float.MIN_VALUE} and {@code direction}
* has a value such that the result should have a smaller
* magnitude, then a zero with the same sign as {@code start}
* is returned.
*
* <li> If {@code start} is infinite and
* {@code direction} has a value such that the result should
* have a smaller magnitude, {@code Float.MAX_VALUE} with the
* same sign as {@code start} is returned.
*
* <li> If {@code start} is equal to &plusmn;
* {@code Float.MAX_VALUE} and {@code direction} has a
* value such that the result should have a larger magnitude, an
* infinity with same sign as {@code start} is returned.
* </ul>
*
* @param start starting floating-point value
* @param direction value indicating which of
* {@code start}'s neighbors or {@code start} should
* be returned
* @return The floating-point number adjacent to {@code start} in the
* direction of {@code direction}.
* @author Joseph D. Darcy
* @deprecated Use Math.nextAfter.
*/
@Deprecated
public static float nextAfter(float start, double direction) {
return Math.nextAfter(start, direction);
}
/**
* Returns the floating-point value adjacent to {@code d} in
* the direction of positive infinity. This method is
* semantically equivalent to {@code nextAfter(d,
* Double.POSITIVE_INFINITY)}; however, a {@code nextUp}
* implementation may run faster than its equivalent
* {@code nextAfter} call.
*
* <p>Special Cases:
* <ul>
* <li> If the argument is NaN, the result is NaN.
*
* <li> If the argument is positive infinity, the result is
* positive infinity.
*
* <li> If the argument is zero, the result is
* {@code Double.MIN_VALUE}
*
* </ul>
*
* @param d starting floating-point value
* @return The adjacent floating-point value closer to positive
* infinity.
* @author Joseph D. Darcy
* @deprecated use Math.nextUp.
*/
@Deprecated
public static double nextUp(double d) {
return Math.nextUp(d);
}
/**
* Returns the floating-point value adjacent to {@code f} in
* the direction of positive infinity. This method is
* semantically equivalent to {@code nextAfter(f,
* Double.POSITIVE_INFINITY)}; however, a {@code nextUp}
* implementation may run faster than its equivalent
* {@code nextAfter} call.
*
* <p>Special Cases:
* <ul>
* <li> If the argument is NaN, the result is NaN.
*
* <li> If the argument is positive infinity, the result is
* positive infinity.
*
* <li> If the argument is zero, the result is
* {@code Float.MIN_VALUE}
*
* </ul>
*
* @param f starting floating-point value
* @return The adjacent floating-point value closer to positive
* infinity.
* @author Joseph D. Darcy
* @deprecated Use Math.nextUp.
*/
@Deprecated
public static float nextUp(float f) {
return Math.nextUp(f);
}
/**
* Returns the floating-point value adjacent to {@code d} in
* the direction of negative infinity. This method is
* semantically equivalent to {@code nextAfter(d,
* Double.NEGATIVE_INFINITY)}; however, a
* {@code nextDown} implementation may run faster than its
* equivalent {@code nextAfter} call.
*
* <p>Special Cases:
* <ul>
* <li> If the argument is NaN, the result is NaN.
*
* <li> If the argument is negative infinity, the result is
* negative infinity.
*
* <li> If the argument is zero, the result is
* {@code -Double.MIN_VALUE}
*
* </ul>
*
* @param d starting floating-point value
* @return The adjacent floating-point value closer to negative
* infinity.
* @author Joseph D. Darcy
* @deprecated Use Math.nextDown.
*/
@Deprecated
public static double nextDown(double d) {
return Math.nextDown(d);
}
/**
* Returns the floating-point value adjacent to {@code f} in
* the direction of negative infinity. This method is
* semantically equivalent to {@code nextAfter(f,
* Float.NEGATIVE_INFINITY)}; however, a
* {@code nextDown} implementation may run faster than its
* equivalent {@code nextAfter} call.
*
* <p>Special Cases:
* <ul>
* <li> If the argument is NaN, the result is NaN.
*
* <li> If the argument is negative infinity, the result is
* negative infinity.
*
* <li> If the argument is zero, the result is
* {@code -Float.MIN_VALUE}
*
* </ul>
*
* @param f starting floating-point value
* @return The adjacent floating-point value closer to negative
* infinity.
* @author Joseph D. Darcy
* @deprecated Use Math.nextDown.
*/
@Deprecated
public static double nextDown(float f) {
return Math.nextDown(f);
}
/**
* Returns the first floating-point argument with the sign of the
* second floating-point argument. For this method, a NaN
* {@code sign} argument is always treated as if it were
* positive.
*
* @param magnitude the parameter providing the magnitude of the result
* @param sign the parameter providing the sign of the result
* @return a value with the magnitude of {@code magnitude}
* and the sign of {@code sign}.
* @author Joseph D. Darcy
* @since 1.5
* @deprecated Use StrictMath.copySign.
*/
@Deprecated
public static double copySign(double magnitude, double sign) {
return StrictMath.copySign(magnitude, sign);
}
/**
* Returns the first floating-point argument with the sign of the
* second floating-point argument. For this method, a NaN
* {@code sign} argument is always treated as if it were
* positive.
*
* @param magnitude the parameter providing the magnitude of the result
* @param sign the parameter providing the sign of the result
* @return a value with the magnitude of {@code magnitude}
* and the sign of {@code sign}.
* @author Joseph D. Darcy
* @deprecated Use StrictMath.copySign.
*/
@Deprecated
public static float copySign(float magnitude, float sign) {
return StrictMath.copySign(magnitude, sign);
}
/**
* Returns the size of an ulp of the argument. An ulp of a
* {@code double} value is the positive distance between this
* floating-point value and the {@code double} value next
* larger in magnitude. Note that for non-NaN <i>x</i>,
* <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
*
* <p>Special Cases:
* <ul>
* <li> If the argument is NaN, then the result is NaN.
* <li> If the argument is positive or negative infinity, then the
* result is positive infinity.
* <li> If the argument is positive or negative zero, then the result is
* {@code Double.MIN_VALUE}.
* <li> If the argument is &plusmn;{@code Double.MAX_VALUE}, then
* the result is equal to 2<sup>971</sup>.
* </ul>
*
* @param d the floating-point value whose ulp is to be returned
* @return the size of an ulp of the argument
* @author Joseph D. Darcy
* @since 1.5
* @deprecated Use Math.ulp.
*/
@Deprecated
public static double ulp(double d) {
return Math.ulp(d);
}
/**
* Returns the size of an ulp of the argument. An ulp of a
* {@code float} value is the positive distance between this
* floating-point value and the {@code float} value next
* larger in magnitude. Note that for non-NaN <i>x</i>,
* <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
*
* <p>Special Cases:
* <ul>
* <li> If the argument is NaN, then the result is NaN.
* <li> If the argument is positive or negative infinity, then the
* result is positive infinity.
* <li> If the argument is positive or negative zero, then the result is
* {@code Float.MIN_VALUE}.
* <li> If the argument is &plusmn;{@code Float.MAX_VALUE}, then
* the result is equal to 2<sup>104</sup>.
* </ul>
*
* @param f the floating-point value whose ulp is to be returned
* @return the size of an ulp of the argument
* @author Joseph D. Darcy
* @since 1.5
* @deprecated Use Math.ulp.
*/
@Deprecated
public static float ulp(float f) {
return Math.ulp(f);
}
/**
* Returns the signum function of the argument; zero if the argument
* is zero, 1.0 if the argument is greater than zero, -1.0 if the
* argument is less than zero.
*
* <p>Special Cases:
* <ul>
* <li> If the argument is NaN, then the result is NaN.
* <li> If the argument is positive zero or negative zero, then the
* result is the same as the argument.
* </ul>
*
* @param d the floating-point value whose signum is to be returned
* @return the signum function of the argument
* @author Joseph D. Darcy
* @since 1.5
* @deprecated Use Math.signum.
*/
@Deprecated
public static double signum(double d) {
return Math.signum(d);
}
/**
* Returns the signum function of the argument; zero if the argument
* is zero, 1.0f if the argument is greater than zero, -1.0f if the
* argument is less than zero.
*
* <p>Special Cases:
* <ul>
* <li> If the argument is NaN, then the result is NaN.
* <li> If the argument is positive zero or negative zero, then the
* result is the same as the argument.
* </ul>
*
* @param f the floating-point value whose signum is to be returned
* @return the signum function of the argument
* @author Joseph D. Darcy
* @since 1.5
* @deprecated Use Math.signum.
*/
@Deprecated
public static float signum(float f) {
return Math.signum(f);
}
}

View File

@@ -0,0 +1,284 @@
/*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* Support for garbage-collection latency requests.
*
* @author Mark Reinhold
* @since 1.2
*/
public class GC {
private GC() { } /* To prevent instantiation */
/* Latency-target value indicating that there's no active target
*/
private static final long NO_TARGET = Long.MAX_VALUE;
/* The current latency target, or NO_TARGET if there is no target
*/
private static long latencyTarget = NO_TARGET;
/* The daemon thread that implements the latency-target mechanism,
* or null if there is presently no daemon thread
*/
private static Thread daemon = null;
/* The lock object for the latencyTarget and daemon fields. The daemon
* thread, if it exists, waits on this lock for notification that the
* latency target has changed.
*/
private static class LatencyLock extends Object { };
private static Object lock = new LatencyLock();
/**
* Returns the maximum <em>object-inspection age</em>, which is the number
* of real-time milliseconds that have elapsed since the
* least-recently-inspected heap object was last inspected by the garbage
* collector.
*
* <p> For simple stop-the-world collectors this value is just the time
* since the most recent collection. For generational collectors it is the
* time since the oldest generation was most recently collected. Other
* collectors are free to return a pessimistic estimate of the elapsed
* time, or simply the time since the last full collection was performed.
*
* <p> Note that in the presence of reference objects, a given object that
* is no longer strongly reachable may have to be inspected multiple times
* before it can be reclaimed.
*/
public static native long maxObjectInspectionAge();
private static class Daemon extends Thread {
public void run() {
for (;;) {
long l;
synchronized (lock) {
l = latencyTarget;
if (l == NO_TARGET) {
/* No latency target, so exit */
GC.daemon = null;
return;
}
long d = maxObjectInspectionAge();
if (d >= l) {
/* Do a full collection. There is a remote possibility
* that a full collection will occurr between the time
* we sample the inspection age and the time the GC
* actually starts, but this is sufficiently unlikely
* that it doesn't seem worth the more expensive JVM
* interface that would be required.
*/
System.gc();
d = 0;
}
/* Wait for the latency period to expire,
* or for notification that the period has changed
*/
try {
lock.wait(l - d);
} catch (InterruptedException x) {
continue;
}
}
}
}
private Daemon(ThreadGroup tg) {
super(tg, "GC Daemon");
}
/* Create a new daemon thread in the root thread group */
public static void create() {
PrivilegedAction<Void> pa = new PrivilegedAction<Void>() {
public Void run() {
ThreadGroup tg = Thread.currentThread().getThreadGroup();
for (ThreadGroup tgn = tg;
tgn != null;
tg = tgn, tgn = tg.getParent());
Daemon d = new Daemon(tg);
d.setDaemon(true);
d.setPriority(Thread.MIN_PRIORITY + 1);
d.start();
GC.daemon = d;
return null;
}};
AccessController.doPrivileged(pa);
}
}
/* Sets the latency target to the given value.
* Must be invoked while holding the lock.
*/
private static void setLatencyTarget(long ms) {
latencyTarget = ms;
if (daemon == null) {
/* Create a new daemon thread */
Daemon.create();
} else {
/* Notify the existing daemon thread
* that the lateency target has changed
*/
lock.notify();
}
}
/**
* Represents an active garbage-collection latency request. Instances of
* this class are created by the <code>{@link #requestLatency}</code>
* method. Given a request, the only interesting operation is that of
* cancellation.
*/
public static class LatencyRequest
implements Comparable<LatencyRequest> {
/* Instance counter, used to generate unique identifers */
private static long counter = 0;
/* Sorted set of active latency requests */
private static SortedSet<LatencyRequest> requests = null;
/* Examine the request set and reset the latency target if necessary.
* Must be invoked while holding the lock.
*/
private static void adjustLatencyIfNeeded() {
if ((requests == null) || requests.isEmpty()) {
if (latencyTarget != NO_TARGET) {
setLatencyTarget(NO_TARGET);
}
} else {
LatencyRequest r = requests.first();
if (r.latency != latencyTarget) {
setLatencyTarget(r.latency);
}
}
}
/* The requested latency, or NO_TARGET
* if this request has been cancelled
*/
private long latency;
/* Unique identifier for this request */
private long id;
private LatencyRequest(long ms) {
if (ms <= 0) {
throw new IllegalArgumentException("Non-positive latency: "
+ ms);
}
this.latency = ms;
synchronized (lock) {
this.id = ++counter;
if (requests == null) {
requests = new TreeSet<LatencyRequest>();
}
requests.add(this);
adjustLatencyIfNeeded();
}
}
/**
* Cancels this latency request.
*
* @throws IllegalStateException
* If this request has already been cancelled
*/
public void cancel() {
synchronized (lock) {
if (this.latency == NO_TARGET) {
throw new IllegalStateException("Request already"
+ " cancelled");
}
if (!requests.remove(this)) {
throw new InternalError("Latency request "
+ this + " not found");
}
if (requests.isEmpty()) requests = null;
this.latency = NO_TARGET;
adjustLatencyIfNeeded();
}
}
public int compareTo(LatencyRequest r) {
long d = this.latency - r.latency;
if (d == 0) d = this.id - r.id;
return (d < 0) ? -1 : ((d > 0) ? +1 : 0);
}
public String toString() {
return (LatencyRequest.class.getName()
+ "[" + latency + "," + id + "]");
}
}
/**
* Makes a new request for a garbage-collection latency of the given
* number of real-time milliseconds. A low-priority daemon thread makes a
* best effort to ensure that the maximum object-inspection age never
* exceeds the smallest of the currently active requests.
*
* @param latency
* The requested latency
*
* @throws IllegalArgumentException
* If the given <code>latency</code> is non-positive
*/
public static LatencyRequest requestLatency(long latency) {
return new LatencyRequest(latency);
}
/**
* Returns the current smallest garbage-collection latency request, or zero
* if there are no active requests.
*/
public static long currentLatencyTarget() {
long t = latencyTarget;
return (t == NO_TARGET) ? 0 : t;
}
}

View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 1995, 1997, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.PrintStream;
import java.io.OutputStream;
import java.io.IOException;
/**
* This class encodes a buffer into the classic: "Hexadecimal Dump" format of
* the past. It is useful for analyzing the contents of binary buffers.
* The format produced is as follows:
* <pre>
* xxxx: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ................
* </pre>
* Where xxxx is the offset into the buffer in 16 byte chunks, followed
* by ascii coded hexadecimal bytes followed by the ASCII representation of
* the bytes or '.' if they are not valid bytes.
*
* @author Chuck McManis
*/
public class HexDumpEncoder extends CharacterEncoder {
private int offset;
private int thisLineLength;
private int currentByte;
private byte thisLine[] = new byte[16];
static void hexDigit(PrintStream p, byte x) {
char c;
c = (char) ((x >> 4) & 0xf);
if (c > 9)
c = (char) ((c-10) + 'A');
else
c = (char)(c + '0');
p.write(c);
c = (char) (x & 0xf);
if (c > 9)
c = (char)((c-10) + 'A');
else
c = (char)(c + '0');
p.write(c);
}
protected int bytesPerAtom() {
return (1);
}
protected int bytesPerLine() {
return (16);
}
protected void encodeBufferPrefix(OutputStream o) throws IOException {
offset = 0;
super.encodeBufferPrefix(o);
}
protected void encodeLinePrefix(OutputStream o, int len) throws IOException {
hexDigit(pStream, (byte)((offset >>> 8) & 0xff));
hexDigit(pStream, (byte)(offset & 0xff));
pStream.print(": ");
currentByte = 0;
thisLineLength = len;
}
protected void encodeAtom(OutputStream o, byte buf[], int off, int len) throws IOException {
thisLine[currentByte] = buf[off];
hexDigit(pStream, buf[off]);
pStream.print(" ");
currentByte++;
if (currentByte == 8)
pStream.print(" ");
}
protected void encodeLineSuffix(OutputStream o) throws IOException {
if (thisLineLength < 16) {
for (int i = thisLineLength; i < 16; i++) {
pStream.print(" ");
if (i == 7)
pStream.print(" ");
}
}
pStream.print(" ");
for (int i = 0; i < thisLineLength; i++) {
if ((thisLine[i] < ' ') || (thisLine[i] > 'z')) {
pStream.print(".");
} else {
pStream.write(thisLine[i]);
}
}
pStream.println();
offset += thisLineLength;
}
}

View File

@@ -0,0 +1,313 @@
/*
* Copyright (c) 2009, 2019, 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.
*/
/**
* IOUtils: A collection of IO-related public static methods.
*/
package sun.misc;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
public class IOUtils {
private static final int DEFAULT_BUFFER_SIZE = 8192;
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
/**
* Read exactly {@code length} of bytes from {@code in}.
*
* <p> Note that this method is safe to be called with unknown large
* {@code length} argument. The memory used is proportional to the
* actual bytes available. An exception is thrown if there are not
* enough bytes in the stream.
*
* @param is input stream, must not be null
* @param length number of bytes to read
* @return bytes read
* @throws EOFException if there are not enough bytes in the stream
* @throws IOException if an I/O error occurs or {@code length} is negative
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated.
*/
public static byte[] readExactlyNBytes(InputStream is, int length)
throws IOException {
if (length < 0) {
throw new IOException("length cannot be negative: " + length);
}
byte[] data = readNBytes(is, length);
if (data.length < length) {
throw new EOFException();
}
return data;
}
/**
* Reads all remaining bytes from the input stream. This method blocks until
* all remaining bytes have been read and end of stream is detected, or an
* exception is thrown. This method does not close the input stream.
*
* <p> When this stream reaches end of stream, further invocations of this
* method will return an empty byte array.
*
* <p> Note that this method is intended for simple cases where it is
* convenient to read all bytes into a byte array. It is not intended for
* reading input streams with large amounts of data.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> If an I/O error occurs reading from the input stream, then it may do
* so after some, but not all, bytes have been read. Consequently the input
* stream may not be at end of stream and may be in an inconsistent state.
* It is strongly recommended that the stream be promptly closed if an I/O
* error occurs.
*
* @implSpec
* This method invokes {@link #readNBytes(int)} with a length of
* {@link Integer#MAX_VALUE}.
*
* @param is input stream, must not be null
* @return a byte array containing the bytes read from this input stream
* @throws IOException if an I/O error occurs
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated.
*
* @since 1.9
*/
public static byte[] readAllBytes(InputStream is) throws IOException {
return readNBytes(is, Integer.MAX_VALUE);
}
/**
* Reads up to a specified number of bytes from the input stream. This
* method blocks until the requested number of bytes have been read, end
* of stream is detected, or an exception is thrown. This method does not
* close the input stream.
*
* <p> The length of the returned array equals the number of bytes read
* from the stream. If {@code len} is zero, then no bytes are read and
* an empty byte array is returned. Otherwise, up to {@code len} bytes
* are read from the stream. Fewer than {@code len} bytes may be read if
* end of stream is encountered.
*
* <p> When this stream reaches end of stream, further invocations of this
* method will return an empty byte array.
*
* <p> Note that this method is intended for simple cases where it is
* convenient to read the specified number of bytes into a byte array. The
* total amount of memory allocated by this method is proportional to the
* number of bytes read from the stream which is bounded by {@code len}.
* Therefore, the method may be safely called with very large values of
* {@code len} provided sufficient memory is available.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> If an I/O error occurs reading from the input stream, then it may do
* so after some, but not all, bytes have been read. Consequently the input
* stream may not be at end of stream and may be in an inconsistent state.
* It is strongly recommended that the stream be promptly closed if an I/O
* error occurs.
*
* @implNote
* The number of bytes allocated to read data from this stream and return
* the result is bounded by {@code 2*(long)len}, inclusive.
*
* @param is input stream, must not be null
* @param len the maximum number of bytes to read
* @return a byte array containing the bytes read from this input stream
* @throws IllegalArgumentException if {@code length} is negative
* @throws IOException if an I/O error occurs
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated.
*
* @since 11
*/
public static byte[] readNBytes(InputStream is, int len) throws IOException {
if (len < 0) {
throw new IllegalArgumentException("len < 0");
}
List<byte[]> bufs = null;
byte[] result = null;
int total = 0;
int remaining = len;
int n;
do {
byte[] buf = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)];
int nread = 0;
// read to EOF which may read more or less than buffer size
while ((n = is.read(buf, nread,
Math.min(buf.length - nread, remaining))) > 0) {
nread += n;
remaining -= n;
}
if (nread > 0) {
if (MAX_BUFFER_SIZE - total < nread) {
throw new OutOfMemoryError("Required array size too large");
}
total += nread;
if (result == null) {
result = buf;
} else {
if (bufs == null) {
bufs = new ArrayList<>();
bufs.add(result);
}
bufs.add(buf);
}
}
// if the last call to read returned -1 or the number of bytes
// requested have been read then break
} while (n >= 0 && remaining > 0);
if (bufs == null) {
if (result == null) {
return new byte[0];
}
return result.length == total ?
result : Arrays.copyOf(result, total);
}
result = new byte[total];
int offset = 0;
remaining = total;
for (byte[] b : bufs) {
int count = Math.min(b.length, remaining);
System.arraycopy(b, 0, result, offset, count);
offset += count;
remaining -= count;
}
return result;
}
/**
* Reads the requested number of bytes from the input stream into the given
* byte array. This method blocks until {@code len} bytes of input data have
* been read, end of stream is detected, or an exception is thrown. The
* number of bytes actually read, possibly zero, is returned. This method
* does not close the input stream.
*
* <p> In the case where end of stream is reached before {@code len} bytes
* have been read, then the actual number of bytes read will be returned.
* When this stream reaches end of stream, further invocations of this
* method will return zero.
*
* <p> If {@code len} is zero, then no bytes are read and {@code 0} is
* returned; otherwise, there is an attempt to read up to {@code len} bytes.
*
* <p> The first byte read is stored into element {@code b[off]}, the next
* one in to {@code b[off+1]}, and so on. The number of bytes read is, at
* most, equal to {@code len}. Let <i>k</i> be the number of bytes actually
* read; these bytes will be stored in elements {@code b[off]} through
* {@code b[off+}<i>k</i>{@code -1]}, leaving elements {@code b[off+}<i>k</i>
* {@code ]} through {@code b[off+len-1]} unaffected.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> If an I/O error occurs reading from the input stream, then it may do
* so after some, but not all, bytes of {@code b} have been updated with
* data from the input stream. Consequently the input stream and {@code b}
* may be in an inconsistent state. It is strongly recommended that the
* stream be promptly closed if an I/O error occurs.
*
* @param is input stream, must not be null
* @param b the byte array into which the data is read
* @param off the start offset in {@code b} at which the data is written
* @param len the maximum number of bytes to read
* @return the actual number of bytes read into the buffer
* @throws IOException if an I/O error occurs
* @throws NullPointerException if {@code b} is {@code null}
* @throws IndexOutOfBoundsException If {@code off} is negative, {@code len}
* is negative, or {@code len} is greater than {@code b.length - off}
*
* @since 1.9
*/
public static int readNBytes(InputStream is, byte[] b, int off, int len) throws IOException {
Objects.requireNonNull(b);
if (off < 0 || len < 0 || len > b.length - off)
throw new IndexOutOfBoundsException();
int n = 0;
while (n < len) {
int count = is.read(b, off + n, len - n);
if (count < 0)
break;
n += count;
}
return n;
}
/**
* Compatibility wrapper for third party users of
* {@code sun.misc.IOUtils.readFully} following its
* removal in JDK-8231139.
*
* Read up to {@code length} of bytes from {@code in}
* until EOF is detected.
*
* @param is input stream, must not be null
* @param length number of bytes to read
* @param readAll if true, an EOFException will be thrown if not enough
* bytes are read.
* @return bytes read
* @throws EOFException if there are not enough bytes in the stream
* @throws IOException if an I/O error occurs or {@code length} is negative
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated.
*/
public static byte[] readFully(InputStream is, int length, boolean readAll)
throws IOException {
if (length < 0) {
throw new IOException("length cannot be negative: " + length);
}
if (readAll) {
return readExactlyNBytes(is, length);
} else {
return readNBytes(is, length);
}
}
}

View File

@@ -0,0 +1,168 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.ProtectionDomain;
import java.security.PrivilegedAction;
import java.util.concurrent.atomic.AtomicInteger;
/**
* A thread that has no permissions, is not a member of any user-defined
* ThreadGroup and supports the ability to erase ThreadLocals.
*
* @implNote Based on the implementation of InnocuousForkJoinWorkerThread.
*/
public final class InnocuousThread extends Thread {
private static final Unsafe UNSAFE;
private static final long THREAD_LOCALS;
private static final long INHERITABLE_THREAD_LOCALS;
private static final ThreadGroup INNOCUOUSTHREADGROUP;
private static final AccessControlContext ACC;
private static final long INHERITEDACCESSCONTROLCONTEXT;
private static final long CONTEXTCLASSLOADER;
private static final AtomicInteger threadNumber = new AtomicInteger(1);
private static String newName() {
return "InnocuousThread-" + threadNumber.getAndIncrement();
}
/**
* Returns a new InnocuousThread with an auto-generated thread name.
* Its context class loader is set to null.
*/
public static Thread newSystemThread(Runnable target) {
return newSystemThread(newName(), target);
}
/**
* Returns a new InnocuousThread with null context class loader.
*/
public static Thread newSystemThread(String name, Runnable target) {
return AccessController.doPrivileged(
new PrivilegedAction<Thread>() {
@Override
public Thread run() {
return new InnocuousThread(INNOCUOUSTHREADGROUP,
target, name, null);
}
});
}
public InnocuousThread(Runnable target) {
super(INNOCUOUSTHREADGROUP, target, newName());
UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
eraseThreadLocals();
}
private InnocuousThread(ThreadGroup group, Runnable target, String name, ClassLoader tccl) {
super(group, target, name, 0L);
UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, tccl);
eraseThreadLocals();
}
@Override
public ClassLoader getContextClassLoader() {
// always report system class loader
return ClassLoader.getSystemClassLoader();
}
@Override
public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) {
// silently fail
}
@Override
public void setContextClassLoader(ClassLoader cl) {
throw new SecurityException("setContextClassLoader");
}
// ensure run method is run only once
private volatile boolean hasRun;
@Override
public void run() {
if (Thread.currentThread() == this && !hasRun) {
hasRun = true;
super.run();
}
}
/**
* Drops all thread locals (and inherited thread locals).
*/
public void eraseThreadLocals() {
UNSAFE.putObject(this, THREAD_LOCALS, null);
UNSAFE.putObject(this, INHERITABLE_THREAD_LOCALS, null);
}
// Use Unsafe to access Thread group and ThreadGroup parent fields
static {
try {
ACC = new AccessControlContext(new ProtectionDomain[] {
new ProtectionDomain(null, null)
});
// Find and use topmost ThreadGroup as parent of new group
UNSAFE = Unsafe.getUnsafe();
Class<?> tk = Thread.class;
Class<?> gk = ThreadGroup.class;
THREAD_LOCALS = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocals"));
INHERITABLE_THREAD_LOCALS = UNSAFE.objectFieldOffset
(tk.getDeclaredField("inheritableThreadLocals"));
INHERITEDACCESSCONTROLCONTEXT = UNSAFE.objectFieldOffset
(tk.getDeclaredField("inheritedAccessControlContext"));
CONTEXTCLASSLOADER = UNSAFE.objectFieldOffset
(tk.getDeclaredField("contextClassLoader"));
long tg = UNSAFE.objectFieldOffset(tk.getDeclaredField("group"));
long gp = UNSAFE.objectFieldOffset(gk.getDeclaredField("parent"));
ThreadGroup group = (ThreadGroup)
UNSAFE.getObject(Thread.currentThread(), tg);
while (group != null) {
ThreadGroup parent = (ThreadGroup)UNSAFE.getObject(group, gp);
if (parent == null)
break;
group = parent;
}
final ThreadGroup root = group;
INNOCUOUSTHREADGROUP = AccessController.doPrivileged(
new PrivilegedAction<ThreadGroup>() {
@Override
public ThreadGroup run() {
return new ThreadGroup(root, "InnocuousThreadGroup");
}
});
} catch (Exception e) {
throw new Error(e);
}
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.lang.LinkageError;
/**
* Thrown if the URLClassLoader finds the INDEX.LIST file of
* a jar file contains incorrect information.
*
* @author Zhenghua Li
* @since 1.3
*/
public
class InvalidJarIndexException extends RuntimeException {
static final long serialVersionUID = -6159797516569680148L;
/**
* Constructs an <code>InvalidJarIndexException</code> with no
* detail message.
*/
public InvalidJarIndexException() {
super();
}
/**
* Constructs an <code>InvalidJarIndexException</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public InvalidJarIndexException(String s) {
super(s);
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.File;
import java.io.FilenameFilter;
/**
* <p>
* This class checks that only jar and zip files are included in the file list.
* This class is used in extension installation support (ExtensionDependency).
* <p>
*
* @author Michael Colburn
*/
public class JarFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
String lower = name.toLowerCase();
return lower.endsWith(".jar") || lower.endsWith(".zip");
}
}

View File

@@ -0,0 +1,356 @@
/*
* Copyright (c) 1999, 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.
*/
package sun.misc;
import java.io.*;
import java.security.AccessController;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;
import sun.security.action.GetPropertyAction;
/**
* This class is used to maintain mappings from packages, classes
* and resources to their enclosing JAR files. Mappings are kept
* at the package level except for class or resource files that
* are located at the root directory. URLClassLoader uses the mapping
* information to determine where to fetch an extension class or
* resource from.
*
* @author Zhenghua Li
* @since 1.3
*/
public class JarIndex {
/**
* The hash map that maintains mappings from
* package/classe/resource to jar file list(s)
*/
private HashMap<String,LinkedList<String>> indexMap;
/**
* The hash map that maintains mappings from
* jar file to package/class/resource lists
*/
private HashMap<String,LinkedList<String>> jarMap;
/*
* An ordered list of jar file names.
*/
private String[] jarFiles;
/**
* The index file name.
*/
public static final String INDEX_NAME = "META-INF/INDEX.LIST";
/**
* true if, and only if, sun.misc.JarIndex.metaInfFilenames is set to true.
* If true, the names of the files in META-INF, and its subdirectories, will
* be added to the index. Otherwise, just the directory names are added.
*/
private static final boolean metaInfFilenames =
"true".equals(AccessController.doPrivileged(
new GetPropertyAction("sun.misc.JarIndex.metaInfFilenames")));
/**
* Constructs a new, empty jar index.
*/
public JarIndex() {
indexMap = new HashMap<>();
jarMap = new HashMap<>();
}
/**
* Constructs a new index from the specified input stream.
*
* @param is the input stream containing the index data
*/
public JarIndex(InputStream is) throws IOException {
this();
read(is);
}
/**
* Constructs a new index for the specified list of jar files.
*
* @param files the list of jar files to construct the index from.
*/
public JarIndex(String[] files) throws IOException {
this();
this.jarFiles = files;
parseJars(files);
}
/**
* Returns the jar index, or <code>null</code> if none.
*
* This single parameter version of the method is retained
* for binary compatibility with earlier releases.
*
* @param jar the JAR file to get the index from.
* @exception IOException if an I/O error has occurred.
*/
public static JarIndex getJarIndex(JarFile jar) throws IOException {
return getJarIndex(jar, null);
}
/**
* Returns the jar index, or <code>null</code> if none.
*
* @param jar the JAR file to get the index from.
* @exception IOException if an I/O error has occurred.
*/
public static JarIndex getJarIndex(JarFile jar, MetaIndex metaIndex) throws IOException {
JarIndex index = null;
/* If metaIndex is not null, check the meta index to see
if META-INF/INDEX.LIST is contained in jar file or not.
*/
if (metaIndex != null &&
!metaIndex.mayContain(INDEX_NAME)) {
return null;
}
JarEntry e = jar.getJarEntry(INDEX_NAME);
// if found, then load the index
if (e != null) {
index = new JarIndex(jar.getInputStream(e));
}
return index;
}
/**
* Returns the jar files that are defined in this index.
*/
public String[] getJarFiles() {
return jarFiles;
}
/*
* Add the key, value pair to the hashmap, the value will
* be put in a linked list which is created if necessary.
*/
private void addToList(String key, String value,
HashMap<String,LinkedList<String>> t) {
LinkedList<String> list = t.get(key);
if (list == null) {
list = new LinkedList<>();
list.add(value);
t.put(key, list);
} else if (!list.contains(value)) {
list.add(value);
}
}
/**
* Returns the list of jar files that are mapped to the file.
*
* @param fileName the key of the mapping
*/
public LinkedList<String> get(String fileName) {
LinkedList<String> jarFiles = null;
if ((jarFiles = indexMap.get(fileName)) == null) {
/* try the package name again */
int pos;
if((pos = fileName.lastIndexOf("/")) != -1) {
jarFiles = indexMap.get(fileName.substring(0, pos));
}
}
return jarFiles;
}
/**
* Add the mapping from the specified file to the specified
* jar file. If there were no mapping for the package of the
* specified file before, a new linked list will be created,
* the jar file is added to the list and a new mapping from
* the package to the jar file list is added to the hashmap.
* Otherwise, the jar file will be added to the end of the
* existing list.
*
* @param fileName the file name
* @param jarName the jar file that the file is mapped to
*
*/
public void add(String fileName, String jarName) {
String packageName;
int pos;
if((pos = fileName.lastIndexOf("/")) != -1) {
packageName = fileName.substring(0, pos);
} else {
packageName = fileName;
}
addMapping(packageName, jarName);
}
/**
* Same as add(String,String) except that it doesn't strip off from the
* last index of '/'. It just adds the jarItem (filename or package)
* as it is received.
*/
private void addMapping(String jarItem, String jarName) {
// add the mapping to indexMap
addToList(jarItem, jarName, indexMap);
// add the mapping to jarMap
addToList(jarName, jarItem, jarMap);
}
/**
* Go through all the jar files and construct the
* index table.
*/
private void parseJars(String[] files) throws IOException {
if (files == null) {
return;
}
String currentJar = null;
for (int i = 0; i < files.length; i++) {
currentJar = files[i];
ZipFile zrf = new ZipFile(currentJar.replace
('/', File.separatorChar));
Enumeration<? extends ZipEntry> entries = zrf.entries();
while(entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String fileName = entry.getName();
// Skip the META-INF directory, the index, and manifest.
// Any files in META-INF/ will be indexed explicitly
if (fileName.equals("META-INF/") ||
fileName.equals(INDEX_NAME) ||
fileName.equals(JarFile.MANIFEST_NAME))
continue;
if (!metaInfFilenames || !fileName.startsWith("META-INF/")) {
add(fileName, currentJar);
} else if (!entry.isDirectory()) {
// Add files under META-INF explicitly so that certain
// services, like ServiceLoader, etc, can be located
// with greater accuracy. Directories can be skipped
// since each file will be added explicitly.
addMapping(fileName, currentJar);
}
}
zrf.close();
}
}
/**
* Writes the index to the specified OutputStream
*
* @param out the output stream
* @exception IOException if an I/O error has occurred
*/
public void write(OutputStream out) throws IOException {
BufferedWriter bw = new BufferedWriter
(new OutputStreamWriter(out, "UTF8"));
bw.write("JarIndex-Version: 1.0\n\n");
if (jarFiles != null) {
for (int i = 0; i < jarFiles.length; i++) {
/* print out the jar file name */
String jar = jarFiles[i];
bw.write(jar + "\n");
LinkedList<String> jarlist = jarMap.get(jar);
if (jarlist != null) {
Iterator<String> listitr = jarlist.iterator();
while(listitr.hasNext()) {
bw.write(listitr.next() + "\n");
}
}
bw.write("\n");
}
bw.flush();
}
}
/**
* Reads the index from the specified InputStream.
*
* @param is the input stream
* @exception IOException if an I/O error has occurred
*/
public void read(InputStream is) throws IOException {
BufferedReader br = new BufferedReader
(new InputStreamReader(is, "UTF8"));
String line = null;
String currentJar = null;
/* an ordered list of jar file names */
Vector<String> jars = new Vector<>();
/* read until we see a .jar line */
while((line = br.readLine()) != null && !line.endsWith(".jar"));
for(;line != null; line = br.readLine()) {
if (line.length() == 0)
continue;
if (line.endsWith(".jar")) {
currentJar = line;
jars.add(currentJar);
} else {
String name = line;
addMapping(name, currentJar);
}
}
jarFiles = jars.toArray(new String[jars.size()]);
}
/**
* Merges the current index into another index, taking into account
* the relative path of the current index.
*
* @param toIndex The destination index which the current index will
* merge into.
* @param path The relative path of the this index to the destination
* index.
*
*/
public void merge(JarIndex toIndex, String path) {
Iterator<Map.Entry<String,LinkedList<String>>> itr = indexMap.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry<String,LinkedList<String>> e = itr.next();
String packageName = e.getKey();
LinkedList<String> from_list = e.getValue();
Iterator<String> listItr = from_list.iterator();
while(listItr.hasNext()) {
String jarName = listItr.next();
if (path != null) {
jarName = path.concat(jarName);
}
toIndex.addMapping(packageName, jarName);
}
}
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
public interface JavaAWTAccess {
// Returns the AppContext used for applet logging isolation, or null if
// no isolation is required.
// If there's no applet, or if the caller is a stand alone application,
// or running in the main app context, returns null.
// Otherwise, returns the AppContext of the calling applet.
public Object getAppletContext();
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.Console;
import java.nio.charset.Charset;
public interface JavaIOAccess {
public Console console();
public Charset charset();
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.FileDescriptor;
/*
* @author Chris Hegarty
*/
public interface JavaIOFileDescriptorAccess {
public void set(FileDescriptor obj, int fd);
public int get(FileDescriptor fd);
// Only valid on Windows
public void setHandle(FileDescriptor obj, long handle);
public long getHandle(FileDescriptor obj);
}

View File

@@ -0,0 +1,135 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.lang.annotation.Annotation;
import java.lang.reflect.Executable;
import java.security.AccessControlContext;
import java.util.Map;
import sun.reflect.ConstantPool;
import sun.reflect.annotation.AnnotationType;
import sun.nio.ch.Interruptible;
public interface JavaLangAccess {
/** Return the constant pool for a class. */
ConstantPool getConstantPool(Class<?> klass);
/**
* Compare-And-Swap the AnnotationType instance corresponding to this class.
* (This method only applies to annotation types.)
*/
boolean casAnnotationType(Class<?> klass, AnnotationType oldType, AnnotationType newType);
/**
* Get the AnnotationType instance corresponding to this class.
* (This method only applies to annotation types.)
*/
AnnotationType getAnnotationType(Class<?> klass);
/**
* Get the declared annotations for a given class, indexed by their types.
*/
Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationMap(Class<?> klass);
/**
* Get the array of bytes that is the class-file representation
* of this Class' annotations.
*/
byte[] getRawClassAnnotations(Class<?> klass);
/**
* Get the array of bytes that is the class-file representation
* of this Class' type annotations.
*/
byte[] getRawClassTypeAnnotations(Class<?> klass);
/**
* Get the array of bytes that is the class-file representation
* of this Executable's type annotations.
*/
byte[] getRawExecutableTypeAnnotations(Executable executable);
/**
* Returns the elements of an enum class or null if the
* Class object does not represent an enum type;
* the result is uncloned, cached, and shared by all callers.
*/
<E extends Enum<E>> E[] getEnumConstantsShared(Class<E> klass);
/** Set thread's blocker field. */
void blockedOn(Thread t, Interruptible b);
/**
* Registers a shutdown hook.
*
* It is expected that this method with registerShutdownInProgress=true
* is only used to register DeleteOnExitHook since the first file
* may be added to the delete on exit list by the application shutdown
* hooks.
*
* @params slot the slot in the shutdown hook array, whose element
* will be invoked in order during shutdown
* @params registerShutdownInProgress true to allow the hook
* to be registered even if the shutdown is in progress.
* @params hook the hook to be registered
*
* @throw IllegalStateException if shutdown is in progress and
* the slot is not valid to register.
*/
void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook);
/**
* Returns the number of stack frames represented by the given throwable.
*/
int getStackTraceDepth(Throwable t);
/**
* Returns the ith StackTraceElement for the given throwable.
*/
StackTraceElement getStackTraceElement(Throwable t, int i);
/**
* Returns a new string backed by the provided character array. The
* character array is not copied and must never be modified after the
* String is created, in order to fulfill String's contract.
*
* @param chars the character array to back the string
* @return a newly created string whose content is the character array
*/
String newStringUnsafe(char[] chars);
/**
* Returns a new Thread with the given Runnable and an
* inherited AccessControlContext.
*/
Thread newThreadWithAcc(Runnable target, AccessControlContext acc);
/**
* Invokes the finalize method of the given object.
*/
void invokeFinalize(Object o) throws Throwable;
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
public interface JavaLangRefAccess {
/**
* Help ReferenceHandler thread process next pending
* {@link java.lang.ref.Reference}
*
* @return {@code true} if there was a pending reference and it
* was enqueue-ed or {@code false} if there was no
* pending reference
*/
boolean tryHandlePendingReference();
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2006, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.net.URLClassLoader;
import java.net.InetAddress;
public interface JavaNetAccess {
/**
* return the URLClassPath belonging to the given loader
*/
URLClassPath getURLClassPath (URLClassLoader u);
/**
* Return the original application specified hostname of
* the given InetAddress object.
*/
String getOriginalHostName(InetAddress ia);
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.net.HttpCookie;
import java.util.List;
public interface JavaNetHttpCookieAccess {
/*
* Constructs cookies from Set-Cookie or Set-Cookie2 header string,
* retaining the original header String in the cookie itself.
*/
public List<HttpCookie> parse(String header);
/*
* Returns the original header this cookie was consructed from, if it was
* constructed by parsing a header, otherwise null.
*/
public String header(HttpCookie cookie);
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.nio.Buffer;
import java.nio.ByteBuffer;
public interface JavaNioAccess {
/**
* Provides access to information on buffer usage.
*/
interface BufferPool {
String getName();
long getCount();
long getTotalCapacity();
long getMemoryUsed();
}
BufferPool getDirectBufferPool();
/**
* Constructs a direct ByteBuffer referring to the block of memory starting
* at the given memory address and and extending {@code cap} bytes.
* The {@code ob} parameter is an arbitrary object that is attached
* to the resulting buffer.
*/
ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob);
/**
* Truncates a buffer by changing its capacity to 0.
*/
void truncate(Buffer buf);
}

View File

@@ -0,0 +1,36 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
public interface JavaOISAccess {
void setObjectInputFilter(ObjectInputStream stream, ObjectInputFilter filter);
ObjectInputFilter getObjectInputFilter(ObjectInputStream stream);
void checkArray(ObjectInputStream stream, Class<?> arrayType, int arrayLength)
throws InvalidClassException;
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.ObjectInputStream;
/**
* The interface to specify methods for accessing {@code ObjectInputStream}
* @author sjiang
*/
public interface JavaObjectInputStreamAccess {
/**
* Sets a descriptor validating.
* @param ois stream to have the descriptors validated
* @param validator validator used to validate a descriptor.
*/
public void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator);
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* Interface to specify methods for accessing {@code ObjectInputStream}.
*/
@FunctionalInterface
public interface JavaObjectInputStreamReadString {
String readString(ObjectInputStream ois) throws IOException;
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
public interface JavaSecurityAccess {
<T> T doIntersectionPrivilege(PrivilegedAction<T> action,
AccessControlContext stack,
AccessControlContext context);
<T> T doIntersectionPrivilege(PrivilegedAction<T> action,
AccessControlContext context);
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.security.PermissionCollection;
import java.security.ProtectionDomain;
public interface JavaSecurityProtectionDomainAccess {
interface ProtectionDomainCache {
void put(ProtectionDomain pd, PermissionCollection pc);
PermissionCollection get(ProtectionDomain pd);
}
/**
* Returns the ProtectionDomainCache.
*/
ProtectionDomainCache getProtectionDomainCache();
/**
* Returns the staticPermissions field of the specified object
*/
boolean getStaticPermissionsField(ProtectionDomain pd);
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
public interface JavaSecuritySignatureAccess {
void initVerify(Signature s, PublicKey publicKey, AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException;
void initVerify(Signature s, java.security.cert.Certificate certificate,
AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException;
void initSign(Signature s, PrivateKey privateKey,
AlgorithmParameterSpec params, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException;
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.IOException;
import java.net.URL;
import java.security.CodeSource;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
public interface JavaUtilJarAccess {
public boolean jarFileHasClassPathAttribute(JarFile jar) throws IOException;
public CodeSource[] getCodeSources(JarFile jar, URL url);
public CodeSource getCodeSource(JarFile jar, URL url, String name);
public Enumeration<String> entryNames(JarFile jar, CodeSource[] cs);
public Enumeration<JarEntry> entries2(JarFile jar);
public void setEagerValidation(JarFile jar, boolean eager);
public List<Object> getManifestDigests(JarFile jar);
public Attributes getTrustedAttributes(Manifest man, String name);
public void ensureInitialization(JarFile jar);
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.util.jar.JarFile;
import java.util.zip.ZipFile;
public interface JavaUtilZipFileAccess {
public boolean startsWithLocHeader(ZipFile zip);
public int getManifestNum(JarFile zip);
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SealedObject;
import java.io.IOException;
import java.io.ObjectInputStream;
public interface JavaxCryptoSealedObjectAccess {
ObjectInputStream getExtObjectInputStream(
SealedObject sealed, Cipher cipher)
throws BadPaddingException, IllegalBlockSizeException, IOException;
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* Utility class for small LRU caches.
*
* @author Mark Reinhold
*/
public abstract class LRUCache<N,V> {
private V[] oa = null;
private final int size;
public LRUCache(int size) {
this.size = size;
}
abstract protected V create(N name);
abstract protected boolean hasName(V ob, N name);
public static void moveToFront(Object[] oa, int i) {
Object ob = oa[i];
for (int j = i; j > 0; j--)
oa[j] = oa[j - 1];
oa[0] = ob;
}
public V forName(N name) {
if (oa == null) {
@SuppressWarnings("unchecked")
V[] temp = (V[])new Object[size];
oa = temp;
} else {
for (int i = 0; i < oa.length; i++) {
V ob = oa[i];
if (ob == null)
continue;
if (hasName(ob, name)) {
if (i > 0)
moveToFront(oa, i);
return ob;
}
}
}
// Create a new object
V ob = create(name);
oa[oa.length - 1] = ob;
moveToFront(oa, oa.length - 1);
return ob;
}
}

View File

@@ -0,0 +1,627 @@
/*
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.File;
import java.io.IOException;
import java.io.FilePermission;
import java.net.*;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.StringTokenizer;
import java.util.Set;
import java.util.Vector;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.AccessControlContext;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Permission;
import java.security.ProtectionDomain;
import java.security.CodeSource;
import sun.security.util.SecurityConstants;
import sun.net.www.ParseUtil;
/**
* This class is used by the system to launch the main application.
*/
public class Launcher {
private static URLStreamHandlerFactory factory = new Factory();
private static Launcher launcher = new Launcher();
private static String bootClassPath =
System.getProperty("sun.boot.class.path");
public static Launcher getLauncher() {
return launcher;
}
private ClassLoader loader;
public Launcher() {
// Create the extension class loader
ClassLoader extcl;
try {
extcl = ExtClassLoader.getExtClassLoader();
} catch (IOException e) {
throw new InternalError(
"Could not create extension class loader", e);
}
// Now create the class loader to use to launch the application
try {
loader = AppClassLoader.getAppClassLoader(extcl);
} catch (IOException e) {
throw new InternalError(
"Could not create application class loader", e);
}
// Also set the context class loader for the primordial thread.
Thread.currentThread().setContextClassLoader(loader);
// Finally, install a security manager if requested
String s = System.getProperty("java.security.manager");
if (s != null) {
// init FileSystem machinery before SecurityManager installation
sun.nio.fs.DefaultFileSystemProvider.create();
SecurityManager sm = null;
if ("".equals(s) || "default".equals(s)) {
sm = new java.lang.SecurityManager();
} else {
try {
sm = (SecurityManager)loader.loadClass(s).newInstance();
} catch (IllegalAccessException e) {
} catch (InstantiationException e) {
} catch (ClassNotFoundException e) {
} catch (ClassCastException e) {
}
}
if (sm != null) {
System.setSecurityManager(sm);
} else {
throw new InternalError(
"Could not create SecurityManager: " + s);
}
}
}
/*
* Returns the class loader used to launch the main application.
*/
public ClassLoader getClassLoader() {
return loader;
}
/*
* The class loader used for loading installed extensions.
*/
static class ExtClassLoader extends URLClassLoader {
static {
ClassLoader.registerAsParallelCapable();
}
private static volatile ExtClassLoader instance = null;
/**
* create an ExtClassLoader. The ExtClassLoader is created
* within a context that limits which files it can read
*/
public static ExtClassLoader getExtClassLoader() throws IOException
{
if (instance == null) {
synchronized(ExtClassLoader.class) {
if (instance == null) {
instance = createExtClassLoader();
}
}
}
return instance;
}
private static ExtClassLoader createExtClassLoader() throws IOException {
try {
// Prior implementations of this doPrivileged() block supplied
// aa synthesized ACC via a call to the private method
// ExtClassLoader.getContext().
return AccessController.doPrivileged(
new PrivilegedExceptionAction<ExtClassLoader>() {
public ExtClassLoader run() throws IOException {
final File[] dirs = getExtDirs();
int len = dirs.length;
for (int i = 0; i < len; i++) {
MetaIndex.registerDirectory(dirs[i]);
}
return new ExtClassLoader(dirs);
}
});
} catch (java.security.PrivilegedActionException e) {
throw (IOException) e.getException();
}
}
void addExtURL(URL url) {
super.addURL(url);
}
/*
* Creates a new ExtClassLoader for the specified directories.
*/
public ExtClassLoader(File[] dirs) throws IOException {
super(getExtURLs(dirs), null, factory);
SharedSecrets.getJavaNetAccess().
getURLClassPath(this).initLookupCache(this);
}
private static File[] getExtDirs() {
String s = System.getProperty("java.ext.dirs");
File[] dirs;
if (s != null) {
StringTokenizer st =
new StringTokenizer(s, File.pathSeparator);
int count = st.countTokens();
dirs = new File[count];
for (int i = 0; i < count; i++) {
dirs[i] = new File(st.nextToken());
}
} else {
dirs = new File[0];
}
return dirs;
}
private static URL[] getExtURLs(File[] dirs) throws IOException {
Vector<URL> urls = new Vector<URL>();
for (int i = 0; i < dirs.length; i++) {
String[] files = dirs[i].list();
if (files != null) {
for (int j = 0; j < files.length; j++) {
if (!files[j].equals("meta-index")) {
File f = new File(dirs[i], files[j]);
urls.add(getFileURL(f));
}
}
}
}
URL[] ua = new URL[urls.size()];
urls.copyInto(ua);
return ua;
}
/*
* Searches the installed extension directories for the specified
* library name. For each extension directory, we first look for
* the native library in the subdirectory whose name is the value
* of the system property <code>os.arch</code>. Failing that, we
* look in the extension directory itself.
*/
public String findLibrary(String name) {
name = System.mapLibraryName(name);
URL[] urls = super.getURLs();
File prevDir = null;
for (int i = 0; i < urls.length; i++) {
// Get the ext directory from the URL; convert to
// URI first, so the URL will be decoded.
URI uri;
try {
uri = urls[i].toURI();
} catch (URISyntaxException ue) {
// skip this URL if cannot convert it to URI
continue;
}
// Use the Paths.get(uri) call in order to handle
// UNC based file name conversion correctly.
File dir = Paths.get(uri).toFile().getParentFile();
if (dir != null && !dir.equals(prevDir)) {
// Look in architecture-specific subdirectory first
// Read from the saved system properties to avoid deadlock
String arch = VM.getSavedProperty("os.arch");
if (arch != null) {
File file = new File(new File(dir, arch), name);
if (file.exists()) {
return file.getAbsolutePath();
}
}
// Then check the extension directory
File file = new File(dir, name);
if (file.exists()) {
return file.getAbsolutePath();
}
}
prevDir = dir;
}
return null;
}
private static AccessControlContext getContext(File[] dirs)
throws IOException
{
PathPermissions perms =
new PathPermissions(dirs);
ProtectionDomain domain = new ProtectionDomain(
new CodeSource(perms.getCodeBase(),
(java.security.cert.Certificate[]) null),
perms);
AccessControlContext acc =
new AccessControlContext(new ProtectionDomain[] { domain });
return acc;
}
}
/**
* The class loader used for loading from java.class.path.
* runs in a restricted security context.
*/
static class AppClassLoader extends URLClassLoader {
static {
ClassLoader.registerAsParallelCapable();
}
public static ClassLoader getAppClassLoader(final ClassLoader extcl)
throws IOException
{
final String s = System.getProperty("java.class.path");
final File[] path = (s == null) ? new File[0] : getClassPath(s);
// Note: on bugid 4256530
// Prior implementations of this doPrivileged() block supplied
// a rather restrictive ACC via a call to the private method
// AppClassLoader.getContext(). This proved overly restrictive
// when loading classes. Specifically it prevent
// accessClassInPackage.sun.* grants from being honored.
//
return AccessController.doPrivileged(
new PrivilegedAction<AppClassLoader>() {
public AppClassLoader run() {
URL[] urls =
(s == null) ? new URL[0] : pathToURLs(path);
return new AppClassLoader(urls, extcl);
}
});
}
final URLClassPath ucp;
/*
* Creates a new AppClassLoader
*/
AppClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent, factory);
ucp = SharedSecrets.getJavaNetAccess().getURLClassPath(this);
ucp.initLookupCache(this);
}
/**
* Override loadClass so we can checkPackageAccess.
*/
public Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
int i = name.lastIndexOf('.');
if (i != -1) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPackageAccess(name.substring(0, i));
}
}
if (ucp.knownToNotExist(name)) {
// The class of the given name is not found in the parent
// class loader as well as its local URLClassPath.
// Check if this class has already been defined dynamically;
// if so, return the loaded class; otherwise, skip the parent
// delegation and findClass.
Class<?> c = findLoadedClass(name);
if (c != null) {
if (resolve) {
resolveClass(c);
}
return c;
}
throw new ClassNotFoundException(name);
}
return (super.loadClass(name, resolve));
}
/**
* allow any classes loaded from classpath to exit the VM.
*/
protected PermissionCollection getPermissions(CodeSource codesource)
{
PermissionCollection perms = super.getPermissions(codesource);
perms.add(new RuntimePermission("exitVM"));
return perms;
}
/**
* This class loader supports dynamic additions to the class path
* at runtime.
*
* @see java.lang.instrument.Instrumentation#appendToSystemClassPathSearch
*/
private void appendToClassPathForInstrumentation(String path) {
assert(Thread.holdsLock(this));
// addURL is a no-op if path already contains the URL
super.addURL( getFileURL(new File(path)) );
}
/**
* create a context that can read any directories (recursively)
* mentioned in the class path. In the case of a jar, it has to
* be the directory containing the jar, not just the jar, as jar
* files might refer to other jar files.
*/
private static AccessControlContext getContext(File[] cp)
throws java.net.MalformedURLException
{
PathPermissions perms =
new PathPermissions(cp);
ProtectionDomain domain =
new ProtectionDomain(new CodeSource(perms.getCodeBase(),
(java.security.cert.Certificate[]) null),
perms);
AccessControlContext acc =
new AccessControlContext(new ProtectionDomain[] { domain });
return acc;
}
}
private static class BootClassPathHolder {
static final URLClassPath bcp;
static {
URL[] urls;
if (bootClassPath != null) {
urls = AccessController.doPrivileged(
new PrivilegedAction<URL[]>() {
public URL[] run() {
File[] classPath = getClassPath(bootClassPath);
int len = classPath.length;
Set<File> seenDirs = new HashSet<File>();
for (int i = 0; i < len; i++) {
File curEntry = classPath[i];
// Negative test used to properly handle
// nonexistent jars on boot class path
if (!curEntry.isDirectory()) {
curEntry = curEntry.getParentFile();
}
if (curEntry != null && seenDirs.add(curEntry)) {
MetaIndex.registerDirectory(curEntry);
}
}
return pathToURLs(classPath);
}
}
);
} else {
urls = new URL[0];
}
bcp = new URLClassPath(urls, factory, null);
bcp.initLookupCache(null);
}
}
public static URLClassPath getBootstrapClassPath() {
return BootClassPathHolder.bcp;
}
private static URL[] pathToURLs(File[] path) {
URL[] urls = new URL[path.length];
for (int i = 0; i < path.length; i++) {
urls[i] = getFileURL(path[i]);
}
// DEBUG
//for (int i = 0; i < urls.length; i++) {
// System.out.println("urls[" + i + "] = " + '"' + urls[i] + '"');
//}
return urls;
}
private static File[] getClassPath(String cp) {
File[] path;
if (cp != null) {
int count = 0, maxCount = 1;
int pos = 0, lastPos = 0;
// Count the number of separators first
while ((pos = cp.indexOf(File.pathSeparator, lastPos)) != -1) {
maxCount++;
lastPos = pos + 1;
}
path = new File[maxCount];
lastPos = pos = 0;
// Now scan for each path component
while ((pos = cp.indexOf(File.pathSeparator, lastPos)) != -1) {
if (pos - lastPos > 0) {
path[count++] = new File(cp.substring(lastPos, pos));
} else {
// empty path component translates to "."
path[count++] = new File(".");
}
lastPos = pos + 1;
}
// Make sure we include the last path component
if (lastPos < cp.length()) {
path[count++] = new File(cp.substring(lastPos));
} else {
path[count++] = new File(".");
}
// Trim array to correct size
if (count != maxCount) {
File[] tmp = new File[count];
System.arraycopy(path, 0, tmp, 0, count);
path = tmp;
}
} else {
path = new File[0];
}
// DEBUG
//for (int i = 0; i < path.length; i++) {
// System.out.println("path[" + i + "] = " + '"' + path[i] + '"');
//}
return path;
}
private static URLStreamHandler fileHandler;
static URL getFileURL(File file) {
try {
file = file.getCanonicalFile();
} catch (IOException e) {}
try {
return ParseUtil.fileToEncodedURL(file);
} catch (MalformedURLException e) {
// Should never happen since we specify the protocol...
throw new InternalError(e);
}
}
/*
* The stream handler factory for loading system protocol handlers.
*/
private static class Factory implements URLStreamHandlerFactory {
private static String PREFIX = "sun.net.www.protocol";
public URLStreamHandler createURLStreamHandler(String protocol) {
String name = PREFIX + "." + protocol + ".Handler";
try {
Class<?> c = Class.forName(name);
return (URLStreamHandler)c.newInstance();
} catch (ReflectiveOperationException e) {
throw new InternalError("could not load " + protocol +
"system protocol handler", e);
}
}
}
}
class PathPermissions extends PermissionCollection {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 8133287259134945693L;
private File path[];
private Permissions perms;
URL codeBase;
PathPermissions(File path[])
{
this.path = path;
this.perms = null;
this.codeBase = null;
}
URL getCodeBase()
{
return codeBase;
}
public void add(java.security.Permission permission) {
throw new SecurityException("attempt to add a permission");
}
private synchronized void init()
{
if (perms != null)
return;
perms = new Permissions();
// this is needed to be able to create the classloader itself!
perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
// add permission to read any "java.*" property
perms.add(new java.util.PropertyPermission("java.*",
SecurityConstants.PROPERTY_READ_ACTION));
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
for (int i=0; i < path.length; i++) {
File f = path[i];
String path;
try {
path = f.getCanonicalPath();
} catch (IOException ioe) {
path = f.getAbsolutePath();
}
if (i == 0) {
codeBase = Launcher.getFileURL(new File(path));
}
if (f.isDirectory()) {
if (path.endsWith(File.separator)) {
perms.add(new FilePermission(path+"-",
SecurityConstants.FILE_READ_ACTION));
} else {
perms.add(new FilePermission(
path + File.separator+"-",
SecurityConstants.FILE_READ_ACTION));
}
} else {
int endIndex = path.lastIndexOf(File.separatorChar);
if (endIndex != -1) {
path = path.substring(0, endIndex+1) + "-";
perms.add(new FilePermission(path,
SecurityConstants.FILE_READ_ACTION));
} else {
// XXX?
}
}
}
return null;
}
});
}
public boolean implies(java.security.Permission permission) {
if (perms == null)
init();
return perms.implies(permission);
}
public java.util.Enumeration<Permission> elements() {
if (perms == null)
init();
synchronized (perms) {
return perms.elements();
}
}
public String toString() {
if (perms == null)
init();
return perms.toString();
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 1994, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* The Lock class provides a simple, useful interface to a lock.
* Unlike monitors which synchronize access to an object, locks
* synchronize access to an arbitrary set of resources (objects,
* methods, variables, etc.). <p>
*
* The programmer using locks must be responsible for clearly defining
* the semantics of their use and should handle deadlock avoidance in
* the face of exceptions. <p>
*
* For example, if you want to protect a set of method invocations with
* a lock, and one of the methods may throw an exception, you must be
* prepared to release the lock similarly to the following example:
* <pre>
* class SomeClass {
* Lock myLock = new Lock();
* void someMethod() {
* myLock.lock();
* try {
* StartOperation();
* ContinueOperation();
* EndOperation();
* } finally {
* myLock.unlock();
* }
* }
* }
* </pre>
*
* @author Peter King
*/
public
class Lock {
private boolean locked = false;
/**
* Create a lock, which is initially not locked.
*/
public Lock () {
}
/**
* Acquire the lock. If someone else has the lock, wait until it
* has been freed, and then try to acquire it again. This method
* will not return until the lock has been acquired.
*
* @exception java.lang.InterruptedException if any thread has
* interrupted this thread.
*/
public final synchronized void lock() throws InterruptedException {
while (locked) {
wait();
}
locked = true;
}
/**
* Release the lock. If someone else is waiting for the lock, the
* will be notitified so they can try to acquire the lock again.
*/
public final synchronized void unlock() {
locked = false;
notifyAll();
}
}

View File

@@ -0,0 +1,127 @@
/*
* Copyright (c) 1995, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* MessageUtils: miscellaneous utilities for handling error and status
* properties and messages.
*
* @author Herb Jellinek
*/
public class MessageUtils {
// can instantiate it for to allow less verbose use - via instance
// instead of classname
public MessageUtils() { }
public static String subst(String patt, String arg) {
String args[] = { arg };
return subst(patt, args);
}
public static String subst(String patt, String arg1, String arg2) {
String args[] = { arg1, arg2 };
return subst(patt, args);
}
public static String subst(String patt, String arg1, String arg2,
String arg3) {
String args[] = { arg1, arg2, arg3 };
return subst(patt, args);
}
public static String subst(String patt, String args[]) {
StringBuffer result = new StringBuffer();
int len = patt.length();
for (int i = 0; i >= 0 && i < len; i++) {
char ch = patt.charAt(i);
if (ch == '%') {
if (i != len) {
int index = Character.digit(patt.charAt(i + 1), 10);
if (index == -1) {
result.append(patt.charAt(i + 1));
i++;
} else if (index < args.length) {
result.append(args[index]);
i++;
}
}
} else {
result.append(ch);
}
}
return result.toString();
}
public static String substProp(String propName, String arg) {
return subst(System.getProperty(propName), arg);
}
public static String substProp(String propName, String arg1, String arg2) {
return subst(System.getProperty(propName), arg1, arg2);
}
public static String substProp(String propName, String arg1, String arg2,
String arg3) {
return subst(System.getProperty(propName), arg1, arg2, arg3);
}
/**
* Print a message directly to stderr, bypassing all the
* character conversion methods.
* @param msg message to print
*/
public static native void toStderr(String msg);
/**
* Print a message directly to stdout, bypassing all the
* character conversion methods.
* @param msg message to print
*/
public static native void toStdout(String msg);
// Short forms of the above
public static void err(String s) {
toStderr(s + "\n");
}
public static void out(String s) {
toStdout(s + "\n");
}
// Print a stack trace to stderr
//
public static void where() {
Throwable t = new Throwable();
StackTraceElement[] es = t.getStackTrace();
for (int i = 1; i < es.length; i++)
toStderr("\t" + es[i].toString() + "\n");
}
}

View File

@@ -0,0 +1,274 @@
/*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/*
* MetaIndex is intended to decrease startup time (in particular cold
* start, when files are not yet in the disk cache) by providing a
* quick reject mechanism for probes into jar files. The on-disk
* representation of the meta-index is a flat text file with per-jar
* entries indicating (generally speaking) prefixes of package names
* contained in the jar. As an example, here is an edited excerpt of
* the meta-index generated for jre/lib in the current build:
*
<PRE>
% VERSION 1
# charsets.jar
sun/
# jce.jar
javax/
! jsse.jar
sun/
com/sun/net/
javax/
com/sun/security/
@ resources.jar
com/sun/xml/
com/sun/rowset/
com/sun/org/
sun/
com/sun/imageio/
javax/
com/sun/java/swing/
META-INF/services/
com/sun/java/util/jar/pack/
com/sun/corba/
com/sun/jndi/
! rt.jar
org/w3c/
com/sun/imageio/
javax/
java/
sun/
...
</PRE>
* <p> A few notes about the design of the meta-index:
*
* <UL>
*
* <LI> It contains entries for multiple jar files. This is
* intentional, to reduce the number of disk accesses that need to be
* performed during startup.
*
* <LI> It is only intended to act as a fast reject mechanism to
* prevent application and other classes from forcing all jar files on
* the boot and extension class paths to be opened. It is not intended
* as a precise index of the contents of the jar.
*
* <LI> It should be as small as possible to reduce the amount of time
* required to parse it during startup. For example, adding on the
* secondary package element to java/ and javax/ packages
* ("javax/swing/", for example) causes the meta-index to grow
* significantly. This is why substrings of the packages have been
* chosen as the principal contents.
*
* <LI> It is versioned, and optional, to prevent strong dependencies
* between the JVM and JDK. It is also potentially applicable to more
* than just the boot and extension class paths.
*
* <LI> Precisely speaking, it plays different role in JVM and J2SE
* side. On the JVM side, meta-index file is used to speed up locating the
* class files only while on the J2SE side, meta-index file is used to speed
* up the resources file & class file.
* To help the JVM and J2SE code to better utilize the information in meta-index
* file, we mark the jar file differently. Here is the current rule we use.
* For jar file containing only class file, we put '!' before the jar file name;
* for jar file containing only resources file, we put '@' before the jar file name;
* for jar file containing both resources and class file, we put '#' before the
* jar name.
* Notice the fact that every jar file contains at least the manifest file, so when
* we say "jar file containing only class file", we don't include that file.
*
* </UL>
*
* <p> To avoid changing the behavior of the current application
* loader and other loaders, the current MetaIndex implementation in
* the JDK requires that the directory containing the meta-index be
* registered with the MetaIndex class before construction of the
* associated URLClassPath. This prevents the need for automatic
* searching for the meta-index in the URLClassPath code and potential
* changes in behavior for non-core ClassLoaders.
*
* This class depends on make/tools/MetaIndex/BuildMetaIndex.java and
* is used principally by sun.misc.URLClassPath.
*/
public class MetaIndex {
// Maps jar file names in registered directories to meta-indices
private static volatile Map<File, MetaIndex> jarMap;
// List of contents of this meta-index
private String[] contents;
// Indicate whether the coresponding jar file is a pure class jar file or not
private boolean isClassOnlyJar;
//----------------------------------------------------------------------
// Registration of directories (which can cause parsing of the
// meta-index file if it is present), and fetching of parsed
// meta-indices
// jarMap is not strictly thread-safe when the meta index mechanism
// is extended for user-provided jar files in future.
public static MetaIndex forJar(File jar) {
return getJarMap().get(jar);
}
// 'synchronized' is added to protect the jarMap from being modified
// by multiple threads.
public static synchronized void registerDirectory(File dir) {
// Note that this does not currently check to see whether the
// directory has previously been registered, since the meta-index
// in a particular directory creates multiple entries in the
// jarMap. If this mechanism is extended beyond the boot and
// extension class paths (for example, automatically searching for
// meta-index files in directories containing jars which have been
// explicitly opened) then this code should be generalized.
//
// This method must be called from a privileged context.
File indexFile = new File(dir, "meta-index");
if (indexFile.exists()) {
try {
BufferedReader reader = new BufferedReader(new FileReader(indexFile));
String line = null;
String curJarName = null;
boolean isCurJarContainClassOnly = false;
List<String> contents = new ArrayList<String>();
Map<File, MetaIndex> map = getJarMap();
/* Convert dir into canonical form. */
dir = dir.getCanonicalFile();
/* Note: The first line should contain the version of
* the meta-index file. We have to match the right version
* before trying to parse this file. */
line = reader.readLine();
if (line == null ||
!line.equals("% VERSION 2")) {
reader.close();
return;
}
while ((line = reader.readLine()) != null) {
switch (line.charAt(0)) {
case '!':
case '#':
case '@': {
// Store away current contents, if any
if ((curJarName != null) && (contents.size() > 0)) {
map.put(new File(dir, curJarName),
new MetaIndex(contents,
isCurJarContainClassOnly));
contents.clear();
}
// Fetch new current jar file name
curJarName = line.substring(2);
if (line.charAt(0) == '!') {
isCurJarContainClassOnly = true;
} else if (isCurJarContainClassOnly) {
isCurJarContainClassOnly = false;
}
break;
}
case '%':
break;
default: {
contents.add(line);
}
}
}
// Store away current contents, if any
if ((curJarName != null) && (contents.size() > 0)) {
map.put(new File(dir, curJarName),
new MetaIndex(contents, isCurJarContainClassOnly));
}
reader.close();
} catch (IOException e) {
// Silently fail for now (similar behavior to elsewhere in
// extension and core loaders)
}
}
}
//----------------------------------------------------------------------
// Public APIs
//
public boolean mayContain(String entry) {
// Ask non-class file from class only jar returns false
// This check is important to avoid some class only jar
// files such as rt.jar are opened for resource request.
if (isClassOnlyJar && !entry.endsWith(".class")){
return false;
}
String[] conts = contents;
for (int i = 0; i < conts.length; i++) {
if (entry.startsWith(conts[i])) {
return true;
}
}
return false;
}
//----------------------------------------------------------------------
// Implementation only below this point
// @IllegalArgumentException if entries is null.
private MetaIndex(List<String> entries, boolean isClassOnlyJar)
throws IllegalArgumentException {
if (entries == null) {
throw new IllegalArgumentException();
}
contents = entries.toArray(new String[0]);
this.isClassOnlyJar = isClassOnlyJar;
}
private static Map<File, MetaIndex> getJarMap() {
if (jarMap == null) {
synchronized (MetaIndex.class) {
if (jarMap == null) {
jarMap = new HashMap<File, MetaIndex>();
}
}
}
assert jarMap != null;
return jarMap;
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/* A package-private class implementing a signal handler in native code. */
final class NativeSignalHandler implements SignalHandler {
private final long handler;
long getHandler() {
return handler;
}
NativeSignalHandler(long handler) {
this.handler = handler;
}
public void handle(Signal sig) {
handle0(sig.getNumber(), handler);
}
private static native void handle0(int number, long handler);
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import sun.io.Win32ErrorMode;
public class OSEnvironment {
/*
* Initialize any miscellenous operating system settings that need to be set
* for the class libraries.
* <p>
* At this time only the process-wide error mode needs to be set.
*/
public static void initialize() {
Win32ErrorMode.initialize();
}
}

View File

@@ -0,0 +1,670 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.ObjectInputStream;
import java.io.SerializablePermission;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import sun.util.logging.PlatformLogger;
import jdk.internal.util.StaticProperty;
/**
* Filter classes, array lengths, and graph metrics during deserialization.
* If set on an {@link ObjectInputStream}, the {@link #checkInput checkInput(FilterInfo)}
* method is called to validate classes, the length of each array,
* the number of objects being read from the stream, the depth of the graph,
* and the total number of bytes read from the stream.
* <p>
* A filter can be set via {@link ObjectInputStream#setObjectInputFilter setObjectInputFilter}
* for an individual ObjectInputStream.
* A filter can be set via {@link Config#setSerialFilter(ObjectInputFilter) Config.setSerialFilter}
* to affect every {@code ObjectInputStream} that does not otherwise set a filter.
* <p>
* A filter determines whether the arguments are {@link Status#ALLOWED ALLOWED}
* or {@link Status#REJECTED REJECTED} and should return the appropriate status.
* If the filter cannot determine the status it should return
* {@link Status#UNDECIDED UNDECIDED}.
* Filters should be designed for the specific use case and expected types.
* A filter designed for a particular use may be passed a class that is outside
* of the scope of the filter. If the purpose of the filter is to black-list classes
* then it can reject a candidate class that matches and report UNDECIDED for others.
* A filter may be called with class equals {@code null}, {@code arrayLength} equal -1,
* the depth, number of references, and stream size and return a status
* that reflects only one or only some of the values.
* This allows a filter to specific about the choice it is reporting and
* to use other filters without forcing either allowed or rejected status.
*
* <p>
* Typically, a custom filter should check if a process-wide filter
* is configured and defer to it if so. For example,
* <pre>{@code
* ObjectInputFilter.Status checkInput(FilterInfo info) {
* ObjectInputFilter serialFilter = ObjectInputFilter.Config.getSerialFilter();
* if (serialFilter != null) {
* ObjectInputFilter.Status status = serialFilter.checkInput(info);
* if (status != ObjectInputFilter.Status.UNDECIDED) {
* // The process-wide filter overrides this filter
* return status;
* }
* }
* if (info.serialClass() != null &&
* Remote.class.isAssignableFrom(info.serialClass())) {
* return Status.REJECTED; // Do not allow Remote objects
* }
* return Status.UNDECIDED;
* }
*}</pre>
* <p>
* Unless otherwise noted, passing a {@code null} argument to a
* method in this interface and its nested classes will cause a
* {@link NullPointerException} to be thrown.
*
* @since 8u
*/
@FunctionalInterface
public interface ObjectInputFilter {
/**
* Check the class, array length, number of object references, depth,
* stream size, and other available filtering information.
* Implementations of this method check the contents of the object graph being created
* during deserialization. The filter returns {@link Status#ALLOWED Status.ALLOWED},
* {@link Status#REJECTED Status.REJECTED}, or {@link Status#UNDECIDED Status.UNDECIDED}.
*
* @param filterInfo provides information about the current object being deserialized,
* if any, and the status of the {@link ObjectInputStream}
* @return {@link Status#ALLOWED Status.ALLOWED} if accepted,
* {@link Status#REJECTED Status.REJECTED} if rejected,
* {@link Status#UNDECIDED Status.UNDECIDED} if undecided.
*/
Status checkInput(FilterInfo filterInfo);
/**
* FilterInfo provides access to information about the current object
* being deserialized and the status of the {@link ObjectInputStream}.
* @since 9
*/
interface FilterInfo {
/**
* The class of an object being deserialized.
* For arrays, it is the array type.
* For example, the array class name of a 2 dimensional array of strings is
* "{@code [[Ljava.lang.String;}".
* To check the array's element type, iteratively use
* {@link Class#getComponentType() Class.getComponentType} while the result
* is an array and then check the class.
* The {@code serialClass is null} in the case where a new object is not being
* created and to give the filter a chance to check the depth, number of
* references to existing objects, and the stream size.
*
* @return class of an object being deserialized; may be null
*/
Class<?> serialClass();
/**
* The number of array elements when deserializing an array of the class.
*
* @return the non-negative number of array elements when deserializing
* an array of the class, otherwise -1
*/
long arrayLength();
/**
* The current depth.
* The depth starts at {@code 1} and increases for each nested object and
* decrements when each nested object returns.
*
* @return the current depth
*/
long depth();
/**
* The current number of object references.
*
* @return the non-negative current number of object references
*/
long references();
/**
* The current number of bytes consumed.
* @implSpec {@code streamBytes} is implementation specific
* and may not be directly related to the object in the stream
* that caused the callback.
*
* @return the non-negative current number of bytes consumed
*/
long streamBytes();
}
/**
* The status of a check on the class, array length, number of references,
* depth, and stream size.
*
* @since 8u
*/
enum Status {
/**
* The status is undecided, not allowed and not rejected.
*/
UNDECIDED,
/**
* The status is allowed.
*/
ALLOWED,
/**
* The status is rejected.
*/
REJECTED;
}
/**
* A utility class to set and get the process-wide filter or create a filter
* from a pattern string. If a process-wide filter is set, it will be
* used for each {@link ObjectInputStream} that does not set its own filter.
* <p>
* When setting the filter, it should be stateless and idempotent,
* reporting the same result when passed the same arguments.
* <p>
* The filter is configured using the {@link java.security.Security}
* property {@code jdk.serialFilter} and can be overridden by
* the System property {@code jdk.serialFilter}.
*
* The syntax is the same as for the {@link #createFilter(String) createFilter} method.
*
* @since 8u
*/
final class Config {
/* No instances. */
private Config() {}
/**
* Lock object for process-wide filter.
*/
private final static Object serialFilterLock = new Object();
/**
* Debug: Logger
*/
private final static PlatformLogger configLog;
/**
* Logger for debugging.
*/
static void filterLog(PlatformLogger.Level level, String msg, Object... args) {
if (configLog != null) {
if (PlatformLogger.Level.INFO.equals(level)) {
configLog.info(msg, args);
} else if (PlatformLogger.Level.WARNING.equals(level)) {
configLog.warning(msg, args);
} else {
configLog.severe(msg, args);
}
}
}
/**
* The name for the process-wide deserialization filter.
* Used as a system property and a java.security.Security property.
*/
private final static String SERIAL_FILTER_PROPNAME = "jdk.serialFilter";
/**
* The process-wide filter; may be null.
* Lookup the filter in java.security.Security or
* the system property.
*/
private final static ObjectInputFilter configuredFilter;
static {
configuredFilter = AccessController
.doPrivileged((PrivilegedAction<ObjectInputFilter>) () -> {
String props = StaticProperty.jdkSerialFilter();
if (props == null) {
props = Security.getProperty(SERIAL_FILTER_PROPNAME);
}
if (props != null) {
PlatformLogger log = PlatformLogger.getLogger("java.io.serialization");
log.info("Creating serialization filter from {0}", props);
try {
return createFilter(props);
} catch (RuntimeException re) {
log.warning("Error configuring filter: {0}", re);
}
}
return null;
});
configLog = (configuredFilter != null) ? PlatformLogger.getLogger("java.io.serialization") : null;
}
/**
* Current configured filter.
*/
private static ObjectInputFilter serialFilter = configuredFilter;
/**
* Get the filter for classes being deserialized on the ObjectInputStream.
*
* @param inputStream ObjectInputStream from which to get the filter; non-null
* @throws RuntimeException if the filter rejects
*/
public static ObjectInputFilter getObjectInputFilter(ObjectInputStream inputStream) {
Objects.requireNonNull(inputStream, "inputStream");
return sun.misc.SharedSecrets.getJavaOISAccess().getObjectInputFilter(inputStream);
}
/**
* Set the process-wide filter if it has not already been configured or set.
*
* @param inputStream ObjectInputStream on which to set the filter; non-null
* @param filter the serialization filter to set as the process-wide filter; not null
* @throws SecurityException if there is security manager and the
* {@code SerializablePermission("serialFilter")} is not granted
* @throws IllegalStateException if the filter has already been set {@code non-null}
*/
public static void setObjectInputFilter(ObjectInputStream inputStream,
ObjectInputFilter filter) {
Objects.requireNonNull(inputStream, "inputStream");
sun.misc.SharedSecrets.getJavaOISAccess().setObjectInputFilter(inputStream, filter);
}
/**
* Returns the process-wide serialization filter or {@code null} if not configured.
*
* @return the process-wide serialization filter or {@code null} if not configured
*/
public static ObjectInputFilter getSerialFilter() {
synchronized (serialFilterLock) {
return serialFilter;
}
}
/**
* Set the process-wide filter if it has not already been configured or set.
*
* @param filter the serialization filter to set as the process-wide filter; not null
* @throws SecurityException if there is security manager and the
* {@code SerializablePermission("serialFilter")} is not granted
* @throws IllegalStateException if the filter has already been set {@code non-null}
*/
public static void setSerialFilter(ObjectInputFilter filter) {
Objects.requireNonNull(filter, "filter");
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SerializablePermission("serialFilter"));
}
synchronized (serialFilterLock) {
if (serialFilter != null) {
throw new IllegalStateException("Serial filter can only be set once");
}
serialFilter = filter;
}
}
/**
* Returns an ObjectInputFilter from a string of patterns.
* <p>
* Patterns are separated by ";" (semicolon). Whitespace is significant and
* is considered part of the pattern.
* If a pattern includes an equals assignment, "{@code =}" it sets a limit.
* If a limit appears more than once the last value is used.
* <ul>
* <li>maxdepth={@code value} - the maximum depth of a graph</li>
* <li>maxrefs={@code value} - the maximum number of internal references</li>
* <li>maxbytes={@code value} - the maximum number of bytes in the input stream</li>
* <li>maxarray={@code value} - the maximum array length allowed</li>
* </ul>
* <p>
* Other patterns match or reject class or package name
* as returned from {@link Class#getName() Class.getName()}.
* Note that for arrays the element type is used in the pattern,
* not the array type.
* <ul>
* <li>If the pattern starts with "!", the class is rejected if the remaining pattern is matched;
* otherwise the class is allowed if the pattern matches.
* <li>If the pattern ends with ".**" it matches any class in the package and all subpackages.
* <li>If the pattern ends with ".*" it matches any class in the package.
* <li>If the pattern ends with "*", it matches any class with the pattern as a prefix.
* <li>If the pattern is equal to the class name, it matches.
* <li>Otherwise, the pattern is not matched.
* </ul>
* <p>
* The resulting filter performs the limit checks and then
* tries to match the class, if any. If any of the limits are exceeded,
* the filter returns {@link Status#REJECTED Status.REJECTED}.
* If the class is an array type, the class to be matched is the element type.
* Arrays of any number of dimensions are treated the same as the element type.
* For example, a pattern of "{@code !example.Foo}",
* rejects creation of any instance or array of {@code example.Foo}.
* The first pattern that matches, working from left to right, determines
* the {@link Status#ALLOWED Status.ALLOWED}
* or {@link Status#REJECTED Status.REJECTED} result.
* If nothing matches, the result is {@link Status#UNDECIDED Status.UNDECIDED}.
*
* @param pattern the pattern string to parse; not null
* @return a filter to check a class being deserialized; may be null;
* {@code null} if no patterns
* @throws IllegalArgumentException
* if a limit is missing the name, or the long value
* is not a number or is negative,
* or if the package is missing for ".*" and ".**"
*/
public static ObjectInputFilter createFilter(String pattern) {
Objects.requireNonNull(pattern, "pattern");
return Global.createFilter(pattern, true);
}
/**
* Returns an ObjectInputFilter from a string of patterns that
* checks only the length for arrays, not the component type.
*
* @param pattern the pattern string to parse; not null
* @return a filter to check a class being deserialized;
* {@code null} if no patterns
*/
public static ObjectInputFilter createFilter2(String pattern) {
Objects.requireNonNull(pattern, "pattern");
return Global.createFilter(pattern, false);
}
/**
* Implementation of ObjectInputFilter that performs the checks of
* the process-wide serialization filter. If configured, it will be
* used for all ObjectInputStreams that do not set their own filters.
*
*/
final static class Global implements ObjectInputFilter {
/**
* The pattern used to create the filter.
*/
private final String pattern;
/**
* The list of class filters.
*/
private final List<Function<Class<?>, Status>> filters;
/**
* Maximum allowed bytes in the stream.
*/
private long maxStreamBytes;
/**
* Maximum depth of the graph allowed.
*/
private long maxDepth;
/**
* Maximum number of references in a graph.
*/
private long maxReferences;
/**
* Maximum length of any array.
*/
private long maxArrayLength;
/**
* True to check the component type for arrays.
*/
private final boolean checkComponentType;
/**
* Returns an ObjectInputFilter from a string of patterns.
*
* @param pattern the pattern string to parse
* @param checkComponentType true if the filter should check
* the component type of arrays
* @return a filter to check a class being deserialized; not null
* @throws IllegalArgumentException if the parameter is malformed
* if the pattern is missing the name, the long value
* is not a number or is negative.
*/
static ObjectInputFilter createFilter(String pattern, boolean checkComponentType) {
Global filter = new Global(pattern, checkComponentType);
return filter.isEmpty() ? null : filter;
}
/**
* Construct a new filter from the pattern String.
*
* @param pattern a pattern string of filters
* @param checkComponentType true if the filter should check
* the component type of arrays
* @throws IllegalArgumentException if the pattern is malformed
*/
private Global(String pattern, boolean checkComponentType) {
this.pattern = pattern;
this.checkComponentType = checkComponentType;
maxArrayLength = Long.MAX_VALUE; // Default values are unlimited
maxDepth = Long.MAX_VALUE;
maxReferences = Long.MAX_VALUE;
maxStreamBytes = Long.MAX_VALUE;
String[] patterns = pattern.split(";");
filters = new ArrayList<>(patterns.length);
for (int i = 0; i < patterns.length; i++) {
String p = patterns[i];
int nameLen = p.length();
if (nameLen == 0) {
continue;
}
if (parseLimit(p)) {
// If the pattern contained a limit setting, i.e. type=value
continue;
}
boolean negate = p.charAt(0) == '!';
if (p.indexOf('/') >= 0) {
throw new IllegalArgumentException("invalid character \"/\" in: \"" + pattern + "\"");
}
if (p.endsWith("*")) {
// Wildcard cases
if (p.endsWith(".*")) {
// Pattern is a package name with a wildcard
final String pkg = p.substring(negate ? 1 : 0, nameLen - 1);
if (pkg.length() < 2) {
throw new IllegalArgumentException("package missing in: \"" + pattern + "\"");
}
if (negate) {
// A Function that fails if the class starts with the pattern, otherwise don't care
filters.add(c -> matchesPackage(c, pkg) ? Status.REJECTED : Status.UNDECIDED);
} else {
// A Function that succeeds if the class starts with the pattern, otherwise don't care
filters.add(c -> matchesPackage(c, pkg) ? Status.ALLOWED : Status.UNDECIDED);
}
} else if (p.endsWith(".**")) {
// Pattern is a package prefix with a double wildcard
final String pkgs = p.substring(negate ? 1 : 0, nameLen - 2);
if (pkgs.length() < 2) {
throw new IllegalArgumentException("package missing in: \"" + pattern + "\"");
}
if (negate) {
// A Function that fails if the class starts with the pattern, otherwise don't care
filters.add(c -> c.getName().startsWith(pkgs) ? Status.REJECTED : Status.UNDECIDED);
} else {
// A Function that succeeds if the class starts with the pattern, otherwise don't care
filters.add(c -> c.getName().startsWith(pkgs) ? Status.ALLOWED : Status.UNDECIDED);
}
} else {
// Pattern is a classname (possibly empty) with a trailing wildcard
final String className = p.substring(negate ? 1 : 0, nameLen - 1);
if (negate) {
// A Function that fails if the class starts with the pattern, otherwise don't care
filters.add(c -> c.getName().startsWith(className) ? Status.REJECTED : Status.UNDECIDED);
} else {
// A Function that succeeds if the class starts with the pattern, otherwise don't care
filters.add(c -> c.getName().startsWith(className) ? Status.ALLOWED : Status.UNDECIDED);
}
}
} else {
final String name = p.substring(negate ? 1 : 0);
if (name.isEmpty()) {
throw new IllegalArgumentException("class or package missing in: \"" + pattern + "\"");
}
// Pattern is a class name
if (negate) {
// A Function that fails if the class equals the pattern, otherwise don't care
filters.add(c -> c.getName().equals(name) ? Status.REJECTED : Status.UNDECIDED);
} else {
// A Function that succeeds if the class equals the pattern, otherwise don't care
filters.add(c -> c.getName().equals(name) ? Status.ALLOWED : Status.UNDECIDED);
}
}
}
}
/**
* Returns if this filter has any checks.
* @return {@code true} if the filter has any checks, {@code false} otherwise
*/
private boolean isEmpty() {
return filters.isEmpty() &&
maxArrayLength == Long.MAX_VALUE &&
maxDepth == Long.MAX_VALUE &&
maxReferences == Long.MAX_VALUE &&
maxStreamBytes == Long.MAX_VALUE;
}
/**
* Parse out a limit for one of maxarray, maxdepth, maxbytes, maxreferences.
*
* @param pattern a string with a type name, '=' and a value
* @return {@code true} if a limit was parsed, else {@code false}
* @throws IllegalArgumentException if the pattern is missing
* the name, the Long value is not a number or is negative.
*/
private boolean parseLimit(String pattern) {
int eqNdx = pattern.indexOf('=');
if (eqNdx < 0) {
// not a limit pattern
return false;
}
String valueString = pattern.substring(eqNdx + 1);
if (pattern.startsWith("maxdepth=")) {
maxDepth = parseValue(valueString);
} else if (pattern.startsWith("maxarray=")) {
maxArrayLength = parseValue(valueString);
} else if (pattern.startsWith("maxrefs=")) {
maxReferences = parseValue(valueString);
} else if (pattern.startsWith("maxbytes=")) {
maxStreamBytes = parseValue(valueString);
} else {
throw new IllegalArgumentException("unknown limit: " + pattern.substring(0, eqNdx));
}
return true;
}
/**
* Parse the value of a limit and check that it is non-negative.
* @param string inputstring
* @return the parsed value
* @throws IllegalArgumentException if parsing the value fails or the value is negative
*/
private static long parseValue(String string) throws IllegalArgumentException {
// Parse a Long from after the '=' to the end
long value = Long.parseLong(string);
if (value < 0) {
throw new IllegalArgumentException("negative limit: " + string);
}
return value;
}
/**
* {@inheritDoc}
*/
@Override
public Status checkInput(FilterInfo filterInfo) {
if (filterInfo.references() < 0
|| filterInfo.depth() < 0
|| filterInfo.streamBytes() < 0
|| filterInfo.references() > maxReferences
|| filterInfo.depth() > maxDepth
|| filterInfo.streamBytes() > maxStreamBytes) {
return Status.REJECTED;
}
Class<?> clazz = filterInfo.serialClass();
if (clazz != null) {
if (clazz.isArray()) {
if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > maxArrayLength) {
// array length is too big
return Status.REJECTED;
}
if (!checkComponentType) {
// As revised; do not check the component type for arrays
return Status.UNDECIDED;
}
do {
// Arrays are decided based on the component type
clazz = clazz.getComponentType();
} while (clazz.isArray());
}
if (clazz.isPrimitive()) {
// Primitive types are undecided; let someone else decide
return Status.UNDECIDED;
} else {
// Find any filter that allowed or rejected the class
final Class<?> cl = clazz;
Optional<Status> status = filters.stream()
.map(f -> f.apply(cl))
.filter(p -> p != Status.UNDECIDED)
.findFirst();
return status.orElse(Status.UNDECIDED);
}
}
return Status.UNDECIDED;
}
/**
* Returns {@code true} if the class is in the package.
*
* @param c a class
* @param pkg a package name (including the trailing ".")
* @return {@code true} if the class is in the package,
* otherwise {@code false}
*/
private static boolean matchesPackage(Class<?> c, String pkg) {
String n = c.getName();
return n.startsWith(pkg) && n.lastIndexOf('.') == pkg.length() - 1;
}
/**
* Returns the pattern used to create this filter.
* @return the pattern used to create this filter
*/
@Override
public String toString() {
return pattern;
}
}
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.ObjectStreamClass;
/**
* A callback used by {@code ObjectInputStream} to do descriptor validation.
*
* @author sjiang
*/
public interface ObjectStreamClassValidator {
/**
* This method will be called by ObjectInputStream to
* check a descriptor just before creating an object described by this descriptor.
* The object will not be created if this method throws a {@code RuntimeException}.
* @param descriptor descriptor to be checked.
*/
public void validateDescriptor(ObjectStreamClass descriptor);
}

View File

@@ -0,0 +1,539 @@
/*
* Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.nio.ByteBuffer;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
* The Perf class provides the ability to attach to an instrumentation
* buffer maintained by a Java virtual machine. The instrumentation
* buffer may be for the Java virtual machine running the methods of
* this class or it may be for another Java virtual machine on the
* same system.
* <p>
* In addition, this class provides methods to create instrumentation
* objects in the instrumentation buffer for the Java virtual machine
* that is running these methods. It also contains methods for acquiring
* the value of a platform specific high resolution clock for time
* stamp and interval measurement purposes.
*
* @author Brian Doherty
* @since 1.4.2
* @see #getPerf
* @see sun.misc.Perf$GetPerfAction
* @see java.nio.ByteBuffer
*/
public final class Perf {
private static Perf instance;
private static final int PERF_MODE_RO = 0;
private static final int PERF_MODE_RW = 1;
private Perf() { } // prevent instantiation
/**
* The GetPerfAction class is a convenience class for acquiring access
* to the singleton Perf instance using the
* <code>AccessController.doPrivileged()</code> method.
* <p>
* An instance of this class can be used as the argument to
* <code>AccessController.doPrivileged(PrivilegedAction)</code>.
* <p> Here is a suggested idiom for use of this class:
*
* <blockquote><pre>
* class MyTrustedClass {
* private static final Perf perf =
* AccessController.doPrivileged(new Perf.GetPerfAction<Perf>());
* ...
* }
* </pre></blockquote>
* <p>
* In the presence of a security manager, the <code>MyTrustedClass</code>
* class in the above example will need to be granted the
* <em>"sun.misc.Perf.getPerf"</em> <code>RuntimePermission</code>
* permission in order to successfully acquire the singleton Perf instance.
* <p>
* Please note that the <em>"sun.misc.Perf.getPerf"</em> permission
* is not a JDK specified permission.
*
* @see java.security.AccessController#doPrivileged(PrivilegedAction)
* @see java.lang.RuntimePermission
*/
public static class GetPerfAction implements PrivilegedAction<Perf>
{
/**
* Run the <code>Perf.getPerf()</code> method in a privileged context.
*
* @see #getPerf
*/
public Perf run() {
return getPerf();
}
}
/**
* Return a reference to the singleton Perf instance.
* <p>
* The getPerf() method returns the singleton instance of the Perf
* class. The returned object provides the caller with the capability
* for accessing the instrumentation buffer for this or another local
* Java virtual machine.
* <p>
* If a security manager is installed, its <code>checkPermission</code>
* method is called with a <code>RuntimePermission</code> with a target
* of <em>"sun.misc.Perf.getPerf"</em>. A security exception will result
* if the caller has not been granted this permission.
* <p>
* Access to the returned <code>Perf</code> object should be protected
* by its caller and not passed on to untrusted code. This object can
* be used to attach to the instrumentation buffer provided by this Java
* virtual machine or for those of other Java virtual machines running
* on the same system. The instrumentation buffer may contain senstitive
* information. API's built on top of this interface may want to provide
* finer grained access control to the contents of individual
* instrumentation objects contained within the buffer.
* <p>
* Please note that the <em>"sun.misc.Perf.getPerf"</em> permission
* is not a JDK specified permission.
*
* @return A reference to the singleton Perf instance.
* @throws AccessControlException if a security manager exists and
* its <code>checkPermission</code> method doesn't allow
* access to the <em>"sun.misc.Perf.getPerf"</em> target.
* @see java.lang.RuntimePermission
* @see #attach
*/
public static Perf getPerf()
{
SecurityManager security = System.getSecurityManager();
if (security != null) {
Permission perm = new RuntimePermission("sun.misc.Perf.getPerf");
security.checkPermission(perm);
}
return instance;
}
/**
* Attach to the instrumentation buffer for the specified Java virtual
* machine.
* <p>
* This method will attach to the instrumentation buffer for the
* specified virtual machine. It returns a <code>ByteBuffer</code> object
* that is initialized to access the instrumentation buffer for the
* indicated Java virtual machine. The <code>lvmid</code> parameter is
* a integer value that uniquely identifies the target local Java virtual
* machine. It is typically, but not necessarily, the process id of
* the target Java virtual machine.
* <p>
* If the <code>lvmid</code> identifies a Java virtual machine different
* from the one running this method, then the coherency characteristics
* of the buffer are implementation dependent. Implementations that do
* not support named, coherent, shared memory may return a
* <code>ByteBuffer</code> object that contains only a snap shot of the
* data in the instrumentation buffer. Implementations that support named,
* coherent, shared memory, may return a <code>ByteBuffer</code> object
* that will be changing dynamically over time as the target Java virtual
* machine updates its mapping of this buffer.
* <p>
* If the <code>lvmid</code> is 0 or equal to the actual <code>lvmid</code>
* for the Java virtual machine running this method, then the returned
* <code>ByteBuffer</code> object will always be coherent and dynamically
* changing.
* <p>
* The attach mode specifies the access permissions requested for the
* instrumentation buffer of the target virtual machine. The permitted
* access permissions are:
* <p>
* <bl>
* <li>"r" - Read only access. This Java virtual machine has only
* read access to the instrumentation buffer for the target Java
* virtual machine.
* <li>"rw" - Read/Write access. This Java virtual machine has read and
* write access to the instrumentation buffer for the target Java virtual
* machine. This mode is currently not supported and is reserved for
* future enhancements.
* </bl>
*
* @param lvmid an integer that uniquely identifies the
* target local Java virtual machine.
* @param mode a string indicating the attach mode.
* @return ByteBuffer a direct allocated byte buffer
* @throws IllegalArgumentException The lvmid or mode was invalid.
* @throws IOException An I/O error occurred while trying to acquire
* the instrumentation buffer.
* @throws OutOfMemoryError The instrumentation buffer could not be mapped
* into the virtual machine's address space.
* @see java.nio.ByteBuffer
*/
public ByteBuffer attach(int lvmid, String mode)
throws IllegalArgumentException, IOException
{
if (mode.compareTo("r") == 0) {
return attachImpl(null, lvmid, PERF_MODE_RO);
}
else if (mode.compareTo("rw") == 0) {
return attachImpl(null, lvmid, PERF_MODE_RW);
}
else {
throw new IllegalArgumentException("unknown mode");
}
}
/**
* Attach to the instrumentation buffer for the specified Java virtual
* machine owned by the given user.
* <p>
* This method behaves just as the <code>attach(int lvmid, String mode)
* </code> method, except that it only searches for Java virtual machines
* owned by the specified user.
*
* @param user A <code>String</code> object containing the
* name of the user that owns the target Java
* virtual machine.
* @param lvmid an integer that uniquely identifies the
* target local Java virtual machine.
* @param mode a string indicating the attach mode.
* @return ByteBuffer a direct allocated byte buffer
* @throws IllegalArgumentException The lvmid or mode was invalid.
* @throws IOException An I/O error occurred while trying to acquire
* the instrumentation buffer.
* @throws OutOfMemoryError The instrumentation buffer could not be mapped
* into the virtual machine's address space.
* @see java.nio.ByteBuffer
*/
public ByteBuffer attach(String user, int lvmid, String mode)
throws IllegalArgumentException, IOException
{
if (mode.compareTo("r") == 0) {
return attachImpl(user, lvmid, PERF_MODE_RO);
}
else if (mode.compareTo("rw") == 0) {
return attachImpl(user, lvmid, PERF_MODE_RW);
}
else {
throw new IllegalArgumentException("unknown mode");
}
}
/**
* Call the implementation specific attach method.
* <p>
* This method calls into the Java virtual machine to perform the platform
* specific attach method. Buffers returned from this method are
* internally managed as <code>PhantomRefereces</code> to provide for
* guaranteed, secure release of the native resources.
*
* @param user A <code>String</code> object containing the
* name of the user that owns the target Java
* virtual machine.
* @param lvmid an integer that uniquely identifies the
* target local Java virtual machine.
* @param mode a string indicating the attach mode.
* @return ByteBuffer a direct allocated byte buffer
* @throws IllegalArgumentException The lvmid or mode was invalid.
* @throws IOException An I/O error occurred while trying to acquire
* the instrumentation buffer.
* @throws OutOfMemoryError The instrumentation buffer could not be mapped
* into the virtual machine's address space.
*/
private ByteBuffer attachImpl(String user, int lvmid, int mode)
throws IllegalArgumentException, IOException
{
final ByteBuffer b = attach(user, lvmid, mode);
if (lvmid == 0) {
// The native instrumentation buffer for this Java virtual
// machine is never unmapped.
return b;
}
else {
// This is an instrumentation buffer for another Java virtual
// machine with native resources that need to be managed. We
// create a duplicate of the native ByteBuffer and manage it
// with a Cleaner object (PhantomReference). When the duplicate
// becomes only phantomly reachable, the native resources will
// be released.
final ByteBuffer dup = b.duplicate();
Cleaner.create(dup, new Runnable() {
public void run() {
try {
instance.detach(b);
}
catch (Throwable th) {
// avoid crashing the reference handler thread,
// but provide for some diagnosability
assert false : th.toString();
}
}
});
return dup;
}
}
/**
* Native method to perform the implementation specific attach mechanism.
* <p>
* The implementation of this method may return distinct or identical
* <code>ByteBuffer</code> objects for two distinct calls requesting
* attachment to the same Java virtual machine.
* <p>
* For the Sun HotSpot JVM, two distinct calls to attach to the same
* target Java virtual machine will result in two distinct ByteBuffer
* objects returned by this method. This may change in a future release.
*
* @param user A <code>String</code> object containing the
* name of the user that owns the target Java
* virtual machine.
* @param lvmid an integer that uniquely identifies the
* target local Java virtual machine.
* @param mode a string indicating the attach mode.
* @return ByteBuffer a direct allocated byte buffer
* @throws IllegalArgumentException The lvmid or mode was invalid.
* @throws IOException An I/O error occurred while trying to acquire
* the instrumentation buffer.
* @throws OutOfMemoryError The instrumentation buffer could not be mapped
* into the virtual machine's address space.
*/
private native ByteBuffer attach(String user, int lvmid, int mode)
throws IllegalArgumentException, IOException;
/**
* Native method to perform the implementation specific detach mechanism.
* <p>
* If this method is passed a <code>ByteBuffer</code> object that is
* not created by the <code>attach</code> method, then the results of
* this method are undefined, with unpredictable and potentially damaging
* effects to the Java virtual machine. To prevent accidental or malicious
* use of this method, all native ByteBuffer created by the <code>
* attach</code> method are managed internally as PhantomReferences
* and resources are freed by the system.
* <p>
* If this method is passed a <code>ByteBuffer</code> object created
* by the <code>attach</code> method with a lvmid for the Java virtual
* machine running this method (lvmid=0, for example), then the detach
* request is silently ignored.
*
* @param ByteBuffer A direct allocated byte buffer created by the
* <code>attach</code> method.
* @see java.nio.ByteBuffer
* @see #attach
*/
private native void detach(ByteBuffer bb);
/**
* Create a <code>long</code> scalar entry in the instrumentation buffer
* with the given variability characteristic, units, and initial value.
* <p>
* Access to the instrument is provided through the returned <code>
* ByteBuffer</code> object. Typically, this object should be wrapped
* with <code>LongBuffer</code> view object.
*
* @param variability the variability characteristic for this entry.
* @param units the units for this entry.
* @param name the name of this entry.
* @param value the initial value for this entry.
* @return ByteBuffer a direct allocated ByteBuffer object that
* allows write access to a native memory location
* containing a <code>long</code> value.
*
* see sun.misc.perf.Variability
* see sun.misc.perf.Units
* @see java.nio.ByteBuffer
*/
public native ByteBuffer createLong(String name, int variability,
int units, long value);
/**
* Create a <code>String</code> entry in the instrumentation buffer with
* the given variability characteristic, units, and initial value.
* <p>
* The maximum length of the <code>String</code> stored in this string
* instrument is given in by <code>maxLength</code> parameter. Updates
* to this instrument with <code>String</code> values with lengths greater
* than <code>maxLength</code> will be truncated to <code>maxLength</code>.
* The truncated value will be terminated by a null character.
* <p>
* The underlying implementation may further limit the length of the
* value, but will continue to preserve the null terminator.
* <p>
* Access to the instrument is provided through the returned <code>
* ByteBuffer</code> object.
*
* @param variability the variability characteristic for this entry.
* @param units the units for this entry.
* @param name the name of this entry.
* @param value the initial value for this entry.
* @param maxLength the maximum string length for this string
* instrument.
* @return ByteBuffer a direct allocated ByteBuffer that allows
* write access to a native memory location
* containing a <code>long</code> value.
*
* see sun.misc.perf.Variability
* see sun.misc.perf.Units
* @see java.nio.ByteBuffer
*/
public ByteBuffer createString(String name, int variability,
int units, String value, int maxLength)
{
byte[] v = getBytes(value);
byte[] v1 = new byte[v.length+1];
System.arraycopy(v, 0, v1, 0, v.length);
v1[v.length] = '\0';
return createByteArray(name, variability, units, v1, Math.max(v1.length, maxLength));
}
/**
* Create a <code>String</code> entry in the instrumentation buffer with
* the given variability characteristic, units, and initial value.
* <p>
* The maximum length of the <code>String</code> stored in this string
* instrument is implied by the length of the <code>value</code> parameter.
* Subsequent updates to the value of this instrument will be truncated
* to this implied maximum length. The truncated value will be terminated
* by a null character.
* <p>
* The underlying implementation may further limit the length of the
* initial or subsequent value, but will continue to preserve the null
* terminator.
* <p>
* Access to the instrument is provided through the returned <code>
* ByteBuffer</code> object.
*
* @param variability the variability characteristic for this entry.
* @param units the units for this entry.
* @param name the name of this entry.
* @param value the initial value for this entry.
* @return ByteBuffer a direct allocated ByteBuffer that allows
* write access to a native memory location
* containing a <code>long</code> value.
*
* see sun.misc.perf.Variability
* see sun.misc.perf.Units
* @see java.nio.ByteBuffer
*/
public ByteBuffer createString(String name, int variability,
int units, String value)
{
byte[] v = getBytes(value);
byte[] v1 = new byte[v.length+1];
System.arraycopy(v, 0, v1, 0, v.length);
v1[v.length] = '\0';
return createByteArray(name, variability, units, v1, v1.length);
}
/**
* Create a <code>byte</code> vector entry in the instrumentation buffer
* with the given variability characteristic, units, and initial value.
* <p>
* The <code>maxLength</code> parameter limits the size of the byte
* array instrument such that the initial or subsequent updates beyond
* this length are silently ignored. No special handling of truncated
* updates is provided.
* <p>
* The underlying implementation may further limit the length of the
* length of the initial or subsequent value.
* <p>
* Access to the instrument is provided through the returned <code>
* ByteBuffer</code> object.
*
* @param variability the variability characteristic for this entry.
* @param units the units for this entry.
* @param name the name of this entry.
* @param value the initial value for this entry.
* @param maxLength the maximum length of this byte array.
* @return ByteBuffer a direct allocated byte buffer that allows
* write access to a native memory location
* containing a <code>long</code> value.
*
* see sun.misc.perf.Variability
* see sun.misc.perf.Units
* @see java.nio.ByteBuffer
*/
public native ByteBuffer createByteArray(String name, int variability,
int units, byte[] value,
int maxLength);
/**
* convert string to an array of UTF-8 bytes
*/
private static byte[] getBytes(String s)
{
byte[] bytes = null;
try {
bytes = s.getBytes("UTF-8");
}
catch (UnsupportedEncodingException e) {
// ignore, UTF-8 encoding is always known
}
return bytes;
}
/**
* Return the value of the High Resolution Counter.
*
* The High Resolution Counter returns the number of ticks since
* since the start of the Java virtual machine. The resolution of
* the counter is machine dependent and can be determined from the
* value return by the {@link #highResFrequency} method.
*
* @return the number of ticks of machine dependent resolution since
* the start of the Java virtual machine.
*
* @see #highResFrequency
* @see java.lang.System#currentTimeMillis()
*/
public native long highResCounter();
/**
* Returns the frequency of the High Resolution Counter, in ticks per
* second.
*
* This value can be used to convert the value of the High Resolution
* Counter, as returned from a call to the {@link #highResCounter} method,
* into the number of seconds since the start of the Java virtual machine.
*
* @return the frequency of the High Resolution Counter.
* @see #highResCounter
*/
public native long highResFrequency();
private static native void registerNatives();
static {
registerNatives();
instance = new Perf();
}
}

View File

@@ -0,0 +1,191 @@
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.LongBuffer;
import java.security.AccessController;
/**
* Performance counter support for internal JRE classes.
* This class defines a fixed list of counters for the platform
* to use as an interim solution until RFE# 6209222 is implemented.
* The perf counters will be created in the jvmstat perf buffer
* that the HotSpot VM creates. The default size is 32K and thus
* the number of counters is bounded. You can alter the size
* with -XX:PerfDataMemorySize=<bytes> option. If there is
* insufficient memory in the jvmstat perf buffer, the C heap memory
* will be used and thus the application will continue to run if
* the counters added exceeds the buffer size but the counters
* will be missing.
*
* See HotSpot jvmstat implementation for certain circumstances
* that the jvmstat perf buffer is not supported.
*
*/
public class PerfCounter {
private static final Perf perf =
AccessController.doPrivileged(new Perf.GetPerfAction());
// Must match values defined in hotspot/src/share/vm/runtime/perfdata.hpp
private final static int V_Constant = 1;
private final static int V_Monotonic = 2;
private final static int V_Variable = 3;
private final static int U_None = 1;
private final String name;
private final LongBuffer lb;
private PerfCounter(String name, int type) {
this.name = name;
ByteBuffer bb = perf.createLong(name, type, U_None, 0L);
bb.order(ByteOrder.nativeOrder());
this.lb = bb.asLongBuffer();
}
static PerfCounter newPerfCounter(String name) {
return new PerfCounter(name, V_Variable);
}
static PerfCounter newConstantPerfCounter(String name) {
PerfCounter c = new PerfCounter(name, V_Constant);
return c;
}
/**
* Returns the current value of the perf counter.
*/
public synchronized long get() {
return lb.get(0);
}
/**
* Sets the value of the perf counter to the given newValue.
*/
public synchronized void set(long newValue) {
lb.put(0, newValue);
}
/**
* Adds the given value to the perf counter.
*/
public synchronized void add(long value) {
long res = get() + value;
lb.put(0, res);
}
/**
* Increments the perf counter with 1.
*/
public void increment() {
add(1);
}
/**
* Adds the given interval to the perf counter.
*/
public void addTime(long interval) {
add(interval);
}
/**
* Adds the elapsed time from the given start time (ns) to the perf counter.
*/
public void addElapsedTimeFrom(long startTime) {
add(System.nanoTime() - startTime);
}
@Override
public String toString() {
return name + " = " + get();
}
static class CoreCounters {
static final PerfCounter pdt = newPerfCounter("sun.classloader.parentDelegationTime");
static final PerfCounter lc = newPerfCounter("sun.classloader.findClasses");
static final PerfCounter lct = newPerfCounter("sun.classloader.findClassTime");
static final PerfCounter rcbt = newPerfCounter("sun.urlClassLoader.readClassBytesTime");
static final PerfCounter zfc = newPerfCounter("sun.zip.zipFiles");
static final PerfCounter zfot = newPerfCounter("sun.zip.zipFile.openTime");
}
static class WindowsClientCounters {
static final PerfCounter d3dAvailable = newConstantPerfCounter("sun.java2d.d3d.available");
}
/**
* Number of findClass calls
*/
public static PerfCounter getFindClasses() {
return CoreCounters.lc;
}
/**
* Time (ns) spent in finding classes that includes
* lookup and read class bytes and defineClass
*/
public static PerfCounter getFindClassTime() {
return CoreCounters.lct;
}
/**
* Time (ns) spent in finding classes
*/
public static PerfCounter getReadClassBytesTime() {
return CoreCounters.rcbt;
}
/**
* Time (ns) spent in the parent delegation to
* the parent of the defining class loader
*/
public static PerfCounter getParentDelegationTime() {
return CoreCounters.pdt;
}
/**
* Number of zip files opened.
*/
public static PerfCounter getZipFileCount() {
return CoreCounters.zfc;
}
/**
* Time (ns) spent in opening the zip files that
* includes building the entries hash table
*/
public static PerfCounter getZipFileOpenTime() {
return CoreCounters.zfot;
}
/**
* D3D graphic pipeline available
*/
public static PerfCounter getD3DAvailable() {
return WindowsClientCounters.d3dAvailable;
}
}

View File

@@ -0,0 +1,315 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.util.Vector;
import java.io.FileWriter;
import java.io.File;
import java.io.OutputStreamWriter;
import java.io.Writer;
/**
* This class is intended to be a central place for the jdk to
* log timing events of interest. There is pre-defined event
* of startTime, as well as a general
* mechanism of setting arbitrary times in an array.
* All unreserved times in the array can be used by callers
* in application-defined situations. The caller is responsible
* for setting and getting all times and for doing whatever
* analysis is interesting; this class is merely a central container
* for those timing values.
* Note that, due to the variables in this class being static,
* use of particular time values by multiple applets will cause
* confusing results. For example, if plugin runs two applets
* simultaneously, the initTime for those applets will collide
* and the results may be undefined.
* <P>
* To automatically track startup performance in an app or applet,
* use the command-line parameter sun.perflog as follows:<BR>
* -Dsun.perflog[=file:<filename>]
* <BR>
* where simply using the parameter with no value will enable output
* to the console and a value of "file:<filename>" will cause
* that given filename to be created and used for all output.
* <P>
* By default, times are measured using System.currentTimeMillis(). To use
* System.nanoTime() instead, add the command-line parameter:<BR>
-Dsun.perflog.nano=true
* <BR>
* <P>
* <B>Warning: Use at your own risk!</B>
* This class is intended for internal testing
* purposes only and may be removed at any time. More
* permanent monitoring and profiling APIs are expected to be
* developed for future releases and this class will cease to
* exist once those APIs are in place.
* @author Chet Haase
*/
public class PerformanceLogger {
// Timing values of global interest
private static final int START_INDEX = 0; // VM start
private static final int LAST_RESERVED = START_INDEX;
private static boolean perfLoggingOn = false;
private static boolean useNanoTime = false;
private static Vector<TimeData> times;
private static String logFileName = null;
private static Writer logWriter = null;
private static long baseTime;
static {
String perfLoggingProp =
java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("sun.perflog"));
if (perfLoggingProp != null) {
perfLoggingOn = true;
// Check if we should use nanoTime
String perfNanoProp =
java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("sun.perflog.nano"));
if (perfNanoProp != null) {
useNanoTime = true;
}
// Now, figure out what the user wants to do with the data
if (perfLoggingProp.regionMatches(true, 0, "file:", 0, 5)) {
logFileName = perfLoggingProp.substring(5);
}
if (logFileName != null) {
if (logWriter == null) {
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
try {
File logFile = new File(logFileName);
logFile.createNewFile();
logWriter = new FileWriter(logFile);
} catch (Exception e) {
System.out.println(e + ": Creating logfile " +
logFileName +
". Log to console");
}
return null;
}
});
}
}
if (logWriter == null) {
logWriter = new OutputStreamWriter(System.out);
}
}
times = new Vector<TimeData>(10);
// Reserve predefined slots
for (int i = 0; i <= LAST_RESERVED; ++i) {
times.add(new TimeData("Time " + i + " not set", 0));
}
}
/**
* Returns status of whether logging is enabled or not. This is
* provided as a convenience method so that users do not have to
* perform the same GetPropertyAction check as above to determine whether
* to enable performance logging.
*/
public static boolean loggingEnabled() {
return perfLoggingOn;
}
/**
* Internal class used to store time/message data together.
*/
static class TimeData {
String message;
long time;
TimeData(String message, long time) {
this.message = message;
this.time = time;
}
String getMessage() {
return message;
}
long getTime() {
return time;
}
}
/**
* Return the current time, in millis or nanos as appropriate
*/
private static long getCurrentTime() {
if (useNanoTime) {
return System.nanoTime();
} else {
return System.currentTimeMillis();
}
}
/**
* Sets the start time. Ideally, this is the earliest time available
* during the startup of a Java applet or application. This time is
* later used to analyze the difference between the initial startup
* time and other events in the system (such as an applet's init time).
*/
public static void setStartTime(String message) {
if (loggingEnabled()) {
long nowTime = getCurrentTime();
setStartTime(message, nowTime);
}
}
/**
* Sets the base time, output can then
* be displayed as offsets from the base time;.
*/
public static void setBaseTime(long time) {
if (loggingEnabled()) {
baseTime = time;
}
}
/**
* Sets the start time.
* This version of the method is
* given the time to log, instead of expecting this method to
* get the time itself. This is done in case the time was
* recorded much earlier than this method was called.
*/
public static void setStartTime(String message, long time) {
if (loggingEnabled()) {
times.set(START_INDEX, new TimeData(message, time));
}
}
/**
* Gets the start time, which should be the time when
* the java process started, prior to the VM actually being
* loaded.
*/
public static long getStartTime() {
if (loggingEnabled()) {
return times.get(START_INDEX).getTime();
} else {
return 0;
}
}
/**
* Sets the value of a given time and returns the index of the
* slot that that time was stored in.
*/
public static int setTime(String message) {
if (loggingEnabled()) {
long nowTime = getCurrentTime();
return setTime(message, nowTime);
} else {
return 0;
}
}
/**
* Sets the value of a given time and returns the index of the
* slot that that time was stored in.
* This version of the method is
* given the time to log, instead of expecting this method to
* get the time itself. This is done in case the time was
* recorded much earlier than this method was called.
*/
public static int setTime(String message, long time) {
if (loggingEnabled()) {
// times is already synchronized, but we need to ensure that
// the size used in times.set() is the same used when returning
// the index of that operation.
synchronized (times) {
times.add(new TimeData(message, time));
return (times.size() - 1);
}
} else {
return 0;
}
}
/**
* Returns time at given index.
*/
public static long getTimeAtIndex(int index) {
if (loggingEnabled()) {
return times.get(index).getTime();
} else {
return 0;
}
}
/**
* Returns message at given index.
*/
public static String getMessageAtIndex(int index) {
if (loggingEnabled()) {
return times.get(index).getMessage();
} else {
return null;
}
}
/**
* Outputs all data to parameter-specified Writer object
*/
public static void outputLog(Writer writer) {
if (loggingEnabled()) {
try {
synchronized(times) {
for (int i = 0; i < times.size(); ++i) {
TimeData td = times.get(i);
if (td != null) {
writer.write(i + " " + td.getMessage() + ": " +
(td.getTime() - baseTime) + "\n");
}
}
}
writer.flush();
} catch (Exception e) {
System.out.println(e + ": Writing performance log to " +
writer);
}
}
}
/**
* Outputs all data to whatever location the user specified
* via sun.perflog command-line parameter.
*/
public static void outputLog() {
outputLog(logWriter);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,214 @@
/*
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.util.Enumeration;
import java.util.NoSuchElementException;
/**
* Queue: implements a simple queue mechanism. Allows for enumeration of the
* elements.
*
* @author Herb Jellinek
*/
public class Queue<T> {
int length = 0;
QueueElement<T> head = null;
QueueElement<T> tail = null;
public Queue() {
}
/**
* Enqueue an object.
*/
public synchronized void enqueue(T obj) {
QueueElement<T> newElt = new QueueElement<>(obj);
if (head == null) {
head = newElt;
tail = newElt;
length = 1;
} else {
newElt.next = head;
head.prev = newElt;
head = newElt;
length++;
}
notify();
}
/**
* Dequeue the oldest object on the queue. Will wait indefinitely.
*
* @return the oldest object on the queue.
* @exception java.lang.InterruptedException if any thread has
* interrupted this thread.
*/
public T dequeue() throws InterruptedException {
return dequeue(0L);
}
/**
* Dequeue the oldest object on the queue.
* @param timeOut the number of milliseconds to wait for something
* to arrive.
*
* @return the oldest object on the queue.
* @exception java.lang.InterruptedException if any thread has
* interrupted this thread.
*/
public synchronized T dequeue(long timeOut)
throws InterruptedException {
while (tail == null) {
wait(timeOut);
}
QueueElement<T> elt = tail;
tail = elt.prev;
if (tail == null) {
head = null;
} else {
tail.next = null;
}
length--;
return elt.obj;
}
/**
* Is the queue empty?
* @return true if the queue is empty.
*/
public synchronized boolean isEmpty() {
return (tail == null);
}
/**
* Returns an enumeration of the elements in Last-In, First-Out
* order. Use the Enumeration methods on the returned object to
* fetch the elements sequentially.
*/
public final synchronized Enumeration<T> elements() {
return new LIFOQueueEnumerator<>(this);
}
/**
* Returns an enumeration of the elements in First-In, First-Out
* order. Use the Enumeration methods on the returned object to
* fetch the elements sequentially.
*/
public final synchronized Enumeration<T> reverseElements() {
return new FIFOQueueEnumerator<>(this);
}
public synchronized void dump(String msg) {
System.err.println(">> "+msg);
System.err.println("["+length+" elt(s); head = "+
(head == null ? "null" : (head.obj)+"")+
" tail = "+(tail == null ? "null" : (tail.obj)+""));
QueueElement<T> cursor = head;
QueueElement<T> last = null;
while (cursor != null) {
System.err.println(" "+cursor);
last = cursor;
cursor = cursor.next;
}
if (last != tail) {
System.err.println(" tail != last: "+tail+", "+last);
}
System.err.println("]");
}
}
final class FIFOQueueEnumerator<T> implements Enumeration<T> {
Queue<T> queue;
QueueElement<T> cursor;
FIFOQueueEnumerator(Queue<T> q) {
queue = q;
cursor = q.tail;
}
public boolean hasMoreElements() {
return (cursor != null);
}
public T nextElement() {
synchronized (queue) {
if (cursor != null) {
QueueElement<T> result = cursor;
cursor = cursor.prev;
return result.obj;
}
}
throw new NoSuchElementException("FIFOQueueEnumerator");
}
}
final class LIFOQueueEnumerator<T> implements Enumeration<T> {
Queue<T> queue;
QueueElement<T> cursor;
LIFOQueueEnumerator(Queue<T> q) {
queue = q;
cursor = q.head;
}
public boolean hasMoreElements() {
return (cursor != null);
}
public T nextElement() {
synchronized (queue) {
if (cursor != null) {
QueueElement<T> result = cursor;
cursor = cursor.next;
return result.obj;
}
}
throw new NoSuchElementException("LIFOQueueEnumerator");
}
}
class QueueElement<T> {
QueueElement<T> next = null;
QueueElement<T> prev = null;
T obj = null;
QueueElement(T obj) {
this.obj = obj;
}
public String toString() {
return "QueueElement[obj="+obj+(prev == null ? " null" : " prev")+
(next == null ? " null" : " next")+"]";
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* A class to signal exception from the RegexpPool class.
* @author James Gosling
*/
public class REException extends Exception {
private static final long serialVersionUID = 4656584872733646963L;
REException (String s) {
super(s);
}
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.lang.ref.SoftReference;
/**
* A "Ref" is an indirect reference to an object that the garbage collector
* knows about. An application should override the reconstitute() method with one
* that will construct the object based on information in the Ref, often by
* reading from a file. The get() method retains a cache of the result of the last call to
* reconstitute() in the Ref. When space gets tight, the garbage collector
* will clear old Ref cache entries when there are no other pointers to the
* object. In normal usage, Ref will always be subclassed. The subclass will add the
* instance variables necessary for the reconstitute() method to work. It will also add a
* constructor to set them up, and write a version of reconstitute().
*
* @deprecated This class has been replaced by
* <code>java.util.SoftReference</code>.
*
* @see java.util.SoftReference
*
*/
@Deprecated
public abstract class Ref {
private SoftReference soft = null;
/**
* Returns a pointer to the object referenced by this Ref. If the object
* has been thrown away by the garbage collector, it will be
* reconstituted. This method does everything necessary to ensure that the garbage
* collector throws things away in Least Recently Used(LRU) order. Applications should
* never override this method. The get() method effectively caches calls to
* reconstitute().
*/
public synchronized Object get() {
Object t = check();
if (t == null) {
t = reconstitute();
setThing(t);
}
return t;
}
/**
* Returns a pointer to the object referenced by this Ref by
* reconstituting it from some external source (such as a file). This method should not
* bother with caching since the method get() will deal with that.
* <p>
* In normal usage, Ref will always be subclassed. The subclass will add
* the instance variables necessary for reconstitute() to work. It will
* also add a constructor to set them up, and write a version of
* reconstitute().
*/
public abstract Object reconstitute();
/**
* Flushes the cached object. Forces the next invocation of get() to
* invoke reconstitute().
*/
public synchronized void flush() {
SoftReference s = soft;
if (s != null) s.clear();
soft = null;
}
/**
* Sets the thing to the specified object.
* @param thing the specified object
*/
public synchronized void setThing(Object thing) {
flush();
soft = new SoftReference(thing);
}
/**
* Checks to see what object is being pointed at by this Ref and returns it.
*/
public synchronized Object check() {
SoftReference s = soft;
if (s == null) return null;
return s.get();
}
/**
* Constructs a new Ref.
*/
public Ref() { }
/**
* Constructs a new Ref that initially points to thing.
*/
public Ref(Object thing) {
setThing(thing);
}
}

View File

@@ -0,0 +1,141 @@
/*
* Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* A class to represent a regular expression. Only handles '*'s.
* @author James Gosling
*/
public class Regexp {
/** if true then the matching process ignores case. */
public boolean ignoreCase;
/*
* regular expressions are carved into three regions: a constant string
* prefix, a constant string suffix, and a series of floating strings in
* between. In the input regular expression, they are separated by *s
*/
public String exp;
public String prefix, suffix;
public boolean exact;
public int prefixLen, suffixLen, totalLen;
public String mids[];
/** Create a new regular expression object. The regular expression
is a series of constant strings separated by *s. For example:
<dl>
<dt>*.gif <dd>Matches any string that ends in ".gif".
<dt>/tmp/* <dd>Matches any string that starts with "/tmp/".
<dt>/tmp/*.gif <dd>Matches any string that starts with "/tmp/" and ends
with ".gif".
<dt>/tmp/*new*.gif <dd>Matches any string that starts with "/tmp/"
and ends with ".gif" and has "new" somewhere in between.
</dl>
*/
public Regexp (String s) {
exp = s;
int firstst = s.indexOf('*');
int lastst = s.lastIndexOf('*');
if (firstst < 0) {
totalLen = s.length();
exact = true; // no * s
} else {
prefixLen = firstst;
if (firstst == 0)
prefix = null;
else
prefix = s.substring(0, firstst);
suffixLen = s.length() - lastst - 1;
if (suffixLen == 0)
suffix = null;
else
suffix = s.substring(lastst + 1);
int nmids = 0;
int pos = firstst;
while (pos < lastst && pos >= 0) {
nmids++;
pos = s.indexOf('*', pos + 1);
}
totalLen = prefixLen + suffixLen;
if (nmids > 0) {
mids = new String[nmids];
pos = firstst;
for (int i = 0; i < nmids; i++) {
pos++;
int npos = s.indexOf('*', pos);
if (pos < npos) {
mids[i] = s.substring(pos, npos);
totalLen += mids[i].length();
}
pos = npos;
}
}
}
}
/** Returns true iff the String s matches this regular expression. */
final boolean matches(String s) {
return matches(s, 0, s.length());
}
/** Returns true iff the substring of s from offset for len characters
matches this regular expression. */
boolean matches(String s, int offset, int len) {
if (exact)
return len == totalLen &&
exp.regionMatches(ignoreCase, 0, s, offset, len);
if (len < totalLen)
return false;
if (prefixLen > 0 &&
!prefix.regionMatches(ignoreCase,
0, s, offset, prefixLen)
||
suffixLen > 0 &&
!suffix.regionMatches(ignoreCase,
0, s, offset + len - suffixLen,
suffixLen))
return false;
if (mids == null)
return true;
int nmids = mids.length;
int spos = offset + prefixLen;
int limit = offset+len-suffixLen;
for (int i = 0; i<nmids; i++) {
String ms = mids[i];
int ml = ms.length();
while (spos+ml<=limit &&
!ms.regionMatches(ignoreCase,
0, s, spos, ml))
spos++;
if (spos+ml>limit)
return false;
spos+=ml;
}
return true;
}
}

View File

@@ -0,0 +1,319 @@
/*
* Copyright (c) 1995, 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.*;
/**
* A class to represent a pool of regular expressions. A string
* can be matched against the whole pool all at once. It is much
* faster than doing individual regular expression matches one-by-one.
*
* @see java.misc.RegexpTarget
* @author James Gosling
*/
public class RegexpPool {
private RegexpNode prefixMachine = new RegexpNode();
private RegexpNode suffixMachine = new RegexpNode();
private static final int BIG = 0x7FFFFFFF;
private int lastDepth = BIG;
public RegexpPool () {
}
/**
* Add a regular expression to the pool of regular expressions.
* @param re The regular expression to add to the pool.
For now, only handles strings that either begin or end with
a '*'.
* @param ret The object to be returned when this regular expression is
matched. If ret is an instance of the RegexpTarget class, ret.found
is called with the string fragment that matched the '*' as its
parameter.
* @exception REException error
*/
public void add(String re, Object ret) throws REException {
add(re, ret, false);
}
/**
* Replace the target for the regular expression with a different
* target.
*
* @param re The regular expression to be replaced in the pool.
* For now, only handles strings that either begin or end with
* a '*'.
* @param ret The object to be returned when this regular expression is
* matched. If ret is an instance of the RegexpTarget class, ret.found
* is called with the string fragment that matched the '*' as its
* parameter.
*/
public void replace(String re, Object ret) {
try {
add(re, ret, true);
} catch(Exception e) {
// should never occur if replace is true
}
}
/**
* Delete the regular expression and its target.
* @param re The regular expression to be deleted from the pool.
* must begin or end with a '*'
* @return target - the old target.
*/
public Object delete(String re) {
Object o = null;
RegexpNode p = prefixMachine;
RegexpNode best = p;
int len = re.length() - 1;
int i;
boolean prefix = true;
if (!re.startsWith("*") ||
!re.endsWith("*"))
len++;
if (len <= 0)
return null;
/* March forward through the prefix machine */
for (i = 0; p != null; i++) {
if (p.result != null && p.depth < BIG
&& (!p.exact || i == len)) {
best = p;
}
if (i >= len)
break;
p = p.find(re.charAt(i));
}
/* march backward through the suffix machine */
p = suffixMachine;
for (i = len; --i >= 0 && p != null;) {
if (p.result != null && p.depth < BIG) {
prefix = false;
best = p;
}
p = p.find(re.charAt(i));
}
// delete only if there is an exact match
if (prefix) {
if (re.equals(best.re)) {
o = best.result;
best.result = null;
}
} else {
if (re.equals(best.re)) {
o = best.result;
best.result = null;
}
}
return o;
}
/** Search for a match to a string & return the object associated
with it with the match. When multiple regular expressions
would match the string, the best match is returned first.
The next best match is returned the next time matchNext is
called.
@param s The string to match against the regular expressions
in the pool.
@return null on failure, otherwise the object associated with
the regular expression when it was added to the pool.
If the object is an instance of RegexpTarget, then
the return value is the result from calling
return.found(string_that_matched_wildcard).
*/
public Object match(String s) {
return matchAfter(s, BIG);
}
/** Identical to match except that it will only find matches to
regular expressions that were added to the pool <i>after</i>
the last regular expression that matched in the last call
to match() or matchNext() */
public Object matchNext(String s) {
return matchAfter(s, lastDepth);
}
private void add(String re, Object ret, boolean replace) throws REException {
int len = re.length();
RegexpNode p;
if (re.charAt(0) == '*') {
p = suffixMachine;
while (len > 1)
p = p.add(re.charAt(--len));
} else {
boolean exact = false;
if (re.charAt(len - 1) == '*')
len--;
else
exact = true;
p = prefixMachine;
for (int i = 0; i < len; i++)
p = p.add(re.charAt(i));
p.exact = exact;
}
if (p.result != null && !replace)
throw new REException(re + " is a duplicate");
p.re = re;
p.result = ret;
}
private Object matchAfter(String s, int lastMatchDepth) {
RegexpNode p = prefixMachine;
RegexpNode best = p;
int bst = 0;
int bend = 0;
int len = s.length();
int i;
if (len <= 0)
return null;
/* March forward through the prefix machine */
for (i = 0; p != null; i++) {
if (p.result != null && p.depth < lastMatchDepth
&& (!p.exact || i == len)) {
lastDepth = p.depth;
best = p;
bst = i;
bend = len;
}
if (i >= len)
break;
p = p.find(s.charAt(i));
}
/* march backward through the suffix machine */
p = suffixMachine;
for (i = len; --i >= 0 && p != null;) {
if (p.result != null && p.depth < lastMatchDepth) {
lastDepth = p.depth;
best = p;
bst = 0;
bend = i+1;
}
p = p.find(s.charAt(i));
}
Object o = best.result;
if (o != null && o instanceof RegexpTarget)
o = ((RegexpTarget) o).found(s.substring(bst, bend));
return o;
}
/** Resets the pool so that the next call to matchNext looks
at all regular expressions in the pool. match(s); is equivalent
to reset(); matchNext(s);
<p><b>Multithreading note:</b> reset/nextMatch leave state in the
regular expression pool. If multiple threads could be using this
pool this way, they should be syncronized to avoid race hazards.
match() was done in such a way that there are no such race
hazards: multiple threads can be matching in the same pool
simultaneously. */
public void reset() {
lastDepth = BIG;
}
/** Print this pool to standard output */
public void print(PrintStream out) {
out.print("Regexp pool:\n");
if (suffixMachine.firstchild != null) {
out.print(" Suffix machine: ");
suffixMachine.firstchild.print(out);
out.print("\n");
}
if (prefixMachine.firstchild != null) {
out.print(" Prefix machine: ");
prefixMachine.firstchild.print(out);
out.print("\n");
}
}
}
/* A node in a regular expression finite state machine. */
class RegexpNode {
char c;
RegexpNode firstchild;
RegexpNode nextsibling;
int depth;
boolean exact;
Object result;
String re = null;
RegexpNode () {
c = '#';
depth = 0;
}
RegexpNode (char C, int depth) {
c = C;
this.depth = depth;
}
RegexpNode add(char C) {
RegexpNode p = firstchild;
if (p == null)
p = new RegexpNode (C, depth+1);
else {
while (p != null)
if (p.c == C)
return p;
else
p = p.nextsibling;
p = new RegexpNode (C, depth+1);
p.nextsibling = firstchild;
}
firstchild = p;
return p;
}
RegexpNode find(char C) {
for (RegexpNode p = firstchild;
p != null;
p = p.nextsibling)
if (p.c == C)
return p;
return null;
}
void print(PrintStream out) {
if (nextsibling != null) {
RegexpNode p = this;
out.print("(");
while (p != null) {
out.write(p.c);
if (p.firstchild != null)
p.firstchild.print(out);
p = p.nextsibling;
out.write(p != null ? '|' : ')');
}
} else {
out.write(c);
if (firstchild != null)
firstchild.print(out);
}
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 1995, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* A class to define actions to be performed when a regular expression match
* occurs.
* @author James Gosling
*/
public interface RegexpTarget {
/** Gets called when a pattern in a RegexpPool matches.
* This method is called by RegexpPool.match() who passes the return
* value from found() back to its caller.
* @param remainder the string that matched the * in the pattern.
*/
Object found(String remainder);
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* Requests are functor objects; that is, they provide part of the mechanism
* for deferred function application.
*
* @author Steven B. Byrne
*/
abstract public class Request {
/**
* The main task of the Request object is to be exectuted from a request
* queue.
*/
abstract public void execute();
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* The request processor allows functors (Request instances) to be created
* in arbitrary threads, and to be posted for execution in a non-restricted
* thread.
*
* @author Steven B. Byrne
*/
public class RequestProcessor implements Runnable {
private static Queue<Request> requestQueue;
private static Thread dispatcher;
/**
* Queues a Request instance for execution by the request procesor
* thread.
*/
public static void postRequest(Request req) {
lazyInitialize();
requestQueue.enqueue(req);
}
/**
* Process requests as they are queued.
*/
public void run() {
lazyInitialize();
while (true) {
try {
Request req = requestQueue.dequeue();
try {
req.execute();
} catch (Throwable t) {
// do nothing at the moment...maybe report an error
// in the future
}
} catch (InterruptedException e) {
// do nothing at the present time.
}
}
}
/**
* This method initiates the request processor thread. It is safe
* to call it after the thread has been started. It provides a way for
* clients to deliberately control the context in which the request
* processor thread is created
*/
public static synchronized void startProcessing() {
if (dispatcher == null) {
dispatcher = new Thread(new RequestProcessor(), "Request Processor");
dispatcher.setPriority(Thread.NORM_PRIORITY + 2);
dispatcher.start();
}
}
/**
* This method performs lazy initialization.
*/
private static synchronized void lazyInitialize() {
if (requestQueue == null) {
requestQueue = new Queue<Request>();
}
}
}

View File

@@ -0,0 +1,195 @@
/*
* Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.EOFException;
import java.net.URL;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.InputStream;
import java.security.CodeSigner;
import java.util.jar.Manifest;
import java.nio.ByteBuffer;
import java.util.Arrays;
import sun.nio.ByteBuffered;
/**
* This class is used to represent a Resource that has been loaded
* from the class path.
*
* @author David Connelly
* @since 1.2
*/
public abstract class Resource {
/**
* Returns the name of the Resource.
*/
public abstract String getName();
/**
* Returns the URL of the Resource.
*/
public abstract URL getURL();
/**
* Returns the CodeSource URL for the Resource.
*/
public abstract URL getCodeSourceURL();
/**
* Returns an InputStream for reading the Resource data.
*/
public abstract InputStream getInputStream() throws IOException;
/**
* Returns the length of the Resource data, or -1 if unknown.
*/
public abstract int getContentLength() throws IOException;
private InputStream cis;
/* Cache result in case getBytes is called after getByteBuffer. */
private synchronized InputStream cachedInputStream() throws IOException {
if (cis == null) {
cis = getInputStream();
}
return cis;
}
/**
* Returns the Resource data as an array of bytes.
*/
public byte[] getBytes() throws IOException {
byte[] b;
// Get stream before content length so that a FileNotFoundException
// can propagate upwards without being caught too early
InputStream in = cachedInputStream();
// This code has been uglified to protect against interrupts.
// Even if a thread has been interrupted when loading resources,
// the IO should not abort, so must carefully retry, failing only
// if the retry leads to some other IO exception.
boolean isInterrupted = Thread.interrupted();
int len;
for (;;) {
try {
len = getContentLength();
break;
} catch (InterruptedIOException iioe) {
Thread.interrupted();
isInterrupted = true;
}
}
try {
b = new byte[0];
if (len == -1) len = Integer.MAX_VALUE;
int pos = 0;
while (pos < len) {
int bytesToRead;
if (pos >= b.length) { // Only expand when there's no room
bytesToRead = Math.min(len - pos, b.length + 1024);
if (b.length < pos + bytesToRead) {
b = Arrays.copyOf(b, pos + bytesToRead);
}
} else {
bytesToRead = b.length - pos;
}
int cc = 0;
try {
cc = in.read(b, pos, bytesToRead);
} catch (InterruptedIOException iioe) {
Thread.interrupted();
isInterrupted = true;
}
if (cc < 0) {
if (len != Integer.MAX_VALUE) {
throw new EOFException("Detect premature EOF");
} else {
if (b.length != pos) {
b = Arrays.copyOf(b, pos);
}
break;
}
}
pos += cc;
}
} finally {
try {
in.close();
} catch (InterruptedIOException iioe) {
isInterrupted = true;
} catch (IOException ignore) {}
if (isInterrupted) {
Thread.currentThread().interrupt();
}
}
return b;
}
/**
* Returns the Resource data as a ByteBuffer, but only if the input stream
* was implemented on top of a ByteBuffer. Return <tt>null</tt> otherwise.
*/
public ByteBuffer getByteBuffer() throws IOException {
InputStream in = cachedInputStream();
if (in instanceof ByteBuffered) {
return ((ByteBuffered)in).getByteBuffer();
}
return null;
}
/**
* Returns the Manifest for the Resource, or null if none.
*/
public Manifest getManifest() throws IOException {
return null;
}
/**
* Returns theCertificates for the Resource, or null if none.
*/
public java.security.cert.Certificate[] getCertificates() {
return null;
}
/**
* Returns the code signers for the Resource, or null if none.
*/
public CodeSigner[] getCodeSigners() {
return null;
}
/**
* Returns non-fatal reading error during data retrieval if there's any.
* For example, CRC error when reading a JAR entry.
*/
public Exception getDataError() {
return null;
}
}

View File

@@ -0,0 +1,434 @@
/*
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeSet;
/**
* A simple service-provider lookup mechanism. A <i>service</i> is a
* well-known set of interfaces and (usually abstract) classes. A <i>service
* provider</i> is a specific implementation of a service. The classes in a
* provider typically implement the interfaces and subclass the classes defined
* in the service itself. Service providers may be installed in an
* implementation of the Java platform in the form of extensions, that is, jar
* files placed into any of the usual extension directories. Providers may
* also be made available by adding them to the applet or application class
* path or by some other platform-specific means.
*
* <p> In this lookup mechanism a service is represented by an interface or an
* abstract class. (A concrete class may be used, but this is not
* recommended.) A provider of a given service contains one or more concrete
* classes that extend this <i>service class</i> with data and code specific to
* the provider. This <i>provider class</i> will typically not be the entire
* provider itself but rather a proxy that contains enough information to
* decide whether the provider is able to satisfy a particular request together
* with code that can create the actual provider on demand. The details of
* provider classes tend to be highly service-specific; no single class or
* interface could possibly unify them, so no such class has been defined. The
* only requirement enforced here is that provider classes must have a
* zero-argument constructor so that they may be instantiated during lookup.
*
* <p> A service provider identifies itself by placing a provider-configuration
* file in the resource directory <tt>META-INF/services</tt>. The file's name
* should consist of the fully-qualified name of the abstract service class.
* The file should contain a list of fully-qualified concrete provider-class
* names, one per line. Space and tab characters surrounding each name, as
* well as blank lines, are ignored. The comment character is <tt>'#'</tt>
* (<tt>0x23</tt>); on each line all characters following the first comment
* character are ignored. The file must be encoded in UTF-8.
*
* <p> If a particular concrete provider class is named in more than one
* configuration file, or is named in the same configuration file more than
* once, then the duplicates will be ignored. The configuration file naming a
* particular provider need not be in the same jar file or other distribution
* unit as the provider itself. The provider must be accessible from the same
* class loader that was initially queried to locate the configuration file;
* note that this is not necessarily the class loader that found the file.
*
* <p> <b>Example:</b> Suppose we have a service class named
* <tt>java.io.spi.CharCodec</tt>. It has two abstract methods:
*
* <pre>
* public abstract CharEncoder getEncoder(String encodingName);
* public abstract CharDecoder getDecoder(String encodingName);
* </pre>
*
* Each method returns an appropriate object or <tt>null</tt> if it cannot
* translate the given encoding. Typical <tt>CharCodec</tt> providers will
* support more than one encoding.
*
* <p> If <tt>sun.io.StandardCodec</tt> is a provider of the <tt>CharCodec</tt>
* service then its jar file would contain the file
* <tt>META-INF/services/java.io.spi.CharCodec</tt>. This file would contain
* the single line:
*
* <pre>
* sun.io.StandardCodec # Standard codecs for the platform
* </pre>
*
* To locate an encoder for a given encoding name, the internal I/O code would
* do something like this:
*
* <pre>
* CharEncoder getEncoder(String encodingName) {
* Iterator ps = Service.providers(CharCodec.class);
* while (ps.hasNext()) {
* CharCodec cc = (CharCodec)ps.next();
* CharEncoder ce = cc.getEncoder(encodingName);
* if (ce != null)
* return ce;
* }
* return null;
* }
* </pre>
*
* The provider-lookup mechanism always executes in the security context of the
* caller. Trusted system code should typically invoke the methods in this
* class from within a privileged security context.
*
* @author Mark Reinhold
* @since 1.3
*/
public final class Service<S> {
private static final String prefix = "META-INF/services/";
private Service() { }
private static void fail(Class<?> service, String msg, Throwable cause)
throws ServiceConfigurationError
{
ServiceConfigurationError sce
= new ServiceConfigurationError(service.getName() + ": " + msg);
sce.initCause(cause);
throw sce;
}
private static void fail(Class<?> service, String msg)
throws ServiceConfigurationError
{
throw new ServiceConfigurationError(service.getName() + ": " + msg);
}
private static void fail(Class<?> service, URL u, int line, String msg)
throws ServiceConfigurationError
{
fail(service, u + ":" + line + ": " + msg);
}
/**
* Parse a single line from the given configuration file, adding the name
* on the line to both the names list and the returned set iff the name is
* not already a member of the returned set.
*/
private static int parseLine(Class<?> service, URL u, BufferedReader r, int lc,
List<String> names, Set<String> returned)
throws IOException, ServiceConfigurationError
{
String ln = r.readLine();
if (ln == null) {
return -1;
}
int ci = ln.indexOf('#');
if (ci >= 0) ln = ln.substring(0, ci);
ln = ln.trim();
int n = ln.length();
if (n != 0) {
if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
fail(service, u, lc, "Illegal configuration-file syntax");
int cp = ln.codePointAt(0);
if (!Character.isJavaIdentifierStart(cp))
fail(service, u, lc, "Illegal provider-class name: " + ln);
for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
cp = ln.codePointAt(i);
if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
fail(service, u, lc, "Illegal provider-class name: " + ln);
}
if (!returned.contains(ln)) {
names.add(ln);
returned.add(ln);
}
}
return lc + 1;
}
/**
* Parse the content of the given URL as a provider-configuration file.
*
* @param service
* The service class for which providers are being sought;
* used to construct error detail strings
*
* @param url
* The URL naming the configuration file to be parsed
*
* @param returned
* A Set containing the names of provider classes that have already
* been returned. This set will be updated to contain the names
* that will be yielded from the returned <tt>Iterator</tt>.
*
* @return A (possibly empty) <tt>Iterator</tt> that will yield the
* provider-class names in the given configuration file that are
* not yet members of the returned set
*
* @throws ServiceConfigurationError
* If an I/O error occurs while reading from the given URL, or
* if a configuration-file format error is detected
*/
private static Iterator<String> parse(Class<?> service, URL u, Set<String> returned)
throws ServiceConfigurationError
{
InputStream in = null;
BufferedReader r = null;
ArrayList<String> names = new ArrayList<>();
try {
in = u.openStream();
r = new BufferedReader(new InputStreamReader(in, "utf-8"));
int lc = 1;
while ((lc = parseLine(service, u, r, lc, names, returned)) >= 0);
} catch (IOException x) {
fail(service, ": " + x);
} finally {
try {
if (r != null) r.close();
if (in != null) in.close();
} catch (IOException y) {
fail(service, ": " + y);
}
}
return names.iterator();
}
/**
* Private inner class implementing fully-lazy provider lookup
*/
private static class LazyIterator<S> implements Iterator<S> {
Class<S> service;
ClassLoader loader;
Enumeration<URL> configs = null;
Iterator<String> pending = null;
Set<String> returned = new TreeSet<>();
String nextName = null;
private LazyIterator(Class<S> service, ClassLoader loader) {
this.service = service;
this.loader = loader;
}
public boolean hasNext() throws ServiceConfigurationError {
if (nextName != null) {
return true;
}
if (configs == null) {
try {
String fullName = prefix + service.getName();
if (loader == null)
configs = ClassLoader.getSystemResources(fullName);
else
configs = loader.getResources(fullName);
} catch (IOException x) {
fail(service, ": " + x);
}
}
while ((pending == null) || !pending.hasNext()) {
if (!configs.hasMoreElements()) {
return false;
}
pending = parse(service, configs.nextElement(), returned);
}
nextName = pending.next();
return true;
}
public S next() throws ServiceConfigurationError {
if (!hasNext()) {
throw new NoSuchElementException();
}
String cn = nextName;
nextName = null;
Class<?> c = null;
try {
c = Class.forName(cn, false, loader);
} catch (ClassNotFoundException x) {
fail(service,
"Provider " + cn + " not found");
}
if (!service.isAssignableFrom(c)) {
fail(service,
"Provider " + cn + " not a subtype");
}
try {
return service.cast(c.newInstance());
} catch (Throwable x) {
fail(service,
"Provider " + cn + " could not be instantiated",
x);
}
return null; /* This cannot happen */
}
public void remove() {
throw new UnsupportedOperationException();
}
}
/**
* Locates and incrementally instantiates the available providers of a
* given service using the given class loader.
*
* <p> This method transforms the name of the given service class into a
* provider-configuration filename as described above and then uses the
* <tt>getResources</tt> method of the given class loader to find all
* available files with that name. These files are then read and parsed to
* produce a list of provider-class names. The iterator that is returned
* uses the given class loader to lookup and then instantiate each element
* of the list.
*
* <p> Because it is possible for extensions to be installed into a running
* Java virtual machine, this method may return different results each time
* it is invoked. <p>
*
* @param service
* The service's abstract service class
*
* @param loader
* The class loader to be used to load provider-configuration files
* and instantiate provider classes, or <tt>null</tt> if the system
* class loader (or, failing that the bootstrap class loader) is to
* be used
*
* @return An <tt>Iterator</tt> that yields provider objects for the given
* service, in some arbitrary order. The iterator will throw a
* <tt>ServiceConfigurationError</tt> if a provider-configuration
* file violates the specified format or if a provider class cannot
* be found and instantiated.
*
* @throws ServiceConfigurationError
* If a provider-configuration file violates the specified format
* or names a provider class that cannot be found and instantiated
*
* @see #providers(java.lang.Class)
* @see #installedProviders(java.lang.Class)
*/
public static <S> Iterator<S> providers(Class<S> service, ClassLoader loader)
throws ServiceConfigurationError
{
return new LazyIterator<S>(service, loader);
}
/**
* Locates and incrementally instantiates the available providers of a
* given service using the context class loader. This convenience method
* is equivalent to
*
* <pre>
* ClassLoader cl = Thread.currentThread().getContextClassLoader();
* return Service.providers(service, cl);
* </pre>
*
* @param service
* The service's abstract service class
*
* @return An <tt>Iterator</tt> that yields provider objects for the given
* service, in some arbitrary order. The iterator will throw a
* <tt>ServiceConfigurationError</tt> if a provider-configuration
* file violates the specified format or if a provider class cannot
* be found and instantiated.
*
* @throws ServiceConfigurationError
* If a provider-configuration file violates the specified format
* or names a provider class that cannot be found and instantiated
*
* @see #providers(java.lang.Class, java.lang.ClassLoader)
*/
public static <S> Iterator<S> providers(Class<S> service)
throws ServiceConfigurationError
{
ClassLoader cl = Thread.currentThread().getContextClassLoader();
return Service.providers(service, cl);
}
/**
* Locates and incrementally instantiates the available providers of a
* given service using the extension class loader. This convenience method
* simply locates the extension class loader, call it
* <tt>extClassLoader</tt>, and then does
*
* <pre>
* return Service.providers(service, extClassLoader);
* </pre>
*
* If the extension class loader cannot be found then the system class
* loader is used; if there is no system class loader then the bootstrap
* class loader is used.
*
* @param service
* The service's abstract service class
*
* @return An <tt>Iterator</tt> that yields provider objects for the given
* service, in some arbitrary order. The iterator will throw a
* <tt>ServiceConfigurationError</tt> if a provider-configuration
* file violates the specified format or if a provider class cannot
* be found and instantiated.
*
* @throws ServiceConfigurationError
* If a provider-configuration file violates the specified format
* or names a provider class that cannot be found and instantiated
*
* @see #providers(java.lang.Class, java.lang.ClassLoader)
*/
public static <S> Iterator<S> installedProviders(Class<S> service)
throws ServiceConfigurationError
{
ClassLoader cl = ClassLoader.getSystemClassLoader();
ClassLoader prev = null;
while (cl != null) {
prev = cl;
cl = cl.getParent();
}
return Service.providers(service, prev);
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* Error thrown when something goes wrong while looking up service providers.
* In particular, this error will be thrown in the following situations:
*
* <ul>
* <li> A concrete provider class cannot be found,
* <li> A concrete provider class cannot be instantiated,
* <li> The format of a provider-configuration file is illegal, or
* <li> An IOException occurs while reading a provider-configuration file.
* </ul>
*
* @author Mark Reinhold
* @since 1.3
*/
public class ServiceConfigurationError extends Error {
static final long serialVersionUID = 8769866263384244465L;
/**
* Constructs a new instance with the specified detail string.
*/
public ServiceConfigurationError(String msg) {
super(msg);
}
/**
* Constructs a new instance that wraps the specified throwable.
*/
public ServiceConfigurationError(Throwable x) {
super(x);
}
}

View File

@@ -0,0 +1,251 @@
/*
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import javax.crypto.SealedObject;
import java.util.jar.JarFile;
import java.io.Console;
import java.io.FileDescriptor;
import java.io.ObjectInputStream;
import java.security.ProtectionDomain;
import java.security.Signature;
import java.security.AccessController;
/** A repository of "shared secrets", which are a mechanism for
calling implementation-private methods in another package without
using reflection. A package-private class implements a public
interface and provides the ability to call package-private methods
within that package; the object implementing that interface is
provided through a third package to which access is restricted.
This framework avoids the primary disadvantage of using reflection
for this purpose, namely the loss of compile-time checking. */
public class SharedSecrets {
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static JavaUtilJarAccess javaUtilJarAccess;
private static JavaLangAccess javaLangAccess;
private static JavaLangRefAccess javaLangRefAccess;
private static JavaIOAccess javaIOAccess;
private static JavaNetAccess javaNetAccess;
private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
private static JavaSecurityAccess javaSecurityAccess;
private static JavaUtilZipFileAccess javaUtilZipFileAccess;
private static JavaAWTAccess javaAWTAccess;
private static JavaOISAccess javaOISAccess;
private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
private static JavaObjectInputStreamReadString javaObjectInputStreamReadString;
private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
private static JavaSecuritySignatureAccess javaSecuritySignatureAccess;
public static JavaUtilJarAccess javaUtilJarAccess() {
if (javaUtilJarAccess == null) {
// Ensure JarFile is initialized; we know that that class
// provides the shared secret
unsafe.ensureClassInitialized(JarFile.class);
}
return javaUtilJarAccess;
}
public static void setJavaUtilJarAccess(JavaUtilJarAccess access) {
javaUtilJarAccess = access;
}
public static void setJavaLangAccess(JavaLangAccess jla) {
javaLangAccess = jla;
}
public static JavaLangAccess getJavaLangAccess() {
return javaLangAccess;
}
public static void setJavaLangRefAccess(JavaLangRefAccess jlra) {
javaLangRefAccess = jlra;
}
public static JavaLangRefAccess getJavaLangRefAccess() {
return javaLangRefAccess;
}
public static void setJavaNetAccess(JavaNetAccess jna) {
javaNetAccess = jna;
}
public static JavaNetAccess getJavaNetAccess() {
return javaNetAccess;
}
public static void setJavaNetHttpCookieAccess(JavaNetHttpCookieAccess a) {
javaNetHttpCookieAccess = a;
}
public static JavaNetHttpCookieAccess getJavaNetHttpCookieAccess() {
if (javaNetHttpCookieAccess == null)
unsafe.ensureClassInitialized(java.net.HttpCookie.class);
return javaNetHttpCookieAccess;
}
public static void setJavaNioAccess(JavaNioAccess jna) {
javaNioAccess = jna;
}
public static JavaNioAccess getJavaNioAccess() {
if (javaNioAccess == null) {
// Ensure java.nio.ByteOrder is initialized; we know that
// this class initializes java.nio.Bits that provides the
// shared secret.
unsafe.ensureClassInitialized(java.nio.ByteOrder.class);
}
return javaNioAccess;
}
public static void setJavaIOAccess(JavaIOAccess jia) {
javaIOAccess = jia;
}
public static JavaIOAccess getJavaIOAccess() {
if (javaIOAccess == null) {
unsafe.ensureClassInitialized(Console.class);
}
return javaIOAccess;
}
public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
javaIOFileDescriptorAccess = jiofda;
}
public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() {
if (javaIOFileDescriptorAccess == null)
unsafe.ensureClassInitialized(FileDescriptor.class);
return javaIOFileDescriptorAccess;
}
public static void setJavaOISAccess(JavaOISAccess access) {
javaOISAccess = access;
}
public static JavaOISAccess getJavaOISAccess() {
if (javaOISAccess == null)
unsafe.ensureClassInitialized(ObjectInputStream.class);
return javaOISAccess;
}
public static void setJavaSecurityProtectionDomainAccess
(JavaSecurityProtectionDomainAccess jspda) {
javaSecurityProtectionDomainAccess = jspda;
}
public static JavaSecurityProtectionDomainAccess
getJavaSecurityProtectionDomainAccess() {
if (javaSecurityProtectionDomainAccess == null)
unsafe.ensureClassInitialized(ProtectionDomain.class);
return javaSecurityProtectionDomainAccess;
}
public static void setJavaSecurityAccess(JavaSecurityAccess jsa) {
javaSecurityAccess = jsa;
}
public static JavaSecurityAccess getJavaSecurityAccess() {
if (javaSecurityAccess == null) {
unsafe.ensureClassInitialized(AccessController.class);
}
return javaSecurityAccess;
}
public static JavaUtilZipFileAccess getJavaUtilZipFileAccess() {
if (javaUtilZipFileAccess == null)
unsafe.ensureClassInitialized(java.util.zip.ZipFile.class);
return javaUtilZipFileAccess;
}
public static void setJavaUtilZipFileAccess(JavaUtilZipFileAccess access) {
javaUtilZipFileAccess = access;
}
public static void setJavaAWTAccess(JavaAWTAccess jaa) {
javaAWTAccess = jaa;
}
public static JavaAWTAccess getJavaAWTAccess() {
// this may return null in which case calling code needs to
// provision for.
if (javaAWTAccess == null) {
return null;
}
return javaAWTAccess;
}
public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() {
if (javaObjectInputStreamReadString == null) {
unsafe.ensureClassInitialized(ObjectInputStream.class);
}
return javaObjectInputStreamReadString;
}
public static void setJavaObjectInputStreamReadString(JavaObjectInputStreamReadString access) {
javaObjectInputStreamReadString = access;
}
public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
if (javaObjectInputStreamAccess == null) {
unsafe.ensureClassInitialized(ObjectInputStream.class);
}
return javaObjectInputStreamAccess;
}
public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) {
javaObjectInputStreamAccess = access;
}
public static void setJavaSecuritySignatureAccess(JavaSecuritySignatureAccess jssa) {
javaSecuritySignatureAccess = jssa;
}
public static JavaSecuritySignatureAccess getJavaSecuritySignatureAccess() {
if (javaSecuritySignatureAccess == null) {
unsafe.ensureClassInitialized(Signature.class);
}
return javaSecuritySignatureAccess;
}
public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAccess jcsoa) {
javaxCryptoSealedObjectAccess = jcsoa;
}
public static JavaxCryptoSealedObjectAccess getJavaxCryptoSealedObjectAccess() {
if (javaxCryptoSealedObjectAccess == null) {
unsafe.ensureClassInitialized(SealedObject.class);
}
return javaxCryptoSealedObjectAccess;
}
}

View File

@@ -0,0 +1,232 @@
/*
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.util.Hashtable;
/**
* This class provides ANSI/ISO C signal support. A Java program can register
* signal handlers for the current process. There are two restrictions:
* <ul>
* <li>
* Java code cannot register a handler for signals that are already used
* by the Java VM implementation. The <code>Signal.handle</code>
* function raises an <code>IllegalArgumentException</code> if such an attempt
* is made.
* <li>
* When <code>Signal.handle</code> is called, the VM internally registers a
* special C signal handler. There is no way to force the Java signal handler
* to run synchronously before the C signal handler returns. Instead, when the
* VM receives a signal, the special C signal handler creates a new thread
* (at priority <code>Thread.MAX_PRIORITY</code>) to
* run the registered Java signal handler. The C signal handler immediately
* returns. Note that because the Java signal handler runs in a newly created
* thread, it may not actually be executed until some time after the C signal
* handler returns.
* </ul>
* <p>
* Signal objects are created based on their names. For example:
* <blockquote><pre>
* new Signal("INT");
* </blockquote></pre>
* constructs a signal object corresponding to <code>SIGINT</code>, which is
* typically produced when the user presses <code>Ctrl-C</code> at the command line.
* The <code>Signal</code> constructor throws <code>IllegalArgumentException</code>
* when it is passed an unknown signal.
* <p>
* This is an example of how Java code handles <code>SIGINT</code>:
* <blockquote><pre>
* SignalHandler handler = new SignalHandler () {
* public void handle(Signal sig) {
* ... // handle SIGINT
* }
* };
* Signal.handle(new Signal("INT"), handler);
* </blockquote></pre>
*
* @author Sheng Liang
* @author Bill Shannon
* @see sun.misc.SignalHandler
* @since 1.2
*/
public final class Signal {
private static Hashtable<Signal,SignalHandler> handlers = new Hashtable<>(4);
private static Hashtable<Integer,Signal> signals = new Hashtable<>(4);
private int number;
private String name;
/* Returns the signal number */
public int getNumber() {
return number;
}
/**
* Returns the signal name.
*
* @return the name of the signal.
* @see sun.misc.Signal#Signal(String name)
*/
public String getName() {
return name;
}
/**
* Compares the equality of two <code>Signal</code> objects.
*
* @param other the object to compare with.
* @return whether two <code>Signal</code> objects are equal.
*/
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || !(other instanceof Signal)) {
return false;
}
Signal other1 = (Signal)other;
return name.equals(other1.name) && (number == other1.number);
}
/**
* Returns a hashcode for this Signal.
*
* @return a hash code value for this object.
*/
public int hashCode() {
return number;
}
/**
* Returns a string representation of this signal. For example, "SIGINT"
* for an object constructed using <code>new Signal ("INT")</code>.
*
* @return a string representation of the signal
*/
public String toString() {
return "SIG" + name;
}
/**
* Constructs a signal from its name.
*
* @param name the name of the signal.
* @exception IllegalArgumentException unknown signal
* @see sun.misc.Signal#getName()
*/
public Signal(String name) {
number = findSignal(name);
this.name = name;
if (number < 0) {
throw new IllegalArgumentException("Unknown signal: " + name);
}
}
/**
* Registers a signal handler.
*
* @param sig a signal
* @param handler the handler to be registered with the given signal.
* @result the old handler
* @exception IllegalArgumentException the signal is in use by the VM
* @see sun.misc.Signal#raise(Signal sig)
* @see sun.misc.SignalHandler
* @see sun.misc.SignalHandler#SIG_DFL
* @see sun.misc.SignalHandler#SIG_IGN
*/
public static synchronized SignalHandler handle(Signal sig,
SignalHandler handler)
throws IllegalArgumentException {
long newH = (handler instanceof NativeSignalHandler) ?
((NativeSignalHandler)handler).getHandler() : 2;
long oldH = handle0(sig.number, newH);
if (oldH == -1) {
throw new IllegalArgumentException
("Signal already used by VM or OS: " + sig);
}
signals.put(sig.number, sig);
synchronized (handlers) {
SignalHandler oldHandler = handlers.get(sig);
handlers.remove(sig);
if (newH == 2) {
handlers.put(sig, handler);
}
if (oldH == 0) {
return SignalHandler.SIG_DFL;
} else if (oldH == 1) {
return SignalHandler.SIG_IGN;
} else if (oldH == 2) {
return oldHandler;
} else {
return new NativeSignalHandler(oldH);
}
}
}
/**
* Raises a signal in the current process.
*
* @param sig a signal
* @see sun.misc.Signal#handle(Signal sig, SignalHandler handler)
*/
public static void raise(Signal sig) throws IllegalArgumentException {
if (handlers.get(sig) == null) {
throw new IllegalArgumentException("Unhandled signal: " + sig);
}
raise0(sig.number);
}
/* Called by the VM to execute Java signal handlers. */
private static void dispatch(final int number) {
final Signal sig = signals.get(number);
final SignalHandler handler = handlers.get(sig);
Runnable runnable = new Runnable () {
public void run() {
// Don't bother to reset the priority. Signal handler will
// run at maximum priority inherited from the VM signal
// dispatch thread.
// Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
handler.handle(sig);
}
};
if (handler != null) {
new Thread(runnable, sig + " handler").start();
}
}
/* Find the signal number, given a name. Returns -1 for unknown signals. */
private static native int findSignal(String sigName);
/* Registers a native signal handler, and returns the old handler.
* Handler values:
* 0 default handler
* 1 ignore the signal
* 2 call back to Signal.dispatch
* other arbitrary native signal handlers
*/
private static native long handle0(int sig, long nativeH);
/* Raise a given signal number */
private static native void raise0(int sig);
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* This is the signal handler interface expected in <code>Signal.handle</code>.
*
* @author Sheng Liang
* @author Bill Shannon
* @see sun.misc.Signal
* @since 1.2
*/
public interface SignalHandler {
/**
* The default signal handler
*/
public static final SignalHandler SIG_DFL = new NativeSignalHandler(0);
/**
* Ignore the signal
*/
public static final SignalHandler SIG_IGN = new NativeSignalHandler(1);
/**
* Handle the given signal
*
* @param sig a signal object
*/
public void handle(Signal sig);
}

View File

@@ -0,0 +1,459 @@
/*
* Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.lang.ref.SoftReference;
import java.lang.ref.ReferenceQueue;
import java.util.Iterator;
import java.util.Map;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Set;
import java.util.AbstractSet;
import java.util.NoSuchElementException;
/**
* A memory-sensitive implementation of the <code>Map</code> interface.
*
* <p> A <code>SoftCache</code> object uses {@link java.lang.ref.SoftReference
* soft references} to implement a memory-sensitive hash map. If the garbage
* collector determines at a certain point in time that a value object in a
* <code>SoftCache</code> entry is no longer strongly reachable, then it may
* remove that entry in order to release the memory occupied by the value
* object. All <code>SoftCache</code> objects are guaranteed to be completely
* cleared before the virtual machine will throw an
* <code>OutOfMemoryError</code>. Because of this automatic clearing feature,
* the behavior of this class is somewhat different from that of other
* <code>Map</code> implementations.
*
* <p> Both null values and the null key are supported. This class has the
* same performance characteristics as the <code>HashMap</code> class, and has
* the same efficiency parameters of <em>initial capacity</em> and <em>load
* factor</em>.
*
* <p> Like most collection classes, this class is not synchronized. A
* synchronized <code>SoftCache</code> may be constructed using the
* <code>Collections.synchronizedMap</code> method.
*
* <p> In typical usage this class will be subclassed and the <code>fill</code>
* method will be overridden. When the <code>get</code> method is invoked on a
* key for which there is no mapping in the cache, it will in turn invoke the
* <code>fill</code> method on that key in an attempt to construct a
* corresponding value. If the <code>fill</code> method returns such a value
* then the cache will be updated and the new value will be returned. Thus,
* for example, a simple URL-content cache can be constructed as follows:
*
* <pre>
* public class URLCache extends SoftCache {
* protected Object fill(Object key) {
* return ((URL)key).getContent();
* }
* }
* </pre>
*
* <p> The behavior of the <code>SoftCache</code> class depends in part upon
* the actions of the garbage collector, so several familiar (though not
* required) <code>Map</code> invariants do not hold for this class. <p>
* Because entries are removed from a <code>SoftCache</code> in response to
* dynamic advice from the garbage collector, a <code>SoftCache</code> may
* behave as though an unknown thread is silently removing entries. In
* particular, even if you synchronize on a <code>SoftCache</code> instance and
* invoke none of its mutator methods, it is possible for the <code>size</code>
* method to return smaller values over time, for the <code>isEmpty</code>
* method to return <code>false</code> and then <code>true</code>, for the
* <code>containsKey</code> method to return <code>true</code> and later
* <code>false</code> for a given key, for the <code>get</code> method to
* return a value for a given key but later return <code>null</code>, for the
* <code>put</code> method to return <code>null</code> and the
* <code>remove</code> method to return <code>false</code> for a key that
* previously appeared to be in the map, and for successive examinations of the
* key set, the value set, and the entry set to yield successively smaller
* numbers of elements.
*
* @author Mark Reinhold
* @since 1.2
* @see java.util.HashMap
* @see java.lang.ref.SoftReference
*/
public class SoftCache extends AbstractMap implements Map {
/* The basic idea of this implementation is to maintain an internal HashMap
that maps keys to soft references whose referents are the keys' values;
the various accessor methods dereference these soft references before
returning values. Because we don't have access to the innards of the
HashMap, each soft reference must contain the key that maps to it so
that the processQueue method can remove keys whose values have been
discarded. Thus the HashMap actually maps keys to instances of the
ValueCell class, which is a simple extension of the SoftReference class.
*/
static private class ValueCell extends SoftReference {
static private Object INVALID_KEY = new Object();
static private int dropped = 0;
private Object key;
private ValueCell(Object key, Object value, ReferenceQueue queue) {
super(value, queue);
this.key = key;
}
private static ValueCell create(Object key, Object value,
ReferenceQueue queue)
{
if (value == null) return null;
return new ValueCell(key, value, queue);
}
private static Object strip(Object val, boolean drop) {
if (val == null) return null;
ValueCell vc = (ValueCell)val;
Object o = vc.get();
if (drop) vc.drop();
return o;
}
private boolean isValid() {
return (key != INVALID_KEY);
}
private void drop() {
super.clear();
key = INVALID_KEY;
dropped++;
}
}
/* Hash table mapping keys to ValueCells */
private Map hash;
/* Reference queue for cleared ValueCells */
private ReferenceQueue queue = new ReferenceQueue();
/* Process any ValueCells that have been cleared and enqueued by the
garbage collector. This method should be invoked once by each public
mutator in this class. We don't invoke this method in public accessors
because that can lead to surprising ConcurrentModificationExceptions.
*/
private void processQueue() {
ValueCell vc;
while ((vc = (ValueCell)queue.poll()) != null) {
if (vc.isValid()) hash.remove(vc.key);
else ValueCell.dropped--;
}
}
/* -- Constructors -- */
/**
* Construct a new, empty <code>SoftCache</code> with the given
* initial capacity and the given load factor.
*
* @param initialCapacity The initial capacity of the cache
*
* @param loadFactor A number between 0.0 and 1.0
*
* @throws IllegalArgumentException If the initial capacity is less than
* or equal to zero, or if the load
* factor is less than zero
*/
public SoftCache(int initialCapacity, float loadFactor) {
hash = new HashMap(initialCapacity, loadFactor);
}
/**
* Construct a new, empty <code>SoftCache</code> with the given
* initial capacity and the default load factor.
*
* @param initialCapacity The initial capacity of the cache
*
* @throws IllegalArgumentException If the initial capacity is less than
* or equal to zero
*/
public SoftCache(int initialCapacity) {
hash = new HashMap(initialCapacity);
}
/**
* Construct a new, empty <code>SoftCache</code> with the default
* capacity and the default load factor.
*/
public SoftCache() {
hash = new HashMap();
}
/* -- Simple queries -- */
/**
* Return the number of key-value mappings in this cache. The time
* required by this operation is linear in the size of the map.
*/
public int size() {
return entrySet().size();
}
/**
* Return <code>true</code> if this cache contains no key-value mappings.
*/
public boolean isEmpty() {
return entrySet().isEmpty();
}
/**
* Return <code>true</code> if this cache contains a mapping for the
* specified key. If there is no mapping for the key, this method will not
* attempt to construct one by invoking the <code>fill</code> method.
*
* @param key The key whose presence in the cache is to be tested
*/
public boolean containsKey(Object key) {
return ValueCell.strip(hash.get(key), false) != null;
}
/* -- Lookup and modification operations -- */
/**
* Create a value object for the given <code>key</code>. This method is
* invoked by the <code>get</code> method when there is no entry for
* <code>key</code>. If this method returns a non-<code>null</code> value,
* then the cache will be updated to map <code>key</code> to that value,
* and that value will be returned by the <code>get</code> method.
*
* <p> The default implementation of this method simply returns
* <code>null</code> for every <code>key</code> value. A subclass may
* override this method to provide more useful behavior.
*
* @param key The key for which a value is to be computed
*
* @return A value for <code>key</code>, or <code>null</code> if one
* could not be computed
* @see #get
*/
protected Object fill(Object key) {
return null;
}
/**
* Return the value to which this cache maps the specified
* <code>key</code>. If the cache does not presently contain a value for
* this key, then invoke the <code>fill</code> method in an attempt to
* compute such a value. If that method returns a non-<code>null</code>
* value, then update the cache and return the new value. Otherwise,
* return <code>null</code>.
*
* <p> Note that because this method may update the cache, it is considered
* a mutator and may cause <code>ConcurrentModificationException</code>s to
* be thrown if invoked while an iterator is in use.
*
* @param key The key whose associated value, if any, is to be returned
*
* @see #fill
*/
public Object get(Object key) {
processQueue();
Object v = hash.get(key);
if (v == null) {
v = fill(key);
if (v != null) {
hash.put(key, ValueCell.create(key, v, queue));
return v;
}
}
return ValueCell.strip(v, false);
}
/**
* Update this cache so that the given <code>key</code> maps to the given
* <code>value</code>. If the cache previously contained a mapping for
* <code>key</code> then that mapping is replaced and the old value is
* returned.
*
* @param key The key that is to be mapped to the given
* <code>value</code>
* @param value The value to which the given <code>key</code> is to be
* mapped
*
* @return The previous value to which this key was mapped, or
* <code>null</code> if if there was no mapping for the key
*/
public Object put(Object key, Object value) {
processQueue();
ValueCell vc = ValueCell.create(key, value, queue);
return ValueCell.strip(hash.put(key, vc), true);
}
/**
* Remove the mapping for the given <code>key</code> from this cache, if
* present.
*
* @param key The key whose mapping is to be removed
*
* @return The value to which this key was mapped, or <code>null</code> if
* there was no mapping for the key
*/
public Object remove(Object key) {
processQueue();
return ValueCell.strip(hash.remove(key), true);
}
/**
* Remove all mappings from this cache.
*/
public void clear() {
processQueue();
hash.clear();
}
/* -- Views -- */
private static boolean valEquals(Object o1, Object o2) {
return (o1 == null) ? (o2 == null) : o1.equals(o2);
}
/* Internal class for entries.
Because it uses SoftCache.this.queue, this class cannot be static.
*/
private class Entry implements Map.Entry {
private Map.Entry ent;
private Object value; /* Strong reference to value, to prevent the GC
from flushing the value while this Entry
exists */
Entry(Map.Entry ent, Object value) {
this.ent = ent;
this.value = value;
}
public Object getKey() {
return ent.getKey();
}
public Object getValue() {
return value;
}
public Object setValue(Object value) {
return ent.setValue(ValueCell.create(ent.getKey(), value, queue));
}
public boolean equals(Object o) {
if (! (o instanceof Map.Entry)) return false;
Map.Entry e = (Map.Entry)o;
return (valEquals(ent.getKey(), e.getKey())
&& valEquals(value, e.getValue()));
}
public int hashCode() {
Object k;
return ((((k = getKey()) == null) ? 0 : k.hashCode())
^ ((value == null) ? 0 : value.hashCode()));
}
}
/* Internal class for entry sets */
private class EntrySet extends AbstractSet {
Set hashEntries = hash.entrySet();
public Iterator iterator() {
return new Iterator() {
Iterator hashIterator = hashEntries.iterator();
Entry next = null;
public boolean hasNext() {
while (hashIterator.hasNext()) {
Map.Entry ent = (Map.Entry)hashIterator.next();
ValueCell vc = (ValueCell)ent.getValue();
Object v = null;
if ((vc != null) && ((v = vc.get()) == null)) {
/* Value has been flushed by GC */
continue;
}
next = new Entry(ent, v);
return true;
}
return false;
}
public Object next() {
if ((next == null) && !hasNext())
throw new NoSuchElementException();
Entry e = next;
next = null;
return e;
}
public void remove() {
hashIterator.remove();
}
};
}
public boolean isEmpty() {
return !(iterator().hasNext());
}
public int size() {
int j = 0;
for (Iterator i = iterator(); i.hasNext(); i.next()) j++;
return j;
}
public boolean remove(Object o) {
processQueue();
if (o instanceof Entry) return hashEntries.remove(((Entry)o).ent);
else return false;
}
}
private Set entrySet = null;
/**
* Return a <code>Set</code> view of the mappings in this cache.
*/
public Set entrySet() {
if (entrySet == null) entrySet = new EntrySet();
return entrySet;
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* A utility class needed to access the root {@code ThreadGroup}
*
* The class should not depend on any others, because it' called from JNI_OnLoad of the AWT
* native library. Triggering class loading could could lead to a deadlock.
*/
public final class ThreadGroupUtils {
private ThreadGroupUtils() {
// Avoid instantiation
}
/**
* Returns a root thread group.
* Should be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION}
*
* @return a root {@code ThreadGroup}
*/
public static ThreadGroup getRootThreadGroup() {
ThreadGroup currentTG = Thread.currentThread().getThreadGroup();
ThreadGroup parentTG = currentTG.getParent();
while (parentTG != null) {
currentTG = parentTG;
parentTG = currentTG.getParent();
}
return currentTG;
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 1995, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
* This interface is used by the Timer class. A class that uses
* Timer objects must implement this interface.
*
* @see Timer
* @author Patrick Chan
*/
public interface Timeable {
/**
* This method is executed every time a timer owned by this
* object ticks. An object can own more than one timer but
* all timers call this method when they tick;
* you can use the supplied timer parameter to determine
* which timer has ticked.
* @param timer a handle to the timer that has just ticked.
*/
public void tick(Timer timer);
}

View File

@@ -0,0 +1,647 @@
/*
* Copyright (c) 1995, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/**
A Timer object is used by algorithms that require timed events.
For example, in an animation loop, a timer would help in
determining when to change frames.
A timer has an interval which determines when it "ticks";
that is, a timer delays for the specified interval and then
it calls the owner's tick() method.
Here's an example of creating a timer with a 5 sec interval:
<pre>
class Main implements Timeable {
public void tick(Timer timer) {
System.out.println("tick");
}
public static void main(String args[]) {
(new Timer(this, 5000)).cont();
}
}
</pre>
A timer can be stopped, continued, or reset at any time.
A timer's state is not stopped while it's calling the
owner's tick() method.
A timer can be regular or irregular. If in regular mode,
a timer ticks at the specified interval, regardless of
how long the owner's tick() method takes. While the timer
is running, no ticks are ever discarded. That means that if
the owner's tick() method takes longer than the interval,
the ticks that would have occurred are delivered immediately.
In irregular mode, a timer starts delaying for exactly
the specified interval only after the tick() method returns.
Synchronization issues: do not hold the timer's monitor
while calling any of the Timer operations below otherwise
the Timer class will deadlock.
@author Patrick Chan
*/
/*
Synchronization issues: there are two data structures that
require locking. A Timer object and the Timer queue
(described in the TimerThread class). To avoid deadlock,
the timer queue monitor is always acquired before the timer
object's monitor. However, the timer queue monitor is acquired
only if the timer operation will make use of the timer
queue, e.g. stop().
The class monitor on the class TimerThread severs as the monitor
to the timer queue.
Possible feature: perhaps a timer should have an associated
thread priority. The thread that makes the callback temporarily
takes on that priority before calling the owner's tick() method.
*/
public class Timer {
/**
* This is the owner of the timer. Its tick method is
* called when the timer ticks.
*/
public Timeable owner;
/*
* This is the interval of time in ms.
*/
long interval;
/*
* This variable is used for two different purposes.
* This is done in order to save space.
* If 'stopped' is true, this variable holds the time
* that the timer was stopped; otherwise, this variable
* is used by the TimerThread to determine when the timer
* should tick.
*/
long sleepUntil;
/*
* This is the time remaining before the timer ticks. It
* is only valid if 'stopped' is true. If the timer is
* continued, the next tick will happen remaingTime
* milliseconds later.
*/
long remainingTime;
/*
* True iff the timer is in regular mode.
*/
boolean regular;
/*
* True iff the timer has been stopped.
*/
boolean stopped;
/* **************************************************************
* Timer queue-related variables
* ************************************************************** */
/*
* A link to another timer object. This is used while the
* timer object is enqueued in the timer queue.
*/
Timer next;
/* **************************************************************
* Timer methods
* ************************************************************** */
/*
* This variable holds a handle to the TimerThread class for
* the purpose of getting at the class monitor. The reason
* why Class.forName("TimerThread") is not used is because it
* doesn't appear to work when loaded via a net class loader.
*/
static TimerThread timerThread = null;
/**
* Creates a timer object that is owned by 'owner' and
* with the interval 'interval' milliseconds. The new timer
* object is stopped and is regular. getRemainingTime()
* return 'interval' at this point. getStopTime() returns
* the time this object was created.
* @param owner owner of the timer object
* @param interval interval of the timer in milliseconds
*/
public Timer(Timeable owner, long interval) {
this.owner = owner;
this.interval = interval;
remainingTime = interval;
regular = true;
sleepUntil = System.currentTimeMillis();
stopped = true;
synchronized (getClass()) {
if (timerThread == null) {
timerThread = new TimerThread();
}
}
}
/**
* Returns true if this timer is stopped.
*/
public synchronized boolean isStopped() {
return stopped;
}
/**
* Stops the timer. The amount of time the timer has already
* delayed is saved so if the timer is continued, it will only
* delay for the amount of time remaining.
* Note that even after stopping a timer, one more tick may
* still occur.
* This method is MT-safe; i.e. it is synchronized but for
* implementation reasons, the synchronized modifier cannot
* be included in the method declaration.
*/
public void stop() {
long now = System.currentTimeMillis();
synchronized (timerThread) {
synchronized (this) {
if (!stopped) {
TimerThread.dequeue(this);
remainingTime = Math.max(0, sleepUntil - now);
sleepUntil = now; // stop time
stopped = true;
}
}
}
}
/**
* Continue the timer. The next tick will come at getRemainingTime()
* milliseconds later. If the timer is not stopped, this
* call will be a no-op.
* This method is MT-safe; i.e. it is synchronized but for
* implementation reasons, the synchronized modifier cannot
* be included in the method declaration.
*/
public void cont() {
synchronized (timerThread) {
synchronized (this) {
if (stopped) {
// The TimerTickThread avoids requeuing the
// timer only if the sleepUntil value has changed.
// The following guarantees that the sleepUntil
// value will be different; without this guarantee,
// it's theoretically possible for the timer to be
// inserted twice.
sleepUntil = Math.max(sleepUntil + 1,
System.currentTimeMillis() + remainingTime);
TimerThread.enqueue(this);
stopped = false;
}
}
}
}
/**
* Resets the timer's remaining time to the timer's interval.
* If the timer's running state is not altered.
*/
public void reset() {
synchronized (timerThread) {
synchronized (this) {
setRemainingTime(interval);
}
}
}
/**
* Returns the time at which the timer was last stopped. The
* return value is valid only if the timer is stopped.
*/
public synchronized long getStopTime() {
return sleepUntil;
}
/**
* Returns the timer's interval.
*/
public synchronized long getInterval() {
return interval;
}
/**
* Changes the timer's interval. The new interval setting
* does not take effect until after the next tick.
* This method does not alter the remaining time or the
* running state of the timer.
* @param interval new interval of the timer in milliseconds
*/
public synchronized void setInterval(long interval) {
this.interval = interval;
}
/**
* Returns the remaining time before the timer's next tick.
* The return value is valid only if timer is stopped.
*/
public synchronized long getRemainingTime() {
return remainingTime;
}
/**
* Sets the remaining time before the timer's next tick.
* This method does not alter the timer's running state.
* This method is MT-safe; i.e. it is synchronized but for
* implementation reasons, the synchronized modifier cannot
* be included in the method declaration.
* @param time new remaining time in milliseconds.
*/
public void setRemainingTime(long time) {
synchronized (timerThread) {
synchronized (this) {
if (stopped) {
remainingTime = time;
} else {
stop();
remainingTime = time;
cont();
}
}
}
}
/**
* In regular mode, a timer ticks at the specified interval,
* regardless of how long the owner's tick() method takes.
* While the timer is running, no ticks are ever discarded.
* That means that if the owner's tick() method takes longer
* than the interval, the ticks that would have occurred are
* delivered immediately.
*
* In irregular mode, a timer starts delaying for exactly
* the specified interval only after the tick() method returns.
*/
public synchronized void setRegular(boolean regular) {
this.regular = regular;
}
/*
* This method is used only for testing purposes.
*/
protected Thread getTimerThread() {
return TimerThread.timerThread;
}
}
/*
This class implements the timer queue and is exclusively used by the
Timer class. There are only two methods exported to the Timer class -
enqueue, for inserting a timer into queue and dequeue, for removing
a timer from the queue.
A timer in the timer queue is awaiting a tick. When a timer is to be
ticked, it is removed from the timer queue before the owner's tick()
method is called.
A single timer thread manages the timer queue. This timer thread
looks at the head of the timer queue and delays until it's time for
the timer to tick. When the time comes, the timer thread creates a
callback thread to call the timer owner's tick() method. The timer
thread then processes the next timer in the queue.
When a timer is inserted at the head of the queue, the timer thread is
notified. This causes the timer thread to prematurely wake up and
process the new head of the queue.
*/
class TimerThread extends Thread {
/*
* Set to true to get debugging output.
*/
public static boolean debug = false;
/*
* This is a handle to the thread managing the thread queue.
*/
static TimerThread timerThread;
/*
* This flag is set if the timer thread has been notified
* while it was in the timed wait. This flag allows the
* timer thread to tell whether or not the wait completed.
*/
static boolean notified = false;
protected TimerThread() {
super("TimerThread");
timerThread = this;
start();
}
public synchronized void run() {
while (true) {
long delay;
while (timerQueue == null) {
try {
wait();
} catch (InterruptedException ex) {
// Just drop through and check timerQueue.
}
}
notified = false;
delay = timerQueue.sleepUntil - System.currentTimeMillis();
if (delay > 0) {
try {
wait(delay);
} catch (InterruptedException ex) {
// Just drop through.
}
}
// remove from timer queue.
if (!notified) {
Timer timer = timerQueue;
timerQueue = timerQueue.next;
TimerTickThread thr = TimerTickThread.call(
timer, timer.sleepUntil);
if (debug) {
long delta = (System.currentTimeMillis() - timer.sleepUntil);
System.out.println("tick(" + thr.getName() + ","
+ timer.interval + ","+delta+ ")");
if (delta > 250) {
System.out.println("*** BIG DELAY ***");
}
}
}
}
}
/* *******************************************************
Timer Queue
******************************************************* */
/*
* The timer queue is a queue of timers waiting to tick.
*/
static Timer timerQueue = null;
/*
* Uses timer.sleepUntil to determine where in the queue
* to insert the timer object.
* A new ticker thread is created only if the timer
* is inserted at the beginning of the queue.
* The timer must not already be in the queue.
* Assumes the caller has the TimerThread monitor.
*/
static protected void enqueue(Timer timer) {
Timer prev = null;
Timer cur = timerQueue;
if (cur == null || timer.sleepUntil <= cur.sleepUntil) {
// insert at front of queue
timer.next = timerQueue;
timerQueue = timer;
notified = true;
timerThread.notify();
} else {
do {
prev = cur;
cur = cur.next;
} while (cur != null && timer.sleepUntil > cur.sleepUntil);
// insert or append to the timer queue
timer.next = cur;
prev.next = timer;
}
if (debug) {
long now = System.currentTimeMillis();
System.out.print(Thread.currentThread().getName()
+ ": enqueue " + timer.interval + ": ");
cur = timerQueue;
while(cur != null) {
long delta = cur.sleepUntil - now;
System.out.print(cur.interval + "(" + delta + ") ");
cur = cur.next;
}
System.out.println();
}
}
/*
* If the timer is not in the queue, returns false;
* otherwise removes the timer from the timer queue and returns true.
* Assumes the caller has the TimerThread monitor.
*/
static protected boolean dequeue(Timer timer) {
Timer prev = null;
Timer cur = timerQueue;
while (cur != null && cur != timer) {
prev = cur;
cur = cur.next;
}
if (cur == null) {
if (debug) {
System.out.println(Thread.currentThread().getName()
+ ": dequeue " + timer.interval + ": no-op");
}
return false;
} if (prev == null) {
timerQueue = timer.next;
notified = true;
timerThread.notify();
} else {
prev.next = timer.next;
}
timer.next = null;
if (debug) {
long now = System.currentTimeMillis();
System.out.print(Thread.currentThread().getName()
+ ": dequeue " + timer.interval + ": ");
cur = timerQueue;
while(cur != null) {
long delta = cur.sleepUntil - now;
System.out.print(cur.interval + "(" + delta + ") ");
cur = cur.next;
}
System.out.println();
}
return true;
}
/*
* Inserts the timer back into the queue. This method
* is used by a callback thread after it has called the
* timer owner's tick() method. This method recomputes
* the sleepUntil field.
* Assumes the caller has the TimerThread and Timer monitor.
*/
protected static void requeue(Timer timer) {
if (!timer.stopped) {
long now = System.currentTimeMillis();
if (timer.regular) {
timer.sleepUntil += timer.interval;
} else {
timer.sleepUntil = now + timer.interval;
}
enqueue(timer);
} else if (debug) {
System.out.println(Thread.currentThread().getName()
+ ": requeue " + timer.interval + ": no-op");
}
}
}
/*
This class implements a simple thread whose only purpose is to call a
timer owner's tick() method. A small fixed-sized pool of threads is
maintained and is protected by the class monitor. If the pool is
exhausted, a new thread is temporarily created and destroyed when
done.
A thread that's in the pool waits on it's own monitor. When the
thread is retrieved from the pool, the retriever notifies the thread's
monitor.
*/
class TimerTickThread extends Thread {
/*
* Maximum size of the thread pool.
*/
static final int MAX_POOL_SIZE = 3;
/*
* Number of threads in the pool.
*/
static int curPoolSize = 0;
/*
* The pool of timer threads.
*/
static TimerTickThread pool = null;
/*
* Is used when linked into the thread pool.
*/
TimerTickThread next = null;
/*
* This is the handle to the timer whose owner's
* tick() method will be called.
*/
Timer timer;
/*
* The value of a timer's sleepUntil value is captured here.
* This is used to determine whether or not the timer should
* be reinserted into the queue. If the timer's sleepUntil
* value has changed, the timer is not reinserted.
*/
long lastSleepUntil;
/*
* Creates a new callback thread to call the timer owner's
* tick() method. A thread is taken from the pool if one
* is available, otherwise, a new thread is created.
* The thread handle is returned.
*/
protected static synchronized TimerTickThread call(
Timer timer, long sleepUntil) {
TimerTickThread thread = pool;
if (thread == null) {
// create one.
thread = new TimerTickThread();
thread.timer = timer;
thread.lastSleepUntil = sleepUntil;
thread.start();
} else {
pool = pool.next;
thread.timer = timer;
thread.lastSleepUntil = sleepUntil;
synchronized (thread) {
thread.notify();
}
}
return thread;
}
/*
* Returns false if the thread should simply exit;
* otherwise the thread is returned the pool, where
* it waits to be notified. (I did try to use the
* class monitor but the time between the notify
* and breaking out of the wait seemed to take
* significantly longer; need to look into this later.)
*/
private boolean returnToPool() {
synchronized (getClass()) {
if (curPoolSize >= MAX_POOL_SIZE) {
return false;
}
next = pool;
pool = this;
curPoolSize++;
timer = null;
}
while (timer == null) {
synchronized (this) {
try {
wait();
} catch (InterruptedException ex) {
// Just drop through and retest timer.
}
}
}
synchronized (getClass()) {
curPoolSize--;
}
return true;
}
public void run() {
do {
timer.owner.tick(timer);
synchronized (TimerThread.timerThread) {
synchronized (timer) {
if (lastSleepUntil == timer.sleepUntil) {
TimerThread.requeue(timer);
}
}
}
} while (returnToPool());
}
}

View File

@@ -0,0 +1,233 @@
/*
* Copyright (c) 1995, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.PushbackInputStream;
import java.io.PrintStream;
import java.io.IOException;
/**
* This class implements a robust character decoder. The decoder will
* converted encoded text into binary data.
*
* The basic encoding unit is a 3 character atom. It encodes two bytes
* of data. Bytes are encoded into a 64 character set, the characters
* were chosen specifically because they appear in all codesets.
* We don't care what their numerical equivalent is because
* we use a character array to map them. This is like UUencoding
* with the dependency on ASCII removed.
*
* The three chars that make up an atom are encoded as follows:
* <pre>
* 00xxxyyy 00axxxxx 00byyyyy
* 00 = leading zeros, all values are 0 - 63
* xxxyyy - Top 3 bits of X, Top 3 bits of Y
* axxxxx - a = X parity bit, xxxxx lower 5 bits of X
* byyyyy - b = Y parity bit, yyyyy lower 5 bits of Y
* </pre>
*
* The atoms are arranged into lines suitable for inclusion into an
* email message or text file. The number of bytes that are encoded
* per line is 48 which keeps the total line length under 80 chars)
*
* Each line has the form(
* <pre>
* *(LLSS)(DDDD)(DDDD)(DDDD)...(CRC)
* Where each (xxx) represents a three character atom.
* (LLSS) - 8 bit length (high byte), and sequence number
* modulo 256;
* (DDDD) - Data byte atoms, if length is odd, last data
* atom has (DD00) (high byte data, low byte 0)
* (CRC) - 16 bit CRC for the line, includes length,
* sequence, and all data bytes. If there is a
* zero pad byte (odd length) it is _NOT_
* included in the CRC.
* </pre>
*
* If an error is encountered during decoding this class throws a
* CEFormatException. The specific detail messages are:
*
* <pre>
* "UCDecoder: High byte parity error."
* "UCDecoder: Low byte parity error."
* "UCDecoder: Out of sequence line."
* "UCDecoder: CRC check failed."
* </pre>
*
* @author Chuck McManis
* @see CharacterEncoder
* @see UCEncoder
*/
public class UCDecoder extends CharacterDecoder {
/** This class encodes two bytes per atom. */
protected int bytesPerAtom() {
return (2);
}
/** this class encodes 48 bytes per line */
protected int bytesPerLine() {
return (48);
}
/* this is the UCE mapping of 0-63 to characters .. */
private final static byte map_array[] = {
// 0 1 2 3 4 5 6 7
(byte)'0',(byte)'1',(byte)'2',(byte)'3',(byte)'4',(byte)'5',(byte)'6',(byte)'7', // 0
(byte)'8',(byte)'9',(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F', // 1
(byte)'G',(byte)'H',(byte)'I',(byte)'J',(byte)'K',(byte)'L',(byte)'M',(byte)'N', // 2
(byte)'O',(byte)'P',(byte)'Q',(byte)'R',(byte)'S',(byte)'T',(byte)'U',(byte)'V', // 3
(byte)'W',(byte)'X',(byte)'Y',(byte)'Z',(byte)'a',(byte)'b',(byte)'c',(byte)'d', // 4
(byte)'e',(byte)'f',(byte)'g',(byte)'h',(byte)'i',(byte)'j',(byte)'k',(byte)'l', // 5
(byte)'m',(byte)'n',(byte)'o',(byte)'p',(byte)'q',(byte)'r',(byte)'s',(byte)'t', // 6
(byte)'u',(byte)'v',(byte)'w',(byte)'x',(byte)'y',(byte)'z',(byte)'(',(byte)')' // 7
};
private int sequence;
private byte tmp[] = new byte[2];
private CRC16 crc = new CRC16();
/**
* Decode one atom - reads the characters from the input stream, decodes
* them, and checks for valid parity.
*/
protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int l) throws IOException {
int i, p1, p2, np1, np2;
byte a = -1, b = -1, c = -1;
byte high_byte, low_byte;
byte tmp[] = new byte[3];
i = inStream.read(tmp);
if (i != 3) {
throw new CEStreamExhausted();
}
for (i = 0; (i < 64) && ((a == -1) || (b == -1) || (c == -1)); i++) {
if (tmp[0] == map_array[i]) {
a = (byte) i;
}
if (tmp[1] == map_array[i]) {
b = (byte) i;
}
if (tmp[2] == map_array[i]) {
c = (byte) i;
}
}
high_byte = (byte) (((a & 0x38) << 2) + (b & 0x1f));
low_byte = (byte) (((a & 0x7) << 5) + (c & 0x1f));
p1 = 0;
p2 = 0;
for (i = 1; i < 256; i = i * 2) {
if ((high_byte & i) != 0)
p1++;
if ((low_byte & i) != 0)
p2++;
}
np1 = (b & 32) / 32;
np2 = (c & 32) / 32;
if ((p1 & 1) != np1) {
throw new CEFormatException("UCDecoder: High byte parity error.");
}
if ((p2 & 1) != np2) {
throw new CEFormatException("UCDecoder: Low byte parity error.");
}
outStream.write(high_byte);
crc.update(high_byte);
if (l == 2) {
outStream.write(low_byte);
crc.update(low_byte);
}
}
private ByteArrayOutputStream lineAndSeq = new ByteArrayOutputStream(2);
/**
* decodeBufferPrefix initializes the sequence number to zero.
*/
protected void decodeBufferPrefix(PushbackInputStream inStream, OutputStream outStream) {
sequence = 0;
}
/**
* decodeLinePrefix reads the sequence number and the number of
* encoded bytes from the line. If the sequence number is not the
* previous sequence number + 1 then an exception is thrown.
* UCE lines are line terminator immune, they all start with *
* so the other thing this method does is scan for the next line
* by looking for the * character.
*
* @exception CEFormatException out of sequence lines detected.
*/
protected int decodeLinePrefix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
int i;
int nLen, nSeq;
byte xtmp[];
int c;
crc.value = 0;
while (true) {
c = inStream.read(tmp, 0, 1);
if (c == -1) {
throw new CEStreamExhausted();
}
if (tmp[0] == '*') {
break;
}
}
lineAndSeq.reset();
decodeAtom(inStream, lineAndSeq, 2);
xtmp = lineAndSeq.toByteArray();
nLen = xtmp[0] & 0xff;
nSeq = xtmp[1] & 0xff;
if (nSeq != sequence) {
throw new CEFormatException("UCDecoder: Out of sequence line.");
}
sequence = (sequence + 1) & 0xff;
return (nLen);
}
/**
* this method reads the CRC that is at the end of every line and
* verifies that it matches the computed CRC.
*
* @exception CEFormatException if CRC check fails.
*/
protected void decodeLineSuffix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
int i;
int lineCRC = crc.value;
int readCRC;
byte tmp[];
lineAndSeq.reset();
decodeAtom(inStream, lineAndSeq, 2);
tmp = lineAndSeq.toByteArray();
readCRC = ((tmp[0] << 8) & 0xFF00) + (tmp[1] & 0xff);
if (readCRC != lineCRC) {
throw new CEFormatException("UCDecoder: CRC check failed.");
}
}
}

View File

@@ -0,0 +1,178 @@
/*
* Copyright (c) 1995, 1997, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.IOException;
/**
* This class implements a robust character encoder. The encoder is designed
* to convert binary data into printable characters. The characters are
* assumed to exist but they are not assumed to be ASCII, the complete set
* is 0-9, A-Z, a-z, "(", and ")".
*
* The basic encoding unit is a 3 character atom. It encodes two bytes
* of data. Bytes are encoded into a 64 character set, the characters
* were chosen specifically because they appear in all codesets.
* We don't care what their numerical equivalent is because
* we use a character array to map them. This is like UUencoding
* with the dependency on ASCII removed.
*
* The three chars that make up an atom are encoded as follows:
* <pre>
* 00xxxyyy 00axxxxx 00byyyyy
* 00 = leading zeros, all values are 0 - 63
* xxxyyy - Top 3 bits of X, Top 3 bits of Y
* axxxxx - a = X parity bit, xxxxx lower 5 bits of X
* byyyyy - b = Y parity bit, yyyyy lower 5 bits of Y
* </pre>
*
* The atoms are arranged into lines suitable for inclusion into an
* email message or text file. The number of bytes that are encoded
* per line is 48 which keeps the total line length under 80 chars)
*
* Each line has the form(
* <pre>
* *(LLSS)(DDDD)(DDDD)(DDDD)...(CRC)
* Where each (xxx) represents a three character atom.
* (LLSS) - 8 bit length (high byte), and sequence number
* modulo 256;
* (DDDD) - Data byte atoms, if length is odd, last data
* atom has (DD00) (high byte data, low byte 0)
* (CRC) - 16 bit CRC for the line, includes length,
* sequence, and all data bytes. If there is a
* zero pad byte (odd length) it is _NOT_
* included in the CRC.
* </pre>
*
* @author Chuck McManis
* @see CharacterEncoder
* @see UCDecoder
*/
public class UCEncoder extends CharacterEncoder {
/** this clase encodes two bytes per atom */
protected int bytesPerAtom() {
return (2);
}
/** this class encodes 48 bytes per line */
protected int bytesPerLine() {
return (48);
}
/* this is the UCE mapping of 0-63 to characters .. */
private final static byte map_array[] = {
// 0 1 2 3 4 5 6 7
(byte)'0',(byte)'1',(byte)'2',(byte)'3',(byte)'4',(byte)'5',(byte)'6',(byte)'7', // 0
(byte)'8',(byte)'9',(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F', // 1
(byte)'G',(byte)'H',(byte)'I',(byte)'J',(byte)'K',(byte)'L',(byte)'M',(byte)'N', // 2
(byte)'O',(byte)'P',(byte)'Q',(byte)'R',(byte)'S',(byte)'T',(byte)'U',(byte)'V', // 3
(byte)'W',(byte)'X',(byte)'Y',(byte)'Z',(byte)'a',(byte)'b',(byte)'c',(byte)'d', // 4
(byte)'e',(byte)'f',(byte)'g',(byte)'h',(byte)'i',(byte)'j',(byte)'k',(byte)'l', // 5
(byte)'m',(byte)'n',(byte)'o',(byte)'p',(byte)'q',(byte)'r',(byte)'s',(byte)'t', // 6
(byte)'u',(byte)'v',(byte)'w',(byte)'x',(byte)'y',(byte)'z',(byte)'(',(byte)')' // 7
};
private int sequence;
private byte tmp[] = new byte[2];
private CRC16 crc = new CRC16();
/**
* encodeAtom - take two bytes and encode them into the correct
* three characters. If only one byte is to be encoded, the other
* must be zero. The padding byte is not included in the CRC computation.
*/
protected void encodeAtom(OutputStream outStream, byte data[], int offset, int len) throws IOException
{
int i;
int p1, p2; // parity bits
byte a, b;
a = data[offset];
if (len == 2) {
b = data[offset+1];
} else {
b = 0;
}
crc.update(a);
if (len == 2) {
crc.update(b);
}
outStream.write(map_array[((a >>> 2) & 0x38) + ((b >>> 5) & 0x7)]);
p1 = 0; p2 = 0;
for (i = 1; i < 256; i = i * 2) {
if ((a & i) != 0) {
p1++;
}
if ((b & i) != 0) {
p2++;
}
}
p1 = (p1 & 1) * 32;
p2 = (p2 & 1) * 32;
outStream.write(map_array[(a & 31) + p1]);
outStream.write(map_array[(b & 31) + p2]);
return;
}
/**
* Each UCE encoded line starts with a prefix of '*[XXX]', where
* the sequence number and the length are encoded in the first
* atom.
*/
protected void encodeLinePrefix(OutputStream outStream, int length) throws IOException {
outStream.write('*');
crc.value = 0;
tmp[0] = (byte) length;
tmp[1] = (byte) sequence;
sequence = (sequence + 1) & 0xff;
encodeAtom(outStream, tmp, 0, 2);
}
/**
* each UCE encoded line ends with YYY and encoded version of the
* 16 bit checksum. The most significant byte of the check sum
* is always encoded FIRST.
*/
protected void encodeLineSuffix(OutputStream outStream) throws IOException {
tmp[0] = (byte) ((crc.value >>> 8) & 0xff);
tmp[1] = (byte) (crc.value & 0xff);
encodeAtom(outStream, tmp, 0, 2);
super.pStream.println();
}
/**
* The buffer prefix code is used to initialize the sequence number
* to zero.
*/
protected void encodeBufferPrefix(OutputStream a) throws IOException {
sequence = 0;
super.encodeBufferPrefix(a);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,274 @@
/*
* Copyright (c) 1995, 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.PushbackInputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.IOException;
/**
* This class implements a Berkeley uu character decoder. This decoder
* was made famous by the uudecode program.
*
* The basic character coding is algorithmic, taking 6 bits of binary
* data and adding it to an ASCII ' ' (space) character. This converts
* these six bits into a printable representation. Note that it depends
* on the ASCII character encoding standard for english. Groups of three
* bytes are converted into 4 characters by treating the three bytes
* a four 6 bit groups, group 1 is byte 1's most significant six bits,
* group 2 is byte 1's least significant two bits plus byte 2's four
* most significant bits. etc.
*
* In this encoding, the buffer prefix is:
* <pre>
* begin [mode] [filename]
* </pre>
*
* This is followed by one or more lines of the form:
* <pre>
* (len)(data)(data)(data) ...
* </pre>
* where (len) is the number of bytes on this line. Note that groupings
* are always four characters, even if length is not a multiple of three
* bytes. When less than three characters are encoded, the values of the
* last remaining bytes is undefined and should be ignored.
*
* The last line of data in a uuencoded buffer is represented by a single
* space character. This is translated by the decoding engine to a line
* length of zero. This is immediately followed by a line which contains
* the word 'end[newline]'
*
* If an error is encountered during decoding this class throws a
* CEFormatException. The specific detail messages are:
*
* <pre>
* "UUDecoder: No begin line."
* "UUDecoder: Malformed begin line."
* "UUDecoder: Short Buffer."
* "UUDecoder: Bad Line Length."
* "UUDecoder: Missing 'end' line."
* </pre>
*
* @author Chuck McManis
* @see CharacterDecoder
* @see UUEncoder
*/
public class UUDecoder extends CharacterDecoder {
/**
* This string contains the name that was in the buffer being decoded.
*/
public String bufferName;
/**
* Represents UNIX(tm) mode bits. Generally three octal digits
* representing read, write, and execute permission of the owner,
* group owner, and others. They should be interpreted as the bit groups:
* <pre>
* (owner) (group) (others)
* rwx rwx rwx (r = read, w = write, x = execute)
*</pre>
*
*/
public int mode;
/**
* UU encoding specifies 3 bytes per atom.
*/
protected int bytesPerAtom() {
return (3);
}
/**
* All UU lines have 45 bytes on them, for line length of 15*4+1 or 61
* characters per line.
*/
protected int bytesPerLine() {
return (45);
}
/** This is used to decode the atoms */
private byte decoderBuffer[] = new byte[4];
/**
* Decode a UU atom. Note that if l is less than 3 we don't write
* the extra bits, however the encoder always encodes 4 character
* groups even when they are not needed.
*/
protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int l)
throws IOException {
int i, c1, c2, c3, c4;
int a, b, c;
StringBuffer x = new StringBuffer();
for (i = 0; i < 4; i++) {
c1 = inStream.read();
if (c1 == -1) {
throw new CEStreamExhausted();
}
x.append((char)c1);
decoderBuffer[i] = (byte) ((c1 - ' ') & 0x3f);
}
a = ((decoderBuffer[0] << 2) & 0xfc) | ((decoderBuffer[1] >>> 4) & 3);
b = ((decoderBuffer[1] << 4) & 0xf0) | ((decoderBuffer[2] >>> 2) & 0xf);
c = ((decoderBuffer[2] << 6) & 0xc0) | (decoderBuffer[3] & 0x3f);
outStream.write((byte)(a & 0xff));
if (l > 1) {
outStream.write((byte)( b & 0xff));
}
if (l > 2) {
outStream.write((byte)(c&0xff));
}
}
/**
* For uuencoded buffers, the data begins with a line of the form:
* begin MODE FILENAME
* This line always starts in column 1.
*/
protected void decodeBufferPrefix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
int c;
StringBuffer q = new StringBuffer(32);
String r;
boolean sawNewLine;
/*
* This works by ripping through the buffer until it finds a 'begin'
* line or the end of the buffer.
*/
sawNewLine = true;
while (true) {
c = inStream.read();
if (c == -1) {
throw new CEFormatException("UUDecoder: No begin line.");
}
if ((c == 'b') && sawNewLine){
c = inStream.read();
if (c == 'e') {
break;
}
}
sawNewLine = (c == '\n') || (c == '\r');
}
/*
* Now we think its begin, (we've seen ^be) so verify it here.
*/
while ((c != '\n') && (c != '\r')) {
c = inStream.read();
if (c == -1) {
throw new CEFormatException("UUDecoder: No begin line.");
}
if ((c != '\n') && (c != '\r')) {
q.append((char)c);
}
}
r = q.toString();
if (r.indexOf(' ') != 3) {
throw new CEFormatException("UUDecoder: Malformed begin line.");
}
mode = Integer.parseInt(r.substring(4,7));
bufferName = r.substring(r.indexOf(' ',6)+1);
/*
* Check for \n after \r
*/
if (c == '\r') {
c = inStream.read ();
if ((c != '\n') && (c != -1))
inStream.unread (c);
}
}
/**
* In uuencoded buffers, encoded lines start with a character that
* represents the number of bytes encoded in this line. The last
* line of input is always a line that starts with a single space
* character, which would be a zero length line.
*/
protected int decodeLinePrefix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
int c;
c = inStream.read();
if (c == ' ') {
c = inStream.read(); /* discard the (first)trailing CR or LF */
c = inStream.read(); /* check for a second one */
if ((c != '\n') && (c != -1))
inStream.unread (c);
throw new CEStreamExhausted();
} else if (c == -1) {
throw new CEFormatException("UUDecoder: Short Buffer.");
}
c = (c - ' ') & 0x3f;
if (c > bytesPerLine()) {
throw new CEFormatException("UUDecoder: Bad Line Length.");
}
return (c);
}
/**
* Find the end of the line for the next operation.
* The following sequences are recognized as end-of-line
* CR, CR LF, or LF
*/
protected void decodeLineSuffix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
int c;
while (true) {
c = inStream.read();
if (c == -1) {
throw new CEStreamExhausted();
}
if (c == '\n') {
break;
}
if (c == '\r') {
c = inStream.read();
if ((c != '\n') && (c != -1)) {
inStream.unread (c);
}
break;
}
}
}
/**
* UUencoded files have a buffer suffix which consists of the word
* end. This line should immediately follow the line with a single
* space in it.
*/
protected void decodeBufferSuffix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
int c;
c = inStream.read(decoderBuffer);
if ((decoderBuffer[0] != 'e') || (decoderBuffer[1] != 'n') ||
(decoderBuffer[2] != 'd')) {
throw new CEFormatException("UUDecoder: Missing 'end' line.");
}
}
}

View File

@@ -0,0 +1,200 @@
/*
* Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.IOException;
/**
* This class implements a Berkeley uu character encoder. This encoder
* was made famous by uuencode program.
*
* The basic character coding is algorithmic, taking 6 bits of binary
* data and adding it to an ASCII ' ' (space) character. This converts
* these six bits into a printable representation. Note that it depends
* on the ASCII character encoding standard for english. Groups of three
* bytes are converted into 4 characters by treating the three bytes
* a four 6 bit groups, group 1 is byte 1's most significant six bits,
* group 2 is byte 1's least significant two bits plus byte 2's four
* most significant bits. etc.
*
* In this encoding, the buffer prefix is:
* <pre>
* begin [mode] [filename]
* </pre>
*
* This is followed by one or more lines of the form:
* <pre>
* (len)(data)(data)(data) ...
* </pre>
* where (len) is the number of bytes on this line. Note that groupings
* are always four characters, even if length is not a multiple of three
* bytes. When less than three characters are encoded, the values of the
* last remaining bytes is undefined and should be ignored.
*
* The last line of data in a uuencoded file is represented by a single
* space character. This is translated by the decoding engine to a line
* length of zero. This is immediately followed by a line which contains
* the word 'end[newline]'
*
* @author Chuck McManis
* @see CharacterEncoder
* @see UUDecoder
*/
public class UUEncoder extends CharacterEncoder {
/**
* This name is stored in the begin line.
*/
private String bufferName;
/**
* Represents UNIX(tm) mode bits. Generally three octal digits representing
* read, write, and execute permission of the owner, group owner, and
* others. They should be interpreted as the bit groups:
* (owner) (group) (others)
* rwx rwx rwx (r = read, w = write, x = execute)
*
* By default these are set to 644 (UNIX rw-r--r-- permissions).
*/
private int mode;
/**
* Default - buffer begin line will be:
* <pre>
* begin 644 encoder.buf
* </pre>
*/
public UUEncoder() {
bufferName = "encoder.buf";
mode = 644;
}
/**
* Specifies a name for the encoded buffer, begin line will be:
* <pre>
* begin 644 [FNAME]
* </pre>
*/
public UUEncoder(String fname) {
bufferName = fname;
mode = 644;
}
/**
* Specifies a name and mode for the encoded buffer, begin line will be:
* <pre>
* begin [MODE] [FNAME]
* </pre>
*/
public UUEncoder(String fname, int newMode) {
bufferName = fname;
mode = newMode;
}
/** number of bytes per atom in uuencoding is 3 */
protected int bytesPerAtom() {
return (3);
}
/** number of bytes per line in uuencoding is 45 */
protected int bytesPerLine() {
return (45);
}
/**
* encodeAtom - take three bytes and encodes them into 4 characters
* If len is less than 3 then remaining bytes are filled with '1'.
* This insures that the last line won't end in spaces and potentiallly
* be truncated.
*/
protected void encodeAtom(OutputStream outStream, byte data[], int offset, int len)
throws IOException {
byte a, b = 1, c = 1;
int c1, c2, c3, c4;
a = data[offset];
if (len > 1) {
b = data[offset+1];
}
if (len > 2) {
c = data[offset+2];
}
c1 = (a >>> 2) & 0x3f;
c2 = ((a << 4) & 0x30) | ((b >>> 4) & 0xf);
c3 = ((b << 2) & 0x3c) | ((c >>> 6) & 0x3);
c4 = c & 0x3f;
outStream.write(c1 + ' ');
outStream.write(c2 + ' ');
outStream.write(c3 + ' ');
outStream.write(c4 + ' ');
return;
}
/**
* Encode the line prefix which consists of the single character. The
* lenght is added to the value of ' ' (32 decimal) and printed.
*/
protected void encodeLinePrefix(OutputStream outStream, int length)
throws IOException {
outStream.write((length & 0x3f) + ' ');
}
/**
* The line suffix for uuencoded files is simply a new line.
*/
protected void encodeLineSuffix(OutputStream outStream) throws IOException {
pStream.println();
}
/**
* encodeBufferPrefix writes the begin line to the output stream.
*/
protected void encodeBufferPrefix(OutputStream a) throws IOException {
super.pStream = new PrintStream(a);
super.pStream.print("begin "+mode+" ");
if (bufferName != null) {
super.pStream.println(bufferName);
} else {
super.pStream.println("encoder.bin");
}
super.pStream.flush();
}
/**
* encodeBufferSuffix writes the single line containing space (' ') and
* the line containing the word 'end' to the output stream.
*/
protected void encodeBufferSuffix(OutputStream a) throws IOException {
super.pStream.println(" \nend");
super.pStream.flush();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,426 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import static java.lang.Thread.State.*;
import java.io.IOException;
import java.security.AccessControlException;
import java.util.Properties;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class VM {
/* The following methods used to be native methods that instruct
* the VM to selectively suspend certain threads in low-memory
* situations. They are inherently dangerous and not implementable
* on native threads. We removed them in JDK 1.2. The skeletons
* remain so that existing applications that use these methods
* will still work.
*/
private static boolean suspended = false;
/** @deprecated */
@Deprecated
public static boolean threadsSuspended() {
return suspended;
}
@SuppressWarnings("deprecation")
public static boolean allowThreadSuspension(ThreadGroup g, boolean b) {
return g.allowThreadSuspension(b);
}
/** @deprecated */
@Deprecated
public static boolean suspendThreads() {
suspended = true;
return true;
}
// Causes any suspended threadgroups to be resumed.
/** @deprecated */
@Deprecated
public static void unsuspendThreads() {
suspended = false;
}
// Causes threadgroups no longer marked suspendable to be resumed.
/** @deprecated */
@Deprecated
public static void unsuspendSomeThreads() {
}
/* Deprecated fields and methods -- Memory advice not supported in 1.2 */
/** @deprecated */
@Deprecated
public static final int STATE_GREEN = 1;
/** @deprecated */
@Deprecated
public static final int STATE_YELLOW = 2;
/** @deprecated */
@Deprecated
public static final int STATE_RED = 3;
/** @deprecated */
@Deprecated
public static final int getState() {
return STATE_GREEN;
}
/** @deprecated */
@Deprecated
public static void registerVMNotification(VMNotification n) { }
/** @deprecated */
@Deprecated
public static void asChange(int as_old, int as_new) { }
/** @deprecated */
@Deprecated
public static void asChange_otherthread(int as_old, int as_new) { }
/*
* Not supported in 1.2 because these will have to be exported as
* JVM functions, and we are not sure we want do that. Leaving
* here so it can be easily resurrected -- just remove the //
* comments.
*/
/**
* Resume Java profiling. All profiling data is added to any
* earlier profiling, unless <code>resetJavaProfiler</code> is
* called in between. If profiling was not started from the
* command line, <code>resumeJavaProfiler</code> will start it.
* <p>
*
* NOTE: Profiling must be enabled from the command line for a
* java.prof report to be automatically generated on exit; if not,
* writeJavaProfilerReport must be invoked to write a report.
*
* @see resetJavaProfiler
* @see writeJavaProfilerReport
*/
// public native static void resumeJavaProfiler();
/**
* Suspend Java profiling.
*/
// public native static void suspendJavaProfiler();
/**
* Initialize Java profiling. Any accumulated profiling
* information is discarded.
*/
// public native static void resetJavaProfiler();
/**
* Write the current profiling contents to the file "java.prof".
* If the file already exists, it will be overwritten.
*/
// public native static void writeJavaProfilerReport();
private static volatile boolean booted = false;
private static final Object lock = new Object();
// Invoked by by System.initializeSystemClass just before returning.
// Subsystems that are invoked during initialization can check this
// property in order to avoid doing things that should wait until the
// application class loader has been set up.
//
public static void booted() {
synchronized (lock) {
booted = true;
lock.notifyAll();
}
}
public static boolean isBooted() {
return booted;
}
// Waits until VM completes initialization
//
// This method is invoked by the Finalizer thread
public static void awaitBooted() throws InterruptedException {
synchronized (lock) {
while (!booted) {
lock.wait();
}
}
}
// A user-settable upper limit on the maximum amount of allocatable direct
// buffer memory. This value may be changed during VM initialization if
// "java" is launched with "-XX:MaxDirectMemorySize=<size>".
//
// The initial value of this field is arbitrary; during JRE initialization
// it will be reset to the value specified on the command line, if any,
// otherwise to Runtime.getRuntime().maxMemory().
//
private static long directMemory = 64 * 1024 * 1024;
// Returns the maximum amount of allocatable direct buffer memory.
// The directMemory variable is initialized during system initialization
// in the saveAndRemoveProperties method.
//
public static long maxDirectMemory() {
return directMemory;
}
// User-controllable flag that determines if direct buffers should be page
// aligned. The "-XX:+PageAlignDirectMemory" option can be used to force
// buffers, allocated by ByteBuffer.allocateDirect, to be page aligned.
private static boolean pageAlignDirectMemory;
// Returns {@code true} if the direct buffers should be page aligned. This
// variable is initialized by saveAndRemoveProperties.
public static boolean isDirectMemoryPageAligned() {
return pageAlignDirectMemory;
}
// A user-settable boolean to determine whether ClassLoader.loadClass should
// accept array syntax. This value may be changed during VM initialization
// via the system property "sun.lang.ClassLoader.allowArraySyntax".
//
// The default for 1.5 is "true", array syntax is allowed. In 1.6, the
// default will be "false". The presence of this system property to
// control array syntax allows applications the ability to preview this new
// behaviour.
//
private static boolean defaultAllowArraySyntax = false;
private static boolean allowArraySyntax = defaultAllowArraySyntax;
// The allowArraySyntax boolean is initialized during system initialization
// in the saveAndRemoveProperties method.
//
// It is initialized based on the value of the system property
// "sun.lang.ClassLoader.allowArraySyntax". If the system property is not
// provided, the default for 1.5 is "true". In 1.6, the default will be
// "false". If the system property is provided, then the value of
// allowArraySyntax will be equal to "true" if Boolean.parseBoolean()
// returns "true". Otherwise, the field will be set to "false".
//
public static boolean allowArraySyntax() {
return allowArraySyntax;
}
/**
* Returns true if the given class loader is in the system domain
* in which all permissions are granted.
*/
public static boolean isSystemDomainLoader(ClassLoader loader) {
return loader == null;
}
/**
* Returns the system property of the specified key saved at
* system initialization time. This method should only be used
* for the system properties that are not changed during runtime.
* It accesses a private copy of the system properties so
* that user's locking of the system properties object will not
* cause the library to deadlock.
*
* Note that the saved system properties do not include
* the ones set by sun.misc.Version.init().
*
*/
public static String getSavedProperty(String key) {
if (savedProps.isEmpty())
throw new IllegalStateException("Should be non-empty if initialized");
return savedProps.getProperty(key);
}
// TODO: the Property Management needs to be refactored and
// the appropriate prop keys need to be accessible to the
// calling classes to avoid duplication of keys.
private static final Properties savedProps = new Properties();
// Save a private copy of the system properties and remove
// the system properties that are not intended for public access.
//
// This method can only be invoked during system initialization.
public static void saveAndRemoveProperties(Properties props) {
if (booted)
throw new IllegalStateException("System initialization has completed");
savedProps.putAll(props);
// Set the maximum amount of direct memory. This value is controlled
// by the vm option -XX:MaxDirectMemorySize=<size>.
// The maximum amount of allocatable direct buffer memory (in bytes)
// from the system property sun.nio.MaxDirectMemorySize set by the VM.
// The system property will be removed.
String s = (String)props.remove("sun.nio.MaxDirectMemorySize");
if (s != null) {
if (s.equals("-1")) {
// -XX:MaxDirectMemorySize not given, take default
directMemory = Runtime.getRuntime().maxMemory();
} else {
long l = Long.parseLong(s);
if (l > -1)
directMemory = l;
}
}
// Check if direct buffers should be page aligned
s = (String)props.remove("sun.nio.PageAlignDirectMemory");
if ("true".equals(s))
pageAlignDirectMemory = true;
// Set a boolean to determine whether ClassLoader.loadClass accepts
// array syntax. This value is controlled by the system property
// "sun.lang.ClassLoader.allowArraySyntax".
s = props.getProperty("sun.lang.ClassLoader.allowArraySyntax");
allowArraySyntax = (s == null
? defaultAllowArraySyntax
: Boolean.parseBoolean(s));
// Remove other private system properties
// used by java.lang.Integer.IntegerCache
props.remove("java.lang.Integer.IntegerCache.high");
// used by java.util.zip.ZipFile
props.remove("sun.zip.disableMemoryMapping");
// used by sun.launcher.LauncherHelper
props.remove("sun.java.launcher.diag");
// used by sun.misc.URLClassPath
props.remove("sun.cds.enableSharedLookupCache");
}
// Initialize any miscellenous operating system settings that need to be
// set for the class libraries.
//
public static void initializeOSEnvironment() {
if (!booted) {
OSEnvironment.initialize();
}
}
/* Current count of objects pending for finalization */
private static volatile int finalRefCount = 0;
/* Peak count of objects pending for finalization */
private static volatile int peakFinalRefCount = 0;
/*
* Gets the number of objects pending for finalization.
*
* @return the number of objects pending for finalization.
*/
public static int getFinalRefCount() {
return finalRefCount;
}
/*
* Gets the peak number of objects pending for finalization.
*
* @return the peak number of objects pending for finalization.
*/
public static int getPeakFinalRefCount() {
return peakFinalRefCount;
}
/*
* Add <tt>n</tt> to the objects pending for finalization count.
*
* @param n an integer value to be added to the objects pending
* for finalization count
*/
public static void addFinalRefCount(int n) {
// The caller must hold lock to synchronize the update.
finalRefCount += n;
if (finalRefCount > peakFinalRefCount) {
peakFinalRefCount = finalRefCount;
}
}
/**
* Returns Thread.State for the given threadStatus
*/
public static Thread.State toThreadState(int threadStatus) {
if ((threadStatus & JVMTI_THREAD_STATE_RUNNABLE) != 0) {
return RUNNABLE;
} else if ((threadStatus & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) {
return BLOCKED;
} else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) != 0) {
return WAITING;
} else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) != 0) {
return TIMED_WAITING;
} else if ((threadStatus & JVMTI_THREAD_STATE_TERMINATED) != 0) {
return TERMINATED;
} else if ((threadStatus & JVMTI_THREAD_STATE_ALIVE) == 0) {
return NEW;
} else {
return RUNNABLE;
}
}
/* The threadStatus field is set by the VM at state transition
* in the hotspot implementation. Its value is set according to
* the JVM TI specification GetThreadState function.
*/
private final static int JVMTI_THREAD_STATE_ALIVE = 0x0001;
private final static int JVMTI_THREAD_STATE_TERMINATED = 0x0002;
private final static int JVMTI_THREAD_STATE_RUNNABLE = 0x0004;
private final static int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400;
private final static int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;
private final static int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
/*
* Returns first non-privileged class loader on the stack (excluding
* reflection generated frames) or the extension class loader if only
* class loaded by the boot class loader and extension class loader are
* found on the stack.
*/
public static native ClassLoader latestUserDefinedLoader0();
public static ClassLoader latestUserDefinedLoader() {
ClassLoader loader = latestUserDefinedLoader0();
if (loader != null) {
return loader;
}
try {
return Launcher.ExtClassLoader.getExtClassLoader();
} catch (IOException e) {
return null;
}
}
static {
initialize();
}
private native static void initialize();
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
/** @deprecated */
@Deprecated
public interface VMNotification {
// when the vm switches allocation states, we get notified
// (possible semantics: if the state changes while in this
// notification, don't recursively notify).
// oldState and newState may be the same if we are just releasing
// suspended threads.
void newAllocState(int oldState, int newState,
boolean threadsSuspended);
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.jar.Attributes;
/*
* Support class used by JVMTI and VM attach mechanism.
*/
public class VMSupport {
private static Properties agentProps = null;
/**
* Returns the agent properties.
*/
public static synchronized Properties getAgentProperties() {
if (agentProps == null) {
agentProps = new Properties();
initAgentProperties(agentProps);
}
return agentProps;
}
private static native Properties initAgentProperties(Properties props);
/**
* Write the given properties list to a byte array and return it. Properties with
* a key or value that is not a String is filtered out. The stream written to the byte
* array is ISO 8859-1 encoded.
*/
private static byte[] serializePropertiesToByteArray(Properties p) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
Properties props = new Properties();
// stringPropertyNames() returns a snapshot of the property keys
Set<String> keyset = p.stringPropertyNames();
for (String key : keyset) {
String value = p.getProperty(key);
props.put(key, value);
}
props.store(out, null);
return out.toByteArray();
}
public static byte[] serializePropertiesToByteArray() throws IOException {
return serializePropertiesToByteArray(System.getProperties());
}
public static byte[] serializeAgentPropertiesToByteArray() throws IOException {
return serializePropertiesToByteArray(getAgentProperties());
}
/*
* Returns true if the given JAR file has the Class-Path attribute in the
* main section of the JAR manifest. Throws RuntimeException if the given
* path is not a JAR file or some other error occurs.
*/
public static boolean isClassPathAttributePresent(String path) {
try {
Manifest man = (new JarFile(path)).getManifest();
if (man != null) {
if (man.getMainAttributes().getValue(Attributes.Name.CLASS_PATH) != null) {
return true;
}
}
return false;
} catch (IOException ioe) {
throw new RuntimeException(ioe.getMessage());
}
}
/*
* Return the temporary directory that the VM uses for the attach
* and perf data files.
*
* It is important that this directory is well-known and the
* same for all VM instances. It cannot be affected by configuration
* variables such as java.io.tmpdir.
*/
public static native String getVMTemporaryDirectory();
}

View File

@@ -0,0 +1,361 @@
/*
* 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 sun.misc;
import java.io.PrintStream;
public class Version {
private static final String launcher_name =
"openjdk";
private static final String java_version =
"1.8.0_462";
private static final String java_runtime_name =
"OpenJDK Runtime Environment";
private static final String java_profile_name =
"";
private static final String java_runtime_version =
"1.8.0_462-b08";
private static final String corretto_version =
"8.462.08.1";
static {
init();
}
public static void init() {
System.setProperty("java.version", java_version);
System.setProperty("java.runtime.version", java_runtime_version);
System.setProperty("java.runtime.name", java_runtime_name);
}
private static boolean versionsInitialized = false;
private static int jvm_major_version = 0;
private static int jvm_minor_version = 0;
private static int jvm_micro_version = 0;
private static int jvm_update_version = 0;
private static int jvm_build_number = 0;
private static String jvm_special_version = null;
private static int jdk_major_version = 0;
private static int jdk_minor_version = 0;
private static int jdk_micro_version = 0;
private static int jdk_update_version = 0;
private static int jdk_build_number = 0;
private static String jdk_special_version = null;
/**
* In case you were wondering this method is called by java -version.
* Sad that it prints to stderr; would be nicer if default printed on
* stdout.
*/
public static void print() {
print(System.err);
}
/**
* This is the same as print except that it adds an extra line-feed
* at the end, typically used by the -showversion in the launcher
*/
public static void println() {
print(System.err);
System.err.println();
}
/**
* Give a stream, it will print version info on it.
*/
public static void print(PrintStream ps) {
boolean isHeadless = false;
/* Report that we're running headless if the property is true */
String headless = System.getProperty("java.awt.headless");
if ( (headless != null) && (headless.equalsIgnoreCase("true")) ) {
isHeadless = true;
}
/* First line: platform version. */
ps.println(launcher_name + " version \"" + java_version + "\"");
/* Second line: runtime version (ie, libraries). */
ps.print(java_runtime_name + " Corretto-" + corretto_version);
ps.print(" (build " + java_runtime_version);
if (java_profile_name.length() > 0) {
// profile name
ps.print(", profile " + java_profile_name);
}
if (java_runtime_name.indexOf("Embedded") != -1 && isHeadless) {
// embedded builds report headless state
ps.print(", headless");
}
ps.println(')');
/* Third line: JVM information. */
String java_vm_name = System.getProperty("java.vm.name");
String java_vm_version = System.getProperty("java.vm.version");
String java_vm_info = System.getProperty("java.vm.info");
ps.println(java_vm_name + " Corretto-" + corretto_version +
" (build " + java_vm_version + ", " + java_vm_info + ")");
}
/**
* Returns the major version of the running JVM if it's 1.6 or newer
* or any RE VM build. It will return 0 if it's an internal 1.5 or
* 1.4.x build.
*
* @since 1.6
*/
public static synchronized int jvmMajorVersion() {
if (!versionsInitialized) {
initVersions();
}
return jvm_major_version;
}
/**
* Returns the minor version of the running JVM if it's 1.6 or newer
* or any RE VM build. It will return 0 if it's an internal 1.5 or
* 1.4.x build.
* @since 1.6
*/
public static synchronized int jvmMinorVersion() {
if (!versionsInitialized) {
initVersions();
}
return jvm_minor_version;
}
/**
* Returns the micro version of the running JVM if it's 1.6 or newer
* or any RE VM build. It will return 0 if it's an internal 1.5 or
* 1.4.x build.
* @since 1.6
*/
public static synchronized int jvmMicroVersion() {
if (!versionsInitialized) {
initVersions();
}
return jvm_micro_version;
}
/**
* Returns the update release version of the running JVM if it's
* a RE build. It will return 0 if it's an internal build.
* @since 1.6
*/
public static synchronized int jvmUpdateVersion() {
if (!versionsInitialized) {
initVersions();
}
return jvm_update_version;
}
public static synchronized String jvmSpecialVersion() {
if (!versionsInitialized) {
initVersions();
}
if (jvm_special_version == null) {
jvm_special_version = getJvmSpecialVersion();
}
return jvm_special_version;
}
public static native String getJvmSpecialVersion();
/**
* Returns the build number of the running JVM if it's a RE build
* It will return 0 if it's an internal build.
* @since 1.6
*/
public static synchronized int jvmBuildNumber() {
if (!versionsInitialized) {
initVersions();
}
return jvm_build_number;
}
/**
* Returns the major version of the running JDK.
*
* @since 1.6
*/
public static synchronized int jdkMajorVersion() {
if (!versionsInitialized) {
initVersions();
}
return jdk_major_version;
}
/**
* Returns the minor version of the running JDK.
* @since 1.6
*/
public static synchronized int jdkMinorVersion() {
if (!versionsInitialized) {
initVersions();
}
return jdk_minor_version;
}
/**
* Returns the micro version of the running JDK.
* @since 1.6
*/
public static synchronized int jdkMicroVersion() {
if (!versionsInitialized) {
initVersions();
}
return jdk_micro_version;
}
/**
* Returns the update release version of the running JDK if it's
* a RE build. It will return 0 if it's an internal build.
* @since 1.6
*/
public static synchronized int jdkUpdateVersion() {
if (!versionsInitialized) {
initVersions();
}
return jdk_update_version;
}
public static synchronized String jdkSpecialVersion() {
if (!versionsInitialized) {
initVersions();
}
if (jdk_special_version == null) {
jdk_special_version = getJdkSpecialVersion();
}
return jdk_special_version;
}
public static native String getJdkSpecialVersion();
/**
* Returns the build number of the running JDK if it's a RE build
* It will return 0 if it's an internal build.
* @since 1.6
*/
public static synchronized int jdkBuildNumber() {
if (!versionsInitialized) {
initVersions();
}
return jdk_build_number;
}
// true if JVM exports the version info including the capabilities
private static boolean jvmVersionInfoAvailable;
private static synchronized void initVersions() {
if (versionsInitialized) {
return;
}
jvmVersionInfoAvailable = getJvmVersionInfo();
if (!jvmVersionInfoAvailable) {
// parse java.vm.version for older JVM before the
// new JVM_GetVersionInfo is added.
// valid format of the version string is:
// n.n.n[_uu[c]][-<identifer>]-bxx
CharSequence cs = System.getProperty("java.vm.version");
if (cs.length() >= 5 &&
Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' &&
Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' &&
Character.isDigit(cs.charAt(4))) {
jvm_major_version = Character.digit(cs.charAt(0), 10);
jvm_minor_version = Character.digit(cs.charAt(2), 10);
jvm_micro_version = Character.digit(cs.charAt(4), 10);
cs = cs.subSequence(5, cs.length());
if (cs.charAt(0) == '_' && cs.length() >= 3) {
int nextChar = 0;
if (Character.isDigit(cs.charAt(1)) &&
Character.isDigit(cs.charAt(2)) &&
Character.isDigit(cs.charAt(3)))
{
nextChar = 4;
} else if (Character.isDigit(cs.charAt(1)) &&
Character.isDigit(cs.charAt(2)))
{
nextChar = 3;
}
try {
String uu = cs.subSequence(1, nextChar).toString();
jvm_update_version = Integer.valueOf(uu).intValue();
if (cs.length() >= nextChar + 1) {
char c = cs.charAt(nextChar);
if (c >= 'a' && c <= 'z') {
jvm_special_version = Character.toString(c);
nextChar++;
}
}
} catch (NumberFormatException e) {
// not conforming to the naming convention
return;
}
cs = cs.subSequence(nextChar, cs.length());
}
if (cs.charAt(0) == '-') {
// skip the first character
// valid format: <identifier>-bxx or bxx
// non-product VM will have -debug|-release appended
cs = cs.subSequence(1, cs.length());
String[] res = cs.toString().split("-");
for (String s : res) {
if (s.charAt(0) == 'b' && s.length() == 3 &&
Character.isDigit(s.charAt(1)) &&
Character.isDigit(s.charAt(2))) {
jvm_build_number =
Integer.valueOf(s.substring(1, 3)).intValue();
break;
}
}
}
}
}
getJdkVersionInfo();
versionsInitialized = true;
}
// Gets the JVM version info if available and sets the jvm_*_version fields
// and its capabilities.
//
// Return false if not available which implies an old VM (Tiger or before).
private static native boolean getJvmVersionInfo();
private static native void getJdkVersionInfo();
}
// Help Emacs a little because this file doesn't end in .java.
//
// Local Variables: ***
// mode: java ***
// End: ***

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for sun.misc.
*
* @author Michael Colburn
*/
public final class Messages extends java.util.ListResourceBundle {
/**
* Returns the contents of this <code>ResourceBundle</code>.
* <p>
* @return the contents of this <code>ResourceBundle</code>.
*/
protected Object[][] getContents() {
return new Object[][]{
{"optpkg.versionerror", "ERROR: Invalid version format used in {0} JAR file. Check the documentation for the supported version format."},
{"optpkg.attributeerror", "ERROR: The required {0} JAR manifest attribute is not set in {1} JAR file."},
{"optpkg.attributeserror", "ERROR: Some required JAR manifest attributes are not set in {0} JAR file."}
};
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for sun.misc.
*
* @author Michael Colburn
*/
public final class Messages_de extends java.util.ListResourceBundle {
/**
* Returns the contents of this <code>ResourceBundle</code>.
* <p>
* @return the contents of this <code>ResourceBundle</code>.
*/
protected Object[][] getContents() {
return new Object[][]{
{"optpkg.versionerror", "ERROR: In JAR-Datei {0} wurde ein ung\u00FCltiges Versionsformat verwendet. Pr\u00FCfen Sie in der Dokumentation, welches Versionsformat unterst\u00FCtzt wird."},
{"optpkg.attributeerror", "ERROR: In JAR-Datei {1} ist das erforderliche JAR-Manifestattribut {0} nicht festgelegt."},
{"optpkg.attributeserror", "ERROR: In JAR-Datei {0} sind einige erforderliche JAR-Manifestattribute nicht festgelegt."}
};
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for sun.misc.
*
* @author Michael Colburn
*/
public final class Messages_es extends java.util.ListResourceBundle {
/**
* Returns the contents of this <code>ResourceBundle</code>.
* <p>
* @return the contents of this <code>ResourceBundle</code>.
*/
protected Object[][] getContents() {
return new Object[][]{
{"optpkg.versionerror", "ERROR: el formato del archivo JAR {0} pertenece a una versi\u00F3n no v\u00E1lida. Busque en la documentaci\u00F3n el formato de una versi\u00F3n soportada."},
{"optpkg.attributeerror", "ERROR: el atributo obligatorio JAR manifest {0} no est\u00E1 definido en el archivo JAR {1}."},
{"optpkg.attributeserror", "ERROR: algunos atributos obligatorios JAR manifest no est\u00E1n definidos en el archivo JAR {0}."}
};
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for sun.misc.
*
* @author Michael Colburn
*/
public final class Messages_fr extends java.util.ListResourceBundle {
/**
* Returns the contents of this <code>ResourceBundle</code>.
* <p>
* @return the contents of this <code>ResourceBundle</code>.
*/
protected Object[][] getContents() {
return new Object[][]{
{"optpkg.versionerror", "ERREUR\u00A0: le format de version utilis\u00E9 pour le fichier JAR {0} n''est pas valide. Pour conna\u00EEtre le format de version pris en charge, consultez la documentation."},
{"optpkg.attributeerror", "ERREUR\u00A0: l''attribut manifest JAR {0} obligatoire n''est pas d\u00E9fini dans le fichier JAR {1}."},
{"optpkg.attributeserror", "ERREUR\u00A0: certains attributs manifest JAR obligatoires ne sont pas d\u00E9finis dans le fichier JAR {0}."}
};
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for sun.misc.
*
* @author Michael Colburn
*/
public final class Messages_it extends java.util.ListResourceBundle {
/**
* Returns the contents of this <code>ResourceBundle</code>.
* <p>
* @return the contents of this <code>ResourceBundle</code>.
*/
protected Object[][] getContents() {
return new Object[][]{
{"optpkg.versionerror", "ERRORE: Formato versione non valido nel file JAR {0}. Verificare nella documentazione il formato della versione supportato."},
{"optpkg.attributeerror", "ERRORE: L''attributo manifest JAR {0} richiesto non \u00E8 impostato nel file JAR {1}."},
{"optpkg.attributeserror", "ERRORE: Alcuni attributi manifesti JAR obbligatori non sono impostati nel file JAR {0}."}
};
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for sun.misc.
*
* @author Michael Colburn
*/
public final class Messages_ja extends java.util.ListResourceBundle {
/**
* Returns the contents of this <code>ResourceBundle</code>.
* <p>
* @return the contents of this <code>ResourceBundle</code>.
*/
protected Object[][] getContents() {
return new Object[][]{
{"optpkg.versionerror", "\u30A8\u30E9\u30FC: JAR\u30D5\u30A1\u30A4\u30EB{0}\u3067\u7121\u52B9\u306A\u30D0\u30FC\u30B8\u30E7\u30F3\u5F62\u5F0F\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u308B\u30D0\u30FC\u30B8\u30E7\u30F3\u5F62\u5F0F\u306B\u3064\u3044\u3066\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002"},
{"optpkg.attributeerror", "\u30A8\u30E9\u30FC: \u5FC5\u8981\u306AJAR\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5C5E\u6027{0}\u304CJAR\u30D5\u30A1\u30A4\u30EB{1}\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
{"optpkg.attributeserror", "\u30A8\u30E9\u30FC: \u8907\u6570\u306E\u5FC5\u8981\u306AJAR\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5C5E\u6027\u304CJAR\u30D5\u30A1\u30A4\u30EB{0}\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"}
};
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for sun.misc.
*
* @author Michael Colburn
*/
public final class Messages_ko extends java.util.ListResourceBundle {
/**
* Returns the contents of this <code>ResourceBundle</code>.
* <p>
* @return the contents of this <code>ResourceBundle</code>.
*/
protected Object[][] getContents() {
return new Object[][]{
{"optpkg.versionerror", "\uC624\uB958: {0} JAR \uD30C\uC77C\uC5D0 \uBD80\uC801\uD569\uD55C \uBC84\uC804 \uD615\uC2DD\uC774 \uC0AC\uC6A9\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC124\uBA85\uC11C\uC5D0\uC11C \uC9C0\uC6D0\uB418\uB294 \uBC84\uC804 \uD615\uC2DD\uC744 \uD655\uC778\uD558\uC2ED\uC2DC\uC624."},
{"optpkg.attributeerror", "\uC624\uB958: \uD544\uC694\uD55C {0} JAR manifest \uC18D\uC131\uC774 {1} JAR \uD30C\uC77C\uC5D0 \uC124\uC815\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."},
{"optpkg.attributeserror", "\uC624\uB958: \uD544\uC694\uD55C \uC77C\uBD80 JAR manifest \uC18D\uC131\uC774 {0} JAR \uD30C\uC77C\uC5D0 \uC124\uC815\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."}
};
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for sun.misc.
*
* @author Michael Colburn
*/
public final class Messages_pt_BR extends java.util.ListResourceBundle {
/**
* Returns the contents of this <code>ResourceBundle</code>.
* <p>
* @return the contents of this <code>ResourceBundle</code>.
*/
protected Object[][] getContents() {
return new Object[][]{
{"optpkg.versionerror", "ERRO: formato de vers\u00E3o inv\u00E1lido usado no arquivo JAR {0}. Verifique a documenta\u00E7\u00E3o para obter o formato de vers\u00E3o suportado."},
{"optpkg.attributeerror", "ERRO: o atributo de manifesto JAR {0} necess\u00E1rio n\u00E3o est\u00E1 definido no arquivo JAR {1}."},
{"optpkg.attributeserror", "ERRO: alguns atributos de manifesto JAR necess\u00E1rios n\u00E3o est\u00E3o definidos no arquivo JAR {0}."}
};
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for sun.misc.
*
* @author Michael Colburn
*/
public final class Messages_sv extends java.util.ListResourceBundle {
/**
* Returns the contents of this <code>ResourceBundle</code>.
* <p>
* @return the contents of this <code>ResourceBundle</code>.
*/
protected Object[][] getContents() {
return new Object[][]{
{"optpkg.versionerror", "FEL: Ogiltigt versionsformat i {0} JAR-fil. Kontrollera i dokumentationen vilket versionsformat som st\u00F6ds."},
{"optpkg.attributeerror", "FEL: Obligatoriskt JAR manifest-attribut {0} \u00E4r inte inst\u00E4llt i {1} JAR-filen."},
{"optpkg.attributeserror", "FEL: Vissa obligatoriska JAR manifest-attribut \u00E4r inte inst\u00E4llda i {0} JAR-filen."}
};
}
}

Some files were not shown because too many files have changed in this diff Show More