From eb669292855a9400cae6a47f546761c15344b330 Mon Sep 17 00:00:00 2001
From: Paul Sandoz Any exceptions thrown by either {@code accept} method are relayed
+ * to the caller; if performing this operation throws an exception, the
+ * other operation will not be performed.
+ *
+ * @param other a BiConsumer which will be chained after this BiConsumer
+ * @return a BiConsumer which performs in sequence the {@code accept} method
+ * of this BiConsumer and the {@code accept} method of the specified
+ * BiConsumer operation
+ * @throws NullPointerException if other is null
+ */
+ default BiConsumer Any exceptions thrown by either {@code accept} method are relayed
+ * to the caller; if performing this operation throws an exception, the
+ * other operation will not be performed.
+ *
+ * @param other a Consumer which will be chained after this Consumer
+ * @return a Consumer which performs in sequence the {@code accept} method
+ * of this Consumer and the {@code accept} method of the specified Consumer
+ * operation
+ * @throws NullPointerException if other is null
+ */
+ default Consumer Any exceptions thrown by either {@code accept} method are relayed
+ * to the caller; if performing this operation throws an exception, the
+ * other operation will not be performed.
+ *
+ * @param other a DoubleConsumer which will be chained after this
+ * DoubleConsumer
+ * @return an DoubleConsumer which performs in sequence the {@code accept} method
+ * of this DoubleConsumer and the {@code accept} method of the specified IntConsumer
+ * operation
+ * @throws NullPointerException if other is null
+ */
+ default DoubleConsumer chain(DoubleConsumer other) {
+ Objects.requireNonNull(other);
+ return (double t) -> { accept(t); other.accept(t); };
+ }
}
diff --git a/jdk/src/share/classes/java/util/function/DoubleFunction.java b/jdk/src/share/classes/java/util/function/DoubleFunction.java
index fcc6bb9dfde..d8141d0a8a2 100644
--- a/jdk/src/share/classes/java/util/function/DoubleFunction.java
+++ b/jdk/src/share/classes/java/util/function/DoubleFunction.java
@@ -43,5 +43,5 @@ public interface DoubleFunction Any exceptions thrown by either {@code test} method are relayed
+ * to the caller; if performing first operation throws an exception, the
+ * second operation will not be performed.
+ *
+ * @param p a predicate which will be logically-ANDed with this predicate
* @return a new predicate which returns {@code true} only if both
- * predicates return {@code true}.
+ * predicates return {@code true}
+ * @throws NullPointerException if p is null
*/
- public default DoublePredicate and(DoublePredicate p) {
+ default DoublePredicate and(DoublePredicate p) {
Objects.requireNonNull(p);
return (value) -> test(value) && p.test(value);
}
@@ -65,9 +70,9 @@ public interface DoublePredicate {
* Returns a predicate which negates the result of this predicate.
*
* @return a new predicate who's result is always the opposite of this
- * predicate.
+ * predicate
*/
- public default DoublePredicate negate() {
+ default DoublePredicate negate() {
return (value) -> !test(value);
}
@@ -77,25 +82,17 @@ public interface DoublePredicate {
* predicate returns {@code true} then the remaining predicate is not
* evaluated.
*
- * @param p a predicate which will be logically-ANDed with this predicate.
+ * Any exceptions thrown by either {@code test} method are relayed
+ * to the caller; if performing first operation throws an exception, the
+ * second operation will not be performed.
+ *
+ * @param p a predicate which will be logically-ANDed with this predicate
* @return a new predicate which returns {@code true} if either predicate
- * returns {@code true}.
+ * returns {@code true}
+ * @throws NullPointerException if p is null
*/
- public default DoublePredicate or(DoublePredicate p) {
+ default DoublePredicate or(DoublePredicate p) {
Objects.requireNonNull(p);
return (value) -> test(value) || p.test(value);
}
-
- /**
- * Returns a predicate that evaluates to {@code true} if both or neither of
- * the component predicates evaluate to {@code true}.
- *
- * @param p a predicate which will be logically-XORed with this predicate.
- * @return a predicate that evaluates to {@code true} if all or none of the
- * component predicates evaluate to {@code true}.
- */
- public default DoublePredicate xor(DoublePredicate p) {
- Objects.requireNonNull(p);
- return (value) -> test(value) ^ p.test(value);
- }
}
diff --git a/jdk/src/share/classes/java/util/function/DoubleSupplier.java b/jdk/src/share/classes/java/util/function/DoubleSupplier.java
index 9f9ab4e9f5a..c661fdff927 100644
--- a/jdk/src/share/classes/java/util/function/DoubleSupplier.java
+++ b/jdk/src/share/classes/java/util/function/DoubleSupplier.java
@@ -39,5 +39,5 @@ public interface DoubleSupplier {
*
* @return a {@code double} value
*/
- public double getAsDouble();
+ double getAsDouble();
}
diff --git a/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java b/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java
index e9be79f5bb9..39dfa6ab6a7 100644
--- a/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java
@@ -24,6 +24,8 @@
*/
package java.util.function;
+import java.util.Objects;
+
/**
* An operation on a {@code double} operand yielding a {@code double}
* result. This is the primitive type specialization of {@link UnaryOperator}
@@ -42,5 +44,46 @@ public interface DoubleUnaryOperator {
* @param operand the operand value
* @return the operation result value
*/
- public double applyAsDouble(double operand);
+ double applyAsDouble(double operand);
+
+ /**
+ * Compose a new function which applies the provided function followed by
+ * this function. If either function throws an exception, it is relayed
+ * to the caller.
+ *
+ * @param before An additional function to be applied before this function
+ * is applied
+ * @return A function which performs the provided function followed by this
+ * function
+ * @throws NullPointerException if before is null
+ */
+ default DoubleUnaryOperator compose(DoubleUnaryOperator before) {
+ Objects.requireNonNull(before);
+ return (double v) -> applyAsDouble(before.applyAsDouble(v));
+ }
+
+ /**
+ * Compose a new function which applies this function followed by the
+ * provided function. If either function throws an exception, it is relayed
+ * to the caller.
+ *
+ * @param after An additional function to be applied after this function is
+ * applied
+ * @return A function which performs this function followed by the provided
+ * function followed
+ * @throws NullPointerException if after is null
+ */
+ default DoubleUnaryOperator andThen(DoubleUnaryOperator after) {
+ Objects.requireNonNull(after);
+ return (double t) -> after.applyAsDouble(applyAsDouble(t));
+ }
+
+ /**
+ * Returns a unary operator that provides its input value as the result.
+ *
+ * @return a unary operator that provides its input value as the result
+ */
+ static DoubleUnaryOperator identity() {
+ return t -> t;
+ }
}
diff --git a/jdk/src/share/classes/java/util/function/Function.java b/jdk/src/share/classes/java/util/function/Function.java
index ff4b538c1a9..3cab4bf99d8 100644
--- a/jdk/src/share/classes/java/util/function/Function.java
+++ b/jdk/src/share/classes/java/util/function/Function.java
@@ -24,14 +24,15 @@
*/
package java.util.function;
+import java.util.Objects;
/**
* Apply a function to the input argument, yielding an appropriate result. A
* function may variously provide a mapping between types, object instances or
* keys and values or any other form of transformation upon the input.
*
- * @param Any exceptions thrown by either {@code accept} method are relayed
+ * to the caller; if performing this operation throws an exception, the
+ * other operation will not be performed.
+ *
+ * @param other an IntConsumer which will be chained after this
+ * IntConsumer
+ * @return an IntConsumer which performs in sequence the {@code accept} method
+ * of this IntConsumer and the {@code accept} method of the specified IntConsumer
+ * operation
+ * @throws NullPointerException if other is null
+ */
+ default IntConsumer chain(IntConsumer other) {
+ Objects.requireNonNull(other);
+ return (int t) -> { accept(t); other.accept(t); };
+ }
}
diff --git a/jdk/src/share/classes/java/util/function/IntFunction.java b/jdk/src/share/classes/java/util/function/IntFunction.java
index b5faecc0ea7..ec2ffcae249 100644
--- a/jdk/src/share/classes/java/util/function/IntFunction.java
+++ b/jdk/src/share/classes/java/util/function/IntFunction.java
@@ -43,5 +43,5 @@ public interface IntFunction Any exceptions thrown by either {@code test} method are relayed
+ * to the caller; if performing first operation throws an exception, the
+ * second operation will not be performed.
+ *
+ * @param p a predicate which will be logically-ANDed with this predicate
* @return a new predicate which returns {@code true} only if both
- * predicates return {@code true}.
+ * predicates return {@code true}
+ * @throws NullPointerException if p is null
*/
- public default IntPredicate and(IntPredicate p) {
+ default IntPredicate and(IntPredicate p) {
Objects.requireNonNull(p);
return (value) -> test(value) && p.test(value);
}
@@ -64,9 +69,9 @@ public interface IntPredicate {
* Returns a predicate which negates the result of this predicate.
*
* @return a new predicate who's result is always the opposite of this
- * predicate.
+ * predicate
*/
- public default IntPredicate negate() {
+ default IntPredicate negate() {
return (value) -> !test(value);
}
@@ -76,25 +81,17 @@ public interface IntPredicate {
* predicate returns {@code true} then the remaining predicate is not
* evaluated.
*
- * @param p a predicate which will be logically-ORed with this predicate.
+ * Any exceptions thrown by either {@code test} method are relayed
+ * to the caller; if performing first operation throws an exception, the
+ * second operation will not be performed.
+ *
+ * @param p a predicate which will be logically-ORed with this predicate
* @return a new predicate which returns {@code true} if either predicate
- * returns {@code true}.
+ * returns {@code true}
+ * @throws NullPointerException if p is null
*/
- public default IntPredicate or(IntPredicate p) {
+ default IntPredicate or(IntPredicate p) {
Objects.requireNonNull(p);
return (value) -> test(value) || p.test(value);
}
-
- /**
- * Returns a predicate that evaluates to {@code true} if both or neither of
- * the component predicates evaluate to {@code true}.
- *
- * @param p a predicate which will be logically-XORed with this predicate.
- * @return a predicate that evaluates to {@code true} if both or neither of
- * the component predicates evaluate to {@code true}
- */
- public default IntPredicate xor(IntPredicate p) {
- Objects.requireNonNull(p);
- return (value) -> test(value) ^ p.test(value);
- }
}
diff --git a/jdk/src/share/classes/java/util/function/IntSupplier.java b/jdk/src/share/classes/java/util/function/IntSupplier.java
index d857b7882b4..3165d3f4061 100644
--- a/jdk/src/share/classes/java/util/function/IntSupplier.java
+++ b/jdk/src/share/classes/java/util/function/IntSupplier.java
@@ -39,5 +39,5 @@ public interface IntSupplier {
*
* @return an {@code int} value
*/
- public int getAsInt();
+ int getAsInt();
}
diff --git a/jdk/src/share/classes/java/util/function/IntUnaryOperator.java b/jdk/src/share/classes/java/util/function/IntUnaryOperator.java
index a3b868dff54..2e14c151b1f 100644
--- a/jdk/src/share/classes/java/util/function/IntUnaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/IntUnaryOperator.java
@@ -24,6 +24,8 @@
*/
package java.util.function;
+import java.util.Objects;
+
/**
* An operation on a single {@code int} operand yielding an {@code int} result.
* This is the primitive type specialization of {@link UnaryOperator} for
@@ -37,10 +39,51 @@ public interface IntUnaryOperator {
/**
* Returns the {@code int} value result of the operation upon the
- * {@code int} operand.
+ * {@code int} operand.
*
* @param operand the operand value
* @return the operation result value
*/
- public int applyAsInt(int operand);
+ int applyAsInt(int operand);
+
+ /**
+ * Compose a new function which applies the provided function followed by
+ * this function. If either function throws an exception, it is relayed
+ * to the caller.
+ *
+ * @param before an additional function to be applied before this function
+ * is applied
+ * @return a function which performs the provided function followed by this
+ * function
+ * @throws NullPointerException if before is null
+ */
+ default IntUnaryOperator compose(IntUnaryOperator before) {
+ Objects.requireNonNull(before);
+ return (int v) -> applyAsInt(before.applyAsInt(v));
+ }
+
+ /**
+ * Compose a new function which applies this function followed by the
+ * provided function. If either function throws an exception, it is relayed
+ * to the caller.
+ *
+ * @param after an additional function to be applied after this function is
+ * applied
+ * @return a function which performs this function followed by the provided
+ * function followed
+ * @throws NullPointerException if after is null
+ */
+ default IntUnaryOperator andThen(IntUnaryOperator after) {
+ Objects.requireNonNull(after);
+ return (int t) -> after.applyAsInt(applyAsInt(t));
+ }
+
+ /**
+ * Returns a unary operator that provides its input value as the result.
+ *
+ * @return a unary operator that provides its input value as the result
+ */
+ static IntUnaryOperator identity() {
+ return t -> t;
+ }
}
diff --git a/jdk/src/share/classes/java/util/function/LongBinaryOperator.java b/jdk/src/share/classes/java/util/function/LongBinaryOperator.java
index d08271d30b1..f35258bea60 100644
--- a/jdk/src/share/classes/java/util/function/LongBinaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/LongBinaryOperator.java
@@ -44,5 +44,5 @@ public interface LongBinaryOperator {
* @param right the right operand value
* @return the result of the operation
*/
- public long applyAsLong(long left, long right);
+ long applyAsLong(long left, long right);
}
diff --git a/jdk/src/share/classes/java/util/function/LongConsumer.java b/jdk/src/share/classes/java/util/function/LongConsumer.java
index 072c0972a60..754af39d918 100644
--- a/jdk/src/share/classes/java/util/function/LongConsumer.java
+++ b/jdk/src/share/classes/java/util/function/LongConsumer.java
@@ -24,6 +24,8 @@
*/
package java.util.function;
+import java.util.Objects;
+
/**
* An operation which accepts a single long argument and returns no result.
* This is the {@code long}-consuming primitive type specialization of
@@ -41,5 +43,26 @@ public interface LongConsumer {
*
* @param value the input value
*/
- public void accept(long value);
+ void accept(long value);
+
+ /**
+ * Returns a {@code LongConsumer} which performs, in sequence, the operation
+ * represented by this object followed by the operation represented by
+ * another {@code LongConsumer}.
+ *
+ * Any exceptions thrown by either {@code accept} method are relayed
+ * to the caller; if performing this operation throws an exception, the
+ * other operation will not be performed.
+ *
+ * @param other a LongConsumer which will be chained after this
+ * LongConsumer
+ * @return a LongConsumer which performs in sequence the {@code accept} method
+ * of this LongConsumer and the {@code accept} method of the specified LongConsumer
+ * operation
+ * @throws NullPointerException if other is null
+ */
+ default LongConsumer chain(LongConsumer other) {
+ Objects.requireNonNull(other);
+ return (long t) -> { accept(t); other.accept(t); };
+ }
}
diff --git a/jdk/src/share/classes/java/util/function/LongFunction.java b/jdk/src/share/classes/java/util/function/LongFunction.java
index 924eb43be17..d87f22ab7e9 100644
--- a/jdk/src/share/classes/java/util/function/LongFunction.java
+++ b/jdk/src/share/classes/java/util/function/LongFunction.java
@@ -43,5 +43,5 @@ public interface LongFunction Any exceptions thrown by either {@code test} method are relayed
+ * to the caller; if performing first operation throws an exception, the
+ * second operation will not be performed.
+ *
+ * @param p a predicate which will be logically-ANDed with this predicate
* @return a new predicate which returns {@code true} only if both
- * predicates return {@code true}.
+ * predicates return {@code true}
*/
- public default LongPredicate and(LongPredicate p) {
+ default LongPredicate and(LongPredicate p) {
Objects.requireNonNull(p);
return (value) -> test(value) && p.test(value);
}
@@ -64,9 +68,9 @@ public interface LongPredicate {
* Returns a predicate which negates the result of this predicate.
*
* @return a new predicate who's result is always the opposite of this
- * predicate.
+ * predicate
*/
- public default LongPredicate negate() {
+ default LongPredicate negate() {
return (value) -> !test(value);
}
@@ -76,25 +80,17 @@ public interface LongPredicate {
* predicate returns {@code true} then the remaining predicate is not
* evaluated.
*
- * @param p a predicate which will be logically-ORed with this predicate.
+ * Any exceptions thrown by either {@code test} method are relayed
+ * to the caller; if performing first operation throws an exception, the
+ * second operation will not be performed.
+ *
+ * @param p a predicate which will be logically-ORed with this predicate
* @return a new predicate which returns {@code true} if either predicate
- * returns {@code true}.
+ * returns {@code true}
+ * @throws NullPointerException if p is null
*/
- public default LongPredicate or(LongPredicate p) {
+ default LongPredicate or(LongPredicate p) {
Objects.requireNonNull(p);
return (value) -> test(value) || p.test(value);
}
-
- /**
- * Returns a predicate that evaluates to {@code true} if both or neither of
- * the component predicates evaluate to {@code true}.
- *
- * @param p a predicate which will be logically-XORed with this predicate.
- * @return a predicate that evaluates to {@code true} if both or neither of
- * the component predicates evaluate to {@code true}.
- */
- public default LongPredicate xor(LongPredicate p) {
- Objects.requireNonNull(p);
- return (value) -> test(value) ^ p.test(value);
- }
}
diff --git a/jdk/src/share/classes/java/util/function/LongSupplier.java b/jdk/src/share/classes/java/util/function/LongSupplier.java
index 2d5a3def105..d88c399a790 100644
--- a/jdk/src/share/classes/java/util/function/LongSupplier.java
+++ b/jdk/src/share/classes/java/util/function/LongSupplier.java
@@ -39,5 +39,5 @@ public interface LongSupplier {
*
* @return a {@code long} value
*/
- public long getAsLong();
+ long getAsLong();
}
diff --git a/jdk/src/share/classes/java/util/function/LongUnaryOperator.java b/jdk/src/share/classes/java/util/function/LongUnaryOperator.java
index 3632e2a118a..a32918fc56b 100644
--- a/jdk/src/share/classes/java/util/function/LongUnaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/LongUnaryOperator.java
@@ -24,6 +24,8 @@
*/
package java.util.function;
+import java.util.Objects;
+
/**
* An operation on a single {@code long} operand yielding a {@code long} result.
* This is the primitive type specialization of {@link UnaryOperator} for
@@ -42,5 +44,46 @@ public interface LongUnaryOperator {
* @param operand the operand value
* @return the operation result value
*/
- public long applyAsLong(long operand);
+ long applyAsLong(long operand);
+
+ /**
+ * Compose a new function which applies the provided function followed by
+ * this function. If either function throws an exception, it is relayed
+ * to the caller.
+ *
+ * @param before An additional function to be applied before this function
+ * is applied
+ * @return A function which performs the provided function followed by this
+ * function
+ * @throws NullPointerException if before is null
+ */
+ default LongUnaryOperator compose(LongUnaryOperator before) {
+ Objects.requireNonNull(before);
+ return (long v) -> applyAsLong(before.applyAsLong(v));
+ }
+
+ /**
+ * Compose a new function which applies this function followed by the
+ * provided function. If either function throws an exception, it is relayed
+ * to the caller.
+ *
+ * @param after An additional function to be applied after this function is
+ * applied
+ * @return A function which performs this function followed by the provided
+ * function followed
+ * @throws NullPointerException if after is null
+ */
+ default LongUnaryOperator andThen(LongUnaryOperator after) {
+ Objects.requireNonNull(after);
+ return (long t) -> after.applyAsLong(applyAsLong(t));
+ }
+
+ /**
+ * Returns a unary operator that provides its input value as the result.
+ *
+ * @return a unary operator that provides its input value as the result
+ */
+ static LongUnaryOperator identity() {
+ return t -> t;
+ }
}
diff --git a/jdk/src/share/classes/java/util/function/ObjDoubleConsumer.java b/jdk/src/share/classes/java/util/function/ObjDoubleConsumer.java
index 24e4c29327c..dd8c0c9cf99 100644
--- a/jdk/src/share/classes/java/util/function/ObjDoubleConsumer.java
+++ b/jdk/src/share/classes/java/util/function/ObjDoubleConsumer.java
@@ -44,5 +44,5 @@ public interface ObjDoubleConsumer Any exceptions thrown by either {@code test} method are relayed
+ * to the caller; if performing first operation throws an exception, the
+ * second operation will not be performed.
+ *
+ * @param p a predicate which will be logically-ANDed with this predicate
* @return a new predicate which returns {@code true} only if both
- * predicates return {@code true}.
+ * predicates return {@code true}
+ * @throws NullPointerException if p is null
*/
- public default Predicate Any exceptions thrown by either {@code test} method are relayed
+ * to the caller; if performing first operation throws an exception, the
+ * second operation will not be performed.
+ *
+ * @param p a predicate which will be logically-ORed with this predicate
* @return a new predicate which returns {@code true} if either predicate
- * returns {@code true}.
+ * returns {@code true}
+ * @throws NullPointerException if p is null
*/
- public default Predicate The elements of the stream are {@link Path} objects that are
+ * obtained as if by {@link Path#resolve(Path) resolving} the name of the
+ * directory entry against {@code dir}. Some file systems maintain special
+ * links to the directory itself and the directory's parent directory.
+ * Entries representing these links are not included.
+ *
+ * The stream is weakly consistent. It is thread safe but does
+ * not freeze the directory while iterating, so it may (or may not)
+ * reflect updates to the directory that occur after returning from this
+ * method.
+ *
+ * When not using the try-with-resources construct, then the stream's
+ * {@link CloseableStream#close close} method should be invoked after the
+ * operation is completed so as to free any resources held for the open
+ * directory. Operating on a closed stream behaves as if the end of stream
+ * has been reached. Due to read-ahead, one or more elements may be
+ * returned after the stream has been closed.
+ *
+ * If an {@link IOException} is thrown when accessing the directory
+ * after this method has returned, it is wrapped in an {@link
+ * UncheckedIOException} which will be thrown from the method that caused
+ * the access to take place.
+ *
+ * @param dir The path to the directory
+ *
+ * @return The {@code CloseableStream} describing the content of the
+ * directory
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory (optional specific exception)
+ * @throws IOException
+ * if an I/O error occurs when opening the directory
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ *
+ * @see #newDirectoryStream(Path)
+ * @since 1.8
+ */
+ public static CloseableStream The {@code stream} walks the file tree as elements are consumed.
+ * The {@code CloseableStream} returned is guaranteed to have at least one
+ * element, the starting file itself. For each file visited, the stream
+ * attempts to read its {@link BasicFileAttributes}. If the file is a
+ * directory and can be opened successfully, entries in the directory, and
+ * their descendants will follow the directory in the stream as
+ * they are encountered. When all entries have been visited, then the
+ * directory is closed. The file tree walk then continues at the next
+ * sibling of the directory.
+ *
+ * The stream is weakly consistent. It does not freeze the
+ * file tree while iterating, so it may (or may not) reflect updates to
+ * the file tree that occur after returned from this method.
+ *
+ * By default, symbolic links are not automatically followed by this
+ * method. If the {@code options} parameter contains the {@link
+ * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then symbolic links are
+ * followed. When following links, and the attributes of the target cannot
+ * be read, then this method attempts to get the {@code BasicFileAttributes}
+ * of the link.
+ *
+ * If the {@code options} parameter contains the {@link
+ * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then the stream keeps
+ * track of directories visited so that cycles can be detected. A cycle
+ * arises when there is an entry in a directory that is an ancestor of the
+ * directory. Cycle detection is done by recording the {@link
+ * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
+ * or if file keys are not available, by invoking the {@link #isSameFile
+ * isSameFile} method to test if a directory is the same file as an
+ * ancestor. When a cycle is detected it is treated as an I/O error with
+ * an instance of {@link FileSystemLoopException}.
+ *
+ * The {@code maxDepth} parameter is the maximum number of levels of
+ * directories to visit. A value of {@code 0} means that only the starting
+ * file is visited, unless denied by the security manager. A value of
+ * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
+ * levels should be visited.
+ *
+ * When a security manager is installed and it denies access to a file
+ * (or directory), then it is ignored and not included in the stream.
+ *
+ * When not using the try-with-resources construct, then the stream's
+ * {@link CloseableStream#close close} method should be invoked after the
+ * operation is completed so as to free any resources held for the open
+ * directory. Operate the stream after it is closed will throw an
+ * {@link java.lang.IllegalStateException}.
+ *
+ * If an {@link IOException} is thrown when accessing the directory
+ * after this method has returned, it is wrapped in an {@link
+ * UncheckedIOException} which will be thrown from the method that caused
+ * the access to take place.
+ *
+ * @param start
+ * the starting file
+ * @param maxDepth
+ * the maximum number of directory levels to visit
+ * @param options
+ * options to configure the traversal
+ *
+ * @return the {@link CloseableStream} of {@link Path}
+ *
+ * @throws IllegalArgumentException
+ * if the {@code maxDepth} parameter is negative
+ * @throws SecurityException
+ * If the security manager denies access to the starting file.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String) checkRead} method is invoked
+ * to check read access to the directory.
+ * @throws IOException
+ * if an I/O error is thrown when accessing the starting file.
+ * @since 1.8
+ */
+ public static CloseableStream This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ * This method walks the file tree in exactly the manner specified by
+ * the {@link #walk walk} method. For each file encountered, the given
+ * {@link BiPredicate} is invoked with its {@link Path} and {@link
+ * BasicFileAttributes}. The {@code Path} object is obtained as if by
+ * {@link Path#resolve(Path) resolving} the relative path against {@code
+ * start} and is only included in the returned {@link CloseableStream} if
+ * the {@code BiPredicate} returns true. Compare to calling {@link
+ * java.util.stream.Stream#filter filter} on the {@code Stream}
+ * returned by {@code walk} method, this method may be more efficient by
+ * avoiding redundant retrieval of the {@code BasicFileAttributes}.
+ *
+ * If an {@link IOException} is thrown when accessing the directory
+ * after returned from this method, it is wrapped in an {@link
+ * UncheckedIOException} which will be thrown from the method that caused
+ * the access to take place.
+ *
+ * @param start
+ * the starting file
+ * @param maxDepth
+ * the maximum number of directory levels to search
+ * @param matcher
+ * the function used to decide whether a file should be included
+ * in the returned stream
+ * @param options
+ * options to configure the traversal
+ *
+ * @return the {@link CloseableStream} of {@link Path}
+ *
+ * @throws IllegalArgumentException
+ * if the {@code maxDepth} parameter is negative
+ * @throws SecurityException
+ * If the security manager denies access to the starting file.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String) checkRead} method is invoked
+ * to check read access to the directory.
+ * @throws IOException
+ * if an I/O error is thrown when accessing the starting file.
+ *
+ * @see #walk(Path, int, FileVisitOption...)
+ * @since 1.8
+ */
+ public static CloseableStream Bytes from the file are decoded into characters using the specified
+ * charset and the same line terminators as specified by {@code
+ * readAllLines} are supported.
+ *
+ * After this method returns, then any subsequent I/O exception that
+ * occurs while reading from the file or when a malformed or unmappable byte
+ * sequence is read, is wrapped in an {@link UncheckedIOException} that will
+ * be thrown form the
+ * {@link java.util.stream.Stream} method that caused the read to take
+ * place. In case an {@code IOException} is thrown when closing the file,
+ * it is also wrapped as an {@code UncheckedIOException}.
+ *
+ * When not using the try-with-resources construct, then stream's
+ * {@link CloseableStream#close close} method should be invoked after
+ * operation is completed so as to free any resources held for the open
+ * file.
+ *
+ * @param path
+ * the path to the file
+ * @param cs
+ * the charset to use for decoding
+ *
+ * @return the lines from the file as a {@code CloseableStream}
+ *
+ * @throws IOException
+ * if an I/O error occurs opening the file
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ *
+ * @see #readAllLines(Path, Charset)
+ * @see #newBufferedReader(Path, Charset)
+ * @see java.io.BufferedReader#lines()
+ * @since 1.8
+ */
+ public static CloseableStream
*
@@ -284,6 +284,8 @@ import java.util.function.LongConsumer;
* is set to {@code true} then diagnostic warnings are reported if boxing of
* primitive values occur when operating on primitive subtype specializations.
*
+ * @param
For example, an instance of
* {@link java.util.concurrent.CopyOnWriteArrayList} is an immutable source.
* A Spliterator created from the source reports a characteristic of
* {@code IMMUTABLE}.
For example, a key set of a {@link java.util.concurrent.ConcurrentHashMap}
* is a concurrent source. A Spliterator created from the source reports a
* characteristic of {@code CONCURRENT}.
Late binding narrows the window during which interference can affect
* the calculation; fail-fast detects, on a best-effort basis, that structural
* interference has occurred after traversal has commenced and throws
* {@link ConcurrentModificationException}. For example, {@link ArrayList},
* and many other non-concurrent {@code Collection} classes in the JDK, provide
* a late-binding, fail-fast spliterator.
The source increases the likelihood of throwing
* {@code ConcurrentModificationException} since the window of potential
* interference is larger.
The source risks arbitrary, non-deterministic behavior after traversal
* has commenced since interference is not detected.
*
The source increases the risk of arbitrary, non-deterministic behavior
* since non-detected interference may occur after construction.
*
*
{@code
+ * try (FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options)) {
+ * while (iterator.hasNext()) {
+ * Event ev = iterator.next();
+ * Path path = ev.file();
+ * BasicFileAttributes attrs = ev.attributes();
+ * }
+ * }
+ * }
+ */
+
+class FileTreeIterator implements Iterator
+ * In other words, it visits all levels of the file tree.
+ *
+ * @param start
+ * the starting file
+ * @param options
+ * options to configure the traversal
+ *
+ * @return the {@link CloseableStream} of {@link Path}
+ *
+ * @throws SecurityException
+ * If the security manager denies access to the starting file.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String) checkRead} method is invoked
+ * to check read access to the directory.
+ * @throws IOException
+ * if an I/O error is thrown when accessing the starting file.
+ *
+ * @see #walk(Path, int, FileVisitOption...)
+ * @since 1.8
+ */
+ public static CloseableStream
+ * walk(start, Integer.MAX_VALUE, options)
+ *
- var anArrayList = new Java.type("java.util.ArrayList")
+ var anArrayList = new (Java.type("java.util.ArrayList"))
or
@@ -496,6 +507,37 @@ However, once you retrieved the outer class, you can access the inner class as a
You can access both static and non-static inner classes. If you want to create an instance of a non-static inner class, remember to pass an instance of its outer class as the first argument to the constructor.
+
+In addition to creating new instances, the type objects returned from Java.type
calls can also be used to access the
+static fields and methods of the classes:
+
+ var File = Java.type("java.io.File")
+ File.createTempFile("nashorn", ".tmp")
+
+
+Methods with names of the form isXxx()
, getXxx()
, and setXxx()
can also be used as properties, for both instances and statics.
+
+A type object returned from Java.type
is distinct from a java.lang.Class
object. You can obtain one from the other using properties class
and static
on them.
+
+ var ArrayList = Java.type("java.util.ArrayList")
+ var a = new ArrayList
+
+ // All of the following print true:
+ print("Type acts as target of instanceof: " + (a instanceof ArrayList))
+ print("Class doesn't act as target of instanceof: " + !(a instanceof a.getClass()))
+ print("Type is not same as instance's getClass(): " + (a.getClass() !== ArrayList))
+ print("Type's `class` property is same as instance getClass(): " + (a.getClass() === ArrayList.class))
+ print("Type is same as instance getClass()'s `static` property: " + (a.getClass().static === ArrayList))
+
+
+You can think of the type object as similar to the class names as used in Java source code: you use them as the
+arguments to the new
and instanceof
operators and as the namespace for the static fields
+and methods, but they are different than the runtime Class
objects returned by getClass()
calls.
+Syntactically and semantically, this separation produces code that is most similar to Java code, where a distinction
+between compile-time class expressions and runtime class objects also exists. (Also, Java can't have the equivalent of static
+property on a Class
object since compile-time class expressions are never reified as objects).
+
-Array element access or length access is -the same as in Java. Also, a script array can be used when a Java -method expects a Java array (auto conversion). So in most cases we -don't have to create Java arrays explicitly.
+Array element access or length access is the same as in Java.
// javaarray.js
@@ -587,7 +626,11 @@ Given a JavaScript array and a Java type, Java.toJavaArray
returns
print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
-Given a Java array or Collection, Java.toJavaScriptArray
returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.i
+You can use either a string or a type object returned from Java.type()
to specify the component type of the array.
+You can also omit the array type, in which case a Object[]
will be created.
+
+Given a Java array or Collection, Java.toJavaScriptArray
returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.
var File = Java.type("java.io.File");
@@ -597,7 +640,7 @@ print(jsList);
A Java interface can be implemented in JavaScript by using a Java anonymous class-like syntax:
@@ -631,8 +674,8 @@ th.join();
If a Java class is abstract, you can instantiate an anonymous subclass of it using an argument list that is applicable to any of its public or protected constructors, but inserting a JavaScript object with functions properties that provide JavaScript implementations of the abstract methods. If method names are overloaded, the JavaScript function will provide implementation for all overloads. E.g.:
@@ -671,6 +714,9 @@ The use of functions can be taken even further; if you are invoking a Java metho Here,Timer.schedule()
expects a TimerTask
as its argument, so Nashorn creates an instance of a TimerTask subclass and uses the passed function to implement its only abstract method, run(). In this usage though, you can't use non-default constructors; the type must be either an interface, or must have a protected or public no-arg constructor.
+
To extend a concrete Java class, you have to use Java.extend
function.
Java.extend
returns a type object for a subclass of the specified Java class (or implementation of the specified interface) that acts as a script-to-Java adapter for it.
@@ -695,26 +741,178 @@ var printAddInvokedArrayList = new ArrayListExtender() {
printSizeInvokedArrayList.size();
printAddInvokedArrayList.add(33, 33);
+
+The reason you must use Java.extend()
with concrete classes is that with concrete classes, there can be a
+syntactic ambiguity if you just invoke their constructor. Consider this example:
+
+var t = new java.lang.Thread({ run: function() { print("Hello!") } })
+
+
+If we allowed subclassing of concrete classes with constructor syntax, Nashorn couldn't tell if you're creating a new
+Thread
and passing it a Runnable
at this point, or you are subclassing Thread
and
+passing it a new implementation for its own run()
method.
+
+Java.extend
can in fact take a list of multiple types. At most one of the types can be a class, and the rest must
+be interfaces (the class doesn't have to be the first in the list). You will get back an object that extends the class and
+implements all the interfaces. (Obviously, if you only specify interfaces and no class, the object will extend java.lang.Object
).
+
+The methods shown so far for extending Java classes and implementing interfaces – passing an implementation JavaScript object
+or function to a constructor, or using Java.extend
with new
– all produce classes that take an
+extra JavaScript object parameter in their constructors that specifies the implementation. The implementation is therefore always bound
+to the actual instance being created with new
, and not to the whole class. This has some advantages, for example in the
+memory footprint of the runtime, as Nashorn can just create a single "universal adapter" for every combination of types being implemented.
+In reality, the below code shows that different instantiations of, say, Runnable
have the same class regardless of them having
+different JavaScript implementation objects:
+
+var Runnable = java.lang.Runnable;
+var r1 = new Runnable(function() { print("I'm runnable 1!") })
+var r2 = new Runnable(function() { print("I'm runnable 2!") })
+r1.run()
+r2.run()
+print("We share the same class: " + (r1.class === r2.class))
+
++prints: +
+
+I'm runnable 1!
+I'm runnable 2!
+We share the same class: true
+
++Sometimes, however, you'll want to extend a Java class or implement an interface with implementation bound to the class, not to +its instances. Such a need arises, for example, when you need to pass the class for instantiation to an external API; prime example +of this is the JavaFX framework where you need to pass an Application class to the FX API and let it instantiate it. +
+
+Fortunately, there's a solution for that: Java.extend()
– aside from being able to take any number of type parameters
+denoting a class to extend and interfaces to implement – can also take one last argument that has to be a JavaScript object
+that serves as the implementation for the methods. In this case, Java.extend()
will create a class that has the same
+constructors as the original class had, as they don't need to take an an extra implementation object parameter. The example below
+shows how you can create class-bound implementations, and shows that in this case, the implementation classes for different invocations
+are indeed different:
+
+var RunnableImpl1 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
+var RunnableImpl2 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 2!") })
+var r1 = new RunnableImpl1()
+var r2 = new RunnableImpl2()
+r1.run()
+r2.run()
+print("We share the same class: " + (r1.class === r2.class))
+
++prints: +
+
+I'm runnable 1!
+I'm runnable 2!
+We share the same class: false
+
+
+As you can see, the major difference here is that we moved the implementation object into the invocation of Java.extend
+from the constructor invocations – indeed the constructor invocations now don't even need to take an extra parameter! Since
+the implementations are bound to a class, the two classes obviously can't be the same, and we indeed see that the two runnables no
+longer share the same class – every invocation of Java.extend()
with a class-specific implementation object triggers
+the creation of a new Java adapter class.
+
+Finally, the adapter classes with class-bound implementations can still take an additional constructor parameter to further
+override the behavior on a per-instance basis. Thus, you can even combine the two approaches: you can provide part of the implementation
+in a class-based JavaScript implementation object passed to Java.extend
, and part in another object passed to the constructor.
+Whatever functions are provided by the constructor-passed object will override the functions in the class-bound object.
+
+var RunnableImpl = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
+var r1 = new RunnableImpl()
+var r2 = new RunnableImpl(function() { print("I'm runnable 2!") })
+r1.run()
+r2.run()
+print("We share the same class: " + (r1.class === r2.class))
+
++prints: +
+
+I'm runnable 1!
+I'm runnable 2!
+We share the same class: true
+
Java methods can be overloaded by argument types. In Java, overload resolution occurs at compile time (performed by javac). -When calling Java methods from a script, the script -interpreter/compiler needs to select the appropriate method. With -the JavaScript engine, you do not need to do anything special - the -correct Java method overload variant is selected based on the -argument types. But, sometimes you may want (or have) to explicitly -select a particular overload variant.
+When calling Java methods from Nashorn, the appropriate method will be +selected based on the argument types at invocation time. You do not need +to do anything special – the correct Java method overload variant +is selected based automatically. You still have the option of explicitly +specifying a particular overload variant. Reasons for this include +either running into a genuine ambiguity with actual argument types, or +rarely reasons of performance – if you specify the actual overload +then the engine doesn't have to perform resolution during invocation. +Individual overloads of a Java methods are exposed as special properties +with the name of the method followed with its signature in parentheses. +You can invoke them like this:
// overload.js
var out = java.lang.System.out;
// select a particular print function
-out["println(java.lang.Object)"]("hello");
+out["println(Object)"]("hello");
++Note that you normally don't even have to use qualified class names in +the signatures as long as the unqualified name of the type is sufficient +for uniquely identifying the signature. In practice this means that only +in the extremely unlikely case that two overloads only differ in +parameter types that have identical unqualified names but come from +different packages would you need to use the fully qualified name of the +class. +
++We have previously shown some of the data type mappings between Java and JavaScript. +We saw that arrays need to be explicitly converted. We have also shown that JavaScript functions +are automatically converted to SAM types when passed as parameters to Java methods. Most other +conversions work as you would expect. +
+
+Every JavaScript object is also a java.util.Map
so APIs receiving maps will receive them directly.
+
+When numbers are passed to a Java API, they will be converted to the expected target numeric type, either boxed or
+primitive, but if the target type is less specific, say Number
or Object
, you can only
+count on them being a Number
, and have to test specifically for whether it's a boxed Double
,
+Integer
, Long
, etc. – it can be any of these due to internal optimizations. Also, you
+can pass any JavaScript value to a Java API expecting either a boxed or primitive number; the JavaScript specification's
+ToNumber
conversion algorithm will be applied to the value.
+
+In a similar vein, if a Java method expects a String
or a Boolean
, the values will be
+converted using all conversions allowed by the JavaScript specification's ToString
and ToBoolean
+conversions.
+
+Finally, a word of caution about strings. Due to internal performance optimizations of string operations, JavaScript strings are
+not always necessarily of type java.lang.String
, but they will always be of type java.lang.CharSequence
.
+If you pass them to a Java method that expects a java.lang.String
parameter, then you will naturally receive a Java
+String, but if the signature of your method is more generic, i.e. it receives a java.lang.Object
parameter, you can
+end up with an object of private engine implementation class that implements CharSequence
but is not a Java String.
+
The skip
method may, for a variety of
* reasons, end up skipping over some smaller number of bytes,
- * possibly 0
. If n
is negative, an
- * IOException
is thrown, even though the skip
- * method of the {@link InputStream} superclass does nothing in this case.
- * The actual number of bytes skipped is returned.
+ * possibly 0
. If n
is negative, the method
+ * will try to skip backwards. In case the backing file does not support
+ * backward skip at its current position, an IOException
is
+ * thrown. The actual number of bytes skipped is returned. If it skips
+ * forwards, it returns a positive value. If it skips backwards, it
+ * returns a negative value.
*
- *
This method may skip more bytes than are remaining in the backing - * file. This produces no exception and the number of bytes skipped + *
This method may skip more bytes than what are remaining in the + * backing file. This produces no exception and the number of bytes skipped * may include some number of bytes that were beyond the EOF of the * backing file. Attempting to read from the stream after skipping past * the end will result in -1 indicating the end of the file. @@ -261,9 +263,10 @@ class FileInputStream extends InputStream /** * Returns an estimate of the number of remaining bytes that can be read (or * skipped over) from this input stream without blocking by the next - * invocation of a method for this input stream. The next invocation might be - * the same thread or another thread. A single read or skip of this - * many bytes will not block, but may read or skip fewer bytes. + * invocation of a method for this input stream. Returns 0 when the file + * position is beyond EOF. The next invocation might be the same thread + * or another thread. A single read or skip of this many bytes will not + * block, but may read or skip fewer bytes. * *
In some cases, a non-blocking read (or skip) may appear to be
* blocked when it is merely slow, for example when reading large
diff --git a/jdk/src/share/classes/java/io/InputStream.java b/jdk/src/share/classes/java/io/InputStream.java
index cb61314b01d..3c7ff17f609 100644
--- a/jdk/src/share/classes/java/io/InputStream.java
+++ b/jdk/src/share/classes/java/io/InputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -193,8 +193,10 @@ public abstract class InputStream implements Closeable {
* up skipping over some smaller number of bytes, possibly 0
.
* This may result from any of a number of conditions; reaching end of file
* before n
bytes have been skipped is only one possibility.
- * The actual number of bytes skipped is returned. If n
is
- * negative, no bytes are skipped.
+ * The actual number of bytes skipped is returned. If {@code n} is
+ * negative, the {@code skip} method for class {@code InputStream} always
+ * returns 0, and no bytes are skipped. Subclasses may handle the negative
+ * value differently.
*
*
The
It is also possible to convert between JavaScript and Java arrays.
-Given a JavaScript array and a Java type,
-You can use either a string or a type object returned from
-Given a Java array or Collection,
- * This code is designed to implement the JAXP 1.1 spec pluggability
- * feature and is designed to run on JDK version 1.1 and
- * later, and to compile on JDK 1.2 and onward.
- * The code also runs both as part of an unbundled jar file and
- * when bundled as part of the JDK.
- *
- *
- */
-final class ObjectFactory {
-
- //
- // Constants
- //
-
- // name of default properties file to look for in JDK's jre/lib directory
- private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties";
-
- /** Set to true for debugging */
- private static final boolean DEBUG = false;
-
- /**
- * Default columns per line.
- */
- private static final int DEFAULT_LINE_LENGTH = 80;
-
- /** cache the contents of the xerces.properties file.
- * Until an attempt has been made to read this file, this will
- * be null; if the file does not exist or we encounter some other error
- * during the read, this will be empty.
- */
- private static Properties fXercesProperties = null;
-
- /***
- * Cache the time stamp of the xerces.properties file so
- * that we know if it's been modified and can invalidate
- * the cache when necessary.
- */
- private static long fLastModified = -1;
-
- //
- // static methods
- //
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- *
- * This code is designed to implement the JAXP 1.1 spec pluggability
- * feature and is designed to run on JDK version 1.1 and
- * later, and to compile on JDK 1.2 and onward.
- * The code also runs both as part of an unbundled jar file and
- * when bundled as part of the JDK.
- *
- *
- */
-final class ObjectFactory {
-
- //
- // Constants
- //
-
- // name of default properties file to look for in JDK's jre/lib directory
- private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties";
-
- /** Set to true for debugging */
- private static final boolean DEBUG = false;
-
- /**
- * Default columns per line.
- */
- private static final int DEFAULT_LINE_LENGTH = 80;
-
- /** cache the contents of the xerces.properties file.
- * Until an attempt has been made to read this file, this will
- * be null; if the file does not exist or we encounter some other error
- * during the read, this will be empty.
- */
- private static Properties fXercesProperties = null;
-
- /***
- * Cache the time stamp of the xerces.properties file so
- * that we know if it's been modified and can invalidate
- * the cache when necessary.
- */
- private static long fLastModified = -1;
-
- //
- // static methods
- //
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- * Note that this returns {@link java.lang.Integer#MAX_VALUE} or {@link java.lang.Integer#MIN_VALUE}
+ * for double values that exceed the int range, including positive and negative Infinity. It is the
+ * caller's responsibility to handle such values correctly. Note that this returns {@link java.lang.Long#MAX_VALUE} or {@link java.lang.Long#MIN_VALUE}
+ * for double values that exceed the long range, including positive and negative Infinity. It is the
+ * caller's responsibility to handle such values correctly.
diff --git a/jdk/src/share/classes/java/util/ListResourceBundle.java b/jdk/src/share/classes/java/util/ListResourceBundle.java
index 736016f7f84..9aa7fdba550 100644
--- a/jdk/src/share/classes/java/util/ListResourceBundle.java
+++ b/jdk/src/share/classes/java/util/ListResourceBundle.java
@@ -89,7 +89,7 @@ import sun.util.ResourceBundleEnumeration;
*
* public class MyResources_fr extends ListResourceBundle {
* protected Object[][] getContents() {
- * return new Object[][] = {
+ * return new Object[][] {
* // LOCALIZE THIS
* {"s1", "Le disque \"{1}\" {0}."}, // MessageFormat pattern
* {"s2", "1"}, // location of {0} in pattern
From 4ef977fec3abe84db61e6c4475bf8b49e9872718 Mon Sep 17 00:00:00 2001
From: David Holmes " + Resources.format(Messages.HELP_ABOUT_DIALOG_JAVA_VERSION, (vmName +", "+ vmVersion)) +
- " " + Resources.format(Messages.HELP_ABOUT_DIALOG_USER_GUIDE_LINK, urlStr) +
- "");
+ " " + urlStr + "skip
method of this class creates a
* byte array and then repeatedly reads into it until n
bytes
diff --git a/jdk/src/share/native/java/io/FileInputStream.c b/jdk/src/share/native/java/io/FileInputStream.c
index 37deaf84efb..52e2cdd8e6b 100644
--- a/jdk/src/share/native/java/io/FileInputStream.c
+++ b/jdk/src/share/native/java/io/FileInputStream.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -100,6 +100,8 @@ Java_java_io_FileInputStream_available(JNIEnv *env, jobject this) {
if (IO_Available(fd, &ret)) {
if (ret > INT_MAX) {
ret = (jlong) INT_MAX;
+ } else if (ret < 0) {
+ ret = 0;
}
return jlong_to_jint(ret);
}
diff --git a/jdk/test/java/io/FileInputStream/LargeFileAvailable.java b/jdk/test/java/io/FileInputStream/LargeFileAvailable.java
index 90eed30d1dc..94f6f856c2a 100644
--- a/jdk/test/java/io/FileInputStream/LargeFileAvailable.java
+++ b/jdk/test/java/io/FileInputStream/LargeFileAvailable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6402006 7030573
+ * @bug 6402006 7030573 8011136
* @summary Test if available returns correct value when reading
* a large file.
*/
@@ -61,9 +61,12 @@ public class LargeFileAvailable {
remaining -= skipBytes(fis, bigSkip, remaining);
remaining -= skipBytes(fis, 10L, remaining);
remaining -= skipBytes(fis, bigSkip, remaining);
- if (fis.available() != (int) remaining) {
- throw new RuntimeException("available() returns "
- + fis.available() + " but expected " + remaining);
+ int expected = (remaining >= Integer.MAX_VALUE)
+ ? Integer.MAX_VALUE
+ : (remaining > 0 ? (int) remaining : 0);
+ if (fis.available() != expected) {
+ throw new RuntimeException("available() returns "
+ + fis.available() + " but expected " + expected);
}
} finally {
file.delete();
@@ -77,19 +80,18 @@ public class LargeFileAvailable {
long skip = is.skip(toSkip);
if (skip != toSkip) {
throw new RuntimeException("skip() returns " + skip
- + " but expected " + toSkip);
+ + " but expected " + toSkip);
}
long remaining = avail - skip;
- int expected = remaining >= Integer.MAX_VALUE
- ? Integer.MAX_VALUE
- : (int) remaining;
+ int expected = (remaining >= Integer.MAX_VALUE)
+ ? Integer.MAX_VALUE
+ : (remaining > 0 ? (int) remaining : 0);
- System.out.println("Skipped " + skip + " bytes "
- + " available() returns " + expected +
- " remaining=" + remaining);
+ System.out.println("Skipped " + skip + " bytes, available() returns "
+ + expected + ", remaining " + remaining);
if (is.available() != expected) {
throw new RuntimeException("available() returns "
- + is.available() + " but expected " + expected);
+ + is.available() + " but expected " + expected);
}
return skip;
}
diff --git a/jdk/test/java/io/FileInputStream/NegativeAvailable.java b/jdk/test/java/io/FileInputStream/NegativeAvailable.java
index a4dedbcdcf7..a0e0e999231 100644
--- a/jdk/test/java/io/FileInputStream/NegativeAvailable.java
+++ b/jdk/test/java/io/FileInputStream/NegativeAvailable.java
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8010837
+ * @bug 8010837 8011136
* @summary Test if available returns correct value when skipping beyond
* the end of a file.
* @author Dan Xu
@@ -42,6 +42,7 @@ public class NegativeAvailable {
public static void main(String[] args) throws IOException {
final int SIZE = 10;
final int SKIP = 5;
+ final int NEGATIVE_SKIP = -5;
// Create a temporary file with size of 10 bytes.
Path tmp = Files.createTempFile(null, null);
@@ -56,12 +57,15 @@ public class NegativeAvailable {
try (FileInputStream fis = new FileInputStream(tempFile)) {
if (tempFile.length() != SIZE) {
throw new RuntimeException("unexpected file size = "
- + tempFile.length());
+ + tempFile.length());
}
long space = skipBytes(fis, SKIP, SIZE);
+ space = skipBytes(fis, NEGATIVE_SKIP, space);
space = skipBytes(fis, SKIP, space);
space = skipBytes(fis, SKIP, space);
space = skipBytes(fis, SKIP, space);
+ space = skipBytes(fis, NEGATIVE_SKIP, space);
+ space = skipBytes(fis, NEGATIVE_SKIP, space);
}
Files.deleteIfExists(tmp);
}
@@ -74,17 +78,18 @@ public class NegativeAvailable {
long skip = fis.skip(toSkip);
if (skip != toSkip) {
throw new RuntimeException("skip() returns " + skip
- + " but expected " + toSkip);
+ + " but expected " + toSkip);
}
- long remaining = space - toSkip;
+ long newSpace = space - toSkip;
+ long remaining = newSpace > 0 ? newSpace : 0;
int avail = fis.available();
if (avail != remaining) {
throw new RuntimeException("available() returns " + avail
- + " but expected " + remaining);
+ + " but expected " + remaining);
}
System.out.println("Skipped " + skip + " bytes "
- + " available() returns " + avail);
- return remaining;
+ + " available() returns " + avail);
+ return newSpace;
}
}
From aab6997ce09c3c27fe6567edaa4a692e68160ec0 Mon Sep 17 00:00:00 2001
From: Weijun Wang Java.toJavaArray
returns a Java array with the same initial contents, and with the specified component type.
+Given a JavaScript array and a Java type, Java.to
returns a Java array with the same initial contents, and with the specified array type.
var anArray = [1, "13", false]
- var javaIntArray = Java.toJavaArray(anArray, "int")
+ var javaIntArray = Java.to(anArray, "int[]")
print(javaIntArray[0]) // prints 1
print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
Java.type()
to specify the component type of the array.
+You can use either a string or a type object returned from Java.type()
to specify the type of the array.
You can also omit the array type, in which case a Object[]
will be created.
Java.toJavaScriptArray
returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.
+Given a Java array or Collection, Java.from
returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.
var File = Java.type("java.io.File");
var listCurDir = new File(".").listFiles();
-var jsList = Java.toJavaScriptArray(listCurDir);
+var jsList = Java.from(listCurDir);
print(jsList);
diff --git a/nashorn/docs/source/javaarray.js b/nashorn/docs/source/javaarray.js
index a02aa3ca9f6..d0de9124684 100644
--- a/nashorn/docs/source/javaarray.js
+++ b/nashorn/docs/source/javaarray.js
@@ -40,7 +40,7 @@ print(a[0]);
// convert a script array to Java array
var anArray = [1, "13", false];
-var javaIntArray = Java.toJavaArray(anArray, "int");
+var javaIntArray = Java.to(anArray, "int[]");
print(javaIntArray[0]);// prints 1
print(javaIntArray[1]); // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
print(javaIntArray[2]);// prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
@@ -48,5 +48,5 @@ print(javaIntArray[2]);// prints 0, as boolean false was converted to number 0 a
// convert a Java array to a JavaScript array
var File = Java.type("java.io.File");
var listCurDir = new File(".").listFiles();
-var jsList = Java.toJavaScriptArray(listCurDir);
+var jsList = Java.from(listCurDir);
print(jsList);
diff --git a/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js b/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js
index e95607287d4..62d6735ee3f 100644
--- a/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js
+++ b/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js
@@ -88,7 +88,7 @@ Object.defineProperty(this, "sprintf", {
}
}
- array = Java.toJavaArray(array);
+ array = Java.to(array);
return Packages.jdk.nashorn.api.scripting.ScriptUtils.format(format, array);
}
});
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
index 5faec5ea98b..800b224f10d 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
@@ -240,39 +240,52 @@ public final class NativeJava {
}
/**
- * Given a JavaScript array and a Java type, returns a Java array with the same initial contents, and with the
- * specified component type. Example:
+ * Given a script object and a Java type, converts the script object into the desired Java type. Currently it only
+ * performs shallow creation of Java arrays, but might be extended for other types in the future. Example:
*
* var anArray = [1, "13", false]
- * var javaIntArray = Java.toJavaArray(anArray, "int")
+ * var javaIntArray = Java.to(anArray, "int[]")
* print(javaIntArray[0]) // prints 1
* print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
* print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
*
* @param self not used
- * @param objArray the JavaScript array. Can be null.
- * @param objType either a {@link #type(Object, Object) type object} or a String describing the component type of
- * the Java array to create. Can not be null. If undefined, Object is assumed (allowing the argument to be omitted).
- * @return a Java array with the copy of JavaScript array's contents, converted to the appropriate Java component
- * type. Returns null if objArray is null.
+ * @param objArray the script object. Can be null.
+ * @param objType either a {@link #type(Object, Object) type object} or a String describing the type of the Java
+ * object to create. Can not be null. If undefined, a "default" conversion is presumed (allowing the argument to be
+ * omitted).
+ * @return a Java object whose value corresponds to the original script object's value. Specifically, for array
+ * target types, returns a Java array of the same type with contents converted to the array's component type. Does
+ * not recursively convert for multidimensional arrays.
+ * type. Returns null if scriptObject is null.
* @throws ClassNotFoundException if the class described by objType is not found
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
- public static Object toJavaArray(final Object self, final Object objArray, final Object objType) throws ClassNotFoundException {
- final StaticClass componentType =
- objType instanceof StaticClass ?
- (StaticClass)objType :
- objType == UNDEFINED ?
- StaticClass.forClass(Object.class) :
- type(objType);
-
+ public static Object to(final Object self, final Object objArray, final Object objType) throws ClassNotFoundException {
if (objArray == null) {
return null;
}
+ final Class> componentType;
+ if(objType == UNDEFINED) {
+ componentType = Object.class;
+ } else {
+ final StaticClass arrayType;
+ if(objType instanceof StaticClass) {
+ arrayType = (StaticClass)objType;
+ } else {
+ arrayType = type(objType);
+ }
+ final Class> arrayClass = arrayType.getRepresentedClass();
+ if(!arrayClass.isArray()) {
+ throw typeError("to.expects.array.type", arrayClass.getName());
+ }
+ componentType = arrayClass.getComponentType();
+ }
+
Global.checkObject(objArray);
- return ((ScriptObject)objArray).getArray().asArrayOfType(componentType.getRepresentedClass());
+ return ((ScriptObject)objArray).getArray().asArrayOfType(componentType);
}
/**
@@ -283,7 +296,7 @@ public final class NativeJava {
*
* var File = Java.type("java.io.File")
* var listHomeDir = new File("~").listFiles()
- * var jsListHome = Java.toJavaScriptArray(listHomeDir)
+ * var jsListHome = Java.from(listHomeDir)
* var jpegModifiedDates = jsListHome
* .filter(function(val) { return val.getName().endsWith(".jpg") })
* .map(function(val) { return val.lastModified() })
@@ -294,7 +307,7 @@ public final class NativeJava {
* null.
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
- public static Object toJavaScriptArray(final Object self, final Object objArray) {
+ public static Object from(final Object self, final Object objArray) {
if (objArray == null) {
return null;
} else if (objArray instanceof Collection) {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
index 9f327521bcc..4f435ea2e96 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
@@ -125,6 +125,7 @@ type.error.no.constructor.matches.args=Can not construct {0} with the passed arg
type.error.no.method.matches.args=Can not invoke method {0} with the passed arguments; they do not match any of its method signatures.
type.error.method.not.constructor=Java method {0} can't be used as a constructor.
type.error.env.not.object=$ENV must be an Object.
+type.error.to.expects.array.type=Java.to() expects an array target type. {0} is not an array type.
range.error.inappropriate.array.length=inappropriate array length: {0}
range.error.invalid.fraction.digits=fractionDigits argument to {0} must be in [0, 20]
range.error.invalid.precision=precision argument toPrecision() must be in [1, 21]
diff --git a/nashorn/test/script/basic/NASHORN-556.js b/nashorn/test/script/basic/NASHORN-556.js
index 5cb164a0cf3..1332d02bef8 100644
--- a/nashorn/test/script/basic/NASHORN-556.js
+++ b/nashorn/test/script/basic/NASHORN-556.js
@@ -47,7 +47,7 @@ function f1() {
// (NoTypeArrayData)
var empty = {};
empty.length = 10;
- Java.toJavaArray(empty);
+ Java.to(empty);
delete empty[0];
Array.prototype.slice.call(empty, 0, 1);
Array.prototype.pop.call(empty);
@@ -63,7 +63,7 @@ function f1() {
function f2() {
// DeletedArrayFilter
var deleted = [,1,,2,,3,,4,,];
- assertEq(2, Java.toJavaArray(deleted)[3]);
+ assertEq(2, Java.to(deleted)[3]);
assertEq(undefined, deleted.pop());
assertEq(4, deleted.pop());
deleted.unshift(5);
@@ -78,7 +78,7 @@ function f2() {
function f3() {
// DeletedRangeArrayFilter
var delrange = [1,2,3,,,,,,,,,,];
- Java.toJavaArray(delrange);
+ Java.to(delrange);
delrange.unshift(4);
p.apply(null, delrange);
print(delrange.slice(1,3), delrange.slice(2,6));
@@ -88,7 +88,7 @@ function f3() {
function f4() {
// NumberArrayData
var num = [1.1,2.2,3.3,4.4,5.5];
- Java.toJavaArray(num);
+ Java.to(num);
assertEq(2, num[3] >>> 1);
assertEq(5, num[4] | 0);
assertEq(5.5, num.pop());
@@ -104,7 +104,7 @@ function f4() {
function f5() {
// ObjectArrayData
var obj = [2,"two",3.14,"pi",14,"fourteen"];
- Java.toJavaArray(obj);
+ Java.to(obj);
assertEq(-12.86, obj[2] - 16);
assertEq(7, obj[4] >>> 1);
obj.unshift("one");
@@ -131,14 +131,14 @@ function f6() {
sparse.length = 1024*1024;
sparse.push(sparse.length);
delete sparse[sparse.length-1];
- //print(Java.toJavaArray(sparse).length);
+ //print(Java.to(sparse).length);
(function(){}).apply(null, sparse);
}
function f7() {
// UndefinedArrayFilter
var undef = [1,2,3,4,5,undefined,7,8,9,19];
- Java.toJavaArray(undef);
+ Java.to(undef);
assertEq(4, undef[8] >>> 1);
var tmp = undef[9] >>> 1;
undef[8] = tmp;
@@ -154,8 +154,8 @@ function f7() {
function f8() {
// LongArrayData
- var j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
- Java.toJavaArray(j);
+ var j = Java.from(Java.to([23,37,42,86,47], "long[]"));
+ Java.to(j);
p.apply(null, j);
assertEq(43, j[3] >>> 1);
assertEq(36, j[4] - 11);
@@ -164,12 +164,12 @@ function f8() {
assertEq(7, j.shift());
assertEq(47, j.pop());
j.push("asdf");
- j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
+ j = Java.from(Java.to([23,37,42,86,47], "long[]"));
j.length = 3;
j[0] = 13;
- j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
+ j = Java.from(Java.to([23,37,42,86,47], "long[]"));
delete j[0];
- j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
+ j = Java.from(Java.to([23,37,42,86,47], "long[]"));
j.length = 20;
j[0] = 13.37;
}
diff --git a/nashorn/test/script/basic/javaarrayconversion.js b/nashorn/test/script/basic/javaarrayconversion.js
index 34e2f95fb12..96ebe904668 100644
--- a/nashorn/test/script/basic/javaarrayconversion.js
+++ b/nashorn/test/script/basic/javaarrayconversion.js
@@ -34,7 +34,7 @@ var x; // used for undefined
var testCount = 0;
function testF(inputValue, type, testFn) {
- var x = Java.toJavaArray([inputValue], type)[0];
+ var x = Java.to([inputValue], type + "[]")[0];
if(!testFn(x)) {
throw ("unexpected value: " + x)
}
@@ -130,7 +130,7 @@ test({ valueOf: function() { return "42"; }, toString: function() { return "43"
function assertCantConvert(sourceType, targetType) {
try {
- Java.toJavaArray([new Java.type(sourceType)()], targetType)
+ Java.to([new Java.type(sourceType)()], targetType + "[]")
throw "no TypeError encountered"
} catch(e) {
if(!(e instanceof TypeError)) {
@@ -164,7 +164,7 @@ var intArray = new (Java.type("int[]"))(3)
intArray[0] = 1234;
intArray[1] = 42;
intArray[2] = 5;
-var jsIntArray = Java.toJavaScriptArray(intArray)
+var jsIntArray = Java.from(intArray)
assert(jsIntArray instanceof Array);
assert(jsIntArray[0] === 1234);
assert(jsIntArray[1] === 42);
@@ -179,7 +179,7 @@ assert(intArray[2] === 6);
var byteArray = new (Java.type("byte[]"))(2)
byteArray[0] = -128;
byteArray[1] = 127;
-var jsByteArray = Java.toJavaScriptArray(byteArray)
+var jsByteArray = Java.from(byteArray)
assert(jsByteArray instanceof Array);
assert(jsByteArray[0] === -128);
assert(jsByteArray[1] === 127);
@@ -187,7 +187,7 @@ assert(jsByteArray[1] === 127);
var shortArray = new (Java.type("short[]"))(2)
shortArray[0] = -32768;
shortArray[1] = 32767;
-var jsShortArray = Java.toJavaScriptArray(shortArray)
+var jsShortArray = Java.from(shortArray)
assert(jsShortArray instanceof Array);
assert(jsShortArray[0] === -32768);
assert(jsShortArray[1] === 32767);
@@ -195,7 +195,7 @@ assert(jsShortArray[1] === 32767);
var floatArray = new (Java.type("float[]"))(2)
floatArray[0] = java.lang.Float.MIN_VALUE;
floatArray[1] = java.lang.Float.MAX_VALUE;
-var jsFloatArray = Java.toJavaScriptArray(floatArray)
+var jsFloatArray = Java.from(floatArray)
assert(jsFloatArray instanceof Array);
assert(jsFloatArray[0] == java.lang.Float.MIN_VALUE);
assert(jsFloatArray[1] == java.lang.Float.MAX_VALUE);
@@ -204,7 +204,7 @@ var charArray = new (Java.type("char[]"))(3)
charArray[0] = "a";
charArray[1] = "b";
charArray[2] = "1";
-var jsCharArray = Java.toJavaScriptArray(charArray)
+var jsCharArray = Java.from(charArray)
assert(jsCharArray instanceof Array);
assert(jsCharArray[0] === 97);
assert(jsCharArray[1] === 98);
@@ -213,7 +213,7 @@ assert(jsCharArray[2] === 49);
var booleanArray = new (Java.type("boolean[]"))(2)
booleanArray[0] = true;
booleanArray[1] = false;
-var jsBooleanArray = Java.toJavaScriptArray(booleanArray)
+var jsBooleanArray = Java.from(booleanArray)
assert(jsBooleanArray instanceof Array);
assert(jsBooleanArray[0] === true);
assert(jsBooleanArray[1] === false);
diff --git a/nashorn/test/script/currently-failing/logcoverage.js b/nashorn/test/script/currently-failing/logcoverage.js
index 18b16aa1e00..2d8d410a881 100644
--- a/nashorn/test/script/currently-failing/logcoverage.js
+++ b/nashorn/test/script/currently-failing/logcoverage.js
@@ -53,8 +53,7 @@ function runScriptEngine(opts, name) {
// set new standard err
System.setErr(newErr);
System.setOut(newOut);
- var strType = Java.type("java.lang.String");
- var engine = fac.getScriptEngine(Java.toJavaArray(opts, strType));
+ var engine = fac.getScriptEngine(Java.to(opts, "java.lang.String[]"));
var reader = new java.io.FileReader(name);
engine.eval(reader);
newErr.flush();
diff --git a/nashorn/test/script/trusted/NASHORN-638.js b/nashorn/test/script/trusted/NASHORN-638.js
index 9cb6d694c55..1ff789a919b 100644
--- a/nashorn/test/script/trusted/NASHORN-638.js
+++ b/nashorn/test/script/trusted/NASHORN-638.js
@@ -47,8 +47,7 @@ function runScriptEngine(opts, code) {
try {
// set new standard err
System.setErr(newErr);
- var strType = Java.type("java.lang.String");
- var engine = fac.getScriptEngine(Java.toJavaArray(opts, strType));
+ var engine = fac.getScriptEngine(Java.to(opts, "java.lang.String[]"));
engine.eval(code);
newErr.flush();
return new java.lang.String(baos.toByteArray());
diff --git a/nashorn/test/script/trusted/NASHORN-653.js b/nashorn/test/script/trusted/NASHORN-653.js
index 2084bf70aeb..14a2cbc4c1c 100644
--- a/nashorn/test/script/trusted/NASHORN-653.js
+++ b/nashorn/test/script/trusted/NASHORN-653.js
@@ -85,8 +85,7 @@ function runScriptEngine(opts, code) {
try {
// set new standard err
System.setErr(newErr);
- var strType = Java.type("java.lang.String");
- var engine = fac.getScriptEngine(Java.toJavaArray(opts, strType));
+ var engine = fac.getScriptEngine(Java.to(opts, "java.lang.String[]"));
engine.eval(code);
newErr.flush();
return new java.lang.String(baos.toByteArray());
From 80041e51d1d0dbd291ca55056f8ad1a40d67cc2b Mon Sep 17 00:00:00 2001
From: Joe Wang
*/
public final class NativeJavaPackage extends ScriptObject {
+ private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
+ private static final MethodHandle CLASS_NOT_FOUND = findOwnMH("classNotFound", Void.TYPE, NativeJavaPackage.class);
+ private static final MethodHandle TYPE_GUARD = Guards.getClassGuard(NativeJavaPackage.class);
+
/** Full name of package (includes path.) */
private final String name;
@@ -123,6 +133,30 @@ public final class NativeJavaPackage extends ScriptObject {
return super.getDefaultValue(hint);
}
+ @Override
+ protected GuardedInvocation findNewMethod(CallSiteDescriptor desc) {
+ return createClassNotFoundInvocation(desc);
+ }
+
+ @Override
+ protected GuardedInvocation findCallMethod(CallSiteDescriptor desc, LinkRequest request) {
+ return createClassNotFoundInvocation(desc);
+ }
+
+ private static GuardedInvocation createClassNotFoundInvocation(final CallSiteDescriptor desc) {
+ // If NativeJavaPackage is invoked either as a constructor or as a function, throw a ClassNotFoundException as
+ // we can assume the user attempted to instantiate a non-existent class.
+ final MethodType type = desc.getMethodType();
+ return new GuardedInvocation(
+ MH.dropArguments(CLASS_NOT_FOUND, 1, type.parameterList().subList(1, type.parameterCount())),
+ type.parameterType(0) == NativeJavaPackage.class ? null : TYPE_GUARD);
+ }
+
+ @SuppressWarnings("unused")
+ private static void classNotFound(final NativeJavaPackage pkg) throws ClassNotFoundException {
+ throw new ClassNotFoundException(pkg.name);
+ }
+
/**
* "No such property" call placeholder.
*
@@ -188,4 +222,7 @@ public final class NativeJavaPackage extends ScriptObject {
return noSuchProperty(desc, request);
}
+ private static MethodHandle findOwnMH(final String name, final Class> rtype, final Class>... types) {
+ return MH.findStatic(MethodHandles.lookup(), NativeJavaPackage.class, name, MH.type(rtype, types));
+ }
}
diff --git a/nashorn/test/script/basic/JDK-8014953.js b/nashorn/test/script/basic/JDK-8014953.js
new file mode 100644
index 00000000000..ba7cef0f9ef
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8014953.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8014953: Have NativeJavaPackage throw a ClassNotFoundException when invoked with "new"
+ *
+ * @test
+ * @run
+ */
+
+try {
+ new java.util.ArrrayList(16)
+} catch(e) {
+ print("Invoked as constructor");
+ print("e.class=" + e.class)
+ print("e.message=" + e.message);
+}
+
+try {
+ java.util.ArrrayList(16)
+} catch(e) {
+ print("Invoked as method");
+ print("e.class=" + e.class)
+ print("e.message=" + e.message);
+}
diff --git a/nashorn/test/script/basic/JDK-8014953.js.EXPECTED b/nashorn/test/script/basic/JDK-8014953.js.EXPECTED
new file mode 100644
index 00000000000..d371112156b
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8014953.js.EXPECTED
@@ -0,0 +1,6 @@
+Invoked as constructor
+e.class=class java.lang.ClassNotFoundException
+e.message=java.util.ArrrayList
+Invoked as method
+e.class=class java.lang.ClassNotFoundException
+e.message=java.util.ArrrayList
From 9e9c04939b7e647a72b0f55ccfdb19f91317c328 Mon Sep 17 00:00:00 2001
From: James Laskey false
value of the parameter errorOccurred
before this
+ * error handler is set as current.
+ * @param errorOccurred true
to indicate that an error was handled,
+ * false
to reset the internal boolean flag
+ */
+ public void setErrorOccurredFlag(boolean errorOccurred) {
+ this.errorOccurred = errorOccurred;
}
}
@@ -76,4 +99,51 @@ public abstract class XErrorHandler {
return theInstance;
}
}
+
+ /**
+ * This is a synthetic error handler for errors generated by the native function
+ * XShmAttach
. If an error is handled, an internal boolean flag of the
+ * handler is set to true
.
+ */
+ public static final class XShmAttachHandler extends XErrorHandlerWithFlag {
+ private XShmAttachHandler() {}
+
+ @Override
+ public int handleError(long display, XErrorEvent err) {
+ if (err.get_minor_code() == XConstants.X_ShmAttach) {
+ setErrorOccurredFlag(true);
+ return 0;
+ }
+ return super.handleError(display, err);
+ }
+
+ // Shared instance
+ private static XShmAttachHandler theInstance = new XShmAttachHandler();
+ public static XShmAttachHandler getInstance() {
+ return theInstance;
+ }
+ }
+
+ /**
+ * This is a synthetic error handler for BadAlloc
errors generated by the
+ * native glX*
functions. Its internal boolean flag is set to true
,
+ * if an error is handled.
+ */
+ public static final class GLXBadAllocHandler extends XErrorHandlerWithFlag {
+ private GLXBadAllocHandler() {}
+
+ @Override
+ public int handleError(long display, XErrorEvent err) {
+ if (err.get_error_code() == XConstants.BadAlloc) {
+ setErrorOccurredFlag(true);
+ return 0;
+ }
+ return super.handleError(display, err);
+ }
+
+ private static GLXBadAllocHandler theInstance = new GLXBadAllocHandler();
+ public static GLXBadAllocHandler getInstance() {
+ return theInstance;
+ }
+ }
}
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XErrorHandlerUtil.java b/jdk/src/solaris/classes/sun/awt/X11/XErrorHandlerUtil.java
new file mode 100644
index 00000000000..500226a0403
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/awt/X11/XErrorHandlerUtil.java
@@ -0,0 +1,162 @@
+/*
+ * 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.awt.X11;
+
+import java.security.AccessController;
+import sun.awt.SunToolkit;
+import sun.security.action.GetBooleanAction;
+import sun.util.logging.PlatformLogger;
+
+/**
+ * This class contains code of the global toolkit error handler, exposes static
+ * methods which allow to set and unset synthetic error handlers.
+ */
+public final class XErrorHandlerUtil {
+ private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XErrorHandlerUtil");
+
+ /**
+ * The connection to X11 window server.
+ */
+ private static long display;
+
+ /**
+ * Error handler at the moment of XErrorHandlerUtil
initialization.
+ */
+ private static long saved_error_handler;
+
+ /**
+ * XErrorEvent being handled.
+ */
+ static volatile XErrorEvent saved_error;
+
+ /**
+ * Current error handler or null if no error handler is set.
+ */
+ private static XErrorHandler current_error_handler;
+
+ /**
+ * Value of sun.awt.noisyerrorhandler system property.
+ */
+ private static boolean noisyAwtHandler = AccessController.doPrivileged(
+ new GetBooleanAction("sun.awt.noisyerrorhandler"));
+
+ /**
+ * The flag indicating that init
was called already.
+ */
+ private static boolean initPassed;
+
+ /**
+ * Guarantees that no instance of this class can be created.
+ */
+ private XErrorHandlerUtil() {}
+
+ /**
+ * Sets the toolkit global error handler, stores the connection to X11 server, which
+ * will be used during an error handling process. This method is called once from
+ * awt_init_Display
function defined in awt_GraphicsEnv.c
+ * file immediately after the connection to X11 window server is opened.
+ * @param display the connection to X11 server which should be stored
+ */
+ private static void init(long display) {
+ SunToolkit.awtLock();
+ try {
+ if (!initPassed) {
+ XErrorHandlerUtil.display = display;
+ saved_error_handler = XlibWrapper.SetToolkitErrorHandler();
+ initPassed = true;
+ }
+ } finally {
+ SunToolkit.awtUnlock();
+ }
+ }
+
+ /**
+ * Sets a synthetic error handler. Must be called with the acquired AWT lock.
+ * @param handler the synthetic error handler to set
+ */
+ public static void WITH_XERROR_HANDLER(XErrorHandler handler) {
+ saved_error = null;
+ current_error_handler = handler;
+ }
+
+ /**
+ * Unsets a current synthetic error handler. Must be called with the acquired AWT lock.
+ */
+ public static void RESTORE_XERROR_HANDLER() {
+ // Wait until all requests are processed by the X server
+ // and only then uninstall the error handler.
+ XSync();
+ current_error_handler = null;
+ }
+
+ /**
+ * Should be called under LOCK.
+ */
+ public static int SAVED_XERROR_HANDLER(long display, XErrorEvent error) {
+ if (saved_error_handler != 0) {
+ // Default XErrorHandler may just terminate the process. Don't call it.
+ // return XlibWrapper.CallErrorHandler(saved_error_handler, display, error.pData);
+ }
+ if (log.isLoggable(PlatformLogger.FINE)) {
+ log.fine("Unhandled XErrorEvent: " +
+ "id=" + error.get_resourceid() + ", " +
+ "serial=" + error.get_serial() + ", " +
+ "ec=" + error.get_error_code() + ", " +
+ "rc=" + error.get_request_code() + ", " +
+ "mc=" + error.get_minor_code());
+ }
+ return 0;
+ }
+
+ /**
+ * Called from the native code when an error occurs.
+ */
+ private static int globalErrorHandler(long display, long event_ptr) {
+ if (noisyAwtHandler) {
+ XlibWrapper.PrintXErrorEvent(display, event_ptr);
+ }
+ XErrorEvent event = new XErrorEvent(event_ptr);
+ saved_error = event;
+ try {
+ if (current_error_handler != null) {
+ return current_error_handler.handleError(display, event);
+ } else {
+ return SAVED_XERROR_HANDLER(display, event);
+ }
+ } catch (Throwable z) {
+ log.fine("Error in GlobalErrorHandler", z);
+ }
+ return 0;
+ }
+
+ private static void XSync() {
+ SunToolkit.awtLock();
+ try {
+ XlibWrapper.XSync(display, 0);
+ } finally {
+ SunToolkit.awtUnlock();
+ }
+ }
+}
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XQueryTree.java b/jdk/src/solaris/classes/sun/awt/X11/XQueryTree.java
index 94921826cbc..dede21f6e30 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XQueryTree.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XQueryTree.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,7 @@ public class XQueryTree {
}
__executed = true;
if (errorHandler != null) {
- XToolkit.WITH_XERROR_HANDLER(errorHandler);
+ XErrorHandlerUtil.WITH_XERROR_HANDLER(errorHandler);
}
Native.putLong(children_ptr, 0);
int status =
@@ -72,7 +72,7 @@ public class XQueryTree {
children_ptr,
nchildren_ptr );
if (errorHandler != null) {
- XToolkit.RESTORE_XERROR_HANDLER();
+ XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
}
return status;
} finally {
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
index 68658d6b5a0..607537cdaa4 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -128,7 +128,6 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
initIDs();
setBackingStoreType();
}
- noisyAwtHandler = AccessController.doPrivileged(new GetBooleanAction("sun.awt.noisyerrorhandler"));
}
/*
@@ -137,78 +136,6 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
*/
static native long getTrayIconDisplayTimeout();
- //---- ERROR HANDLER CODE ----//
-
- /*
- * Error handler at the moment of XToolkit initialization
- */
- private static long saved_error_handler;
-
- /*
- * XErrorEvent being handled
- */
- static volatile XErrorEvent saved_error;
-
- /*
- * Current error handler or null if no error handler is set
- */
- private static XErrorHandler current_error_handler;
-
- /*
- * Value of sun.awt.noisyerrorhandler system property
- */
- private static boolean noisyAwtHandler;
-
- public static void WITH_XERROR_HANDLER(XErrorHandler handler) {
- saved_error = null;
- current_error_handler = handler;
- }
-
- public static void RESTORE_XERROR_HANDLER() {
- // wait until all requests are processed by the X server
- // and only then uninstall the error handler
- XSync();
- current_error_handler = null;
- }
-
- // Should be called under LOCK
- public static int SAVED_ERROR_HANDLER(long display, XErrorEvent error) {
- if (saved_error_handler != 0) {
- // Default XErrorHandler may just terminate the process. Don't call it.
- // return XlibWrapper.CallErrorHandler(saved_error_handler, display, error.pData);
- }
- if (log.isLoggable(PlatformLogger.FINE)) {
- log.fine("Unhandled XErrorEvent: " +
- "id=" + error.get_resourceid() + ", " +
- "serial=" + error.get_serial() + ", " +
- "ec=" + error.get_error_code() + ", " +
- "rc=" + error.get_request_code() + ", " +
- "mc=" + error.get_minor_code());
- }
- return 0;
- }
-
- // Called from the native code when an error occurs
- private static int globalErrorHandler(long display, long event_ptr) {
- if (noisyAwtHandler) {
- XlibWrapper.PrintXErrorEvent(display, event_ptr);
- }
- XErrorEvent event = new XErrorEvent(event_ptr);
- saved_error = event;
- try {
- if (current_error_handler != null) {
- return current_error_handler.handleError(display, event);
- } else {
- return SAVED_ERROR_HANDLER(display, event);
- }
- } catch (Throwable z) {
- log.fine("Error in GlobalErrorHandler", z);
- }
- return 0;
- }
-
- //---- END OF ERROR HANDLER CODE ----//
-
private native static void initIDs();
native static void waitForEvents(long nextTaskTime);
static Thread toolkitThread;
@@ -306,8 +233,6 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
//set system property if not yet assigned
System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled);
- saved_error_handler = XlibWrapper.SetToolkitErrorHandler();
-
// Detect display mode changes
XlibWrapper.XSelectInput(XToolkit.getDisplay(), XToolkit.getDefaultRootWindow(), XConstants.StructureNotifyMask);
XToolkit.addEventDispatcher(XToolkit.getDefaultRootWindow(), new XEventDispatcher() {
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XTranslateCoordinates.java b/jdk/src/solaris/classes/sun/awt/X11/XTranslateCoordinates.java
index ba805a472b0..42a3a42844e 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XTranslateCoordinates.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XTranslateCoordinates.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,7 +68,7 @@ public class XTranslateCoordinates {
}
__executed = true;
if (errorHandler != null) {
- XToolkit.WITH_XERROR_HANDLER(errorHandler);
+ XErrorHandlerUtil.WITH_XERROR_HANDLER(errorHandler);
}
int status =
XlibWrapper.XTranslateCoordinates(XToolkit.getDisplay(),
@@ -80,7 +80,7 @@ public class XTranslateCoordinates {
dest_y_ptr,
child_ptr );
if (errorHandler != null) {
- XToolkit.RESTORE_XERROR_HANDLER();
+ XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
}
return status;
} finally {
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWM.java b/jdk/src/solaris/classes/sun/awt/X11/XWM.java
index 6dd929460c9..94410519dca 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XWM.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWM.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -284,12 +284,12 @@ final class XWM
winmgr_running = false;
substruct.set_event_mask(XConstants.SubstructureRedirectMask);
- XToolkit.WITH_XERROR_HANDLER(detectWMHandler);
+ XErrorHandlerUtil.WITH_XERROR_HANDLER(detectWMHandler);
XlibWrapper.XChangeWindowAttributes(XToolkit.getDisplay(),
XToolkit.getDefaultRootWindow(),
XConstants.CWEventMask,
substruct.pData);
- XToolkit.RESTORE_XERROR_HANDLER();
+ XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
/*
* If no WM is running then our selection for SubstructureRedirect
@@ -632,15 +632,16 @@ final class XWM
XToolkit.awtLock();
try {
- XToolkit.WITH_XERROR_HANDLER(XErrorHandler.VerifyChangePropertyHandler.getInstance());
+ XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.VerifyChangePropertyHandler.getInstance());
XlibWrapper.XChangePropertyS(XToolkit.getDisplay(), XToolkit.getDefaultRootWindow(),
XA_ICEWM_WINOPTHINT.getAtom(),
XA_ICEWM_WINOPTHINT.getAtom(),
8, XConstants.PropModeReplace,
new String(opt));
- XToolkit.RESTORE_XERROR_HANDLER();
+ XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
- if (XToolkit.saved_error != null && XToolkit.saved_error.get_error_code() != XConstants.Success) {
+ if ((XErrorHandlerUtil.saved_error != null) &&
+ (XErrorHandlerUtil.saved_error.get_error_code() != XConstants.Success)) {
log.finer("Erorr getting XA_ICEWM_WINOPTHINT property");
return false;
}
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XlibUtil.java b/jdk/src/solaris/classes/sun/awt/X11/XlibUtil.java
index 875ab16f642..f06af9856ae 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XlibUtil.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XlibUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -151,8 +151,8 @@ public class XlibUtil
{
int status = xtc.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance());
if ((status != 0) &&
- ((XToolkit.saved_error == null) ||
- (XToolkit.saved_error.get_error_code() == XConstants.Success)))
+ ((XErrorHandlerUtil.saved_error == null) ||
+ (XErrorHandlerUtil.saved_error.get_error_code() == XConstants.Success)))
{
translated = new Point(xtc.get_dest_x(), xtc.get_dest_y());
}
@@ -345,13 +345,13 @@ public class XlibUtil
XWindowAttributes wattr = new XWindowAttributes();
try
{
- XToolkit.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());
+ XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance());
int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
window, wattr.pData);
- XToolkit.RESTORE_XERROR_HANDLER();
+ XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
if ((status != 0) &&
- ((XToolkit.saved_error == null) ||
- (XToolkit.saved_error.get_error_code() == XConstants.Success)))
+ ((XErrorHandlerUtil.saved_error == null) ||
+ (XErrorHandlerUtil.saved_error.get_error_code() == XConstants.Success)))
{
return wattr.get_map_state();
}
diff --git a/jdk/src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java b/jdk/src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java
index fd66a03fda5..9da0fd93442 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -996,7 +996,7 @@ public class WrapperGenerator {
pw.println("\t\t\t}");
pw.println("\t\t\t__executed = true;");
pw.println("\t\t\tif (errorHandler != null) {");
- pw.println("\t\t\t XToolkit.WITH_XERROR_HANDLER(errorHandler);");
+ pw.println("\t\t\t XErrorHandlerUtil.WITH_XERROR_HANDLER(errorHandler);");
pw.println("\t\t\t}");
iter = ft.getArguments().iterator();
while (iter.hasNext()) {
@@ -1025,7 +1025,7 @@ public class WrapperGenerator {
}
pw.println("\t\t\t);");
pw.println("\t\t\tif (errorHandler != null) {");
- pw.println("\t\t\t XToolkit.RESTORE_XERROR_HANDLER();");
+ pw.println("\t\t\t XErrorHandlerUtil.RESTORE_XERROR_HANDLER();");
pw.println("\t\t\t}");
if (!ft.isVoid()) {
pw.println("\t\t\treturn status;");
diff --git a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c
index 7ae4cdd3259..0c62dca97a2 100644
--- a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c
+++ b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -758,6 +758,8 @@ awt_init_Display(JNIEnv *env, jobject this)
}
XSetIOErrorHandler(xioerror_handler);
+ JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XErrorHandlerUtil", "init", "(J)V",
+ ptr_to_jlong(awt_display));
/* set awt_numScreens, and whether or not we're using Xinerama */
xineramaInit();
@@ -904,28 +906,12 @@ Java_sun_awt_X11GraphicsDevice_getDisplay(JNIEnv *env, jobject this)
static jint canUseShmExt = UNSET_MITSHM;
static jint canUseShmExtPixmaps = UNSET_MITSHM;
-static jboolean xshmAttachFailed = JNI_FALSE;
-
-int J2DXErrHandler(Display *display, XErrorEvent *xerr) {
- int ret = 0;
- if (xerr->minor_code == X_ShmAttach) {
- xshmAttachFailed = JNI_TRUE;
- } else {
- ret = (*xerror_saved_handler)(display, xerr);
- }
- return ret;
-}
-jboolean isXShmAttachFailed() {
- return xshmAttachFailed;
-}
-void resetXShmAttachFailed() {
- xshmAttachFailed = JNI_FALSE;
-}
void TryInitMITShm(JNIEnv *env, jint *shmExt, jint *shmPixmaps) {
XShmSegmentInfo shminfo;
int XShmMajor, XShmMinor;
int a, b, c;
+ jboolean xShmAttachResult;
AWT_LOCK();
if (canUseShmExt != UNSET_MITSHM) {
@@ -963,21 +949,14 @@ void TryInitMITShm(JNIEnv *env, jint *shmExt, jint *shmPixmaps) {
}
shminfo.readOnly = True;
- resetXShmAttachFailed();
- /**
- * The J2DXErrHandler handler will set xshmAttachFailed
- * to JNI_TRUE if any Shm error has occured.
- */
- EXEC_WITH_XERROR_HANDLER(J2DXErrHandler,
- XShmAttach(awt_display, &shminfo));
-
+ xShmAttachResult = TryXShmAttach(env, awt_display, &shminfo);
/**
* Get rid of the id now to reduce chances of leaking
* system resources.
*/
shmctl(shminfo.shmid, IPC_RMID, 0);
- if (isXShmAttachFailed() == JNI_FALSE) {
+ if (xShmAttachResult == JNI_TRUE) {
canUseShmExt = CAN_USE_MITSHM;
/* check if we can use shared pixmaps */
XShmQueryVersion(awt_display, &XShmMajor, &XShmMinor,
@@ -992,6 +971,23 @@ void TryInitMITShm(JNIEnv *env, jint *shmExt, jint *shmPixmaps) {
}
AWT_UNLOCK();
}
+
+/*
+ * Must be called with the acquired AWT lock.
+ */
+jboolean TryXShmAttach(JNIEnv *env, Display *display, XShmSegmentInfo *shminfo) {
+ jboolean errorOccurredFlag = JNI_FALSE;
+ jobject errorHandlerRef;
+
+ /*
+ * XShmAttachHandler will set its internal flag to JNI_TRUE, if any Shm error occurs.
+ */
+ EXEC_WITH_XERROR_HANDLER(env, "sun/awt/X11/XErrorHandler$XShmAttachHandler",
+ "()Lsun/awt/X11/XErrorHandler$XShmAttachHandler;", JNI_TRUE,
+ errorHandlerRef, errorOccurredFlag,
+ XShmAttach(display, shminfo));
+ return errorOccurredFlag == JNI_FALSE ? JNI_TRUE : JNI_FALSE;
+}
#endif /* MITSHM */
/*
diff --git a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.h b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.h
index 39ea6d596a5..cb06ae1bd08 100644
--- a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.h
+++ b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,8 +50,7 @@
extern int XShmQueryExtension();
void TryInitMITShm(JNIEnv *env, jint *shmExt, jint *shmPixmaps);
-void resetXShmAttachFailed();
-jboolean isXShmAttachFailed();
+jboolean TryXShmAttach(JNIEnv *env, Display *display, XShmSegmentInfo *shminfo);
#endif /* MITSHM */
diff --git a/jdk/src/solaris/native/sun/awt/awt_util.c b/jdk/src/solaris/native/sun/awt/awt_util.c
index f1f897c1564..d92c96e5e92 100644
--- a/jdk/src/solaris/native/sun/awt/awt_util.c
+++ b/jdk/src/solaris/native/sun/awt/awt_util.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2003, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -41,18 +41,6 @@
#include "java_awt_event_MouseWheelEvent.h"
-/*
- * Since X reports protocol errors asynchronously, we often need to
- * install an error handler that acts like a callback. While that
- * specialized handler is installed we save original handler here.
- */
-XErrorHandler xerror_saved_handler;
-
-/*
- * A place for error handler to report the error code.
- */
-unsigned char xerror_code;
-
extern jint getModifiers(uint32_t state, jint button, jint keyCode);
extern jint getButton(uint32_t button);
diff --git a/jdk/src/solaris/native/sun/awt/awt_util.h b/jdk/src/solaris/native/sun/awt/awt_util.h
index 5fb113fc405..6e350727806 100644
--- a/jdk/src/solaris/native/sun/awt/awt_util.h
+++ b/jdk/src/solaris/native/sun/awt/awt_util.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -29,42 +29,47 @@
#ifndef HEADLESS
#include "gdefs.h"
-#define WITH_XERROR_HANDLER(f) do { \
- XSync(awt_display, False); \
- xerror_code = Success; \
- xerror_saved_handler = XSetErrorHandler(f); \
-} while (0)
-
-/* Convenience macro for handlers to use */
-#define XERROR_SAVE(err) do { \
- xerror_code = (err)->error_code; \
-} while (0)
-
-#define RESTORE_XERROR_HANDLER do { \
- XSync(awt_display, False); \
- XSetErrorHandler(xerror_saved_handler); \
-} while (0)
-
-#define EXEC_WITH_XERROR_HANDLER(f, code) do { \
- WITH_XERROR_HANDLER(f); \
- do { \
- code; \
- } while (0); \
- RESTORE_XERROR_HANDLER; \
+/*
+ * Expected types of arguments of the macro.
+ * (JNIEnv*, const char*, const char*, jboolean, jobject)
+ */
+#define WITH_XERROR_HANDLER(env, handlerClassName, getInstanceSignature, \
+ handlerHasFlag, handlerRef) do { \
+ handlerRef = JNU_CallStaticMethodByName(env, NULL, handlerClassName, "getInstance", \
+ getInstanceSignature).l; \
+ if (handlerHasFlag == JNI_TRUE) { \
+ JNU_CallMethodByName(env, NULL, handlerRef, "setErrorOccurredFlag", "(Z)V", JNI_FALSE); \
+ } \
+ JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XErrorHandlerUtil", "WITH_XERROR_HANDLER", \
+ "(Lsun/awt/X11/XErrorHandler;)V", handlerRef); \
} while (0)
/*
- * Since X reports protocol errors asynchronously, we often need to
- * install an error handler that acts like a callback. While that
- * specialized handler is installed we save original handler here.
+ * Expected types of arguments of the macro.
+ * (JNIEnv*)
*/
-extern XErrorHandler xerror_saved_handler;
+#define RESTORE_XERROR_HANDLER(env) do { \
+ JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XErrorHandlerUtil", \
+ "RESTORE_XERROR_HANDLER", "()V"); \
+} while (0)
/*
- * A place for error handler to report the error code.
+ * Expected types of arguments of the macro.
+ * (JNIEnv*, const char*, const char*, jboolean, jobject, jboolean, No type - C expression)
*/
-extern unsigned char xerror_code;
-
+#define EXEC_WITH_XERROR_HANDLER(env, handlerClassName, getInstanceSignature, handlerHasFlag, \
+ handlerRef, errorOccurredFlag, code) do { \
+ handlerRef = NULL; \
+ WITH_XERROR_HANDLER(env, handlerClassName, getInstanceSignature, handlerHasFlag, handlerRef); \
+ do { \
+ code; \
+ } while (0); \
+ RESTORE_XERROR_HANDLER(env); \
+ if (handlerHasFlag == JNI_TRUE) { \
+ errorOccurredFlag = JNU_CallMethodByName(env, NULL, handlerRef, "getErrorOccurredFlag", \
+ "()Z").z; \
+ } \
+} while (0)
#endif /* !HEADLESS */
#ifndef INTERSECTS
diff --git a/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c b/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
index a9549e0cd03..4a4e75f6228 100644
--- a/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
+++ b/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,8 +48,6 @@ extern DisposeFunc OGLSD_Dispose;
extern void
OGLSD_SetNativeDimensions(JNIEnv *env, OGLSDOps *oglsdo, jint w, jint h);
-jboolean surfaceCreationFailed = JNI_FALSE;
-
#endif /* !HEADLESS */
JNIEXPORT void JNICALL
@@ -349,18 +347,6 @@ OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo)
return JNI_TRUE;
}
-static int
-GLXSD_BadAllocXErrHandler(Display *display, XErrorEvent *xerr)
-{
- int ret = 0;
- if (xerr->error_code == BadAlloc) {
- surfaceCreationFailed = JNI_TRUE;
- } else {
- ret = (*xerror_saved_handler)(display, xerr);
- }
- return ret;
-}
-
JNIEXPORT jboolean JNICALL
Java_sun_java2d_opengl_GLXSurfaceData_initPbuffer
(JNIEnv *env, jobject glxsd,
@@ -376,6 +362,8 @@ Java_sun_java2d_opengl_GLXSurfaceData_initPbuffer
int attrlist[] = {GLX_PBUFFER_WIDTH, 0,
GLX_PBUFFER_HEIGHT, 0,
GLX_PRESERVED_CONTENTS, GL_FALSE, 0};
+ jboolean errorOccurredFlag;
+ jobject errorHandlerRef;
J2dTraceLn3(J2D_TRACE_INFO,
"GLXSurfaceData_initPbuffer: w=%d h=%d opq=%d",
@@ -403,12 +391,13 @@ Java_sun_java2d_opengl_GLXSurfaceData_initPbuffer
attrlist[1] = width;
attrlist[3] = height;
- surfaceCreationFailed = JNI_FALSE;
- EXEC_WITH_XERROR_HANDLER(
- GLXSD_BadAllocXErrHandler,
- pbuffer = j2d_glXCreatePbuffer(awt_display,
- glxinfo->fbconfig, attrlist));
- if ((pbuffer == 0) || surfaceCreationFailed) {
+ errorOccurredFlag = JNI_FALSE;
+ EXEC_WITH_XERROR_HANDLER(env, "sun/awt/X11/XErrorHandler$GLXBadAllocHandler",
+ "()Lsun/awt/X11/XErrorHandler$GLXBadAllocHandler;", JNI_TRUE,
+ errorHandlerRef, errorOccurredFlag,
+ pbuffer = j2d_glXCreatePbuffer(awt_display, glxinfo->fbconfig, attrlist));
+
+ if ((pbuffer == 0) || errorOccurredFlag) {
J2dRlsTraceLn(J2D_TRACE_ERROR,
"GLXSurfaceData_initPbuffer: could not create glx pbuffer");
return JNI_FALSE;
diff --git a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
index cee9bb75bfd..57e121701ff 100644
--- a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
+++ b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -65,7 +65,6 @@ static UnlockFunc X11SD_Unlock;
static DisposeFunc X11SD_Dispose;
static GetPixmapBgFunc X11SD_GetPixmapWithBg;
static ReleasePixmapBgFunc X11SD_ReleasePixmapWithBg;
-extern int J2DXErrHandler(Display *display, XErrorEvent *xerr);
extern AwtGraphicsConfigDataPtr
getGraphicsConfigFromComponentPeer(JNIEnv *env, jobject this);
extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
@@ -521,6 +520,8 @@ XImage* X11SD_CreateSharedImage(X11SDOps *xsdo,
{
XImage *img = NULL;
XShmSegmentInfo *shminfo;
+ JNIEnv* env;
+ jboolean xShmAttachResult;
shminfo = malloc(sizeof(XShmSegmentInfo));
if (shminfo == NULL) {
@@ -559,9 +560,8 @@ XImage* X11SD_CreateSharedImage(X11SDOps *xsdo,
shminfo->readOnly = False;
- resetXShmAttachFailed();
- EXEC_WITH_XERROR_HANDLER(J2DXErrHandler,
- XShmAttach(awt_display, shminfo));
+ env = (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+ xShmAttachResult = TryXShmAttach(env, awt_display, shminfo);
/*
* Once the XSync round trip has finished then we
@@ -570,7 +570,7 @@ XImage* X11SD_CreateSharedImage(X11SDOps *xsdo,
*/
shmctl(shminfo->shmid, IPC_RMID, 0);
- if (isXShmAttachFailed() == JNI_TRUE) {
+ if (xShmAttachResult == JNI_FALSE) {
J2dRlsTraceLn1(J2D_TRACE_ERROR,
"X11SD_SetupSharedSegment XShmAttach has failed: %s",
strerror(errno));
diff --git a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c
index f48e833ad2d..ac6506c5a3c 100644
--- a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c
+++ b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -1264,8 +1264,8 @@ static int ToolkitErrorHandler(Display * dpy, XErrorEvent * event) {
if (jvm != NULL) {
env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (env) {
- return JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XToolkit", "globalErrorHandler", "(JJ)I",
- ptr_to_jlong(dpy), ptr_to_jlong(event)).i;
+ return JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XErrorHandlerUtil",
+ "globalErrorHandler", "(JJ)I", ptr_to_jlong(dpy), ptr_to_jlong(event)).i;
}
}
return 0;
From aa649f097f319dc96ed7aa4f09a9674f8ec16545 Mon Sep 17 00:00:00 2001
From: David Holmes
- *
- *
- * @return Class object of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- static Object createObject(String factoryId, String fallbackClassName)
- throws ConfigurationError {
- return createObject(factoryId, null, fallbackClassName);
- } // createObject(String,String):Object
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- * System.getProperty
- * META-INF/services/factoryId
file
- *
- *
- *
- * @return Class object of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param propertiesFilename The filename in the $java.home/lib directory
- * of the properties file. If none specified,
- * ${java.home}/lib/xerces.properties will be used.
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- static Object createObject(String factoryId,
- String propertiesFilename,
- String fallbackClassName)
- throws ConfigurationError
- {
- if (DEBUG) debugPrintln("debug is on");
-
- SecuritySupport ss = SecuritySupport.getInstance();
- ClassLoader cl = findClassLoader();
-
- // Use the system property first
- try {
- String systemProp = ss.getSystemProperty(factoryId);
- if (systemProp != null) {
- if (DEBUG) debugPrintln("found system property, value=" + systemProp);
- return newInstance(systemProp, cl, true);
- }
- } catch (SecurityException se) {
- // Ignore and continue w/ next location
- }
-
- // JAXP specific change
- // always use fallback class to avoid the expense of constantly
- // "stat"ing a non-existent "xerces.properties" and jar SPI entry
- // see CR 6400863: Expensive creating of SAX parser in Mustang
- if (true) {
- if (fallbackClassName == null) {
- throw new ConfigurationError(
- "Provider for " + factoryId + " cannot be found", null);
- }
-
- if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName);
- return newInstance(fallbackClassName, cl, true);
- }
-
- // Try to read from propertiesFilename, or $java.home/lib/xerces.properties
- String factoryClassName = null;
- // no properties file name specified; use $JAVA_HOME/lib/xerces.properties:
- if (propertiesFilename == null) {
- File propertiesFile = null;
- boolean propertiesFileExists = false;
- try {
- String javah = ss.getSystemProperty("java.home");
- propertiesFilename = javah + File.separator +
- "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
- propertiesFile = new File(propertiesFilename);
- propertiesFileExists = ss.getFileExists(propertiesFile);
- } catch (SecurityException e) {
- // try again...
- fLastModified = -1;
- fXercesProperties = null;
- }
-
- synchronized (ObjectFactory.class) {
- boolean loadProperties = false;
- FileInputStream fis = null;
- try {
- // file existed last time
- if(fLastModified >= 0) {
- if(propertiesFileExists &&
- (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
- loadProperties = true;
- } else {
- // file has stopped existing...
- if(!propertiesFileExists) {
- fLastModified = -1;
- fXercesProperties = null;
- } // else, file wasn't modified!
- }
- } else {
- // file has started to exist:
- if(propertiesFileExists) {
- loadProperties = true;
- fLastModified = ss.getLastModified(propertiesFile);
- } // else, nothing's changed
- }
- if(loadProperties) {
- // must never have attempted to read xerces.properties before (or it's outdeated)
- fXercesProperties = new Properties();
- fis = ss.getFileInputStream(propertiesFile);
- fXercesProperties.load(fis);
- }
- } catch (Exception x) {
- fXercesProperties = null;
- fLastModified = -1;
- // assert(x instanceof FileNotFoundException
- // || x instanceof SecurityException)
- // In both cases, ignore and continue w/ next location
- }
- finally {
- // try to close the input stream if one was opened.
- if (fis != null) {
- try {
- fis.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
- }
- }
- if(fXercesProperties != null) {
- factoryClassName = fXercesProperties.getProperty(factoryId);
- }
- } else {
- FileInputStream fis = null;
- try {
- fis = ss.getFileInputStream(new File(propertiesFilename));
- Properties props = new Properties();
- props.load(fis);
- factoryClassName = props.getProperty(factoryId);
- } catch (Exception x) {
- // assert(x instanceof FileNotFoundException
- // || x instanceof SecurityException)
- // In both cases, ignore and continue w/ next location
- }
- finally {
- // try to close the input stream if one was opened.
- if (fis != null) {
- try {
- fis.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
- }
- }
- if (factoryClassName != null) {
- if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName);
- return newInstance(factoryClassName, cl, true);
- }
-
- // Try Jar Service Provider Mechanism
- Object provider = findJarServiceProvider(factoryId);
- if (provider != null) {
- return provider;
- }
-
- if (fallbackClassName == null) {
- throw new ConfigurationError(
- "Provider for " + factoryId + " cannot be found", null);
- }
-
- if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName);
- return newInstance(fallbackClassName, cl, true);
- } // createObject(String,String,String):Object
-
- //
- // Private static methods
- //
-
- /** Prints a message to standard error if debugging is enabled. */
- private static void debugPrintln(String msg) {
- if (DEBUG) {
- System.err.println("JAXP: " + msg);
- }
- } // debugPrintln(String)
-
- /**
- * Figure out which ClassLoader to use. For JDK 1.2 and later use
- * the context ClassLoader.
- */
- static ClassLoader findClassLoader()
- throws ConfigurationError
- {
- SecuritySupport ss = SecuritySupport.getInstance();
-
- // Figure out which ClassLoader to use for loading the provider
- // class. If there is a Context ClassLoader then use it.
- ClassLoader context = ss.getContextClassLoader();
- ClassLoader system = ss.getSystemClassLoader();
-
- ClassLoader chain = system;
- while (true) {
- if (context == chain) {
- // Assert: we are on JDK 1.1 or we have no Context ClassLoader
- // or any Context ClassLoader in chain of system classloader
- // (including extension ClassLoader) so extend to widest
- // ClassLoader (always look in system ClassLoader if Xerces
- // is in boot/extension/system classpath and in current
- // ClassLoader otherwise); normal classloaders delegate
- // back to system ClassLoader first so this widening doesn't
- // change the fact that context ClassLoader will be consulted
- ClassLoader current = ObjectFactory.class.getClassLoader();
-
- chain = system;
- while (true) {
- if (current == chain) {
- // Assert: Current ClassLoader in chain of
- // boot/extension/system ClassLoaders
- return system;
- }
- if (chain == null) {
- break;
- }
- chain = ss.getParentClassLoader(chain);
- }
-
- // Assert: Current ClassLoader not in chain of
- // boot/extension/system ClassLoaders
- return current;
- }
-
- if (chain == null) {
- // boot ClassLoader reached
- break;
- }
-
- // Check for any extension ClassLoaders in chain up to
- // boot ClassLoader
- chain = ss.getParentClassLoader(chain);
- };
-
- // Assert: Context ClassLoader not in chain of
- // boot/extension/system ClassLoaders
- return context;
- } // findClassLoader():ClassLoader
-
- /**
- * Create an instance of a class using the specified ClassLoader
- */
- static Object newInstance(String className, ClassLoader cl,
- boolean doFallback)
- throws ConfigurationError
- {
- // assert(className != null);
- try{
- Class providerClass = findProviderClass(className, cl, doFallback);
- Object instance = providerClass.newInstance();
- if (DEBUG) debugPrintln("created new instance of " + providerClass +
- " using ClassLoader: " + cl);
- return instance;
- } catch (ClassNotFoundException x) {
- throw new ConfigurationError(
- "Provider " + className + " not found", x);
- } catch (Exception x) {
- throw new ConfigurationError(
- "Provider " + className + " could not be instantiated: " + x,
- x);
- }
- }
-
- /**
- * Find a Class using the specified ClassLoader
- */
- static Class findProviderClass(String className, ClassLoader cl,
- boolean doFallback)
- throws ClassNotFoundException, ConfigurationError
- {
- //throw security exception if the calling thread is not allowed to access the package
- //restrict the access to package as speicified in java.security policy
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- final int lastDot = className.lastIndexOf(".");
- String packageName = className;
- if (lastDot != -1) packageName = className.substring(0, lastDot);
- security.checkPackageAccess(packageName);
- }
- Class providerClass;
- if (cl == null) {
- // XXX Use the bootstrap ClassLoader. There is no way to
- // load a class using the bootstrap ClassLoader that works
- // in both JDK 1.1 and Java 2. However, this should still
- // work b/c the following should be true:
- //
- // (cl == null) iff current ClassLoader == null
- //
- // Thus Class.forName(String) will use the current
- // ClassLoader which will be the bootstrap ClassLoader.
- providerClass = Class.forName(className);
- } else {
- try {
- providerClass = cl.loadClass(className);
- } catch (ClassNotFoundException x) {
- if (doFallback) {
- // Fall back to current classloader
- ClassLoader current = ObjectFactory.class.getClassLoader();
- if (current == null) {
- providerClass = Class.forName(className);
- } else if (cl != current) {
- cl = current;
- providerClass = cl.loadClass(className);
- } else {
- throw x;
- }
- } else {
- throw x;
- }
- }
- }
-
- return providerClass;
- }
-
- /*
- * Try to find provider using Jar Service Provider Mechanism
- *
- * @return instance of provider class if found or null
- */
- private static Object findJarServiceProvider(String factoryId)
- throws ConfigurationError
- {
- SecuritySupport ss = SecuritySupport.getInstance();
- String serviceId = "META-INF/services/" + factoryId;
- InputStream is = null;
-
- // First try the Context ClassLoader
- ClassLoader cl = findClassLoader();
-
- is = ss.getResourceAsStream(cl, serviceId);
-
- // If no provider found then try the current ClassLoader
- if (is == null) {
- ClassLoader current = ObjectFactory.class.getClassLoader();
- if (cl != current) {
- cl = current;
- is = ss.getResourceAsStream(cl, serviceId);
- }
- }
-
- if (is == null) {
- // No provider found
- return null;
- }
-
- if (DEBUG) debugPrintln("found jar resource=" + serviceId +
- " using ClassLoader: " + cl);
-
- // Read the service provider name in UTF-8 as specified in
- // the jar spec. Unfortunately this fails in Microsoft
- // VJ++, which does not implement the UTF-8
- // encoding. Theoretically, we should simply let it fail in
- // that case, since the JVM is obviously broken if it
- // doesn't support such a basic standard. But since there
- // are still some users attempting to use VJ++ for
- // development, we have dropped in a fallback which makes a
- // second attempt using the platform's default encoding. In
- // VJ++ this is apparently ASCII, which is a subset of
- // UTF-8... and since the strings we'll be reading here are
- // also primarily limited to the 7-bit ASCII range (at
- // least, in English versions), this should work well
- // enough to keep us on the air until we're ready to
- // officially decommit from VJ++. [Edited comment from
- // jkesselm]
- BufferedReader rd;
- try {
- rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH);
- } catch (java.io.UnsupportedEncodingException e) {
- rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH);
- }
-
- String factoryClassName = null;
- try {
- // XXX Does not handle all possible input as specified by the
- // Jar Service Provider specification
- factoryClassName = rd.readLine();
- } catch (IOException x) {
- // No provider found
- return null;
- }
- finally {
- try {
- // try to close the reader.
- rd.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
-
- if (factoryClassName != null &&
- ! "".equals(factoryClassName)) {
- if (DEBUG) debugPrintln("found in resource, value="
- + factoryClassName);
-
- // Note: here we do not want to fall back to the current
- // ClassLoader because we want to avoid the case where the
- // resource file was found using one ClassLoader and the
- // provider class was instantiated using a different one.
- return newInstance(factoryClassName, cl, false);
- }
-
- // No provider found
- return null;
- }
-
- //
- // Classes
- //
-
- /**
- * A configuration error.
- */
- static final class ConfigurationError
- extends Error {
-
- /** Serialization version. */
- static final long serialVersionUID = 5061904944269807898L;
-
- //
- // Data
- //
-
- /** Exception. */
- private Exception exception;
-
- //
- // Constructors
- //
-
- /**
- * Construct a new instance with the specified detail string and
- * exception.
- */
- ConfigurationError(String msg, Exception x) {
- super(msg);
- this.exception = x;
- } // System.getProperty
- * $java.home/lib/propertiesFilename
file
- * META-INF/services/factoryId
file
- *
- *
- *
- * @return Class object of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- static Object createObject(String factoryId, String fallbackClassName)
- throws ConfigurationError {
- return createObject(factoryId, null, fallbackClassName);
- } // createObject(String,String):Object
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- * System.getProperty
- * META-INF/services/factoryId
file
- *
- *
- *
- * @return Class object of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param propertiesFilename The filename in the $java.home/lib directory
- * of the properties file. If none specified,
- * ${java.home}/lib/xerces.properties will be used.
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- static Object createObject(String factoryId,
- String propertiesFilename,
- String fallbackClassName)
- throws ConfigurationError
- {
- if (DEBUG) debugPrintln("debug is on");
-
- SecuritySupport ss = SecuritySupport.getInstance();
- ClassLoader cl = findClassLoader();
-
- // Use the system property first
- try {
- String systemProp = ss.getSystemProperty(factoryId);
- if (systemProp != null) {
- if (DEBUG) debugPrintln("found system property, value=" + systemProp);
- return newInstance(systemProp, cl, true);
- }
- } catch (SecurityException se) {
- // Ignore and continue w/ next location
- }
-
- // JAXP specific change
- // always use fallback class to avoid the expense of constantly
- // "stat"ing a non-existent "xerces.properties" and jar SPI entry
- // see CR 6400863: Expensive creating of SAX parser in Mustang
- if (true) {
- if (fallbackClassName == null) {
- throw new ConfigurationError(
- "Provider for " + factoryId + " cannot be found", null);
- }
-
- if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName);
- return newInstance(fallbackClassName, cl, true);
- }
-
- // Try to read from propertiesFilename, or $java.home/lib/xerces.properties
- String factoryClassName = null;
- // no properties file name specified; use $JAVA_HOME/lib/xerces.properties:
- if (propertiesFilename == null) {
- File propertiesFile = null;
- boolean propertiesFileExists = false;
- try {
- String javah = ss.getSystemProperty("java.home");
- propertiesFilename = javah + File.separator +
- "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
- propertiesFile = new File(propertiesFilename);
- propertiesFileExists = ss.getFileExists(propertiesFile);
- } catch (SecurityException e) {
- // try again...
- fLastModified = -1;
- fXercesProperties = null;
- }
-
- synchronized (ObjectFactory.class) {
- boolean loadProperties = false;
- FileInputStream fis = null;
- try {
- // file existed last time
- if(fLastModified >= 0) {
- if(propertiesFileExists &&
- (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
- loadProperties = true;
- } else {
- // file has stopped existing...
- if(!propertiesFileExists) {
- fLastModified = -1;
- fXercesProperties = null;
- } // else, file wasn't modified!
- }
- } else {
- // file has started to exist:
- if(propertiesFileExists) {
- loadProperties = true;
- fLastModified = ss.getLastModified(propertiesFile);
- } // else, nothing's changed
- }
- if(loadProperties) {
- // must never have attempted to read xerces.properties before (or it's outdeated)
- fXercesProperties = new Properties();
- fis = ss.getFileInputStream(propertiesFile);
- fXercesProperties.load(fis);
- }
- } catch (Exception x) {
- fXercesProperties = null;
- fLastModified = -1;
- // assert(x instanceof FileNotFoundException
- // || x instanceof SecurityException)
- // In both cases, ignore and continue w/ next location
- }
- finally {
- // try to close the input stream if one was opened.
- if (fis != null) {
- try {
- fis.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
- }
- }
- if(fXercesProperties != null) {
- factoryClassName = fXercesProperties.getProperty(factoryId);
- }
- } else {
- FileInputStream fis = null;
- try {
- fis = ss.getFileInputStream(new File(propertiesFilename));
- Properties props = new Properties();
- props.load(fis);
- factoryClassName = props.getProperty(factoryId);
- } catch (Exception x) {
- // assert(x instanceof FileNotFoundException
- // || x instanceof SecurityException)
- // In both cases, ignore and continue w/ next location
- }
- finally {
- // try to close the input stream if one was opened.
- if (fis != null) {
- try {
- fis.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
- }
- }
- if (factoryClassName != null) {
- if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName);
- return newInstance(factoryClassName, cl, true);
- }
-
- // Try Jar Service Provider Mechanism
- Object provider = findJarServiceProvider(factoryId);
- if (provider != null) {
- return provider;
- }
-
- if (fallbackClassName == null) {
- throw new ConfigurationError(
- "Provider for " + factoryId + " cannot be found", null);
- }
-
- if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName);
- return newInstance(fallbackClassName, cl, true);
- } // createObject(String,String,String):Object
-
- //
- // Private static methods
- //
-
- /** Prints a message to standard error if debugging is enabled. */
- private static void debugPrintln(String msg) {
- if (DEBUG) {
- System.err.println("JAXP: " + msg);
- }
- } // debugPrintln(String)
-
- /**
- * Figure out which ClassLoader to use. For JDK 1.2 and later use
- * the context ClassLoader.
- */
- static ClassLoader findClassLoader()
- throws ConfigurationError
- {
- SecuritySupport ss = SecuritySupport.getInstance();
-
- // Figure out which ClassLoader to use for loading the provider
- // class. If there is a Context ClassLoader then use it.
- ClassLoader context = ss.getContextClassLoader();
- ClassLoader system = ss.getSystemClassLoader();
-
- ClassLoader chain = system;
- while (true) {
- if (context == chain) {
- // Assert: we are on JDK 1.1 or we have no Context ClassLoader
- // or any Context ClassLoader in chain of system classloader
- // (including extension ClassLoader) so extend to widest
- // ClassLoader (always look in system ClassLoader if Xerces
- // is in boot/extension/system classpath and in current
- // ClassLoader otherwise); normal classloaders delegate
- // back to system ClassLoader first so this widening doesn't
- // change the fact that context ClassLoader will be consulted
- ClassLoader current = ObjectFactory.class.getClassLoader();
-
- chain = system;
- while (true) {
- if (current == chain) {
- // Assert: Current ClassLoader in chain of
- // boot/extension/system ClassLoaders
- return system;
- }
- if (chain == null) {
- break;
- }
- chain = ss.getParentClassLoader(chain);
- }
-
- // Assert: Current ClassLoader not in chain of
- // boot/extension/system ClassLoaders
- return current;
- }
-
- if (chain == null) {
- // boot ClassLoader reached
- break;
- }
-
- // Check for any extension ClassLoaders in chain up to
- // boot ClassLoader
- chain = ss.getParentClassLoader(chain);
- };
-
- // Assert: Context ClassLoader not in chain of
- // boot/extension/system ClassLoaders
- return context;
- } // findClassLoader():ClassLoader
-
- /**
- * Create an instance of a class using the specified ClassLoader
- */
- static Object newInstance(String className, ClassLoader cl,
- boolean doFallback)
- throws ConfigurationError
- {
- // assert(className != null);
- try{
- Class providerClass = findProviderClass(className, cl, doFallback);
- Object instance = providerClass.newInstance();
- if (DEBUG) debugPrintln("created new instance of " + providerClass +
- " using ClassLoader: " + cl);
- return instance;
- } catch (ClassNotFoundException x) {
- throw new ConfigurationError(
- "Provider " + className + " not found", x);
- } catch (Exception x) {
- throw new ConfigurationError(
- "Provider " + className + " could not be instantiated: " + x,
- x);
- }
- }
-
- /**
- * Find a Class using the specified ClassLoader
- */
- static Class findProviderClass(String className, ClassLoader cl,
- boolean doFallback)
- throws ClassNotFoundException, ConfigurationError
- {
- //throw security exception if the calling thread is not allowed to access the package
- //restrict the access to package as speicified in java.security policy
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- final int lastDot = className.lastIndexOf(".");
- String packageName = className;
- if (lastDot != -1) packageName = className.substring(0, lastDot);
- security.checkPackageAccess(packageName);
- }
- Class providerClass;
- if (cl == null) {
- // XXX Use the bootstrap ClassLoader. There is no way to
- // load a class using the bootstrap ClassLoader that works
- // in both JDK 1.1 and Java 2. However, this should still
- // work b/c the following should be true:
- //
- // (cl == null) iff current ClassLoader == null
- //
- // Thus Class.forName(String) will use the current
- // ClassLoader which will be the bootstrap ClassLoader.
- providerClass = Class.forName(className);
- } else {
- try {
- providerClass = cl.loadClass(className);
- } catch (ClassNotFoundException x) {
- if (doFallback) {
- // Fall back to current classloader
- ClassLoader current = ObjectFactory.class.getClassLoader();
- if (current == null) {
- providerClass = Class.forName(className);
- } else if (cl != current) {
- cl = current;
- providerClass = cl.loadClass(className);
- } else {
- throw x;
- }
- } else {
- throw x;
- }
- }
- }
-
- return providerClass;
- }
-
- /*
- * Try to find provider using Jar Service Provider Mechanism
- *
- * @return instance of provider class if found or null
- */
- private static Object findJarServiceProvider(String factoryId)
- throws ConfigurationError
- {
- SecuritySupport ss = SecuritySupport.getInstance();
- String serviceId = "META-INF/services/" + factoryId;
- InputStream is = null;
-
- // First try the Context ClassLoader
- ClassLoader cl = findClassLoader();
-
- is = ss.getResourceAsStream(cl, serviceId);
-
- // If no provider found then try the current ClassLoader
- if (is == null) {
- ClassLoader current = ObjectFactory.class.getClassLoader();
- if (cl != current) {
- cl = current;
- is = ss.getResourceAsStream(cl, serviceId);
- }
- }
-
- if (is == null) {
- // No provider found
- return null;
- }
-
- if (DEBUG) debugPrintln("found jar resource=" + serviceId +
- " using ClassLoader: " + cl);
-
- // Read the service provider name in UTF-8 as specified in
- // the jar spec. Unfortunately this fails in Microsoft
- // VJ++, which does not implement the UTF-8
- // encoding. Theoretically, we should simply let it fail in
- // that case, since the JVM is obviously broken if it
- // doesn't support such a basic standard. But since there
- // are still some users attempting to use VJ++ for
- // development, we have dropped in a fallback which makes a
- // second attempt using the platform's default encoding. In
- // VJ++ this is apparently ASCII, which is a subset of
- // UTF-8... and since the strings we'll be reading here are
- // also primarily limited to the 7-bit ASCII range (at
- // least, in English versions), this should work well
- // enough to keep us on the air until we're ready to
- // officially decommit from VJ++. [Edited comment from
- // jkesselm]
- BufferedReader rd;
- try {
- rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH);
- } catch (java.io.UnsupportedEncodingException e) {
- rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH);
- }
-
- String factoryClassName = null;
- try {
- // XXX Does not handle all possible input as specified by the
- // Jar Service Provider specification
- factoryClassName = rd.readLine();
- } catch (IOException x) {
- // No provider found
- return null;
- }
- finally {
- try {
- // try to close the reader.
- rd.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
-
- if (factoryClassName != null &&
- ! "".equals(factoryClassName)) {
- if (DEBUG) debugPrintln("found in resource, value="
- + factoryClassName);
-
- // Note: here we do not want to fall back to the current
- // ClassLoader because we want to avoid the case where the
- // resource file was found using one ClassLoader and the
- // provider class was instantiated using a different one.
- return newInstance(factoryClassName, cl, false);
- }
-
- // No provider found
- return null;
- }
-
- //
- // Classes
- //
-
- /**
- * A configuration error.
- */
- static final class ConfigurationError
- extends Error {
-
- /** Serialization version. */
- static final long serialVersionUID = 937647395548533254L;
-
- //
- // Data
- //
-
- /** Exception. */
- private Exception exception;
-
- //
- // Constructors
- //
-
- /**
- * Construct a new instance with the specified detail string and
- * exception.
- */
- ConfigurationError(String msg, Exception x) {
- super(msg);
- this.exception = x;
- } // System.getProperty
- * $java.home/lib/propertiesFilename
file
- * META-INF/services/factoryId
file
- * DateFormatSymbols
is a public class for encapsulating
* localizable date-time formatting data, such as the names of the
* months, the names of the days of the week, and the time zone data.
- * DateFormat
and SimpleDateFormat
both use
+ * SimpleDateFormat
uses
* DateFormatSymbols
to encapsulate this information.
*
*