--- a/jdk/make/java/java/FILES_java.gmk Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/make/java/java/FILES_java.gmk Mon Feb 14 16:30:10 2011 -0800
@@ -443,7 +443,6 @@
java/io/FileReader.java \
java/io/PipedReader.java \
java/io/StringReader.java \
- java/io/TempFileHelper.java \
java/io/Writer.java \
java/io/BufferedWriter.java \
java/io/PrintWriter.java \
--- a/jdk/make/java/nio/FILES_java.gmk Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/make/java/nio/FILES_java.gmk Mon Feb 14 16:30:10 2011 -0800
@@ -81,12 +81,12 @@
java/nio/file/ClosedDirectoryStreamException.java \
java/nio/file/ClosedFileSystemException.java \
java/nio/file/ClosedWatchServiceException.java \
+ java/nio/file/CopyMoveHelper.java \
java/nio/file/CopyOption.java \
java/nio/file/DirectoryIteratorException.java \
java/nio/file/DirectoryNotEmptyException.java \
java/nio/file/DirectoryStream.java \
java/nio/file/FileAlreadyExistsException.java \
- java/nio/file/FileRef.java \
java/nio/file/FileStore.java \
java/nio/file/FileSystem.java \
java/nio/file/FileSystemAlreadyExistsException.java \
@@ -116,6 +116,7 @@
java/nio/file/StandardCopyOption.java \
java/nio/file/StandardOpenOption.java \
java/nio/file/StandardWatchEventKind.java \
+ java/nio/file/TempFileHelper.java \
java/nio/file/WatchEvent.java \
java/nio/file/WatchKey.java \
java/nio/file/WatchService.java \
@@ -127,7 +128,6 @@
java/nio/file/attribute/AclEntryType.java \
java/nio/file/attribute/AclFileAttributeView.java \
java/nio/file/attribute/AttributeView.java \
- java/nio/file/attribute/Attributes.java \
java/nio/file/attribute/BasicFileAttributeView.java \
java/nio/file/attribute/BasicFileAttributes.java \
java/nio/file/attribute/DosFileAttributeView.java \
@@ -136,8 +136,6 @@
java/nio/file/attribute/FileAttributeView.java \
java/nio/file/attribute/FileOwnerAttributeView.java \
java/nio/file/attribute/FileStoreAttributeView.java \
- java/nio/file/attribute/FileStoreSpaceAttributeView.java \
- java/nio/file/attribute/FileStoreSpaceAttributes.java \
java/nio/file/attribute/FileTime.java \
java/nio/file/attribute/GroupPrincipal.java \
java/nio/file/attribute/UserDefinedFileAttributeView.java \
@@ -246,6 +244,7 @@
sun/nio/fs/AbstractAclFileAttributeView.java \
sun/nio/fs/AbstractBasicFileAttributeView.java \
sun/nio/fs/AbstractFileTypeDetector.java \
+ sun/nio/fs/AbstractFileSystemProvider.java \
sun/nio/fs/AbstractPath.java \
sun/nio/fs/AbstractPoller.java \
sun/nio/fs/AbstractUserDefinedFileAttributeView.java \
--- a/jdk/make/netbeans/common/java-data-native.ent Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/make/netbeans/common/java-data-native.ent Mon Feb 14 16:30:10 2011 -0800
@@ -31,7 +31,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
+<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
<compilation-unit>
<package-root>${root}/src/share/classes</package-root>
<package-root>${root}/src/windows/classes</package-root>
@@ -39,6 +39,6 @@
<classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath>
<built-to>${root}/build/${platform}-${arch}/classes</built-to>
<javadoc-built-to>${root}/build/javadoc/${name}</javadoc-built-to>
- <source-level>1.5</source-level>
+ <source-level>1.7</source-level>
</compilation-unit>
</java-data>
--- a/jdk/make/netbeans/common/java-data-no-native.ent Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/make/netbeans/common/java-data-no-native.ent Mon Feb 14 16:30:10 2011 -0800
@@ -31,12 +31,12 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
+<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
<compilation-unit>
<package-root>${root}/src/share/classes</package-root>
<classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath>
<built-to>${root}/build/${platform}-${arch}/classes</built-to>
<javadoc-built-to>${root}/build/javadoc/${name}</javadoc-built-to>
- <source-level>1.5</source-level>
+ <source-level>1.7</source-level>
</compilation-unit>
</java-data>
--- a/jdk/src/share/bin/java.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/bin/java.c Mon Feb 14 16:30:10 2011 -0800
@@ -244,6 +244,7 @@
for (i = 0; i < argc ; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
+ AddOption("-Dsun.java.launcher.diag=true", NULL);
}
CreateExecutionEnvironment(&argc, &argv,
@@ -1009,6 +1010,8 @@
} else if (JLI_StrCmp(arg, "-XshowSettings") == 0 ||
JLI_StrCCmp(arg, "-XshowSettings:") == 0) {
showSettings = arg;
+ } else if (JLI_StrCmp(arg, "-Xdiag") == 0) {
+ AddOption("-Dsun.java.launcher.diag=true", NULL);
/*
* The following case provide backward compatibility with old-style
* command line options.
--- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Mon Feb 14 16:30:10 2011 -0800
@@ -656,14 +656,17 @@
}
nparent = notifyParent;
}
- }
- if (nparent) {
- LdapRequest ldr = pendingRequests;
- while (ldr != null) {
- ldr.notify();
- ldr = ldr.next;
+ if (nparent) {
+ LdapRequest ldr = pendingRequests;
+ while (ldr != null) {
+
+ synchronized (ldr) {
+ ldr.notify();
+ ldr = ldr.next;
+ }
+ }
+ parent.processConnectionClosure();
}
- parent.processConnectionClosure();
}
}
--- a/jdk/src/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java Mon Feb 14 16:30:10 2011 -0800
@@ -143,7 +143,7 @@
e.setRemainingName(remainingName);
e.setResolvedObj(resolvedObj);
- if (starter == null)
+ if (starter == null || starter.isEmpty())
e.setResolvedName(null);
else if (remainingName == null)
e.setResolvedName(starter);
--- a/jdk/src/share/classes/java/awt/Window.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/awt/Window.java Mon Feb 14 16:30:10 2011 -0800
@@ -504,6 +504,8 @@
}
modalExclusionType = Dialog.ModalExclusionType.NO_EXCLUDE;
+
+ SunToolkit.checkAndSetPolicy(this, false);
}
/**
--- a/jdk/src/share/classes/java/awt/doc-files/FocusSpec.html Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/awt/doc-files/FocusSpec.html Mon Feb 14 16:30:10 2011 -0800
@@ -894,8 +894,7 @@
focus across Windows. If the request is denied for this reason, the
request is remembered and will be granted when the Window is later
focused by the user. Otherwise, the focus change request changes the
-focused Window as well. Currently, Microsoft Windows supports cross-Window
-focus transfers while Solaris does not.
+focused Window as well.
<p>
There is no way to determine synchronously whether a focus change
request has been granted. Instead, client code must install a
--- a/jdk/src/share/classes/java/awt/geom/CubicCurve2D.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/awt/geom/CubicCurve2D.java Mon Feb 14 16:30:10 2011 -0800
@@ -31,6 +31,10 @@
import java.io.Serializable;
import sun.awt.geom.Curve;
+import static java.lang.Math.abs;
+import static java.lang.Math.max;
+import static java.lang.Math.ulp;
+
/**
* The <code>CubicCurve2D</code> class defines a cubic parametric curve
* segment in {@code (x,y)} coordinate space.
@@ -1083,95 +1087,286 @@
* @since 1.3
*/
public static int solveCubic(double eqn[], double res[]) {
- // From Numerical Recipes, 5.6, Quadratic and Cubic Equations
- double d = eqn[3];
- if (d == 0.0) {
- // The cubic has degenerated to quadratic (or line or ...).
+ // From Graphics Gems:
+ // http://tog.acm.org/resources/GraphicsGems/gems/Roots3And4.c
+ final double d = eqn[3];
+ if (d == 0) {
return QuadCurve2D.solveQuadratic(eqn, res);
}
- double a = eqn[2] / d;
- double b = eqn[1] / d;
- double c = eqn[0] / d;
- int roots = 0;
- double Q = (a * a - 3.0 * b) / 9.0;
- double R = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0;
- double R2 = R * R;
- double Q3 = Q * Q * Q;
- a = a / 3.0;
- if (R2 < Q3) {
- double theta = Math.acos(R / Math.sqrt(Q3));
- Q = -2.0 * Math.sqrt(Q);
+
+ /* normal form: x^3 + Ax^2 + Bx + C = 0 */
+ final double A = eqn[2] / d;
+ final double B = eqn[1] / d;
+ final double C = eqn[0] / d;
+
+
+ // substitute x = y - A/3 to eliminate quadratic term:
+ // x^3 +Px + Q = 0
+ //
+ // Since we actually need P/3 and Q/2 for all of the
+ // calculations that follow, we will calculate
+ // p = P/3
+ // q = Q/2
+ // instead and use those values for simplicity of the code.
+ double sq_A = A * A;
+ double p = 1.0/3 * (-1.0/3 * sq_A + B);
+ double q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C);
+
+ /* use Cardano's formula */
+
+ double cb_p = p * p * p;
+ double D = q * q + cb_p;
+
+ final double sub = 1.0/3 * A;
+
+ int num;
+ if (D < 0) { /* Casus irreducibilis: three real solutions */
+ // see: http://en.wikipedia.org/wiki/Cubic_function#Trigonometric_.28and_hyperbolic.29_method
+ double phi = 1.0/3 * Math.acos(-q / Math.sqrt(-cb_p));
+ double t = 2 * Math.sqrt(-p);
+
if (res == eqn) {
- // Copy the eqn so that we don't clobber it with the
- // roots. This is needed so that fixRoots can do its
- // work with the original equation.
- eqn = new double[4];
- System.arraycopy(res, 0, eqn, 0, 4);
+ eqn = Arrays.copyOf(eqn, 4);
}
- res[roots++] = Q * Math.cos(theta / 3.0) - a;
- res[roots++] = Q * Math.cos((theta + Math.PI * 2.0)/ 3.0) - a;
- res[roots++] = Q * Math.cos((theta - Math.PI * 2.0)/ 3.0) - a;
- fixRoots(res, eqn);
+
+ res[ 0 ] = ( t * Math.cos(phi));
+ res[ 1 ] = (-t * Math.cos(phi + Math.PI / 3));
+ res[ 2 ] = (-t * Math.cos(phi - Math.PI / 3));
+ num = 3;
+
+ for (int i = 0; i < num; ++i) {
+ res[ i ] -= sub;
+ }
+
} else {
- boolean neg = (R < 0.0);
- double S = Math.sqrt(R2 - Q3);
- if (neg) {
- R = -R;
+ // Please see the comment in fixRoots marked 'XXX' before changing
+ // any of the code in this case.
+ double sqrt_D = Math.sqrt(D);
+ double u = Math.cbrt(sqrt_D - q);
+ double v = - Math.cbrt(sqrt_D + q);
+ double uv = u+v;
+
+ num = 1;
+
+ double err = 1200000000*ulp(abs(uv) + abs(sub));
+ if (iszero(D, err) || within(u, v, err)) {
+ if (res == eqn) {
+ eqn = Arrays.copyOf(eqn, 4);
+ }
+ res[1] = -(uv / 2) - sub;
+ num = 2;
}
- double A = Math.pow(R + S, 1.0 / 3.0);
- if (!neg) {
- A = -A;
- }
- double B = (A == 0.0) ? 0.0 : (Q / A);
- res[roots++] = (A + B) - a;
+ // this must be done after the potential Arrays.copyOf
+ res[ 0 ] = uv - sub;
+ }
+
+ if (num > 1) { // num == 3 || num == 2
+ num = fixRoots(eqn, res, num);
}
- return roots;
+ if (num > 2 && (res[2] == res[1] || res[2] == res[0])) {
+ num--;
+ }
+ if (num > 1 && res[1] == res[0]) {
+ res[1] = res[--num]; // Copies res[2] to res[1] if needed
+ }
+ return num;
}
- /*
- * This pruning step is necessary since solveCubic uses the
- * cosine function to calculate the roots when there are 3
- * of them. Since the cosine method can have an error of
- * +/- 1E-14 we need to make sure that we don't make any
- * bad decisions due to an error.
- *
- * If the root is not near one of the endpoints, then we will
- * only have a slight inaccuracy in calculating the x intercept
- * which will only cause a slightly wrong answer for some
- * points very close to the curve. While the results in that
- * case are not as accurate as they could be, they are not
- * disastrously inaccurate either.
- *
- * On the other hand, if the error happens near one end of
- * the curve, then our processing to reject values outside
- * of the t=[0,1] range will fail and the results of that
- * failure will be disastrous since for an entire horizontal
- * range of test points, we will either overcount or undercount
- * the crossings and get a wrong answer for all of them, even
- * when they are clearly and obviously inside or outside the
- * curve.
- *
- * To work around this problem, we try a couple of Newton-Raphson
- * iterations to see if the true root is closer to the endpoint
- * or further away. If it is further away, then we can stop
- * since we know we are on the right side of the endpoint. If
- * we change direction, then either we are now being dragged away
- * from the endpoint in which case the first condition will cause
- * us to stop, or we have passed the endpoint and are headed back.
- * In the second case, we simply evaluate the slope at the
- * endpoint itself and place ourselves on the appropriate side
- * of it or on it depending on that result.
- */
- private static void fixRoots(double res[], double eqn[]) {
- final double EPSILON = 1E-5;
+ // preconditions: eqn != res && eqn[3] != 0 && num > 1
+ // This method tries to improve the accuracy of the roots of eqn (which
+ // should be in res). It also might eliminate roots in res if it decideds
+ // that they're not real roots. It will not check for roots that the
+ // computation of res might have missed, so this method should only be
+ // used when the roots in res have been computed using an algorithm
+ // that never underestimates the number of roots (such as solveCubic above)
+ private static int fixRoots(double[] eqn, double[] res, int num) {
+ double[] intervals = {eqn[1], 2*eqn[2], 3*eqn[3]};
+ int critCount = QuadCurve2D.solveQuadratic(intervals, intervals);
+ if (critCount == 2 && intervals[0] == intervals[1]) {
+ critCount--;
+ }
+ if (critCount == 2 && intervals[0] > intervals[1]) {
+ double tmp = intervals[0];
+ intervals[0] = intervals[1];
+ intervals[1] = tmp;
+ }
+
+ // below we use critCount to possibly filter out roots that shouldn't
+ // have been computed. We require that eqn[3] != 0, so eqn is a proper
+ // cubic, which means that its limits at -/+inf are -/+inf or +/-inf.
+ // Therefore, if critCount==2, the curve is shaped like a sideways S,
+ // and it could have 1-3 roots. If critCount==0 it is monotonic, and
+ // if critCount==1 it is monotonic with a single point where it is
+ // flat. In the last 2 cases there can only be 1 root. So in cases
+ // where num > 1 but critCount < 2, we eliminate all roots in res
+ // except one.
+
+ if (num == 3) {
+ double xe = getRootUpperBound(eqn);
+ double x0 = -xe;
+
+ Arrays.sort(res, 0, num);
+ if (critCount == 2) {
+ // this just tries to improve the accuracy of the computed
+ // roots using Newton's method.
+ res[0] = refineRootWithHint(eqn, x0, intervals[0], res[0]);
+ res[1] = refineRootWithHint(eqn, intervals[0], intervals[1], res[1]);
+ res[2] = refineRootWithHint(eqn, intervals[1], xe, res[2]);
+ return 3;
+ } else if (critCount == 1) {
+ // we only need fx0 and fxe for the sign of the polynomial
+ // at -inf and +inf respectively, so we don't need to do
+ // fx0 = solveEqn(eqn, 3, x0); fxe = solveEqn(eqn, 3, xe)
+ double fxe = eqn[3];
+ double fx0 = -fxe;
+
+ double x1 = intervals[0];
+ double fx1 = solveEqn(eqn, 3, x1);
+
+ // if critCount == 1 or critCount == 0, but num == 3 then
+ // something has gone wrong. This branch and the one below
+ // would ideally never execute, but if they do we can't know
+ // which of the computed roots is closest to the real root;
+ // therefore, we can't use refineRootWithHint. But even if
+ // we did know, being here most likely means that the
+ // curve is very flat close to two of the computed roots
+ // (or maybe even all three). This might make Newton's method
+ // fail altogether, which would be a pain to detect and fix.
+ // This is why we use a very stable bisection method.
+ if (oppositeSigns(fx0, fx1)) {
+ res[0] = bisectRootWithHint(eqn, x0, x1, res[0]);
+ } else if (oppositeSigns(fx1, fxe)) {
+ res[0] = bisectRootWithHint(eqn, x1, xe, res[2]);
+ } else /* fx1 must be 0 */ {
+ res[0] = x1;
+ }
+ // return 1
+ } else if (critCount == 0) {
+ res[0] = bisectRootWithHint(eqn, x0, xe, res[1]);
+ // return 1
+ }
+ } else if (num == 2 && critCount == 2) {
+ // XXX: here we assume that res[0] has better accuracy than res[1].
+ // This is true because this method is only used from solveCubic
+ // which puts in res[0] the root that it would compute anyway even
+ // if num==1. If this method is ever used from any other method, or
+ // if the solveCubic implementation changes, this assumption should
+ // be reevaluated, and the choice of goodRoot might have to become
+ // goodRoot = (abs(eqn'(res[0])) > abs(eqn'(res[1]))) ? res[0] : res[1]
+ // where eqn' is the derivative of eqn.
+ double goodRoot = res[0];
+ double badRoot = res[1];
+ double x1 = intervals[0];
+ double x2 = intervals[1];
+ // If a cubic curve really has 2 roots, one of those roots must be
+ // at a critical point. That can't be goodRoot, so we compute x to
+ // be the farthest critical point from goodRoot. If there are two
+ // roots, x must be the second one, so we evaluate eqn at x, and if
+ // it is zero (or close enough) we put x in res[1] (or badRoot, if
+ // |solveEqn(eqn, 3, badRoot)| < |solveEqn(eqn, 3, x)| but this
+ // shouldn't happen often).
+ double x = abs(x1 - goodRoot) > abs(x2 - goodRoot) ? x1 : x2;
+ double fx = solveEqn(eqn, 3, x);
+
+ if (iszero(fx, 10000000*ulp(x))) {
+ double badRootVal = solveEqn(eqn, 3, badRoot);
+ res[1] = abs(badRootVal) < abs(fx) ? badRoot : x;
+ return 2;
+ }
+ } // else there can only be one root - goodRoot, and it is already in res[0]
+
+ return 1;
+ }
+
+ // use newton's method.
+ private static double refineRootWithHint(double[] eqn, double min, double max, double t) {
+ if (!inInterval(t, min, max)) {
+ return t;
+ }
+ double[] deriv = {eqn[1], 2*eqn[2], 3*eqn[3]};
+ double origt = t;
for (int i = 0; i < 3; i++) {
- double t = res[i];
- if (Math.abs(t) < EPSILON) {
- res[i] = findZero(t, 0, eqn);
- } else if (Math.abs(t - 1) < EPSILON) {
- res[i] = findZero(t, 1, eqn);
+ double slope = solveEqn(deriv, 2, t);
+ double y = solveEqn(eqn, 3, t);
+ double delta = - (y / slope);
+ double newt = t + delta;
+
+ if (slope == 0 || y == 0 || t == newt) {
+ break;
+ }
+
+ t = newt;
+ }
+ if (within(t, origt, 1000*ulp(origt)) && inInterval(t, min, max)) {
+ return t;
+ }
+ return origt;
+ }
+
+ private static double bisectRootWithHint(double[] eqn, double x0, double xe, double hint) {
+ double delta1 = Math.min(abs(hint - x0) / 64, 0.0625);
+ double delta2 = Math.min(abs(hint - xe) / 64, 0.0625);
+ double x02 = hint - delta1;
+ double xe2 = hint + delta2;
+ double fx02 = solveEqn(eqn, 3, x02);
+ double fxe2 = solveEqn(eqn, 3, xe2);
+ while (oppositeSigns(fx02, fxe2)) {
+ if (x02 >= xe2) {
+ return x02;
}
+ x0 = x02;
+ xe = xe2;
+ delta1 /= 64;
+ delta2 /= 64;
+ x02 = hint - delta1;
+ xe2 = hint + delta2;
+ fx02 = solveEqn(eqn, 3, x02);
+ fxe2 = solveEqn(eqn, 3, xe2);
}
+ if (fx02 == 0) {
+ return x02;
+ }
+ if (fxe2 == 0) {
+ return xe2;
+ }
+
+ return bisectRoot(eqn, x0, xe);
+ }
+
+ private static double bisectRoot(double[] eqn, double x0, double xe) {
+ double fx0 = solveEqn(eqn, 3, x0);
+ double m = x0 + (xe - x0) / 2;
+ while (m != x0 && m != xe) {
+ double fm = solveEqn(eqn, 3, m);
+ if (fm == 0) {
+ return m;
+ }
+ if (oppositeSigns(fx0, fm)) {
+ xe = m;
+ } else {
+ fx0 = fm;
+ x0 = m;
+ }
+ m = x0 + (xe-x0)/2;
+ }
+ return m;
+ }
+
+ private static boolean inInterval(double t, double min, double max) {
+ return min <= t && t <= max;
+ }
+
+ private static boolean within(double x, double y, double err) {
+ double d = y - x;
+ return (d <= err && d >= -err);
+ }
+
+ private static boolean iszero(double x, double err) {
+ return within(x, 0, err);
+ }
+
+ private static boolean oppositeSigns(double x1, double x2) {
+ return (x1 < 0 && x2 > 0) || (x1 > 0 && x2 < 0);
}
private static double solveEqn(double eqn[], int order, double t) {
@@ -1182,60 +1377,26 @@
return v;
}
- private static double findZero(double t, double target, double eqn[]) {
- double slopeqn[] = {eqn[1], 2*eqn[2], 3*eqn[3]};
- double slope;
- double origdelta = 0;
- double origt = t;
- while (true) {
- slope = solveEqn(slopeqn, 2, t);
- if (slope == 0) {
- // At a local minima - must return
- return t;
- }
- double y = solveEqn(eqn, 3, t);
- if (y == 0) {
- // Found it! - return it
- return t;
- }
- // assert(slope != 0 && y != 0);
- double delta = - (y / slope);
- // assert(delta != 0);
- if (origdelta == 0) {
- origdelta = delta;
- }
- if (t < target) {
- if (delta < 0) return t;
- } else if (t > target) {
- if (delta > 0) return t;
- } else { /* t == target */
- return (delta > 0
- ? (target + java.lang.Double.MIN_VALUE)
- : (target - java.lang.Double.MIN_VALUE));
- }
- double newt = t + delta;
- if (t == newt) {
- // The deltas are so small that we aren't moving...
- return t;
- }
- if (delta * origdelta < 0) {
- // We have reversed our path.
- int tag = (origt < t
- ? getTag(target, origt, t)
- : getTag(target, t, origt));
- if (tag != INSIDE) {
- // Local minima found away from target - return the middle
- return (origt + t) / 2;
- }
- // Local minima somewhere near target - move to target
- // and let the slope determine the resulting t.
- t = target;
- } else {
- t = newt;
- }
- }
+ /*
+ * Computes M+1 where M is an upper bound for all the roots in of eqn.
+ * See: http://en.wikipedia.org/wiki/Sturm%27s_theorem#Applications.
+ * The above link doesn't contain a proof, but I [dlila] proved it myself
+ * so the result is reliable. The proof isn't difficult, but it's a bit
+ * long to include here.
+ * Precondition: eqn must represent a cubic polynomial
+ */
+ private static double getRootUpperBound(double[] eqn) {
+ double d = eqn[3];
+ double a = eqn[2];
+ double b = eqn[1];
+ double c = eqn[0];
+
+ double M = 1 + max(max(abs(a), abs(b)), abs(c)) / abs(d);
+ M += ulp(M) + 1;
+ return M;
}
+
/**
* {@inheritDoc}
* @since 1.2
@@ -1273,110 +1434,6 @@
return contains(p.getX(), p.getY());
}
- /*
- * Fill an array with the coefficients of the parametric equation
- * in t, ready for solving against val with solveCubic.
- * We currently have:
- * <pre>
- * val = P(t) = C1(1-t)^3 + 3CP1 t(1-t)^2 + 3CP2 t^2(1-t) + C2 t^3
- * = C1 - 3C1t + 3C1t^2 - C1t^3 +
- * 3CP1t - 6CP1t^2 + 3CP1t^3 +
- * 3CP2t^2 - 3CP2t^3 +
- * C2t^3
- * 0 = (C1 - val) +
- * (3CP1 - 3C1) t +
- * (3C1 - 6CP1 + 3CP2) t^2 +
- * (C2 - 3CP2 + 3CP1 - C1) t^3
- * 0 = C + Bt + At^2 + Dt^3
- * C = C1 - val
- * B = 3*CP1 - 3*C1
- * A = 3*CP2 - 6*CP1 + 3*C1
- * D = C2 - 3*CP2 + 3*CP1 - C1
- * </pre>
- */
- private static void fillEqn(double eqn[], double val,
- double c1, double cp1, double cp2, double c2) {
- eqn[0] = c1 - val;
- eqn[1] = (cp1 - c1) * 3.0;
- eqn[2] = (cp2 - cp1 - cp1 + c1) * 3.0;
- eqn[3] = c2 + (cp1 - cp2) * 3.0 - c1;
- return;
- }
-
- /*
- * Evaluate the t values in the first num slots of the vals[] array
- * and place the evaluated values back into the same array. Only
- * evaluate t values that are within the range <0, 1>, including
- * the 0 and 1 ends of the range iff the include0 or include1
- * booleans are true. If an "inflection" equation is handed in,
- * then any points which represent a point of inflection for that
- * cubic equation are also ignored.
- */
- private static int evalCubic(double vals[], int num,
- boolean include0,
- boolean include1,
- double inflect[],
- double c1, double cp1,
- double cp2, double c2) {
- int j = 0;
- for (int i = 0; i < num; i++) {
- double t = vals[i];
- if ((include0 ? t >= 0 : t > 0) &&
- (include1 ? t <= 1 : t < 1) &&
- (inflect == null ||
- inflect[1] + (2*inflect[2] + 3*inflect[3]*t)*t != 0))
- {
- double u = 1 - t;
- vals[j++] = c1*u*u*u + 3*cp1*t*u*u + 3*cp2*t*t*u + c2*t*t*t;
- }
- }
- return j;
- }
-
- private static final int BELOW = -2;
- private static final int LOWEDGE = -1;
- private static final int INSIDE = 0;
- private static final int HIGHEDGE = 1;
- private static final int ABOVE = 2;
-
- /*
- * Determine where coord lies with respect to the range from
- * low to high. It is assumed that low <= high. The return
- * value is one of the 5 values BELOW, LOWEDGE, INSIDE, HIGHEDGE,
- * or ABOVE.
- */
- private static int getTag(double coord, double low, double high) {
- if (coord <= low) {
- return (coord < low ? BELOW : LOWEDGE);
- }
- if (coord >= high) {
- return (coord > high ? ABOVE : HIGHEDGE);
- }
- return INSIDE;
- }
-
- /*
- * Determine if the pttag represents a coordinate that is already
- * in its test range, or is on the border with either of the two
- * opttags representing another coordinate that is "towards the
- * inside" of that test range. In other words, are either of the
- * two "opt" points "drawing the pt inward"?
- */
- private static boolean inwards(int pttag, int opt1tag, int opt2tag) {
- switch (pttag) {
- case BELOW:
- case ABOVE:
- default:
- return false;
- case LOWEDGE:
- return (opt1tag >= INSIDE || opt2tag >= INSIDE);
- case INSIDE:
- return true;
- case HIGHEDGE:
- return (opt1tag <= INSIDE || opt2tag <= INSIDE);
- }
- }
-
/**
* {@inheritDoc}
* @since 1.2
--- a/jdk/src/share/classes/java/io/BufferedReader.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/io/BufferedReader.java Mon Feb 14 16:30:10 2011 -0800
@@ -54,6 +54,7 @@
*
* @see FileReader
* @see InputStreamReader
+ * @see java.nio.file.Files#newBufferedReader
*
* @author Mark Reinhold
* @since JDK1.1
@@ -374,6 +375,8 @@
* stream has been reached
*
* @exception IOException If an I/O error occurs
+ *
+ * @see java.nio.file.Files#readAllLines
*/
public String readLine() throws IOException {
return readLine(false);
--- a/jdk/src/share/classes/java/io/BufferedWriter.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/io/BufferedWriter.java Mon Feb 14 16:30:10 2011 -0800
@@ -57,6 +57,7 @@
* @see PrintWriter
* @see FileWriter
* @see OutputStreamWriter
+ * @see java.nio.file.Files#newBufferedWriter
*
* @author Mark Reinhold
* @since JDK1.1
--- a/jdk/src/share/classes/java/io/File.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/io/File.java Mon Feb 14 16:30:10 2011 -0800
@@ -35,8 +35,7 @@
import java.security.AccessController;
import java.security.SecureRandom;
import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.FileAttribute;
+import java.nio.file.FileSystems;
import sun.security.action.GetPropertyAction;
/**
@@ -139,9 +138,10 @@
* many of the limitations of the {@code java.io.File} class.
* The {@link #toPath toPath} method may be used to obtain a {@link
* Path} that uses the abstract path represented by a {@code File} object to
- * locate a file. The resulting {@code Path} provides more efficient and
- * extensive access to file attributes, additional file operations, and I/O
- * exceptions to help diagnose errors when an operation on a file fails.
+ * locate a file. The resulting {@code Path} may be used with the {@link
+ * java.nio.file.Files} class to provide more efficient and extensive access to
+ * additional file operations, file attributes, and I/O exceptions to help
+ * diagnose errors when an operation on a file fails.
*
* @author unascribed
* @since JDK1.0
@@ -778,6 +778,12 @@
* Tests whether the file denoted by this abstract pathname is a
* directory.
*
+ * <p> Where it is required to distinguish an I/O exception from the case
+ * that the file is not a directory, or where several attributes of the
+ * same file are required at the same time, then the {@link
+ * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+ * Files.readAttributes} method may be used.
+ *
* @return <code>true</code> if and only if the file denoted by this
* abstract pathname exists <em>and</em> is a directory;
* <code>false</code> otherwise
@@ -786,8 +792,6 @@
* If a security manager exists and its <code>{@link
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public boolean isDirectory() {
SecurityManager security = System.getSecurityManager();
@@ -804,6 +808,12 @@
* addition, satisfies other system-dependent criteria. Any non-directory
* file created by a Java application is guaranteed to be a normal file.
*
+ * <p> Where it is required to distinguish an I/O exception from the case
+ * that the file is not a normal file, or where several attributes of the
+ * same file are required at the same time, then the {@link
+ * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+ * Files.readAttributes} method may be used.
+ *
* @return <code>true</code> if and only if the file denoted by this
* abstract pathname exists <em>and</em> is a normal file;
* <code>false</code> otherwise
@@ -812,8 +822,6 @@
* If a security manager exists and its <code>{@link
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public boolean isFile() {
SecurityManager security = System.getSecurityManager();
@@ -853,6 +861,13 @@
* Returns the time that the file denoted by this abstract pathname was
* last modified.
*
+ * <p> Where it is required to distinguish an I/O exception from the case
+ * where {@code 0L} is returned, or where several attributes of the
+ * same file are required at the same time, or where the time of last
+ * access or the creation time are required, then the {@link
+ * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+ * Files.readAttributes} method may be used.
+ *
* @return A <code>long</code> value representing the time the file was
* last modified, measured in milliseconds since the epoch
* (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
@@ -862,8 +877,6 @@
* If a security manager exists and its <code>{@link
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public long lastModified() {
SecurityManager security = System.getSecurityManager();
@@ -877,6 +890,12 @@
* Returns the length of the file denoted by this abstract pathname.
* The return value is unspecified if this pathname denotes a directory.
*
+ * <p> Where it is required to distinguish an I/O exception from the case
+ * that {@code 0L} is returned, or where several attributes of the same file
+ * are required at the same time, then the {@link
+ * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+ * Files.readAttributes} method may be used.
+ *
* @return The length, in bytes, of the file denoted by this abstract
* pathname, or <code>0L</code> if the file does not exist. Some
* operating systems may return <code>0L</code> for pathnames
@@ -886,8 +905,6 @@
* If a security manager exists and its <code>{@link
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public long length() {
SecurityManager security = System.getSecurityManager();
@@ -937,11 +954,10 @@
* this pathname denotes a directory, then the directory must be empty in
* order to be deleted.
*
- * <p> Note that the {@link Path} class defines the {@link Path#delete
- * delete} method to throw an {@link IOException} when a file cannot be
- * deleted. This is useful for error reporting and to diagnose why a file
- * cannot be deleted. The {@link #toPath toPath} method may be used to
- * obtain a {@code Path} representing this abstract pathname.
+ * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+ * java.nio.file.Files#delete(Path) delete} method to throw an {@link IOException}
+ * when a file cannot be deleted. This is useful for error reporting and to
+ * diagnose why a file cannot be deleted.
*
* @return <code>true</code> if and only if the file or directory is
* successfully deleted; <code>false</code> otherwise
@@ -1009,12 +1025,11 @@
* will appear in any specific order; they are not, in particular,
* guaranteed to appear in alphabetical order.
*
- * <p> Note that the {@link Path} class defines the {@link
- * Path#newDirectoryStream newDirectoryStream} method to open a directory
- * and iterate over the names of the files in the directory. This may use
- * less resources when working with very large directories. The {@link
- * #toPath toPath} method may be used to obtain a {@code Path} representing
- * this abstract pathname.
+ * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+ * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method to
+ * open a directory and iterate over the names of the files in the directory.
+ * This may use less resources when working with very large directories, and
+ * may be more responsive when working with remote directories.
*
* @return An array of strings naming the files and directories in the
* directory denoted by this abstract pathname. The array will be
@@ -1061,6 +1076,8 @@
* If a security manager exists and its {@link
* SecurityManager#checkRead(String)} method denies read access to
* the directory
+ *
+ * @see java.nio.file.Files#newDirectoryStream(Path,String)
*/
public String[] list(FilenameFilter filter) {
String names[] = list();
@@ -1095,12 +1112,11 @@
* will appear in any specific order; they are not, in particular,
* guaranteed to appear in alphabetical order.
*
- * <p> Note that the {@link Path} class defines the {@link
- * Path#newDirectoryStream newDirectoryStream} method to open a directory
- * and iterate over the names of the files in the directory. This may use
- * less resources when working with very large directories. The {@link
- * #toPath toPath} method may be used to obtain a {@code Path} representing
- * this abstract pathname.
+ * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+ * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method
+ * to open a directory and iterate over the names of the files in the
+ * directory. This may use less resources when working with very large
+ * directories.
*
* @return An array of abstract pathnames denoting the files and
* directories in the directory denoted by this abstract pathname.
@@ -1154,6 +1170,7 @@
* the directory
*
* @since 1.2
+ * @see java.nio.file.Files#newDirectoryStream(Path,String)
*/
public File[] listFiles(FilenameFilter filter) {
String ss[] = list();
@@ -1191,6 +1208,7 @@
* the directory
*
* @since 1.2
+ * @see java.nio.file.Files#newDirectoryStream(Path,java.nio.file.DirectoryStream.Filter)
*/
public File[] listFiles(FileFilter filter) {
String ss[] = list();
@@ -1207,12 +1225,6 @@
/**
* Creates the directory named by this abstract pathname.
*
- * <p> Note that the {@link Path} class defines the {@link Path#createDirectory
- * createDirectory} method to throw an {@link IOException} when a directory
- * cannot be created. This is useful for error reporting and to diagnose why
- * a directory cannot be created. The {@link #toPath toPath} method may be
- * used to obtain a {@code Path} representing this abstract pathname.
- *
* @return <code>true</code> if and only if the directory was
* created; <code>false</code> otherwise
*
@@ -1278,10 +1290,9 @@
* already exists. The return value should always be checked to make sure
* that the rename operation was successful.
*
- * <p> Note that the {@link Path} class defines the {@link Path#moveTo
- * moveTo} method to move or rename a file in a platform independent manner.
- * The {@link #toPath toPath} method may be used to obtain a {@code Path}
- * representing this abstract pathname.
+ * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+ * java.nio.file.Files#move move} method to move or rename a file in a
+ * platform independent manner.
*
* @param dest The new abstract pathname for the named file
*
@@ -1369,10 +1380,9 @@
* Sets the owner's or everybody's write permission for this abstract
* pathname.
*
- * <p> The {@link java.nio.file.attribute.Attributes Attributes} class
- * defines methods that operate on file attributes including file
- * permissions. This may be used when finer manipulation of file permissions
- * is required.
+ * <p> The {@link java.nio.file.Files} class defines methods that operate on
+ * file attributes including file permissions. This may be used when finer
+ * manipulation of file permissions is required.
*
* @param writable
* If <code>true</code>, sets the access permission to allow write
@@ -1437,10 +1447,9 @@
* Sets the owner's or everybody's read permission for this abstract
* pathname.
*
- * <p> The {@link java.nio.file.attribute.Attributes Attributes} class
- * defines methods that operate on file attributes including file
- * permissions. This may be used when finer manipulation of file permissions
- * is required.
+ * <p> The {@link java.nio.file.Files} class defines methods that operate on
+ * file attributes including file permissions. This may be used when finer
+ * manipulation of file permissions is required.
*
* @param readable
* If <code>true</code>, sets the access permission to allow read
@@ -1511,10 +1520,9 @@
* Sets the owner's or everybody's execute permission for this abstract
* pathname.
*
- * <p> The {@link java.nio.file.attribute.Attributes Attributes} class
- * defines methods that operate on file attributes including file
- * permissions. This may be used when finer manipulation of file permissions
- * is required.
+ * <p> The {@link java.nio.file.Files} class defines methods that operate on
+ * file attributes including file permissions. This may be used when finer
+ * manipulation of file permissions is required.
*
* @param executable
* If <code>true</code>, sets the access permission to allow execute
@@ -1646,6 +1654,7 @@
* filesystem roots.
*
* @since 1.2
+ * @see java.nio.file.FileStore
*/
public static File[] listRoots() {
return fs.listRoots();
@@ -1753,7 +1762,7 @@
/* -- Temporary files -- */
- static class TempDirectory {
+ private static class TempDirectory {
private TempDirectory() { }
// temporary directory location
@@ -1880,11 +1889,12 @@
* java.lang.String, java.io.File)
* createTempFile(prefix, suffix, null)}</code>.
*
- * <p> The {@link #createTemporaryFile(String,String,FileAttribute[])} method
- * provides an alternative method to create an empty file in the
- * temporary-file directory. Files created by that method may have more
- * restrictive access permissions to files created by this method and so
- * may be more suited to security-sensitive applications.
+ * <p> The {@link
+ * java.nio.file.Files#createTempFile(String,String,java.nio.file.attribute.FileAttribute[])
+ * Files.createTempFile} method provides an alternative method to create an
+ * empty file in the temporary-file directory. Files created by that method
+ * may have more restrictive access permissions to files created by this
+ * method and so may be more suited to security-sensitive applications.
*
* @param prefix The prefix string to be used in generating the file's
* name; must be at least three characters long
@@ -1907,6 +1917,7 @@
* method does not allow a file to be created
*
* @since 1.2
+ * @see java.nio.file.Files#createTempDirectory(String,FileAttribute[])
*/
public static File createTempFile(String prefix, String suffix)
throws IOException
@@ -1914,61 +1925,6 @@
return createTempFile(prefix, suffix, null);
}
- /**
- * Creates an empty file in the default temporary-file directory, using
- * the given prefix and suffix to generate its name.
- *
- * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
- * attributes} to set atomically when creating the file. Each attribute is
- * identified by its {@link FileAttribute#name name}. If more than one attribute
- * of the same name is included in the array then all but the last occurrence
- * is ignored.
- *
- * <p> Where the {@code attrs} parameter does not specify <i>access
- * permissions</i> to set atomically when creating the file, then the
- * resulting file may have more restrictive access permissions than files
- * created by the {@link #createTempFile(java.lang.String, java.lang.String)}
- * method.
- *
- * @param prefix
- * The prefix string to be used in generating the file's
- * name; must be at least three characters long
- * @param suffix
- * The suffix string to be used in generating the file's
- * name; may be {@code null}, in which case the suffix
- * {@code ".tmp"} will be used
- * @param attrs
- * An optional list of file attributes to set atomically when creating
- * the file
- *
- * @return An abstract pathname denoting a newly-created empty file
- *
- * @throws IllegalArgumentException
- * If the {@code prefix} argument contains fewer than three
- * characters
- * @throws UnsupportedOperationException
- * If the array contains an attribute that cannot be set atomically
- * when creating the file
- * @throws IOException
- * If a file could not be created
- * @throws SecurityException
- * If a security manager exists and its <code>{@link
- * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
- * method does not allow a file to be created.
- *
- * @since 1.7
- */
- public static File createTemporaryFile(String prefix,
- String suffix,
- FileAttribute<?>... attrs)
- throws IOException
- {
- if (prefix.length() < 3)
- throw new IllegalArgumentException("Prefix string too short");
- suffix = (suffix == null) ? ".tmp" : suffix;
- return TempFileHelper.createFile(prefix, suffix, attrs);
- }
-
/* -- Basic infrastructure -- */
/**
@@ -2104,6 +2060,7 @@
* path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath})
*
* @since 1.7
+ * @see Path#toFile
*/
public Path toPath() {
Path result = filePath;
@@ -2111,12 +2068,7 @@
synchronized (this) {
result = filePath;
if (result == null) {
- if (path.length() == 0) {
- // assume default file system treats "." as current directory
- result = Paths.get(".");
- } else {
- result = Paths.get(path);
- }
+ result = FileSystems.getDefault().getPath(path);
filePath = result;
}
}
--- a/jdk/src/share/classes/java/io/FileInputStream.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/io/FileInputStream.java Mon Feb 14 16:30:10 2011 -0800
@@ -42,6 +42,7 @@
* @see java.io.File
* @see java.io.FileDescriptor
* @see java.io.FileOutputStream
+ * @see java.nio.file.Files#newInputStream
* @since JDK1.0
*/
public
--- a/jdk/src/share/classes/java/io/FileOutputStream.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/io/FileOutputStream.java Mon Feb 14 16:30:10 2011 -0800
@@ -46,6 +46,7 @@
* @see java.io.File
* @see java.io.FileDescriptor
* @see java.io.FileInputStream
+ * @see java.nio.file.Files#newOutputStream
* @since JDK1.0
*/
public
--- a/jdk/src/share/classes/java/io/FilePermission.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/io/FilePermission.java Mon Feb 14 16:30:10 2011 -0800
@@ -72,7 +72,7 @@
* <DT> readlink
* <DD> read link permission. Allows the target of a
* <a href="../nio/file/package-summary.html#links">symbolic link</a>
- * to be read by invoking the {@link java.nio.file.Path#readSymbolicLink
+ * to be read by invoking the {@link java.nio.file.Files#readSymbolicLink
* readSymbolicLink } method.
* </DL>
* <P>
--- a/jdk/src/share/classes/java/io/PrintStream.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/io/PrintStream.java Mon Feb 14 16:30:10 2011 -0800
@@ -70,11 +70,11 @@
private OutputStreamWriter charOut;
/**
- * nonNull is explicitly declared here so as not to create an extra
- * dependency on java.util.Objects.nonNull. PrintStream is loaded
+ * requireNonNull is explicitly declared here so as not to create an extra
+ * dependency on java.util.Objects.requireNonNull. PrintStream is loaded
* early during system initialization.
*/
- private static <T> T nonNull(T obj, String message) {
+ private static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
@@ -88,7 +88,7 @@
private static Charset toCharset(String csn)
throws UnsupportedEncodingException
{
- nonNull(csn, "charsetName");
+ requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
@@ -148,7 +148,7 @@
* @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
*/
public PrintStream(OutputStream out, boolean autoFlush) {
- this(autoFlush, nonNull(out, "Null output stream"));
+ this(autoFlush, requireNonNull(out, "Null output stream"));
}
/**
@@ -173,7 +173,7 @@
throws UnsupportedEncodingException
{
this(autoFlush,
- nonNull(out, "Null output stream"),
+ requireNonNull(out, "Null output stream"),
toCharset(encoding));
}
--- a/jdk/src/share/classes/java/io/PrintWriter.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/io/PrintWriter.java Mon Feb 14 16:30:10 2011 -0800
@@ -82,7 +82,7 @@
private static Charset toCharset(String csn)
throws UnsupportedEncodingException
{
- Objects.nonNull(csn, "charsetName");
+ Objects.requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
--- a/jdk/src/share/classes/java/io/SerialCallbackContext.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/io/SerialCallbackContext.java Mon Feb 14 16:30:10 2011 -0800
@@ -54,5 +54,3 @@
thread = null;
}
}
-
-
--- a/jdk/src/share/classes/java/io/TempFileHelper.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.io;
-
-import java.nio.file.FileSystems;
-import java.nio.file.InvalidPathException;
-import java.nio.file.FileAlreadyExistsException;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.file.attribute.PosixFilePermission;
-import java.nio.file.attribute.PosixFilePermissions;
-import static java.nio.file.attribute.PosixFilePermission.*;
-import java.util.Set;
-import java.util.EnumSet;
-
-/**
- * Helper class to support creation of temporary files and directory with
- * initial attributes.
- */
-
-class TempFileHelper {
- private TempFileHelper() { }
-
- // default file and directory permissions (lazily initialized)
- private static class PermissionsHolder {
- static final boolean hasPosixPermissions = FileSystems.getDefault()
- .supportedFileAttributeViews().contains("posix");
- static final FileAttribute<Set<PosixFilePermission>> filePermissions =
- PosixFilePermissions.asFileAttribute(EnumSet.of(OWNER_READ, OWNER_WRITE));
- static final FileAttribute<Set<PosixFilePermission>> directoryPermissions =
- PosixFilePermissions.asFileAttribute(EnumSet
- .of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE));
- }
-
- /**
- * Creates a file or directory in the temporary directory.
- */
- private static File create(String prefix,
- String suffix,
- FileAttribute[] attrs,
- boolean isDirectory)
- throws IOException
- {
- // in POSIX environments use default file and directory permissions
- // if initial permissions not given by caller.
- if (PermissionsHolder.hasPosixPermissions) {
- if (attrs.length == 0) {
- // no attributes so use default permissions
- attrs = new FileAttribute<?>[1];
- attrs[0] = (isDirectory) ? PermissionsHolder.directoryPermissions :
- PermissionsHolder.filePermissions;
- } else {
- // check if posix permissions given; if not use default
- boolean hasPermissions = false;
- for (int i=0; i<attrs.length; i++) {
- if (attrs[i].name().equals("posix:permissions")) {
- hasPermissions = true;
- break;
- }
- }
- if (!hasPermissions) {
- FileAttribute<?>[] copy = new FileAttribute<?>[attrs.length+1];
- System.arraycopy(attrs, 0, copy, 0, attrs.length);
- attrs = copy;
- attrs[attrs.length-1] = (isDirectory) ?
- PermissionsHolder.directoryPermissions :
- PermissionsHolder.filePermissions;
- }
- }
- }
-
- // loop generating random names until file or directory can be created
- SecurityManager sm = System.getSecurityManager();
- for (;;) {
- File tmpdir = File.TempDirectory.location();
- File f = File.TempDirectory.generateFile(prefix, suffix, tmpdir);
- try {
- if (isDirectory) {
- f.toPath().createDirectory(attrs);
- } else {
- f.toPath().createFile(attrs);
- }
- return f;
- } catch (InvalidPathException e) {
- // don't reveal temporary directory location
- if (sm != null)
- throw new IllegalArgumentException("Invalid prefix or suffix");
- throw e;
- } catch (SecurityException e) {
- // don't reveal temporary directory location
- if (sm != null)
- throw new SecurityException("Unable to create temporary file");
- throw e;
- } catch (FileAlreadyExistsException e) {
- // ignore
- }
- }
- }
-
- /**
- * Creates a file in the temporary directory.
- */
- static File createFile(String prefix, String suffix, FileAttribute[] attrs)
- throws IOException
- {
- return create(prefix, suffix, attrs, false);
- }
-
- /**
- * Creates a directory in the temporary directory.
- */
- static File createDirectory(String prefix, FileAttribute[] attrs)
- throws IOException
- {
- return create(prefix, "", attrs, true);
- }
-}
--- a/jdk/src/share/classes/java/lang/StackTraceElement.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/lang/StackTraceElement.java Mon Feb 14 16:30:10 2011 -0800
@@ -68,8 +68,8 @@
*/
public StackTraceElement(String declaringClass, String methodName,
String fileName, int lineNumber) {
- this.declaringClass = Objects.nonNull(declaringClass, "Declaring class is null");
- this.methodName = Objects.nonNull(methodName, "Method name is null");
+ this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
+ this.methodName = Objects.requireNonNull(methodName, "Method name is null");
this.fileName = fileName;
this.lineNumber = lineNumber;
}
--- a/jdk/src/share/classes/java/lang/SuppressWarnings.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/lang/SuppressWarnings.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,7 @@
* @since 1.5
* @author Josh Bloch
*/
-@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER})
+@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
/**
--- a/jdk/src/share/classes/java/lang/Thread.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/lang/Thread.java Mon Feb 14 16:30:10 2011 -0800
@@ -690,7 +690,7 @@
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
- group.threadStarting(this);
+ group.add(this);
boolean started = false;
try {
--- a/jdk/src/share/classes/java/lang/ThreadGroup.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/lang/ThreadGroup.java Mon Feb 14 16:30:10 2011 -0800
@@ -868,21 +868,6 @@
}
/**
- * Notifies the group that the thread {@code t} is about to be
- * started and adds the thread to this thread group.
- *
- * The thread is now a fully fledged member of the group, even though
- * it hasn't been started yet. It will prevent the group from being
- * destroyed so the unstarted Threads count is decremented.
- */
- void threadStarting(Thread t) {
- synchronized (this) {
- add(t);
- nUnstartedThreads--;
- }
- }
-
- /**
* Adds the specified thread to this thread group.
*
* <p> Note: This method is called from both library code
@@ -910,6 +895,12 @@
// This is done last so it doesn't matter in case the
// thread is killed
nthreads++;
+
+ // The thread is now a fully fledged member of the group, even
+ // though it may, or may not, have been started yet. It will prevent
+ // the group from being destroyed so the unstarted Threads count is
+ // decremented.
+ nUnstartedThreads--;
}
}
--- a/jdk/src/share/classes/java/lang/annotation/ElementType.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/lang/annotation/ElementType.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,12 +40,6 @@
/** Class, interface (including annotation type), or enum declaration */
TYPE,
- /** Uses of a type */
- TYPE_USE,
-
- /** type parameters */
- TYPE_PARAMETER,
-
/** Field declaration (includes enum constants) */
FIELD,
--- a/jdk/src/share/classes/java/math/BigDecimal.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/math/BigDecimal.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -121,8 +121,8 @@
* scale for each operation is listed in the table below.
*
* <table border>
- * <caption top><h3>Preferred Scales for Results of Arithmetic Operations
- * </h3></caption>
+ * <caption><b>Preferred Scales for Results of Arithmetic Operations
+ * </b></caption>
* <tr><th>Operation</th><th>Preferred Scale of Result</th></tr>
* <tr><td>Add</td><td>max(addend.scale(), augend.scale())</td>
* <tr><td>Subtract</td><td>max(minuend.scale(), subtrahend.scale())</td>
@@ -661,25 +661,25 @@
* <dd>{@code .} <i>FractionPart</i>
* <dd><i>IntegerPart</i>
* <p>
- * <dt><i>IntegerPart:
- * <dd>Digits</i>
+ * <dt><i>IntegerPart:</i>
+ * <dd><i>Digits</i>
* <p>
- * <dt><i>FractionPart:
- * <dd>Digits</i>
+ * <dt><i>FractionPart:</i>
+ * <dd><i>Digits</i>
* <p>
- * <dt><i>Exponent:
- * <dd>ExponentIndicator SignedInteger</i>
+ * <dt><i>Exponent:</i>
+ * <dd><i>ExponentIndicator SignedInteger</i>
* <p>
* <dt><i>ExponentIndicator:</i>
* <dd>{@code e}
* <dd>{@code E}
* <p>
- * <dt><i>SignedInteger:
- * <dd>Sign<sub>opt</sub> Digits</i>
+ * <dt><i>SignedInteger:</i>
+ * <dd><i>Sign<sub>opt</sub> Digits</i>
* <p>
- * <dt><i>Digits:
- * <dd>Digit
- * <dd>Digits Digit</i>
+ * <dt><i>Digits:</i>
+ * <dd><i>Digit</i>
+ * <dd><i>Digits Digit</i>
* <p>
* <dt><i>Digit:</i>
* <dd>any character for which {@link Character#isDigit}
--- a/jdk/src/share/classes/java/math/RoundingMode.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/math/RoundingMode.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,7 @@
*
*<p>
*<table border>
- * <caption top><h3>Summary of Rounding Operations Under Different Rounding Modes</h3></caption>
+ * <caption><b>Summary of Rounding Operations Under Different Rounding Modes</b></caption>
* <tr><th></th><th colspan=8>Result of rounding input to one digit with the given
* rounding mode</th>
* <tr valign=top>
--- a/jdk/src/share/classes/java/nio/channels/FileChannel.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/channels/FileChannel.java Mon Feb 14 16:30:10 2011 -0800
@@ -248,7 +248,7 @@
* FileSystemProvider#newFileChannel newFileChannel} method on the
* provider that created the {@code Path}.
*
- * @param file
+ * @param path
* The path of the file to open or create
* @param options
* Options specifying how the file is opened
@@ -261,7 +261,7 @@
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
* @throws UnsupportedOperationException
- * If the {@code file} is associated with a provider that does not
+ * If the {@code path} is associated with a provider that does not
* support creating file channels, or an unsupported open option is
* specified, or the array contains an attribute that cannot be set
* atomically when creating the file
@@ -278,13 +278,13 @@
*
* @since 1.7
*/
- public static FileChannel open(Path file,
+ public static FileChannel open(Path path,
Set<? extends OpenOption> options,
FileAttribute<?>... attrs)
throws IOException
{
- FileSystemProvider provider = file.getFileSystem().provider();
- return provider.newFileChannel(file, options, attrs);
+ FileSystemProvider provider = path.getFileSystem().provider();
+ return provider.newFileChannel(path, options, attrs);
}
private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
@@ -295,10 +295,12 @@
* <p> An invocation of this method behaves in exactly the same way as the
* invocation
* <pre>
- * fc.{@link #open(Path,Set,FileAttribute[]) open}(file, options, new FileAttribute<?>[0]);
+ * fc.{@link #open(Path,Set,FileAttribute[]) open}(file, opts, new FileAttribute<?>[0]);
* </pre>
+ * where {@code opts} is a set of the options specified in the {@code
+ * options} array.
*
- * @param file
+ * @param path
* The path of the file to open or create
* @param options
* Options specifying how the file is opened
@@ -308,7 +310,7 @@
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
* @throws UnsupportedOperationException
- * If the {@code file} is associated with a provider that does not
+ * If the {@code path} is associated with a provider that does not
* support creating file channels, or an unsupported open option is
* specified
* @throws IOException
@@ -324,12 +326,12 @@
*
* @since 1.7
*/
- public static FileChannel open(Path file, OpenOption... options)
+ public static FileChannel open(Path path, OpenOption... options)
throws IOException
{
Set<OpenOption> set = new HashSet<OpenOption>(options.length);
Collections.addAll(set, options);
- return open(file, set, NO_ATTRIBUTES);
+ return open(path, set, NO_ATTRIBUTES);
}
// -- Channel operations --
--- a/jdk/src/share/classes/java/nio/channels/SeekableByteChannel.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/channels/SeekableByteChannel.java Mon Feb 14 16:30:10 2011 -0800
@@ -47,7 +47,7 @@
* so that method invocations on the implementation class can be chained.
*
* @since 1.7
- * @see java.nio.file.Path#newByteChannel
+ * @see java.nio.file.Files#newByteChannel
*/
public interface SeekableByteChannel
--- a/jdk/src/share/classes/java/nio/file/AccessMode.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/AccessMode.java Mon Feb 14 16:30:10 2011 -0800
@@ -29,8 +29,6 @@
* Defines access modes used to test the accessibility of a file.
*
* @since 1.7
- *
- * @see Path#checkAccess
*/
public enum AccessMode {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/CopyMoveHelper.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Helper class to support copying or moving files when the source and target
+ * are associated with different providers.
+ */
+
+class CopyMoveHelper {
+ private CopyMoveHelper() { }
+
+ /**
+ * Parses the arguments for a file copy operation.
+ */
+ private static class CopyOptions {
+ boolean replaceExisting = false;
+ boolean copyAttributes = false;
+ boolean followLinks = true;
+
+ private CopyOptions() { }
+
+ static CopyOptions parse(CopyOption... options) {
+ CopyOptions result = new CopyOptions();
+ for (CopyOption option: options) {
+ if (option == StandardCopyOption.REPLACE_EXISTING) {
+ result.replaceExisting = true;
+ continue;
+ }
+ if (option == LinkOption.NOFOLLOW_LINKS) {
+ result.followLinks = false;
+ continue;
+ }
+ if (option == StandardCopyOption.COPY_ATTRIBUTES) {
+ result.copyAttributes = true;
+ continue;
+ }
+ if (option == null)
+ throw new NullPointerException();
+ throw new UnsupportedOperationException("'" + option +
+ "' is not a recognized copy option");
+ }
+ return result;
+ }
+ }
+
+ /**
+ * Converts the given array of options for moving a file to options suitable
+ * for copying the file when a move is implemented as copy + delete.
+ */
+ private static CopyOption[] convertMoveToCopyOptions(CopyOption... options)
+ throws AtomicMoveNotSupportedException
+ {
+ int len = options.length;
+ CopyOption[] newOptions = new CopyOption[len+2];
+ for (int i=0; i<len; i++) {
+ CopyOption option = options[i];
+ if (option == StandardCopyOption.ATOMIC_MOVE) {
+ throw new AtomicMoveNotSupportedException(null, null,
+ "Atomic move between providers is not supported");
+ }
+ newOptions[i] = option;
+ }
+ newOptions[len] = LinkOption.NOFOLLOW_LINKS;
+ newOptions[len+1] = StandardCopyOption.COPY_ATTRIBUTES;
+ return newOptions;
+ }
+
+ /**
+ * Simple copy for use when source and target are associated with different
+ * providers
+ */
+ static void copyToForeignTarget(Path source, Path target,
+ CopyOption... options)
+ throws IOException
+ {
+ CopyOptions opts = CopyOptions.parse(options);
+ LinkOption[] linkOptions = (opts.followLinks) ? new LinkOption[0] :
+ new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
+
+ // attributes of source file
+ BasicFileAttributes attrs = Files.readAttributes(source,
+ BasicFileAttributes.class,
+ linkOptions);
+ if (attrs.isSymbolicLink())
+ throw new IOException("Copying of symbolic links not supported");
+
+ // delete target if it exists and REPLACE_EXISTING is specified
+ if (opts.replaceExisting) {
+ Files.deleteIfExists(target);
+ } else if (Files.exists(target))
+ throw new FileAlreadyExistsException(target.toString());
+
+ // create directory or copy file
+ if (attrs.isDirectory()) {
+ Files.createDirectory(target);
+ } else {
+ try (InputStream in = Files.newInputStream(source)) {
+ Files.copy(in, target);
+ }
+ }
+
+ // copy basic attributes to target
+ if (opts.copyAttributes) {
+ BasicFileAttributeView view =
+ Files.getFileAttributeView(target, BasicFileAttributeView.class, linkOptions);
+ try {
+ view.setTimes(attrs.lastModifiedTime(),
+ attrs.lastAccessTime(),
+ attrs.creationTime());
+ } catch (IOException x) {
+ // rollback
+ try {
+ Files.delete(target);
+ } catch (IOException ignore) { }
+ throw x;
+ }
+ }
+ }
+
+ /**
+ * Simple move implements as copy+delete for use when source and target are
+ * associated with different providers
+ */
+ static void moveToForeignTarget(Path source, Path target,
+ CopyOption... options) throws IOException
+ {
+ copyToForeignTarget(source, target, convertMoveToCopyOptions(options));
+ Files.delete(source);
+ }
+}
--- a/jdk/src/share/classes/java/nio/file/CopyOption.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/CopyOption.java Mon Feb 14 16:30:10 2011 -0800
@@ -28,8 +28,12 @@
/**
* An object that configures how to copy or move a file.
*
- * <p> Objects of this type may be used with the {@link Path#copyTo copyTo} and
- * {@link Path#moveTo moveTo} methods to configure how a file is copied or moved.
+ * <p> Objects of this type may be used with the {@link
+ * Files#copy(Path,Path,CopyOption[]) Files.copy(Path,Path,CopyOption...)},
+ * {@link Files#copy(java.io.InputStream,Path,CopyOption[])
+ * Files.copy(InputStream,Path,CopyOption...)} and {@link Files#move
+ * Files.move(Path,Path,CopyOption...)} methods to configure how a file is
+ * copied or moved.
*
* <p> The {@link StandardCopyOption} enumeration type defines the
* <i>standard</i> options.
--- a/jdk/src/share/classes/java/nio/file/DirectoryIteratorException.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/DirectoryIteratorException.java Mon Feb 14 16:30:10 2011 -0800
@@ -56,7 +56,7 @@
* if the cause is {@code null}
*/
public DirectoryIteratorException(IOException cause) {
- super(Objects.nonNull(cause));
+ super(Objects.requireNonNull(cause));
}
/**
--- a/jdk/src/share/classes/java/nio/file/DirectoryStream.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/DirectoryStream.java Mon Feb 14 16:30:10 2011 -0800
@@ -54,7 +54,7 @@
* construct to ensure that the stream is closed:
* <pre>
* Path dir = ...
- * try (DirectoryStream<Path> stream = dir.newDirectoryStream()) {
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
* for (Path entry: stream) {
* ...
* }
@@ -97,8 +97,8 @@
* both the for-each and try-with-resources constructs.
* <pre>
* List<Path> listSourceFiles(Path dir) throws IOException {
- * List<Path> result = new ArrayList<Path>();
- * try (DirectoryStream<Path> stream = dir.newDirectoryStream("*.{c,h,cpp,hpp,java}")) {
+ * List<Path> result = new ArrayList<>();
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
* for (Path entry: stream) {
* result.add(entry);
* }
@@ -113,7 +113,7 @@
*
* @since 1.7
*
- * @see Path#newDirectoryStream
+ * @see Files#newDirectoryStream(Path)
*/
public interface DirectoryStream<T>
@@ -122,9 +122,9 @@
/**
* An interface that is implemented by objects that decide if a directory
* entry should be accepted or filtered. A {@code Filter} is passed as the
- * parameter to the {@link Path#newDirectoryStream(DirectoryStream.Filter)
- * newDirectoryStream} method when opening a directory to iterate over the
- * entries in the directory.
+ * parameter to the {@link Files#newDirectoryStream(Path,DirectoryStream.Filter)}
+ * method when opening a directory to iterate over the entries in the
+ * directory.
*
* @param <T> the type of the directory entry
*
--- a/jdk/src/share/classes/java/nio/file/FileRef.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file;
-
-import java.nio.file.attribute.*;
-import java.util.Map;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.IOException;
-
-/**
- * A reference to a file.
- *
- * <p> A {@code FileRef} is an object that locates a file and defines methods to
- * open the file for reading or writing. It also provides access to associated
- * metadata or file attributes.
- *
- * @since 1.7
- * @see java.nio.file.attribute.Attributes
- * @see java.io.File#toPath
- */
-
-public interface FileRef {
-
- /**
- * Opens the file referenced by this object, returning an input stream to
- * read from the file. The stream will not be buffered, and is not required
- * to support the {@link InputStream#mark mark} or {@link InputStream#reset
- * reset} methods. The stream will be safe for access by multiple concurrent
- * threads. Reading commences at the beginning of the file.
- *
- * <p> The {@code options} parameter determines how the file is opened.
- * If no options are present then it is equivalent to opening the file with
- * the {@link StandardOpenOption#READ READ} option. In addition to the {@code
- * READ} option, an implementation may also support additional implementation
- * specific options.
- *
- * @return an input stream to read bytes from the file
- *
- * @throws IllegalArgumentException
- * if an invalid combination of options is specified
- * @throws UnsupportedOperationException
- * if an unsupported option is specified
- * @throws IOException
- * if an I/O error occurs
- * @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.
- */
- InputStream newInputStream(OpenOption... options) throws IOException;
-
- /**
- * Opens or creates the file located by this object for writing, returning
- * an output stream to write bytes to the file.
- *
- * <p> The {@code options} parameter determines how the file is opened.
- * If no options are present then this method creates a new file for writing
- * or truncates an existing file. In addition to the {@link StandardOpenOption
- * standard} options, an implementation may also support additional
- * implementation specific options.
- *
- * <p> The resulting stream will not be buffered. The stream will be safe
- * for access by multiple concurrent threads.
- *
- * @param options
- * options specifying how the file is opened
- *
- * @return a new output stream
- *
- * @throws IllegalArgumentException
- * if {@code options} contains an invalid combination of options
- * @throws UnsupportedOperationException
- * if an unsupported option is specified
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
- * method is invoked to check write access to the file.
- */
- OutputStream newOutputStream(OpenOption... options) throws IOException;
-
- /**
- * Returns a file attribute view of a given type.
- *
- * <p> A file attribute view provides a read-only or updatable view of a
- * set of file attributes. This method is intended to be used where the file
- * attribute view defines type-safe methods to read or update the file
- * attributes. The {@code type} parameter is the type of the attribute view
- * required and the method returns an instance of that type if supported.
- * The {@link BasicFileAttributeView} type supports access to the basic
- * attributes of a file. Invoking this method to select a file attribute
- * view of that type will always return an instance of that class.
- *
- * <p> The {@code options} array may be used to indicate how symbolic links
- * are handled by the resulting file attribute view for the case that the
- * file is a symbolic link. By default, symbolic links are followed. If the
- * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then
- * symbolic links are not followed. This option is ignored by implementations
- * that do not support symbolic links.
- *
- * @param type
- * the {@code Class} object corresponding to the file attribute view
- * @param options
- * options indicating how symbolic links are handled
- *
- * @return a file attribute view of the specified type, or {@code null} if
- * the attribute view type is not available
- *
- * @throws UnsupportedOperationException
- * If options contains an unsupported option. This exception is
- * specified to allow the {@code LinkOption} enum be extended
- * in future releases.
- *
- * @see Attributes#readBasicFileAttributes
- */
- <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
- LinkOption... options);
-
- /**
- * Sets the value of a file attribute.
- *
- * <p> The {@code attribute} parameter identifies the attribute to be set
- * and takes the form:
- * <blockquote>
- * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
- * </blockquote>
- * where square brackets [...] delineate an optional component and the
- * character {@code ':'} stands for itself.
- *
- * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
- * FileAttributeView} that identifies a set of file attributes. If not
- * specified then it defaults to {@code "basic"}, the name of the file
- * attribute view that identifies the basic set of file attributes common to
- * many file systems. <i>attribute-name</i> is the name of the attribute
- * within the set.
- *
- * <p> <b>Usage Example:</b>
- * Suppose we want to set the DOS "hidden" attribute:
- * <pre>
- * file.setAttribute("dos:hidden", true);
- * </pre>
- *
- * @param attribute
- * the attribute to set
- * @param value
- * the attribute value
- * @param options
- * options indicating how symbolic links are handled
- *
- * @throws UnsupportedOperationException
- * if the attribute view is not available or it does not support
- * updating the attribute
- * @throws IllegalArgumentException
- * if the attribute value is of the correct type but has an
- * inappropriate value
- * @throws ClassCastException
- * If the attribute value is not of the expected type or is a
- * collection containing elements that are not of the expected
- * type
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the file. If this method is invoked
- * to set security sensitive attributes then the security manager
- * may be invoked to check for additional permissions.
- */
- void setAttribute(String attribute, Object value, LinkOption... options)
- throws IOException;
-
- /**
- * Reads the value of a file attribute.
- *
- * <p> The {@code attribute} parameter identifies the attribute to be read
- * and takes the form:
- * <blockquote>
- * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
- * </blockquote>
- * where square brackets [...] delineate an optional component and the
- * character {@code ':'} stands for itself.
- *
- * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
- * FileAttributeView} that identifies a set of file attributes. If not
- * specified then it defaults to {@code "basic"}, the name of the file
- * attribute view that identifies the basic set of file attributes common to
- * many file systems. <i>attribute-name</i> is the name of the attribute.
- *
- * <p> The {@code options} array may be used to indicate how symbolic links
- * are handled for the case that the file is a symbolic link. By default,
- * symbolic links are followed and the file attribute of the final target
- * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
- * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
- * the method returns the file attribute of the symbolic link.
- *
- * <p> <b>Usage Example:</b>
- * Suppose we require the user ID of the file owner on a system that
- * supports a "{@code unix}" view:
- * <pre>
- * int uid = (Integer)file.getAttribute("unix:uid");
- * </pre>
- *
- * @param attribute
- * the attribute to read
- * @param options
- * options indicating how symbolic links are handled
- * @return the attribute value or {@code null} if the attribute view
- * is not available or it does not support reading the attribute
- *
- * reading the attribute
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, its {@link SecurityManager#checkRead(String) checkRead}
- * method denies read access to the file. If this method is invoked
- * to read security sensitive attributes then the security manager
- * may be invoked to check for additional permissions.
- */
- Object getAttribute(String attribute, LinkOption... options) throws IOException;
-
- /**
- * Reads a set of file attributes as a bulk operation.
- *
- * <p> The {@code attributes} parameter identifies the attributes to be read
- * and takes the form:
- * <blockquote>
- * [<i>view-name</i><b>:</b>]<i>attribute-list</i>
- * </blockquote>
- * where square brackets [...] delineate an optional component and the
- * character {@code ':'} stands for itself.
- *
- * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
- * FileAttributeView} that identifies a set of file attributes. If not
- * specified then it defaults to {@code "basic"}, the name of the file
- * attribute view that identifies the basic set of file attributes common to
- * many file systems.
- *
- * <p> The <i>attribute-list</i> component is a comma separated list of
- * zero or more names of attributes to read. If the list contains the value
- * {@code "*"} then all attributes are read. Attributes that are not supported
- * are ignored and will not be present in the returned map. It is
- * implementation specific if all attributes are read as an atomic operation
- * with respect to other file system operations.
- *
- * <p> The following examples demonstrate possible values for the {@code
- * attributes} parameter:
- *
- * <blockquote>
- * <table border="0">
- * <tr>
- * <td> {@code "*"} </td>
- * <td> Read all {@link BasicFileAttributes basic-file-attributes}. </td>
- * </tr>
- * <tr>
- * <td> {@code "size,lastModifiedTime,lastAccessTime"} </td>
- * <td> Reads the file size, last modified time, and last access time
- * attributes. </td>
- * </tr>
- * <tr>
- * <td> {@code "posix:*"} </td>
- * <td> Read all {@link PosixFileAttributes POSIX-file-attributes}.. </td>
- * </tr>
- * <tr>
- * <td> {@code "posix:permissions,owner,size"} </td>
- * <td> Reads the POSX file permissions, owner, and file size. </td>
- * </tr>
- * </table>
- * </blockquote>
- *
- * <p> The {@code options} array may be used to indicate how symbolic links
- * are handled for the case that the file is a symbolic link. By default,
- * symbolic links are followed and the file attribute of the final target
- * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
- * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
- * the method returns the file attribute of the symbolic link.
- *
- * @param attributes
- * The attributes to read
- * @param options
- * Options indicating how symbolic links are handled
- *
- * @return A map of the attributes returned; may be empty. The map's keys
- * are the attribute names, its values are the attribute values
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, its {@link SecurityManager#checkRead(String) checkRead}
- * method denies read access to the file. If this method is invoked
- * to read security sensitive attributes then the security manager
- * may be invoke to check for additional permissions.
- */
- Map<String,?> readAttributes(String attributes, LinkOption... options)
- throws IOException;
-}
--- a/jdk/src/share/classes/java/nio/file/FileStore.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileStore.java Mon Feb 14 16:30:10 2011 -0800
@@ -32,16 +32,13 @@
* Storage for files. A {@code FileStore} represents a storage pool, device,
* partition, volume, concrete file system or other implementation specific means
* of file storage. The {@code FileStore} for where a file is stored is obtained
- * by invoking the {@link Path#getFileStore getFileStore} method, or all file
+ * by invoking the {@link Files#getFileStore getFileStore} method, or all file
* stores can be enumerated by invoking the {@link FileSystem#getFileStores
* getFileStores} method.
*
* <p> In addition to the methods defined by this class, a file store may support
* one or more {@link FileStoreAttributeView FileStoreAttributeView} classes
* that provide a read-only or updatable view of a set of file store attributes.
- * File stores associated with the default provider support the {@link
- * FileStoreSpaceAttributeView} to read the space related attributes of the
- * file store.
*
* @since 1.7
*/
@@ -87,6 +84,51 @@
public abstract boolean isReadOnly();
/**
+ * Returns the size, in bytes, of the file store.
+ *
+ * @return the size of the file store, in bytes
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract long getTotalSpace() throws IOException;
+
+ /**
+ * Returns the number of bytes available to this Java virtual machine on the
+ * file store.
+ *
+ * <p> The returned number of available bytes is a hint, but not a
+ * guarantee, that it is possible to use most or any of these bytes. The
+ * number of usable bytes is most likely to be accurate immediately
+ * after the space attributes are obtained. It is likely to be made inaccurate
+ * by any external I/O operations including those made on the system outside
+ * of this Java virtual machine.
+ *
+ * @return the number of bytes available
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract long getUsableSpace() throws IOException;
+
+ /**
+ * Returns the number of unallocated bytes in the file store.
+ *
+ * <p> The returned number of unallocated bytes is a hint, but not a
+ * guarantee, that it is possible to use most or any of these bytes. The
+ * number of unallocated bytes is most likely to be accurate immediately
+ * after the space attributes are obtained. It is likely to be
+ * made inaccurate by any external I/O operations including those made on
+ * the system outside of this virtual machine.
+ *
+ * @return the number of unallocated bytes
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract long getUnallocatedSpace() throws IOException;
+
+ /**
* Tells whether or not this file store supports the file attributes
* identified by the given file attribute view.
*
@@ -131,12 +173,6 @@
* The {@code type} parameter is the type of the attribute view required and
* the method returns an instance of that type if supported.
*
- * <p> For {@code FileStore} objects created by the default provider, then
- * the file stores support the {@link FileStoreSpaceAttributeView} that
- * provides access to space attributes. In that case invoking this method
- * with a parameter value of {@code FileStoreSpaceAttributeView.class} will
- * always return an instance of that class.
- *
* @param type
* the {@code Class} object corresponding to the attribute view
*
@@ -160,10 +196,6 @@
* a {@link FileStore AttributeView} that identifies a set of file attributes.
* <i>attribute-name</i> is the name of the attribute.
*
- * <p> For {@code FileStore} objects created by the default provider, then
- * the file stores support the {@link FileStoreSpaceAttributeView} that
- * provides access to space attributes.
- *
* <p> <b>Usage Example:</b>
* Suppose we want to know if ZFS compression is enabled (assuming the "zfs"
* view is supported):
--- a/jdk/src/share/classes/java/nio/file/FileSystem.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileSystem.java Mon Feb 14 16:30:10 2011 -0800
@@ -38,8 +38,8 @@
* <p> The default file system, obtained by invoking the {@link FileSystems#getDefault
* FileSystems.getDefault} method, provides access to the file system that is
* accessible to the Java virtual machine. The {@link FileSystems} class defines
- * methods to create file systems that provide access to other types of file
- * systems.
+ * methods to create file systems that provide access to other types of (custom)
+ * file systems.
*
* <p> A file system is the factory for several types of objects:
*
@@ -214,10 +214,9 @@
* Suppose we want to print the space usage for all file stores:
* <pre>
* for (FileStore store: FileSystems.getDefault().getFileStores()) {
- * FileStoreSpaceAttributes attrs = Attributes.readFileStoreSpaceAttributes(store);
- * long total = attrs.totalSpace() / 1024;
- * long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / 1024;
- * long avail = attrs.usableSpace() / 1024;
+ * long total = store.getTotalSpace() / 1024;
+ * long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / 1024;
+ * long avail = store.getUsableSpace() / 1024;
* System.out.format("%-20s %12d %12d %12d%n", store, total, used, avail);
* }
* </pre>
@@ -244,7 +243,20 @@
public abstract Set<String> supportedFileAttributeViews();
/**
- * Converts a path string to a {@code Path}.
+ * Converts a path string, or a sequence of strings that when joined form
+ * a path string, to a {@code Path}. If {@code more} does not specify any
+ * elements then the value of the {@code first} parameter is the path string
+ * to convert. If {@code more} specifies one or more elements then each
+ * non-empty string, including {@code first}, is considered to be a sequence
+ * of name elements (see {@link Path}) and is joined to form a path string.
+ * The details as to how the Strings are joined is provider specific but
+ * typically they will be joined using the {@link #getSeparator
+ * name-separator} as the separator. For example, if the name separator is
+ * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the
+ * path string {@code "/foo/bar/gus"} is converted to a {@code Path}.
+ * A {@code Path} representing an empty path is returned if {@code first}
+ * is the empty string and {@code more} does not contain any non-empty
+ * strings.
*
* <p> The parsing and conversion to a path object is inherently
* implementation dependent. In the simplest case, the path string is rejected,
@@ -270,18 +282,17 @@
* index} value indicating the first position in the {@code path} parameter
* that caused the path string to be rejected.
*
- * <p> Invoking this method with an empty path string throws
- * {@code InvalidPathException}.
+ * @param first
+ * the path string or initial part of the path string
+ * @param more
+ * additional strings to be joined to form the path string
*
- * @param path
- * The path string
- *
- * @return A {@code Path} object
+ * @return the resulting {@code Path}
*
* @throws InvalidPathException
* If the path string cannot be converted
*/
- public abstract Path getPath(String path);
+ public abstract Path getPath(String first, String... more);
/**
* Returns a {@code PathMatcher} that performs match operations on the
@@ -290,9 +301,9 @@
*
* The {@code syntaxAndPattern} parameter identifies the syntax and the
* pattern and takes the form:
- * <blockquote>
+ * <blockquote><pre>
* <i>syntax</i><b>:</b><i>pattern</i>
- * </blockquote>
+ * </pre></blockquote>
* where {@code ':'} stands for itself.
*
* <p> A {@code FileSystem} implementation supports the "{@code glob}" and
@@ -409,7 +420,7 @@
* @throws UnsupportedOperationException
* If the pattern syntax is not known to the implementation
*
- * @see Path#newDirectoryStream(String)
+ * @see Files#newDirectoryStream(Path,String)
*/
public abstract PathMatcher getPathMatcher(String syntaxAndPattern);
@@ -421,10 +432,8 @@
* <p> <b>Usage Example:</b>
* Suppose we want to make "joe" the owner of a file:
* <pre>
- * Path file = ...
- * UserPrincipal joe = file.getFileSystem().getUserPrincipalLookupService()
- * .lookupPrincipalByName("joe");
- * Attributes.setOwner(file, joe);
+ * UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
+ * Files.setOwner(path, lookupService.lookupPrincipalByName("joe"));
* </pre>
*
* @throws UnsupportedOperationException
--- a/jdk/src/share/classes/java/nio/file/FileSystems.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileSystems.java Mon Feb 14 16:30:10 2011 -0800
@@ -164,8 +164,8 @@
* to the first provider instance. The third provider class is instantiated
* by invoking it with a reference to the second instance, and so on. The
* last provider to be instantiated becomes the default provider; its {@code
- * getFileSystem} method is invoked with the URI {@code "file:///"} to create
- * the default file system.
+ * getFileSystem} method is invoked with the URI {@code "file:///"} to
+ * get a reference to the default file system.
*
* <p> Subsequent invocations of this method return the file system that was
* returned by the first invocation.
@@ -238,7 +238,7 @@
* Suppose there is a provider identified by the scheme {@code "memory"}
* installed:
* <pre>
- * Map<String,String> env = new HashMap<String,String>();
+ * Map<String,String> env = new HashMap<>();
* env.put("capacity", "16G");
* env.put("blockSize", "4k");
* FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"), env);
@@ -343,33 +343,25 @@
*
* <p> This method makes use of specialized providers that create pseudo file
* systems where the contents of one or more files is treated as a file
- * system. The {@code file} parameter is a reference to an existing file
- * and the {@code env} parameter is a map of provider specific properties to
- * configure the file system.
+ * system.
*
* <p> This method iterates over the {@link FileSystemProvider#installedProviders()
* installed} providers. It invokes, in turn, each provider's {@link
- * FileSystemProvider#newFileSystem(FileRef,Map) newFileSystem(FileRef,Map)} method.
- * If a provider returns a file system then the iteration terminates
- * and the file system is returned. If none of the installed providers return
- * a {@code FileSystem} then an attempt is made to locate the provider using
- * the given class loader. If a provider returns a file system then the lookup
- * terminates and the file system is returned.
+ * FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)} method
+ * with an empty map. If a provider returns a file system then the iteration
+ * terminates and the file system is returned. If none of the installed
+ * providers return a {@code FileSystem} then an attempt is made to locate
+ * the provider using the given class loader. If a provider returns a file
+ * system then the lookup terminates and the file system is returned.
*
- * @param file
- * a reference to a file
- * @param env
- * a map of provider specific properties to configure the file system;
- * may be empty
+ * @param path
+ * the path to the file
* @param loader
* the class loader to locate the provider or {@code null} to only
* attempt to locate an installed provider
*
* @return a new file system
*
- * @throws IllegalArgumentException
- * if the {@code env} parameter does not contain properties required
- * by the provider, or a property value is invalid
* @throws ProviderNotFoundException
* if a provider supporting this file type cannot be located
* @throws ServiceConfigurationError
@@ -380,18 +372,18 @@
* if a security manager is installed and it denies an unspecified
* permission
*/
- public static FileSystem newFileSystem(FileRef file,
- Map<String,?> env,
+ public static FileSystem newFileSystem(Path path,
ClassLoader loader)
throws IOException
{
- if (file == null)
+ if (path == null)
throw new NullPointerException();
+ Map<String,?> env = Collections.emptyMap();
// check installed providers
for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
try {
- return provider.newFileSystem(file, env);
+ return provider.newFileSystem(path, env);
} catch (UnsupportedOperationException uoe) {
}
}
@@ -402,7 +394,7 @@
.load(FileSystemProvider.class, loader);
for (FileSystemProvider provider: sl) {
try {
- return provider.newFileSystem(file, env);
+ return provider.newFileSystem(path, env);
} catch (UnsupportedOperationException uoe) {
}
}
--- a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Mon Feb 14 16:30:10 2011 -0800
@@ -69,7 +69,7 @@
FileVisitResult result = walk(start,
0,
new ArrayList<AncestorDirectory>());
- Objects.nonNull(result, "FileVisitor returned null");
+ Objects.requireNonNull(result, "FileVisitor returned null");
}
/**
@@ -102,12 +102,13 @@
if (attrs == null) {
try {
try {
- attrs = Attributes.readBasicFileAttributes(file, linkOptions);
+ attrs = Files.readAttributes(file, BasicFileAttributes.class, linkOptions);
} catch (IOException x1) {
if (followLinks) {
try {
- attrs = Attributes
- .readBasicFileAttributes(file, LinkOption.NOFOLLOW_LINKS);
+ attrs = Files.readAttributes(file,
+ BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS);
} catch (IOException x2) {
exc = x2;
}
@@ -151,7 +152,7 @@
} else {
boolean isSameFile = false;
try {
- isSameFile = file.isSameFile(ancestor.file());
+ isSameFile = Files.isSameFile(file, ancestor.file());
} catch (IOException x) {
// ignore
} catch (SecurityException x) {
@@ -175,7 +176,7 @@
// open the directory
try {
- stream = file.newDirectoryStream();
+ stream = Files.newDirectoryStream(file);
} catch (IOException x) {
return visitor.visitFileFailed(file, x);
} catch (SecurityException x) {
@@ -212,7 +213,11 @@
} finally {
try {
stream.close();
- } catch (IOException x) { }
+ } catch (IOException e) {
+ // IOException will be notified to postVisitDirectory
+ if (ioe == null)
+ ioe = e;
+ }
}
// invoke postVisitDirectory last
--- a/jdk/src/share/classes/java/nio/file/FileVisitor.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileVisitor.java Mon Feb 14 16:30:10 2011 -0800
@@ -30,8 +30,8 @@
/**
* A visitor of files. An implementation of this interface is provided to the
- * {@link Files#walkFileTree walkFileTree} utility method to visit each file
- * in a tree.
+ * {@link Files#walkFileTree Files.walkFileTree} methods to visit each file in
+ * a file tree.
*
* <p> <b>Usage Examples:</b>
* Suppose we want to delete a file tree. In that case, each directory should
@@ -43,19 +43,20 @@
* public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
* throws IOException
* {
- * file.delete();
+ * Files.delete(file);
* return FileVisitResult.CONTINUE;
* }
* @Override
* public FileVisitResult postVisitDirectory(Path dir, IOException e)
* throws IOException
* {
- * if (e != null) {
+ * if (e == null) {
+ * Files.delete(dir);
+ * return FileVisitResult.CONTINUE;
+ * } else {
* // directory iteration failed
* throw e;
* }
- * dir.delete();
- * return FileVisitResult.CONTINUE;
* }
* });
* </pre>
@@ -72,10 +73,12 @@
* public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
* throws IOException
* {
+ * Path targetdir = target.resolve(source.relativize(dir));
* try {
- * dir.copyTo(target.resolve(source.relativize(dir)));
+ * Files.copy(dir, targetdir);
* } catch (FileAlreadyExistsException e) {
- * // ignore
+ * if (!Files.isDirectory(targetdir))
+ * throw e;
* }
* return CONTINUE;
* }
@@ -83,7 +86,7 @@
* public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
* throws IOException
* {
- * file.copyTo(target.resolve(source.relativize(file)));
+ * Files.copy(file, target.resolve(source.relativize(file)));
* return CONTINUE;
* }
* });
--- a/jdk/src/share/classes/java/nio/file/Files.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/Files.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,16 +25,32 @@
package java.nio.file;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
import java.nio.file.spi.FileTypeDetector;
-import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
import java.io.IOException;
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
/**
- * This class consists exclusively of static methods that operate on files or
- * directories.
+ * This class consists exclusively of static methods that operate on files,
+ * directories, or other types of files.
+ *
+ * <p> In most cases, the methods defined here will delegate to the associated
+ * file system provider to perform the file operations.
*
* @since 1.7
*/
@@ -42,8 +58,1422 @@
public final class Files {
private Files() { }
+ /**
+ * Returns the {@code FileSystemProvider} to delegate to.
+ */
+ private static FileSystemProvider provider(Path path) {
+ return path.getFileSystem().provider();
+ }
+
+ // -- File contents --
+
+ /**
+ * Opens a file, returning an input stream to read from the file. The stream
+ * will not be buffered, and is not required to support the {@link
+ * InputStream#mark mark} or {@link InputStream#reset reset} methods. The
+ * stream will be safe for access by multiple concurrent threads. Reading
+ * commences at the beginning of the file. Whether the returned stream is
+ * <i>asynchronously closeable</i> and/or <i>interruptible</i> is highly
+ * file system provider specific and therefore not specified.
+ *
+ * <p> The {@code options} parameter determines how the file is opened.
+ * If no options are present then it is equivalent to opening the file with
+ * the {@link StandardOpenOption#READ READ} option. In addition to the {@code
+ * READ} option, an implementation may also support additional implementation
+ * specific options.
+ *
+ * @param path
+ * the path to the file to open
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new input stream
+ *
+ * @throws IllegalArgumentException
+ * if an invalid combination of options is specified
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws IOException
+ * if an I/O error occurs
+ * @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.
+ */
+ public static InputStream newInputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ return provider(path).newInputStream(path, options);
+ }
+
+ /**
+ * Opens or creates a file, returning an output stream that may be used to
+ * write bytes to the file. The resulting stream will not be buffered. The
+ * stream will be safe for access by multiple concurrent threads. Whether
+ * the returned stream is <i>asynchronously closeable</i> and/or
+ * <i>interruptible</i> is highly file system provider specific and
+ * therefore not specified.
+ *
+ * <p> This method opens or creates a file in exactly the manner specified
+ * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
+ * method with the exception that the {@link StandardOpenOption#READ READ}
+ * option may not be present in the array of options. If no options are
+ * present then this method works as if the {@link StandardOpenOption#CREATE
+ * CREATE}, {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING},
+ * and {@link StandardOpenOption#WRITE WRITE} options are present. In other
+ * words, it opens the file for writing, creating the file if it doesn't
+ * exist, or initially truncating an existing {@link #isRegularFile
+ * regular-file} to a size of {@code 0} if it exists.
+ *
+ * <p> <b>Usage Examples:</b>
+ * <pre>
+ * Path path = ...
+ *
+ * // replace an existing file or create the file if it doesn't initially exist
+ * OutputStream out = Files.newOutputStream(path);
+ *
+ * // append to an existing file, fail if the file does not exist
+ * out = Files.newOutputStream(path, APPEND);
+ *
+ * // append to an existing file, create file if it doesn't initially exist
+ * out = Files.newOutputStream(CREATE, APPEND);
+ *
+ * // always create new file, failing if it already exists
+ * out = Files.newOutputStream(CREATE_NEW);
+ * </pre>
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new output stream
+ *
+ * @throws IllegalArgumentException
+ * if {@code options} contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ */
+ public static OutputStream newOutputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ return provider(path).newOutputStream(path, options);
+ }
+
+ /**
+ * Opens or creates a file, returning a seekable byte channel to access the
+ * file.
+ *
+ * <p> The {@code options} parameter determines how the file is opened.
+ * The {@link StandardOpenOption#READ READ} and {@link
+ * StandardOpenOption#WRITE WRITE} options determine if the file should be
+ * opened for reading and/or writing. If neither option (or the {@link
+ * StandardOpenOption#APPEND APPEND} option) is present then the file is
+ * opened for reading. By default reading or writing commence at the
+ * beginning of the file.
+ *
+ * <p> In the addition to {@code READ} and {@code WRITE}, the following
+ * options may be present:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Option</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#APPEND APPEND} </td>
+ * <td> If this option is present then the file is opened for writing and
+ * each invocation of the channel's {@code write} method first advances
+ * the position to the end of the file and then writes the requested
+ * data. Whether the advancement of the position and the writing of the
+ * data are done in a single atomic operation is system-dependent and
+ * therefore unspecified. This option may not be used in conjunction
+ * with the {@code READ} or {@code TRUNCATE_EXISTING} options. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
+ * <td> If this option is present then the existing file is truncated to
+ * a size of 0 bytes. This option is ignored when the file is opened only
+ * for reading. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
+ * <td> If this option is present then a new file is created, failing if
+ * the file already exists or is a symbolic link. When creating a file the
+ * check for the existence of the file and the creation of the file if it
+ * does not exist is atomic with respect to other file system operations.
+ * This option is ignored when the file is opened only for reading. </td>
+ * </tr>
+ * <tr>
+ * <td > {@link StandardOpenOption#CREATE CREATE} </td>
+ * <td> If this option is present then an existing file is opened if it
+ * exists, otherwise a new file is created. This option is ignored if the
+ * {@code CREATE_NEW} option is also present or the file is opened only
+ * for reading. </td>
+ * </tr>
+ * <tr>
+ * <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
+ * <td> When this option is present then the implementation makes a
+ * <em>best effort</em> attempt to delete the file when closed by the
+ * {@link SeekableByteChannel#close close} method. If the {@code close}
+ * method is not invoked then a <em>best effort</em> attempt is made to
+ * delete the file when the Java virtual machine terminates. </td>
+ * </tr>
+ * <tr>
+ * <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
+ * <td> When creating a new file this option is a <em>hint</em> that the
+ * new file will be sparse. This option is ignored when not creating
+ * a new file. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#SYNC SYNC} </td>
+ * <td> Requires that every update to the file's content or metadata be
+ * written synchronously to the underlying storage device. (see <a
+ * href="package-summary.html#integrity"> Synchronized I/O file
+ * integrity</a>). </td>
+ * <tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
+ * <td> Requires that every update to the file's content be written
+ * synchronously to the underlying storage device. (see <a
+ * href="package-summary.html#integrity"> Synchronized I/O file
+ * integrity</a>). </td>
+ * </tr>
+ * </table>
+ *
+ * <p> An implementation may also support additional implementation specific
+ * options.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when a new file is created.
+ *
+ * <p> In the case of the default provider, the returned seekable byte channel
+ * is a {@link java.nio.channels.FileChannel}.
+ *
+ * <p> <b>Usage Examples:</b>
+ * <pre>
+ * Path path = ...
+ *
+ * // open file for reading
+ * ReadableByteChannel rbc = Files.newByteChannel(path, EnumSet.of(READ)));
+ *
+ * // open file for writing to the end of an existing file, creating
+ * // the file if it doesn't already exist
+ * WritableByteChannel wbc = Files.newByteChannel(path, EnumSet.of(CREATE,APPEND));
+ *
+ * // create file with initial permissions, opening it for both reading and writing
+ * {@code FileAttribute<<SetPosixFilePermission>> perms = ...}
+ * SeekableByteChannel sbc = Files.newByteChannel(path, EnumSet.of(CREATE_NEW,READ,WRITE), perms);
+ * </pre>
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return a new seekable byte channel
+ *
+ * @throws IllegalArgumentException
+ * if the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported open option is specified or the array contains
+ * attributes that cannot be set atomically when creating the file
+ * @throws FileAlreadyExistsException
+ * if a file of that name already exists and the {@link
+ * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @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 path if the file is
+ * opened for reading. The {@link SecurityManager#checkWrite(String)
+ * checkWrite} method is invoked to check write access to the path
+ * if the file is opened for writing. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ *
+ * @see java.nio.channels.FileChannel#open(Path,Set,FileAttribute[])
+ */
+ public static SeekableByteChannel newByteChannel(Path path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return provider(path).newByteChannel(path, options, attrs);
+ }
+
+ /**
+ * Opens or creates a file, returning a seekable byte channel to access the
+ * file.
+ *
+ * <p> This method opens or creates a file in exactly the manner specified
+ * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
+ * method.
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new seekable byte channel
+ *
+ * @throws IllegalArgumentException
+ * if the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported open option is specified
+ * @throws FileAlreadyExistsException
+ * if a file of that name already exists and the {@link
+ * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @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 path if the file is
+ * opened for reading. The {@link SecurityManager#checkWrite(String)
+ * checkWrite} method is invoked to check write access to the path
+ * if the file is opened for writing. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ *
+ * @see java.nio.channels.FileChannel#open(Path,OpenOption[])
+ */
+ public static SeekableByteChannel newByteChannel(Path path, OpenOption... options)
+ throws IOException
+ {
+ Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+ Collections.addAll(set, options);
+ return newByteChannel(path, set);
+ }
+
+ // -- Directories --
+
+ /**
+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
+ * all entries in the directory. The elements returned by the directory
+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+ * Path}, each one representing an entry in the directory. The {@code Path}
+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+ * name of the directory entry against {@code dir}.
+ *
+ * <p> When not using the try-with-resources construct, then directory
+ * stream's {@code close} method should be invoked after iteration is
+ * completed so as to free any resources held for the open directory.
+ *
+ * <p> When an implementation supports operations on entries in the
+ * directory that execute in a race-free manner then the returned directory
+ * stream is a {@link SecureDirectoryStream}.
+ *
+ * @param dir
+ * the path to the directory
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @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.
+ */
+ public static DirectoryStream<Path> newDirectoryStream(Path dir)
+ throws IOException
+ {
+ return provider(dir).newDirectoryStream(dir, new DirectoryStream.Filter<Path>() {
+ @Override
+ public boolean accept(Path entry) {
+ return true;
+ }
+ });
+ }
+
+ /**
+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
+ * the entries in the directory. The elements returned by the directory
+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+ * Path}, each one representing an entry in the directory. The {@code Path}
+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+ * name of the directory entry against {@code dir}. The entries returned by
+ * the iterator are filtered by matching the {@code String} representation
+ * of their file names against the given <em>globbing</em> pattern.
+ *
+ * <p> For example, suppose we want to iterate over the files ending with
+ * ".java" in a directory:
+ * <pre>
+ * Path dir = ...
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.java")) {
+ * :
+ * }
+ * </pre>
+ *
+ * <p> The globbing pattern is specified by the {@link
+ * FileSystem#getPathMatcher getPathMatcher} method.
+ *
+ * <p> When not using the try-with-resources construct, then directory
+ * stream's {@code close} method should be invoked after iteration is
+ * completed so as to free any resources held for the open directory.
+ *
+ * <p> When an implementation supports operations on entries in the
+ * directory that execute in a race-free manner then the returned directory
+ * stream is a {@link SecureDirectoryStream}.
+ *
+ * @param dir
+ * the path to the directory
+ * @param glob
+ * the glob pattern
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws java.util.regex.PatternSyntaxException
+ * if the pattern is invalid
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @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.
+ */
+ public static DirectoryStream<Path> newDirectoryStream(Path dir, String glob)
+ throws IOException
+ {
+ // avoid creating a matcher if all entries are required.
+ if (glob.equals("*"))
+ return newDirectoryStream(dir);
+
+ // create a matcher and return a filter that uses it.
+ FileSystem fs = dir.getFileSystem();
+ final PathMatcher matcher = fs.getPathMatcher("glob:" + glob);
+ DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+ @Override
+ public boolean accept(Path entry) {
+ return matcher.matches(entry.getFileName());
+ }
+ };
+ return fs.provider().newDirectoryStream(dir, filter);
+ }
+
+ /**
+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
+ * the entries in the directory. The elements returned by the directory
+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+ * Path}, each one representing an entry in the directory. The {@code Path}
+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+ * name of the directory entry against {@code dir}. The entries returned by
+ * the iterator are filtered by the given {@link DirectoryStream.Filter
+ * filter}.
+ *
+ * <p> When not using the try-with-resources construct, then directory
+ * stream's {@code close} method should be invoked after iteration is
+ * completed so as to free any resources held for the open directory.
+ *
+ * <p> Where the filter terminates due to an uncaught error or runtime
+ * exception then it is propagated to the {@link Iterator#hasNext()
+ * hasNext} or {@link Iterator#next() next} method. Where an {@code
+ * IOException} is thrown, it results in the {@code hasNext} or {@code
+ * next} method throwing a {@link DirectoryIteratorException} with the
+ * {@code IOException} as the cause.
+ *
+ * <p> When an implementation supports operations on entries in the
+ * directory that execute in a race-free manner then the returned directory
+ * stream is a {@link SecureDirectoryStream}.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to iterate over the files in a directory that are
+ * larger than 8K.
+ * <pre>
+ * DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+ * public boolean accept(Path file) throws IOException {
+ * return (Files.size(file) > 8192L);
+ * }
+ * };
+ * Path dir = ...
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
+ * :
+ * }
+ * </pre>
+ *
+ * @param dir
+ * the path to the directory
+ * @param filter
+ * the directory stream filter
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @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.
+ */
+ public static DirectoryStream<Path> newDirectoryStream(Path dir,
+ DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ return provider(dir).newDirectoryStream(dir, filter);
+ }
+
+ // -- Creation and deletion --
+
+ /**
+ * Creates a new and empty file, failing if the file already exists. The
+ * check for the existence of the file and the creation of the new file if
+ * it does not exist are a single operation that is atomic with respect to
+ * all other filesystem activities that might affect the directory.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the file. Each attribute
+ * is identified by its {@link FileAttribute#name name}. If more than one
+ * attribute of the same name is included in the array then all but the last
+ * occurrence is ignored.
+ *
+ * @param path
+ * the path to the file to create
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return the file
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the file
+ * @throws FileAlreadyExistsException
+ * if a file of that name already exists
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs or the parent directory does not exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the new file.
+ */
+ public static Path createFile(Path path, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ EnumSet<StandardOpenOption> options =
+ EnumSet.<StandardOpenOption>of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
+ newByteChannel(path, options, attrs).close();
+ return path;
+ }
+
+ /**
+ * Creates a new directory. The check for the existence of the file and the
+ * creation of the directory if it does not exist are a single operation
+ * that is atomic with respect to all other filesystem activities that might
+ * affect the directory. The {@link #createDirectories createDirectories}
+ * method should be used where it is required to create all nonexistent
+ * parent directories first.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the directory. Each
+ * attribute is identified by its {@link FileAttribute#name name}. If more
+ * than one attribute of the same name is included in the array then all but
+ * the last occurrence is ignored.
+ *
+ * @param dir
+ * the directory to create
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @return the directory
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws FileAlreadyExistsException
+ * if a directory could not otherwise be created because a file of
+ * that name already exists <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs or the parent directory does not exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the new directory.
+ */
+ public static Path createDirectory(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ provider(dir).createDirectory(dir, attrs);
+ return dir;
+ }
+
+ /**
+ * Creates a directory by creating all nonexistent parent directories first.
+ * Unlike the {@link #createDirectory createDirectory} method, an exception
+ * is not thrown if the directory could not be created because it already
+ * exists.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the nonexistent
+ * directories. Each file attribute is identified by its {@link
+ * FileAttribute#name name}. If more than one attribute of the same name is
+ * included in the array then all but the last occurrence is ignored.
+ *
+ * <p> If this method fails, then it may do so after creating some, but not
+ * all, of the parent directories.
+ *
+ * @param dir
+ * the directory to create
+ *
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @return the directory
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws FileAlreadyExistsException
+ * if {@code dir} exists but is not a directory <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * in the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked prior to attempting to create a directory and
+ * its {@link SecurityManager#checkRead(String) checkRead} is
+ * invoked for each parent directory that is checked. If {@code
+ * dir} is not an absolute path then its {@link Path#toAbsolutePath
+ * toAbsolutePath} may need to be invoked to get its absolute path.
+ * This may invoke the security manager's {@link
+ * SecurityManager#checkPropertyAccess(String) checkPropertyAccess}
+ * method to check access to the system property {@code user.dir}
+ */
+ public static Path createDirectories(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ // attempt to create the directory
+ try {
+ createAndCheckIsDirectory(dir, attrs);
+ return dir;
+ } catch (FileAlreadyExistsException x) {
+ // file exists and is not a directory
+ throw x;
+ } catch (IOException x) {
+ // parent may not exist or other reason
+ }
+ SecurityException se = null;
+ try {
+ dir = dir.toAbsolutePath();
+ } catch (SecurityException x) {
+ // don't have permission to get absolute path
+ se = x;
+ }
+ // find a decendent that exists
+ Path parent = dir.getParent();
+ while (parent != null) {
+ try {
+ provider(parent).checkAccess(parent);
+ break;
+ } catch (NoSuchFileException x) {
+ // does not exist
+ }
+ parent = parent.getParent();
+ }
+ if (parent == null) {
+ // unable to find existing parent
+ if (se != null)
+ throw se;
+ throw new IOException("Root directory does not exist");
+ }
+
+ // create directories
+ Path child = parent;
+ for (Path name: parent.relativize(dir)) {
+ child = child.resolve(name);
+ createAndCheckIsDirectory(child, attrs);
+ }
+ return dir;
+ }
+
+ /**
+ * Used by createDirectories to attempt to create a directory. A no-op
+ * if the directory already exists.
+ */
+ private static void createAndCheckIsDirectory(Path dir,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ try {
+ createDirectory(dir, attrs);
+ } catch (FileAlreadyExistsException x) {
+ if (!isDirectory(dir, LinkOption.NOFOLLOW_LINKS))
+ throw x;
+ }
+ }
+
+ /**
+ * Creates a new empty file in the specified directory, using the given
+ * prefix and suffix strings to generate its name. The resulting
+ * {@code Path} is associated with the same {@code FileSystem} as the given
+ * directory.
+ *
+ * <p> The details as to how the name of the file is constructed is
+ * implementation dependent and therefore not specified. Where possible
+ * the {@code prefix} and {@code suffix} are used to construct candidate
+ * names in the same manner as the {@link
+ * java.io.File#createTempFile(String,String,File)} method.
+ *
+ * <p> As with the {@code File.createTempFile} methods, this method is only
+ * part of a temporary-file facility. Where used as a <em>work files</em>,
+ * the resulting file may be opened using the {@link
+ * StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} option so that the
+ * file is deleted when the appropriate {@code close} method is invoked.
+ * Alternatively, a {@link Runtime#addShutdownHook shutdown-hook}, or the
+ * {@link java.io.File#deleteOnExit} mechanism may be used to delete the
+ * file automatically.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the file. Each attribute
+ * is identified by its {@link FileAttribute#name name}. If more than one
+ * attribute of the same name is included in the array then all but the last
+ * occurrence is ignored. When no file attributes are specified, then the
+ * resulting file may have more restrictive access permissions to files
+ * created by the {@link java.io.File#createTempFile(String,String,File)}
+ * method.
+ *
+ * @param dir
+ * the path to directory in which to create the file
+ * @param prefix
+ * the prefix string to be used in generating the file's name;
+ * may be {@code null}
+ * @param suffix
+ * the suffix string to be used in generating the file's name;
+ * may be {@code null}, in which case "{@code .tmp}" is used
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return the path to the newly created file that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix or suffix parameters cannot be used to generate
+ * a candidate file name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or {@code dir} does not exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ */
+ public static Path createTempFile(Path dir,
+ String prefix,
+ String suffix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempFile(dir, prefix, suffix, attrs);
+ }
+
+ /**
+ * Creates an empty file in the default temporary-file directory, using
+ * the given prefix and suffix to generate its name. The resulting {@code
+ * Path} is associated with the default {@code FileSystem}.
+ *
+ * <p> This method works in exactly the manner specified by the
+ * {@link #createTempFile(Path,String,String,FileAttribute[])} method for
+ * the case that the {@code dir} parameter is the temporary-file directory.
+ *
+ * @param prefix
+ * the prefix string to be used in generating the file's name;
+ * may be {@code null}
+ * @param suffix
+ * the suffix string to be used in generating the file's name;
+ * may be {@code null}, in which case "{@code .tmp}" is used
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return the path to the newly created file that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix or suffix parameters cannot be used to generate
+ * a candidate file name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or the temporary-file directory does not
+ * exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ */
+ public static Path createTempFile(String prefix,
+ String suffix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempFile(null, prefix, suffix, attrs);
+ }
+
+ /**
+ * Creates a new directory in the specified directory, using the given
+ * prefix to generate its name. The resulting {@code Path} is associated
+ * with the same {@code FileSystem} as the given directory.
+ *
+ * <p> The details as to how the name of the directory is constructed is
+ * implementation dependent and therefore not specified. Where possible
+ * the {@code prefix} is used to construct candidate names.
+ *
+ * <p> As with the {@code createTempFile} methods, this method is only
+ * part of a temporary-file facility. A {@link Runtime#addShutdownHook
+ * shutdown-hook}, or the {@link java.io.File#deleteOnExit} mechanism may be
+ * used to delete the directory automatically.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the directory. Each
+ * attribute is identified by its {@link FileAttribute#name name}. If more
+ * than one attribute of the same name is included in the array then all but
+ * the last occurrence is ignored.
+ *
+ * @param dir
+ * the path to directory in which to create the directory
+ * @param prefix
+ * the prefix string to be used in generating the directory's name;
+ * may be {@code null}
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @return the path to the newly created directory that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix cannot be used to generate a candidate directory name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or {@code dir} does not exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access when creating the
+ * directory.
+ */
+ public static Path createTempDirectory(Path dir,
+ String prefix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempDirectory(dir, prefix, attrs);
+ }
+
+ /**
+ * Creates a new directory in the default temporary-file directory, using
+ * the given prefix and suffix to generate its name. The resulting {@code
+ * Path} is associated with the default {@code FileSystem}.
+ *
+ * <p> This method works in exactly the manner specified by {@link
+ * #createTempDirectory(Path,String,FileAttribute[])} method for the case
+ * that the {@code dir} parameter is the temporary-file directory.
+ *
+ * @param prefix
+ * the prefix string to be used in generating the directory's name;
+ * may be {@code null}
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @return the path to the newly created directory that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix cannot be used to generate a candidate directory name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or the temporary-file directory does not
+ * exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access when creating the
+ * directory.
+ */
+ public static Path createTempDirectory(String prefix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempDirectory(null, prefix, attrs);
+ }
+
+ /**
+ * Creates a symbolic link to a target <i>(optional operation)</i>.
+ *
+ * <p> The {@code target} parameter is the target of the link. It may be an
+ * {@link Path#isAbsolute absolute} or relative path and may not exist. When
+ * the target is a relative path then file system operations on the resulting
+ * link are relative to the path of the link.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * attributes} to set atomically when creating the link. Each attribute is
+ * identified by its {@link FileAttribute#name name}. If more than one attribute
+ * of the same name is included in the array then all but the last occurrence
+ * is ignored.
+ *
+ * <p> Where symbolic links are supported, but the underlying {@link FileStore}
+ * does not support symbolic links, then this may fail with an {@link
+ * IOException}. Additionally, some operating systems may require that the
+ * Java virtual machine be started with implementation specific privileges to
+ * create symbolic links, in which case this method may throw {@code IOException}.
+ *
+ * @param link
+ * the path of the symbolic link to create
+ * @param target
+ * the target of the symbolic link
+ * @param attrs
+ * the array of attributes to set atomically when creating the
+ * symbolic link
+ *
+ * @return the path to the symbolic link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links or the
+ * array contains an attribute that cannot be set atomically when
+ * creating the symbolic link
+ * @throws FileAlreadyExistsException
+ * if a file with the name already exists <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it denies {@link LinkPermission}<tt>("symbolic")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the path of the symbolic link.
+ */
+ public static Path createSymbolicLink(Path link, Path target,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ provider(link).createSymbolicLink(link, target, attrs);
+ return link;
+ }
+
+ /**
+ * Creates a new link (directory entry) for an existing file <i>(optional
+ * operation)</i>.
+ *
+ * <p> The {@code link} parameter locates the directory entry to create.
+ * The {@code existing} parameter is the path to an existing file. This
+ * method creates a new directory entry for the file so that it can be
+ * accessed using {@code link} as the path. On some file systems this is
+ * known as creating a "hard link". Whether the file attributes are
+ * maintained for the file or for each directory entry is file system
+ * specific and therefore not specified. Typically, a file system requires
+ * that all links (directory entries) for a file be on the same file system.
+ * Furthermore, on some platforms, the Java virtual machine may require to
+ * be started with implementation specific privileges to create hard links
+ * or to create links to directories.
+ *
+ * @param link
+ * the link (directory entry) to create
+ * @param existing
+ * a path to an existing file
+ *
+ * @return the path to the link (directory entry)
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support adding an existing file
+ * to a directory
+ * @throws FileAlreadyExistsException
+ * if the entry could not otherwise be created because a file of
+ * that name already exists <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it denies {@link LinkPermission}<tt>("hard")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to either the link or the
+ * existing file.
+ */
+ public static Path createLink(Path link, Path existing) throws IOException {
+ provider(link).createLink(link, existing);
+ return link;
+ }
+
+ /**
+ * Deletes a file.
+ *
+ * <p> An implementation may require to examine the file to determine if the
+ * file is a directory. Consequently this method may not be atomic with respect
+ * to other file system operations. If the file is a symbolic link then the
+ * symbolic link itself, not the final target of the link, is deleted.
+ *
+ * <p> If the file is a directory then the directory must be empty. In some
+ * implementations a directory has entries for special files or links that
+ * are created when the directory is created. In such implementations a
+ * directory is considered empty when only the special entries exist.
+ * This method can be used with the {@link #walkFileTree walkFileTree}
+ * method to delete a directory and all entries in the directory, or an
+ * entire <i>file-tree</i> where required.
+ *
+ * <p> On some operating systems it may not be possible to remove a file when
+ * it is open and in use by this Java virtual machine or other programs.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @throws NoSuchFileException
+ * if the file does not exist <i>(optional specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * if the file is a directory and could not otherwise be deleted
+ * because the directory is not empty <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String)} method
+ * is invoked to check delete access to the file
+ */
+ public static void delete(Path path) throws IOException {
+ provider(path).delete(path);
+ }
+
+ /**
+ * Deletes a file if it exists.
+ *
+ * <p> As with the {@link #delete(Path) delete(Path)} method, an
+ * implementation may need to examine the file to determine if the file is a
+ * directory. Consequently this method may not be atomic with respect to
+ * other file system operations. If the file is a symbolic link, then the
+ * symbolic link itself, not the final target of the link, is deleted.
+ *
+ * <p> If the file is a directory then the directory must be empty. In some
+ * implementations a directory has entries for special files or links that
+ * are created when the directory is created. In such implementations a
+ * directory is considered empty when only the special entries exist.
+ *
+ * <p> On some operating systems it may not be possible to remove a file when
+ * it is open and in use by this Java virtual machine or other programs.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @return {@code true} if the file was deleted by this method; {@code
+ * false} if the file could not be deleted because it did not
+ * exist
+ *
+ * @throws DirectoryNotEmptyException
+ * if the file is a directory and could not otherwise be deleted
+ * because the directory is not empty <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String)} method
+ * is invoked to check delete access to the file.
+ */
+ public static boolean deleteIfExists(Path path) throws IOException {
+ return provider(path).deleteIfExists(path);
+ }
+
+ // -- Copying and moving files --
+
+ /**
+ * Copy a file to a target file.
+ *
+ * <p> This method copies a file to the target file with the {@code
+ * options} parameter specifying how the copy is performed. By default, the
+ * copy fails if the target file already exists or is a symbolic link,
+ * except if the source and target are the {@link #isSameFile same} file, in
+ * which case the method completes without copying the file. File attributes
+ * are not required to be copied to the target file. If symbolic links are
+ * supported, and the file is a symbolic link, then the final target of the
+ * link is copied. If the file is a directory then it creates an empty
+ * directory in the target location (entries in the directory are not
+ * copied). This method can be used with the {@link #walkFileTree
+ * walkFileTree} method to copy a directory and all entries in the directory,
+ * or an entire <i>file-tree</i> where required.
+ *
+ * <p> The {@code options} parameter may include any of the following:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Option</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
+ * <td> If the target file exists, then the target file is replaced if it
+ * is not a non-empty directory. If the target file exists and is a
+ * symbolic link, then the symbolic link itself, not the target of
+ * the link, is replaced. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} </td>
+ * <td> Attempts to copy the file attributes associated with this file to
+ * the target file. The exact file attributes that are copied is platform
+ * and file system dependent and therefore unspecified. Minimally, the
+ * {@link BasicFileAttributes#lastModifiedTime last-modified-time} is
+ * copied to the target file if supported by both the source and target
+ * file store. Copying of file timestamps may result in precision
+ * loss. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} </td>
+ * <td> Symbolic links are not followed. If the file is a symbolic link,
+ * then the symbolic link itself, not the target of the link, is copied.
+ * It is implementation specific if file attributes can be copied to the
+ * new link. In other words, the {@code COPY_ATTRIBUTES} option may be
+ * ignored when copying a symbolic link. </td>
+ * </tr>
+ * </table>
+ *
+ * <p> An implementation of this interface may support additional
+ * implementation specific options.
+ *
+ * <p> Copying a file is not an atomic operation. If an {@link IOException}
+ * is thrown then it possible that the target file is incomplete or some of
+ * its file attributes have not been copied from the source file. When the
+ * {@code REPLACE_EXISTING} option is specified and the target file exists,
+ * then the target file is replaced. The check for the existence of the file
+ * and the creation of the new file may not be atomic with respect to other
+ * file system activities.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to copy a file into a directory, giving it the same file
+ * name as the source file:
+ * <pre>
+ * Path source = ...
+ * Path newdir = ...
+ * Files.copy(source, newdir.resolve(source.getFileName());
+ * </pre>
+ *
+ * @param source
+ * the path to the file to copy
+ * @param target
+ * the path to the target file (may be associated with a different
+ * provider to the source path)
+ * @param options
+ * options specifying how the copy should be done
+ *
+ * @return the path to the target file
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @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 source file, the
+ * {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+ * to check write access to the target file. If a symbolic link is
+ * copied the security manager is invoked to check {@link
+ * LinkPermission}{@code ("symbolic")}.
+ */
+ public static Path copy(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ FileSystemProvider provider = provider(source);
+ if (provider(target) == provider) {
+ // same provider
+ provider.copy(source, target, options);
+ } else {
+ // different providers
+ CopyMoveHelper.copyToForeignTarget(source, target, options);
+ }
+ return target;
+ }
+
+ /**
+ * Move or rename a file to a target file.
+ *
+ * <p> By default, this method attempts to move the file to the target
+ * file, failing if the target file exists except if the source and
+ * target are the {@link #isSameFile same} file, in which case this method
+ * has no effect. If the file is a symbolic link then the symbolic link
+ * itself, not the target of the link, is moved. This method may be
+ * invoked to move an empty directory. In some implementations a directory
+ * has entries for special files or links that are created when the
+ * directory is created. In such implementations a directory is considered
+ * empty when only the special entries exist. When invoked to move a
+ * directory that is not empty then the directory is moved if it does not
+ * require moving the entries in the directory. For example, renaming a
+ * directory on the same {@link FileStore} will usually not require moving
+ * the entries in the directory. When moving a directory requires that its
+ * entries be moved then this method fails (by throwing an {@code
+ * IOException}). To move a <i>file tree</i> may involve copying rather
+ * than moving directories and this can be done using the {@link
+ * #copy copy} method in conjunction with the {@link
+ * #walkFileTree Files.walkFileTree} utility method.
+ *
+ * <p> The {@code options} parameter may include any of the following:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Option</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
+ * <td> If the target file exists, then the target file is replaced if it
+ * is not a non-empty directory. If the target file exists and is a
+ * symbolic link, then the symbolic link itself, not the target of
+ * the link, is replaced. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} </td>
+ * <td> The move is performed as an atomic file system operation and all
+ * other options are ignored. If the target file exists then it is
+ * implementation specific if the existing file is replaced or this method
+ * fails by throwing an {@link IOException}. If the move cannot be
+ * performed as an atomic file system operation then {@link
+ * AtomicMoveNotSupportedException} is thrown. This can arise, for
+ * example, when the target location is on a different {@code FileStore}
+ * and would require that the file be copied, or target location is
+ * associated with a different provider to this object. </td>
+ * </table>
+ *
+ * <p> An implementation of this interface may support additional
+ * implementation specific options.
+ *
+ * <p> Where the move requires that the file be copied then the {@link
+ * BasicFileAttributes#lastModifiedTime last-modified-time} is copied to the
+ * new file. An implementation may also attempt to copy other file
+ * attributes but is not required to fail if the file attributes cannot be
+ * copied. When the move is performed as a non-atomic operation, and a {@code
+ * IOException} is thrown, then the state of the files is not defined. The
+ * original file and the target file may both exist, the target file may be
+ * incomplete or some of its file attributes may not been copied from the
+ * original file.
+ *
+ * <p> <b>Usage Examples:</b>
+ * Suppose we want to rename a file to "newname", keeping the file in the
+ * same directory:
+ * <pre>
+ * Path source = ...
+ * Files.move(source, source.resolveSibling("newname"));
+ * </pre>
+ * Alternatively, suppose we want to move a file to new directory, keeping
+ * the same file name, and replacing any existing file of that name in the
+ * directory:
+ * <pre>
+ * Path source = ...
+ * Path newdir = ...
+ * Files.move(source, newdir.resolve(source.getFileName()), REPLACE_EXISTING);
+ * </pre>
+ *
+ * @param source
+ * the path to the file to move
+ * @param target
+ * the path to the target file (may be associated with a different
+ * provider to the source path)
+ * @param options
+ * options specifying how the move should be done
+ *
+ * @return the path to the target file
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i>
+ * @throws AtomicMoveNotSupportedException
+ * if the options array contains the {@code ATOMIC_MOVE} option but
+ * the file cannot be moved as an atomic file system operation.
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to both the source and
+ * target file.
+ */
+ public static Path move(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ FileSystemProvider provider = provider(source);
+ if (provider(target) == provider) {
+ // same provider
+ provider.move(source, target, options);
+ } else {
+ // different providers
+ CopyMoveHelper.moveToForeignTarget(source, target, options);
+ }
+ return target;
+ }
+
+ // -- Miscellenous --
+
+ /**
+ * Reads the target of a symbolic link <i>(optional operation)</i>.
+ *
+ * <p> If the file system supports <a href="package-summary.html#links">symbolic
+ * links</a> then this method is used to read the target of the link, failing
+ * if the file is not a symbolic link. The target of the link need not exist.
+ * The returned {@code Path} object will be associated with the same file
+ * system as {@code link}.
+ *
+ * @param link
+ * the path to the symbolic link
+ *
+ * @return a {@code Path} object representing the target of the link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links
+ * @throws NotLinkException
+ * if the target could otherwise not be read because the file
+ * is not a symbolic link <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it checks that {@code FilePermission} has been
+ * granted with the "{@code readlink}" action to read the link.
+ */
+ public static Path readSymbolicLink(Path link) throws IOException {
+ return provider(link).readSymbolicLink(link);
+ }
+
+ /**
+ * Returns the {@link FileStore} representing the file store where a file
+ * is located.
+ *
+ * <p> Once a reference to the {@code FileStore} is obtained it is
+ * implementation specific if operations on the returned {@code FileStore},
+ * or {@link FileStoreAttributeView} objects obtained from it, continue
+ * to depend on the existence of the file. In particular the behavior is not
+ * defined for the case that the file is deleted or moved to a different
+ * file store.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the file store where the file is stored
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @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, and in
+ * addition it checks {@link RuntimePermission}<tt>
+ * ("getFileStoreAttributes")</tt>
+ */
+ public static FileStore getFileStore(Path path) throws IOException {
+ return provider(path).getFileStore(path);
+ }
+
+ /**
+ * Tests if two paths locate the same file.
+ *
+ * <p> If both {@code Path} objects are {@link Path#equals(Object) equal}
+ * then this method returns {@code true} without checking if the file exists.
+ * If the two {@code Path} objects are associated with different providers
+ * then this method returns {@code false}. Otherwise, this method checks if
+ * both {@code Path} objects locate the same file, and depending on the
+ * implementation, may require to open or access both files.
+ *
+ * <p> If the file system and files remain static, then this method implements
+ * an equivalence relation for non-null {@code Paths}.
+ * <ul>
+ * <li>It is <i>reflexive</i>: for {@code Path} {@code f},
+ * {@code isSameFile(f,f)} should return {@code true}.
+ * <li>It is <i>symmetric</i>: for two {@code Paths} {@code f} and {@code g},
+ * {@code isSameFile(f,g)} will equal {@code isSameFile(g,f)}.
+ * <li>It is <i>transitive</i>: for three {@code Paths}
+ * {@code f}, {@code g}, and {@code h}, if {@code isSameFile(f,g)} returns
+ * {@code true} and {@code isSameFile(g,h)} returns {@code true}, then
+ * {@code isSameFile(g,h)} will return return {@code true}.
+ * </ul>
+ *
+ * @param path
+ * one path to the file
+ * @param path2
+ * the other path
+ *
+ * @return {@code true} if, and only if, the two paths locate the same file
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @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 both files.
+ *
+ * @see java.nio.file.attribute.BasicFileAttributes#fileKey
+ */
+ public static boolean isSameFile(Path path, Path path2) throws IOException {
+ return provider(path).isSameFile(path, path2);
+ }
+
+ /**
+ * Tells whether or not a file is considered <em>hidden</em>. The exact
+ * definition of hidden is platform or provider dependent. On UNIX for
+ * example a file is considered to be hidden if its name begins with a
+ * period character ('.'). On Windows a file is considered hidden if it
+ * isn't a directory and the DOS {@link DosFileAttributes#isHidden hidden}
+ * attribute is set.
+ *
+ * <p> Depending on the implementation this method may require to access
+ * the file system to determine if the file is considered hidden.
+ *
+ * @param path
+ * the path to the file to test
+ *
+ * @return {@code true} if the file is considered hidden
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @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.
+ */
+ public static boolean isHidden(Path path) throws IOException {
+ return provider(path).isHidden(path);
+ }
+
// lazy loading of default and installed file type detectors
- private static class DefaultFileTypeDetectorHolder {
+ private static class FileTypeDetectors{
static final FileTypeDetector defaultFileTypeDetector =
sun.nio.fs.DefaultFileTypeDetector.create();
static final List<FileTypeDetector> installeDetectors =
@@ -54,7 +1484,7 @@
return AccessController
.doPrivileged(new PrivilegedAction<List<FileTypeDetector>>() {
@Override public List<FileTypeDetector> run() {
- List<FileTypeDetector> list = new ArrayList<FileTypeDetector>();
+ List<FileTypeDetector> list = new ArrayList<>();
ServiceLoader<FileTypeDetector> loader = ServiceLoader
.load(FileTypeDetector.class, ClassLoader.getSystemClassLoader());
for (FileTypeDetector detector: loader) {
@@ -100,34 +1530,949 @@
* Message Bodies</i></a>. The string is guaranteed to be parsable according
* to the grammar in the RFC.
*
- * @param file
- * The file reference
+ * @param path
+ * the path to the file to probe
*
* @return The content type of the file, or {@code null} if the content
* type cannot be determined
*
* @throws IOException
- * If an I/O error occurs
+ * if an I/O error occurs
* @throws SecurityException
* If a security manager is installed and it denies an unspecified
* permission required by a file type detector implementation.
*/
- public static String probeContentType(FileRef file)
+ public static String probeContentType(Path path)
throws IOException
{
// try installed file type detectors
- for (FileTypeDetector detector: DefaultFileTypeDetectorHolder.installeDetectors) {
- String result = detector.probeContentType(file);
+ for (FileTypeDetector detector: FileTypeDetectors.installeDetectors) {
+ String result = detector.probeContentType(path);
if (result != null)
return result;
}
// fallback to default
- return DefaultFileTypeDetectorHolder.defaultFileTypeDetector
- .probeContentType(file);
+ return FileTypeDetectors.defaultFileTypeDetector.probeContentType(path);
+ }
+
+ // -- File Attributes --
+
+ /**
+ * Returns a file attribute view of a given type.
+ *
+ * <p> A file attribute view provides a read-only or updatable view of a
+ * set of file attributes. This method is intended to be used where the file
+ * attribute view defines type-safe methods to read or update the file
+ * attributes. The {@code type} parameter is the type of the attribute view
+ * required and the method returns an instance of that type if supported.
+ * The {@link BasicFileAttributeView} type supports access to the basic
+ * attributes of a file. Invoking this method to select a file attribute
+ * view of that type will always return an instance of that class.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled by the resulting file attribute view for the case that the
+ * file is a symbolic link. By default, symbolic links are followed. If the
+ * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then
+ * symbolic links are not followed. This option is ignored by implementations
+ * that do not support symbolic links.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want read or set a file's ACL, if supported:
+ * <pre>
+ * Path path = ...
+ * AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
+ * if (view != null) {
+ * List<AclEntry> acl = view.getAcl();
+ * :
+ * }
+ * </pre>
+ *
+ *
+ * @param path
+ * the path to the file
+ * @param type
+ * the {@code Class} object corresponding to the file attribute view
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a file attribute view of the specified type, or {@code null} if
+ * the attribute view type is not available
+ */
+ public static <V extends FileAttributeView> V getFileAttributeView(Path path,
+ Class<V> type,
+ LinkOption... options)
+ {
+ return provider(path).getFileAttributeView(path, type, options);
+ }
+
+ /**
+ * Reads a file's attributes as a bulk operation.
+ *
+ * <p> The {@code type} parameter is the type of the attributes required
+ * and this method returns an instance of that type if supported. All
+ * implementations support a basic set of file attributes and so invoking
+ * this method with a {@code type} parameter of {@code
+ * BasicFileAttributes.class} will not throw {@code
+ * UnsupportedOperationException}.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> It is implementation specific if all file attributes are read as an
+ * atomic operation with respect to other file system operations.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to read a file's attributes in bulk:
+ * <pre>
+ * Path path = ...
+ * BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
+ * </pre>
+ * Alternatively, suppose we want to read file's POSIX attributes without
+ * following symbolic links:
+ * <pre>
+ * PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class, NOFOLLOW_LINKS);
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param type
+ * the {@code Class} of the file attributes required
+ * to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the file attributes
+ *
+ * @throws UnsupportedOperationException
+ * if an attributes of the given type are not supported
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file. If this
+ * method is invoked to read security sensitive attributes then the
+ * security manager may be invoke to check for additional permissions.
+ */
+ public static <A extends BasicFileAttributes> A readAttributes(Path path,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ return provider(path).readAttributes(path, type, options);
+ }
+
+ /**
+ * Sets the value of a file attribute.
+ *
+ * <p> The {@code attribute} parameter identifies the attribute to be set
+ * and takes the form:
+ * <blockquote>
+ * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
+ * </blockquote>
+ * where square brackets [...] delineate an optional component and the
+ * character {@code ':'} stands for itself.
+ *
+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+ * FileAttributeView} that identifies a set of file attributes. If not
+ * specified then it defaults to {@code "basic"}, the name of the file
+ * attribute view that identifies the basic set of file attributes common to
+ * many file systems. <i>attribute-name</i> is the name of the attribute
+ * within the set.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is set. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to set the DOS "hidden" attribute:
+ * <pre>
+ * Path path = ...
+ * Files.setAttribute(path, "dos:hidden", true);
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param attribute
+ * the attribute to set
+ * @param value
+ * the attribute value
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the {@code path} parameter
+ *
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available or it does not support
+ * updating the attribute
+ * @throws IllegalArgumentException
+ * if the attribute value is of the correct type but has an
+ * inappropriate value
+ * @throws ClassCastException
+ * if the attribute value is not of the expected type or is a
+ * collection containing elements that are not of the expected
+ * type
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file. If this method is invoked
+ * to set security sensitive attributes then the security manager
+ * may be invoked to check for additional permissions.
+ */
+ public static Path setAttribute(Path path, String attribute, Object value,
+ LinkOption... options)
+ throws IOException
+ {
+ provider(path).setAttribute(path, attribute, value, options);
+ return path;
+ }
+
+ /**
+ * Reads the value of a file attribute.
+ *
+ * <p> The {@code attribute} parameter identifies the attribute to be read
+ * and takes the form:
+ * <blockquote>
+ * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
+ * </blockquote>
+ * where square brackets [...] delineate an optional component and the
+ * character {@code ':'} stands for itself.
+ *
+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+ * FileAttributeView} that identifies a set of file attributes. If not
+ * specified then it defaults to {@code "basic"}, the name of the file
+ * attribute view that identifies the basic set of file attributes common to
+ * many file systems. <i>attribute-name</i> is the name of the attribute.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we require the user ID of the file owner on a system that
+ * supports a "{@code unix}" view:
+ * <pre>
+ * Path path = ...
+ * int uid = (Integer)Files.getAttribute(path, "unix:uid");
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param attribute
+ * the attribute to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the attribute value or {@code null} if the attribute view
+ * is not available or it does not support reading the attribute
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file. If this method is invoked
+ * to read security sensitive attributes then the security manager
+ * may be invoked to check for additional permissions.
+ */
+ public static Object getAttribute(Path path, String attribute,
+ LinkOption... options)
+ throws IOException
+ {
+ // only one attribute should be read
+ if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0)
+ return null;
+ Map<String,Object> map = readAttributes(path, attribute, options);
+ String name;
+ int pos = attribute.indexOf(':');
+ if (pos == -1) {
+ name = attribute;
+ } else {
+ name = (pos == attribute.length()) ? "" : attribute.substring(pos+1);
+ }
+ return map.get(name);
+ }
+
+ /**
+ * Reads a set of file attributes as a bulk operation.
+ *
+ * <p> The {@code attributes} parameter identifies the attributes to be read
+ * and takes the form:
+ * <blockquote>
+ * [<i>view-name</i><b>:</b>]<i>attribute-list</i>
+ * </blockquote>
+ * where square brackets [...] delineate an optional component and the
+ * character {@code ':'} stands for itself.
+ *
+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+ * FileAttributeView} that identifies a set of file attributes. If not
+ * specified then it defaults to {@code "basic"}, the name of the file
+ * attribute view that identifies the basic set of file attributes common to
+ * many file systems.
+ *
+ * <p> The <i>attribute-list</i> component is a comma separated list of
+ * zero or more names of attributes to read. If the list contains the value
+ * {@code "*"} then all attributes are read. Attributes that are not supported
+ * are ignored and will not be present in the returned map. It is
+ * implementation specific if all attributes are read as an atomic operation
+ * with respect to other file system operations.
+ *
+ * <p> The following examples demonstrate possible values for the {@code
+ * attributes} parameter:
+ *
+ * <blockquote>
+ * <table border="0">
+ * <tr>
+ * <td> {@code "*"} </td>
+ * <td> Read all {@link BasicFileAttributes basic-file-attributes}. </td>
+ * </tr>
+ * <tr>
+ * <td> {@code "size,lastModifiedTime,lastAccessTime"} </td>
+ * <td> Reads the file size, last modified time, and last access time
+ * attributes. </td>
+ * </tr>
+ * <tr>
+ * <td> {@code "posix:*"} </td>
+ * <td> Read all {@link PosixFileAttributes POSIX-file-attributes}. </td>
+ * </tr>
+ * <tr>
+ * <td> {@code "posix:permissions,owner,size"} </td>
+ * <td> Reads the POSX file permissions, owner, and file size. </td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * @param path
+ * the path to the file
+ * @param attributes
+ * the attributes to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a map of the attributes returned; may be empty. The map's keys
+ * are the attribute names, its values are the attribute values
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file. If this method is invoked
+ * to read security sensitive attributes then the security manager
+ * may be invoke to check for additional permissions.
+ */
+ public static Map<String,Object> readAttributes(Path path, String attributes,
+ LinkOption... options)
+ throws IOException
+ {
+ return provider(path).readAttributes(path, attributes, options);
+ }
+
+ /**
+ * Returns a file's POSIX file permissions.
+ *
+ * <p> The {@code path} parameter is associated with a {@code FileSystem}
+ * that supports the {@link PosixFileAttributeView}. This attribute view
+ * provides access to file attributes commonly associated with files on file
+ * systems used by operating systems that implement the Portable Operating
+ * System Interface (POSIX) family of standards.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * @param path
+ * the path to the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the file permissions
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * PosixFileAttributeView}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ */
+ public static Set<PosixFilePermission> getPosixFilePermissions(Path path,
+ LinkOption... options)
+ throws IOException
+ {
+ return readAttributes(path, PosixFileAttributes.class, options).permissions();
+ }
+
+ /**
+ * Sets a file's POSIX permissions.
+ *
+ * <p> The {@code path} parameter is associated with a {@code FileSystem}
+ * that supports the {@link PosixFileAttributeView}. This attribute view
+ * provides access to file attributes commonly associated with files on file
+ * systems used by operating systems that implement the Portable Operating
+ * System Interface (POSIX) family of standards.
+ *
+ * @param path
+ * A file reference that locates the file
+ * @param perms
+ * The new set of permissions
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * PosixFileAttributeView}
+ * @throws ClassCastException
+ * if the sets contains elements that are not of type {@code
+ * PosixFilePermission}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file.
+ */
+ public static Path setPosixFilePermissions(Path path,
+ Set<PosixFilePermission> perms)
+ throws IOException
+ {
+ PosixFileAttributeView view =
+ getFileAttributeView(path, PosixFileAttributeView.class);
+ if (view == null)
+ throw new UnsupportedOperationException();
+ view.setPermissions(perms);
+ return path;
+ }
+
+ /**
+ * Returns the owner of a file.
+ *
+ * <p> The {@code path} parameter is associated with a file system that
+ * supports {@link FileOwnerAttributeView}. This file attribute view provides
+ * access to a file attribute that is the owner of the file.
+ *
+ * @param path
+ * A file reference that locates the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return A user principal representing the owner of the file
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * FileOwnerAttributeView}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ */
+ public static UserPrincipal getOwner(Path path, LinkOption... options) throws IOException {
+ FileOwnerAttributeView view =
+ getFileAttributeView(path, FileOwnerAttributeView.class, options);
+ if (view == null)
+ throw new UnsupportedOperationException();
+ return view.getOwner();
}
/**
+ * Updates the file owner.
+ *
+ * <p> The {@code path} parameter is associated with a file system that
+ * supports {@link FileOwnerAttributeView}. This file attribute view provides
+ * access to a file attribute that is the owner of the file.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to make "joe" the owner of a file:
+ * <pre>
+ * Path path = ...
+ * UserPrincipalLookupService lookupService =
+ * provider(path).getUserPrincipalLookupService();
+ * UserPrincipal joe = lookupService.lookupPrincipalByName("joe");
+ * Files.setOwner(path, joe);
+ * </pre>
+ *
+ * @param path
+ * A file reference that locates the file
+ * @param owner
+ * The new file owner
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * FileOwnerAttributeView}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file.
+ *
+ * @see FileSystem#getUserPrincipalLookupService
+ * @see java.nio.file.attribute.UserPrincipalLookupService
+ */
+ public static Path setOwner(Path path, UserPrincipal owner)
+ throws IOException
+ {
+ FileOwnerAttributeView view =
+ getFileAttributeView(path, FileOwnerAttributeView.class);
+ if (view == null)
+ throw new UnsupportedOperationException();
+ view.setOwner(owner);
+ return path;
+ }
+
+ /**
+ * Tests whether a file is a symbolic link.
+ *
+ * <p> Where is it required to distinguish an I/O exception from the case
+ * that the file is not a symbolic link then the file attributes can be
+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
+ * readAttributes} method and the file type tested with the {@link
+ * BasicFileAttributes#isSymbolicLink} method.
+ *
+ * @return {@code true} if the file is a symbolic link; {@code false} if
+ * the file does not exist, is not a symbolic link, or it cannot
+ * be determined if the file is symbolic link or not.
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file.
+ */
+ public static boolean isSymbolicLink(Path path) {
+ try {
+ return readAttributes(path,
+ BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS).isSymbolicLink();
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+
+ /**
+ * Tests whether a file is a directory.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> Where is it required to distinguish an I/O exception from the case
+ * that the file is not a directory then the file attributes can be
+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
+ * readAttributes} method and the file type tested with the {@link
+ * BasicFileAttributes#isDirectory} method.
+ *
+ * @param path
+ * the path to the file to test
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return {@code true} if the file is a directory; {@code false} if
+ * the file does not exist, is not a directory, or it cannot
+ * be determined if the file is directory or not.
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file.
+ */
+ public static boolean isDirectory(Path path, LinkOption... options) {
+ try {
+ return readAttributes(path, BasicFileAttributes.class, options).isDirectory();
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+
+ /**
+ * Tests whether a file is a regular file with opaque content.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> Where is it required to distinguish an I/O exception from the case
+ * that the file is not a regular file then the file attributes can be
+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
+ * readAttributes} method and the file type tested with the {@link
+ * BasicFileAttributes#isRegularFile} method.
+ *
+ * @param path
+ * the path to the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return {@code true} if the file is a regular file; {@code false} if
+ * the file does not exist, is not a direcregular filetory, or it
+ * cannot be determined if the file is regular file or not.
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file.
+ */
+ public static boolean isRegularFile(Path path, LinkOption... options) {
+ try {
+ return readAttributes(path, BasicFileAttributes.class, options).isRegularFile();
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns a file's last modified time.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * @param path
+ * the path to the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a {@code FileTime} representing the time the file was last
+ * modified, or an implementation specific default when a time
+ * stamp to indicate the time of last modification is not supported
+ * by the file system
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file.
+ *
+ * @see BasicFileAttributes#lastModifiedTime
+ */
+ public static FileTime getLastModifiedTime(Path path, LinkOption... options)
+ throws IOException
+ {
+ return readAttributes(path, BasicFileAttributes.class, options).lastModifiedTime();
+ }
+
+ /**
+ * Updates a file's last modified time attribute. The file time is converted
+ * to the epoch and precision supported by the file system. Converting from
+ * finer to coarser granularities result in precision loss. The behavior of
+ * this method when attempting to set the last modified time when it is not
+ * supported by the file system or is outside the range supported by the
+ * underlying file store is not defined. It may or not fail by throwing an
+ * {@code IOException}.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to set the last modified time to the current time:
+ * <pre>
+ * Path path = ...
+ * FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+ * Files.setLastModifiedTime(path, now);
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param time
+ * the new last modified time
+ *
+ * @return the file
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, the security manager's {@link
+ * SecurityManager#checkWrite(String) checkWrite} method is invoked
+ * to check write access to file
+ *
+ * @see BasicFileAttributeView#setTimes
+ */
+ public static Path setLastModifiedTime(Path path, FileTime time)
+ throws IOException
+ {
+ getFileAttributeView(path, BasicFileAttributeView.class)
+ .setTimes(time, null, null);
+ return path;
+ }
+
+ /**
+ * Returns the size of a file (in bytes). The size may differ from the
+ * actual size on the file system due to compression, support for sparse
+ * files, or other reasons. The size of files that are not {@link
+ * #isRegularFile regular} files is implementation specific and
+ * therefore unspecified.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the file size, in bytes
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file.
+ *
+ * @see BasicFileAttributes#size
+ */
+ public static long size(Path path) throws IOException {
+ return readAttributes(path, BasicFileAttributes.class).size();
+ }
+
+ // -- Accessibility --
+
+ /**
+ * Returns {@code false} if NOFOLLOW_LINKS is present.
+ */
+ private static boolean followLinks(LinkOption... options) {
+ boolean followLinks = true;
+ for (LinkOption opt: options) {
+ if (opt == LinkOption.NOFOLLOW_LINKS) {
+ followLinks = false;
+ continue;
+ }
+ if (opt == null)
+ throw new NullPointerException();
+ throw new AssertionError("Should not get here");
+ }
+ return followLinks;
+ }
+
+ /**
+ * Tests whether a file exists.
+ *
+ * <p> The {@code options} parameter may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> Note that the result of this method is immediately outdated. If this
+ * method indicates the file exists then there is no guarantee that a
+ * subsequence access will succeed. Care should be taken when using this
+ * method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to test
+ * @param options
+ * options indicating how symbolic links are handled
+ * .
+ * @return {@code true} if the file exists; {@code false} if the file does
+ * not exist or its existence cannot be determined.
+ *
+ * @throws SecurityException
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String)} is invoked to check
+ * read access to the file.
+ *
+ * @see #notExists
+ */
+ public static boolean exists(Path path, LinkOption... options) {
+ try {
+ if (followLinks(options)) {
+ provider(path).checkAccess(path);
+ } else {
+ // attempt to read attributes without following links
+ readAttributes(path, BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS);
+ }
+ // file exists
+ return true;
+ } catch (IOException x) {
+ // does not exist or unable to determine if file exists
+ return false;
+ }
+
+ }
+
+ /**
+ * Tests whether the file located by this path does not exist. This method
+ * is intended for cases where it is required to take action when it can be
+ * confirmed that a file does not exist.
+ *
+ * <p> The {@code options} parameter may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> Note that this method is not the complement of the {@link #exists
+ * exists} method. Where it is not possible to determine if a file exists
+ * or not then both methods return {@code false}. As with the {@code exists}
+ * method, the result of this method is immediately outdated. If this
+ * method indicates the file does exist then there is no guarantee that a
+ * subsequence attempt to create the file will succeed. Care should be taken
+ * when using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to test
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return {@code true} if the file does not exist; {@code false} if the
+ * file exists or its existence cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String)} is invoked to check
+ * read access to the file.
+ */
+ public static boolean notExists(Path path, LinkOption... options) {
+ try {
+ if (followLinks(options)) {
+ provider(path).checkAccess(path);
+ } else {
+ // attempt to read attributes without following links
+ readAttributes(path, BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS);
+ }
+ // file exists
+ return false;
+ } catch (NoSuchFileException x) {
+ // file confirmed not to exist
+ return true;
+ } catch (IOException x) {
+ return false;
+ }
+ }
+
+ /**
+ * Used by isReadbale, isWritable, isExecutable to test access to a file.
+ */
+ private static boolean isAccessible(Path path, AccessMode... modes) {
+ try {
+ provider(path).checkAccess(path, modes);
+ return true;
+ } catch (IOException x) {
+ return false;
+ }
+ }
+
+ /**
+ * Tests whether a file is readable. This method checks that a file exists
+ * and that this Java virtual machine has appropriate privileges that would
+ * allow it open the file for reading. Depending on the implementation, this
+ * method may require to read file permissions, access control lists, or
+ * other file attributes in order to check the effective access to the file.
+ * Consequently, this method may not be atomic with respect to other file
+ * system operations.
+ *
+ * <p> Note that the result of this method is immediately outdated, there is
+ * no guarantee that a subsequent attempt to open the file for reading will
+ * succeed (or even that it will access the same file). Care should be taken
+ * when using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to check
+ *
+ * @return {@code true} if the file exists and is readable; {@code false}
+ * if the file does not exist, read access would be denied because
+ * the Java virtual machine has insufficient privileges, or access
+ * cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * is invoked to check read access to the file.
+ */
+ public static boolean isReadable(Path path) {
+ return isAccessible(path, AccessMode.READ);
+ }
+
+ /**
+ * Tests whether a file is writable. This method checks that a file exists
+ * and that this Java virtual machine has appropriate privileges that would
+ * allow it open the file for writing. Depending on the implementation, this
+ * method may require to read file permissions, access control lists, or
+ * other file attributes in order to check the effective access to the file.
+ * Consequently, this method may not be atomic with respect to other file
+ * system operations.
+ *
+ * <p> Note that result of this method is immediately outdated, there is no
+ * guarantee that a subsequent attempt to open the file for writing will
+ * succeed (or even that it will access the same file). Care should be taken
+ * when using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to check
+ *
+ * @return {@code true} if the file exists and is writable; {@code false}
+ * if the file does not exist, write access would be denied because
+ * the Java virtual machine has insufficient privileges, or access
+ * cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * is invoked to check write access to the file.
+ */
+ public static boolean isWritable(Path path) {
+ return isAccessible(path, AccessMode.WRITE);
+ }
+
+ /**
+ * Tests whether a file is executable. This method checks that a file exists
+ * and that this Java virtual machine has appropriate privileges to {@link
+ * Runtime#exec execute} the file. The semantics may differ when checking
+ * access to a directory. For example, on UNIX systems, checking for
+ * execute access checks that the Java virtual machine has permission to
+ * search the directory in order to access file or subdirectories.
+ *
+ * <p> Depending on the implementation, this method may require to read file
+ * permissions, access control lists, or other file attributes in order to
+ * check the effective access to the file. Consequently, this method may not
+ * be atomic with respect to other file system operations.
+ *
+ * <p> Note that the result of this method is immediately outdated, there is
+ * no guarantee that a subsequent attempt to execute the file will succeed
+ * (or even that it will access the same file). Care should be taken when
+ * using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to check
+ *
+ * @return {@code true} if the file exists and is executable; {@code false}
+ * if the file does not exist, execute access would be denied because
+ * the Java virtual machine has insufficient privileges, or access
+ * cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkExec(String)
+ * checkExec} is invoked to check execute access to the file.
+ */
+ public static boolean isExecutable(Path path) {
+ return isAccessible(path, AccessMode.EXECUTE);
+ }
+
+ // -- Recursive operations --
+
+ /**
* Walks a file tree.
*
* <p> This method walks a file tree rooted at a given starting file. The
@@ -139,7 +2484,7 @@
* an uncaught error, or runtime exception, then the traversal is terminated
* and the error or exception is propagated to the caller of this method.
*
- * <p> For each file encountered this method attempts to gets its {@link
+ * <p> For each file encountered this method attempts to read its {@link
* java.nio.file.attribute.BasicFileAttributes}. If the file is not a
* directory then the {@link FileVisitor#visitFile visitFile} method is
* invoked with the file attributes. If the file attributes cannot be read,
@@ -174,7 +2519,7 @@
* 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 Path#isSameFile
+ * 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, and the
* {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
@@ -197,25 +2542,27 @@
* that file (or directory).
*
* @param start
- * The starting file
+ * the starting file
* @param options
- * Options to configure the traversal
+ * options to configure the traversal
* @param maxDepth
- * The maximum number of directory levels to visit
+ * the maximum number of directory levels to visit
* @param visitor
- * The file visitor to invoke for each file
+ * the file visitor to invoke for each file
+ *
+ * @return the starting file
*
* @throws IllegalArgumentException
- * If the {@code maxDepth} parameter is negative
+ * 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 by a visitor method
+ * if an I/O error is thrown by a visitor method
*/
- public static void walkFileTree(Path start,
+ public static Path walkFileTree(Path start,
Set<FileVisitOption> options,
int maxDepth,
FileVisitor<? super Path> visitor)
@@ -224,6 +2571,7 @@
if (maxDepth < 0)
throw new IllegalArgumentException("'maxDepth' is negative");
new FileTreeWalker(options, visitor, maxDepth).walk(start);
+ return start;
}
/**
@@ -234,11 +2582,15 @@
* <blockquote><pre>
* walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, visitor)
* </pre></blockquote>
+ * In other words, it does not follow symbolic links, and visits all levels
+ * of the file level.
*
* @param start
- * The starting file
+ * the starting file
* @param visitor
- * The file visitor to invoke for each file
+ * the file visitor to invoke for each file
+ *
+ * @return the starting file
*
* @throws SecurityException
* If the security manager denies access to the starting file.
@@ -246,118 +2598,511 @@
* SecurityManager#checkRead(String) checkRead} method is invoked
* to check read access to the directory.
* @throws IOException
- * If an I/O error is thrown by a visitor method
+ * if an I/O error is thrown by a visitor method
*/
- public static void walkFileTree(Path start, FileVisitor<? super Path> visitor)
+ public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
+ throws IOException
+ {
+ return walkFileTree(start,
+ EnumSet.noneOf(FileVisitOption.class),
+ Integer.MAX_VALUE,
+ visitor);
+ }
+
+
+ // -- Utility methods for simple usages --
+
+ // buffer size used for reading and writing
+ private static final int BUFFER_SIZE = 8192;
+
+ /**
+ * Opens a file for reading, returning a {@code BufferedReader} that may be
+ * used to read text from the file in an efficient manner. Bytes from the
+ * file are decoded into characters using the specified charset. Reading
+ * commences at the beginning of the file.
+ *
+ * <p> The {@code Reader} methods that read from the file throw {@code
+ * IOException} if a malformed or unmappable byte sequence is read.
+ *
+ * @param path
+ * the path to the file
+ * @param cs
+ * the charset to use for decoding
+ *
+ * @return a new buffered reader, with default buffer size, to read text
+ * from the file
+ *
+ * @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
+ */
+ public static BufferedReader newBufferedReader(Path path, Charset cs)
throws IOException
{
- walkFileTree(start,
- EnumSet.noneOf(FileVisitOption.class),
- Integer.MAX_VALUE,
- visitor);
+ CharsetDecoder decoder = cs.newDecoder();
+ Reader reader = new InputStreamReader(newInputStream(path), decoder);
+ return new BufferedReader(reader);
+ }
+
+ /**
+ * Opens or creates a file for writing, returning a {@code BufferedWriter}
+ * that may be used to write text to the file in an efficient manner.
+ * The {@code options} parameter specifies how the the file is created or
+ * opened. If no options are present then this method works as if the {@link
+ * StandardOpenOption#CREATE CREATE}, {@link
+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+ * opens the file for writing, creating the file if it doesn't exist, or
+ * initially truncating an existing {@link #isRegularFile regular-file} to
+ * a size of {@code 0} if it exists.
+ *
+ * <p> The {@code Writer} methods to write text throw {@code IOException}
+ * if the text cannot be encoded using the specified charset.
+ *
+ * @param path
+ * the path to the file
+ * @param cs
+ * the charset to use for encoding
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new buffered writer, with default buffer size, to write text
+ * to the file
+ *
+ * @throws IOException
+ * if an I/O error occurs opening or creating the file
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ *
+ * @see #write(Path,Iterable,Charset,OpenOption[])
+ */
+ public static BufferedWriter newBufferedWriter(Path path, Charset cs,
+ OpenOption... options)
+ throws IOException
+ {
+ CharsetEncoder encoder = cs.newEncoder();
+ Writer writer = new OutputStreamWriter(newOutputStream(path, options), encoder);
+ return new BufferedWriter(writer);
+ }
+
+ /**
+ * Reads all bytes from an input stream and writes them to an output stream.
+ */
+ private static long copy(InputStream source, OutputStream sink)
+ throws IOException
+ {
+ long nread = 0L;
+ byte[] buf = new byte[BUFFER_SIZE];
+ int n;
+ while ((n = source.read(buf)) > 0) {
+ sink.write(buf, 0, n);
+ nread += n;
+ }
+ return nread;
}
/**
- * Creates a directory by creating all nonexistent parent directories first.
+ * Copies all bytes from an input stream to a file. On return, the input
+ * stream will be at end of stream.
+ *
+ * <p> By default, the copy fails if the target file already exists or is a
+ * symbolic link. If the {@link StandardCopyOption#REPLACE_EXISTING
+ * REPLACE_EXISTING} option is specified, and the target file already exists,
+ * then it is replaced if it is not a non-empty directory. If the target
+ * file exists and is a symbolic link, then the symbolic link is replaced.
+ * In this release, the {@code REPLACE_EXISTING} option is the only option
+ * required to be supported by this method. Additional options may be
+ * supported in future releases.
*
- * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
- * file-attributes} to set atomically when creating the nonexistent
- * directories. Each file attribute is identified by its {@link
- * FileAttribute#name name}. If more than one attribute of the same name is
- * included in the array then all but the last occurrence is ignored.
+ * <p> If an I/O error occurs reading from the input stream or writing to
+ * the file, then it may do so after the target file has been created and
+ * after some bytes have been read or written. Consequently the input
+ * stream may not be at end of stream and may be in an inconsistent state.
+ * It is strongly recommended that the input stream be promptly closed if an
+ * I/O error occurs.
+ *
+ * <p> This method may block indefinitely reading from the input stream (or
+ * writing to the file). The behavior for the case that the input stream is
+ * <i>asynchronously closed</i> or the thread interrupted during the copy is
+ * highly input stream and file system provider specific and therefore not
+ * specified.
*
- * <p> If this method fails, then it may do so after creating some, but not
- * all, of the parent directories.
+ * <p> <b>Usage example</b>: Suppose we want to capture a web page and save
+ * it to a file:
+ * <pre>
+ * Path path = ...
+ * URI u = URI.create("http://java.sun.com/");
+ * try (InputStream in = u.toURL().openStream()) {
+ * Files.copy(in, path);
+ * }
+ * </pre>
*
- * @param dir
- * the directory to create
+ * @param in
+ * the input stream to read from
+ * @param target
+ * the path to the file
+ * @param options
+ * options specifying how the copy should be done
+ *
+ * @return the number of bytes read or written
*
- * @param attrs
- * an optional list of file attributes to set atomically when
- * creating the directory
- *
+ * @throws IOException
+ * if an I/O error occurs when reading or writing
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i> *
* @throws UnsupportedOperationException
- * if the array contains an attribute that cannot be set atomically
- * when creating the directory
- * @throws FileAlreadyExistsException
- * if {@code dir} exists but is not a directory <i>(optional specific
- * exception)</i>
- * @throws IOException
- * if an I/O error occurs
+ * if {@code options} contains a copy option that is not supported
* @throws SecurityException
- * in the case of the default provider, and a security manager is
+ * In the case of the default provider, and a security manager is
* installed, the {@link SecurityManager#checkWrite(String) checkWrite}
- * method is invoked prior to attempting to create a directory and
- * its {@link SecurityManager#checkRead(String) checkRead} is
- * invoked for each parent directory that is checked. If {@code
- * dir} is not an absolute path then its {@link Path#toAbsolutePath
- * toAbsolutePath} may need to be invoked to get its absolute path.
- * This may invoke the security manager's {@link
- * SecurityManager#checkPropertyAccess(String) checkPropertyAccess}
- * method to check access to the system property {@code user.dir}
- *
+ * method is invoked to check write access to the file. Where the
+ * {@code REPLACE_EXISTING} option is specified, the security
+ * manager's {@link SecurityManager#checkDelete(String) checkDelete}
+ * method is invoked to check that an existing file can be deleted.
*/
- public static void createDirectories(Path dir, FileAttribute<?>... attrs)
+ public static long copy(InputStream in, Path target, CopyOption... options)
throws IOException
{
- // attempt to create the directory
- try {
- createAndCheckIsDirectory(dir, attrs);
- return;
- } catch (FileAlreadyExistsException x) {
- // file exists and is not a directory
- throw x;
- } catch (IOException x) {
- // parent may not exist or other reason
+ // ensure not null before opening file
+ Objects.requireNonNull(in);
+
+ // check for REPLACE_EXISTING
+ boolean replaceExisting = false;
+ for (CopyOption opt: options) {
+ if (opt == StandardCopyOption.REPLACE_EXISTING) {
+ replaceExisting = true;
+ } else {
+ if (opt == null) {
+ throw new NullPointerException("options contains 'null'");
+ } else {
+ throw new UnsupportedOperationException(opt + " not supported");
+ }
+ }
}
- // find existing parent (may require absolute path)
+ // attempt to delete an existing file
SecurityException se = null;
- try {
- dir = dir.toAbsolutePath();
- } catch (SecurityException x) {
- // don't have permission to get absolute path
- se = x;
+ if (replaceExisting) {
+ try {
+ deleteIfExists(target);
+ } catch (SecurityException x) {
+ se = x;
+ }
}
- Path parent = dir.getParent();
- while (parent != null) {
- try {
- parent.checkAccess();
- break;
- } catch (NoSuchFileException x) {
- // does not exist
- }
- parent = parent.getParent();
- }
- if (parent == null) {
- // unable to find existing parent
+
+ // attempt to create target file. If it fails with
+ // FileAlreadyExistsException then it may be because the security
+ // manager prevented us from deleting the file, in which case we just
+ // throw the SecurityException.
+ OutputStream ostream;
+ try {
+ ostream = newOutputStream(target, StandardOpenOption.CREATE_NEW,
+ StandardOpenOption.WRITE);
+ } catch (FileAlreadyExistsException x) {
if (se != null)
throw se;
- throw new IOException("Root directory does not exist");
+ // someone else won the race and created the file
+ throw x;
}
- // create directories
- Path child = parent;
- for (Path name: parent.relativize(dir)) {
- child = child.resolve(name);
- createAndCheckIsDirectory(child, attrs);
+ // do the copy
+ try (OutputStream out = ostream) {
+ return copy(in, out);
}
}
/**
- * Attempts to create a directory. Does nothing if the directory already
- * exists.
+ * Copies all bytes from a file to an output stream.
+ *
+ * <p> If an I/O error occurs reading from the file or writing to the output
+ * stream, then it may do so after some bytes have been read or written.
+ * Consequently the output stream may be in an inconsistent state. It is
+ * strongly recommended that the output stream be promptly closed if an I/O
+ * error occurs.
+ *
+ * <p> This method may block indefinitely writing to the output stream (or
+ * reading from the file). The behavior for the case that the output stream
+ * is <i>asynchronously closed</i> or the thread interrupted during the copy
+ * is highly output stream and file system provider specific and therefore
+ * not specified.
+ *
+ * <p> Note that if the given output stream is {@link java.io.Flushable}
+ * then its {@link java.io.Flushable#flush flush} method may need to invoked
+ * after this method completes so as to flush any buffered output.
+ *
+ * @param source
+ * the path to the file
+ * @param out
+ * the output stream to write to
+ *
+ * @return the number of bytes read or written
+ *
+ * @throws IOException
+ * if an I/O error occurs when reading or writing
+ * @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.
*/
- private static void createAndCheckIsDirectory(Path dir, FileAttribute<?>... attrs)
+ public static long copy(Path source, OutputStream out) throws IOException {
+ // ensure not null before opening file
+ Objects.requireNonNull(out);
+
+ try (InputStream in = newInputStream(source)) {
+ return copy(in, out);
+ }
+ }
+
+ /**
+ * Read all the bytes from an input stream. The {@code initialSize}
+ * parameter indicates the initial size of the byte[] to allocate.
+ */
+ private static byte[] read(InputStream source, int initialSize)
throws IOException
{
- try {
- dir.createDirectory(attrs);
- } catch (FileAlreadyExistsException x) {
- boolean isDirectory = Attributes
- .readBasicFileAttributes(dir, LinkOption.NOFOLLOW_LINKS).isDirectory();
- if (!isDirectory)
- throw x;
+ int capacity = initialSize;
+ byte[] buf = new byte[capacity];
+ int nread = 0;
+ int rem = buf.length;
+ int n;
+ // read to EOF which may read more or less than initialSize (eg: file
+ // is truncated while we are reading)
+ while ((n = source.read(buf, nread, rem)) > 0) {
+ nread += n;
+ rem -= n;
+ assert rem >= 0;
+ if (rem == 0) {
+ // need larger buffer
+ int newCapacity = capacity << 1;
+ if (newCapacity < 0) {
+ if (capacity == Integer.MAX_VALUE)
+ throw new OutOfMemoryError("Required array size too large");
+ newCapacity = Integer.MAX_VALUE;
+ }
+ rem = newCapacity - capacity;
+ buf = Arrays.copyOf(buf, newCapacity);
+ capacity = newCapacity;
+ }
+ }
+ return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
+ }
+
+ /**
+ * Read all the bytes from a file. The method ensures that the file is
+ * closed when all bytes have been read or an I/O error, or other runtime
+ * exception, is thrown.
+ *
+ * <p> Note that this method is intended for simple cases where it is
+ * convenient to read all bytes into a byte array. It is not intended for
+ * reading in large files.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return a byte array containing the bytes read from the file
+ *
+ * @throws IOException
+ * if an I/O error occurs reading from the stream
+ * @throws OutOfMemoryError
+ * if an array of the required size cannot be allocated, for
+ * example the file is larger that {@code 2GB}
+ * @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.
+ */
+ public static byte[] readAllBytes(Path path) throws IOException {
+ long size = size(path);
+ if (size > (long)Integer.MAX_VALUE)
+ throw new OutOfMemoryError("Required array size too large");
+
+ try (InputStream in = newInputStream(path)) {
+ return read(in, (int)size);
+ }
+ }
+
+ /**
+ * Read all lines from a file. This method ensures that the file is
+ * closed when all bytes have been read or an I/O error, or other runtime
+ * exception, is thrown. Bytes from the file are decoded into characters
+ * using the specified charset.
+ *
+ * <p> This method recognizes the following as line terminators:
+ * <ul>
+ * <li> <code>\u000D</code> followed by <code>\u000A</code>,
+ * CARRIAGE RETURN followed by LINE FEED </li>
+ * <li> <code>\u000A</code>, LINE FEED </li>
+ * <li> <code>\u000D</code>, CARRIAGE RETURN </li>
+ * </ul>
+ * <p> Additional Unicode line terminators may be recognized in future
+ * releases.
+ *
+ * <p> Note that this method is intended for simple cases where it is
+ * convenient to read all lines in a single operation. It is not intended
+ * for reading in large files.
+ *
+ * @param path
+ * the path to the file
+ * @param cs
+ * the charset to use for decoding
+ *
+ * @return the lines from the file as a {@code List}; whether the {@code
+ * List} is modifiable or not is implementation dependent and
+ * therefore not specified
+ *
+ * @throws IOException
+ * if an I/O error occurs reading from the file or a malformed or
+ * unmappable byte sequence is read
+ * @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 #newBufferedReader
+ */
+ public static List<String> readAllLines(Path path, Charset cs)
+ throws IOException
+ {
+ try (BufferedReader reader = newBufferedReader(path, cs)) {
+ List<String> result = new ArrayList<>();
+ for (;;) {
+ String line = reader.readLine();
+ if (line == null)
+ break;
+ result.add(line);
+ }
+ return result;
}
}
+
+ /**
+ * Writes bytes to a file. The {@code options} parameter specifies how the
+ * the file is created or opened. If no options are present then this method
+ * works as if the {@link StandardOpenOption#CREATE CREATE}, {@link
+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+ * opens the file for writing, creating the file if it doesn't exist, or
+ * initially truncating an existing {@link #isRegularFile regular-file} to
+ * a size of {@code 0}. All bytes in the byte array are written to the file.
+ * The method ensures that the file is closed when all bytes have been
+ * written (or an I/O error or other runtime exception is thrown). If an I/O
+ * error occurs then it may do so after the file has created or truncated,
+ * or after some bytes have been written to the file.
+ *
+ * <p> <b>Usage example</b>: By default the method creates a new file or
+ * overrides an existing file. Suppose you instead want to append bytes
+ * to an existing file:
+ * <pre>
+ * Path path = ...
+ * byte[] bytes = ...
+ * Files.write(path, bytes, StandardOpenOption.APPEND);
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param bytes
+ * the byte array with the bytes to write
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return the path
+ *
+ * @throws IOException
+ * if an I/O error occurs writing to or creating the file
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ */
+ public static Path write(Path path, byte[] bytes, OpenOption... options)
+ throws IOException
+ {
+ // ensure bytes is not null before opening file
+ Objects.requireNonNull(bytes);
+
+ try (OutputStream out = Files.newOutputStream(path, options)) {
+ int len = bytes.length;
+ int rem = len;
+ while (rem > 0) {
+ int n = Math.min(rem, BUFFER_SIZE);
+ out.write(bytes, (len-rem), n);
+ rem -= n;
+ }
+ }
+ return path;
+ }
+
+ /**
+ * Write lines of text to a file. Each line is a char sequence and is
+ * written to the file in sequence with each line terminated by the
+ * platform's line separator, as defined by the system property {@code
+ * line.separator}. Characters are encoded into bytes using the specified
+ * charset.
+ *
+ * <p> The {@code options} parameter specifies how the the file is created
+ * or opened. If no options are present then this method works as if the
+ * {@link StandardOpenOption#CREATE CREATE}, {@link
+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+ * opens the file for writing, creating the file if it doesn't exist, or
+ * initially truncating an existing {@link #isRegularFile regular-file} to
+ * a size of {@code 0}. The method ensures that the file is closed when all
+ * lines have been written (or an I/O error or other runtime exception is
+ * thrown). If an I/O error occurs then it may do so after the file has
+ * created or truncated, or after some bytes have been written to the file.
+ *
+ * @param path
+ * the path to the file
+ * @param lines
+ * an object to iterate over the char sequences
+ * @param cs
+ * the charset to use for encoding
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return the path
+ *
+ * @throws IOException
+ * if an I/O error occurs writing to or creating the file, or the
+ * text cannot be encoded using the specified charset
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ */
+ public static Path write(Path path, Iterable<? extends CharSequence> lines,
+ Charset cs, OpenOption... options)
+ throws IOException
+ {
+ // ensure lines is not null before opening file
+ Objects.requireNonNull(lines);
+ CharsetEncoder encoder = cs.newEncoder();
+ OutputStream out = newOutputStream(path, options);
+ try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
+ for (CharSequence line: lines) {
+ writer.append(line);
+ writer.newLine();
+ }
+ }
+ return path;
+ }
}
--- a/jdk/src/share/classes/java/nio/file/LinkOption.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/LinkOption.java Mon Feb 14 16:30:10 2011 -0800
@@ -35,8 +35,8 @@
/**
* Do not follow symbolic links.
*
- * @see FileRef#getFileAttributeView(Class,LinkOption[])
- * @see Path#copyTo
+ * @see Files#getFileAttributeView(Path,Class,LinkOption[])
+ * @see Files#copy
* @see SecureDirectoryStream#newByteChannel
*/
NOFOLLOW_LINKS;
--- a/jdk/src/share/classes/java/nio/file/LinkPermission.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/LinkPermission.java Mon Feb 14 16:30:10 2011 -0800
@@ -59,8 +59,8 @@
*
* @since 1.7
*
- * @see Path#createLink
- * @see Path#createSymbolicLink
+ * @see Files#createLink
+ * @see Files#createSymbolicLink
*/
public final class LinkPermission extends BasicPermission {
static final long serialVersionUID = -1441492453772213220L;
--- a/jdk/src/share/classes/java/nio/file/OpenOption.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/OpenOption.java Mon Feb 14 16:30:10 2011 -0800
@@ -29,8 +29,8 @@
* An object that configures how to open or create a file.
*
* <p> Objects of this type are used by methods such as {@link
- * Path#newOutputStream(OpenOption[]) newOutputStream}, {@link
- * Path#newByteChannel newByteChannel}, {@link
+ * Files#newOutputStream(Path,OpenOption[]) newOutputStream}, {@link
+ * Files#newByteChannel newByteChannel}, {@link
* java.nio.channels.FileChannel#open FileChannel.open}, and {@link
* java.nio.channels.AsynchronousFileChannel#open AsynchronousFileChannel.open}
* when opening or creating a file.
--- a/jdk/src/share/classes/java/nio/file/Path.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/Path.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,147 +25,95 @@
package java.nio.file;
-import java.nio.file.attribute.*;
-import java.nio.channels.SeekableByteChannel;
+import java.io.File;
import java.io.IOException;
-import java.io.OutputStream;
import java.net.URI;
import java.util.Iterator;
-import java.util.Set;
/**
- * A file reference that locates a file using a system dependent path. The file
- * is not required to exist.
- *
- * <p> On many platforms a <em>path</em> is the means to locate and access files
- * in a file system. A path is hierarchical and composed of a sequence of
- * directory and file name elements separated by a special separator or
- * delimiter.
- *
- * <h4>Path operations</h4>
+ * An object that may be used to locate a file in a file system. It will
+ * typically represent a system dependent file path.
*
- * <p> A system dependent path represented by this class is conceptually a
- * sequence of name elements and optionally a <em>root component</em>. The name
- * that is <em>farthest</em> from the root of the directory hierarchy is the
- * name of a file or directory. The other elements are directory names. The root
- * component typically identifies a file system hierarchy. A {@code Path} can
- * represent a root, a root and a sequence of names, or simply one or more name
- * elements. It defines the {@link #getName() getName}, {@link #getParent
- * getParent}, {@link #getRoot getRoot}, and {@link #subpath subpath} methods
- * to access the components or a subsequence of its name elements.
+ * <p> A {@code Path} represents a path that is hierarchical and composed of a
+ * sequence of directory and file name elements separated by a special separator
+ * or delimiter. A <em>root component</em>, that identifies a file system
+ * hierarchy, may also be present. The name element that is <em>farthest</em>
+ * from the root of the directory hierarchy is the name of a file or directory.
+ * The other name elements are directory names. A {@code Path} can represent a
+ * root, a root and a sequence of names, or simply one or more name elements.
+ * A {@code Path} is considered to be an <i>empty path</i> if it consists
+ * solely of one name element that is empty. Accessing a file using an
+ * <i>empty path</i> is equivalent to accessing the default directory of the
+ * file system. {@code Path} defines the {@link #getFileName() getFileName},
+ * {@link #getParent getParent}, {@link #getRoot getRoot}, and {@link #subpath
+ * subpath} methods to access the path components or a subsequence of its name
+ * elements.
*
* <p> In addition to accessing the components of a path, a {@code Path} also
- * defines {@link #resolve(Path) resolve} and {@link #relativize relativize}
- * operations. Paths can also be {@link #compareTo compared}, and tested
- * against each other using using the {@link #startsWith startsWith} and {@link
- * #endsWith endWith} methods.
- *
- * <h4>File operations</h4>
+ * defines the {@link #resolve(Path) resolve} and {@link #resolveSibling(Path)
+ * resolveSibling} methods to combine paths. The {@link #relativize relativize}
+ * method that can be used to construct a relative path between two paths.
+ * Paths can be {@link #compareTo compared}, and tested against each other using
+ * the {@link #startsWith startsWith} and {@link #endsWith endWith} methods.
*
- * <p> A {@code Path} is either <em>absolute</em> or <em>relative</em>. An
- * absolute path is complete in that does not need to be combined with another
- * path in order to locate a file. All operations on relative paths are first
- * resolved against a file system's default directory as if by invoking the
- * {@link #toAbsolutePath toAbsolutePath} method.
- *
- * <p> In addition to the operations defined by the {@link FileRef} interface,
- * this class defines the following operations:
+ * <p> This interface extends {@link Watchable} interface so that a directory
+ * located by a path can be {@link #register registered} with a {@link
+ * WatchService} and entries in the directory watched. </p>
*
- * <ul>
- * <li><p> The {@link #newByteChannel newByteChannel} method
- * may be used to open a file and obtain a byte channel for reading or
- * writing. </p></li>
- * <li><p> Files may be {@link #createFile(FileAttribute[]) created}, or
- * directories may be {@link #createDirectory(FileAttribute[]) created}.
- * </p></li>
- * <li><p> The {@link #delete delete} method may be used to delete a file.
- * </p></li>
- * <li><p> The {@link #checkAccess checkAccess} method may be used to check
- * the existence or accessibility of a file. </p></li>
- * <li><p> The {@link #isSameFile isSameFile} method may be used to test if
- * two file references locate the same file. </p></li>
- * <li><p> The {@link #getFileStore getFileStore} method may be used to
- * obtain the {@link FileStore} representing the storage where a file is
- * located. </p></li>
- * <li><p> Directories can be {@link #newDirectoryStream opened} so as to
- * iterate over the entries in the directory. </p></li>
- * <li><p> Files can be {@link #copyTo(Path,CopyOption[]) copied} or
- * {@link #moveTo(Path,CopyOption[]) moved}. </p></li>
- * <li><p> Symbolic links may be {@link #createSymbolicLink created}, or the
- * target of a symbolic link may be {@link #readSymbolicLink read}. </p></li>
- * <li><p> The {@link #toRealPath real} path of an existing file may be
- * obtained. </li></p>
- * </ul>
+ * <p> <b>WARNING:</b> This interface is only intended to be implemented by
+ * those developing custom file system implementations. Methods may be added to
+ * this interface in future releases. </p>
*
- * <p> This class implements {@link Watchable} interface so that a directory
- * located by a path can be {@link #register registered} with a {@link WatchService}.
- * and entries in the directory watched.
- *
- * <h4>File attributes</h4>
- *
- * In addition to the {@link #setAttribute setAttribute} and {@link #getAttribute
- * getAttribute} methods, the <a href="attribute/package-summary.html">{@code
- * java.nio.file.attribute}</a> package provides type-safe and efficient access
- * to file attributes or <em>meta-data</em> associated with files. The {@link
- * Attributes Attributes} class defines methods that operate on or return file
- * attributes. For example, the file type, size, timestamps, and other
- * <em>basic</em> meta-data are obtained, in bulk, by invoking the {@link
- * Attributes#readBasicFileAttributes Attributes.readBasicFileAttributes} method:
+ * <a name="interop"><h4>Accessing Files</h4></a>
+ * <p> Paths may be used with the {@link Files} class to operate on files,
+ * directories, and other types of files. For example, suppose we want a {@link
+ * java.io.BufferedReader} to read text from a file "{@code access.log}". The
+ * file is located in a directory "{@code logs}" relative to the current working
+ * directory and is UTF-8 encoded.
* <pre>
- * Path file = ...
- * BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+ * Path path = FileSystems.getDefault().getPath("logs", "access.log");
+ * BufferReader reader = Files.newBufferedReader(path, Charset.forName("UTF-8"));
* </pre>
*
* <a name="interop"><h4>Interoperability</h4></a>
- *
- * <p> Paths created by file systems associated with the default {@link
+ * <p> Paths associated with the default {@link
* java.nio.file.spi.FileSystemProvider provider} are generally interoperable
* with the {@link java.io.File java.io.File} class. Paths created by other
* providers are unlikely to be interoperable with the abstract path names
- * represented by {@code java.io.File}. The {@link java.io.File#toPath
- * File.toPath} method may be used to obtain a {@code Path} from the abstract
- * path name represented by a {@code java.io.File java.io.File} object. The
- * resulting {@code Path} can be used to operate on the same file as the {@code
- * java.io.File} object.
- *
- * <p> Path objects created by file systems associated with the default
- * provider are interoperable with objects created by other file systems created
- * by the same provider. Path objects created by file systems associated with
- * other providers may not be interoperable with other file systems created by
- * the same provider. The reasons for this are provider specific.
+ * represented by {@code java.io.File}. The {@link java.io.File#toPath toPath}
+ * method may be used to obtain a {@code Path} from the abstract path name
+ * represented by a {@code java.io.File} object. The resulting {@code Path} can
+ * be used to operate on the same file as the {@code java.io.File} object. In
+ * addition, the {@link #toFile toFile} method is useful to construct a {@code
+ * File} from the {@code String} representation of a {@code Path}.
*
* <h4>Concurrency</h4></a>
- *
- * <p> Instances of this class are immutable and safe for use by multiple concurrent
- * threads.
+ * <p> Implementations of this interface are immutable and safe for use by
+ * multiple concurrent threads.
*
* @since 1.7
+ * @see Paths
*/
-public abstract class Path
- implements FileRef, Comparable<Path>, Iterable<Path>, Watchable
+public interface Path
+ extends Comparable<Path>, Iterable<Path>, Watchable
{
/**
- * Initializes a new instance of this class.
- */
- protected Path() { }
-
- /**
* Returns the file system that created this object.
*
* @return the file system that created this object
*/
- public abstract FileSystem getFileSystem();
+ FileSystem getFileSystem();
/**
* Tells whether or not this path is absolute.
*
- * <p> An absolute path is complete in that it doesn't need to be
- * combined with other path information in order to locate a file.
+ * <p> An absolute path is complete in that it doesn't need to be combined
+ * with other path information in order to locate a file.
*
* @return {@code true} if, and only if, this path is absolute
*/
- public abstract boolean isAbsolute();
+ boolean isAbsolute();
/**
* Returns the root component of this path as a {@code Path} object,
@@ -174,17 +122,17 @@
* @return a path representing the root component of this path,
* or {@code null}
*/
- public abstract Path getRoot();
+ Path getRoot();
/**
- * Returns the name of the file or directory denoted by this path. The
- * file name is the <em>farthest</em> element from the root in the directory
- * hierarchy.
+ * Returns the name of the file or directory denoted by this path as a
+ * {@code Path} object. The file name is the <em>farthest</em> element from
+ * the root in the directory hierarchy.
*
* @return a path representing the name of the file or directory, or
* {@code null} if this path has zero elements
*/
- public abstract Path getName();
+ Path getFileName();
/**
* Returns the <em>parent path</em>, or {@code null} if this path does not
@@ -209,7 +157,7 @@
*
* @return a path representing the path's parent
*/
- public abstract Path getParent();
+ Path getParent();
/**
* Returns the number of name elements in the path.
@@ -217,10 +165,10 @@
* @return the number of elements in the path, or {@code 0} if this path
* only represents a root component
*/
- public abstract int getNameCount();
+ int getNameCount();
- /**
- * Returns a name element of this path.
+ /**
+ * Returns a name element of this path as a {@code Path} object.
*
* <p> The {@code index} parameter is the index of the name element to return.
* The element that is <em>closest</em> to the root in the directory hierarchy
@@ -237,7 +185,7 @@
* equal to the number of elements, or this path has zero name
* elements
*/
- public abstract Path getName(int index);
+ Path getName(int index);
/**
* Returns a relative {@code Path} that is a subsequence of the name
@@ -264,7 +212,7 @@
* the number of elements. If {@code endIndex} is less than or
* equal to {@code beginIndex}, or larger than the number of elements.
*/
- public abstract Path subpath(int beginIndex, int endIndex);
+ Path subpath(int beginIndex, int endIndex);
/**
* Tests if this path starts with the given path.
@@ -286,7 +234,25 @@
* @return {@code true} if this path starts with the given path; otherwise
* {@code false}
*/
- public abstract boolean startsWith(Path other);
+ boolean startsWith(Path other);
+
+ /**
+ * Tests if this path starts with a {@code Path}, constructed by converting
+ * the given path string, in exactly the manner specified by the {@link
+ * #startsWith(Path) startsWith(Path)} method. On UNIX for example, the path
+ * "{@code foo/bar}" starts with "{@code foo}" and "{@code foo/bar}". It
+ * does not start with "{@code f}" or "{@code fo}".
+ *
+ * @param other
+ * the given path string
+ *
+ * @return {@code true} if this path starts with the given path; otherwise
+ * {@code false}
+ *
+ * @throws InvalidPathException
+ * If the path string cannot be converted to a Path.
+ */
+ boolean startsWith(String other);
/**
* Tests if this path ends with the given path.
@@ -310,7 +276,25 @@
* @return {@code true} if this path ends with the given path; otherwise
* {@code false}
*/
- public abstract boolean endsWith(Path other);
+ boolean endsWith(Path other);
+
+ /**
+ * Tests if this path ends with a {@code Path}, constructed by converting
+ * the given path string, in exactly the manner specified by the {@link
+ * #endsWith(Path) endsWith(Path)} method. On UNIX for example, the path
+ * "{@code foo/bar}" ends with "{@code foo/bar}" and "{@code bar}". It does
+ * not end with "{@code r}" or "{@code /bar}".
+ *
+ * @param other
+ * the given path string
+ *
+ * @return {@code true} if this path starts with the given path; otherwise
+ * {@code false}
+ *
+ * @throws InvalidPathException
+ * If the path string cannot be converted to a Path.
+ */
+ boolean endsWith(String other);
/**
* Returns a path that is this path with redundant name elements eliminated.
@@ -330,14 +314,14 @@
* path may result in the path that locates a different file than the original
* path. This can arise when the preceding name is a symbolic link.
*
- * @return the resulting path, or this path if it does not contain
- * redundant name elements, or {@code null} if this path does not
- * have a root component and all name elements are redundant
+ * @return the resulting path or this path if it does not contain
+ * redundant name elements; an empty path is returned if this path
+ * does have a root component and all name elements are redundant
*
* @see #getParent
* @see #toRealPath
*/
- public abstract Path normalize();
+ Path normalize();
// -- resolution and relativization --
@@ -346,28 +330,31 @@
*
* <p> If the {@code other} parameter is an {@link #isAbsolute() absolute}
* path then this method trivially returns {@code other}. If {@code other}
- * is {@code null} then this path is returned. Otherwise this method
- * considers this path to be a directory and resolves the given path
- * against this path. In the simplest case, the given path does not have
- * a {@link #getRoot root} component, in which case this method <em>joins</em>
- * the given path to this path and returns a resulting path that {@link
- * #endsWith ends} with the given path. Where the given path has a root
- * component then resolution is highly implementation dependent and therefore
- * unspecified.
+ * is an <i>empty path</i> then this method trivially returns this path.
+ * Otherwise this method considers this path to be a directory and resolves
+ * the given path against this path. In the simplest case, the given path
+ * does not have a {@link #getRoot root} component, in which case this method
+ * <em>joins</em> the given path to this path and returns a resulting path
+ * that {@link #endsWith ends} with the given path. Where the given path has
+ * a root component then resolution is highly implementation dependent and
+ * therefore unspecified.
*
* @param other
- * the path to resolve against this path; can be {@code null}
+ * the path to resolve against this path
*
* @return the resulting path
*
* @see #relativize
*/
- public abstract Path resolve(Path other);
+ Path resolve(Path other);
/**
* Converts a given path string to a {@code Path} and resolves it against
* this {@code Path} in exactly the manner specified by the {@link
- * #resolve(Path) resolve} method.
+ * #resolve(Path) resolve} method. For example, suppose that the name
+ * separator is "{@code /}" and a path represents "{@code foo/bar}", then
+ * invoking this method with the path string "{@code gus}" will result in
+ * the {@code Path} "{@code foo/bar/gus}".
*
* @param other
* the path string to resolve against this path
@@ -375,11 +362,49 @@
* @return the resulting path
*
* @throws InvalidPathException
- * If the path string cannot be converted to a Path.
+ * if the path string cannot be converted to a Path.
*
* @see FileSystem#getPath
*/
- public abstract Path resolve(String other);
+ Path resolve(String other);
+
+ /**
+ * Resolves the given path against this path's {@link #getParent parent}
+ * path. This is useful where a file name needs to be <i>replaced</i> with
+ * another file name. For example, suppose that the name separator is
+ * "{@code /}" and a path represents "{@code dir1/dir2/foo}", then invoking
+ * this method with the {@code Path} "{@code bar}" will result in the {@code
+ * Path} "{@code dir1/dir2/bar}". If this path does not have a parent path,
+ * or {@code other} is {@link #isAbsolute() absolute}, then this method
+ * returns {@code other}. If {@code other} is an empty path then this method
+ * returns this path's parent, or where this path doesn't have a parent, the
+ * empty path.
+ *
+ * @param other
+ * the path to resolve against this path's parent
+ *
+ * @return the resulting path
+ *
+ * @see #resolve(Path)
+ */
+ Path resolveSibling(Path other);
+
+ /**
+ * Converts a given path string to a {@code Path} and resolves it against
+ * this path's {@link #getParent parent} path in exactly the manner
+ * specified by the {@link #resolveSibling(Path) resolveSibling} method.
+ *
+ * @param other
+ * the path string to resolve against this path's parent
+ *
+ * @return the resulting path
+ *
+ * @throws InvalidPathException
+ * if the path string cannot be converted to a Path.
+ *
+ * @see FileSystem#getPath
+ */
+ Path resolveSibling(String other);
/**
* Constructs a relative path between this path and a given path.
@@ -395,17 +420,17 @@
* constructed if only one of the paths have a root component. Where both
* paths have a root component then it is implementation dependent if a
* relative path can be constructed. If this path and the given path are
- * {@link #equals equal} then {@code null} is returned.
+ * {@link #equals equal} then an <i>empty path</i> is returned.
*
- * <p> For any two paths <i>p</i> and <i>q</i>, where <i>q</i> does not have
- * a root component,
+ * <p> For any two {@link #normalize normalized} paths <i>p</i> and
+ * <i>q</i>, where <i>q</i> does not have a root component,
* <blockquote>
* <i>p</i><tt>.relativize(</tt><i>p</i><tt>.resolve(</tt><i>q</i><tt>)).equals(</tt><i>q</i><tt>)</tt>
* </blockquote>
*
* <p> When symbolic links are supported, then whether the resulting path,
* when resolved against this path, yields a path that can be used to locate
- * the {@link #isSameFile same} file as {@code other} is implementation
+ * the {@link Files#isSameFile same} file as {@code other} is implementation
* dependent. For example, if this path is {@code "/a/b"} and the given
* path is {@code "/a/x"} then the resulting relative path may be {@code
* "../x"}. If {@code "b"} is a symbolic link then is implementation
@@ -414,185 +439,14 @@
* @param other
* the path to relativize against this path
*
- * @return the resulting relative path, or {@code null} if both paths are
+ * @return the resulting relative path, or an empty path if both paths are
* equal
*
* @throws IllegalArgumentException
* if {@code other} is not a {@code Path} that can be relativized
* against this path
*/
- public abstract Path relativize(Path other);
-
- // -- file operations --
-
- /**
- * Deletes the file located by this path.
- *
- * <p> An implementation may require to examine the file to determine if the
- * file is a directory. Consequently this method may not be atomic with respect
- * to other file system operations. If the file is a symbolic link then the
- * symbolic link itself, not the final target of the link, is deleted.
- *
- * <p> If the file is a directory then the directory must be empty. In some
- * implementations a directory has entries for special files or links that
- * are created when the directory is created. In such implementations a
- * directory is considered empty when only the special entries exist.
- *
- * <p> On some operating systems it may not be possible to remove a file when
- * it is open and in use by this Java virtual machine or other programs.
- *
- * @throws NoSuchFileException
- * if the file does not exist <i>(optional specific exception)</i>
- * @throws DirectoryNotEmptyException
- * if the file is a directory and could not otherwise be deleted
- * because the directory is not empty <i>(optional specific
- * exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, the {@link SecurityManager#checkDelete(String)} method
- * is invoked to check delete access to the file
- */
- public abstract void delete() throws IOException;
-
- /**
- * Deletes the file located by this path, if it exists.
- *
- * <p> As with the {@link #delete delete()} method, an implementation may
- * need to examine the file to determine if the file is a directory.
- * Consequently this method may not be atomic with respect to other file
- * system operations. If the file is a symbolic link, then the symbolic
- * link itself, not the final target of the link, is deleted.
- *
- * <p> If the file is a directory then the directory must be empty. In some
- * implementations a directory has entries for special files or links that
- * are created when the directory is created. In such implementations a
- * directory is considered empty when only the special entries exist.
- *
- * <p> On some operating systems it may not be possible to remove a file when
- * it is open and in use by this Java virtual machine or other programs.
- *
- * @throws DirectoryNotEmptyException
- * if the file is a directory and could not otherwise be deleted
- * because the directory is not empty <i>(optional specific
- * exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, the {@link SecurityManager#checkDelete(String)} method
- * is invoked to check delete access to the file.
- */
- public abstract void deleteIfExists() throws IOException;
-
- /**
- * Creates a symbolic link to a target <i>(optional operation)</i>.
- *
- * <p> The {@code target} parameter is the target of the link. It may be an
- * {@link Path#isAbsolute absolute} or relative path and may not exist. When
- * the target is a relative path then file system operations on the resulting
- * link are relative to the path of the link.
- *
- * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
- * attributes} to set atomically when creating the link. Each attribute is
- * identified by its {@link FileAttribute#name name}. If more than one attribute
- * of the same name is included in the array then all but the last occurrence
- * is ignored.
- *
- * <p> Where symbolic links are supported, but the underlying {@link FileStore}
- * does not support symbolic links, then this may fail with an {@link
- * IOException}. Additionally, some operating systems may require that the
- * Java virtual machine be started with implementation specific privileges to
- * create symbolic links, in which case this method may throw {@code IOException}.
- *
- * @param target
- * the target of the symbolic link
- * @param attrs
- * the array of attributes to set atomically when creating the
- * symbolic link
- *
- * @return this path
- *
- * @throws UnsupportedOperationException
- * if the implementation does not support symbolic links or the
- * array contains an attribute that cannot be set atomically when
- * creating the symbolic link
- * @throws FileAlreadyExistsException
- * if a file with the name already exists <i>(optional specific
- * exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager
- * is installed, it denies {@link LinkPermission}<tt>("symbolic")</tt>
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the path of the symbolic link.
- */
- public abstract Path createSymbolicLink(Path target, FileAttribute<?>... attrs)
- throws IOException;
-
- /**
- * Creates a new link (directory entry) for an existing file <i>(optional
- * operation)</i>.
- *
- * <p> This path locates the directory entry to create. The {@code existing}
- * parameter is the path to an existing file. This method creates a new
- * directory entry for the file so that it can be accessed using this path.
- * On some file systems this is known as creating a "hard link". Whether the
- * file attributes are maintained for the file or for each directory entry
- * is file system specific and therefore not specified. Typically, a file
- * system requires that all links (directory entries) for a file be on the
- * same file system. Furthermore, on some platforms, the Java virtual machine
- * may require to be started with implementation specific privileges to
- * create hard links or to create links to directories.
- *
- * @param existing
- * a reference to an existing file
- *
- * @return this path
- *
- * @throws UnsupportedOperationException
- * if the implementation does not support adding an existing file
- * to a directory
- * @throws FileAlreadyExistsException
- * if the entry could not otherwise be created because a file of
- * that name already exists <i>(optional specific exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager
- * is installed, it denies {@link LinkPermission}<tt>("hard")</tt>
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to both this path and the path of the
- * existing file.
- */
- public abstract Path createLink(Path existing) throws IOException;
-
- /**
- * Reads the target of a symbolic link <i>(optional operation)</i>.
- *
- * <p> If the file system supports <a href="package-summary.html#links">symbolic
- * links</a> then this method is used to read the target of the link, failing
- * if the file is not a symbolic link. The target of the link need not exist.
- * The returned {@code Path} object will be associated with the same file
- * system as this {@code Path}.
- *
- * @return a {@code Path} object representing the target of the link
- *
- * @throws UnsupportedOperationException
- * if the implementation does not support symbolic links
- * @throws NotLinkException
- * if the target could otherwise not be read because the file
- * is not a symbolic link <i>(optional specific exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager
- * is installed, it checks that {@code FilePermission} has been
- * granted with the "{@code readlink}" action to read the link.
- */
- public abstract Path readSymbolicLink() throws IOException;
+ Path relativize(Path other);
/**
* Returns a URI to represent this path.
@@ -647,7 +501,7 @@
* is installed, the {@link #toAbsolutePath toAbsolutePath} method
* throws a security exception.
*/
- public abstract URI toUri();
+ URI toUri();
/**
* Returns a {@code Path} object representing the absolute path of this
@@ -670,14 +524,14 @@
* checkPropertyAccess} method is invoked to check access to the
* system property {@code user.dir}
*/
- public abstract Path toAbsolutePath();
+ Path toAbsolutePath();
/**
* Returns the <em>real</em> path of an existing file.
*
* <p> The precise definition of this method is implementation dependent but
* in general it derives from this path, an {@link #isAbsolute absolute}
- * path that locates the {@link #isSameFile same} file as this path, but
+ * path that locates the {@link Files#isSameFile same} file as this path, but
* with name elements that represent the actual name of the directories
* and the file. For example, where filename comparisons on a file system
* are case insensitive then the name elements represent the names in their
@@ -713,756 +567,25 @@
* checkPropertyAccess} method is invoked to check access to the
* system property {@code user.dir}
*/
- public abstract Path toRealPath(boolean resolveLinks) throws IOException;
-
- /**
- * Copy the file located by this path to a target location.
- *
- * <p> This method copies the file located by this {@code Path} to the
- * target location with the {@code options} parameter specifying how the
- * copy is performed. By default, the copy fails if the target file already
- * exists, except if the source and target are the {@link #isSameFile same}
- * file, in which case this method has no effect. File attributes are not
- * required to be copied to the target file. If symbolic links are supported,
- * and the file is a symbolic link, then the final target of the link is copied.
- * If the file is a directory then it creates an empty directory in the target
- * location (entries in the directory are not copied). This method can be
- * used with the {@link Files#walkFileTree Files.walkFileTree} utility
- * method to copy a directory and all entries in the directory, or an entire
- * <i>file-tree</i> where required.
- *
- * <p> The {@code options} parameter is an array of options and may contain
- * any of the following:
- *
- * <table border=1 cellpadding=5 summary="">
- * <tr> <th>Option</th> <th>Description</th> </tr>
- * <tr>
- * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
- * <td> If the target file exists, then the target file is replaced if it
- * is not a non-empty directory. If the target file exists and is a
- * symbolic link, then the symbolic link itself, not the target of
- * the link, is replaced. </td>
- * </tr>
- * <tr>
- * <td> {@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} </td>
- * <td> Attempts to copy the file attributes associated with this file to
- * the target file. The exact file attributes that are copied is platform
- * and file system dependent and therefore unspecified. Minimally, the
- * {@link BasicFileAttributes#lastModifiedTime last-modified-time} is
- * copied to the target file if supported by both the source and target
- * file store. Copying of file timestamps may result in precision
- * loss. </td>
- * </tr>
- * <tr>
- * <td> {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} </td>
- * <td> Symbolic links are not followed. If the file, located by this path,
- * is a symbolic link, then the symbolic link itself, not the target of
- * the link, is copied. It is implementation specific if file attributes
- * can be copied to the new link. In other words, the {@code
- * COPY_ATTRIBUTES} option may be ignored when copying a symbolic link. </td>
- * </tr>
- * </table>
- *
- * <p> An implementation of this interface may support additional
- * implementation specific options.
- *
- * <p> Copying a file is not an atomic operation. If an {@link IOException}
- * is thrown then it possible that the target file is incomplete or some of
- * its file attributes have not been copied from the source file. When the
- * {@code REPLACE_EXISTING} option is specified and the target file exists,
- * then the target file is replaced. The check for the existence of the file
- * and the creation of the new file may not be atomic with respect to other
- * file system activities.
- *
- * @param target
- * the target location
- * @param options
- * options specifying how the copy should be done
- *
- * @return the target
- *
- * @throws UnsupportedOperationException
- * if the array contains a copy option that is not supported
- * @throws FileAlreadyExistsException
- * if the target file exists and cannot be replaced because the
- * {@code REPLACE_EXISTING} option is not specified, or the target
- * file is a non-empty directory <i>(optional specific exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @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 source file, the
- * {@link SecurityManager#checkWrite(String) checkWrite} is invoked
- * to check write access to the target file. If a symbolic link is
- * copied the security manager is invoked to check {@link
- * LinkPermission}{@code ("symbolic")}.
- */
- public abstract Path copyTo(Path target, CopyOption... options)
- throws IOException;
-
- /**
- * Move or rename the file located by this path to a target location.
- *
- * <p> By default, this method attempts to move the file to the target
- * location, failing if the target file exists except if the source and
- * target are the {@link #isSameFile same} file, in which case this method
- * has no effect. If the file is a symbolic link then the symbolic link
- * itself, not the target of the link, is moved. This method may be
- * invoked to move an empty directory. In some implementations a directory
- * has entries for special files or links that are created when the
- * directory is created. In such implementations a directory is considered
- * empty when only the special entries exist. When invoked to move a
- * directory that is not empty then the directory is moved if it does not
- * require moving the entries in the directory. For example, renaming a
- * directory on the same {@link FileStore} will usually not require moving
- * the entries in the directory. When moving a directory requires that its
- * entries be moved then this method fails (by throwing an {@code
- * IOException}). To move a <i>file tree</i> may involve copying rather
- * than moving directories and this can be done using the {@link
- * #copyTo copyTo} method in conjunction with the {@link
- * Files#walkFileTree Files.walkFileTree} utility method.
- *
- * <p> The {@code options} parameter is an array of options and may contain
- * any of the following:
- *
- * <table border=1 cellpadding=5 summary="">
- * <tr> <th>Option</th> <th>Description</th> </tr>
- * <tr>
- * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
- * <td> If the target file exists, then the target file is replaced if it
- * is not a non-empty directory. If the target file exists and is a
- * symbolic link, then the symbolic link itself, not the target of
- * the link, is replaced. </td>
- * </tr>
- * <tr>
- * <td> {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} </td>
- * <td> The move is performed as an atomic file system operation and all
- * other options are ignored. If the target file exists then it is
- * implementation specific if the existing file is replaced or this method
- * fails by throwing an {@link IOException}. If the move cannot be
- * performed as an atomic file system operation then {@link
- * AtomicMoveNotSupportedException} is thrown. This can arise, for
- * example, when the target location is on a different {@code FileStore}
- * and would require that the file be copied, or target location is
- * associated with a different provider to this object. </td>
- * </table>
- *
- * <p> An implementation of this interface may support additional
- * implementation specific options.
- *
- * <p> Where the move requires that the file be copied then the {@link
- * BasicFileAttributes#lastModifiedTime last-modified-time} is copied to the
- * new file. An implementation may also attempt to copy other file
- * attributes but is not required to fail if the file attributes cannot be
- * copied. When the move is performed as a non-atomic operation, and a {@code
- * IOException} is thrown, then the state of the files is not defined. The
- * original file and the target file may both exist, the target file may be
- * incomplete or some of its file attributes may not been copied from the
- * original file.
- *
- * @param target
- * the target location
- * @param options
- * options specifying how the move should be done
- *
- * @return the target
- *
- * @throws UnsupportedOperationException
- * if the array contains a copy option that is not supported
- * @throws FileAlreadyExistsException
- * if the target file exists and cannot be replaced because the
- * {@code REPLACE_EXISTING} option is not specified, or the target
- * file is a non-empty directory
- * @throws AtomicMoveNotSupportedException
- * if the options array contains the {@code ATOMIC_MOVE} option but
- * the file cannot be moved as an atomic file system operation.
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
- * method is invoked to check write access to both the source and
- * target file.
- */
- public abstract Path moveTo(Path target, CopyOption... options)
- throws IOException;
+ Path toRealPath(boolean resolveLinks) throws IOException;
/**
- * Opens the directory referenced by this object, returning a {@code
- * DirectoryStream} to iterate over all entries in the directory. The
- * elements returned by the directory stream's {@link DirectoryStream#iterator
- * iterator} are of type {@code Path}, each one representing an entry in the
- * directory. The {@code Path} objects are obtained as if by {@link
- * #resolve(Path) resolving} the name of the directory entry against this
- * path.
- *
- * <p> The directory stream's {@code close} method should be invoked after
- * iteration is completed so as to free any resources held for the open
- * directory.
- *
- * <p> When an implementation supports operations on entries in the
- * directory that execute in a race-free manner then the returned directory
- * stream is a {@link SecureDirectoryStream}.
- *
- * @return a new and open {@code DirectoryStream} object
- *
- * @throws NotDirectoryException
- * if the file could not otherwise be opened because it is not
- * a directory <i>(optional specific exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @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.
- */
- public abstract DirectoryStream<Path> newDirectoryStream()
- throws IOException;
-
- /**
- * Opens the directory referenced by this object, returning a {@code
- * DirectoryStream} to iterate over the entries in the directory. The
- * elements returned by the directory stream's {@link DirectoryStream#iterator
- * iterator} are of type {@code Path}, each one representing an entry in the
- * directory. The {@code Path} objects are obtained as if by {@link
- * #resolve(Path) resolving} the name of the directory entry against this
- * path. The entries returned by the iterator are filtered by matching the
- * {@code String} representation of their file names against the given
- * <em>globbing</em> pattern.
- *
- * <p> For example, suppose we want to iterate over the files ending with
- * ".java" in a directory:
- * <pre>
- * Path dir = ...
- * DirectoryStream<Path> stream = dir.newDirectoryStream("*.java");
- * </pre>
- *
- * <p> The globbing pattern is specified by the {@link
- * FileSystem#getPathMatcher getPathMatcher} method.
- *
- * <p> The directory stream's {@code close} method should be invoked after
- * iteration is completed so as to free any resources held for the open
- * directory.
- *
- * <p> When an implementation supports operations on entries in the
- * directory that execute in a race-free manner then the returned directory
- * stream is a {@link SecureDirectoryStream}.
- *
- * @param glob
- * the glob pattern
- *
- * @return a new and open {@code DirectoryStream} object
- *
- * @throws java.util.regex.PatternSyntaxException
- * if the pattern is invalid
- * @throws NotDirectoryException
- * if the file could not otherwise be opened because it is not
- * a directory <i>(optional specific exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @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.
- */
- public abstract DirectoryStream<Path> newDirectoryStream(String glob)
- throws IOException;
-
- /**
- * Opens the directory referenced by this object, returning a {@code
- * DirectoryStream} to iterate over the entries in the directory. The
- * elements returned by the directory stream's {@link DirectoryStream#iterator
- * iterator} are of type {@code Path}, each one representing an entry in the
- * directory. The {@code Path} objects are obtained as if by {@link
- * #resolve(Path) resolving} the name of the directory entry against this
- * path. The entries returned by the iterator are filtered by the given
- * {@link DirectoryStream.Filter filter}.
- *
- * <p> The directory stream's {@code close} method should be invoked after
- * iteration is completed so as to free any resources held for the open
- * directory.
+ * Returns a {@link File} object representing this path. Where this {@code
+ * Path} is associated with the default provider, then this method is
+ * equivalent to returning a {@code File} object constructed with the
+ * {@code String} representation of this path.
*
- * <p> Where the filter terminates due to an uncaught error or runtime
- * exception then it is propagated to the {@link Iterator#hasNext()
- * hasNext} or {@link Iterator#next() next} method. Where an {@code
- * IOException} is thrown, it results in the {@code hasNext} or {@code
- * next} method throwing a {@link DirectoryIteratorException} with the
- * {@code IOException} as the cause.
- *
- * <p> When an implementation supports operations on entries in the
- * directory that execute in a race-free manner then the returned directory
- * stream is a {@link SecureDirectoryStream}.
- *
- * <p> <b>Usage Example:</b>
- * Suppose we want to iterate over the files in a directory that are
- * larger than 8K.
- * <pre>
- * DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
- * public boolean accept(Path file) throws IOException {
- * long size = Attributes.readBasicFileAttributes(file).size();
- * return (size > 8192L);
- * }
- * };
- * Path dir = ...
- * DirectoryStream<Path> stream = dir.newDirectoryStream(filter);
- * </pre>
- * @param filter
- * the directory stream filter
- *
- * @return a new and open {@code DirectoryStream} object
- *
- * @throws NotDirectoryException
- * if the file could not otherwise be opened because it is not
- * a directory <i>(optional specific exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @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.
- */
- public abstract DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
- throws IOException;
-
- /**
- * Creates a new and empty file, failing if the file already exists.
+ * <p> If this path was created by invoking the {@code File} {@link
+ * File#toPath toPath} method then there is no guarantee that the {@code
+ * File} object returned by this method is {@link #equals equal} to the
+ * original {@code File}.
*
- * <p> This {@code Path} locates the file to create. The check for the
- * existence of the file and the creation of the new file if it does not
- * exist are a single operation that is atomic with respect to all other
- * filesystem activities that might affect the directory.
- *
- * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
- * file-attributes} to set atomically when creating the file. Each attribute
- * is identified by its {@link FileAttribute#name name}. If more than one
- * attribute of the same name is included in the array then all but the last
- * occurrence is ignored.
- *
- * @param attrs
- * an optional list of file attributes to set atomically when
- * creating the file
- *
- * @return this path
- *
- * @throws UnsupportedOperationException
- * if the array contains an attribute that cannot be set atomically
- * when creating the file
- * @throws FileAlreadyExistsException
- * if a file of that name already exists
- * <i>(optional specific exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
- * method is invoked to check write access to the new file.
- */
- public abstract Path createFile(FileAttribute<?>... attrs) throws IOException;
-
- /**
- * Creates a new directory.
- *
- * <p> This {@code Path} locates the directory to create. The check for the
- * existence of the file and the creation of the directory if it does not
- * exist are a single operation that is atomic with respect to all other
- * filesystem activities that might affect the directory.
- *
- * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
- * file-attributes} to set atomically when creating the directory. Each
- * file attribute is identified by its {@link FileAttribute#name name}. If
- * more than one attribute of the same name is included in the array then all
- * but the last occurrence is ignored.
- *
- * @param attrs
- * an optional list of file attributes to set atomically when
- * creating the directory
- *
- * @return this path
+ * @return a {@code File} object representing this path
*
* @throws UnsupportedOperationException
- * if the array contains an attribute that cannot be set atomically
- * when creating the directory
- * @throws FileAlreadyExistsException
- * if a directory could not otherwise be created because a file of
- * that name already exists <i>(optional specific exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
- * method is invoked to check write access to the new directory.
- *
- * @see Files#createDirectories
- */
- public abstract Path createDirectory(FileAttribute<?>... attrs)
- throws IOException;
-
- /**
- * Opens or creates a file, returning a seekable byte channel to access the
- * file.
- *
- * <p> The {@code options} parameter determines how the file is opened.
- * The {@link StandardOpenOption#READ READ} and {@link StandardOpenOption#WRITE WRITE}
- * options determine if the file should be opened for reading and/or writing.
- * If neither option (or the {@link StandardOpenOption#APPEND APPEND}
- * option) is contained in the array then the file is opened for reading.
- * By default reading or writing commences at the beginning of the file.
- *
- * <p> In the addition to {@code READ} and {@code WRITE}, the following
- * options may be present:
- *
- * <table border=1 cellpadding=5 summary="">
- * <tr> <th>Option</th> <th>Description</th> </tr>
- * <tr>
- * <td> {@link StandardOpenOption#APPEND APPEND} </td>
- * <td> If this option is present then the file is opened for writing and
- * each invocation of the channel's {@code write} method first advances
- * the position to the end of the file and then writes the requested
- * data. Whether the advancement of the position and the writing of the
- * data are done in a single atomic operation is system-dependent and
- * therefore unspecified. This option may not be used in conjunction
- * with the {@code READ} or {@code TRUNCATE_EXISTING} options. </td>
- * </tr>
- * <tr>
- * <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
- * <td> If this option is present then the existing file is truncated to
- * a size of 0 bytes. This option is ignored when the file is opened only
- * for reading. </td>
- * </tr>
- * <tr>
- * <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
- * <td> If this option is present then a new file is created, failing if
- * the file already exists or is a symbolic link. When creating a file the
- * check for the existence of the file and the creation of the file if it
- * does not exist is atomic with respect to other file system operations.
- * This option is ignored when the file is opened only for reading. </td>
- * </tr>
- * <tr>
- * <td > {@link StandardOpenOption#CREATE CREATE} </td>
- * <td> If this option is present then an existing file is opened if it
- * exists, otherwise a new file is created. This option is ignored if the
- * {@code CREATE_NEW} option is also present or the file is opened only
- * for reading. </td>
- * </tr>
- * <tr>
- * <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
- * <td> When this option is present then the implementation makes a
- * <em>best effort</em> attempt to delete the file when closed by the
- * {@link SeekableByteChannel#close close} method. If the {@code close}
- * method is not invoked then a <em>best effort</em> attempt is made to
- * delete the file when the Java virtual machine terminates. </td>
- * </tr>
- * <tr>
- * <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
- * <td> When creating a new file this option is a <em>hint</em> that the
- * new file will be sparse. This option is ignored when not creating
- * a new file. </td>
- * </tr>
- * <tr>
- * <td> {@link StandardOpenOption#SYNC SYNC} </td>
- * <td> Requires that every update to the file's content or metadata be
- * written synchronously to the underlying storage device. (see <a
- * href="package-summary.html#integrity"> Synchronized I/O file
- * integrity</a>). </td>
- * <tr>
- * <tr>
- * <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
- * <td> Requires that every update to the file's content be written
- * synchronously to the underlying storage device. (see <a
- * href="package-summary.html#integrity"> Synchronized I/O file
- * integrity</a>). </td>
- * </tr>
- * </table>
- *
- * <p> An implementation may also support additional implementation specific
- * options.
- *
- * <p> The {@code attrs} parameter is an optional array of file {@link
- * FileAttribute file-attributes} to set atomically when a new file is created.
- *
- * <p> In the case of the default provider, the returned seekable byte channel
- * is a {@link java.nio.channels.FileChannel}.
- *
- * <p> <b>Usage Examples:</b>
- * <pre>
- * Path file = ...
- *
- * // open file for reading
- * ReadableByteChannel rbc = file.newByteChannel(EnumSet.of(READ)));
- *
- * // open file for writing to the end of an existing file, creating
- * // the file if it doesn't already exist
- * WritableByteChannel wbc = file.newByteChannel(EnumSet.of(CREATE,APPEND));
- *
- * // create file with initial permissions, opening it for both reading and writing
- * FileAttribute<Set<PosixFilePermission>> perms = ...
- * SeekableByteChannel sbc = file.newByteChannel(EnumSet.of(CREATE_NEW,READ,WRITE), perms);
- * </pre>
- *
- * @param options
- * Options specifying how the file is opened
- * @param attrs
- * An optional list of file attributes to set atomically when
- * creating the file
- *
- * @return a new seekable byte channel
- *
- * @throws IllegalArgumentException
- * if the set contains an invalid combination of options
- * @throws UnsupportedOperationException
- * if an unsupported open option is specified or the array contains
- * attributes that cannot be set atomically when creating the file
- * @throws FileAlreadyExistsException
- * if a file of that name already exists and the {@link
- * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
- * <i>(optional specific exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @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 path if the file is
- * opened for reading. The {@link SecurityManager#checkWrite(String)
- * checkWrite} method is invoked to check write access to the path
- * if the file is opened for writing.
- */
- public abstract SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException;
-
- /**
- * Opens or creates a file, returning a seekable byte channel to access the
- * file.
- *
- * <p> This method opens or creates a file in exactly the manner specified
- * by the {@link Path#newByteChannel(Set,FileAttribute[]) newByteChannel}
- * method.
- *
- * @param options
- * options specifying how the file is opened
- *
- * @return a new seekable byte channel
- *
- * @throws IllegalArgumentException
- * if the set contains an invalid combination of options
- * @throws UnsupportedOperationException
- * if an unsupported open option is specified
- * @throws FileAlreadyExistsException
- * if a file of that name already exists and the {@link
- * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
- * <i>(optional specific exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @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 path if the file is
- * opened for reading. The {@link SecurityManager#checkWrite(String)
- * checkWrite} method is invoked to check write access to the path
- * if the file is opened for writing.
+ * if this {@code Path} is not associated with the default provider
*/
- public abstract SeekableByteChannel newByteChannel(OpenOption... options)
- throws IOException;
-
- /**
- * Opens or creates the file located by this object for writing, returning
- * an output stream to write bytes to the file.
- *
- * <p> This method opens or creates a file in exactly the manner specified
- * by the {@link Path#newByteChannel(Set,FileAttribute[]) newByteChannel}
- * method except that the {@link StandardOpenOption#READ READ} option may not
- * be present in the array of open options.
- *
- * @param options
- * options specifying how the file is opened
- *
- * @return a new output stream
- *
- * @throws IllegalArgumentException {@inheritDoc}
- * @throws UnsupportedOperationException {@inheritDoc}
- * @throws IOException {@inheritDoc}
- * @throws SecurityException {@inheritDoc}
- */
- @Override
- public abstract OutputStream newOutputStream(OpenOption... options)
- throws IOException;
-
- /**
- * Tells whether or not the file located by this object is considered
- * <em>hidden</em>. The exact definition of hidden is platform or provider
- * dependent. On UNIX for example a file is considered to be hidden if its
- * name begins with a period character ('.'). On Windows a file is
- * considered hidden if it isn't a directory and the DOS {@link
- * DosFileAttributes#isHidden hidden} attribute is set.
- *
- * <p> Depending on the implementation this method may require to access
- * the file system to determine if the file is considered hidden.
- *
- * @return {@code true} if the file is considered hidden
- *
- * @throws IOException
- * if an I/O error occurs
- * @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.
- */
- public abstract boolean isHidden() throws IOException;
-
- /**
- * Checks the existence and optionally the accessibility of the file
- * located by this path.
- *
- * <p> This method checks the existence of a file and that this Java virtual
- * machine has appropriate privileges that would allow it access the file
- * according to all of access modes specified in the {@code modes} parameter
- * as follows:
- *
- * <table border=1 cellpadding=5 summary="">
- * <tr> <th>Value</th> <th>Description</th> </tr>
- * <tr>
- * <td> {@link AccessMode#READ READ} </td>
- * <td> Checks that the file exists and that the Java virtual machine has
- * permission to read the file. </td>
- * </tr>
- * <tr>
- * <td> {@link AccessMode#WRITE WRITE} </td>
- * <td> Checks that the file exists and that the Java virtual machine has
- * permission to write to the file, </td>
- * </tr>
- * <tr>
- * <td> {@link AccessMode#EXECUTE EXECUTE} </td>
- * <td> Checks that the file exists and that the Java virtual machine has
- * permission to {@link Runtime#exec execute} the file. The semantics
- * may differ when checking access to a directory. For example, on UNIX
- * systems, checking for {@code EXECUTE} access checks that the Java
- * virtual machine has permission to search the directory in order to
- * access file or subdirectories. </td>
- * </tr>
- * </table>
- *
- * <p> If the {@code modes} parameter is of length zero, then the existence
- * of the file is checked.
- *
- * <p> This method follows symbolic links if the file referenced by this
- * object is a symbolic link. Depending on the implementation, this method
- * may require to read file permissions, access control lists, or other
- * file attributes in order to check the effective access to the file. To
- * determine the effective access to a file may require access to several
- * attributes and so in some implementations this method may not be atomic
- * with respect to other file system operations. Furthermore, as the result
- * of this method is immediately outdated, there is no guarantee that a
- * subsequence access will succeed (or even that it will access the same
- * file). Care should be taken when using this method in security sensitive
- * applications.
- *
- * @param modes
- * The access modes to check; may have zero elements
- *
- * @throws UnsupportedOperationException
- * an implementation is required to support checking for
- * {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
- * exception is specified to allow for the {@code Access} enum to
- * be extended in future releases.
- * @throws NoSuchFileException
- * if a file does not exist <i>(optional specific exception)</i>
- * @throws AccessDeniedException
- * the requested access would be denied or the access cannot be
- * determined because the Java virtual machine has insufficient
- * privileges or other reasons. <i>(optional specific exception)</i>
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, the {@link SecurityManager#checkRead(String) checkRead}
- * is invoked when checking read access to the file or only the
- * existence of the file, the {@link SecurityManager#checkWrite(String)
- * checkWrite} is invoked when checking write access to the file,
- * and {@link SecurityManager#checkExec(String) checkExec} is invoked
- * when checking execute access.
- */
- public abstract void checkAccess(AccessMode... modes) throws IOException;
-
- /**
- * Tests whether the file located by this path exists.
- *
- * <p> This convenience method is intended for cases where it is required to
- * take action when it can be confirmed that a file exists. This method simply
- * invokes the {@link #checkAccess checkAccess} method to check if the file
- * exists. If the {@code checkAccess} method succeeds then this method returns
- * {@code true}, otherwise if an {@code IOException} is thrown (because the
- * file doesn't exist or cannot be accessed by this Java virtual machine)
- * then {@code false} is returned.
- *
- * <p> Note that the result of this method is immediately outdated. If this
- * method indicates the file exists then there is no guarantee that a
- * subsequence access will succeed. Care should be taken when using this
- * method in security sensitive applications.
- *
- * @return {@code true} if the file exists; {@code false} if the file does
- * not exist or its existence cannot be determined.
- *
- * @throws SecurityException
- * In the case of the default provider, the {@link
- * SecurityManager#checkRead(String)} is invoked to check
- * read access to the file.
- *
- * @see #notExists
- */
- public abstract boolean exists();
-
- /**
- * Tests whether the file located by this path does not exist.
- *
- * <p> This convenience method is intended for cases where it is required to
- * take action when it can be confirmed that a file does not exist. This
- * method invokes the {@link #checkAccess checkAccess} method to check if the
- * file exists. If the file does not exist then {@code true} is returned,
- * otherwise the file exists or cannot be accessed by this Java virtual
- * machine and {@code false} is returned.
- *
- * <p> Note that this method is not the complement of the {@link #exists
- * exists} method. Where it is not possible to determine if a file exists
- * or not then both methods return {@code false}. As with the {@code exists}
- * method, the result of this method is immediately outdated. If this
- * method indicates the file does exist then there is no guarantee that a
- * subsequence attempt to create the file will succeed. Care should be taken
- * when using this method in security sensitive applications.
- *
- * @return {@code true} if the file does not exist; {@code false} if the
- * file exists or its existence cannot be determined.
- *
- * @throws SecurityException
- * In the case of the default provider, the {@link
- * SecurityManager#checkRead(String)} is invoked to check
- * read access to the file.
- */
- public abstract boolean notExists();
-
- /**
- * Returns the {@link FileStore} representing the file store where an
- * existing file, located by this path, is stored.
- *
- * <p> Once a reference to the {@code FileStore} is obtained it is
- * implementation specific if operations on the returned {@code FileStore},
- * or {@link FileStoreAttributeView} objects obtained from it, continue
- * to depend on the existence of the file. In particular the behavior is not
- * defined for the case that the file is deleted or moved to a different
- * file store.
- *
- * @return the file store where the file is stored
- *
- * @throws IOException
- * if an I/O error occurs
- * @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, and in
- * addition it checks {@link RuntimePermission}<tt>
- * ("getFileStoreAttributes")</tt>
- */
- public abstract FileStore getFileStore() throws IOException;
+ File toFile();
// -- watchable --
@@ -1471,8 +594,8 @@
*
* <p> In this release, this path locates a directory that exists. The
* directory is registered with the watch service so that entries in the
- * directory can be watched. The {@code events} parameter is an array of
- * events to register and may contain the following events:
+ * directory can be watched. The {@code events} parameter is the events to
+ * register and may contain the following events:
* <ul>
* <li>{@link StandardWatchEventKind#ENTRY_CREATE ENTRY_CREATE} -
* entry created or moved into the directory</li>
@@ -1489,10 +612,10 @@
* <p> The set of events may include additional implementation specific
* event that are not defined by the enum {@link StandardWatchEventKind}
*
- * <p> The {@code modifiers} parameter is an array of <em>modifiers</em>
- * that qualify how the directory is registered. This release does not
- * define any <em>standard</em> modifiers. The array may contain
- * implementation specific modifiers.
+ * <p> The {@code modifiers} parameter specifies <em>modifiers</em> that
+ * qualify how the directory is registered. This release does not define any
+ * <em>standard</em> modifiers. It may contain implementation specific
+ * modifiers.
*
* <p> Where a file is registered with a watch service by means of a symbolic
* link then it is implementation specific if the watch continues to depend
@@ -1525,9 +648,9 @@
* method is invoked to check read access to the file.
*/
@Override
- public abstract WatchKey register(WatchService watcher,
- WatchEvent.Kind<?>[] events,
- WatchEvent.Modifier... modifiers)
+ WatchKey register(WatchService watcher,
+ WatchEvent.Kind<?>[] events,
+ WatchEvent.Modifier... modifiers)
throws IOException;
/**
@@ -1573,8 +696,8 @@
* method is invoked to check read access to the file.
*/
@Override
- public abstract WatchKey register(WatchService watcher,
- WatchEvent.Kind<?>... events)
+ WatchKey register(WatchService watcher,
+ WatchEvent.Kind<?>... events)
throws IOException;
// -- Iterable --
@@ -1591,7 +714,7 @@
* @return an iterator over the name elements of this path.
*/
@Override
- public abstract Iterator<Path> iterator();
+ Iterator<Path> iterator();
// -- compareTo/equals/hashCode --
@@ -1609,50 +732,7 @@
* lexicographically greater than the argument
*/
@Override
- public abstract int compareTo(Path other);
-
- /**
- * Tests if the file referenced by this object is the same file referenced
- * by another object.
- *
- * <p> If this {@code Path} and the given {@code Path} are {@link
- * #equals(Object) equal} then this method returns {@code true} without checking
- * if the file exists. If the {@code Path} and the given {@code Path}
- * are associated with different providers, or the given {@code Path} is
- * {@code null} then this method returns {@code false}. Otherwise, this method
- * checks if both {@code Paths} locate the same file, and depending on the
- * implementation, may require to open or access both files.
- *
- * <p> If the file system and files remain static, then this method implements
- * an equivalence relation for non-null {@code Paths}.
- * <ul>
- * <li>It is <i>reflexive</i>: for a non-null {@code Path} {@code f},
- * {@code f.isSameFile(f)} should return {@code true}.
- * <li>It is <i>symmetric</i>: for two non-null {@code Path}
- * {@code f} and {@code g}, {@code f.isSameFile(g)} will equal
- * {@code g.isSameFile(f)}.
- * <li>It is <i>transitive</i>: for three {@code Paths}
- * {@code f}, {@code g}, and {@code h}, if {@code f.isSameFile(g)} returns
- * {@code true} and {@code g.isSameFile(h)} returns {@code true}, then
- * {@code f.isSameFile(h)} will return return {@code true}.
- * </ul>
- *
- * @param other
- * the other file reference
- *
- * @return {@code true} if, and only if, this object and the given object
- * locate the same file
- *
- * @throws IOException
- * if an I/O error occurs
- * @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 both files.
- *
- * @see java.nio.file.attribute.BasicFileAttributes#fileKey
- */
- public abstract boolean isSameFile(Path other) throws IOException;
+ int compareTo(Path other);
/**
* Tests this path for equality with the given object.
@@ -1663,7 +743,9 @@
* <p> Whether or not two path are equal depends on the file system
* implementation. In some cases the paths are compared without regard
* to case, and others are case sensitive. This method does not access the
- * file system and the file is not required to exist.
+ * file system and the file is not required to exist. Where required, the
+ * {@link Files#isSameFile isSameFile} method may be used to check if two
+ * paths locate the same file.
*
* <p> This method satisfies the general contract of the {@link
* java.lang.Object#equals(Object) Object.equals} method. </p>
@@ -1674,8 +756,7 @@
* @return {@code true} if, and only if, the given object is a {@code Path}
* that is identical to this {@code Path}
*/
- @Override
- public abstract boolean equals(Object other);
+ boolean equals(Object other);
/**
* Computes a hash code for this path.
@@ -1686,8 +767,7 @@
*
* @return the hash-code value for this path
*/
- @Override
- public abstract int hashCode();
+ int hashCode();
/**
* Returns the string representation of this path.
@@ -1701,6 +781,5 @@
*
* @return the string representation of this path
*/
- @Override
- public abstract String toString();
+ String toString();
}
--- a/jdk/src/share/classes/java/nio/file/PathMatcher.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/PathMatcher.java Mon Feb 14 16:30:10 2011 -0800
@@ -32,7 +32,7 @@
* @since 1.7
*
* @see FileSystem#getPathMatcher
- * @see Path#newDirectoryStream(String)
+ * @see Files#newDirectoryStream(Path,String)
*/
public interface PathMatcher {
--- a/jdk/src/share/classes/java/nio/file/Paths.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/Paths.java Mon Feb 14 16:30:10 2011 -0800
@@ -39,14 +39,27 @@
private Paths() { }
/**
- * Constructs a {@code Path} by converting the given path string.
+ * Converts a path string, or a sequence of strings that when joined form
+ * a path string, to a {@code Path}. If {@code more} does not specify any
+ * elements then the value of the {@code first} parameter is the path string
+ * to convert. If {@code more} specifies one or more elements then each
+ * non-empty string, including {@code first}, is considered to be a sequence
+ * of name elements (see {@link Path}) and is joined to form a path string.
+ * The details as to how the Strings are joined is provider specific but
+ * typically they will be joined using the {@link FileSystem#getSeparator
+ * name-separator} as the separator. For example, if the name separator is
+ * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the
+ * path string {@code "/foo/bar/gus"} is converted to a {@code Path}.
+ * A {@code Path} representing an empty path is returned if {@code first}
+ * is the empty string and {@code more} does not contain any non-empty
+ * strings.
*
* <p> The {@code Path} is obtained by invoking the {@link FileSystem#getPath
* getPath} method of the {@link FileSystems#getDefault default} {@link
* FileSystem}.
*
- * <p> Note that while this method is very convenient, using it will
- * imply an assumed reference to the default FileSystem and limit the
+ * <p> Note that while this method is very convenient, using it will imply
+ * an assumed reference to the default {@code FileSystem} and limit the
* utility of the calling code. Hence it should not be used in library code
* intended for flexible reuse. A more flexible alternative is to use an
* existing {@code Path} instance as an anchor, such as:
@@ -55,8 +68,10 @@
* Path path = dir.resolve("file");
* </pre>
*
- * @param path
- * the path string to convert
+ * @param first
+ * the path string or initial part of the path string
+ * @param more
+ * additional strings to be joined to form the path string
*
* @return the resulting {@code Path}
*
@@ -65,8 +80,8 @@
*
* @see FileSystem#getPath
*/
- public static Path get(String path) {
- return FileSystems.getDefault().getPath(path);
+ public static Path get(String first, String... more) {
+ return FileSystems.getDefault().getPath(first, more);
}
/**
--- a/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java Mon Feb 14 16:30:10 2011 -0800
@@ -43,7 +43,7 @@
*
* <p> A {@code SecureDirectoryStream} requires corresponding support from the
* underlying operating system. Where an implementation supports this features
- * then the {@code DirectoryStream} returned by the {@link Path#newDirectoryStream
+ * then the {@code DirectoryStream} returned by the {@link Files#newDirectoryStream
* newDirectoryStream} method will be a {@code SecureDirectoryStream} and must
* be cast to that type in order to invoke the methods defined by this interface.
*
@@ -56,20 +56,15 @@
* @since 1.7
*/
-public abstract class SecureDirectoryStream<T>
- implements DirectoryStream<T>
+public interface SecureDirectoryStream<T>
+ extends DirectoryStream<T>
{
/**
- * Initialize a new instance of this class.
- */
- protected SecureDirectoryStream() { }
-
- /**
* Opens the directory identified by the given path, returning a {@code
* SecureDirectoryStream} to iterate over the entries in the directory.
*
* <p> This method works in exactly the manner specified by the {@link
- * Path#newDirectoryStream() newDirectoryStream} method for the case that
+ * Files#newDirectoryStream(Path) newDirectoryStream} method for the case that
* the {@code path} parameter is an {@link Path#isAbsolute absolute} path.
* When the parameter is a relative path then the directory to open is
* relative to this open directory. The {@link
@@ -99,8 +94,7 @@
* installed, the {@link SecurityManager#checkRead(String) checkRead}
* method is invoked to check read access to the directory.
*/
- public abstract SecureDirectoryStream<T> newDirectoryStream(T path,
- LinkOption... options)
+ SecureDirectoryStream<T> newDirectoryStream(T path, LinkOption... options)
throws IOException;
/**
@@ -108,11 +102,11 @@
* channel to access the file.
*
* <p> This method works in exactly the manner specified by the {@link
- * Path#newByteChannel Path.newByteChannel} method for the
+ * Files#newByteChannel Files.newByteChannel} method for the
* case that the {@code path} parameter is an {@link Path#isAbsolute absolute}
* path. When the parameter is a relative path then the file to open or
* create is relative to this open directory. In addition to the options
- * defined by the {@code Path.newByteChannel} method, the {@link
+ * defined by the {@code Files.newByteChannel} method, the {@link
* LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
* ensure that this method fails if the file is a symbolic link.
*
@@ -149,15 +143,15 @@
* checkWrite} method is invoked to check write access to the path
* if the file is opened for writing.
*/
- public abstract SeekableByteChannel newByteChannel(T path,
- Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
+ SeekableByteChannel newByteChannel(T path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
throws IOException;
/**
* Deletes a file.
*
- * <p> Unlike the {@link Path#delete delete()} method, this method does
+ * <p> Unlike the {@link Files#delete delete()} method, this method does
* not first examine the file to determine if the file is a directory.
* Whether a directory is deleted by this method is system dependent and
* therefore not specified. If the file is a symbolic link, then the link
@@ -179,12 +173,12 @@
* installed, the {@link SecurityManager#checkDelete(String) checkDelete}
* method is invoked to check delete access to the file
*/
- public abstract void deleteFile(T path) throws IOException;
+ void deleteFile(T path) throws IOException;
/**
* Deletes a directory.
*
- * <p> Unlike the {@link Path#delete delete()} method, this method
+ * <p> Unlike the {@link Files#delete delete()} method, this method
* does not first examine the file to determine if the file is a directory.
* Whether non-directories are deleted by this method is system dependent and
* therefore not specified. When the parameter is a relative path then the
@@ -207,12 +201,12 @@
* installed, the {@link SecurityManager#checkDelete(String) checkDelete}
* method is invoked to check delete access to the directory
*/
- public abstract void deleteDirectory(T path) throws IOException;
+ void deleteDirectory(T path) throws IOException;
/**
* Move a file from this directory to another directory.
*
- * <p> This method works in a similar manner to {@link Path#moveTo moveTo}
+ * <p> This method works in a similar manner to {@link Files#move move}
* method when the {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} option
* is specified. That is, this method moves a file as an atomic file system
* operation. If the {@code srcpath} parameter is an {@link Path#isAbsolute
@@ -247,7 +241,7 @@
* method is invoked to check write access to both the source and
* target file.
*/
- public abstract void move(T srcpath, SecureDirectoryStream<T> targetdir, T targetpath)
+ void move(T srcpath, SecureDirectoryStream<T> targetdir, T targetpath)
throws IOException;
/**
@@ -273,7 +267,7 @@
* this directory stream, or {@code null} if the attribute view
* type is not available
*/
- public abstract <V extends FileAttributeView> V getFileAttributeView(Class<V> type);
+ <V extends FileAttributeView> V getFileAttributeView(Class<V> type);
/**
* Returns a new file attribute view to access the file attributes of a file
@@ -306,7 +300,7 @@
* type is not available
*
*/
- public abstract <V extends FileAttributeView> V getFileAttributeView(T path,
- Class<V> type,
- LinkOption... options);
+ <V extends FileAttributeView> V getFileAttributeView(T path,
+ Class<V> type,
+ LinkOption... options);
}
--- a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java Mon Feb 14 16:30:10 2011 -0800
@@ -57,8 +57,8 @@
public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
throws IOException
{
- Objects.nonNull(dir);
- Objects.nonNull(attrs);
+ Objects.requireNonNull(dir);
+ Objects.requireNonNull(attrs);
return FileVisitResult.CONTINUE;
}
@@ -72,8 +72,8 @@
public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
throws IOException
{
- Objects.nonNull(file);
- Objects.nonNull(attrs);
+ Objects.requireNonNull(file);
+ Objects.requireNonNull(attrs);
return FileVisitResult.CONTINUE;
}
@@ -87,7 +87,7 @@
public FileVisitResult visitFileFailed(T file, IOException exc)
throws IOException
{
- Objects.nonNull(file);
+ Objects.requireNonNull(file);
throw exc;
}
@@ -104,7 +104,7 @@
public FileVisitResult postVisitDirectory(T dir, IOException exc)
throws IOException
{
- Objects.nonNull(dir);
+ Objects.requireNonNull(dir);
if (exc != null)
throw exc;
return FileVisitResult.CONTINUE;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/TempFileHelper.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.util.Set;
+import java.util.EnumSet;
+import java.security.SecureRandom;
+import static java.security.AccessController.*;
+import java.io.IOException;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import static java.nio.file.attribute.PosixFilePermission.*;
+import sun.security.action.GetPropertyAction;
+
+
+/**
+ * Helper class to support creation of temporary files and directories with
+ * initial attributes.
+ */
+
+class TempFileHelper {
+ private TempFileHelper() { }
+
+ // temporary directory location
+ private static final Path tmpdir =
+ Paths.get(doPrivileged(new GetPropertyAction("java.io.tmpdir")));
+
+ private static final boolean isPosix =
+ FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
+
+ // file name generation, same as java.io.File for now
+ private static final SecureRandom random = new SecureRandom();
+ private static Path generatePath(String prefix, String suffix, Path dir) {
+ long n = random.nextLong();
+ n = (n == Long.MIN_VALUE) ? 0 : Math.abs(n);
+ Path name = dir.getFileSystem().getPath(prefix + Long.toString(n) + suffix);
+ // the generated name should be a simple file name
+ if (name.getParent() != null)
+ throw new IllegalArgumentException("Invalid prefix or suffix");
+ return dir.resolve(name);
+ }
+
+ // default file and directory permissions (lazily initialized)
+ private static class PosixPermissions {
+ static final FileAttribute<Set<PosixFilePermission>> filePermissions =
+ PosixFilePermissions.asFileAttribute(EnumSet.of(OWNER_READ, OWNER_WRITE));
+ static final FileAttribute<Set<PosixFilePermission>> dirPermissions =
+ PosixFilePermissions.asFileAttribute(EnumSet
+ .of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE));
+ }
+
+ /**
+ * Creates a file or directory in in the given given directory (or in the
+ * temporary directory if dir is {@code null}).
+ */
+ private static Path create(Path dir,
+ String prefix,
+ String suffix,
+ boolean createDirectory,
+ FileAttribute[] attrs)
+ throws IOException
+ {
+ if (prefix == null)
+ prefix = "";
+ if (suffix == null)
+ suffix = (createDirectory) ? "" : ".tmp";
+ if (dir == null)
+ dir = tmpdir;
+
+ // in POSIX environments use default file and directory permissions
+ // if initial permissions not given by caller.
+ if (isPosix && (dir.getFileSystem() == FileSystems.getDefault())) {
+ if (attrs.length == 0) {
+ // no attributes so use default permissions
+ attrs = new FileAttribute<?>[1];
+ attrs[0] = (createDirectory) ? PosixPermissions.dirPermissions :
+ PosixPermissions.filePermissions;
+ } else {
+ // check if posix permissions given; if not use default
+ boolean hasPermissions = false;
+ for (int i=0; i<attrs.length; i++) {
+ if (attrs[i].name().equals("posix:permissions")) {
+ hasPermissions = true;
+ break;
+ }
+ }
+ if (!hasPermissions) {
+ FileAttribute<?>[] copy = new FileAttribute<?>[attrs.length+1];
+ System.arraycopy(attrs, 0, copy, 0, attrs.length);
+ attrs = copy;
+ attrs[attrs.length-1] = (createDirectory) ?
+ PosixPermissions.dirPermissions :
+ PosixPermissions.filePermissions;
+ }
+ }
+ }
+
+ // loop generating random names until file or directory can be created
+ SecurityManager sm = System.getSecurityManager();
+ for (;;) {
+ Path f;
+ try {
+ f = generatePath(prefix, suffix, dir);
+ } catch (InvalidPathException e) {
+ // don't reveal temporary directory location
+ if (sm != null)
+ throw new IllegalArgumentException("Invalid prefix or suffix");
+ throw e;
+ }
+ try {
+ if (createDirectory) {
+ return Files.createDirectory(f, attrs);
+ } else {
+ return Files.createFile(f, attrs);
+ }
+ } catch (SecurityException e) {
+ // don't reveal temporary directory location
+ if (dir == tmpdir && sm != null)
+ throw new SecurityException("Unable to create temporary file or directory");
+ throw e;
+ } catch (FileAlreadyExistsException e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Creates a temporary file in the given directory, or in in the
+ * temporary directory if dir is {@code null}.
+ */
+ static Path createTempFile(Path dir,
+ String prefix,
+ String suffix,
+ FileAttribute[] attrs)
+ throws IOException
+ {
+ return create(dir, prefix, suffix, false, attrs);
+ }
+
+ /**
+ * Creates a temporary directory in the given directory, or in in the
+ * temporary directory if dir is {@code null}.
+ */
+ static Path createTempDirectory(Path dir,
+ String prefix,
+ FileAttribute[] attrs)
+ throws IOException
+ {
+ return create(dir, prefix, null, true, attrs);
+ }
+}
--- a/jdk/src/share/classes/java/nio/file/WatchEvent.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/WatchEvent.java Mon Feb 14 16:30:10 2011 -0800
@@ -44,7 +44,7 @@
* @since 1.7
*/
-public abstract class WatchEvent<T> {
+public interface WatchEvent<T> {
/**
* An event kind, for the purposes of identification.
@@ -65,11 +65,6 @@
}
/**
- * Initializes a new instance of this class.
- */
- protected WatchEvent() { }
-
- /**
* An event modifier that qualifies how a {@link Watchable} is registered
* with a {@link WatchService}.
*
@@ -90,7 +85,7 @@
*
* @return the event kind
*/
- public abstract Kind<T> kind();
+ Kind<T> kind();
/**
* Returns the event count. If the event count is greater than {@code 1}
@@ -98,7 +93,7 @@
*
* @return the event count
*/
- public abstract int count();
+ int count();
/**
* Returns the context for the event.
@@ -112,5 +107,5 @@
*
* @return the event context; may be {@code null}
*/
- public abstract T context();
+ T context();
}
--- a/jdk/src/share/classes/java/nio/file/WatchKey.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/WatchKey.java Mon Feb 14 16:30:10 2011 -0800
@@ -81,11 +81,7 @@
* @since 1.7
*/
-public abstract class WatchKey {
- /**
- * Initializes a new instance of this class.
- */
- protected WatchKey() { }
+public interface WatchKey {
/**
* Tells whether or not this watch key is valid.
@@ -95,7 +91,7 @@
*
* @return {@code true} if, and only if, this watch key is valid
*/
- public abstract boolean isValid();
+ boolean isValid();
/**
* Retrieves and removes all pending events for this watch key, returning
@@ -105,7 +101,7 @@
*
* @return the list of the events retrieved; may be empty
*/
- public abstract List<WatchEvent<?>> pollEvents();
+ List<WatchEvent<?>> pollEvents();
/**
* Resets this watch key.
@@ -121,7 +117,7 @@
* {@code false} if the watch key could not be reset because it is
* no longer {@link #isValid valid}
*/
- public abstract boolean reset();
+ boolean reset();
/**
* Cancels the registration with the watch service. Upon return the watch key
@@ -134,5 +130,21 @@
* <p> If this watch key has already been cancelled then invoking this
* method has no effect. Once cancelled, a watch key remains forever invalid.
*/
- public abstract void cancel();
+ void cancel();
+
+ /**
+ * Returns the object for which this watch key was created. This method will
+ * continue to return the object even after the key is cancelled.
+ *
+ * <p> As the {@code WatchService} is intended to map directly on to the
+ * native file event notification facility (where available) then many of
+ * details on how registered objects are watched is highly implementation
+ * specific. When watching a directory for changes for example, and the
+ * directory is moved or renamed in the file system, there is no guarantee
+ * that the watch key will be cancelled and so the object returned by this
+ * method may no longer be a valid path to the directory.
+ *
+ * @return the object for which this watch key was created
+ */
+ //T watchable();
}
--- a/jdk/src/share/classes/java/nio/file/WatchService.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/WatchService.java Mon Feb 14 16:30:10 2011 -0800
@@ -103,13 +103,9 @@
* @see FileSystem#newWatchService
*/
-public abstract class WatchService
- implements Closeable
+public interface WatchService
+ extends Closeable
{
- /**
- * Initializes a new instance of this class.
- */
- protected WatchService() { }
/**
* Closes this watch service.
@@ -129,7 +125,7 @@
* if an I/O error occurs
*/
@Override
- public abstract void close() throws IOException;
+ void close() throws IOException;
/**
* Retrieves and removes the next watch key, or {@code null} if none are
@@ -140,7 +136,7 @@
* @throws ClosedWatchServiceException
* if this watch service is closed
*/
- public abstract WatchKey poll();
+ WatchKey poll();
/**
* Retrieves and removes the next watch key, waiting if necessary up to the
@@ -160,7 +156,7 @@
* @throws InterruptedException
* if interrupted while waiting
*/
- public abstract WatchKey poll(long timeout, TimeUnit unit)
+ WatchKey poll(long timeout, TimeUnit unit)
throws InterruptedException;
/**
@@ -174,5 +170,5 @@
* @throws InterruptedException
* if interrupted while waiting
*/
- public abstract WatchKey take() throws InterruptedException;
+ WatchKey take() throws InterruptedException;
}
--- a/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java Mon Feb 14 16:30:10 2011 -0800
@@ -176,7 +176,7 @@
*/
public Builder setPermissions(Set<AclEntryPermission> perms) {
// copy and check for erroneous elements
- perms = new HashSet<AclEntryPermission>(perms);
+ perms = EnumSet.copyOf(perms);
checkSet(perms, AclEntryPermission.class);
this.perms = perms;
return this;
@@ -190,8 +190,7 @@
* @return this builder
*/
public Builder setPermissions(AclEntryPermission... perms) {
- Set<AclEntryPermission> set =
- new HashSet<AclEntryPermission>(perms.length);
+ Set<AclEntryPermission> set = EnumSet.noneOf(AclEntryPermission.class);
// copy and check for null elements
for (AclEntryPermission p: perms) {
if (p == null)
@@ -214,7 +213,7 @@
*/
public Builder setFlags(Set<AclEntryFlag> flags) {
// copy and check for erroneous elements
- flags = new HashSet<AclEntryFlag>(flags);
+ flags = EnumSet.copyOf(flags);
checkSet(flags, AclEntryFlag.class);
this.flags = flags;
return this;
@@ -228,7 +227,7 @@
* @return this builder
*/
public Builder setFlags(AclEntryFlag... flags) {
- Set<AclEntryFlag> set = new HashSet<AclEntryFlag>(flags.length);
+ Set<AclEntryFlag> set = EnumSet.noneOf(AclEntryFlag.class);
// copy and check for null elements
for (AclEntryFlag f: flags) {
if (f == null)
--- a/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -65,7 +65,7 @@
* UserPrincipalLookupService} may be used to obtain a {@link UserPrincipal}
* to represent these special identities by invoking the {@link
* UserPrincipalLookupService#lookupPrincipalByName lookupPrincipalByName}
- * method.
+ * method. </p>
*
* <p> <b>Usage Example:</b>
* Suppose we wish to add an entry to an existing ACL to grant "joe" access:
@@ -75,7 +75,7 @@
* .lookupPrincipalByName("joe");
*
* // get view
- * AclFileAttributeView view = file.getFileAttributeView(AclFileAttributeView.class);
+ * AclFileAttributeView view = Files.getFileAttributeView(file, AclFileAttributeView.class);
*
* // create ACE to give "joe" read access
* AclEntry entry = AclEntry.newBuilder()
@@ -110,11 +110,11 @@
* </table>
* </blockquote>
*
- * <p> The {@link FileRef#getAttribute getAttribute} method may be used to read
+ * <p> The {@link Files#getAttribute getAttribute} method may be used to read
* the ACL or owner attributes as if by invoking the {@link #getAcl getAcl} or
* {@link #getOwner getOwner} methods.
*
- * <p> The {@link FileRef#setAttribute setAttribute} method may be used to
+ * <p> The {@link Files#setAttribute setAttribute} method may be used to
* update the ACL or owner attributes as if by invoking the {@link #setAcl setAcl}
* or {@link #setOwner setOwner} methods.
*
@@ -122,8 +122,8 @@
*
* <p> Implementations supporting this attribute view may also support setting
* the initial ACL when creating a file or directory. The initial ACL
- * may be provided to methods such as {@link Path#createFile createFile} or {@link
- * Path#createDirectory createDirectory} as an {@link FileAttribute} with {@link
+ * may be provided to methods such as {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} as an {@link FileAttribute} with {@link
* FileAttribute#name name} {@code "acl:acl"} and a {@link FileAttribute#value
* value} that is the list of {@code AclEntry} objects.
*
@@ -135,8 +135,6 @@
* translation.
*
* @since 1.7
- * @see Attributes#getAcl
- * @see Attributes#setAcl
*/
public interface AclFileAttributeView
--- a/jdk/src/share/classes/java/nio/file/attribute/Attributes.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,460 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-import java.nio.file.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * This class consists exclusively of static methods that operate on or return
- * the attributes of files or file stores. These methods provide for convenient
- * use of the {@link AttributeView attribute-views} defined in this package.
- *
- * @since 1.7
- */
-
-public final class Attributes {
- private Attributes() { }
-
- /**
- * Reads the basic file attributes of a file.
- *
- * <p> The {@code options} array may be used to indicate how symbolic links
- * are handled for the case that the file is a symbolic link. By default,
- * symbolic links are followed and the file attributes of the final target
- * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
- * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
- * the method returns the file attributes of the symbolic link itself.
- * This option should be used where there is a need to determine if a
- * file is a symbolic link:
- * <pre>
- * boolean isSymbolicLink = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS).isSymbolicLink();
- * </pre>
- *
- * <p> It is implementation specific if all file attributes are read as an
- * atomic operation with respect to other file system operations.
- *
- * @param file
- * A file reference that locates the file
- * @param options
- * Options indicating how symbolic links are handled
- *
- * @return The basic file attributes
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkRead(String) checkRead} method is invoked
- * to check read access to file
- *
- * @see BasicFileAttributeView#readAttributes
- */
- public static BasicFileAttributes readBasicFileAttributes(FileRef file,
- LinkOption... options)
- throws IOException
- {
- return file.getFileAttributeView(BasicFileAttributeView.class, options)
- .readAttributes();
- }
-
- /**
- * Reads the POSIX file attributes of a file.
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * PosixFileAttributeView}. This file attribute view provides access to a
- * subset of the file attributes commonly associated with files on file
- * systems used by operating systems that implement the Portable Operating
- * System Interface (POSIX) family of standards. It is implementation
- * specific if all file attributes are read as an atomic operation with
- * respect to other file system operations.
- *
- * <p> The {@code options} array may be used to indicate how symbolic links
- * are handled for the case that the file is a symbolic link. By default,
- * symbolic links are followed and the file attributes of the final target
- * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
- * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
- * the method returns the file attributes of the symbolic link itself.
- *
- * @param file
- * A file reference that locates the file
- * @param options
- * Options indicating how symbolic links are handled
- *
- * @return The POSIX file attributes
- *
- * @throws UnsupportedOperationException
- * If the {@code PosixFileAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkRead(String) checkRead} method
- * denies read access to the file.
- *
- * @see PosixFileAttributeView#readAttributes
- */
- public static PosixFileAttributes readPosixFileAttributes(FileRef file,
- LinkOption... options)
- throws IOException
- {
- PosixFileAttributeView view =
- file.getFileAttributeView(PosixFileAttributeView.class, options);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.readAttributes();
- }
-
- /**
- * Reads the DOS file attributes of a file.
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * DosFileAttributeView}. This file attribute view provides access to
- * legacy "DOS" attributes supported by the file systems such as File
- * Allocation Table (FAT), commonly used in <em>consumer devices</em>. It is
- * implementation specific if all file attributes are read as an atomic
- * operation with respect to other file system operations.
- *
- * <p> The {@code options} array may be used to indicate how symbolic links
- * are handled for the case that the file is a symbolic link. By default,
- * symbolic links are followed and the file attributes of the final target
- * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
- * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
- * the method returns the file attributes of the symbolic link itself.
- *
- * @param file
- * A file reference that locates the file
- * @param options
- * Options indicating how symbolic links are handled
- *
- * @return The DOS file attributes
- *
- * @throws UnsupportedOperationException
- * If the {@code DosFileAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkRead(String) checkRead} method is invoked
- * to check read access to file
- *
- * @see DosFileAttributeView#readAttributes
- */
- public static DosFileAttributes readDosFileAttributes(FileRef file,
- LinkOption... options)
- throws IOException
- {
- DosFileAttributeView view =
- file.getFileAttributeView(DosFileAttributeView.class, options);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.readAttributes();
- }
-
- /**
- * Returns the owner of a file.
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * FileOwnerAttributeView}. This file attribute view provides access to
- * a file attribute that is the owner of the file.
- *
- * @param file
- * A file reference that locates the file
- *
- * @return A user principal representing the owner of the file
- *
- * @throws UnsupportedOperationException
- * If the {@code FileOwnerAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkRead(String) checkRead} method
- * denies read access to the file.
- *
- * @see FileOwnerAttributeView#getOwner
- */
- public static UserPrincipal getOwner(FileRef file) throws IOException {
- FileOwnerAttributeView view =
- file.getFileAttributeView(FileOwnerAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.getOwner();
- }
-
- /**
- * Updates the file owner.
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * FileOwnerAttributeView}. This file attribute view provides access to
- * a file attribute that is the owner of the file.
- *
- * @param file
- * A file reference that locates the file
- * @param owner
- * The new file owner
- *
- * @throws UnsupportedOperationException
- * If the {@code FileOwnerAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the file.
- *
- * @see FileOwnerAttributeView#setOwner
- */
- public static void setOwner(FileRef file, UserPrincipal owner)
- throws IOException
- {
- FileOwnerAttributeView view =
- file.getFileAttributeView(FileOwnerAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- view.setOwner(owner);
- }
-
- /**
- * Reads a file's Access Control List (ACL).
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * AclFileAttributeView}. This file attribute view provides access to ACLs
- * based on the ACL model specified in
- * <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC 3530</i></a>.
- *
- * @param file
- * A file reference that locates the file
- *
- * @return An ordered list of {@link AclEntry entries} representing the
- * ACL. The returned list is modifiable.
- *
- * @throws UnsupportedOperationException
- * If the {@code AclAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkRead(String) checkRead} method
- * denies read access to the file.
- *
- * @see AclFileAttributeView#getAcl
- */
- public static List<AclEntry> getAcl(FileRef file) throws IOException {
- AclFileAttributeView view =
- file.getFileAttributeView(AclFileAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.getAcl();
- }
-
- /**
- * Updates a file's Access Control List (ACL).
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * AclFileAttributeView}. This file attribute view provides access to ACLs
- * based on the ACL model specified in
- * <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC 3530</i></a>.
- *
- * @param file
- * A file reference that locates the file
- * @param acl
- * The new file ACL
- *
- * @throws UnsupportedOperationException
- * If the {@code AclFileAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the file.
- *
- * @see AclFileAttributeView#setAcl
- */
- public static void setAcl(FileRef file, List<AclEntry> acl)
- throws IOException
- {
- AclFileAttributeView view =
- file.getFileAttributeView(AclFileAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- view.setAcl(acl);
- }
-
- /**
- * Updates a file's last modified time attribute. The file time is converted
- * to the epoch and precision supported by the file system. Converting from
- * finer to coarser granularities result in precision loss. The behavior of
- * this method when attempting to set a timestamp to a value that is outside
- * the range supported by the underlying file store is not defined. It may
- * or not fail by throwing an {@code IOException}.
- *
- * <p> If the file system does not support a last modified time attribute
- * then this method has no effect.
- *
- * <p> <b>Usage Example:</b>
- * Suppose we want to set the last modified time to the current time:
- * <pre>
- * FileTime now = FileTime.fromMillis(System.currentTimeMillis());
- * Attributes.setLastModifiedTime(file, now);
- * </pre>
- *
- * @param file
- * A file reference that locates the file
- * @param lastModifiedTime
- * The new last modified time
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkWrite(String) checkWrite} method is invoked
- * to check write access to file
- *
- * @see BasicFileAttributeView#setTimes
- */
- public static void setLastModifiedTime(FileRef file,
- FileTime lastModifiedTime)
- throws IOException
- {
- if (lastModifiedTime == null)
- throw new NullPointerException("'lastModifiedTime' is null");
- file.getFileAttributeView(BasicFileAttributeView.class)
- .setTimes(lastModifiedTime, null, null);
- }
-
- /**
- * Updates a file's last access time attribute. The file time is converted
- * to the epoch and precision supported by the file system. Converting from
- * finer to coarser granularities result in precision loss. The behavior of
- * this method when attempting to set a timestamp to a value that is outside
- * the range supported by the underlying file store is not defined. It may
- * or not fail by throwing an {@code IOException}.
- *
- * <p> If the file system does not support a last access time attribute then
- * this method has no effect.
- *
- * @param file
- * A file reference that locates the file
- * @param lastAccessTime
- * The new last access time
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkWrite(String) checkWrite} method is invoked
- * to check write access to file
- *
- * @see BasicFileAttributeView#setTimes
- */
- public static void setLastAccessTime(FileRef file,
- FileTime lastAccessTime)
- throws IOException
- {
- if (lastAccessTime == null)
- throw new NullPointerException("'lastAccessTime' is null");
- file.getFileAttributeView(BasicFileAttributeView.class)
- .setTimes(null, lastAccessTime, null);
- }
-
- /**
- * Sets a file's POSIX permissions.
- *
- * <p> The {@code file} parameter is a reference to an existing file. It
- * supports the {@link PosixFileAttributeView} that provides access to file
- * attributes commonly associated with files on file systems used by
- * operating systems that implement the Portable Operating System Interface
- * (POSIX) family of standards.
- *
- * @param file
- * A file reference that locates the file
- * @param perms
- * The new set of permissions
- *
- * @throws UnsupportedOperationException
- * If {@code PosixFileAttributeView} is not available
- * @throws ClassCastException
- * If the sets contains elements that are not of type {@code
- * PosixFilePermission}
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the file.
- *
- * @see PosixFileAttributeView#setPermissions
- */
- public static void setPosixFilePermissions(FileRef file,
- Set<PosixFilePermission> perms)
- throws IOException
- {
- PosixFileAttributeView view =
- file.getFileAttributeView(PosixFileAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- view.setPermissions(perms);
- }
-
- /**
- * Reads the space attributes of a file store.
- *
- * <p> The {@code store} parameter is a file store that supports the
- * {@link FileStoreSpaceAttributeView} providing access to the space related
- * attributes of the file store. It is implementation specific if all attributes
- * are read as an atomic operation with respect to other file system operations.
- *
- * @param store
- * The file store
- *
- * @return The file store space attributes
- *
- * @throws UnsupportedOperationException
- * If the file store space attribute view is not supported
- * @throws IOException
- * If an I/O error occurs
- *
- * @see FileStoreSpaceAttributeView#readAttributes()
- */
- public static FileStoreSpaceAttributes readFileStoreSpaceAttributes(FileStore store)
- throws IOException
- {
- FileStoreSpaceAttributeView view =
- store.getFileStoreAttributeView(FileStoreSpaceAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.readAttributes();
- }
-}
--- a/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -85,16 +85,15 @@
* </table>
* </blockquote>
*
- * <p> The {@link java.nio.file.FileRef#getAttribute getAttribute} method may be
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} method may be
* used to read any of these attributes as if by invoking the {@link
* #readAttributes() readAttributes()} method.
*
- * <p> The {@link java.nio.file.FileRef#setAttribute setAttribute} method may be
+ * <p> The {@link java.nio.file.Files#setAttribute setAttribute} method may be
* used to update the file's last modified time, last access time or create time
* attributes as if by invoking the {@link #setTimes setTimes} method.
*
* @since 1.7
- * @see Attributes
*/
public interface BasicFileAttributeView
@@ -131,9 +130,10 @@
* <p> This method updates the file's timestamp attributes. The values are
* converted to the epoch and precision supported by the file system.
* Converting from finer to coarser granularities result in precision loss.
- * The behavior of this method when attempting to set a timestamp to a value
- * that is outside the range supported by the underlying file store is not
- * defined. It may or not fail by throwing an {@code IOException}.
+ * The behavior of this method when attempting to set a timestamp that is
+ * not supported or to a value that is outside the range supported by the
+ * underlying file store is not defined. It may or not fail by throwing an
+ * {@code IOException}.
*
* <p> If any of the {@code lastModifiedTime}, {@code lastAccessTime},
* or {@code createTime} parameters has the value {@code null} then the
@@ -146,6 +146,14 @@
* lastAccessTime} and {@code createTime} parameters are {@code null} then
* this method has no effect.
*
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to change a file's creation time.
+ * <pre>
+ * Path path = ...
+ * FileTime time = ...
+ * Files.getFileAttributeView(path, BasicFileAttributeView.class).setTimes(null, null, time);
+ * </pre>
+ *
* @param lastModifiedTime
* the new last modified time, or {@code null} to not change the
* value
@@ -160,6 +168,8 @@
* In the case of the default provider, a security manager is
* installed, its {@link SecurityManager#checkWrite(String) checkWrite}
* method is invoked to check write access to the file
+ *
+ * @see java.nio.file.Files#setLastModifiedTime
*/
void setTimes(FileTime lastModifiedTime,
FileTime lastAccessTime,
--- a/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java Mon Feb 14 16:30:10 2011 -0800
@@ -34,8 +34,8 @@
*
* <p> <b>Usage Example:</b>
* <pre>
- * FileRef file = ...
- * BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+ * Path file = ...
+ * BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
* </pre>
*
* @since 1.7
@@ -48,25 +48,40 @@
/**
* Returns the time of last modification.
*
+ * <p> If the file system implementation does not support a time stamp
+ * to indicate the time of last modification then this method returns an
+ * implementation specific default value, typically a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
+ *
* @return a {@code FileTime} representing the time the file was last
- * modified or {@code null} if the attribute is not supported.
+ * modified
*/
FileTime lastModifiedTime();
/**
- * Returns the time of last access if supported.
+ * Returns the time of last access.
*
- * @return a {@code FileTime} representing the time of last access or
- * {@code null} if the attribute is not supported.
+ * <p> If the file system implementation does not support a time stamp
+ * to indicate the time of last access then this method returns
+ * an implementation specific default value, typically the {@link
+ * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
+ *
+ * @return a {@code FileTime} representing the time of last access
*/
FileTime lastAccessTime();
/**
- * Returns the creation time if supported. The creation time is the time
- * that the file was created.
+ * Returns the creation time. The creation time is the time that the file
+ * was created.
*
- * @return a {@code FileTime} representing the time the file was created
- * or {@code null} if the attribute is not supported.
+ * <p> If the file system implementation does not support a time stamp
+ * to indicate the time when the file was created then this method returns
+ * an implementation specific default value, typically the {@link
+ * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
+ *
+ * @return a {@code FileTime} representing the time the file was created
*/
FileTime creationTime();
@@ -120,7 +135,7 @@
*
* <p> File keys returned by this method can be compared for equality and are
* suitable for use in collections. If the file system and files remain static,
- * and two files are the {@link java.nio.file.Path#isSameFile same} with
+ * and two files are the {@link java.nio.file.Files#isSameFile same} with
* non-{@code null} file keys, then their file keys are equal.
*
* @see java.nio.file.Files#walkFileTree
--- a/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -65,12 +65,12 @@
* </table>
* </blockquote>
*
- * <p> The {@link java.nio.file.FileRef#getAttribute getAttribute} method may
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} method may
* be used to read any of these attributes, or any of the attributes defined by
* {@link BasicFileAttributeView} as if by invoking the {@link #readAttributes
* readAttributes()} method.
*
- * <p> The {@link java.nio.file.FileRef#setAttribute setAttribute} method may
+ * <p> The {@link java.nio.file.Files#setAttribute setAttribute} method may
* be used to update the file's last modified time, last access time or create
* time attributes as defined by {@link BasicFileAttributeView}. It may also be
* used to update the DOS attributes as if by invoking the {@link #setReadOnly
--- a/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributes.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributes.java Mon Feb 14 16:30:10 2011 -0800
@@ -29,13 +29,13 @@
* File attributes associated with a file in a file system that supports
* legacy "DOS" attributes.
*
- * <p> The DOS attributes of a file are retrieved using a {@link
- * DosFileAttributeView} by invoking its {@link DosFileAttributeView#readAttributes
- * readAttributes} method.
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ * Path file = ...
+ * DosFileAttributes attrs = Files.readAttributes(file, DosFileAttributes.class);
+ * </pre>
*
* @since 1.7
- *
- * @see Attributes#readDosFileAttributes
*/
public interface DosFileAttributes
--- a/jdk/src/share/classes/java/nio/file/attribute/FileAttribute.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileAttribute.java Mon Feb 14 16:30:10 2011 -0800
@@ -28,8 +28,8 @@
/**
* An object that encapsulates the value of a file attribute that can be set
* atomically when creating a new file or directory by invoking the {@link
- * java.nio.file.Path#createFile createFile} or {@link
- * java.nio.file.Path#createDirectory createDirectory} methods.
+ * java.nio.file.Files#createFile createFile} or {@link
+ * java.nio.file.Files#createDirectory createDirectory} methods.
*
* @param <T> The type of the file attribute value
*
--- a/jdk/src/share/classes/java/nio/file/attribute/FileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -33,7 +33,7 @@
*
* @since 1.7
*
- * @see java.nio.file.FileRef#getFileAttributeView(Class,java.nio.file.LinkOption[])
+ * @see java.nio.file.Files#getFileAttributeView(Path,Class,java.nio.file.LinkOption[])
*/
public interface FileAttributeView
--- a/jdk/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -37,8 +37,8 @@
* <p> The {@link #getOwner getOwner} or {@link #setOwner setOwner} methods may
* be used to read or update the owner of the file.
*
- * <p> The {@link java.nio.file.FileRef#getAttribute getAttribute} and
- * {@link java.nio.file.FileRef#setAttribute setAttribute} methods may also be
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} and
+ * {@link java.nio.file.Files#setAttribute setAttribute} methods may also be
* used to read or update the owner. In that case, the owner attribute is
* identified by the name {@code "owner"}, and the value of the attribute is
* a {@link UserPrincipal}.
--- a/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-import java.io.IOException;
-
-/**
- * A file store attribute view that supports reading of space attributes.
- *
- * <p> Where dynamic access to file attributes is required, the attributes
- * supported by this attribute view have the following names and types:
- * <blockquote>
- * <table border="1" cellpadding="8">
- * <tr>
- * <th> Name </th>
- * <th> Type </th>
- * </tr>
- * <tr>
- * <td> "totalSpace" </td>
- * <td> {@link Long} </td>
- * </tr>
- * <tr>
- * <td> "usableSpace" </td>
- * <td> {@link Long} </td>
- * </tr>
- * <tr>
- * <td> "unallocatedSpace" </td>
- * <td> {@link Long} </td>
- * </tr>
- * </table>
- * </blockquote>
- * <p> The {@link java.nio.file.FileStore#getAttribute getAttribute} method may
- * be used to read any of these attributes.
- *
- * @since 1.7
- */
-
-public interface FileStoreSpaceAttributeView
- extends FileStoreAttributeView
-{
- /**
- * Returns the name of the attribute view. Attribute views of this type
- * have the name {@code "space"}.
- */
- @Override
- String name();
-
- /**
- * Reads the disk space attributes as a bulk operation.
- *
- * <p> It is file system specific if all attributes are read as an
- * atomic operation with respect to other file system operations.
- *
- * @return The disk space attributes
- *
- * @throws IOException
- * If an I/O error occurs
- */
- FileStoreSpaceAttributes readAttributes() throws IOException;
-}
--- a/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributes.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-/**
- * Space related attributes of a file store.
- *
- * @since 1.7
- *
- * @see Attributes#readFileStoreSpaceAttributes
- */
-
-public interface FileStoreSpaceAttributes {
- /**
- * Returns the size, in bytes, of the file store.
- */
- long totalSpace();
-
- /**
- * Returns the number of bytes available to this Java virtual machine on the
- * file store.
- *
- * <p> The returned number of available bytes is a hint, but not a
- * guarantee, that it is possible to use most or any of these bytes. The
- * number of usable bytes is most likely to be accurate immediately
- * after the space attributes are obtained. It is likely to be made inaccurate
- * by any external I/O operations including those made on the system outside
- * of this Java virtual machine.
- */
- long usableSpace();
-
- /**
- * Returns the number of unallocated bytes in the file store.
- *
- * <p> The returned number of unallocated bytes is a hint, but not a
- * guarantee, that it is possible to use most or any of these bytes. The
- * number of unallocated bytes is most likely to be accurate immediately
- * after the space attributes are obtained. It is likely to be
- * made inaccurate by any external I/O operations including those made on
- * the system outside of this virtual machine.
- */
- long unallocatedSpace();
-}
--- a/jdk/src/share/classes/java/nio/file/attribute/FileTime.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileTime.java Mon Feb 14 16:30:10 2011 -0800
@@ -35,20 +35,53 @@
/**
* Represents the value of a file's time stamp attribute. For example, it may
- * represent the time that the file was last modified, accessed, or created.
+ * represent the time that the file was last
+ * {@link BasicFileAttributes#lastModifiedTime() modified},
+ * {@link BasicFileAttributes#lastAccessTime() accessed},
+ * or {@link BasicFileAttributes#creationTime() created}.
*
* <p> Instances of this class are immutable.
*
* @since 1.7
- * @see BasicFileAttributes
- * @see Attributes#setLastModifiedTime
+ * @see java.nio.file.Files#setLastModifiedTime
+ * @see java.nio.file.Files#getLastModifiedTime
*/
-public final class FileTime implements Comparable<FileTime> {
+public final class FileTime
+ implements Comparable<FileTime>
+{
+ /**
+ * The value since the epoch; can be negative.
+ */
private final long value;
+
+ /**
+ * The unit of granularity to interpret the value.
+ */
private final TimeUnit unit;
- private String valueAsString; // created lazily
+
+ /**
+ * The value return by toString (created lazily)
+ */
+ private String valueAsString;
+
+ /**
+ * The value in days and excess nanos (created lazily)
+ */
+ private DaysAndNanos daysAndNanos;
+ /**
+ * Returns a DaysAndNanos object representing the value.
+ */
+ private DaysAndNanos asDaysAndNanos() {
+ if (daysAndNanos == null)
+ daysAndNanos = new DaysAndNanos(value, unit);
+ return daysAndNanos;
+ }
+
+ /**
+ * Initializes a new instance of this class.
+ */
private FileTime(long value, TimeUnit unit) {
if (unit == null)
throw new NullPointerException();
@@ -143,9 +176,8 @@
*/
@Override
public int hashCode() {
- // hash value for fixed granularity to satisfy contract with equals
- long ms = toMillis();
- return (int)(ms ^ (ms >>> 32));
+ // hashcode of days/nanos representation to satisfy contract with equals
+ return asDaysAndNanos().hashCode();
}
/**
@@ -162,46 +194,12 @@
@Override
public int compareTo(FileTime other) {
// same granularity
- if (unit == other.unit)
+ if (unit == other.unit) {
return (value < other.value) ? -1 : (value == other.value ? 0 : 1);
-
- // compare in days
- long thisValueInDays = unit.toDays(value);
- long otherValueInDays = other.unit.toDays(other.value);
- if (thisValueInDays != otherValueInDays)
- return (thisValueInDays < otherValueInDays) ? -1 : 1;
-
- // compare remainder in nanoseconds
- long thisRemainder = remainderInNanos(thisValueInDays);
- long otherRemainder = other.remainderInNanos(otherValueInDays);
- return (thisRemainder < otherRemainder) ? -1 :
- (thisRemainder == otherRemainder) ? 0 : 1;
- }
-
- private long remainderInNanos(long days) {
- // constants for conversion
- final long C0 = 1L;
- final long C1 = C0 * 24L;
- final long C2 = C1 * 60L;
- final long C3 = C2 * 60L;
- final long C4 = C3 * 1000L;
- final long C5 = C4 * 1000L;
- final long C6 = C5 * 1000L;
-
- long scale;
- switch (unit) {
- case DAYS : scale = C0; break;
- case HOURS : scale = C1; break;
- case MINUTES : scale = C2; break;
- case SECONDS : scale = C3; break;
- case MILLISECONDS : scale = C4; break;
- case MICROSECONDS : scale = C5; break;
- case NANOSECONDS : scale = C6; break;
- default:
- throw new AssertionError("Unit not handled");
+ } else {
+ // compare using days/nanos representation when unit differs
+ return asDaysAndNanos().compareTo(other.asDaysAndNanos());
}
- long rem = value - (days * scale);
- return unit.toNanos(rem);
}
/**
@@ -239,26 +237,12 @@
// nothing to do when seconds/minutes/hours/days
String fractionAsString = "";
if (unit.compareTo(TimeUnit.SECONDS) < 0) {
- // constants for conversion
- final long C0 = 1L;
- final long C1 = C0 * 1000L;
- final long C2 = C1 * 1000L;
- final long C3 = C2 * 1000L;
-
- long scale;
- int width;
- switch (unit) {
- case MILLISECONDS : scale = C1; width = 3; break;
- case MICROSECONDS : scale = C2; width = 6; break;
- case NANOSECONDS : scale = C3; width = 9; break;
- default:
- throw new AssertionError("Unit not handled");
- }
- long fraction = value % scale;
+ long fraction = asDaysAndNanos().fractionOfSecondInNanos();
if (fraction != 0L) {
// fraction must be positive
if (fraction < 0L) {
- fraction += scale;
+ final long MAX_FRACTION_PLUS_1 = 1000L * 1000L * 1000L;
+ fraction += MAX_FRACTION_PLUS_1;
if (ms != Long.MIN_VALUE) ms--;
}
@@ -266,7 +250,7 @@
// stripping any trailing zeros
String s = Long.toString(fraction);
int len = s.length();
- width -= len;
+ int width = 9 - len;
StringBuilder sb = new StringBuilder(".");
while (width-- > 0) {
sb.append('0');
@@ -302,4 +286,76 @@
}
return v;
}
+
+ /**
+ * Represents a FileTime's value as two longs: the number of days since
+ * the epoch, and the excess (in nanoseconds). This is used for comparing
+ * values with different units of granularity.
+ */
+ private static class DaysAndNanos implements Comparable<DaysAndNanos> {
+ // constants for conversion
+ private static final long C0 = 1L;
+ private static final long C1 = C0 * 24L;
+ private static final long C2 = C1 * 60L;
+ private static final long C3 = C2 * 60L;
+ private static final long C4 = C3 * 1000L;
+ private static final long C5 = C4 * 1000L;
+ private static final long C6 = C5 * 1000L;
+
+ /**
+ * The value (in days) since the epoch; can be negative.
+ */
+ private final long days;
+
+ /**
+ * The excess (in nanoseconds); can be negative if days <= 0.
+ */
+ private final long excessNanos;
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ DaysAndNanos(long value, TimeUnit unit) {
+ long scale;
+ switch (unit) {
+ case DAYS : scale = C0; break;
+ case HOURS : scale = C1; break;
+ case MINUTES : scale = C2; break;
+ case SECONDS : scale = C3; break;
+ case MILLISECONDS : scale = C4; break;
+ case MICROSECONDS : scale = C5; break;
+ case NANOSECONDS : scale = C6; break;
+ default : throw new AssertionError("Unit not handled");
+ }
+ this.days = unit.toDays(value);
+ this.excessNanos = unit.toNanos(value - (this.days * scale));
+ }
+
+ /**
+ * Returns the fraction of a second, in nanoseconds.
+ */
+ long fractionOfSecondInNanos() {
+ return excessNanos % (1000L * 1000L * 1000L);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof DaysAndNanos) ?
+ compareTo((DaysAndNanos)obj) == 0 : false;
+ }
+
+ @Override
+ public int hashCode() {
+ return (int)(days ^ (days >>> 32) ^
+ excessNanos ^ (excessNanos >>> 32));
+ }
+
+ @Override
+ public int compareTo(DaysAndNanos other) {
+ if (this.days != other.days)
+ return (this.days < other.days) ? -1 : 1;
+ return (this.excessNanos < other.excessNanos) ? -1 :
+ (this.excessNanos == other.excessNanos) ? 0 : 1;
+ }
+ }
}
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -60,8 +60,8 @@
* <p> <b>Usage Example:</b>
* Suppose we need to print out the owner and access permissions of a file:
* <pre>
- * FileRef file = ...
- * PosixFileAttributes attrs = file.getFileAttributeView(PosixFileAttributeView.class)
+ * Path file = ...
+ * PosixFileAttributes attrs = Files.getFileAttributeView(file, PosixFileAttributeView.class)
* .readAttributes();
* System.out.format("%s %s%n",
* attrs.owner().getName(),
@@ -90,12 +90,12 @@
* </table>
* </blockquote>
*
- * <p> The {@link FileRef#getAttribute getAttribute} method may be used to read
+ * <p> The {@link Files#getAttribute getAttribute} method may be used to read
* any of these attributes, or any of the attributes defined by {@link
* BasicFileAttributeView} as if by invoking the {@link #readAttributes
* readAttributes()} method.
*
- * <p> The {@link FileRef#setAttribute setAttribute} method may be used to update
+ * <p> The {@link Files#setAttribute setAttribute} method may be used to update
* the file's last modified time, last access time or create time attributes as
* defined by {@link BasicFileAttributeView}. It may also be used to update
* the permissions, owner, or group-owner as if by invoking the {@link
@@ -105,8 +105,8 @@
* <h4> Setting Initial Permissions </h4>
* <p> Implementations supporting this attribute view may also support setting
* the initial permissions when creating a file or directory. The
- * initial permissions are provided to the {@link Path#createFile createFile}
- * or {@link Path#createDirectory createDirectory} methods as a {@link
+ * initial permissions are provided to the {@link Files#createFile createFile}
+ * or {@link Files#createDirectory createDirectory} methods as a {@link
* FileAttribute} with {@link FileAttribute#name name} {@code "posix:permissions"}
* and a {@link FileAttribute#value value} that is the set of permissions. The
* following example uses the {@link PosixFilePermissions#asFileAttribute
@@ -117,7 +117,7 @@
* Path path = ...
* Set<PosixFilePermission> perms =
* EnumSet.of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ);
- * path.createFile(PosixFilePermissions.asFileAttribute(perms));
+ * Files.createFile(path, PosixFilePermissions.asFileAttribute(perms));
* </pre>
*
* <p> When the access permissions are set at file creation time then the actual
@@ -128,13 +128,11 @@
* the access permissions, and the underlying file system supports access
* permissions, then it is required that the value of the actual access
* permissions will be equal or less than the value of the attribute
- * provided to the {@link java.nio.file.Path#createFile createFile} or
- * {@link java.nio.file.Path#createDirectory createDirectory} methods. In
- * other words, the file may be more secure than requested.
+ * provided to the {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} methods. In other words, the file may
+ * be more secure than requested.
*
* @since 1.7
- *
- * @see Attributes#readPosixFileAttributes
*/
public interface PosixFileAttributeView
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java Mon Feb 14 16:30:10 2011 -0800
@@ -37,8 +37,6 @@
* PosixFileAttributeView#readAttributes readAttributes} method.
*
* @since 1.7
- *
- * @see Attributes#readPosixFileAttributes
*/
public interface PosixFileAttributes
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermission.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermission.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,14 +25,12 @@
package java.nio.file.attribute;
-import java.util.*;
-
/**
* Defines the bits for use with the {@link PosixFileAttributes#permissions()
* permissions} attribute.
*
- * <p> The {@link PosixFileAttributes} class defines method methods for
- * manipulating {@link Set sets} of permissions.
+ * <p> The {@link PosixFilePermissions} class defines methods for manipulating
+ * set of permissions.
*
* @since 1.7
*/
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java Mon Feb 14 16:30:10 2011 -0800
@@ -126,7 +126,7 @@
public static Set<PosixFilePermission> fromString(String perms) {
if (perms.length() != 9)
throw new IllegalArgumentException("Invalid mode");
- Set<PosixFilePermission> result = new HashSet<PosixFilePermission>();
+ Set<PosixFilePermission> result = EnumSet.noneOf(PosixFilePermission.class);
if (isR(perms.charAt(0))) result.add(OWNER_READ);
if (isW(perms.charAt(1))) result.add(OWNER_WRITE);
if (isX(perms.charAt(2))) result.add(OWNER_EXECUTE);
@@ -141,8 +141,8 @@
/**
* Creates a {@link FileAttribute}, encapsulating a copy of the given file
- * permissions, suitable for passing to the {@link java.nio.file.Path#createFile
- * createFile} or {@link java.nio.file.Path#createDirectory createDirectory}
+ * permissions, suitable for passing to the {@link java.nio.file.Files#createFile
+ * createFile} or {@link java.nio.file.Files#createDirectory createDirectory}
* methods.
*
* @param perms
--- a/jdk/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -59,9 +59,9 @@
* attributes.
*
* <p> Where dynamic access to file attributes is required, the {@link
- * java.nio.file.FileRef#getAttribute getAttribute} method may be used to read
+ * java.nio.file.Files#getAttribute getAttribute} method may be used to read
* the attribute value. The attribute value is returned as a byte array (byte[]).
- * The {@link java.nio.file.FileRef#setAttribute setAttribute} method may be used
+ * The {@link java.nio.file.Files#setAttribute setAttribute} method may be used
* to write the value of a user-defined attribute from a buffer (as if by
* invoking the {@link #write write} method), or byte array (byte[]).
*
@@ -132,8 +132,8 @@
* Suppose we want to read a file's MIME type that is stored as a user-defined
* attribute with the name "{@code user.mimetype}".
* <pre>
- * UserDefinedFileAttributeView view = file
- * .getFileAttributeView(UserDefinedFileAttributeView.class);
+ * UserDefinedFileAttributeView view =
+ * Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
* String name = "user.mimetype";
* ByteBuffer buf = ByteBuffer.allocate(view.size(name));
* view.read(name, buf);
@@ -189,8 +189,8 @@
* <p> <b>Usage Example:</b>
* Suppose we want to write a file's MIME type as a user-defined attribute:
* <pre>
- * UserDefinedFileAttributeView view = file
- * .getFileAttributeView(UserDefinedFileAttributeView.class);
+ * UserDefinedFileAttributeView view =
+ * FIles.getFileAttributeView(path, UserDefinedFileAttributeView.class);
* view.write("user.mimetype", Charset.defaultCharset().encode("text/html"));
* </pre>
*
--- a/jdk/src/share/classes/java/nio/file/attribute/package-info.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/package-info.java Mon Feb 14 16:30:10 2011 -0800
@@ -46,8 +46,6 @@
* <td>Can read or update user-defined file attributes</td></tr>
* <tr><td valign=top><tt> <i>{@link java.nio.file.attribute.FileStoreAttributeView}</i></tt></td>
* <td>Can read or update file system attributes</td></tr>
- * <tr><td valign=top><tt> <i>{@link java.nio.file.attribute.FileStoreSpaceAttributeView} </i></tt></td>
- * <td>Can read file system <em>space usage</em> related attributes</td></tr>
* </table></blockquote>
*
* <p> An attribute view provides a read-only or updatable view of the non-opaque
@@ -55,7 +53,7 @@
* The {@link java.nio.file.attribute.FileAttributeView} interface is
* extended by several other interfaces that that views to specific sets of file
* attributes. {@code FileAttributeViews} are selected by invoking the {@link
- * java.nio.file.FileRef#getFileAttributeView} method with a
+ * java.nio.file.Files#getFileAttributeView} method with a
* <em>type-token</em> to identify the required view. Views can also be identified
* by name. The {@link java.nio.file.attribute.FileStoreAttributeView} interface
* provides access to file store attributes. A {@code FileStoreAttributeView} of
@@ -83,13 +81,6 @@
* on the model defined by <a href="http://www.ietf.org/rfc/rfc3530.txt">
* <i>RFC 3530: Network File System (NFS) version 4 Protocol</i></a>.
*
- * <p> The {@link java.nio.file.attribute.FileStoreSpaceAttributeView} class
- * defines methods to read file system space usage related attributes of a file system.
- *
- * <p> The {@link java.nio.file.attribute.Attributes} utility class defines
- * static methods to access file or file system attribute using the above
- * attribute views.
- *
* <p> In addition to attribute views, this package also defines classes and
* interfaces that are used when accessing attributes:
*
--- a/jdk/src/share/classes/java/nio/file/package-info.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/package-info.java Mon Feb 14 16:30:10 2011 -0800
@@ -31,7 +31,7 @@
* systems. The API to access file and file system attributes is defined in the
* {@link java.nio.file.attribute} package. The {@link java.nio.file.spi}
* package is used by service provider implementors wishing to extend the
- * platform default provider, or to construct other provider implementations.
+ * platform default provider, or to construct other provider implementations. </p>
*
* <a name="links"><h3>Symbolic Links</h3></a>
* Many operating systems and file systems support for <em>symbolic links</em>.
@@ -43,7 +43,7 @@
* target of the link. This package includes support for symbolic links where
* implementations provide these semantics. File systems may support other types
* that are semantically close but support for these other types of links is
- * not included in this package.
+ * not included in this package. </p>
*
* <a name="interop"><h3>Interoperability</h3></a>
* The {@link java.io.File} class defines the {@link java.io.File#toPath
@@ -52,7 +52,7 @@
* {@code Path} can be used to operate on the same file as the {@code File}
* object. The {@code Path} specification provides further information
* on the <a href="Path.html#interop">interoperability</a> between {@code Path}
- * and {@code java.io.File} objects.
+ * and {@code java.io.File} objects. </p>
*
* <h3>Visibility</h3>
* The view of the files and file system provided by classes in this package are
@@ -63,7 +63,7 @@
* network-filesystem protocols. This is true regardless of the language in which
* these other programs are written, and whether they are running on the same machine
* or on some other machine. The exact nature of any such inconsistencies are
- * system-dependent and are therefore unspecified.
+ * system-dependent and are therefore unspecified. </p>
*
* <a name="integrity"><h3>Synchronized I/O File Integrity</h3></a>
* The {@link java.nio.file.StandardOpenOption#SYNC SYNC} and {@link
@@ -80,14 +80,14 @@
* crash. If the file does not reside on a local device then no such guarantee
* is made. Whether this guarantee is possible with other {@link
* java.nio.file.spi.FileSystemProvider provider} implementations is provider
- * specific.
+ * specific. </p>
*
* <h3>General Exceptions</h3>
* Unless otherwise noted, passing a {@code null} argument to a constructor
* or method of any class or interface in this package will cause a {@link
* java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
* invoking a method with a collection containing a {@code null} element will
- * cause a {@code NullPointerException}, unless otherwise specified.
+ * cause a {@code NullPointerException}, unless otherwise specified. </p>
*
* <p> Unless otherwise noted, methods that attempt to access the file system
* will throw {@link java.nio.file.ClosedFileSystemException} when invoked on
@@ -95,12 +95,13 @@
* {@link java.nio.file.FileSystem#close closed}. Additionally, any methods
* that attempt write access to a file system will throw {@link
* java.nio.file.ReadOnlyFileSystemException} when invoked on an object associated
- * with a {@link java.nio.file.FileSystem} that only provides read-only access.
+ * with a {@link java.nio.file.FileSystem} that only provides read-only
+ * access. </p>
*
* <p> Unless otherwise noted, invoking a method of any class or interface in
* this package created by one {@link java.nio.file.spi.FileSystemProvider
* provider} with a parameter that is an object created by another provider,
- * will throw {@link java.nio.file.ProviderMismatchException}.
+ * will throw {@link java.nio.file.ProviderMismatchException}. </p>
*
* <h3>Optional Specific Exceptions</h3>
* Most of the methods defined by classes in this package that access the
--- a/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java Mon Feb 14 16:30:10 2011 -0800
@@ -26,17 +26,21 @@
package java.nio.file.spi;
import java.nio.file.*;
-import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.*;
import java.nio.channels.*;
import java.net.URI;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.io.IOException;
/**
- * Service-provider class for file systems.
+ * Service-provider class for file systems. The methods defined by the {@link
+ * java.nio.file.Files} class will typically delegate to an instance of this
+ * class.
*
* <p> A file system provider is a concrete implementation of this class that
* implements the abstract methods defined by this class. A provider is
@@ -64,13 +68,6 @@
* the {@code newFileSystem} method is invoked. In the case of the default
* provider, the {@code FileSystem} is created when the provider is initialized.
*
- * <p> In addition to file systems, a provider is also a factory for {@link
- * FileChannel} and {@link AsynchronousFileChannel} channels. The {@link
- * #newFileChannel newFileChannel} and {@link #newAsynchronousFileChannel
- * AsynchronousFileChannel} methods are defined to open or create files, returning
- * a channel to access the file. These methods are invoked by static factory
- * methods defined in the {@link java.nio.channels} package.
- *
* <p> All of the methods in this class are safe for use by multiple concurrent
* threads.
*
@@ -202,9 +199,10 @@
*
* <p> This method throws {@link FileSystemAlreadyExistsException} if the
* file system already exists because it was previously created by an
- * invocation of this method. Once a file system is {@link FileSystem#close
- * closed} it is provider-dependent if the provider allows a new file system
- * to be created with the same URI as a file system it previously created.
+ * invocation of this method. Once a file system is {@link
+ * java.nio.file.FileSystem#close closed} it is provider-dependent if the
+ * provider allows a new file system to be created with the same URI as a
+ * file system it previously created.
*
* @param uri
* URI reference
@@ -234,20 +232,21 @@
*
* <p> This method returns a reference to a {@code FileSystem} that was
* created by invoking the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
- * method. File systems created the {@link #newFileSystem(FileRef,Map)
- * newFileSystem(FileRef,Map)} method are not returned by this method.
+ * method. File systems created the {@link #newFileSystem(Path,Map)
+ * newFileSystem(Path,Map)} method are not returned by this method.
* The file system is identified by its {@code URI}. Its exact form
* is highly provider dependent. In the case of the default provider the URI's
* path component is {@code "/"} and the authority, query and fragment components
* are undefined (Undefined components are represented by {@code null}).
*
- * <p> Once a file system created by this provider is {@link FileSystem#close
- * closed} it is provider-dependent if this method returns a reference to
- * the closed file system or throws {@link FileSystemNotFoundException}.
- * If the provider allows a new file system to be created with the same URI
- * as a file system it previously created then this method throws the
- * exception if invoked after the file system is closed (and before a new
- * instance is created by the {@link #newFileSystem newFileSystem} method).
+ * <p> Once a file system created by this provider is {@link
+ * java.nio.file.FileSystem#close closed} it is provider-dependent if this
+ * method returns a reference to the closed file system or throws {@link
+ * FileSystemNotFoundException}. If the provider allows a new file system to
+ * be created with the same URI as a file system it previously created then
+ * this method throws the exception if invoked after the file system is
+ * closed (and before a new instance is created by the {@link #newFileSystem
+ * newFileSystem} method).
*
* <p> If a security manager is installed then a provider implementation
* may require to check a permission before returning a reference to an
@@ -306,17 +305,16 @@
*
* <p> This method is intended for specialized providers of pseudo file
* systems where the contents of one or more files is treated as a file
- * system. The {@code file} parameter is a reference to an existing file
- * and the {@code env} parameter is a map of provider specific properties to
- * configure the file system.
+ * system. The {@code env} parameter is a map of provider specific properties
+ * to configure the file system.
*
* <p> If this provider does not support the creation of such file systems
* or if the provider does not recognize the file type of the given file then
* it throws {@code UnsupportedOperationException}. The default implementation
* of this method throws {@code UnsupportedOperationException}.
*
- * @param file
- * The file
+ * @param path
+ * The path to the file
* @param env
* A map of provider specific properties to configure the file system;
* may be empty
@@ -336,32 +334,121 @@
* If a security manager is installed and it denies an unspecified
* permission.
*/
- public FileSystem newFileSystem(FileRef file, Map<String,?> env)
+ public FileSystem newFileSystem(Path path, Map<String,?> env)
throws IOException
{
throw new UnsupportedOperationException();
}
/**
- * Opens or creates a file for reading and/or writing, returning a file
- * channel to access the file.
+ * Opens a file, returning an input stream to read from the file. This
+ * method works in exactly the manner specified by the {@link
+ * Files#newInputStream} method.
+ *
+ * <p> The default implementation of this method opens a channel to the file
+ * as if by invoking the {@link #newByteChannel} method and constructs a
+ * stream that reads bytes from the channel. This method should be overridden
+ * where appropriate.
+ *
+ * @param path
+ * the path to the file to open
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new input stream
*
- * <p> This method is invoked by the {@link FileChannel#open(Path,Set,FileAttribute[])
- * FileChannel.open} method to open a file channel. A provider that does not
- * support all the features required to construct a file channel throws
- * {@code UnsupportedOperationException}. The default provider is required
- * to support the creation of file channels. When not overridden, the
- * default implementation throws {@code UnsupportedOperationException}.
+ * @throws IllegalArgumentException
+ * if an invalid combination of options is specified
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws IOException
+ * if an I/O error occurs
+ * @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.
+ */
+ public InputStream newInputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ if (options.length > 0) {
+ for (OpenOption opt: options) {
+ if (opt != StandardOpenOption.READ)
+ throw new UnsupportedOperationException("'" + opt + "' not allowed");
+ }
+ }
+ return Channels.newInputStream(Files.newByteChannel(path));
+ }
+
+ /**
+ * Opens or creates a file, returning an output stream that may be used to
+ * write bytes to the file. This method works in exactly the manner
+ * specified by the {@link Files#newOutputStream} method.
+ *
+ * <p> The default implementation of this method opens a channel to the file
+ * as if by invoking the {@link #newByteChannel} method and constructs a
+ * stream that writes bytes to the channel. This method should be overridden
+ * where appropriate.
*
* @param path
- * The path of the file to open or create
+ * the path to the file to open or create
* @param options
- * Options specifying how the file is opened
+ * options specifying how the file is opened
+ *
+ * @return a new output stream
+ *
+ * @throws IllegalArgumentException
+ * if {@code options} contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ */
+ public OutputStream newOutputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ int len = options.length;
+ Set<OpenOption> opts = new HashSet<OpenOption>(len + 3);
+ if (len == 0) {
+ opts.add(StandardOpenOption.CREATE);
+ opts.add(StandardOpenOption.TRUNCATE_EXISTING);
+ } else {
+ for (OpenOption opt: options) {
+ if (opt == StandardOpenOption.READ)
+ throw new IllegalArgumentException("READ not allowed");
+ opts.add(opt);
+ }
+ }
+ opts.add(StandardOpenOption.WRITE);
+ return Channels.newOutputStream(newByteChannel(path, opts));
+ }
+
+ /**
+ * Opens or creates a file for reading and/or writing, returning a file
+ * channel to access the file. This method works in exactly the manner
+ * specified by the {@link FileChannel#open(Path,Set,FileAttribute[])
+ * FileChannel.open} method. A provider that does not support all the
+ * features required to construct a file channel throws {@code
+ * UnsupportedOperationException}. The default provider is required to
+ * support the creation of file channels. When not overridden, the default
+ * implementation throws {@code UnsupportedOperationException}.
+ *
+ * @param path
+ * the path of the file to open or create
+ * @param options
+ * options specifying how the file is opened
* @param attrs
- * An optional list of file attributes to set atomically when
+ * an optional list of file attributes to set atomically when
* creating the file
*
- * @return A new file channel
+ * @return a new file channel
*
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
@@ -387,11 +474,10 @@
/**
* Opens or creates a file for reading and/or writing, returning an
- * asynchronous file channel to access the file.
- *
- * <p> This method is invoked by the {@link
+ * asynchronous file channel to access the file. This method works in
+ * exactly the manner specified by the {@link
* AsynchronousFileChannel#open(Path,Set,ExecutorService,FileAttribute[])
- * AsynchronousFileChannel.open} method to open an asynchronous file channel.
+ * AsynchronousFileChannel.open} method.
* A provider that does not support all the features required to construct
* an asynchronous file channel throws {@code UnsupportedOperationException}.
* The default provider is required to support the creation of asynchronous
@@ -399,17 +485,17 @@
* method throws {@code UnsupportedOperationException}.
*
* @param path
- * The path of the file to open or create
+ * the path of the file to open or create
* @param options
- * Options specifying how the file is opened
+ * options specifying how the file is opened
* @param executor
- * The thread pool or {@code null} to associate the channel with
+ * the thread pool or {@code null} to associate the channel with
* the default thread pool
* @param attrs
- * An optional list of file attributes to set atomically when
+ * an optional list of file attributes to set atomically when
* creating the file
*
- * @return A new asynchronous file channel
+ * @return a new asynchronous file channel
*
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
@@ -434,4 +520,569 @@
{
throw new UnsupportedOperationException();
}
+
+ /**
+ * Opens or creates a file, returning a seekable byte channel to access the
+ * file. This method works in exactly the manner specified by the {@link
+ * Files#newByteChannel(Path,Set,FileAttribute[])} method.
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return a new seekable byte channel
+ *
+ * @throws IllegalArgumentException
+ * if the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported open option is specified or the array contains
+ * attributes that cannot be set atomically when creating the file
+ * @throws FileAlreadyExistsException
+ * if a file of that name already exists and the {@link
+ * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @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 path if the file is
+ * opened for reading. The {@link SecurityManager#checkWrite(String)
+ * checkWrite} method is invoked to check write access to the path
+ * if the file is opened for writing. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ */
+ public abstract SeekableByteChannel newByteChannel(Path path,
+ Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException;
+
+ /**
+ * Opens a directory, returning a {@code DirectoryStream} to iterate over
+ * the entries in the directory. This method works in exactly the manner
+ * specified by the {@link
+ * Files#newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter)}
+ * method.
+ *
+ * @param dir
+ * the path to the directory
+ * @param filter
+ * the directory stream filter
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @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.
+ */
+ public abstract DirectoryStream<Path> newDirectoryStream(Path dir,
+ DirectoryStream.Filter<? super Path> filter) throws IOException;
+
+ /**
+ * Creates a new directory. This method works in exactly the manner
+ * specified by the {@link Files#createDirectory} method.
+ *
+ * @param dir
+ * the directory to create
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws FileAlreadyExistsException
+ * if a directory could not otherwise be created because a file of
+ * that name already exists <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs or the parent directory does not exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the new directory.
+ */
+ public abstract void createDirectory(Path dir, FileAttribute<?>... attrs)
+ throws IOException;
+
+ /**
+ * Creates a symbolic link to a target. This method works in exactly the
+ * manner specified by the {@link Files#createSymbolicLink} method.
+ *
+ * <p> The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the path of the symbolic link to create
+ * @param target
+ * the target of the symbolic link
+ * @param attrs
+ * the array of attributes to set atomically when creating the
+ * symbolic link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links or the
+ * array contains an attribute that cannot be set atomically when
+ * creating the symbolic link
+ * @throws FileAlreadyExistsException
+ * if a file with the name already exists <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it denies {@link LinkPermission}<tt>("symbolic")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the path of the symbolic link.
+ */
+ public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a new link (directory entry) for an existing file. This method
+ * works in exactly the manner specified by the {@link Files#createLink}
+ * method.
+ *
+ * <p> The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the link (directory entry) to create
+ * @param existing
+ * a path to an existing file
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support adding an existing file
+ * to a directory
+ * @throws FileAlreadyExistsException
+ * if the entry could not otherwise be created because a file of
+ * that name already exists <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it denies {@link LinkPermission}<tt>("hard")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to either the link or the
+ * existing file.
+ */
+ public void createLink(Path link, Path existing) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Deletes a file. This method works in exactly the manner specified by the
+ * {@link Files#delete} method.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @throws NoSuchFileException
+ * if the file does not exist <i>(optional specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * if the file is a directory and could not otherwise be deleted
+ * because the directory is not empty <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String)} method
+ * is invoked to check delete access to the file
+ */
+ public abstract void delete(Path path) throws IOException;
+
+ /**
+ * Deletes a file if it exists. This method works in exactly the manner
+ * specified by the {@link Files#deleteIfExists} method.
+ *
+ * <p> The default implementation of this method simply invokes {@link
+ * #delete} ignoring the {@code NoSuchFileException} when the file does not
+ * exist. It may be overridden where appropriate.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @return {@code true} if the file was deleted by this method; {@code
+ * false} if the file could not be deleted because it did not
+ * exist
+ *
+ * @throws DirectoryNotEmptyException
+ * if the file is a directory and could not otherwise be deleted
+ * because the directory is not empty <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String)} method
+ * is invoked to check delete access to the file
+ */
+ public boolean deleteIfExists(Path path) throws IOException {
+ try {
+ delete(path);
+ return true;
+ } catch (NoSuchFileException ignore) {
+ return false;
+ }
+ }
+
+ /**
+ * Reads the target of a symbolic link. This method works in exactly the
+ * manner specified by the {@link Files#readSymbolicLink} method.
+ *
+ * <p> The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the path to the symbolic link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links
+ * @throws NotLinkException
+ * if the target could otherwise not be read because the file
+ * is not a symbolic link <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it checks that {@code FilePermission} has been
+ * granted with the "{@code readlink}" action to read the link.
+ */
+ public Path readSymbolicLink(Path link) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Copy a file to a target file. This method works in exactly the manner
+ * specified by the {@link Files#copy(Path,Path,CopyOption[])} method
+ * except that both the source and target paths must be associated with
+ * this provider.
+ *
+ * @param source
+ * the path to the file to copy
+ * @param target
+ * the path to the target file
+ * @param options
+ * options specifying how the copy should be done
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @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 source file, the
+ * {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+ * to check write access to the target file. If a symbolic link is
+ * copied the security manager is invoked to check {@link
+ * LinkPermission}{@code ("symbolic")}.
+ */
+ public abstract void copy(Path source, Path target, CopyOption... options)
+ throws IOException;
+
+ /**
+ * Move or rename a file to a target file. This method works in exactly the
+ * manner specified by the {@link Files#move} method except that both the
+ * source and target paths must be associated with this provider.
+ *
+ * @param source
+ * the path to the file to move
+ * @param target
+ * the path to the target file
+ * @param options
+ * options specifying how the move should be done
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i>
+ * @throws AtomicMoveNotSupportedException
+ * if the options array contains the {@code ATOMIC_MOVE} option but
+ * the file cannot be moved as an atomic file system operation.
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to both the source and
+ * target file.
+ */
+ public abstract void move(Path source, Path target, CopyOption... options)
+ throws IOException;
+
+ /**
+ * Tests if two paths locate the same file. This method works in exactly the
+ * manner specified by the {@link Files#isSameFile} method.
+ *
+ * @param path
+ * one path to the file
+ * @param path2
+ * the other path
+ *
+ * @return {@code true} if, and only if, the two paths locate the same file
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @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 both files.
+ */
+ public abstract boolean isSameFile(Path path, Path path2)
+ throws IOException;
+
+ /**
+ * Tells whether or not a file is considered <em>hidden</em>. This method
+ * works in exactly the manner specified by the {@link Files#isHidden}
+ * method.
+ *
+ * <p> This method is invoked by the {@link Files#isHidden isHidden} method.
+ *
+ * @param path
+ * the path to the file to test
+ *
+ * @return {@code true} if the file is considered hidden
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @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.
+ */
+ public abstract boolean isHidden(Path path) throws IOException;
+
+ /**
+ * Returns the {@link FileStore} representing the file store where a file
+ * is located. This method works in exactly the manner specified by the
+ * {@link Files#getFileStore} method.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the file store where the file is stored
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @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, and in
+ * addition it checks {@link RuntimePermission}<tt>
+ * ("getFileStoreAttributes")</tt>
+ */
+ public abstract FileStore getFileStore(Path path) throws IOException;
+
+ /**
+ * Checks the existence, and optionally the accessibility, of a file.
+ *
+ * <p> This method may be used by the {@link Files#isReadable isReadable},
+ * {@link Files#isWritable isWritable} and {@link Files#isExecutable
+ * isExecutable} methods to check the accessibility of a file.
+ *
+ * <p> This method checks the existence of a file and that this Java virtual
+ * machine has appropriate privileges that would allow it access the file
+ * according to all of access modes specified in the {@code modes} parameter
+ * as follows:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Value</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link AccessMode#READ READ} </td>
+ * <td> Checks that the file exists and that the Java virtual machine has
+ * permission to read the file. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link AccessMode#WRITE WRITE} </td>
+ * <td> Checks that the file exists and that the Java virtual machine has
+ * permission to write to the file, </td>
+ * </tr>
+ * <tr>
+ * <td> {@link AccessMode#EXECUTE EXECUTE} </td>
+ * <td> Checks that the file exists and that the Java virtual machine has
+ * permission to {@link Runtime#exec execute} the file. The semantics
+ * may differ when checking access to a directory. For example, on UNIX
+ * systems, checking for {@code EXECUTE} access checks that the Java
+ * virtual machine has permission to search the directory in order to
+ * access file or subdirectories. </td>
+ * </tr>
+ * </table>
+ *
+ * <p> If the {@code modes} parameter is of length zero, then the existence
+ * of the file is checked.
+ *
+ * <p> This method follows symbolic links if the file referenced by this
+ * object is a symbolic link. Depending on the implementation, this method
+ * may require to read file permissions, access control lists, or other
+ * file attributes in order to check the effective access to the file. To
+ * determine the effective access to a file may require access to several
+ * attributes and so in some implementations this method may not be atomic
+ * with respect to other file system operations.
+ *
+ * @param path
+ * the path to the file to check
+ * @param modes
+ * The access modes to check; may have zero elements
+ *
+ * @throws UnsupportedOperationException
+ * an implementation is required to support checking for
+ * {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
+ * exception is specified to allow for the {@code Access} enum to
+ * be extended in future releases.
+ * @throws NoSuchFileException
+ * if a file does not exist <i>(optional specific exception)</i>
+ * @throws AccessDeniedException
+ * the requested access would be denied or the access cannot be
+ * determined because the Java virtual machine has insufficient
+ * privileges or other reasons. <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * is invoked when checking read access to the file or only the
+ * existence of the file, the {@link SecurityManager#checkWrite(String)
+ * checkWrite} is invoked when checking write access to the file,
+ * and {@link SecurityManager#checkExec(String) checkExec} is invoked
+ * when checking execute access.
+ */
+ public abstract void checkAccess(Path path, AccessMode... modes)
+ throws IOException;
+
+ /**
+ * Returns a file attribute view of a given type. This method works in
+ * exactly the manner specified by the {@link Files#getFileAttributeView}
+ * method.
+ *
+ * @param path
+ * the path to the file
+ * @param type
+ * the {@code Class} object corresponding to the file attribute view
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a file attribute view of the specified type, or {@code null} if
+ * the attribute view type is not available
+ */
+ public abstract <V extends FileAttributeView> V
+ getFileAttributeView(Path path, Class<V> type, LinkOption... options);
+
+ /**
+ * Reads a file's attributes as a bulk operation. This method works in
+ * exactly the manner specified by the {@link
+ * Files#readAttributes(Path,Class,LinkOption[])} method.
+ *
+ * @param path
+ * the path to the file
+ * @param type
+ * the {@code Class} of the file attributes required
+ * to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the file attributes
+ *
+ * @throws UnsupportedOperationException
+ * if an attributes of the given type are not supported
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file
+ */
+ public abstract <A extends BasicFileAttributes> A
+ readAttributes(Path path, Class<A> type, LinkOption... options) throws IOException;
+
+ /**
+ * Reads a set of file attributes as a bulk operation. This method works in
+ * exactly the manner specified by the {@link
+ * Files#readAttributes(Path,String,LinkOption[])} method.
+ *
+ * @param path
+ * the path to the file
+ * @param attributes
+ * the attributes to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a map of the attributes returned; may be empty. The map's keys
+ * are the attribute names, its values are the attribute values
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file. If this method is invoked
+ * to read security sensitive attributes then the security manager
+ * may be invoke to check for additional permissions.
+ */
+ public abstract Map<String,Object> readAttributes(Path path, String attributes,
+ LinkOption... options)
+ throws IOException;
+
+ /**
+ * Sets the value of a file attribute. This method works in exactly the
+ * manner specified by the {@link Files#setAttribute} method.
+ *
+ * @param path
+ * the path to the file
+ * @param attribute
+ * the attribute to set
+ * @param value
+ * the attribute value
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available or it does not support
+ * updating the attribute
+ * @throws IllegalArgumentException
+ * if the attribute value is of the correct type but has an
+ * inappropriate value
+ * @throws ClassCastException
+ * If the attribute value is not of the expected type or is a
+ * collection containing elements that are not of the expected
+ * type
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file. If this method is invoked
+ * to set security sensitive attributes then the security manager
+ * may be invoked to check for additional permissions.
+ */
+ public abstract void setAttribute(Path path, String attribute,
+ Object value, LinkOption... options)
+ throws IOException;
}
--- a/jdk/src/share/classes/java/nio/file/spi/FileTypeDetector.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/spi/FileTypeDetector.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,7 +25,7 @@
package java.nio.file.spi;
-import java.nio.file.FileRef;
+import java.nio.file.Path;
import java.io.IOException;
/**
@@ -42,7 +42,7 @@
* href="../attribute/package-summary.html"> attribute</a> or the bytes in a
* file may be examined to guess its file type.
*
- * @see java.nio.file.Files#probeContentType(FileRef)
+ * @see java.nio.file.Files#probeContentType(Path)
*
* @since 1.7
*/
@@ -83,8 +83,8 @@
* Message Bodies</i></a>. The string must be parsable according to the
* grammar in the RFC 2045.
*
- * @param file
- * The file to probe
+ * @param path
+ * the path to the file to probe
*
* @return The content type or {@code null} if the file type is not
* recognized
@@ -101,6 +101,6 @@
*
* @see java.nio.file.Files#probeContentType
*/
- public abstract String probeContentType(FileRef file)
+ public abstract String probeContentType(Path path)
throws IOException;
}
--- a/jdk/src/share/classes/java/security/AlgorithmParameterGenerator.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/AlgorithmParameterGenerator.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,6 +66,20 @@
* default modulus prime size of 1024 bits for the generation of DSA
* parameters.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>AlgorithmParameterGenerator</code> algorithms and
+ * keysizes in parentheses:
+ * <ul>
+ * <li><tt>DiffieHellman</tt> (1024)</li>
+ * <li><tt>DSA</tt> (1024)</li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+ * AlgorithmParameterGenerator section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
*
@@ -126,9 +140,9 @@
*
* @param algorithm the name of the algorithm this
* parameter generator is associated with.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameterGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new AlgorithmParameterGenerator object.
@@ -168,9 +182,9 @@
*
* @param algorithm the name of the algorithm this
* parameter generator is associated with.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameterGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the string name of the Provider.
@@ -214,9 +228,9 @@
*
* @param algorithm the string name of the algorithm this
* parameter generator is associated with.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameterGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the Provider object.
--- a/jdk/src/share/classes/java/security/AlgorithmParameters.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/AlgorithmParameters.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -46,6 +46,22 @@
* <code>getParameterSpec</code>, and a byte encoding of the parameters is
* obtained via a call to <code>getEncoded</code>.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>AlgorithmParameters</code> algorithms:
+ * <ul>
+ * <li><tt>AES</tt></li>
+ * <li><tt>DES</tt></li>
+ * <li><tt>DESede</tt></li>
+ * <li><tt>DiffieHellman</tt></li>
+ * <li><tt>DSA</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
+ * AlgorithmParameters section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
*
@@ -111,9 +127,9 @@
* parameter encoding.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameters section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new parameter object.
@@ -153,9 +169,9 @@
* parameter encoding.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameters section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -200,9 +216,9 @@
* parameter encoding.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameters section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
--- a/jdk/src/share/classes/java/security/KeyFactory.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/KeyFactory.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -67,9 +67,22 @@
* sig.verify(signature);
* </pre>
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>KeyFactory</code> algorithms:
+ * <ul>
+ * <li><tt>DiffieHellman</tt></li>
+ * <li><tt>DSA</tt></li>
+ * <li><tt>RSA</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyFactory">
+ * KeyFactory section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
- *
* @see Key
* @see PublicKey
* @see PrivateKey
@@ -141,9 +154,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested key algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new KeyFactory object.
@@ -172,9 +185,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested key algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -211,9 +224,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the name of the requested key algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/java/security/KeyPairGenerator.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/KeyPairGenerator.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -105,9 +105,23 @@
* the superclass are intended for cryptographic service providers who wish to
* supply their own implementations of key pair generators.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>KeyPairGenerator</code> algorithms and keysizes in
+ * parentheses:
+ * <ul>
+ * <li><tt>DiffieHellman</tt> (1024)</li>
+ * <li><tt>DSA</tt> (1024)</li>
+ * <li><tt>RSA</tt> (1024, 2048)</li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * KeyPairGenerator section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Benjamin Renaud
*
- *
* @see java.security.spec.AlgorithmParameterSpec
*/
@@ -122,9 +136,9 @@
* Creates a KeyPairGenerator object for the specified algorithm.
*
* @param algorithm the standard string name of the algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyPairGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*/
protected KeyPairGenerator(String algorithm) {
@@ -133,9 +147,9 @@
/**
* Returns the standard name of the algorithm for this key pair generator.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyPairGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the standard string name of the algorithm.
@@ -171,9 +185,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard string name of the algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyPairGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new KeyPairGenerator object.
@@ -227,9 +241,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard string name of the algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyPairGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the string name of the provider.
@@ -266,9 +280,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the standard string name of the algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyPairGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/java/security/KeyStore.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/KeyStore.java Mon Feb 14 16:30:10 2011 -0800
@@ -164,9 +164,20 @@
* different passwords or other protection parameters
* may also be used.
*
+ * <p> Every implementation of the Java platform is required to support
+ * the following standard <code>KeyStore</code> type:
+ * <ul>
+ * <li><tt>PKCS12</tt></li>
+ * </ul>
+ * This type is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
+ * KeyStore section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other types are supported.
+ *
* @author Jan Luehe
*
- *
* @see java.security.PrivateKey
* @see javax.crypto.SecretKey
* @see java.security.cert.Certificate
@@ -582,9 +593,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param type the type of keystore.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard keystore types.
*
* @return a keystore object of the specified type.
@@ -620,9 +631,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param type the type of keystore.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard keystore types.
*
* @param provider the name of the provider.
@@ -663,9 +674,9 @@
* does not have to be registered in the provider list.
*
* @param type the type of keystore.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard keystore types.
*
* @param provider the provider.
--- a/jdk/src/share/classes/java/security/MessageDigest.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/MessageDigest.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
/**
* This MessageDigest class provides applications the functionality of a
- * message digest algorithm, such as MD5 or SHA.
+ * message digest algorithm, such as SHA-1 or SHA-256.
* Message digests are secure one-way hash functions that take arbitrary-sized
* data and output a fixed-length hash value.
*
@@ -81,9 +81,22 @@
* the superclass are intended for cryptographic service providers who wish to
* supply their own implementations of message digest algorithms.
*
+ * <p> Every implementation of the Java platform is required to support
+ * the following standard <code>MessageDigest</code> algorithms:
+ * <ul>
+ * <li><tt>MD5</tt></li>
+ * <li><tt>SHA-1</tt></li>
+ * <li><tt>SHA-256</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * MessageDigest section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Benjamin Renaud
*
- *
* @see DigestInputStream
* @see DigestOutputStream
*/
@@ -104,9 +117,9 @@
* Creates a message digest with the specified algorithm name.
*
* @param algorithm the standard name of the digest algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the MessageDigest section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*/
protected MessageDigest(String algorithm) {
@@ -127,9 +140,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the MessageDigest section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return a Message Digest object that implements the specified algorithm.
@@ -173,9 +186,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the MessageDigest section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -222,9 +235,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the MessageDigest section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
@@ -439,9 +452,9 @@
* Returns a string that identifies the algorithm, independent of
* implementation details. The name should be a standard
* Java Security name (such as "SHA", "MD5", and so on).
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the MessageDigest section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the name of the algorithm
--- a/jdk/src/share/classes/java/security/Policy.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/Policy.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -67,9 +67,6 @@
* implementation. In addition, an instance of a Policy object can be
* constructed by invoking one of the <code>getInstance</code> factory methods
* with a standard type. The default policy type is "JavaPolicy".
- * See Appendix A in the <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for a list of standard Policy types.
*
* <p> Once a Policy instance has been installed (either by default, or by
* calling <code>setPolicy</code>),
@@ -133,7 +130,7 @@
* This method first calls
* <code>SecurityManager.checkPermission</code> with a
* <code>SecurityPermission("getPolicy")</code> permission
- * to ensure it's ok to get the Policy object..
+ * to ensure it's ok to get the Policy object.
*
* @return the installed Policy.
*
@@ -340,9 +337,10 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * @param type the specified Policy type. See Appendix A in the
- * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * @param type the specified Policy type. See the Policy section in the
+ * <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Policy">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for a list of standard Policy types.
*
* @param params parameters for the Policy, which may be null.
@@ -393,9 +391,10 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * @param type the specified Policy type. See Appendix A in the
- * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * @param type the specified Policy type. See the Policy section in the
+ * <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Policy">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for a list of standard Policy types.
*
* @param params parameters for the Policy, which may be null.
@@ -456,9 +455,10 @@
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
- * @param type the specified Policy type. See Appendix A in the
- * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * @param type the specified Policy type. See the Policy section in the
+ * <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Policy">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for a list of standard Policy types.
*
* @param params parameters for the Policy, which may be null.
--- a/jdk/src/share/classes/java/security/SecureRandom.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/SecureRandom.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, 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
@@ -133,9 +133,9 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * <p> See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * <p> See the SecureRandom section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard RNG algorithm names.
*
* <p> The returned SecureRandom object has not been seeded. To seed the
@@ -171,9 +171,9 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * <p> See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * <p> See the SecureRandom section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard RNG algorithm names.
*
* @param seed the seed.
@@ -256,9 +256,9 @@
* previously called.
*
* @param algorithm the name of the RNG algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the SecureRandom section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard RNG algorithm names.
*
* @return the new SecureRandom object.
@@ -299,9 +299,9 @@
* previously called.
*
* @param algorithm the name of the RNG algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the SecureRandom section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard RNG algorithm names.
*
* @param provider the name of the provider.
@@ -347,9 +347,9 @@
* previously called.
*
* @param algorithm the name of the RNG algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the SecureRandom section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard RNG algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/java/security/Security.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/Security.java Mon Feb 14 16:30:10 2011 -0800
@@ -277,10 +277,11 @@
/**
* Gets a specified property for an algorithm. The algorithm name
- * should be a standard name. See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * should be a standard name. See the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
+ *
* One possible use is by specialized algorithm parsers, which may map
* classes to algorithms which they understand (much like Key parsers
* do).
@@ -513,9 +514,9 @@
*
* </ul>
*
- * <p> See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * <p> See the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard cryptographic service names, standard
* algorithm names and standard attribute names.
*
@@ -581,9 +582,9 @@
* constraint expressed by the specified attribute name/value pair.
* </ul>
*
- * <p> See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * <p> See the <a href=
+ * "../../../technotes/guides/security/StandardNames.html">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard cryptographic service names, standard
* algorithm names and standard attribute names.
*
--- a/jdk/src/share/classes/java/security/Signature.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/Signature.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, 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
@@ -47,7 +47,7 @@
import sun.security.jca.GetInstance.Instance;
/**
- * This Signature class is used to provide applications the functionality
+ * The Signature class is used to provide applications the functionality
* of a digital signature algorithm. Digital signatures are used for
* authentication and integrity assurance of digital data.
*
@@ -98,6 +98,20 @@
* the superclass are intended for cryptographic service providers who wish to
* supply their own implementations of digital signature algorithms.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>Signature</code> algorithms:
+ * <ul>
+ * <li><tt>SHA1withDSA</tt></li>
+ * <li><tt>SHA1withRSA</tt></li>
+ * <li><tt>SHA256withRSA</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Signature">
+ * Signature section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Benjamin Renaud
*
*/
@@ -144,9 +158,9 @@
* Creates a Signature object for the specified algorithm.
*
* @param algorithm the standard string name of the algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the Signature section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Signature">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*/
protected Signature(String algorithm) {
@@ -184,9 +198,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the Signature section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Signature">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new Signature object.
@@ -303,9 +317,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the Signature section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Signature">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -353,9 +367,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the Signature section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Signature">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/java/security/cert/CertPath.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertPath.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -83,6 +83,19 @@
* may not follow these conventions. PKIX <code>CertPathValidator</code>s will
* detect any departure from these conventions that cause the certification
* path to be invalid and throw a <code>CertPathValidatorException</code>.
+ *
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>CertPath</code> encodings:
+ * <ul>
+ * <li><tt>PKCS7</tt></li>
+ * <li><tt>PkiPath</tt></li>
+ * </ul>
+ * These encodings are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * CertPath Encodings section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other encodings are supported.
* <p>
* <b>Concurrent Access</b>
* <p>
--- a/jdk/src/share/classes/java/security/cert/CertPathBuilder.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertPathBuilder.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -52,6 +52,19 @@
* result (including the <code>CertPath</code> that was built) is returned
* in an object that implements the <code>CertPathBuilderResult</code>
* interface.
+ *
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>CertPathBuilder</code> algorithm:
+ * <ul>
+ * <li><tt>PKIX</tt></li>
+ * </ul>
+ * This algorithm is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
+ * CertPathBuilder section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* <p>
* <b>Concurrent Access</b>
* <p>
@@ -118,10 +131,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested <code>CertPathBuilder</code>
- * algorithm. See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * algorithm. See the CertPathBuilder section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @return a <code>CertPathBuilder</code> object that implements the
* specified algorithm.
@@ -153,10 +166,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested <code>CertPathBuilder</code>
- * algorithm. See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * algorithm. See the CertPathBuilder section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @param provider the name of the provider.
*
@@ -193,10 +206,10 @@
* does not have to be registered in the provider list.
*
* @param algorithm the name of the requested <code>CertPathBuilder</code>
- * algorithm. See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * algorithm. See the CertPathBuilder section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @param provider the provider.
*
--- a/jdk/src/share/classes/java/security/cert/CertPathValidator.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertPathValidator.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -53,6 +53,19 @@
* and an algorithm-specific set of parameters. If successful, the result is
* returned in an object that implements the
* <code>CertPathValidatorResult</code> interface.
+ *
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>CertPathValidator</code> algorithm:
+ * <ul>
+ * <li><tt>PKIX</tt></li>
+ * </ul>
+ * This algorithm is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator">
+ * CertPathValidator section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* <p>
* <b>Concurrent Access</b>
* <p>
@@ -118,10 +131,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested <code>CertPathValidator</code>
- * algorithm. See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * algorithm. See the CertPathValidator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @return a <code>CertPathValidator</code> object that implements the
* specified algorithm.
@@ -153,10 +166,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested <code>CertPathValidator</code>
- * algorithm. See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * algorithm. See the CertPathValidator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @param provider the name of the provider.
*
@@ -193,12 +206,11 @@
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
- * @param algorithm the name of the requested
- * <code>CertPathValidator</code> algorithm.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * @param algorithm the name of the requested <code>CertPathValidator</code>
+ * algorithm. See the CertPathValidator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @param provider the provider.
*
--- a/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -286,6 +286,11 @@
/**
* The signature is invalid.
*/
- INVALID_SIGNATURE
+ INVALID_SIGNATURE,
+
+ /**
+ * The public key or the signature algorithm has been constrained.
+ */
+ ALGORITHM_CONSTRAINED
}
}
--- a/jdk/src/share/classes/java/security/cert/CertStore.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertStore.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -58,10 +58,20 @@
* vast repository of untrusted certificates and CRLs. For example, an LDAP
* implementation of <code>CertStore</code> provides access to certificates
* and CRLs stored in one or more directories using the LDAP protocol and the
- * schema as defined in the RFC service attribute. See Appendix A in the
- * <a href= "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide</a> for more information about
- * standard <code>CertStore</code> types.
+ * schema as defined in the RFC service attribute.
+ *
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>CertStore</code> type:
+ * <ul>
+ * <li><tt>Collection</tt></li>
+ * </ul>
+ * This type is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertStore">
+ * CertStore section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other types are supported.
+ *
* <p>
* <b>Concurrent Access</b>
* <p>
@@ -192,10 +202,10 @@
* cloned.
*
* @param type the name of the requested <code>CertStore</code> type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard types.
+ * See the CertStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard types.
*
* @param params the initialization parameters (may be <code>null</code>).
*
@@ -252,10 +262,10 @@
* cloned.
*
* @param type the requested <code>CertStore</code> type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard types.
+ * See the CertStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard types.
*
* @param params the initialization parameters (may be <code>null</code>).
*
@@ -310,10 +320,10 @@
* cloned.
*
* @param type the requested <code>CertStore</code> type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard types.
+ * See the CertStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard types.
*
* @param params the initialization parameters (may be <code>null</code>).
*
--- a/jdk/src/share/classes/java/security/cert/Certificate.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/Certificate.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -69,9 +69,9 @@
* Creates a certificate of the specified type.
*
* @param type the standard name of the certificate type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the CertificateFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard certificate types.
*/
protected Certificate(String type) {
--- a/jdk/src/share/classes/java/security/cert/CertificateFactory.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertificateFactory.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, 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
@@ -91,11 +91,29 @@
* }
* </pre>
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>CertificateFactory</code> type:
+ * <ul>
+ * <li><tt>X.509</tt></li>
+ * </ul>
+ * and the following standard <code>CertPath</code> encodings:
+ * <ul>
+ * <li><tt>PKCS7</tt></li>
+ * <li><tt>PkiPath</tt></li>
+ * </ul>
+ * The type and encodings are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
+ * CertificateFactory section</a> and the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * CertPath Encodings section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other types or encodings are supported.
+ *
* @author Hemma Prafullchandra
* @author Jan Luehe
* @author Sean Mullan
*
- *
* @see Certificate
* @see X509Certificate
* @see CertPath
@@ -146,9 +164,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param type the name of the requested certificate type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the CertificateFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard certificate types.
*
* @return a certificate factory object for the specified type.
@@ -184,9 +202,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param type the certificate type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the CertificateFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard certificate types.
*
* @param provider the name of the provider.
@@ -228,11 +246,10 @@
* does not have to be registered in the provider list.
*
* @param type the certificate type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the CertificateFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard certificate types.
-
* @param provider the provider.
*
* @return a certificate factory object for the specified type.
@@ -325,10 +342,10 @@
/**
* Returns an iteration of the <code>CertPath</code> encodings supported
* by this certificate factory, with the default encoding first. See
- * Appendix A in the
- * <a href="../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide</a> for information about
- * standard encoding names and their formats.
+ * the CertPath Encodings section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard encoding names and their formats.
* <p>
* Attempts to modify the returned <code>Iterator</code> via its
* <code>remove</code> method result in an
@@ -364,9 +381,10 @@
/**
* Generates a <code>CertPath</code> object and initializes it with
* the data read from the <code>InputStream</code> inStream. The data
- * is assumed to be in the specified encoding. See Appendix A in the
- * <a href="../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide</a>
+ * is assumed to be in the specified encoding. See
+ * the CertPath Encodings section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard encoding names and their formats.
*
* @param inStream an <code>InputStream</code> containing the data
--- a/jdk/src/share/classes/java/security/cert/CertificateFactorySpi.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertificateFactorySpi.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, 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
@@ -182,9 +182,9 @@
/**
* Returns an iteration of the <code>CertPath</code> encodings supported
* by this certificate factory, with the default encoding first. See
- * Appendix A in the
- * <a href="../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide</a>
+ * the CertPath Encodings section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard encoding names.
* <p>
* Attempts to modify the returned <code>Iterator</code> via its
--- a/jdk/src/share/classes/java/security/cert/package.html Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/package.html Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
<!--
- Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -35,9 +35,15 @@
<h2>Package Specification</h2>
<ul>
- <li><a href="../../../../technotes/guides/security/crypto/CryptoSpec.html"><b>Cryptography
- Architecture</b></a>
- <li>RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL Profile
+ <li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture (JCA) Reference Guide</b></a>
+ <li>RFC 3280: Internet X.509 Public Key Infrastructure Certificate and
+ Certificate Revocation List (CRL) Profile
+ <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture Standard Algorithm Name
+ Documentation</b></a></li>
</ul>
<h2>Related Documentation</h2>
@@ -45,11 +51,13 @@
For information about X.509 certificates and CRLs, please see:
<ul>
<li><a href="http://www.ietf.org/rfc/rfc3280.txt">
-http://www.ietf.org/rfc/rfc3280.txt</a>
- <li><a href="../../../../technotes/guides/security/certpath/CertPathProgGuide.html">
-PKI API Programmer's Guide</a>
- <li><a href="../../../../technotes/guides/security/cert3.html">
-X.509 Certificates and CRLs</a>
+ http://www.ietf.org/rfc/rfc3280.txt</a>
+ <li><a href=
+ "{@docRoot}/../technotes/guides/security/certpath/CertPathProgGuide.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ PKI Programmer's Guide</a>
+ <li><a href="{@docRoot}/../technotes/guides/security/cert3.html">
+ X.509 Certificates and Certificate Revocation Lists (CRLs)</a>
</ul>
@since 1.2
--- a/jdk/src/share/classes/java/security/package.html Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/security/package.html Mon Feb 14 16:30:10 2011 -0800
@@ -2,7 +2,7 @@
<html>
<head>
<!--
-Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1998, 2010, 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
@@ -51,10 +51,17 @@
<h2>Package Specification</h2>
<ul>
- <li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html"><b>
- Cryptography Architecture</b></a></li>
+ <li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture (JCA) Reference Guide</b></a></li>
- <li>PKCS8: Private-Key Information Standard, Version 1.2, November 1993</li>
+ <li>PKCS #8: Private-Key Information Syntax Standard, Version 1.2,
+ November 1993</li>
+
+ <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture Standard Algorithm Name
+ Documentation</b></a></li>
</ul>
<h2>Related Documentation</h2>
@@ -62,13 +69,16 @@
For further documentation, please see:
<ul>
<li><a href=
- "{@docRoot}/../technotes/guides/security/spec/security-spec.doc.html"><b>
- Security Architecture</b></a></li>
+ "{@docRoot}/../technotes/guides/security/spec/security-spec.doc.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ SE Platform Security Architecture</b></a></li>
<li><a href=
- "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html"><b>
- How to Implement a Provider for the Java Cryptography Architecture
+ "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
+ <b>How to Implement a Provider in the
+ Java<FONT SIZE=-2><SUP>TM</SUP></FONT> Cryptography Architecture
</b></a></li>
+
<li><a href=
"{@docRoot}/../technotes/guides/security/PolicyFiles.html"><b>
Default Policy Implementation and Policy File Syntax
@@ -76,12 +86,14 @@
<li><a href=
"{@docRoot}/../technotes/guides/security/permissions.html"><b>
- Policy Permissions
+ Permissions in the
+ Java<FONT SIZE=-2><SUP>TM</SUP></FONT> SE Development Kit (JDK)
</b></a></li>
<li><a href=
"{@docRoot}/../technotes/guides/security/SecurityToolsSummary.html"><b>
- Security Tools Summary
+ Summary of Tools for
+ Java<FONT SIZE=-2><SUP>TM</SUP></FONT> Platform Security
</b></a></li>
<li><b>keytool</b>
@@ -100,6 +112,6 @@
</ul>
-@since JDK1.1
+@since 1.1
</body>
</html>
--- a/jdk/src/share/classes/java/sql/package.html Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/sql/package.html Mon Feb 14 16:30:10 2011 -0800
@@ -2,7 +2,7 @@
<html>
<head>
<!--
-Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -45,21 +45,22 @@
use and update data from a spread sheet, flat file, or any other tabular
data source.
<P>
-<h2>What the JDBC<sup><font size=-2>TM</font></sup> 4.0 API Includes</h2>
-The JDBC<sup><font size=-2>TM</font></sup> 4.0 API includes both
+<h2>What the JDBC<sup><font size=-2>TM</font></sup> 4.1 API Includes</h2>
+The JDBC<sup><font size=-2>TM</font></sup> 4.1 API includes both
the <code>java.sql</code> package, referred to as the JDBC core API,
and the <code>javax.sql</code> package, referred to as the JDBC Optional
Package API. This complete JDBC API
is included in the Java<sup><font size=-2>TM</font></sup>
-Standard Edition (Java SE<sup><font size=-2>TM</font></sup>), version 6.
+Standard Edition (Java SE<sup><font size=-2>TM</font></sup>), version 7.
The <code>javax.sql</code> package extends the functionality of the JDBC API
from a client-side API to a server-side API, and it is an essential part
of the Java<sup><font size=-2>TM</font></sup> Enterprise Edition
(Java EE<sup><font size=-2>TM</font></sup>) technology.
<P>
<h2>Versions</h2>
-The JDBC 4.0 API incorporates all of the previous JDBC API versions:
+The JDBC 4.1 API incorporates all of the previous JDBC API versions:
<UL>
+ <LI> The JDBC 4.0 API
<LI> The JDBC 3.0 API
<LI> The JDBC 2.1 core API
<LI> The JDBC 2.0 Optional Package API<br>
@@ -75,7 +76,9 @@
Javadoc<sup><font size=-2>TM</font></sup> comments for the JDBC API,
they indicate the following:
<UL>
- <LI>Since 1.6 -- new in the JDBC 4.0 API and part of the Java SE platform,
+ <LI>Since 1.7 -- new in the JDBC 4.1 API and part of the Java SE platform,
+ version 7
+<LI>Since 1.6 -- new in the JDBC 4.0 API and part of the Java SE platform,
version 6
<LI>Since 1.4 -- new in the JDBC 3.0 API and part of the J2SE platform,
version 1.4
@@ -176,6 +179,25 @@
</UL>
</UL>
<P>
+ <h3><code>java.sql</code> and <code>javax.sql</code> Features Introduced in the JDBC 4.1 API</h3>
+<UL>
+ <LI>Allow <code>Connection</code>,
+ <code>ResultSet</code> and <code>Statement</code> objects to be
+ used with the try-with-resources statement</LI>
+ <LI>Supported added to <code>CallableStatement</code> and
+ <code>ResultSet</code> to specify the Java type to convert to via the
+ <code>getObject</code> method</LI>
+ <LI><code>DatabaseMetaData</code> methods to return PseudoColumns and if a
+ generated key is always returned</LI>
+ <LI>Added support to <code>Connection</code> to specify a database schema,
+ abort and timeout a physical connection.</LI>
+ <LI>Added support to close a <code>Statement</code> object when its dependent
+ objects have been closed</LI>
+ <LI>Support for obtaining the parent logger for a <code>Driver</code>,
+ <code>DataSource</code>, <code>ConnectionPoolDataSource</code> and
+ <code>XADataSource</code></LI>
+
+</UL>
<h3><code>java.sql</code> and <code>javax.sql</code> Features Introduced in the JDBC 4.0 API</h3>
<UL>
<LI>auto java.sql.Driver discovery -- no longer need to load a
@@ -190,7 +212,7 @@
<li>Support added to allow a JDBC application to access an instance of a JDBC resource
that has been wrapped by a vendor, usually in an application server or connection
pooling environment.
- <li>Availability to be notfied when a <code>PreparedStatement</code> that is associated
+ <li>Availability to be notified when a <code>PreparedStatement</code> that is associated
with a <code>PooledConnection</code> has been closed or the driver determines is invalid
@@ -288,7 +310,7 @@
<h2>Related Documentation</h2>
<ul>
- <li><a href="../../../guide/jdbc/getstart/GettingStartedTOC.fm.html">Getting Started</a>--overviews of the major interfaces
+ <li><a href="../../../technotes/guides/jdbc/getstart/GettingStartedTOC.fm.html">Getting Started</a>--overviews of the major interfaces
<P>
<li><a href="http://java.sun.com/docs/books/tutorial/jdbc">Chapters on the JDBC
API</a>--from the online version of <i>The Java Tutorial Continued</i>
--- a/jdk/src/share/classes/java/util/Arrays.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/util/Arrays.java Mon Feb 14 16:30:10 2011 -0800
@@ -2823,6 +2823,7 @@
* @param a the array by which the list will be backed
* @return a list view of the specified array
*/
+ @SafeVarargs
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
--- a/jdk/src/share/classes/java/util/Collections.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/util/Collections.java Mon Feb 14 16:30:10 2011 -0800
@@ -3827,6 +3827,7 @@
* @see Collection#addAll(Collection)
* @since 1.5
*/
+ @SafeVarargs
public static <T> boolean addAll(Collection<? super T> c, T... elements) {
boolean result = false;
for (T element : elements)
--- a/jdk/src/share/classes/java/util/DualPivotQuicksort.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/util/DualPivotQuicksort.java Mon Feb 14 16:30:10 2011 -0800
@@ -36,7 +36,7 @@
* @author Jon Bentley
* @author Josh Bloch
*
- * @version 2010.10.13 m765.827.12i:5\7p
+ * @version 2011.02.11 m765.827.12i:5\7pm
* @since 1.7
*/
final class DualPivotQuicksort {
@@ -51,6 +51,22 @@
*/
/**
+ * The maximum number of runs in merge sort.
+ */
+ private static final int MAX_RUN_COUNT = 67;
+
+ /**
+ * The maximum length of run in merge sort.
+ */
+ private static final int MAX_RUN_LENGTH = 33;
+
+ /**
+ * If the length of an array to be sorted is less than this
+ * constant, Quicksort is used in preference to merge sort.
+ */
+ private static final int QUICKSORT_THRESHOLD = 286;
+
+ /**
* If the length of an array to be sorted is less than this
* constant, insertion sort is used in preference to Quicksort.
*/
@@ -78,7 +94,7 @@
* @param a the array to be sorted
*/
public static void sort(int[] a) {
- sort(a, 0, a.length - 1, true);
+ sort(a, 0, a.length - 1);
}
/**
@@ -89,7 +105,89 @@
* @param right the index of the last element, inclusive, to be sorted
*/
public static void sort(int[] a, int left, int right) {
- sort(a, left, right, true);
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT + 1];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ int t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ int[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new int[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new int[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ int[] t = a; a = b; b = t;
+ }
}
/**
@@ -103,7 +201,7 @@
private static void sort(int[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -126,26 +224,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- int a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ int a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -202,19 +298,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- int pivot1 = a[e2];
- int pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ int pivot1 = a[e2];
+ int pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -259,7 +355,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -269,7 +365,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -278,7 +374,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -299,10 +395,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -330,7 +427,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -348,12 +445,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = pivot1;
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -361,7 +458,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ int pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -383,35 +486,35 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
int ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
*/
- a[k] = pivot1;
+ a[k] = pivot;
}
a[great] = ak;
- great--;
+ --great;
}
}
@@ -431,7 +534,7 @@
* @param a the array to be sorted
*/
public static void sort(long[] a) {
- sort(a, 0, a.length - 1, true);
+ sort(a, 0, a.length - 1);
}
/**
@@ -442,7 +545,89 @@
* @param right the index of the last element, inclusive, to be sorted
*/
public static void sort(long[] a, int left, int right) {
- sort(a, left, right, true);
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT + 1];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ long t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ long[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new long[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new long[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ long[] t = a; a = b; b = t;
+ }
}
/**
@@ -456,7 +641,7 @@
private static void sort(long[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -479,26 +664,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- long a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ long a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -555,19 +738,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- long pivot1 = a[e2];
- long pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ long pivot1 = a[e2];
+ long pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -612,7 +795,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -622,7 +805,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -631,7 +814,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -652,10 +835,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -683,7 +867,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -701,12 +885,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = pivot1;
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -714,7 +898,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ long pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -736,35 +926,35 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
long ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
*/
- a[k] = pivot1;
+ a[k] = pivot;
}
a[great] = ak;
- great--;
+ --great;
}
}
@@ -799,9 +989,9 @@
if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
int[] count = new int[NUM_SHORT_VALUES];
- for (int i = left - 1; ++i <= right; ) {
- count[a[i] - Short.MIN_VALUE]++;
- }
+ for (int i = left - 1; ++i <= right;
+ count[a[i] - Short.MIN_VALUE]++
+ );
for (int i = NUM_SHORT_VALUES, k = right + 1; k > left; ) {
while (count[--i] == 0);
short value = (short) (i + Short.MIN_VALUE);
@@ -812,7 +1002,7 @@
} while (--s > 0);
}
} else { // Use Dual-Pivot Quicksort on small arrays
- sort(a, left, right, true);
+ doSort(a, left, right);
}
}
@@ -820,6 +1010,99 @@
private static final int NUM_SHORT_VALUES = 1 << 16;
/**
+ * Sorts the specified range of the array.
+ *
+ * @param a the array to be sorted
+ * @param left the index of the first element, inclusive, to be sorted
+ * @param right the index of the last element, inclusive, to be sorted
+ */
+ private static void doSort(short[] a, int left, int right) {
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT + 1];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ short t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ short[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new short[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new short[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ short[] t = a; a = b; b = t;
+ }
+ }
+
+ /**
* Sorts the specified range of the array by Dual-Pivot Quicksort.
*
* @param a the array to be sorted
@@ -827,10 +1110,10 @@
* @param right the index of the last element, inclusive, to be sorted
* @param leftmost indicates if this part is the leftmost in the range
*/
- private static void sort(short[] a, int left, int right,boolean leftmost) {
+ private static void sort(short[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -853,26 +1136,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- short a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ short a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -929,19 +1210,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- short pivot1 = a[e2];
- short pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ short pivot1 = a[e2];
+ short pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -986,7 +1267,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -996,7 +1277,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -1005,7 +1286,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -1026,10 +1307,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -1057,7 +1339,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -1075,12 +1357,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = pivot1;
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -1088,7 +1370,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ short pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -1110,35 +1398,35 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
short ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
*/
- a[k] = pivot1;
+ a[k] = pivot;
}
a[great] = ak;
- great--;
+ --great;
}
}
@@ -1173,9 +1461,9 @@
if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
int[] count = new int[NUM_CHAR_VALUES];
- for (int i = left - 1; ++i <= right; ) {
- count[a[i]]++;
- }
+ for (int i = left - 1; ++i <= right;
+ count[a[i]]++
+ );
for (int i = NUM_CHAR_VALUES, k = right + 1; k > left; ) {
while (count[--i] == 0);
char value = (char) i;
@@ -1186,7 +1474,7 @@
} while (--s > 0);
}
} else { // Use Dual-Pivot Quicksort on small arrays
- sort(a, left, right, true);
+ doSort(a, left, right);
}
}
@@ -1194,6 +1482,99 @@
private static final int NUM_CHAR_VALUES = 1 << 16;
/**
+ * Sorts the specified range of the array.
+ *
+ * @param a the array to be sorted
+ * @param left the index of the first element, inclusive, to be sorted
+ * @param right the index of the last element, inclusive, to be sorted
+ */
+ private static void doSort(char[] a, int left, int right) {
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT + 1];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ char t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ char[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new char[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new char[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ char[] t = a; a = b; b = t;
+ }
+ }
+
+ /**
* Sorts the specified range of the array by Dual-Pivot Quicksort.
*
* @param a the array to be sorted
@@ -1204,7 +1585,7 @@
private static void sort(char[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -1227,26 +1608,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- char a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ char a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -1303,19 +1682,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- char pivot1 = a[e2];
- char pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ char pivot1 = a[e2];
+ char pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -1360,7 +1739,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -1370,7 +1749,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -1379,7 +1758,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -1400,10 +1779,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -1431,7 +1811,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -1449,12 +1829,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = pivot1;
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -1462,7 +1842,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ char pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -1484,35 +1870,35 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
char ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
*/
- a[k] = pivot1;
+ a[k] = pivot;
}
a[great] = ak;
- great--;
+ --great;
}
}
@@ -1550,9 +1936,9 @@
if (right - left > COUNTING_SORT_THRESHOLD_FOR_BYTE) {
int[] count = new int[NUM_BYTE_VALUES];
- for (int i = left - 1; ++i <= right; ) {
- count[a[i] - Byte.MIN_VALUE]++;
- }
+ for (int i = left - 1; ++i <= right;
+ count[a[i] - Byte.MIN_VALUE]++
+ );
for (int i = NUM_BYTE_VALUES, k = right + 1; k > left; ) {
while (count[--i] == 0);
byte value = (byte) (i + Byte.MIN_VALUE);
@@ -1597,21 +1983,21 @@
* Phase 1: Move NaNs to the end of the array.
*/
while (left <= right && Float.isNaN(a[right])) {
- right--;
+ --right;
}
for (int k = right; --k >= left; ) {
float ak = a[k];
if (ak != ak) { // a[k] is NaN
a[k] = a[right];
a[right] = ak;
- right--;
+ --right;
}
}
/*
* Phase 2: Sort everything except NaNs (which are already in place).
*/
- sort(a, left, right, true);
+ doSort(a, left, right);
/*
* Phase 3: Place negative zeros before positive zeros.
@@ -1636,7 +2022,7 @@
* Skip the last negative value (if any) or all leading negative zeros.
*/
while (left <= right && Float.floatToRawIntBits(a[left]) < 0) {
- left++;
+ ++left;
}
/*
@@ -1673,6 +2059,99 @@
}
/**
+ * Sorts the specified range of the array.
+ *
+ * @param a the array to be sorted
+ * @param left the index of the first element, inclusive, to be sorted
+ * @param right the index of the last element, inclusive, to be sorted
+ */
+ private static void doSort(float[] a, int left, int right) {
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT + 1];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ float t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ float[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new float[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new float[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ float[] t = a; a = b; b = t;
+ }
+ }
+
+ /**
* Sorts the specified range of the array by Dual-Pivot Quicksort.
*
* @param a the array to be sorted
@@ -1680,10 +2159,10 @@
* @param right the index of the last element, inclusive, to be sorted
* @param leftmost indicates if this part is the leftmost in the range
*/
- private static void sort(float[] a, int left, int right,boolean leftmost) {
+ private static void sort(float[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -1706,26 +2185,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- float a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ float a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -1782,19 +2259,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- float pivot1 = a[e2];
- float pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ float pivot1 = a[e2];
+ float pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -1839,7 +2316,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -1849,7 +2326,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -1858,7 +2335,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -1879,10 +2356,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -1910,7 +2388,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -1928,12 +2406,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -1941,7 +2419,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ float pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -1963,27 +2447,27 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
float ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
@@ -1991,7 +2475,7 @@
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
@@ -2026,21 +2510,21 @@
* Phase 1: Move NaNs to the end of the array.
*/
while (left <= right && Double.isNaN(a[right])) {
- right--;
+ --right;
}
for (int k = right; --k >= left; ) {
double ak = a[k];
if (ak != ak) { // a[k] is NaN
a[k] = a[right];
a[right] = ak;
- right--;
+ --right;
}
}
/*
* Phase 2: Sort everything except NaNs (which are already in place).
*/
- sort(a, left, right, true);
+ doSort(a, left, right);
/*
* Phase 3: Place negative zeros before positive zeros.
@@ -2065,7 +2549,7 @@
* Skip the last negative value (if any) or all leading negative zeros.
*/
while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) {
- left++;
+ ++left;
}
/*
@@ -2102,6 +2586,99 @@
}
/**
+ * Sorts the specified range of the array.
+ *
+ * @param a the array to be sorted
+ * @param left the index of the first element, inclusive, to be sorted
+ * @param right the index of the last element, inclusive, to be sorted
+ */
+ private static void doSort(double[] a, int left, int right) {
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT + 1];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ double t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ double[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new double[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new double[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ double[] t = a; a = b; b = t;
+ }
+ }
+
+ /**
* Sorts the specified range of the array by Dual-Pivot Quicksort.
*
* @param a the array to be sorted
@@ -2109,10 +2686,10 @@
* @param right the index of the last element, inclusive, to be sorted
* @param leftmost indicates if this part is the leftmost in the range
*/
- private static void sort(double[] a, int left,int right,boolean leftmost) {
+ private static void sort(double[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -2135,26 +2712,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- double a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ double a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -2211,19 +2786,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- double pivot1 = a[e2];
- double pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ double pivot1 = a[e2];
+ double pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -2268,7 +2843,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -2278,7 +2853,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -2287,7 +2862,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -2308,10 +2883,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -2339,7 +2915,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -2357,12 +2933,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -2370,7 +2946,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ double pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -2392,27 +2974,27 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
double ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
@@ -2420,7 +3002,7 @@
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
--- a/jdk/src/share/classes/java/util/EnumSet.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/util/EnumSet.java Mon Feb 14 16:30:10 2011 -0800
@@ -317,6 +317,7 @@
* or if <tt>rest</tt> is null
* @return an enum set initially containing the specified elements
*/
+ @SafeVarargs
public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
EnumSet<E> result = noneOf(first.getDeclaringClass());
result.add(first);
--- a/jdk/src/share/classes/java/util/Formatter.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/util/Formatter.java Mon Feb 14 16:30:10 2011 -0800
@@ -47,9 +47,6 @@
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -1859,7 +1856,7 @@
private static Charset toCharset(String csn)
throws UnsupportedEncodingException
{
- Objects.nonNull(csn, "charsetName");
+ Objects.requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
@@ -2179,7 +2176,7 @@
*/
public Formatter(PrintStream ps) {
this(Locale.getDefault(Locale.Category.FORMAT),
- (Appendable)Objects.nonNull(ps));
+ (Appendable)Objects.requireNonNull(ps));
}
/**
--- a/jdk/src/share/classes/java/util/Locale.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/util/Locale.java Mon Feb 14 16:30:10 2011 -0800
@@ -1265,7 +1265,9 @@
StringBuilder buf = new StringBuilder();
String subtag = tag.getLanguage();
- buf.append(LanguageTag.canonicalizeLanguage(subtag));
+ if (subtag.length() > 0) {
+ buf.append(LanguageTag.canonicalizeLanguage(subtag));
+ }
subtag = tag.getScript();
if (subtag.length() > 0) {
@@ -1294,7 +1296,10 @@
subtag = tag.getPrivateuse();
if (subtag.length() > 0) {
- buf.append(LanguageTag.SEP).append(LanguageTag.PRIVATEUSE).append(LanguageTag.SEP);
+ if (buf.length() > 0) {
+ buf.append(LanguageTag.SEP);
+ }
+ buf.append(LanguageTag.PRIVATEUSE).append(LanguageTag.SEP);
// preserve casing
buf.append(subtag);
}
--- a/jdk/src/share/classes/java/util/Objects.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/util/Objects.java Mon Feb 14 16:30:10 2011 -0800
@@ -187,7 +187,7 @@
* and constructors, as demonstrated below:
* <blockquote><pre>
* public Foo(Bar bar) {
- * this.bar = Objects.nonNull(bar);
+ * this.bar = Objects.requireNonNull(bar);
* }
* </pre></blockquote>
*
@@ -196,7 +196,7 @@
* @return {@code obj} if not {@code null}
* @throws NullPointerException if {@code obj} is {@code null}
*/
- public static <T> T nonNull(T obj) {
+ public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
@@ -209,8 +209,8 @@
* constructors with multiple parameters, as demonstrated below:
* <blockquote><pre>
* public Foo(Bar bar, Baz baz) {
- * this.bar = Objects.nonNull(bar, "bar must not be null");
- * this.baz = Objects.nonNull(baz, "baz must not be null");
+ * this.bar = Objects.requireNonNull(bar, "bar must not be null");
+ * this.baz = Objects.requireNonNull(baz, "baz must not be null");
* }
* </pre></blockquote>
*
@@ -221,7 +221,7 @@
* @return {@code obj} if not {@code null}
* @throws NullPointerException if {@code obj} is {@code null}
*/
- public static <T> T nonNull(T obj, String message) {
+ public static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
--- a/jdk/src/share/classes/java/util/Scanner.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/util/Scanner.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,7 +25,8 @@
package java.util;
-import java.nio.file.FileRef;
+import java.nio.file.Path;
+import java.nio.file.Files;
import java.util.regex.*;
import java.io.*;
import java.math.*;
@@ -34,6 +35,7 @@
import java.nio.charset.*;
import java.text.*;
import java.util.Locale;
+
import sun.misc.LRUCache;
/**
@@ -591,7 +593,7 @@
* interface
*/
public Scanner(Readable source) {
- this(Objects.nonNull(source, "source"), WHITESPACE_PATTERN);
+ this(Objects.requireNonNull(source, "source"), WHITESPACE_PATTERN);
}
/**
@@ -618,7 +620,7 @@
* does not exist
*/
public Scanner(InputStream source, String charsetName) {
- this(makeReadable(Objects.nonNull(source, "source"), toCharset(charsetName)),
+ this(makeReadable(Objects.requireNonNull(source, "source"), toCharset(charsetName)),
WHITESPACE_PATTERN);
}
@@ -628,7 +630,7 @@
* @throws IllegalArgumentException if the charset is not supported
*/
private static Charset toCharset(String csn) {
- Objects.nonNull(csn, "charsetName");
+ Objects.requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException e) {
@@ -669,7 +671,7 @@
public Scanner(File source, String charsetName)
throws FileNotFoundException
{
- this(Objects.nonNull(source), toDecoder(charsetName));
+ this(Objects.requireNonNull(source), toDecoder(charsetName));
}
private Scanner(File source, CharsetDecoder dec)
@@ -679,7 +681,7 @@
}
private static CharsetDecoder toDecoder(String charsetName) {
- Objects.nonNull(charsetName, "charsetName");
+ Objects.requireNonNull(charsetName, "charsetName");
try {
return Charset.forName(charsetName).newDecoder();
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
@@ -699,16 +701,16 @@
* {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
*
* @param source
- * A file to be scanned
+ * the path to the file to be scanned
* @throws IOException
* if an I/O error occurs opening source
*
* @since 1.7
*/
- public Scanner(FileRef source)
+ public Scanner(Path source)
throws IOException
{
- this(source.newInputStream());
+ this(Files.newInputStream(source));
}
/**
@@ -717,7 +719,7 @@
* characters using the specified charset.
*
* @param source
- * A file to be scanned
+ * the path to the file to be scanned
* @param charsetName
* The encoding type used to convert bytes from the file
* into characters to be scanned
@@ -727,12 +729,12 @@
* if the specified encoding is not found
* @since 1.7
*/
- public Scanner(FileRef source, String charsetName) throws IOException {
- this(Objects.nonNull(source), toCharset(charsetName));
+ public Scanner(Path source, String charsetName) throws IOException {
+ this(Objects.requireNonNull(source), toCharset(charsetName));
}
- private Scanner(FileRef source, Charset charset) throws IOException {
- this(makeReadable(source.newInputStream(), charset));
+ private Scanner(Path source, Charset charset) throws IOException {
+ this(makeReadable(Files.newInputStream(source), charset));
}
/**
@@ -754,7 +756,7 @@
* @param source A channel to scan
*/
public Scanner(ReadableByteChannel source) {
- this(makeReadable(Objects.nonNull(source, "source")),
+ this(makeReadable(Objects.requireNonNull(source, "source")),
WHITESPACE_PATTERN);
}
@@ -774,7 +776,7 @@
* does not exist
*/
public Scanner(ReadableByteChannel source, String charsetName) {
- this(makeReadable(Objects.nonNull(source, "source"), toDecoder(charsetName)),
+ this(makeReadable(Objects.requireNonNull(source, "source"), toDecoder(charsetName)),
WHITESPACE_PATTERN);
}
--- a/jdk/src/share/classes/java/util/regex/Pattern.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/util/regex/Pattern.java Mon Feb 14 16:30:10 2011 -0800
@@ -101,6 +101,11 @@
* <td headers="matches">The character with hexadecimal value <tt>0x</tt><i>hh</i></td></tr>
* <tr><td valign="top" headers="construct characters"><tt>\u</tt><i>hhhh</i></td>
* <td headers="matches">The character with hexadecimal value <tt>0x</tt><i>hhhh</i></td></tr>
+ * <tr><td valign="top" headers="construct characters"><tt>\x</tt><i>{h...h}</i></td>
+ * <td headers="matches">The character with hexadecimal value <tt>0x</tt><i>h...h</i>
+ * ({@link java.lang.Character#MIN_CODE_POINT Character.MIN_CODE_POINT}
+ * <= <tt>0x</tt><i>h...h</i> <= 
+ * {@link java.lang.Character#MAX_CODE_POINT Character.MAX_CODE_POINT})</td></tr>
* <tr><td valign="top" headers="matches"><tt>\t</tt></td>
* <td headers="matches">The tab character (<tt>'\u0009'</tt>)</td></tr>
* <tr><td valign="top" headers="construct characters"><tt>\n</tt></td>
@@ -529,6 +534,13 @@
* while not equal, compile into the same pattern, which matches the character
* with hexadecimal value <tt>0x2014</tt>.
*
+ * <p> A Unicode character can also be represented in a regular-expression by
+ * using its hexadecimal code point value directly as described in construct
+ * <tt>\x{...}</tt>, for example a supplementary character U+2011F
+ * can be specified as <tt>\x{2011F}</tt>, instead of two consecutive
+ * Unicode escape sequences of the surrogate pair
+ * <tt>\uD840</tt><tt>\uDD1F</tt>.
+ *
* <a name="ubc">
* <p>Unicode scripts, blocks and categories are written with the <tt>\p</tt> and
* <tt>\P</tt> constructs as in Perl. <tt>\p{</tt><i>prop</i><tt>}</tt> matches if
@@ -2993,6 +3005,16 @@
if (ASCII.isHexDigit(m)) {
return ASCII.toDigit(n) * 16 + ASCII.toDigit(m);
}
+ } else if (n == '{' && ASCII.isHexDigit(peek())) {
+ int ch = 0;
+ while (ASCII.isHexDigit(n = read())) {
+ ch = (ch << 4) + ASCII.toDigit(n);
+ if (ch > Character.MAX_CODE_POINT)
+ throw error("Hexadecimal codepoint is too big");
+ }
+ if (n != '}')
+ throw error("Unclosed hexadecimal escape sequence");
+ return ch;
}
throw error("Illegal hexadecimal escape sequence");
}
--- a/jdk/src/share/classes/java/util/spi/LocaleNameProvider.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/java/util/spi/LocaleNameProvider.java Mon Feb 14 16:30:10 2011 -0800
@@ -77,7 +77,7 @@
* is "Cyrl" and <code>locale</code> is fr_FR, getDisplayScript() will return "cyrillique".
* If the name returned cannot be localized according to <code>locale</code>,
* (say, the provider does not have a Japanese name for Cyrillic),
- * this method returns null.
+ * this method returns null. The default implementation returns null.
* @param scriptCode the four letter script code string in the form of title-case
* letters (the first letter is upper-case character between 'A' (U+0041) and
* 'Z' (U+005A) followed by three lower-case character between 'a' (U+0061)
--- a/jdk/src/share/classes/javax/crypto/Cipher.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/Cipher.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -78,7 +78,7 @@
* Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>");
* </pre>
*
- * Using modes such as <code>CFB</code> and <code>OFB<code>, block
+ * Using modes such as <code>CFB</code> and <code>OFB</code>, block
* ciphers can encrypt data in units smaller than the cipher's actual
* block size. When requesting such a mode, you may optionally specify
* the number of bits to be processed at a time by appending this number
@@ -89,6 +89,33 @@
* Thus, block ciphers can be turned into byte-oriented stream ciphers by
* using an 8 bit mode such as CFB8 or OFB8.
*
+ * <p> Every implementation of the Java platform is required to support
+ * the following standard <code>Cipher</code> transformations with the keysizes
+ * in parentheses:
+ * <ul>
+ * <li><tt>AES/CBC/NoPadding</tt> (128)</li>
+ * <li><tt>AES/CBC/PKCS5Padding</tt> (128)</li>
+ * <li><tt>AES/ECB/NoPadding</tt> (128)</li>
+ * <li><tt>AES/ECB/PKCS5Padding</tt> (128)</li>
+ * <li><tt>DES/CBC/NoPadding</tt> (56)</li>
+ * <li><tt>DES/CBC/PKCS5Padding</tt> (56)</li>
+ * <li><tt>DES/ECB/NoPadding</tt> (56)</li>
+ * <li><tt>DES/ECB/PKCS5Padding</tt> (56)</li>
+ * <li><tt>DESede/CBC/NoPadding</tt> (168)</li>
+ * <li><tt>DESede/CBC/PKCS5Padding</tt> (168)</li>
+ * <li><tt>DESede/ECB/NoPadding</tt> (168)</li>
+ * <li><tt>DESede/ECB/PKCS5Padding</tt> (168)</li>
+ * <li><tt>RSA/ECB/PKCS1Padding</tt> (1024, 2048)</li>
+ * <li><tt>RSA/ECB/OAEPWithSHA-1AndMGF1Padding</tt> (1024, 2048)</li>
+ * <li><tt>RSA/ECB/OAEPWithSHA-256AndMGF1Padding</tt> (1024, 2048)</li>
+ * </ul>
+ * These transformations are described in the
+ * <a href="{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
+ * Cipher section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other transformations are supported.
+ *
* @author Jan Luehe
* @see KeyGenerator
* @see SecretKey
@@ -408,10 +435,9 @@
*
* @param transformation the name of the transformation, e.g.,
* <i>DES/CBC/PKCS5Padding</i>.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Cipher section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard transformation names.
*
* @return a cipher that implements the requested transformation.
@@ -485,10 +511,9 @@
*
* @param transformation the name of the transformation,
* e.g., <i>DES/CBC/PKCS5Padding</i>.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Cipher section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard transformation names.
*
* @param provider the name of the provider.
@@ -538,10 +563,9 @@
*
* @param transformation the name of the transformation,
* e.g., <i>DES/CBC/PKCS5Padding</i>.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Cipher section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard transformation names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/ExemptionMechanism.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/ExemptionMechanism.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, 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
@@ -114,10 +114,10 @@
*
* @param algorithm the standard name of the requested exemption
* mechanism.
- * See Appendix A in the
+ * See the ExemptionMechanism section in the
* <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * "{docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard exemption mechanism names.
*
* @return the new <code>ExemptionMechanism</code> object.
@@ -153,10 +153,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
* @param algorithm the standard name of the requested exemption mechanism.
- * See Appendix A in the
+ * See the ExemptionMechanism section in the
* <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * "{docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard exemption mechanism names.
*
* @param provider the name of the provider.
@@ -197,10 +197,10 @@
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested exemption mechanism.
- * See Appendix A in the
+ * See the ExemptionMechanism section in the
* <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * "{docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard exemption mechanism names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/KeyAgreement.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/KeyAgreement.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -54,6 +54,18 @@
* <code>false</code>, and the second time setting it to <code>true</code>.
* There may be any number of parties involved in a key exchange.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>KeyAgreement</code> algorithm:
+ * <ul>
+ * <li><tt>DiffieHellman</tt></li>
+ * </ul>
+ * This algorithm is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
+ * KeyAgreement section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
* @see KeyGenerator
@@ -135,10 +147,9 @@
*
* @param algorithm the standard name of the requested key agreement
* algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyAgreement section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
* @return the new <code>KeyAgreement</code> object.
@@ -182,10 +193,9 @@
*
* @param algorithm the standard name of the requested key agreement
* algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyAgreement section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -227,10 +237,9 @@
*
* @param algorithm the standard name of the requested key agreement
* algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyAgreement section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/KeyGenerator.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/KeyGenerator.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -84,6 +84,23 @@
* (via a call to an <code>init</code> method), each provider must
* supply (and document) a default initialization.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>KeyGenerator</code> algorithms with the keysizes in
+ * parentheses:
+ * <ul>
+ * <li><tt>AES</tt> (128)</li>
+ * <li><tt>DES</tt> (56)</li>
+ * <li><tt>DESede</tt> (168)</li>
+ * <li><tt>HmacSHA1</tt></li>
+ * <li><tt>HmacSHA256</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
+ * KeyGenerator section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
* @see SecretKey
@@ -170,10 +187,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested key algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new <code>KeyGenerator</code> object.
@@ -204,10 +220,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested key algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -247,10 +262,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested key algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/Mac.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/Mac.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, 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
@@ -53,6 +53,20 @@
* e.g., MD5 or SHA-1, in combination with a secret shared key. HMAC is
* specified in RFC 2104.
*
+ * <p> Every implementation of the Java platform is required to support
+ * the following standard <code>Mac</code> algorithms:
+ * <ul>
+ * <li><tt>HmacMD5</tt></li>
+ * <li><tt>HmacSHA1</tt></li>
+ * <li><tt>HmacSHA256</tt></li>
+ * </ul>
+ * These algorithms are described in the
+ * <a href="{@docRoot}/../technotes/guides/security/StandardNames.html#Mac">
+ * Mac section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
* @since 1.4
@@ -134,9 +148,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested MAC algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Mac section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Mac">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new <code>Mac</code> object.
@@ -176,9 +190,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested MAC algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Mac section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Mac">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -214,9 +228,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested MAC algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Mac section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Mac">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/SecretKeyFactory.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/SecretKeyFactory.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -58,6 +58,20 @@
* <code>DESedeKeySpec</code> as a transparent representation of Triple DES
* keys.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>SecretKeyFactory</code> algorithms:
+ * <ul>
+ * <li><tt>AES</tt></li>
+ * <li><tt>DES</tt></li>
+ * <li><tt>DESede</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
+ * SecretKeyFactory section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
* @see SecretKey
@@ -125,9 +139,9 @@
*
* @param algorithm the standard name of the requested secret-key
* algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the SecretKeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new <code>SecretKeyFactory</code> object.
@@ -160,9 +174,9 @@
*
* @param algorithm the standard name of the requested secret-key
* algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the SecretKeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -204,9 +218,9 @@
*
* @param algorithm the standard name of the requested secret-key
* algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the SecretKeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/package.html Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/package.html Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
<!--
-Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1999, 2010, 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
@@ -44,6 +44,15 @@
Therefore application developers may take advantage of any number of
provider-based implementations without having to add or rewrite code.
+<h2>Package Specification</h2>
+
+<ul>
+ <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html"><b>
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture Standard Algorithm Name
+ Documentation</b></a></li>
+</ul>
+
<h2>Related Documentation</h2>
For further documentation, please see:
@@ -52,12 +61,12 @@
<a href=
"{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
<b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
- Cryptography Architecture API Specification and Reference
+ Cryptography Architecture (JCA) Reference Guide
</b></a></li>
<li>
<a href=
"{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
- <b>How to Implement a Provider for the
+ <b>How to Implement a Provider in the
Java<FONT SIZE=-2><SUP>TM</SUP></FONT> Cryptography Architecture
</b></a></li>
</ul>
--- a/jdk/src/share/classes/javax/net/ssl/SSLContext.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/net/ssl/SSLContext.java Mon Feb 14 16:30:10 2011 -0800
@@ -37,6 +37,18 @@
* with an optional set of key and trust managers and source of
* secure random bytes.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>SSLContext</code> protocol:
+ * <ul>
+ * <li><tt>TLSv1</tt></li>
+ * </ul>
+ * This protocol is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext">
+ * SSLContext section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @since 1.4
*/
public class SSLContext {
@@ -124,9 +136,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param protocol the standard name of the requested protocol.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html#AppA">
- * Java Secure Socket Extension Reference Guide </a>
+ * See the SSLContext section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a>
* for information about standard protocol names.
*
* @return the new <code>SSLContext</code> object.
@@ -159,9 +172,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param protocol the standard name of the requested protocol.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html#AppA">
- * Java Secure Socket Extension Reference Guide </a>
+ * See the SSLContext section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a>
* for information about standard protocol names.
*
* @param provider the name of the provider.
@@ -198,9 +212,10 @@
* does not have to be registered in the provider list.
*
* @param protocol the standard name of the requested protocol.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html#AppA">
- * Java Secure Socket Extension Reference Guide </a>
+ * See the SSLContext section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a>
* for information about standard protocol names.
*
* @param provider an instance of the provider.
--- a/jdk/src/share/classes/javax/net/ssl/package.html Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/net/ssl/package.html Mon Feb 14 16:30:10 2011 -0800
@@ -2,7 +2,7 @@
<html>
<head>
<!--
-Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -33,14 +33,17 @@
classes, you can communicate using SSL or a related security protocol
to reliably detect any errors introduced into the network byte stream
and to optionally encrypt the data and/or authenticate the communicating peers.
-<!--
+
<h2>Package Specification</h2>
-##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
<ul>
- <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
+ <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture Standard Algorithm Name
+ Documentation</b></a></li>
</ul>
+<!--
<h2>Related Documentation</h2>
For overviews, tutorials, examples, guides, and tool documentation, please see:
--- a/jdk/src/share/classes/javax/security/auth/login/Configuration.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/security/auth/login/Configuration.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, 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
@@ -184,9 +184,9 @@
* implementation. In addition, an instance of a Configuration object can be
* constructed by invoking one of the <code>getInstance</code> factory methods
* with a standard type. The default policy type is "JavaLoginConfig".
- * See Appendix A in the
- * <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the Configuration section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for a list of standard Configuration types.
*
* @see javax.security.auth.login.LoginContext
@@ -319,10 +319,11 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * @param type the specified Configuration type. See Appendix A in the
- * <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for a list of standard Configuration types.
+ * @param type the specified Configuration type. See the Configuration
+ * section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a> for a list of standard Configuration types.
*
* @param params parameters for the Configuration, which may be null.
*
@@ -374,10 +375,11 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * @param type the specified Configuration type. See Appendix A in the
- * <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for a list of standard Configuration types.
+ * @param type the specified Configuration type. See the Configuration
+ * section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a> for a list of standard Configuration types.
*
* @param params parameters for the Configuration, which may be null.
*
@@ -439,10 +441,11 @@
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
- * @param type the specified Configuration type. See Appendix A in the
- * <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for a list of standard Configuration types.
+ * @param type the specified Configuration type. See the Configuration
+ * section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a> for a list of standard Configuration types.
*
* @param params parameters for the Configuration, which may be null.
*
--- a/jdk/src/share/classes/javax/security/auth/login/package.html Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/security/auth/login/package.html Mon Feb 14 16:30:10 2011 -0800
@@ -2,7 +2,7 @@
<html>
<head>
<!--
-Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -30,14 +30,16 @@
<body bgcolor="white">
This package provides a pluggable authentication framework.
-<!--
<h2>Package Specification</h2>
-##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
<ul>
- <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
+ <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture Standard Algorithm Name
+ Documentation</b></a></li>
</ul>
+<!--
<h2>Related Documentation</h2>
For overviews, tutorials, examples, guides, and tool documentation, please see:
@@ -47,6 +49,6 @@
-->
-@since JDK1.4
+@since 1.4
</body>
</html>
--- a/jdk/src/share/classes/javax/swing/BorderFactory.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/BorderFactory.java Mon Feb 14 16:30:10 2011 -0800
@@ -159,9 +159,6 @@
* Creates a beveled border of the specified type, using
* the specified colors for the inner and outer highlight
* and shadow areas.
- * <p>
- * Note: The shadow inner and outer colors are
- * switched for a lowered bevel border.
*
* @param type an integer specifying either
* <code>BevelBorder.LOWERED</code> or
--- a/jdk/src/share/classes/javax/swing/BufferStrategyPaintManager.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/BufferStrategyPaintManager.java Mon Feb 14 16:30:10 2011 -0800
@@ -209,7 +209,7 @@
synchronized(BufferStrategyPaintManager.this) {
while (showing) {
try {
- wait();
+ BufferStrategyPaintManager.this.wait();
} catch (InterruptedException ie) {
}
}
--- a/jdk/src/share/classes/javax/swing/JComponent.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/JComponent.java Mon Feb 14 16:30:10 2011 -0800
@@ -4911,7 +4911,7 @@
* painting to originate from this Component, or one of its ancestors.
* <p/>
* Calling {@link JComponent#repaint} on a Swing component will be delegated to
- * the first ancestor which {@code isPaintingOrigin()} returns {@true},
+ * the first ancestor which {@code isPaintingOrigin()} returns {@code true},
* if there are any.
* <p/>
* {@code JComponent} subclasses that need to be repainted when any of their
--- a/jdk/src/share/classes/javax/swing/SwingWorker.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/SwingWorker.java Mon Feb 14 16:30:10 2011 -0800
@@ -404,6 +404,7 @@
* @see #process
*
*/
+ @SafeVarargs
protected final void publish(V... chunks) {
synchronized (this) {
if (doProcess == null) {
--- a/jdk/src/share/classes/javax/swing/ToolTipManager.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/ToolTipManager.java Mon Feb 14 16:30:10 2011 -0800
@@ -75,6 +75,9 @@
private MouseMotionListener moveBeforeEnterListener = null;
private KeyListener accessibilityKeyListener = null;
+ private KeyStroke postTip;
+ private KeyStroke hideTip;
+
// PENDING(ges)
protected boolean lightWeightPopupEnabled = true;
protected boolean heavyWeightPopupEnabled = false;
@@ -89,6 +92,9 @@
moveBeforeEnterListener = new MoveBeforeEnterListener();
accessibilityKeyListener = new AccessibilityKeyListener();
+
+ postTip = KeyStroke.getKeyStroke(KeyEvent.VK_F1, InputEvent.CTRL_MASK);
+ hideTip = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
}
/**
@@ -805,13 +811,13 @@
public void keyPressed(KeyEvent e) {
if (!e.isConsumed()) {
JComponent source = (JComponent) e.getComponent();
- if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
+ KeyStroke keyStrokeForEvent = KeyStroke.getKeyStrokeForEvent(e);
+ if (hideTip.equals(keyStrokeForEvent)) {
if (tipWindow != null) {
hide(source);
e.consume();
}
- } else if (e.getKeyCode() == KeyEvent.VK_F1
- && e.getModifiers() == Event.CTRL_MASK) {
+ } else if (postTip.equals(keyStrokeForEvent)) {
// Shown tooltip will be hidden
ToolTipManager.this.show(source);
e.consume();
--- a/jdk/src/share/classes/javax/swing/border/BevelBorder.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/border/BevelBorder.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -26,7 +26,6 @@
import java.awt.Graphics;
import java.awt.Insets;
-import java.awt.Rectangle;
import java.awt.Color;
import java.awt.Component;
import java.beans.ConstructorProperties;
@@ -82,9 +81,6 @@
/**
* Creates a bevel border with the specified type, highlight and
* shadow colors.
- * <p>
- * Note: The shadow inner and outer colors are
- * switched for a lowered bevel border.
*
* @param bevelType the type of bevel for the border
* @param highlightOuterColor the color to use for the bevel outer highlight
--- a/jdk/src/share/classes/javax/swing/border/StrokeBorder.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/border/StrokeBorder.java Mon Feb 14 16:30:10 2011 -0800
@@ -88,6 +88,10 @@
/**
* Paints the border for the specified component
* with the specified position and size.
+ * If the border was not specified with a {@link Paint} object,
+ * the component's foreground color will be used to render the border.
+ * If the component's foreground color is not available,
+ * the default color of the {@link Graphics} object will be used.
*
* @param c the component for which this border is being painted
* @param g the paint graphics
@@ -96,7 +100,7 @@
* @param width the width of the painted border
* @param height the height of the painted border
*
- * @throws NullPointerException if the specified {@code c} or {@code g} are {@code null}
+ * @throws NullPointerException if the specified {@code g} is {@code null}
*/
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
@@ -106,7 +110,7 @@
if (g instanceof Graphics2D) {
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(this.stroke);
- g2d.setPaint(this.paint != null ? this.paint : c.getForeground());
+ g2d.setPaint(this.paint != null ? this.paint : c == null ? null : c.getForeground());
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.draw(new Rectangle2D.Float(x + size / 2, y + size / 2, width - size, height - size));
@@ -118,13 +122,17 @@
/**
* Reinitializes the {@code insets} parameter
* with this border's current insets.
- * All insets are equal to the line width of the stroke.
+ * Every inset is the smallest (closest to negative infinity) integer value
+ * that is greater than or equal to the line width of the stroke
+ * that is used to paint the border.
*
* @param c the component for which this border insets value applies
* @param insets the {@code Insets} object to be reinitialized
* @return the reinitialized {@code insets} parameter
*
* @throws NullPointerException if the specified {@code insets} is {@code null}
+ *
+ * @see Math#ceil
*/
@Override
public Insets getBorderInsets(Component c, Insets insets) {
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java Mon Feb 14 16:30:10 2011 -0800
@@ -1721,6 +1721,7 @@
editor.setFont( comboBox.getFont() );
}
isMinimumSizeDirty = true;
+ isDisplaySizeDirty = true;
comboBox.validate();
}
else if ( propertyName == JComponent.TOOL_TIP_TEXT_KEY ) {
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java Mon Feb 14 16:30:10 2011 -0800
@@ -342,12 +342,10 @@
setOrientation(splitPane.getOrientation());
- // This plus 2 here is to provide backwards consistancy. Previously,
- // the old size did not include the 2 pixel border around the divider,
- // it now does.
- Integer dividerSize = (Integer)UIManager.get("SplitPane.dividerSize");
- if (divider == null) dividerSize = 10;
- LookAndFeel.installProperty(splitPane, "dividerSize", dividerSize);
+ // note: don't rename this temp variable to dividerSize
+ // since it will conflict with "this.dividerSize" field
+ Integer temp = (Integer)UIManager.get("SplitPane.dividerSize");
+ LookAndFeel.installProperty(splitPane, "dividerSize", temp == null? 10: temp);
divider.setDividerSize(splitPane.getDividerSize());
dividerSize = divider.getDividerSize();
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java Mon Feb 14 16:30:10 2011 -0800
@@ -92,7 +92,7 @@
* </ol>
*
* @param c the editor component
- * @see BasicTextUI#installUI
+ * @see javax.swing.plaf.basic.BasicTextUI#installUI
* @see ComponentUI#installUI
*/
@Override
--- a/jdk/src/share/classes/javax/swing/text/JTextComponent.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/text/JTextComponent.java Mon Feb 14 16:30:10 2011 -0800
@@ -4822,6 +4822,7 @@
* @return {@code true} if the composed text exists and is saved,
* {@code false} otherwise
* @see #restoreComposedText
+ * @since 1.7
*/
protected boolean saveComposedText(int pos) {
if (composedTextExists()) {
@@ -4845,6 +4846,7 @@
* should be invoked only if {@code saveComposedText} returns {@code true}.
*
* @see #saveComposedText
+ * @since 1.7
*/
protected void restoreComposedText() {
Document doc = getDocument();
--- a/jdk/src/share/classes/javax/swing/text/Keymap.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/text/Keymap.java Mon Feb 14 16:30:10 2011 -0800
@@ -137,6 +137,8 @@
/**
* Sets the parent keymap, which will be used to
* resolve key-bindings.
+ * The behavior is unspecified if a {@code Keymap} has itself
+ * as one of its resolve parents.
*
* @param parent the parent keymap
*/
--- a/jdk/src/share/classes/sun/java2d/SunGraphicsEnvironment.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/java2d/SunGraphicsEnvironment.java Mon Feb 14 16:30:10 2011 -0800
@@ -95,6 +95,22 @@
String line = br.readLine();
if (line.indexOf("OpenSolaris") >= 0) {
isOpenSolaris = true;
+ } else {
+ /* We are using isOpenSolaris as meaning
+ * we know the Solaris commercial fonts aren't
+ * present. "Solaris Next" (03/10) did not
+ * include these even though its was not
+ * OpenSolaris. Need to revisit how this is
+ * handled but for now as in 6ux, we'll use
+ * the test for a standard font resource as
+ * being an indicator as to whether we need
+ * to treat this as OpenSolaris from a font
+ * config perspective.
+ */
+ String courierNew =
+ "/usr/openwin/lib/X11/fonts/TrueType/CourierNew.ttf";
+ File courierFile = new File(courierNew);
+ isOpenSolaris = !courierFile.exists();
}
fis.close();
}
--- a/jdk/src/share/classes/sun/java2d/pisces/Curve.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/java2d/pisces/Curve.java Mon Feb 14 16:30:10 2011 -0800
@@ -27,7 +27,7 @@
import java.util.Iterator;
-class Curve {
+final class Curve {
float ax, ay, bx, by, cx, cy, dx, dy;
float dax, day, dbx, dby;
@@ -101,14 +101,6 @@
return t * (t * day + dby) + cy;
}
- private float ddxat(float t) {
- return 2 * dax * t + dbx;
- }
-
- private float ddyat(float t) {
- return 2 * day * t + dby;
- }
-
int dxRoots(float[] roots, int off) {
return Helpers.quadraticRoots(dax, dbx, cx, roots, off);
}
@@ -131,17 +123,17 @@
// finds points where the first and second derivative are
// perpendicular. This happens when g(t) = f'(t)*f''(t) == 0 (where
// * is a dot product). Unfortunately, we have to solve a cubic.
- private int perpendiculardfddf(float[] pts, int off, final float err) {
+ private int perpendiculardfddf(float[] pts, int off) {
assert pts.length >= off + 4;
- // these are the coefficients of g(t):
+ // these are the coefficients of some multiple of g(t) (not g(t),
+ // because the roots of a polynomial are not changed after multiplication
+ // by a constant, and this way we save a few multiplications).
final float a = 2*(dax*dax + day*day);
final float b = 3*(dax*dbx + day*dby);
final float c = 2*(dax*cx + day*cy) + dbx*dbx + dby*dby;
final float d = dbx*cx + dby*cy;
- // TODO: We might want to divide the polynomial by a to make the
- // coefficients smaller. This won't change the roots.
- return Helpers.cubicRootsInAB(a, b, c, d, pts, off, err, 0f, 1f);
+ return Helpers.cubicRootsInAB(a, b, c, d, pts, off, 0f, 1f);
}
// Tries to find the roots of the function ROC(t)-w in [0, 1). It uses
@@ -161,7 +153,7 @@
// no OOB exception, because by now off<=6, and roots.length >= 10
assert off <= 6 && roots.length >= 10;
int ret = off;
- int numPerpdfddf = perpendiculardfddf(roots, off, err);
+ int numPerpdfddf = perpendiculardfddf(roots, off);
float t0 = 0, ft0 = ROCsq(t0) - w*w;
roots[off + numPerpdfddf] = 1f; // always check interval end points
numPerpdfddf++;
@@ -189,8 +181,9 @@
// A slight modification of the false position algorithm on wikipedia.
// This only works for the ROCsq-x functions. It might be nice to have
// the function as an argument, but that would be awkward in java6.
- // It is something to consider for java7, depending on how closures
- // and function objects turn out. Same goes for the newton's method
+ // TODO: It is something to consider for java8 (or whenever lambda
+ // expressions make it into the language), depending on how closures
+ // and turn out. Same goes for the newton's method
// algorithm in Helpers.java
private float falsePositionROCsqMinusX(float x0, float x1,
final float x, final float err)
@@ -203,7 +196,7 @@
for (int i = 0; i < iterLimit && Math.abs(t - s) > err * Math.abs(t + s); i++) {
r = (fs * t - ft * s) / (fs - ft);
fr = ROCsq(r) - x;
- if (fr * ft > 0) {// have the same sign
+ if (sameSign(fr, ft)) {
ft = fr; t = r;
if (side < 0) {
fs /= (1 << (-side));
@@ -226,55 +219,65 @@
return r;
}
+ private static boolean sameSign(double x, double y) {
+ // another way is to test if x*y > 0. This is bad for small x, y.
+ return (x < 0 && y < 0) || (x > 0 && y > 0);
+ }
+
// returns the radius of curvature squared at t of this curve
// see http://en.wikipedia.org/wiki/Radius_of_curvature_(applications)
private float ROCsq(final float t) {
- final float dx = dxat(t);
- final float dy = dyat(t);
- final float ddx = ddxat(t);
- final float ddy = ddyat(t);
+ // dx=xat(t) and dy=yat(t). These calls have been inlined for efficiency
+ final float dx = t * (t * dax + dbx) + cx;
+ final float dy = t * (t * day + dby) + cy;
+ final float ddx = 2 * dax * t + dbx;
+ final float ddy = 2 * day * t + dby;
final float dx2dy2 = dx*dx + dy*dy;
final float ddx2ddy2 = ddx*ddx + ddy*ddy;
final float ddxdxddydy = ddx*dx + ddy*dy;
- float ret = ((dx2dy2*dx2dy2) / (dx2dy2 * ddx2ddy2 - ddxdxddydy*ddxdxddydy))*dx2dy2;
- return ret;
+ return dx2dy2*((dx2dy2*dx2dy2) / (dx2dy2 * ddx2ddy2 - ddxdxddydy*ddxdxddydy));
}
- // curve to be broken should be in pts[0]
- // this will change the contents of both pts and Ts
+ // curve to be broken should be in pts
+ // this will change the contents of pts but not Ts
// TODO: There's no reason for Ts to be an array. All we need is a sequence
// of t values at which to subdivide. An array statisfies this condition,
// but is unnecessarily restrictive. Ts should be an Iterator<Float> instead.
// Doing this will also make dashing easier, since we could easily make
// LengthIterator an Iterator<Float> and feed it to this function to simplify
// the loop in Dasher.somethingTo.
- static Iterator<float[]> breakPtsAtTs(final float[][] pts, final int type,
+ static Iterator<Integer> breakPtsAtTs(final float[] pts, final int type,
final float[] Ts, final int numTs)
{
- assert pts.length >= 2 && pts[0].length >= 8 && numTs <= Ts.length;
- return new Iterator<float[]>() {
- int nextIdx = 0;
+ assert pts.length >= 2*type && numTs <= Ts.length;
+ return new Iterator<Integer>() {
+ // these prevent object creation and destruction during autoboxing.
+ // Because of this, the compiler should be able to completely
+ // eliminate the boxing costs.
+ final Integer i0 = 0;
+ final Integer itype = type;
int nextCurveIdx = 0;
+ Integer curCurveOff = i0;
float prevT = 0;
@Override public boolean hasNext() {
return nextCurveIdx < numTs + 1;
}
- @Override public float[] next() {
- float[] ret;
+ @Override public Integer next() {
+ Integer ret;
if (nextCurveIdx < numTs) {
float curT = Ts[nextCurveIdx];
float splitT = (curT - prevT) / (1 - prevT);
Helpers.subdivideAt(splitT,
- pts[nextIdx], 0,
- pts[nextIdx], 0,
- pts[1-nextIdx], 0, type);
- updateTs(Ts, Ts[nextCurveIdx], nextCurveIdx + 1, numTs - nextCurveIdx - 1);
- ret = pts[nextIdx];
- nextIdx = 1 - nextIdx;
+ pts, curCurveOff,
+ pts, 0,
+ pts, type, type);
+ prevT = curT;
+ ret = i0;
+ curCurveOff = itype;
} else {
- ret = pts[nextIdx];
+ ret = curCurveOff;
}
nextCurveIdx++;
return ret;
@@ -283,12 +286,5 @@
@Override public void remove() {}
};
}
-
- // precondition: ts[off]...ts[off+len-1] must all be greater than t.
- private static void updateTs(float[] ts, final float t, final int off, final int len) {
- for (int i = off; i < off + len; i++) {
- ts[i] = (ts[i] - t) / (1 - t);
- }
- }
}
--- a/jdk/src/share/classes/sun/java2d/pisces/Dasher.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/java2d/pisces/Dasher.java Mon Feb 14 16:30:10 2011 -0800
@@ -38,7 +38,7 @@
* semantics are unclear.
*
*/
-public class Dasher implements sun.awt.geom.PathConsumer2D {
+final class Dasher implements sun.awt.geom.PathConsumer2D {
private final PathConsumer2D out;
private final float[] dash;
@@ -169,7 +169,7 @@
float dx = x1 - x0;
float dy = y1 - y0;
- float len = (float) Math.hypot(dx, dy);
+ float len = (float) Math.sqrt(dx*dx + dy*dy);
if (len == 0) {
return;
@@ -226,7 +226,7 @@
return;
}
if (li == null) {
- li = new LengthIterator(4, 0.0001f);
+ li = new LengthIterator(4, 0.01f);
}
li.initializeIterationOnCurve(curCurvepts, type);
@@ -237,9 +237,9 @@
while ((t = li.next(leftInThisDashSegment)) < 1) {
if (t != 0) {
Helpers.subdivideAt((t - lastSplitT) / (1 - lastSplitT),
- curCurvepts, curCurveoff,
- curCurvepts, 0,
- curCurvepts, type, type);
+ curCurvepts, curCurveoff,
+ curCurvepts, 0,
+ curCurvepts, type, type);
lastSplitT = t;
goTo(curCurvepts, 2, type);
curCurveoff = type;
@@ -307,6 +307,11 @@
private int recLevel;
private boolean done;
+ // the lengths of the lines of the control polygon. Only its first
+ // curveType/2 - 1 elements are valid. This is an optimization. See
+ // next(float) for more detail.
+ private float[] curLeafCtrlPolyLengths = new float[3];
+
public LengthIterator(int reclimit, float err) {
this.limit = reclimit;
this.minTincrement = 1f / (1 << limit);
@@ -344,11 +349,52 @@
this.lastSegLen = 0;
}
+ // 0 == false, 1 == true, -1 == invalid cached value.
+ private int cachedHaveLowAcceleration = -1;
+
+ private boolean haveLowAcceleration(float err) {
+ if (cachedHaveLowAcceleration == -1) {
+ final float len1 = curLeafCtrlPolyLengths[0];
+ final float len2 = curLeafCtrlPolyLengths[1];
+ // the test below is equivalent to !within(len1/len2, 1, err).
+ // It is using a multiplication instead of a division, so it
+ // should be a bit faster.
+ if (!Helpers.within(len1, len2, err*len2)) {
+ cachedHaveLowAcceleration = 0;
+ return false;
+ }
+ if (curveType == 8) {
+ final float len3 = curLeafCtrlPolyLengths[2];
+ // if len1 is close to 2 and 2 is close to 3, that probably
+ // means 1 is close to 3 so the second part of this test might
+ // not be needed, but it doesn't hurt to include it.
+ if (!(Helpers.within(len2, len3, err*len3) &&
+ Helpers.within(len1, len3, err*len3))) {
+ cachedHaveLowAcceleration = 0;
+ return false;
+ }
+ }
+ cachedHaveLowAcceleration = 1;
+ return true;
+ }
+
+ return (cachedHaveLowAcceleration == 1);
+ }
+
+ // we want to avoid allocations/gc so we keep this array so we
+ // can put roots in it,
+ private float[] nextRoots = new float[4];
+
+ // caches the coefficients of the current leaf in its flattened
+ // form (see inside next() for what that means). The cache is
+ // invalid when it's third element is negative, since in any
+ // valid flattened curve, this would be >= 0.
+ private float[] flatLeafCoefCache = new float[] {0, 0, -1, 0};
// returns the t value where the remaining curve should be split in
// order for the left subdivided curve to have length len. If len
// is >= than the length of the uniterated curve, it returns 1.
- public float next(float len) {
- float targetLength = lenAtLastSplit + len;
+ public float next(final float len) {
+ final float targetLength = lenAtLastSplit + len;
while(lenAtNextT < targetLength) {
if (done) {
lastSegLen = lenAtNextT - lenAtLastSplit;
@@ -357,8 +403,46 @@
goToNextLeaf();
}
lenAtLastSplit = targetLength;
- float t = binSearchForLen(lenAtLastSplit - lenAtLastT,
- recCurveStack[recLevel], curveType, lenAtNextT - lenAtLastT, ERR);
+ final float leaflen = lenAtNextT - lenAtLastT;
+ float t = (targetLength - lenAtLastT) / leaflen;
+
+ // cubicRootsInAB is a fairly expensive call, so we just don't do it
+ // if the acceleration in this section of the curve is small enough.
+ if (!haveLowAcceleration(0.05f)) {
+ // We flatten the current leaf along the x axis, so that we're
+ // left with a, b, c which define a 1D Bezier curve. We then
+ // solve this to get the parameter of the original leaf that
+ // gives us the desired length.
+
+ if (flatLeafCoefCache[2] < 0) {
+ float x = 0+curLeafCtrlPolyLengths[0],
+ y = x+curLeafCtrlPolyLengths[1];
+ if (curveType == 8) {
+ float z = y + curLeafCtrlPolyLengths[2];
+ flatLeafCoefCache[0] = 3*(x - y) + z;
+ flatLeafCoefCache[1] = 3*(y - 2*x);
+ flatLeafCoefCache[2] = 3*x;
+ flatLeafCoefCache[3] = -z;
+ } else if (curveType == 6) {
+ flatLeafCoefCache[0] = 0f;
+ flatLeafCoefCache[1] = y - 2*x;
+ flatLeafCoefCache[2] = 2*x;
+ flatLeafCoefCache[3] = -y;
+ }
+ }
+ float a = flatLeafCoefCache[0];
+ float b = flatLeafCoefCache[1];
+ float c = flatLeafCoefCache[2];
+ float d = t*flatLeafCoefCache[3];
+
+ // we use cubicRootsInAB here, because we want only roots in 0, 1,
+ // and our quadratic root finder doesn't filter, so it's just a
+ // matter of convenience.
+ int n = Helpers.cubicRootsInAB(a, b, c, d, nextRoots, 0, 0, 1);
+ if (n == 1 && !Float.isNaN(nextRoots[0])) {
+ t = nextRoots[0];
+ }
+ }
// t is relative to the current leaf, so we must make it a valid parameter
// of the original curve.
t = t * (nextT - lastT) + lastT;
@@ -379,36 +463,6 @@
return lastSegLen;
}
- // Returns t such that if leaf is subdivided at t the left
- // curve will have length len. leafLen must be the length of leaf.
- private static Curve bsc = new Curve();
- private static float binSearchForLen(float len, float[] leaf, int type,
- float leafLen, float err)
- {
- assert len <= leafLen;
- bsc.set(leaf, type);
- float errBound = err*len;
- float left = 0, right = 1;
- while (left < right) {
- float m = (left + right) / 2;
- if (m == left || m == right) {
- return m;
- }
- float x = bsc.xat(m);
- float y = bsc.yat(m);
- float leftLen = Helpers.linelen(leaf[0], leaf[1], x, y);
- if (Math.abs(leftLen - len) < errBound) {
- return m;
- }
- if (leftLen < len) {
- left = m;
- } else {
- right = m;
- }
- }
- return left;
- }
-
// go to the next leaf (in an inorder traversal) in the recursion tree
// preconditions: must be on a leaf, and that leaf must not be the root.
private void goToNextLeaf() {
@@ -437,6 +491,9 @@
lenAtLastT = lenAtNextT;
nextT += (1 << (limit - recLevel)) * minTincrement;
lenAtNextT += len;
+ // invalidate caches
+ flatLeafCoefCache[2] = -1;
+ cachedHaveLowAcceleration = -1;
} else {
Helpers.subdivide(recCurveStack[recLevel], 0,
recCurveStack[recLevel+1], 0,
@@ -450,11 +507,24 @@
// this is a bit of a hack. It returns -1 if we're not on a leaf, and
// the length of the leaf if we are on a leaf.
private float onLeaf() {
- float polylen = Helpers.polyLineLength(recCurveStack[recLevel], 0, curveType);
- float linelen = Helpers.linelen(recCurveStack[recLevel][0], recCurveStack[recLevel][1],
- recCurveStack[recLevel][curveType - 2], recCurveStack[recLevel][curveType - 1]);
- return (polylen - linelen < ERR || recLevel == limit) ?
- (polylen + linelen)/2 : -1;
+ float[] curve = recCurveStack[recLevel];
+ float polyLen = 0;
+
+ float x0 = curve[0], y0 = curve[1];
+ for (int i = 2; i < curveType; i += 2) {
+ final float x1 = curve[i], y1 = curve[i+1];
+ final float len = Helpers.linelen(x0, y0, x1, y1);
+ polyLen += len;
+ curLeafCtrlPolyLengths[i/2 - 1] = len;
+ x0 = x1;
+ y0 = y1;
+ }
+
+ final float lineLen = Helpers.linelen(curve[0], curve[1], curve[curveType-2], curve[curveType-1]);
+ if (polyLen - lineLen < ERR || recLevel == limit) {
+ return (polyLen + lineLen)/2;
+ }
+ return -1;
}
}
--- a/jdk/src/share/classes/sun/java2d/pisces/Helpers.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/java2d/pisces/Helpers.java Mon Feb 14 16:30:10 2011 -0800
@@ -26,6 +26,12 @@
package sun.java2d.pisces;
import java.util.Arrays;
+import static java.lang.Math.PI;
+import static java.lang.Math.cos;
+import static java.lang.Math.sqrt;
+import static java.lang.Math.cbrt;
+import static java.lang.Math.acos;
+
final class Helpers {
private Helpers() {
@@ -75,100 +81,74 @@
return ret - off;
}
- // find the roots of g(t) = a*t^3 + b*t^2 + c*t + d in [A,B)
- // We will not use Cardano's method, since it is complicated and
- // involves too many square and cubic roots. We will use Newton's method.
- // TODO: this should probably return ALL roots. Then the user can do
- // his own filtering of roots outside [A,B).
- static int cubicRootsInAB(final float a, final float b,
- final float c, final float d,
- float[] pts, final int off, final float E,
+ // find the roots of g(t) = d*t^3 + a*t^2 + b*t + c in [A,B)
+ static int cubicRootsInAB(float d, float a, float b, float c,
+ float[] pts, final int off,
final float A, final float B)
{
- if (a == 0) {
- return quadraticRoots(b, c, d, pts, off);
+ if (d == 0) {
+ int num = quadraticRoots(a, b, c, pts, off);
+ return filterOutNotInAB(pts, off, num, A, B) - off;
}
- // the coefficients of g'(t). no dc variable because dc=c
- // we use these to get the critical points of g(t), which
- // we then use to chose starting points for Newton's method. These
- // should be very close to the actual roots.
- final float da = 3 * a;
- final float db = 2 * b;
- int numCritPts = quadraticRoots(da, db, c, pts, off+1);
- numCritPts = filterOutNotInAB(pts, off+1, numCritPts, A, B) - off - 1;
- // need them sorted.
- if (numCritPts == 2 && pts[off+1] > pts[off+2]) {
- float tmp = pts[off+1];
- pts[off+1] = pts[off+2];
- pts[off+2] = tmp;
+ // From Graphics Gems:
+ // http://tog.acm.org/resources/GraphicsGems/gems/Roots3And4.c
+ // (also from awt.geom.CubicCurve2D. But here we don't need as
+ // much accuracy and we don't want to create arrays so we use
+ // our own customized version).
+
+ /* normal form: x^3 + ax^2 + bx + c = 0 */
+ a /= d;
+ b /= d;
+ c /= d;
+
+ // substitute x = y - A/3 to eliminate quadratic term:
+ // x^3 +Px + Q = 0
+ //
+ // Since we actually need P/3 and Q/2 for all of the
+ // calculations that follow, we will calculate
+ // p = P/3
+ // q = Q/2
+ // instead and use those values for simplicity of the code.
+ double sq_A = a * a;
+ double p = 1.0/3 * (-1.0/3 * sq_A + b);
+ double q = 1.0/2 * (2.0/27 * a * sq_A - 1.0/3 * a * b + c);
+
+ /* use Cardano's formula */
+
+ double cb_p = p * p * p;
+ double D = q * q + cb_p;
+
+ int num;
+ if (D < 0) {
+ // see: http://en.wikipedia.org/wiki/Cubic_function#Trigonometric_.28and_hyperbolic.29_method
+ final double phi = 1.0/3 * acos(-q / sqrt(-cb_p));
+ final double t = 2 * sqrt(-p);
+
+ pts[ off+0 ] = (float)( t * cos(phi));
+ pts[ off+1 ] = (float)(-t * cos(phi + PI / 3));
+ pts[ off+2 ] = (float)(-t * cos(phi - PI / 3));
+ num = 3;
+ } else {
+ final double sqrt_D = sqrt(D);
+ final double u = cbrt(sqrt_D - q);
+ final double v = - cbrt(sqrt_D + q);
+
+ pts[ off ] = (float)(u + v);
+ num = 1;
+
+ if (within(D, 0, 1e-8)) {
+ pts[off+1] = -(pts[off] / 2);
+ num = 2;
+ }
}
- int ret = off;
-
- // we don't actually care much about the extrema themselves. We
- // only use them to ensure that g(t) is monotonic in each
- // interval [pts[i],pts[i+1] (for i in off...off+numCritPts+1).
- // This will allow us to determine intervals containing exactly
- // one root.
- // The end points of the interval are always local extrema.
- pts[off] = A;
- pts[off + numCritPts + 1] = B;
- numCritPts += 2;
-
- float x0 = pts[off], fx0 = evalCubic(a, b, c, d, x0);
- for (int i = off; i < off + numCritPts - 1; i++) {
- float x1 = pts[i+1], fx1 = evalCubic(a, b, c, d, x1);
- if (fx0 == 0f) {
- pts[ret++] = x0;
- } else if (fx1 * fx0 < 0f) { // have opposite signs
- pts[ret++] = CubicNewton(a, b, c, d,
- x0 + fx0 * (x1 - x0) / (fx0 - fx1), E);
- }
- x0 = x1;
- fx0 = fx1;
- }
- return ret - off;
- }
+ final float sub = 1.0f/3 * a;
- // precondition: the polynomial to be evaluated must not be 0 at x0.
- static float CubicNewton(final float a, final float b,
- final float c, final float d,
- float x0, final float err)
- {
- // considering how this function is used, 10 should be more than enough
- final int itlimit = 10;
- float fx0 = evalCubic(a, b, c, d, x0);
- float x1;
- int count = 0;
- while(true) {
- x1 = x0 - (fx0 / evalCubic(0, 3 * a, 2 * b, c, x0));
- if (Math.abs(x1 - x0) < err * Math.abs(x1 + x0) || count == itlimit) {
- break;
- }
- x0 = x1;
- fx0 = evalCubic(a, b, c, d, x0);
- count++;
+ for (int i = 0; i < num; ++i) {
+ pts[ off+i ] -= sub;
}
- return x1;
- }
- // fills the input array with numbers 0, INC, 2*INC, ...
- static void fillWithIdxes(final float[] data, final int[] idxes) {
- if (idxes.length > 0) {
- idxes[0] = 0;
- for (int i = 1; i < idxes.length; i++) {
- idxes[i] = idxes[i-1] + (int)data[idxes[i-1]];
- }
- }
- }
-
- static void fillWithIdxes(final int[] idxes, final int inc) {
- if (idxes.length > 0) {
- idxes[0] = 0;
- for (int i = 1; i < idxes.length; i++) {
- idxes[i] = idxes[i-1] + inc;
- }
- }
+ return filterOutNotInAB(pts, off, num, A, B) - off;
}
// These use a hardcoded factor of 2 for increasing sizes. Perhaps this
@@ -182,6 +162,7 @@
}
return Arrays.copyOf(in, 2 * (cursize + numToAdd));
}
+
static int[] widenArray(int[] in, final int cursize, final int numToAdd) {
if (in.length >= cursize + numToAdd) {
return in;
@@ -208,7 +189,7 @@
{
int ret = off;
for (int i = off; i < off + len; i++) {
- if (nums[i] > a && nums[i] < b) {
+ if (nums[i] >= a && nums[i] < b) {
nums[ret++] = nums[i];
}
}
@@ -225,7 +206,9 @@
}
static float linelen(float x1, float y1, float x2, float y2) {
- return (float)Math.hypot(x2 - x1, y2 - y1);
+ final float dx = x2 - x1;
+ final float dy = y2 - y1;
+ return (float)Math.sqrt(dx*dx + dy*dy);
}
static void subdivide(float[] src, int srcoff, float[] left, int leftoff,
--- a/jdk/src/share/classes/sun/java2d/pisces/PiscesCache.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/java2d/pisces/PiscesCache.java Mon Feb 14 16:30:10 2011 -0800
@@ -32,7 +32,7 @@
*
* @see PiscesRenderer#render
*/
-public final class PiscesCache {
+final class PiscesCache {
final int bboxX0, bboxY0, bboxX1, bboxY1;
--- a/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Mon Feb 14 16:30:10 2011 -0800
@@ -27,7 +27,6 @@
import java.awt.Shape;
import java.awt.BasicStroke;
-import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Path2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
@@ -250,7 +249,7 @@
float dashphase,
PathConsumer2D pc2d)
{
- // We use inat and outat so that in Stroker and Dasher we can work only
+ // We use strokerat and outat so that in Stroker and Dasher we can work only
// with the pre-transformation coordinates. This will repeat a lot of
// computations done in the path iterator, but the alternative is to
// work with transformed paths and compute untransformed coordinates
@@ -265,7 +264,7 @@
// transformation after the path processing has been done.
// We can't do this if normalization is on, because it isn't a good
// idea to normalize before the transformation is applied.
- AffineTransform inat = null;
+ AffineTransform strokerat = null;
AffineTransform outat = null;
PathIterator pi = null;
@@ -284,9 +283,9 @@
// again so, nothing can be drawn.
// Every path needs an initial moveTo and a pathDone. If these
- // aren't there this causes a SIGSEV in libawt.so (at the time
+ // are not there this causes a SIGSEGV in libawt.so (at the time
// of writing of this comment (September 16, 2010)). Actually,
- // I'm not sure if the moveTo is necessary to avoid the SIGSEV
+ // I am not sure if the moveTo is necessary to avoid the SIGSEGV
// but the pathDone is definitely needed.
pc2d.moveTo(0, 0);
pc2d.pathDone();
@@ -313,25 +312,32 @@
if (normalize != NormMode.OFF) {
pi = new NormalizingPathIterator(pi, normalize);
}
- // leave inat and outat null.
+ // by now strokerat == null && outat == null. Input paths to
+ // stroker (and maybe dasher) will have the full transform at
+ // applied to them and nothing will happen to the output paths.
} else {
- // We only need the inverse if normalization is on. Otherwise
- // we just don't transform the input paths, do all the stroking
- // and then transform out output (instead of making PathIterator
- // apply the transformation, us applying the inverse, and then
- // us applying the transform again to our output).
- outat = at;
if (normalize != NormMode.OFF) {
- try {
- inat = outat.createInverse();
- } catch (NoninvertibleTransformException e) {
- // we made sure this can't happen
- e.printStackTrace();
- }
+ strokerat = at;
pi = src.getPathIterator(at);
pi = new NormalizingPathIterator(pi, normalize);
+ // by now strokerat == at && outat == null. Input paths to
+ // stroker (and maybe dasher) will have the full transform at
+ // applied to them, then they will be normalized, and then
+ // the inverse of *only the non translation part of at* will
+ // be applied to the normalized paths. This won't cause problems
+ // in stroker, because, suppose at = T*A, where T is just the
+ // translation part of at, and A is the rest. T*A has already
+ // been applied to Stroker/Dasher's input. Then Ainv will be
+ // applied. Ainv*T*A is not equal to T, but it is a translation,
+ // which means that none of stroker's assumptions about its
+ // input will be violated. After all this, A will be applied
+ // to stroker's output.
} else {
+ outat = at;
pi = src.getPathIterator(null);
+ // outat == at && strokerat == null. This is because if no
+ // normalization is done, we can just apply all our
+ // transformations to stroker's output.
}
}
} else {
@@ -343,13 +349,17 @@
}
}
+ // by now, at least one of outat and strokerat will be null. Unless at is not
+ // a constant multiple of an orthogonal transformation, they will both be
+ // null. In other cases, outat == at if normalization is off, and if
+ // normalization is on, strokerat == at.
pc2d = TransformingPathConsumer2D.transformConsumer(pc2d, outat);
+ pc2d = TransformingPathConsumer2D.deltaTransformConsumer(pc2d, strokerat);
pc2d = new Stroker(pc2d, width, caps, join, miterlimit);
if (dashes != null) {
pc2d = new Dasher(pc2d, dashes, dashphase);
}
- pc2d = TransformingPathConsumer2D.transformConsumer(pc2d, inat);
-
+ pc2d = TransformingPathConsumer2D.inverseDeltaTransformConsumer(pc2d, strokerat);
pathTo(pi, pc2d);
}
@@ -588,9 +598,9 @@
}
Renderer r = new Renderer(3, 3,
- clip.getLoX(), clip.getLoY(),
- clip.getWidth(), clip.getHeight(),
- PathIterator.WIND_EVEN_ODD);
+ clip.getLoX(), clip.getLoY(),
+ clip.getWidth(), clip.getHeight(),
+ PathIterator.WIND_EVEN_ODD);
r.moveTo((float) x, (float) y);
r.lineTo((float) (x+dx1), (float) (y+dy1));
--- a/jdk/src/share/classes/sun/java2d/pisces/PiscesTileGenerator.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/java2d/pisces/PiscesTileGenerator.java Mon Feb 14 16:30:10 2011 -0800
@@ -30,7 +30,7 @@
import sun.java2d.pipe.AATileGenerator;
-public final class PiscesTileGenerator implements AATileGenerator {
+final class PiscesTileGenerator implements AATileGenerator {
public static final int TILE_SIZE = PiscesCache.TILE_SIZE;
// perhaps we should be using weak references here, but right now
--- a/jdk/src/share/classes/sun/java2d/pisces/Renderer.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/java2d/pisces/Renderer.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,12 +25,9 @@
package sun.java2d.pisces;
-import java.util.Arrays;
-import java.util.Iterator;
-
import sun.awt.geom.PathConsumer2D;
-public class Renderer implements PathConsumer2D {
+final class Renderer implements PathConsumer2D {
private class ScanlineIterator {
@@ -39,115 +36,81 @@
// crossing bounds. The bounds are not necessarily tight (the scan line
// at minY, for example, might have no crossings). The x bounds will
// be accumulated as crossings are computed.
- private int minY, maxY;
+ private final int maxY;
private int nextY;
// indices into the segment pointer lists. They indicate the "active"
// sublist in the segment lists (the portion of the list that contains
// all the segments that cross the next scan line).
- private int elo, ehi;
- private final int[] edgePtrs;
- private int qlo, qhi;
- private final int[] quadPtrs;
- private int clo, chi;
- private final int[] curvePtrs;
+ private int edgeCount;
+ private int[] edgePtrs;
private static final int INIT_CROSSINGS_SIZE = 10;
private ScanlineIterator() {
crossings = new int[INIT_CROSSINGS_SIZE];
-
- edgePtrs = new int[numEdges];
- Helpers.fillWithIdxes(edgePtrs, SIZEOF_EDGE);
- qsort(edges, edgePtrs, YMIN, 0, numEdges - 1);
-
- quadPtrs = new int[numQuads];
- Helpers.fillWithIdxes(quadPtrs, SIZEOF_QUAD);
- qsort(quads, quadPtrs, YMIN, 0, numQuads - 1);
-
- curvePtrs = new int[numCurves];
- Helpers.fillWithIdxes(curvePtrs, SIZEOF_CURVE);
- qsort(curves, curvePtrs, YMIN, 0, numCurves - 1);
+ edgePtrs = new int[INIT_CROSSINGS_SIZE];
// We don't care if we clip some of the line off with ceil, since
// no scan line crossings will be eliminated (in fact, the ceil is
// the y of the first scan line crossing).
- nextY = minY = Math.max(boundsMinY, (int)Math.ceil(edgeMinY));
- maxY = Math.min(boundsMaxY, (int)Math.ceil(edgeMaxY));
-
- for (elo = 0; elo < numEdges && edges[edgePtrs[elo]+YMAX] <= minY; elo++)
- ;
- // the active list is *edgePtrs[lo] (inclusive) *edgePtrs[hi] (exclusive)
- for (ehi = elo; ehi < numEdges && edges[edgePtrs[ehi]+YMIN] <= minY; ehi++)
- edgeSetCurY(edgePtrs[ehi], minY);// TODO: make minY a float to avoid casts
-
- for (qlo = 0; qlo < numQuads && quads[quadPtrs[qlo]+YMAX] <= minY; qlo++)
- ;
- for (qhi = qlo; qhi < numQuads && quads[quadPtrs[qhi]+YMIN] <= minY; qhi++)
- quadSetCurY(quadPtrs[qhi], minY);
-
- for (clo = 0; clo < numCurves && curves[curvePtrs[clo]+YMAX] <= minY; clo++)
- ;
- for (chi = clo; chi < numCurves && curves[curvePtrs[chi]+YMIN] <= minY; chi++)
- curveSetCurY(curvePtrs[chi], minY);
+ final int minY = getFirstScanLineCrossing();
+ nextY = minY;
+ maxY = getScanLineCrossingEnd()-1;
+ edgeCount = 0;
}
private int next() {
- // we go through the active lists and remove segments that don't cross
- // the nextY scanline.
- int crossingIdx = 0;
- for (int i = elo; i < ehi; i++) {
- if (edges[edgePtrs[i]+YMAX] <= nextY) {
- edgePtrs[i] = edgePtrs[elo++];
+ int cury = nextY++;
+ int bucket = cury - boundsMinY;
+ int count = this.edgeCount;
+ int ptrs[] = this.edgePtrs;
+ int bucketcount = edgeBucketCounts[bucket];
+ if ((bucketcount & 0x1) != 0) {
+ int newCount = 0;
+ for (int i = 0; i < count; i++) {
+ int ecur = ptrs[i];
+ if (edges[ecur+YMAX] > cury) {
+ ptrs[newCount++] = ecur;
+ }
}
+ count = newCount;
}
- for (int i = qlo; i < qhi; i++) {
- if (quads[quadPtrs[i]+YMAX] <= nextY) {
- quadPtrs[i] = quadPtrs[qlo++];
- }
- }
- for (int i = clo; i < chi; i++) {
- if (curves[curvePtrs[i]+YMAX] <= nextY) {
- curvePtrs[i] = curvePtrs[clo++];
- }
+ ptrs = Helpers.widenArray(ptrs, count, bucketcount >> 1);
+ for (int ecur = edgeBuckets[bucket]; ecur != NULL; ecur = (int)edges[ecur+NEXT]) {
+ ptrs[count++] = ecur;
+ // REMIND: Adjust start Y if necessary
}
-
- crossings = Helpers.widenArray(crossings, 0, ehi-elo+qhi-qlo+chi-clo);
-
- // Now every edge between lo and hi crosses nextY. Compute it's
- // crossing and put it in the crossings array.
- for (int i = elo; i < ehi; i++) {
- int ptr = edgePtrs[i];
- addCrossing(nextY, (int)edges[ptr+CURX], edges[ptr+OR], crossingIdx);
- edgeGoToNextY(ptr);
- crossingIdx++;
- }
- for (int i = qlo; i < qhi; i++) {
- int ptr = quadPtrs[i];
- addCrossing(nextY, (int)quads[ptr+CURX], quads[ptr+OR], crossingIdx);
- quadGoToNextY(ptr);
- crossingIdx++;
+ this.edgePtrs = ptrs;
+ this.edgeCount = count;
+// if ((count & 0x1) != 0) {
+// System.out.println("ODD NUMBER OF EDGES!!!!");
+// }
+ int xings[] = this.crossings;
+ if (xings.length < count) {
+ this.crossings = xings = new int[ptrs.length];
}
- for (int i = clo; i < chi; i++) {
- int ptr = curvePtrs[i];
- addCrossing(nextY, (int)curves[ptr+CURX], curves[ptr+OR], crossingIdx);
- curveGoToNextY(ptr);
- crossingIdx++;
+ for (int i = 0; i < count; i++) {
+ int ecur = ptrs[i];
+ float curx = edges[ecur+CURX];
+ int cross = ((int) curx) << 1;
+ edges[ecur+CURX] = curx + edges[ecur+SLOPE];
+ if (edges[ecur+OR] > 0) {
+ cross |= 1;
+ }
+ int j = i;
+ while (--j >= 0) {
+ int jcross = xings[j];
+ if (jcross <= cross) {
+ break;
+ }
+ xings[j+1] = jcross;
+ ptrs[j+1] = ptrs[j];
+ }
+ xings[j+1] = cross;
+ ptrs[j+1] = ecur;
}
-
- nextY++;
- // Expand active lists to include new edges.
- for (; ehi < numEdges && edges[edgePtrs[ehi]+YMIN] <= nextY; ehi++) {
- edgeSetCurY(edgePtrs[ehi], nextY);
- }
- for (; qhi < numQuads && quads[quadPtrs[qhi]+YMIN] <= nextY; qhi++) {
- quadSetCurY(quadPtrs[qhi], nextY);
- }
- for (; chi < numCurves && curves[curvePtrs[chi]+YMIN] <= nextY; chi++) {
- curveSetCurY(curvePtrs[chi], nextY);
- }
- Arrays.sort(crossings, 0, crossingIdx);
- return crossingIdx;
+ return count;
}
private boolean hasNext() {
@@ -157,51 +120,7 @@
private int curY() {
return nextY - 1;
}
-
- private void addCrossing(int y, int x, float or, int idx) {
- x <<= 1;
- crossings[idx] = ((or > 0) ? (x | 0x1) : x);
- }
}
- // quicksort implementation for sorting the edge indices ("pointers")
- // by increasing y0. first, last are indices into the "pointer" array
- // It sorts the pointer array from first (inclusive) to last (inclusive)
- private static void qsort(final float[] data, final int[] ptrs,
- final int fieldForCmp, int first, int last)
- {
- if (last > first) {
- int p = partition(data, ptrs, fieldForCmp, first, last);
- if (first < p - 1) {
- qsort(data, ptrs, fieldForCmp, first, p - 1);
- }
- if (p < last) {
- qsort(data, ptrs, fieldForCmp, p, last);
- }
- }
- }
-
- // i, j are indices into edgePtrs.
- private static int partition(final float[] data, final int[] ptrs,
- final int fieldForCmp, int i, int j)
- {
- int pivotValFieldForCmp = ptrs[i]+fieldForCmp;
- while (i <= j) {
- // edges[edgePtrs[i]+1] is equivalent to (*(edgePtrs[i])).y0 in C
- while (data[ptrs[i]+fieldForCmp] < data[pivotValFieldForCmp])
- i++;
- while (data[ptrs[j]+fieldForCmp] > data[pivotValFieldForCmp])
- j--;
- if (i <= j) {
- int tmp = ptrs[i];
- ptrs[i] = ptrs[j];
- ptrs[j] = tmp;
- i++;
- j--;
- }
- }
- return i;
- }
-//============================================================================
//////////////////////////////////////////////////////////////////////////////
@@ -209,269 +128,89 @@
//////////////////////////////////////////////////////////////////////////////
// TODO(maybe): very tempting to use fixed point here. A lot of opportunities
// for shifts and just removing certain operations altogether.
-// TODO: it might be worth it to make an EdgeList class. It would probably
-// clean things up a bit and not impact performance much.
// common to all types of input path segments.
- private static final int YMIN = 0;
- private static final int YMAX = 1;
- private static final int CURX = 2;
- // this and OR are meant to be indeces into "int" fields, but arrays must
+ private static final int YMAX = 0;
+ private static final int CURX = 1;
+ // NEXT and OR are meant to be indices into "int" fields, but arrays must
// be homogenous, so every field is a float. However floats can represent
// exactly up to 26 bit ints, so we're ok.
- private static final int CURY = 3;
- private static final int OR = 4;
-
- // for straight lines only:
- private static final int SLOPE = 5;
-
- // for quads and cubics:
- private static final int X0 = 5;
- private static final int Y0 = 6;
- private static final int XL = 7;
- private static final int COUNT = 8;
- private static final int CURSLOPE = 9;
- private static final int DX = 10;
- private static final int DY = 11;
- private static final int DDX = 12;
- private static final int DDY = 13;
-
- // for cubics only
- private static final int DDDX = 14;
- private static final int DDDY = 15;
+ private static final int OR = 2;
+ private static final int SLOPE = 3;
+ private static final int NEXT = 4;
private float edgeMinY = Float.POSITIVE_INFINITY;
private float edgeMaxY = Float.NEGATIVE_INFINITY;
private float edgeMinX = Float.POSITIVE_INFINITY;
private float edgeMaxX = Float.NEGATIVE_INFINITY;
- private static final int SIZEOF_EDGE = 6;
+ private static final int SIZEOF_EDGE = 5;
+ // don't just set NULL to -1, because we want NULL+NEXT to be negative.
+ private static final int NULL = -SIZEOF_EDGE;
private float[] edges = null;
+ private int[] edgeBuckets = null;
+ private int[] edgeBucketCounts = null; // 2*newedges + (1 if pruning needed)
private int numEdges;
- // these are static because we need them to be usable from ScanlineIterator
- private void edgeSetCurY(final int idx, int y) {
- edges[idx+CURX] += (y - edges[idx+CURY]) * edges[idx+SLOPE];
- edges[idx+CURY] = y;
- }
- private void edgeGoToNextY(final int idx) {
- edges[idx+CURY] += 1;
- edges[idx+CURX] += edges[idx+SLOPE];
- }
-
-
- private static final int SIZEOF_QUAD = 14;
- private float[] quads = null;
- private int numQuads;
- // This function should be called exactly once, to set the first scanline
- // of the curve. Before it is called, the curve should think its first
- // scanline is CEIL(YMIN).
- private void quadSetCurY(final int idx, final int y) {
- assert y < quads[idx+YMAX];
- assert (quads[idx+CURY] > y);
- assert (quads[idx+CURY] == Math.ceil(quads[idx+CURY]));
-
- while (quads[idx+CURY] < ((float)y)) {
- quadGoToNextY(idx);
- }
- }
- private void quadGoToNextY(final int idx) {
- quads[idx+CURY] += 1;
- // this will get overriden if the while executes.
- quads[idx+CURX] += quads[idx+CURSLOPE];
- int count = (int)quads[idx+COUNT];
- // this loop should never execute more than once because our
- // curve is monotonic in Y. Still we put it in because you can
- // never be too sure when dealing with floating point.
- while(quads[idx+CURY] >= quads[idx+Y0] && count > 0) {
- float x0 = quads[idx+X0], y0 = quads[idx+Y0];
- count = executeQuadAFDIteration(idx);
- float x1 = quads[idx+X0], y1 = quads[idx+Y0];
- // our quads are monotonic, so this shouldn't happen, but
- // it is conceivable that for very flat quads with different
- // y values at their endpoints AFD might give us a horizontal
- // segment.
- if (y1 == y0) {
- continue;
- }
- quads[idx+CURSLOPE] = (x1 - x0) / (y1 - y0);
- quads[idx+CURX] = x0 + (quads[idx+CURY] - y0) * quads[idx+CURSLOPE];
- }
- }
-
-
- private static final int SIZEOF_CURVE = 16;
- private float[] curves = null;
- private int numCurves;
- private void curveSetCurY(final int idx, final int y) {
- assert y < curves[idx+YMAX];
- assert (curves[idx+CURY] > y);
- assert (curves[idx+CURY] == Math.ceil(curves[idx+CURY]));
-
- while (curves[idx+CURY] < ((float)y)) {
- curveGoToNextY(idx);
- }
- }
- private void curveGoToNextY(final int idx) {
- curves[idx+CURY] += 1;
- // this will get overriden if the while executes.
- curves[idx+CURX] += curves[idx+CURSLOPE];
- int count = (int)curves[idx+COUNT];
- // this loop should never execute more than once because our
- // curve is monotonic in Y. Still we put it in because you can
- // never be too sure when dealing with floating point.
- while(curves[idx+CURY] >= curves[idx+Y0] && count > 0) {
- float x0 = curves[idx+X0], y0 = curves[idx+Y0];
- count = executeCurveAFDIteration(idx);
- float x1 = curves[idx+X0], y1 = curves[idx+Y0];
- // our curves are monotonic, so this shouldn't happen, but
- // it is conceivable that for very flat curves with different
- // y values at their endpoints AFD might give us a horizontal
- // segment.
- if (y1 == y0) {
- continue;
- }
- curves[idx+CURSLOPE] = (x1 - x0) / (y1 - y0);
- curves[idx+CURX] = x0 + (curves[idx+CURY] - y0) * curves[idx+CURSLOPE];
- }
- }
-
private static final float DEC_BND = 20f;
private static final float INC_BND = 8f;
+
+ // each bucket is a linked list. this method adds eptr to the
+ // start "bucket"th linked list.
+ private void addEdgeToBucket(final int eptr, final int bucket) {
+ edges[eptr+NEXT] = edgeBuckets[bucket];
+ edgeBuckets[bucket] = eptr;
+ edgeBucketCounts[bucket] += 2;
+ }
+
// Flattens using adaptive forward differencing. This only carries out
// one iteration of the AFD loop. All it does is update AFD variables (i.e.
// X0, Y0, D*[X|Y], COUNT; not variables used for computing scanline crossings).
- private int executeQuadAFDIteration(int idx) {
- int count = (int)quads[idx+COUNT];
- float ddx = quads[idx+DDX];
- float ddy = quads[idx+DDY];
- float dx = quads[idx+DX];
- float dy = quads[idx+DY];
-
- while (Math.abs(ddx) > DEC_BND || Math.abs(ddy) > DEC_BND) {
- ddx = ddx / 4;
- ddy = ddy / 4;
- dx = (dx - ddx) / 2;
- dy = (dy - ddy) / 2;
+ private void quadBreakIntoLinesAndAdd(float x0, float y0,
+ final Curve c,
+ final float x2, final float y2) {
+ final float QUAD_DEC_BND = 32;
+ final int countlg = 4;
+ int count = 1 << countlg;
+ int countsq = count * count;
+ float maxDD = Math.max(c.dbx / countsq, c.dby / countsq);
+ while (maxDD > QUAD_DEC_BND) {
+ maxDD /= 4;
count <<= 1;
}
- // can only do this on even "count" values, because we must divide count by 2
- while (count % 2 == 0 && Math.abs(dx) <= INC_BND && Math.abs(dy) <= INC_BND) {
- dx = 2 * dx + ddx;
- dy = 2 * dy + ddy;
- ddx = 4 * ddx;
- ddy = 4 * ddy;
- count >>= 1;
- }
- count--;
- if (count > 0) {
- quads[idx+X0] += dx;
- dx += ddx;
- quads[idx+Y0] += dy;
- dy += ddy;
- } else {
- quads[idx+X0] = quads[idx+XL];
- quads[idx+Y0] = quads[idx+YMAX];
- }
- quads[idx+COUNT] = count;
- quads[idx+DDX] = ddx;
- quads[idx+DDY] = ddy;
- quads[idx+DX] = dx;
- quads[idx+DY] = dy;
- return count;
- }
- private int executeCurveAFDIteration(int idx) {
- int count = (int)curves[idx+COUNT];
- float ddx = curves[idx+DDX];
- float ddy = curves[idx+DDY];
- float dx = curves[idx+DX];
- float dy = curves[idx+DY];
- float dddx = curves[idx+DDDX];
- float dddy = curves[idx+DDDY];
+
+ countsq = count * count;
+ final float ddx = c.dbx / countsq;
+ final float ddy = c.dby / countsq;
+ float dx = c.bx / countsq + c.cx / count;
+ float dy = c.by / countsq + c.cy / count;
- while (Math.abs(ddx) > DEC_BND || Math.abs(ddy) > DEC_BND) {
- dddx /= 8;
- dddy /= 8;
- ddx = ddx/4 - dddx;
- ddy = ddy/4 - dddy;
- dx = (dx - ddx) / 2;
- dy = (dy - ddy) / 2;
- count <<= 1;
- }
- // can only do this on even "count" values, because we must divide count by 2
- while (count % 2 == 0 && Math.abs(dx) <= INC_BND && Math.abs(dy) <= INC_BND) {
- dx = 2 * dx + ddx;
- dy = 2 * dy + ddy;
- ddx = 4 * (ddx + dddx);
- ddy = 4 * (ddy + dddy);
- dddx = 8 * dddx;
- dddy = 8 * dddy;
- count >>= 1;
+ while (count-- > 1) {
+ float x1 = x0 + dx;
+ dx += ddx;
+ float y1 = y0 + dy;
+ dy += ddy;
+ addLine(x0, y0, x1, y1);
+ x0 = x1;
+ y0 = y1;
}
- count--;
- if (count > 0) {
- curves[idx+X0] += dx;
- dx += ddx;
- ddx += dddx;
- curves[idx+Y0] += dy;
- dy += ddy;
- ddy += dddy;
- } else {
- curves[idx+X0] = curves[idx+XL];
- curves[idx+Y0] = curves[idx+YMAX];
- }
- curves[idx+COUNT] = count;
- curves[idx+DDDX] = dddx;
- curves[idx+DDDY] = dddy;
- curves[idx+DDX] = ddx;
- curves[idx+DDY] = ddy;
- curves[idx+DX] = dx;
- curves[idx+DY] = dy;
- return count;
+ addLine(x0, y0, x2, y2);
}
-
- private void initLine(final int idx, float[] pts, int or) {
- edges[idx+SLOPE] = (pts[2] - pts[0]) / (pts[3] - pts[1]);
- edges[idx+CURX] = pts[0] + (edges[idx+CURY] - pts[1]) * edges[idx+SLOPE];
- }
-
- private void initQuad(final int idx, float[] points, int or) {
+ // x0, y0 and x3,y3 are the endpoints of the curve. We could compute these
+ // using c.xat(0),c.yat(0) and c.xat(1),c.yat(1), but this might introduce
+ // numerical errors, and our callers already have the exact values.
+ // Another alternative would be to pass all the control points, and call c.set
+ // here, but then too many numbers are passed around.
+ private void curveBreakIntoLinesAndAdd(float x0, float y0,
+ final Curve c,
+ final float x3, final float y3) {
final int countlg = 3;
- final int count = 1 << countlg;
+ int count = 1 << countlg;
// the dx and dy refer to forward differencing variables, not the last
// coefficients of the "points" polynomial
- final float ddx, ddy, dx, dy;
- c.set(points, 6);
-
- ddx = c.dbx / (1 << (2 * countlg));
- ddy = c.dby / (1 << (2 * countlg));
- dx = c.bx / (1 << (2 * countlg)) + c.cx / (1 << countlg);
- dy = c.by / (1 << (2 * countlg)) + c.cy / (1 << countlg);
-
- quads[idx+DDX] = ddx;
- quads[idx+DDY] = ddy;
- quads[idx+DX] = dx;
- quads[idx+DY] = dy;
- quads[idx+COUNT] = count;
- quads[idx+XL] = points[4];
- quads[idx+X0] = points[0];
- quads[idx+Y0] = points[1];
- executeQuadAFDIteration(idx);
- float x1 = quads[idx+X0], y1 = quads[idx+Y0];
- quads[idx+CURSLOPE] = (x1 - points[0]) / (y1 - points[1]);
- quads[idx+CURX] = points[0] + (quads[idx+CURY] - points[1])*quads[idx+CURSLOPE];
- }
-
- private void initCurve(final int idx, float[] points, int or) {
- final int countlg = 3;
- final int count = 1 << countlg;
-
- // the dx and dy refer to forward differencing variables, not the last
- // coefficients of the "points" polynomial
- final float dddx, dddy, ddx, ddy, dx, dy;
- c.set(points, 8);
+ float dddx, dddy, ddx, ddy, dx, dy;
dddx = 2f * c.dax / (1 << (3 * countlg));
dddy = 2f * c.day / (1 << (3 * countlg));
@@ -480,93 +219,100 @@
dx = c.ax / (1 << (3 * countlg)) + c.bx / (1 << (2 * countlg)) + c.cx / (1 << countlg);
dy = c.ay / (1 << (3 * countlg)) + c.by / (1 << (2 * countlg)) + c.cy / (1 << countlg);
- curves[idx+DDDX] = dddx;
- curves[idx+DDDY] = dddy;
- curves[idx+DDX] = ddx;
- curves[idx+DDY] = ddy;
- curves[idx+DX] = dx;
- curves[idx+DY] = dy;
- curves[idx+COUNT] = count;
- curves[idx+XL] = points[6];
- curves[idx+X0] = points[0];
- curves[idx+Y0] = points[1];
- executeCurveAFDIteration(idx);
- float x1 = curves[idx+X0], y1 = curves[idx+Y0];
- curves[idx+CURSLOPE] = (x1 - points[0]) / (y1 - points[1]);
- curves[idx+CURX] = points[0] + (curves[idx+CURY] - points[1])*curves[idx+CURSLOPE];
- }
-
- private void addPathSegment(float[] pts, final int type, final int or) {
- int idx;
- float[] addTo;
- switch (type) {
- case 4:
- idx = numEdges * SIZEOF_EDGE;
- addTo = edges = Helpers.widenArray(edges, numEdges*SIZEOF_EDGE, SIZEOF_EDGE);
- numEdges++;
- break;
- case 6:
- idx = numQuads * SIZEOF_QUAD;
- addTo = quads = Helpers.widenArray(quads, numQuads*SIZEOF_QUAD, SIZEOF_QUAD);
- numQuads++;
- break;
- case 8:
- idx = numCurves * SIZEOF_CURVE;
- addTo = curves = Helpers.widenArray(curves, numCurves*SIZEOF_CURVE, SIZEOF_CURVE);
- numCurves++;
- break;
- default:
- throw new InternalError();
- }
- // set the common fields, except CURX, for which we must know the kind
- // of curve. NOTE: this must be done before the type specific fields
- // are initialized, because those depend on the common ones.
- addTo[idx+YMIN] = pts[1];
- addTo[idx+YMAX] = pts[type-1];
- addTo[idx+OR] = or;
- addTo[idx+CURY] = (float)Math.ceil(pts[1]);
- switch (type) {
- case 4:
- initLine(idx, pts, or);
- break;
- case 6:
- initQuad(idx, pts, or);
- break;
- case 8:
- initCurve(idx, pts, or);
- break;
- default:
- throw new InternalError();
+ // we use x0, y0 to walk the line
+ float x1 = x0, y1 = y0;
+ while (count > 0) {
+ while (Math.abs(ddx) > DEC_BND || Math.abs(ddy) > DEC_BND) {
+ dddx /= 8;
+ dddy /= 8;
+ ddx = ddx/4 - dddx;
+ ddy = ddy/4 - dddy;
+ dx = (dx - ddx) / 2;
+ dy = (dy - ddy) / 2;
+ count <<= 1;
+ }
+ // can only do this on even "count" values, because we must divide count by 2
+ while (count % 2 == 0 && Math.abs(dx) <= INC_BND && Math.abs(dy) <= INC_BND) {
+ dx = 2 * dx + ddx;
+ dy = 2 * dy + ddy;
+ ddx = 4 * (ddx + dddx);
+ ddy = 4 * (ddy + dddy);
+ dddx = 8 * dddx;
+ dddy = 8 * dddy;
+ count >>= 1;
+ }
+ count--;
+ if (count > 0) {
+ x1 += dx;
+ dx += ddx;
+ ddx += dddx;
+ y1 += dy;
+ dy += ddy;
+ ddy += dddy;
+ } else {
+ x1 = x3;
+ y1 = y3;
+ }
+ addLine(x0, y0, x1, y1);
+ x0 = x1;
+ y0 = y1;
}
}
- // precondition: the curve in pts must be monotonic and increasing in y.
- private void somethingTo(float[] pts, final int type, final int or) {
- // NOTE: it's very important that we check for or >= 0 below (as
- // opposed to or == 1, or or > 0, or anything else). That's
- // because if we check for or==1, when the curve being added
- // is a horizontal line, or will be 0 so or==1 will be false and
- // x0 and y0 will be updated to pts[0] and pts[1] instead of pts[type-2]
- // and pts[type-1], which is the correct thing to do.
- this.x0 = or >= 0 ? pts[type - 2] : pts[0];
- this.y0 = or >= 0 ? pts[type - 1] : pts[1];
-
- float minY = pts[1], maxY = pts[type - 1];
- if (Math.ceil(minY) >= Math.ceil(maxY) ||
- Math.ceil(minY) >= boundsMaxY || maxY < boundsMinY)
- {
+ // Preconditions: y2 > y1 and the curve must cross some scanline
+ // i.e.: y1 <= y < y2 for some y such that boundsMinY <= y < boundsMaxY
+ private void addLine(float x1, float y1, float x2, float y2) {
+ float or = 1; // orientation of the line. 1 if y increases, 0 otherwise.
+ if (y2 < y1) {
+ or = y2; // no need to declare a temp variable. We have or.
+ y2 = y1;
+ y1 = or;
+ or = x2;
+ x2 = x1;
+ x1 = or;
+ or = 0;
+ }
+ final int firstCrossing = Math.max((int) Math.ceil(y1), boundsMinY);
+ final int lastCrossing = Math.min((int)Math.ceil(y2), boundsMaxY);
+ if (firstCrossing >= lastCrossing) {
return;
}
- if (minY < edgeMinY) { edgeMinY = minY; }
- if (maxY > edgeMaxY) { edgeMaxY = maxY; }
+ if (y1 < edgeMinY) { edgeMinY = y1; }
+ if (y2 > edgeMaxY) { edgeMaxY = y2; }
+
+ final float slope = (x2 - x1) / (y2 - y1);
+
+ if (slope > 0) { // <==> x1 < x2
+ if (x1 < edgeMinX) { edgeMinX = x1; }
+ if (x2 > edgeMaxX) { edgeMaxX = x2; }
+ } else {
+ if (x2 < edgeMinX) { edgeMinX = x2; }
+ if (x1 > edgeMaxX) { edgeMaxX = x1; }
+ }
- int minXidx = (pts[0] < pts[type-2] ? 0 : type - 2);
- float minX = pts[minXidx];
- float maxX = pts[type - 2 - minXidx];
- if (minX < edgeMinX) { edgeMinX = minX; }
- if (maxX > edgeMaxX) { edgeMaxX = maxX; }
- addPathSegment(pts, type, or);
+ final int ptr = numEdges * SIZEOF_EDGE;
+ edges = Helpers.widenArray(edges, ptr, SIZEOF_EDGE);
+ numEdges++;
+ edges[ptr+OR] = or;
+ edges[ptr+CURX] = x1 + (firstCrossing - y1) * slope;
+ edges[ptr+SLOPE] = slope;
+ edges[ptr+YMAX] = y2;
+ final int bucketIdx = firstCrossing - boundsMinY;
+ addEdgeToBucket(ptr, bucketIdx);
+ if (lastCrossing < boundsMaxY) {
+ edgeBucketCounts[lastCrossing - boundsMinY] |= 1;
+ }
+ }
+
+ // preconditions: should not be called before the last line has been added
+ // to the edge list (even though it will return a correct answer at that
+ // point in time, it's not meant to be used that way).
+ private int getFirstScanLineCrossing() {
+ return Math.max(boundsMinY, (int)Math.ceil(edgeMinY));
+ }
+ private int getScanLineCrossingEnd() {
+ return Math.min(boundsMaxY, (int)Math.ceil(edgeMaxY));
}
// END EDGE LIST
@@ -619,6 +365,10 @@
this.boundsMinY = pix_boundsY * SUBPIXEL_POSITIONS_Y;
this.boundsMaxX = (pix_boundsX + pix_boundsWidth) * SUBPIXEL_POSITIONS_X;
this.boundsMaxY = (pix_boundsY + pix_boundsHeight) * SUBPIXEL_POSITIONS_Y;
+
+ edgeBuckets = new int[boundsMaxY - boundsMinY];
+ java.util.Arrays.fill(edgeBuckets, NULL);
+ edgeBucketCounts = new int[edgeBuckets.length];
}
private float tosubpixx(float pix_x) {
@@ -636,74 +386,34 @@
this.x0 = tosubpixx(pix_x0);
}
- public void lineJoin() { /* do nothing */ }
-
- private final float[][] pts = new float[2][8];
- private final float[] ts = new float[4];
-
- private static void invertPolyPoints(float[] pts, int off, int type) {
- for (int i = off, j = off + type - 2; i < j; i += 2, j -= 2) {
- float tmp = pts[i];
- pts[i] = pts[j];
- pts[j] = tmp;
- tmp = pts[i+1];
- pts[i+1] = pts[j+1];
- pts[j+1] = tmp;
- }
- }
-
- // return orientation before making the curve upright.
- private static int makeMonotonicCurveUpright(float[] pts, int off, int type) {
- float y0 = pts[off + 1];
- float y1 = pts[off + type - 1];
- if (y0 > y1) {
- invertPolyPoints(pts, off, type);
- return -1;
- } else if (y0 < y1) {
- return 1;
- }
- return 0;
- }
-
public void lineTo(float pix_x1, float pix_y1) {
- pts[0][0] = x0; pts[0][1] = y0;
- pts[0][2] = tosubpixx(pix_x1); pts[0][3] = tosubpixy(pix_y1);
- int or = makeMonotonicCurveUpright(pts[0], 0, 4);
- somethingTo(pts[0], 4, or);
+ float x1 = tosubpixx(pix_x1);
+ float y1 = tosubpixy(pix_y1);
+ addLine(x0, y0, x1, y1);
+ x0 = x1;
+ y0 = y1;
}
Curve c = new Curve();
- private void curveOrQuadTo(int type) {
- c.set(pts[0], type);
- int numTs = c.dxRoots(ts, 0);
- numTs += c.dyRoots(ts, numTs);
- numTs = Helpers.filterOutNotInAB(ts, 0, numTs, 0, 1);
- Helpers.isort(ts, 0, numTs);
-
- Iterator<float[]> it = Curve.breakPtsAtTs(pts, type, ts, numTs);
- while(it.hasNext()) {
- float[] curCurve = it.next();
- int or = makeMonotonicCurveUpright(curCurve, 0, type);
- somethingTo(curCurve, type, or);
- }
- }
-
@Override public void curveTo(float x1, float y1,
float x2, float y2,
float x3, float y3)
{
- pts[0][0] = x0; pts[0][1] = y0;
- pts[0][2] = tosubpixx(x1); pts[0][3] = tosubpixy(y1);
- pts[0][4] = tosubpixx(x2); pts[0][5] = tosubpixy(y2);
- pts[0][6] = tosubpixx(x3); pts[0][7] = tosubpixy(y3);
- curveOrQuadTo(8);
+ final float xe = tosubpixx(x3);
+ final float ye = tosubpixy(y3);
+ c.set(x0, y0, tosubpixx(x1), tosubpixy(y1), tosubpixx(x2), tosubpixy(y2), xe, ye);
+ curveBreakIntoLinesAndAdd(x0, y0, c, xe, ye);
+ x0 = xe;
+ y0 = ye;
}
@Override public void quadTo(float x1, float y1, float x2, float y2) {
- pts[0][0] = x0; pts[0][1] = y0;
- pts[0][2] = tosubpixx(x1); pts[0][3] = tosubpixy(y1);
- pts[0][4] = tosubpixx(x2); pts[0][5] = tosubpixy(y2);
- curveOrQuadTo(6);
+ final float xe = tosubpixx(x2);
+ final float ye = tosubpixy(y2);
+ c.set(x0, y0, tosubpixx(x1), tosubpixy(y1), xe, ye);
+ quadBreakIntoLinesAndAdd(x0, y0, c, xe, ye);
+ x0 = xe;
+ y0 = ye;
}
public void closePath() {
@@ -728,9 +438,9 @@
// 0x1 if EVEN_ODD, all bits if NON_ZERO
int mask = (windingRule == WIND_EVEN_ODD) ? 0x1 : ~0x0;
- // add 1 to better deal with the last pixel in a pixel row.
- int width = pix_bboxx1 - pix_bboxx0 + 1;
- int[] alpha = new int[width+1];
+ // add 2 to better deal with the last pixel in a pixel row.
+ int width = pix_bboxx1 - pix_bboxx0;
+ int[] alpha = new int[width+2];
int bboxx0 = pix_bboxx0 << SUBPIXEL_LG_POSITIONS_X;
int bboxx1 = pix_bboxx1 << SUBPIXEL_LG_POSITIONS_X;
@@ -766,7 +476,8 @@
for (int i = 0; i < numCrossings; i++) {
int curxo = crossings[i];
int curx = curxo >> 1;
- int crorientation = ((curxo & 0x1) == 0x1) ? 1 : -1;
+ // to turn {0, 1} into {-1, 1}, multiply by 2 and subtract 1.
+ int crorientation = ((curxo & 0x1) << 1) -1;
if ((sum & mask) != 0) {
int x0 = Math.max(prev, bboxx0);
int x1 = Math.min(curx, bboxx1);
@@ -811,26 +522,26 @@
}
public void endRendering() {
- final int bminx = boundsMinX >> SUBPIXEL_LG_POSITIONS_X;
- final int bmaxx = boundsMaxX >> SUBPIXEL_LG_POSITIONS_X;
- final int bminy = boundsMinY >> SUBPIXEL_LG_POSITIONS_Y;
- final int bmaxy = boundsMaxY >> SUBPIXEL_LG_POSITIONS_Y;
- final int eminx = ((int)Math.floor(edgeMinX)) >> SUBPIXEL_LG_POSITIONS_X;
- final int emaxx = ((int)Math.ceil(edgeMaxX)) >> SUBPIXEL_LG_POSITIONS_X;
- final int eminy = ((int)Math.floor(edgeMinY)) >> SUBPIXEL_LG_POSITIONS_Y;
- final int emaxy = ((int)Math.ceil(edgeMaxY)) >> SUBPIXEL_LG_POSITIONS_Y;
+ int spminX = Math.max((int)Math.ceil(edgeMinX), boundsMinX);
+ int spmaxX = Math.min((int)Math.ceil(edgeMaxX), boundsMaxX);
+ int spminY = Math.max((int)Math.ceil(edgeMinY), boundsMinY);
+ int spmaxY = Math.min((int)Math.ceil(edgeMaxY), boundsMaxY);
- final int minX = Math.max(bminx, eminx);
- final int maxX = Math.min(bmaxx, emaxx);
- final int minY = Math.max(bminy, eminy);
- final int maxY = Math.min(bmaxy, emaxy);
- if (minX > maxX || minY > maxY) {
- this.cache = new PiscesCache(bminx, bminy, bmaxx, bmaxy);
+ int pminX = spminX >> SUBPIXEL_LG_POSITIONS_X;
+ int pmaxX = (spmaxX + SUBPIXEL_MASK_X) >> SUBPIXEL_LG_POSITIONS_X;
+ int pminY = spminY >> SUBPIXEL_LG_POSITIONS_Y;
+ int pmaxY = (spmaxY + SUBPIXEL_MASK_Y) >> SUBPIXEL_LG_POSITIONS_Y;
+
+ if (pminX > pmaxX || pminY > pmaxY) {
+ this.cache = new PiscesCache(boundsMinX >> SUBPIXEL_LG_POSITIONS_X,
+ boundsMinY >> SUBPIXEL_LG_POSITIONS_Y,
+ boundsMaxX >> SUBPIXEL_LG_POSITIONS_X,
+ boundsMaxY >> SUBPIXEL_LG_POSITIONS_Y);
return;
}
- this.cache = new PiscesCache(minX, minY, maxX, maxY);
- _endRendering(minX, minY, maxX, maxY);
+ this.cache = new PiscesCache(pminX, pminY, pmaxX, pmaxY);
+ _endRendering(pminX, pminY, pmaxX, pmaxY);
}
public PiscesCache getCache() {
--- a/jdk/src/share/classes/sun/java2d/pisces/Stroker.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/java2d/pisces/Stroker.java Mon Feb 14 16:30:10 2011 -0800
@@ -33,7 +33,7 @@
// TODO: some of the arithmetic here is too verbose and prone to hard to
// debug typos. We should consider making a small Point/Vector class that
// has methods like plus(Point), minus(Point), dot(Point), cross(Point)and such
-public class Stroker implements PathConsumer2D {
+final class Stroker implements PathConsumer2D {
private static final int MOVE_TO = 0;
private static final int DRAWING_OP_TO = 1; // ie. curve, line, or quad
@@ -130,7 +130,7 @@
private static void computeOffset(final float lx, final float ly,
final float w, final float[] m)
{
- final float len = (float)Math.hypot(lx, ly);
+ final float len = (float)Math.sqrt(lx*lx + ly*ly);
if (len == 0) {
m[0] = m[1] = 0;
} else {
@@ -758,7 +758,7 @@
// This is where the curve to be processed is put. We give it
// enough room to store 2 curves: one for the current subdivision, the
// other for the rest of the curve.
- private float[][] middle = new float[2][8];
+ private float[] middle = new float[2*8];
private float[] lp = new float[8];
private float[] rp = new float[8];
private static final int MAX_N_CURVES = 11;
@@ -766,55 +766,55 @@
private void somethingTo(final int type) {
// need these so we can update the state at the end of this method
- final float xf = middle[0][type-2], yf = middle[0][type-1];
- float dxs = middle[0][2] - middle[0][0];
- float dys = middle[0][3] - middle[0][1];
- float dxf = middle[0][type - 2] - middle[0][type - 4];
- float dyf = middle[0][type - 1] - middle[0][type - 3];
+ final float xf = middle[type-2], yf = middle[type-1];
+ float dxs = middle[2] - middle[0];
+ float dys = middle[3] - middle[1];
+ float dxf = middle[type - 2] - middle[type - 4];
+ float dyf = middle[type - 1] - middle[type - 3];
switch(type) {
case 6:
if ((dxs == 0f && dys == 0f) ||
(dxf == 0f && dyf == 0f)) {
- dxs = dxf = middle[0][4] - middle[0][0];
- dys = dyf = middle[0][5] - middle[0][1];
+ dxs = dxf = middle[4] - middle[0];
+ dys = dyf = middle[5] - middle[1];
}
break;
case 8:
boolean p1eqp2 = (dxs == 0f && dys == 0f);
boolean p3eqp4 = (dxf == 0f && dyf == 0f);
if (p1eqp2) {
- dxs = middle[0][4] - middle[0][0];
- dys = middle[0][5] - middle[0][1];
+ dxs = middle[4] - middle[0];
+ dys = middle[5] - middle[1];
if (dxs == 0f && dys == 0f) {
- dxs = middle[0][6] - middle[0][0];
- dys = middle[0][7] - middle[0][1];
+ dxs = middle[6] - middle[0];
+ dys = middle[7] - middle[1];
}
}
if (p3eqp4) {
- dxf = middle[0][6] - middle[0][2];
- dyf = middle[0][7] - middle[0][3];
+ dxf = middle[6] - middle[2];
+ dyf = middle[7] - middle[3];
if (dxf == 0f && dyf == 0f) {
- dxf = middle[0][6] - middle[0][0];
- dyf = middle[0][7] - middle[0][1];
+ dxf = middle[6] - middle[0];
+ dyf = middle[7] - middle[1];
}
}
}
if (dxs == 0f && dys == 0f) {
// this happens iff the "curve" is just a point
- lineTo(middle[0][0], middle[0][1]);
+ lineTo(middle[0], middle[1]);
return;
}
// if these vectors are too small, normalize them, to avoid future
// precision problems.
if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) {
- double len = Math.hypot(dxs, dys);
- dxs = (float)(dxs / len);
- dys = (float)(dys / len);
+ float len = (float)Math.sqrt(dxs*dxs + dys*dys);
+ dxs /= len;
+ dys /= len;
}
if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) {
- double len = Math.hypot(dxf, dyf);
- dxf = (float)(dxf / len);
- dyf = (float)(dyf / len);
+ float len = (float)Math.sqrt(dxf*dxf + dyf*dyf);
+ dxf /= len;
+ dyf /= len;
}
computeOffset(dxs, dys, lineWidth2, offset[0]);
@@ -822,20 +822,20 @@
final float my = offset[0][1];
drawJoin(cdx, cdy, cx0, cy0, dxs, dys, cmx, cmy, mx, my);
- int nSplits = findSubdivPoints(middle[0], subdivTs, type,lineWidth2);
+ int nSplits = findSubdivPoints(middle, subdivTs, type, lineWidth2);
int kind = 0;
- Iterator<float[]> it = Curve.breakPtsAtTs(middle, type, subdivTs, nSplits);
+ Iterator<Integer> it = Curve.breakPtsAtTs(middle, type, subdivTs, nSplits);
while(it.hasNext()) {
- float[] curCurve = it.next();
+ int curCurveOff = it.next();
kind = 0;
switch (type) {
case 8:
- kind = computeOffsetCubic(curCurve, 0, lp, rp);
+ kind = computeOffsetCubic(middle, curCurveOff, lp, rp);
break;
case 6:
- kind = computeOffsetQuad(curCurve, 0, lp, rp);
+ kind = computeOffsetQuad(middle, curCurveOff, lp, rp);
break;
}
if (kind != 0) {
@@ -871,8 +871,7 @@
// to get good offset curves a distance of w away from the middle curve.
// Stores the points in ts, and returns how many of them there were.
private static Curve c = new Curve();
- private static int findSubdivPoints(float[] pts, float[] ts,
- final int type, final float w)
+ private static int findSubdivPoints(float[] pts, float[] ts, final int type, final float w)
{
final float x12 = pts[2] - pts[0];
final float y12 = pts[3] - pts[1];
@@ -919,6 +918,7 @@
// now we must subdivide at points where one of the offset curves will have
// a cusp. This happens at ts where the radius of curvature is equal to w.
ret += c.rootsOfROCMinusW(ts, ret, w, 0.0001f);
+
ret = Helpers.filterOutNotInAB(ts, 0, ret, 0.0001f, 0.9999f);
Helpers.isort(ts, 0, ret);
return ret;
@@ -928,10 +928,10 @@
float x2, float y2,
float x3, float y3)
{
- middle[0][0] = cx0; middle[0][1] = cy0;
- middle[0][2] = x1; middle[0][3] = y1;
- middle[0][4] = x2; middle[0][5] = y2;
- middle[0][6] = x3; middle[0][7] = y3;
+ middle[0] = cx0; middle[1] = cy0;
+ middle[2] = x1; middle[3] = y1;
+ middle[4] = x2; middle[5] = y2;
+ middle[6] = x3; middle[7] = y3;
somethingTo(8);
}
@@ -940,9 +940,9 @@
}
@Override public void quadTo(float x1, float y1, float x2, float y2) {
- middle[0][0] = cx0; middle[0][1] = cy0;
- middle[0][2] = x1; middle[0][3] = y1;
- middle[0][4] = x2; middle[0][5] = y2;
+ middle[0] = cx0; middle[1] = cy0;
+ middle[2] = x1; middle[3] = y1;
+ middle[4] = x2; middle[5] = y2;
somethingTo(6);
}
--- a/jdk/src/share/classes/sun/java2d/pisces/TransformingPathConsumer2D.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/java2d/pisces/TransformingPathConsumer2D.java Mon Feb 14 16:30:10 2011 -0800
@@ -28,7 +28,7 @@
import sun.awt.geom.PathConsumer2D;
import java.awt.geom.AffineTransform;
-public class TransformingPathConsumer2D {
+final class TransformingPathConsumer2D {
public static PathConsumer2D
transformConsumer(PathConsumer2D out,
AffineTransform at)
@@ -50,17 +50,72 @@
return new TranslateFilter(out, Mxt, Myt);
}
} else {
- return new ScaleFilter(out, Mxx, Myy, Mxt, Myt);
+ if (Mxt == 0f && Myt == 0f) {
+ return new DeltaScaleFilter(out, Mxx, Myy);
+ } else {
+ return new ScaleFilter(out, Mxx, Myy, Mxt, Myt);
+ }
}
+ } else if (Mxt == 0f && Myt == 0f) {
+ return new DeltaTransformFilter(out, Mxx, Mxy, Myx, Myy);
} else {
return new TransformFilter(out, Mxx, Mxy, Mxt, Myx, Myy, Myt);
}
}
- static class TranslateFilter implements PathConsumer2D {
- PathConsumer2D out;
- float tx;
- float ty;
+ public static PathConsumer2D
+ deltaTransformConsumer(PathConsumer2D out,
+ AffineTransform at)
+ {
+ if (at == null) {
+ return out;
+ }
+ float Mxx = (float) at.getScaleX();
+ float Mxy = (float) at.getShearX();
+ float Myx = (float) at.getShearY();
+ float Myy = (float) at.getScaleY();
+ if (Mxy == 0f && Myx == 0f) {
+ if (Mxx == 1f && Myy == 1f) {
+ return out;
+ } else {
+ return new DeltaScaleFilter(out, Mxx, Myy);
+ }
+ } else {
+ return new DeltaTransformFilter(out, Mxx, Mxy, Myx, Myy);
+ }
+ }
+
+ public static PathConsumer2D
+ inverseDeltaTransformConsumer(PathConsumer2D out,
+ AffineTransform at)
+ {
+ if (at == null) {
+ return out;
+ }
+ float Mxx = (float) at.getScaleX();
+ float Mxy = (float) at.getShearX();
+ float Myx = (float) at.getShearY();
+ float Myy = (float) at.getScaleY();
+ if (Mxy == 0f && Myx == 0f) {
+ if (Mxx == 1f && Myy == 1f) {
+ return out;
+ } else {
+ return new DeltaScaleFilter(out, 1.0f/Mxx, 1.0f/Myy);
+ }
+ } else {
+ float det = Mxx * Myy - Mxy * Myx;
+ return new DeltaTransformFilter(out,
+ Myy / det,
+ -Mxy / det,
+ -Myx / det,
+ Mxx / det);
+ }
+ }
+
+ static final class TranslateFilter implements PathConsumer2D {
+ private final PathConsumer2D out;
+ private final float tx;
+ private final float ty;
TranslateFilter(PathConsumer2D out,
float tx, float ty)
@@ -107,12 +162,12 @@
}
}
- static class ScaleFilter implements PathConsumer2D {
- PathConsumer2D out;
- float sx;
- float sy;
- float tx;
- float ty;
+ static final class ScaleFilter implements PathConsumer2D {
+ private final PathConsumer2D out;
+ private final float sx;
+ private final float sy;
+ private final float tx;
+ private final float ty;
ScaleFilter(PathConsumer2D out,
float sx, float sy, float tx, float ty)
@@ -161,14 +216,14 @@
}
}
- static class TransformFilter implements PathConsumer2D {
- PathConsumer2D out;
- float Mxx;
- float Mxy;
- float Mxt;
- float Myx;
- float Myy;
- float Myt;
+ static final class TransformFilter implements PathConsumer2D {
+ private final PathConsumer2D out;
+ private final float Mxx;
+ private final float Mxy;
+ private final float Mxt;
+ private final float Myx;
+ private final float Myy;
+ private final float Myt;
TransformFilter(PathConsumer2D out,
float Mxx, float Mxy, float Mxt,
@@ -226,4 +281,113 @@
return 0;
}
}
+
+ static final class DeltaScaleFilter implements PathConsumer2D {
+ private final float sx, sy;
+ private final PathConsumer2D out;
+
+ public DeltaScaleFilter(PathConsumer2D out, float Mxx, float Myy) {
+ sx = Mxx;
+ sy = Myy;
+ this.out = out;
+ }
+
+ public void moveTo(float x0, float y0) {
+ out.moveTo(x0 * sx, y0 * sy);
+ }
+
+ public void lineTo(float x1, float y1) {
+ out.lineTo(x1 * sx, y1 * sy);
+ }
+
+ public void quadTo(float x1, float y1,
+ float x2, float y2)
+ {
+ out.quadTo(x1 * sx, y1 * sy,
+ x2 * sx, y2 * sy);
+ }
+
+ public void curveTo(float x1, float y1,
+ float x2, float y2,
+ float x3, float y3)
+ {
+ out.curveTo(x1 * sx, y1 * sy,
+ x2 * sx, y2 * sy,
+ x3 * sx, y3 * sy);
+ }
+
+ public void closePath() {
+ out.closePath();
+ }
+
+ public void pathDone() {
+ out.pathDone();
+ }
+
+ public long getNativeConsumer() {
+ return 0;
+ }
+ }
+
+ static final class DeltaTransformFilter implements PathConsumer2D {
+ private PathConsumer2D out;
+ private final float Mxx;
+ private final float Mxy;
+ private final float Myx;
+ private final float Myy;
+
+ DeltaTransformFilter(PathConsumer2D out,
+ float Mxx, float Mxy,
+ float Myx, float Myy)
+ {
+ this.out = out;
+ this.Mxx = Mxx;
+ this.Mxy = Mxy;
+ this.Myx = Myx;
+ this.Myy = Myy;
+ }
+
+ public void moveTo(float x0, float y0) {
+ out.moveTo(x0 * Mxx + y0 * Mxy,
+ x0 * Myx + y0 * Myy);
+ }
+
+ public void lineTo(float x1, float y1) {
+ out.lineTo(x1 * Mxx + y1 * Mxy,
+ x1 * Myx + y1 * Myy);
+ }
+
+ public void quadTo(float x1, float y1,
+ float x2, float y2)
+ {
+ out.quadTo(x1 * Mxx + y1 * Mxy,
+ x1 * Myx + y1 * Myy,
+ x2 * Mxx + y2 * Mxy,
+ x2 * Myx + y2 * Myy);
+ }
+
+ public void curveTo(float x1, float y1,
+ float x2, float y2,
+ float x3, float y3)
+ {
+ out.curveTo(x1 * Mxx + y1 * Mxy,
+ x1 * Myx + y1 * Myy,
+ x2 * Mxx + y2 * Mxy,
+ x2 * Myx + y2 * Myy,
+ x3 * Mxx + y3 * Mxy,
+ x3 * Myx + y3 * Myy);
+ }
+
+ public void closePath() {
+ out.closePath();
+ }
+
+ public void pathDone() {
+ out.pathDone();
+ }
+
+ public long getNativeConsumer() {
+ return 0;
+ }
+ }
}
--- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java Mon Feb 14 16:30:10 2011 -0800
@@ -63,8 +63,6 @@
public enum LauncherHelper {
INSTANCE;
- private static final String defaultBundleName =
- "sun.launcher.resources.launcher";
private static final String MAIN_CLASS = "Main-Class";
private static StringBuilder outBuf = new StringBuilder();
@@ -76,11 +74,14 @@
private static final String PROP_SETTINGS = "Property settings:";
private static final String LOCALE_SETTINGS = "Locale settings:";
- private static synchronized ResourceBundle getLauncherResourceBundle() {
- if (javarb == null) {
- javarb = ResourceBundle.getBundle(defaultBundleName);
- }
- return javarb;
+ // sync with java.c and sun.misc.VM
+ private static final String diagprop = "sun.java.launcher.diag";
+
+ private static final String defaultBundleName =
+ "sun.launcher.resources.launcher";
+ private static class ResourceBundleHolder {
+ private static final ResourceBundle RB =
+ ResourceBundle.getBundle(defaultBundleName);
}
/*
@@ -308,7 +309,7 @@
* apply any arguments that we might pass.
*/
private static String getLocalizedMessage(String key, Object... args) {
- String msg = getLauncherResourceBundle().getString(key);
+ String msg = ResourceBundleHolder.RB.getString(key);
return (args != null) ? MessageFormat.format(msg, args) : msg;
}
@@ -380,25 +381,29 @@
File.pathSeparator));
}
- static String getMainClassFromJar(String jarname) throws IOException {
- JarFile jarFile = null;
+ static String getMainClassFromJar(PrintStream ostream, String jarname) {
try {
- jarFile = new JarFile(jarname);
- Manifest manifest = jarFile.getManifest();
- if (manifest == null) {
- throw new IOException("manifest not found in " + jarname);
+ JarFile jarFile = null;
+ try {
+ jarFile = new JarFile(jarname);
+ Manifest manifest = jarFile.getManifest();
+ if (manifest == null) {
+ abort(ostream, null, "java.launcher.jar.error2", jarname);
+ }
+ Attributes mainAttrs = manifest.getMainAttributes();
+ if (mainAttrs == null) {
+ abort(ostream, null, "java.launcher.jar.error3", jarname);
+ }
+ return mainAttrs.getValue(MAIN_CLASS).trim();
+ } finally {
+ if (jarFile != null) {
+ jarFile.close();
+ }
}
- Attributes mainAttrs = manifest.getMainAttributes();
- if (mainAttrs == null) {
- throw new IOException("no main mainifest attributes, in " +
- jarname);
- }
- return mainAttrs.getValue(MAIN_CLASS).trim();
- } finally {
- if (jarFile != null) {
- jarFile.close();
- }
+ } catch (IOException ioe) {
+ abort(ostream, ioe, "java.launcher.jar.error1", jarname);
}
+ return null;
}
@@ -409,6 +414,20 @@
private static final int LM_CLASS = 1;
private static final int LM_JAR = 2;
+ static void abort(PrintStream ostream, Throwable t, String msgKey, Object... args) {
+ if (msgKey != null) {
+ ostream.println(getLocalizedMessage(msgKey, args));
+ }
+ if (sun.misc.VM.getSavedProperty(diagprop) != null) {
+ if (t != null) {
+ t.printStackTrace();
+ } else {
+ Thread.currentThread().dumpStack();
+ }
+ }
+ System.exit(1);
+ }
+
/**
* This method does the following:
* 1. gets the classname from a Jar's manifest, if necessary
@@ -426,39 +445,31 @@
* @param isJar
* @param name
* @return
- * @throws java.io.IOException
*/
public static Class<?> checkAndLoadMain(boolean printToStderr,
int mode,
- String what) throws IOException
- {
-
- ClassLoader ld = ClassLoader.getSystemClassLoader();
-
+ String what) {
+ final PrintStream ostream = (printToStderr) ? System.err : System.out;
+ final ClassLoader ld = ClassLoader.getSystemClassLoader();
// get the class name
String cn = null;
switch (mode) {
- case LM_CLASS:
- cn = what;
- break;
- case LM_JAR:
- cn = getMainClassFromJar(what);
- break;
- default:
- throw new InternalError("" + mode + ": Unknown launch mode");
+ case LM_CLASS:
+ cn = what;
+ break;
+ case LM_JAR:
+ cn = getMainClassFromJar(ostream, what);
+ break;
+ default:
+ // should never happen
+ throw new InternalError("" + mode + ": Unknown launch mode");
}
cn = cn.replace('/', '.');
-
- PrintStream ostream = (printToStderr) ? System.err : System.out;
Class<?> c = null;
try {
c = ld.loadClass(cn);
} catch (ClassNotFoundException cnfe) {
- ostream.println(getLocalizedMessage("java.launcher.cls.error1",
- cn));
- NoClassDefFoundError ncdfe = new NoClassDefFoundError(cn);
- ncdfe.initCause(cnfe);
- throw ncdfe;
+ abort(ostream, cnfe, "java.launcher.cls.error1", cn);
}
signatureDiagnostic(ostream, c);
return c;
@@ -470,9 +481,7 @@
try {
method = clazz.getMethod("main", String[].class);
} catch (NoSuchMethodException nsme) {
- ostream.println(getLocalizedMessage("java.launcher.cls.error4",
- classname));
- throw new RuntimeException("Main method not found in " + classname);
+ abort(ostream, null, "java.launcher.cls.error4", classname);
}
/*
* getMethod (above) will choose the correct method, based
@@ -481,17 +490,10 @@
*/
int mod = method.getModifiers();
if (!Modifier.isStatic(mod)) {
- ostream.println(getLocalizedMessage("java.launcher.cls.error2",
- "static", classname));
- throw new RuntimeException("Main method is not static in class " +
- classname);
+ abort(ostream, null, "java.launcher.cls.error2", "static", classname);
}
if (method.getReturnType() != java.lang.Void.TYPE) {
- ostream.println(getLocalizedMessage("java.launcher.cls.error3",
- classname));
- throw new RuntimeException("Main method must return a value" +
- " of type void in class " +
- classname);
+ abort(ostream, null, "java.launcher.cls.error3", classname);
}
return;
}
--- a/jdk/src/share/classes/sun/launcher/resources/launcher.properties Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/launcher/resources/launcher.properties Mon Feb 14 16:30:10 2011 -0800
@@ -84,6 +84,7 @@
\ append to end of bootstrap class path\n\
\ -Xbootclasspath/p:<directories and zip/jar files separated by {0}>\n\
\ prepend in front of bootstrap class path\n\
+\ -Xdiag show additional diagnostic messages\n\
\ -Xnoclassgc disable class garbage collection\n\
\ -Xincgc enable incremental garbage collection\n\
\ -Xloggc:<file> log GC status to a file with time stamps\n\
@@ -109,7 +110,7 @@
The -X options are non-standard and subject to change without notice.\n
java.launcher.cls.error1=\
- Error: Could not find main class {0}
+ Error: Could not find or load main class {0}
java.launcher.cls.error2=\
Error: Main method is not {0} in class {1}, please define the main method as:\n\
\ public static void main(String[] args)
@@ -120,5 +121,7 @@
java.launcher.cls.error4=\
Error: Main method not found in class {0}, please define the main method as:\n\
\ public static void main(String[] args)
-
-
+java.launcher.jar.error1=\
+ Error: An unexpected error occurred while trying to open file {0}
+java.launcher.jar.error2=manifest not found in {0}
+java.launcher.jar.error3=no main manifest attribute, in {0}
--- a/jdk/src/share/classes/sun/misc/FloatingDecimal.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/misc/FloatingDecimal.java Mon Feb 14 16:30:10 2011 -0800
@@ -1547,7 +1547,7 @@
if ( (cmpResult = bigB.cmp( bigD ) ) > 0 ){
overvalue = true; // our candidate is too big.
diff = bigB.sub( bigD );
- if ( (bigIntNBits == 1) && (bigIntExp > -expBias) ){
+ if ( (bigIntNBits == 1) && (bigIntExp > -expBias+1) ){
// candidate is a normalized exact power of 2 and
// is too big. We will be subtracting.
// For our purposes, ulp is the ulp of the
--- a/jdk/src/share/classes/sun/misc/JarIndex.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/misc/JarIndex.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,6 +67,14 @@
public static final String INDEX_NAME = "META-INF/INDEX.LIST";
/**
+ * true if, and only if, sun.misc.JarIndex.metaInfFilenames is set to true.
+ * If true, the names of the files in META-INF, and its subdirectories, will
+ * be added to the index. Otherwise, just the directory names are added.
+ */
+ private static final boolean metaInfFilenames =
+ "true".equals(System.getProperty("sun.misc.JarIndex.metaInfFilenames"));
+
+ /**
* Constructs a new, empty jar index.
*/
public JarIndex() {
@@ -187,6 +195,18 @@
}
/**
+ * Same as add(String,String) except that it doesn't strip off from the
+ * last index of '/'. It just adds the filename.
+ */
+ private void addExplicit(String fileName, String jarName) {
+ // add the mapping to indexMap
+ addToList(fileName, jarName, indexMap);
+
+ // add the mapping to jarMap
+ addToList(jarName, fileName, jarMap);
+ }
+
+ /**
* Go through all the jar files and construct the
* index table.
*/
@@ -204,15 +224,31 @@
Enumeration entries = zrf.entries();
while(entries.hasMoreElements()) {
- String fileName = ((ZipEntry)(entries.nextElement())).getName();
- // Index the META-INF directory, but not the index or manifest.
- if (!fileName.startsWith("META-INF/") ||
- !(fileName.equals("META-INF/") ||
- fileName.equals(INDEX_NAME) ||
- fileName.equals(JarFile.MANIFEST_NAME))) {
+ ZipEntry entry = (ZipEntry) entries.nextElement();
+ String fileName = entry.getName();
+
+ // Skip the META-INF directory, the index, and manifest.
+ // Any files in META-INF/ will be indexed explicitly
+ if (fileName.equals("META-INF/") ||
+ fileName.equals(INDEX_NAME) ||
+ fileName.equals(JarFile.MANIFEST_NAME))
+ continue;
+
+ if (!metaInfFilenames) {
add(fileName, currentJar);
+ } else {
+ if (!fileName.startsWith("META-INF/")) {
+ add(fileName, currentJar);
+ } else if (!entry.isDirectory()) {
+ // Add files under META-INF explicitly so that certain
+ // services, like ServiceLoader, etc, can be located
+ // with greater accuracy. Directories can be skipped
+ // since each file will be added explicitly.
+ addExplicit(fileName, currentJar);
+ }
}
}
+
zrf.close();
}
}
--- a/jdk/src/share/classes/sun/misc/VM.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/misc/VM.java Mon Feb 14 16:30:10 2011 -0800
@@ -235,6 +235,9 @@
return savedProps.getProperty(key);
}
+ // TODO: the Property Management needs to be refactored and
+ // the appropriate prop keys need to be accessible to the
+ // calling classes to avoid duplication of keys.
private static final Properties savedProps = new Properties();
// Save a private copy of the system properties and remove
@@ -283,6 +286,9 @@
// used by java.util.zip.ZipFile
props.remove("sun.zip.disableMemoryMapping");
+
+ // used by sun.launcher.LauncherHelper
+ props.remove("sun.java.launcher.diag");
}
// Initialize any miscellenous operating system settings that need to be
--- a/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java Mon Feb 14 16:30:10 2011 -0800
@@ -106,6 +106,9 @@
keepAliveTimer = new Thread(grp, cache, "Keep-Alive-Timer");
keepAliveTimer.setDaemon(true);
keepAliveTimer.setPriority(Thread.MAX_PRIORITY - 2);
+ // Set the context class loader to null in order to avoid
+ // keeping a strong reference to an application classloader.
+ keepAliveTimer.setContextClassLoader(null);
keepAliveTimer.start();
return null;
}
--- a/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java Mon Feb 14 16:30:10 2011 -0800
@@ -185,6 +185,9 @@
cleanerThread = new Thread(grp, queue, "Keep-Alive-SocketCleaner");
cleanerThread.setDaemon(true);
cleanerThread.setPriority(Thread.MAX_PRIORITY - 2);
+ // Set the context class loader to null in order to avoid
+ // keeping a strong reference to an application classloader.
+ cleanerThread.setContextClassLoader(null);
cleanerThread.start();
return null;
}
--- a/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -45,15 +45,6 @@
}
@Override
- public final Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(OWNER_NAME))
- return getOwner();
- if (attribute.equals(ACL_NAME))
- return getAcl();
- return null;
- }
-
- @Override
@SuppressWarnings("unchecked")
public final void setAttribute(String attribute, Object value)
throws IOException
@@ -71,7 +62,7 @@
}
@Override
- public final Map<String,?> readAttributes(String[] attributes)
+ public final Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
boolean acl = false;
@@ -91,7 +82,7 @@
continue;
}
}
- Map<String,Object> result = new HashMap<String,Object>(2);
+ Map<String,Object> result = new HashMap<>(2);
if (acl)
result.put(ACL_NAME, getAcl());
if (owner)
--- a/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -54,30 +54,6 @@
}
@Override
- public Object getAttribute(String attribute) throws IOException {
- BasicFileAttributes attrs = readAttributes();
- if (attribute.equals(SIZE_NAME))
- return attrs.size();
- if (attribute.equals(CREATION_TIME_NAME))
- return attrs.creationTime();
- if (attribute.equals(LAST_ACCESS_TIME_NAME))
- return attrs.lastAccessTime();
- if (attribute.equals(LAST_MODIFIED_TIME_NAME))
- return attrs.lastModifiedTime();
- if (attribute.equals(FILE_KEY_NAME))
- return attrs.fileKey();
- if (attribute.equals(IS_DIRECTORY_NAME))
- return attrs.isDirectory();
- if (attribute.equals(IS_REGULAR_FILE_NAME))
- return attrs.isRegularFile();
- if (attribute.equals(IS_SYMBOLIC_LINK_NAME))
- return attrs.isSymbolicLink();
- if (attribute.equals(IS_OTHER_NAME))
- return attrs.isOther();
- return null;
- }
-
- @Override
public void setAttribute(String attribute, Object value)
throws IOException
{
@@ -101,8 +77,8 @@
* Used to build a map of attribute name/values.
*/
static class AttributesBuilder {
- private Set<String> set = new HashSet<String>();
- private Map<String,Object> map = new HashMap<String,Object>();
+ private Set<String> set = new HashSet<>();
+ private Map<String,Object> map = new HashMap<>();
private boolean copyAll;
private AttributesBuilder(String[] attributes) {
@@ -172,7 +148,7 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes) throws IOException {
+ public Map<String,Object> readAttributes(String[] attributes) throws IOException {
AttributesBuilder builder = AttributesBuilder.create(attributes);
addBasicAttributesToBuilder(readAttributes(), builder);
return builder.unmodifiableMap();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractFileSystemProvider.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Collections;
+
+/**
+ * Base implementation class of FileSystemProvider
+ */
+
+abstract class AbstractFileSystemProvider extends FileSystemProvider {
+ protected AbstractFileSystemProvider() { }
+
+ /**
+ * Splits the given attribute name into the name of an attribute view and
+ * the attribute. If the attribute view is not identified then it assumed
+ * to be "basic".
+ */
+ private static String[] split(String attribute) {
+ String[] s = new String[2];
+ int pos = attribute.indexOf(':');
+ if (pos == -1) {
+ s[0] = "basic";
+ s[1] = attribute;
+ } else {
+ s[0] = attribute.substring(0, pos++);
+ s[1] = (pos == attribute.length()) ? "" : attribute.substring(pos);
+ }
+ return s;
+ }
+
+ /**
+ * Gets a DynamicFileAttributeView by name. Returns {@code null} if the
+ * view is not available.
+ */
+ abstract DynamicFileAttributeView getFileAttributeView(Path file,
+ String name,
+ LinkOption... options);
+
+ @Override
+ public final void setAttribute(Path file,
+ String attribute,
+ Object value,
+ LinkOption... options)
+ throws IOException
+ {
+ String[] s = split(attribute);
+ DynamicFileAttributeView view = getFileAttributeView(file, s[0], options);
+ if (view == null)
+ throw new UnsupportedOperationException("View '" + s[0] + "' not available");
+ view.setAttribute(s[1], value);
+ }
+
+ @Override
+ public final Map<String,Object> readAttributes(Path file, String attributes, LinkOption... options)
+ throws IOException
+ {
+ String[] s = split(attributes);
+ DynamicFileAttributeView view = getFileAttributeView(file, s[0], options);
+ if (view == null)
+ return Collections.emptyMap();
+ return view.readAttributes(s[1].split(","));
+ }
+
+ /**
+ * Deletes a file. The {@code failIfNotExists} parameters determines if an
+ * {@code IOException} is thrown when the file does not exist.
+ */
+ abstract boolean implDelete(Path file, boolean failIfNotExists) throws IOException;
+
+ @Override
+ public final void delete(Path file) throws IOException {
+ implDelete(file, true);
+ }
+
+ @Override
+ public final boolean deleteIfExists(Path file) throws IOException {
+ return implDelete(file, false);
+ }
+}
--- a/jdk/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,7 +25,7 @@
package sun.nio.fs;
-import java.nio.file.FileRef;
+import java.nio.file.Path;
import java.nio.file.spi.FileTypeDetector;
import java.util.Locale;
import java.io.IOException;
@@ -46,7 +46,7 @@
* and checks that the content type's syntax is valid.
*/
@Override
- public final String probeContentType(FileRef file) throws IOException {
+ public final String probeContentType(Path file) throws IOException {
if (file == null)
throw new NullPointerException("'file' is null");
String result = implProbeContentType(file);
@@ -56,7 +56,7 @@
/**
* Probes the given file to guess its content type.
*/
- protected abstract String implProbeContentType(FileRef file)
+ protected abstract String implProbeContentType(Path file)
throws IOException;
/**
--- a/jdk/src/share/classes/sun/nio/fs/AbstractPath.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractPath.java Mon Feb 14 16:30:10 2011 -0800
@@ -26,391 +26,81 @@
package sun.nio.fs;
import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import java.nio.file.attribute.*;
-import java.nio.channels.*;
-import java.nio.ByteBuffer;
-import java.io.*;
-import java.util.*;
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
/**
- * Base implementation class for a {@code Path}.
+ * Base implementation class of {@code Path}.
*/
-abstract class AbstractPath extends Path {
+abstract class AbstractPath implements Path {
protected AbstractPath() { }
@Override
- public final Path createFile(FileAttribute<?>... attrs)
- throws IOException
- {
- EnumSet<StandardOpenOption> options = EnumSet.of(CREATE_NEW, WRITE);
- SeekableByteChannel sbc = newByteChannel(options, attrs);
- try {
- sbc.close();
- } catch (IOException x) {
- // ignore
- }
- return this;
- }
-
- /**
- * Deletes a file. The {@code failIfNotExists} parameters determines if an
- * {@code IOException} is thrown when the file does not exist.
- */
- abstract void implDelete(boolean failIfNotExists) throws IOException;
-
- @Override
- public final void delete() throws IOException {
- implDelete(true);
+ public final boolean startsWith(String other) {
+ return startsWith(getFileSystem().getPath(other));
}
@Override
- public final void deleteIfExists() throws IOException {
- implDelete(false);
+ public final boolean endsWith(String other) {
+ return endsWith(getFileSystem().getPath(other));
}
@Override
- public final InputStream newInputStream(OpenOption... options)
- throws IOException
- {
- if (options.length > 0) {
- for (OpenOption opt: options) {
- if (opt != READ)
- throw new UnsupportedOperationException("'" + opt + "' not allowed");
- }
- }
- return Channels.newInputStream(newByteChannel());
+ public final Path resolve(String other) {
+ return resolve(getFileSystem().getPath(other));
}
@Override
- public final OutputStream newOutputStream(OpenOption... options)
- throws IOException
- {
- int len = options.length;
- Set<OpenOption> opts = new HashSet<OpenOption>(len + 3);
- if (len == 0) {
- opts.add(CREATE);
- opts.add(TRUNCATE_EXISTING);
- } else {
- for (OpenOption opt: options) {
- if (opt == READ)
- throw new IllegalArgumentException("READ not allowed");
- opts.add(opt);
- }
- }
- opts.add(WRITE);
- return Channels.newOutputStream(newByteChannel(opts));
+ public final Path resolveSibling(Path other) {
+ if (other == null)
+ throw new NullPointerException();
+ Path parent = getParent();
+ return (parent == null) ? other : parent.resolve(other);
}
@Override
- public final SeekableByteChannel newByteChannel(OpenOption... options)
- throws IOException
- {
- Set<OpenOption> set = new HashSet<OpenOption>(options.length);
- Collections.addAll(set, options);
- return newByteChannel(set);
- }
-
- private static final DirectoryStream.Filter<Path> acceptAllFilter =
- new DirectoryStream.Filter<Path>() {
- @Override public boolean accept(Path entry) { return true; }
- };
-
- @Override
- public final DirectoryStream<Path> newDirectoryStream() throws IOException {
- return newDirectoryStream(acceptAllFilter);
+ public final Path resolveSibling(String other) {
+ return resolveSibling(getFileSystem().getPath(other));
}
@Override
- public final DirectoryStream<Path> newDirectoryStream(String glob)
- throws IOException
- {
- // avoid creating a matcher if all entries are required.
- if (glob.equals("*"))
- return newDirectoryStream();
-
- // create a matcher and return a filter that uses it.
- final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
- DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+ public final Iterator<Path> iterator() {
+ return new Iterator<Path>() {
+ private int i = 0;
+ @Override
+ public boolean hasNext() {
+ return (i < getNameCount());
+ }
@Override
- public boolean accept(Path entry) {
- return matcher.matches(entry.getName());
+ public Path next() {
+ if (i < getNameCount()) {
+ Path result = getName(i);
+ i++;
+ return result;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
}
};
- return newDirectoryStream(filter);
}
@Override
- public final boolean exists() {
- try {
- checkAccess();
- return true;
- } catch (IOException x) {
- // unable to determine if file exists
- }
- return false;
+ public final File toFile() {
+ return new File(toString());
}
@Override
- public final boolean notExists() {
- try {
- checkAccess();
- return false;
- } catch (NoSuchFileException x) {
- // file confirmed not to exist
- return true;
- } catch (IOException x) {
- return false;
- }
- }
-
- private static final WatchEvent.Modifier[] NO_MODIFIERS = new WatchEvent.Modifier[0];
-
- @Override
public final WatchKey register(WatchService watcher,
WatchEvent.Kind<?>... events)
throws IOException
{
- return register(watcher, events, NO_MODIFIERS);
- }
-
- abstract void implCopyTo(Path target, CopyOption... options)
- throws IOException;
-
- @Override
- public final Path copyTo(Path target, CopyOption... options)
- throws IOException
- {
- if ((getFileSystem().provider() == target.getFileSystem().provider())) {
- implCopyTo(target, options);
- } else {
- copyToForeignTarget(target, options);
- }
- return target;
- }
-
- abstract void implMoveTo(Path target, CopyOption... options)
- throws IOException;
-
- @Override
- public final Path moveTo(Path target, CopyOption... options)
- throws IOException
- {
- if ((getFileSystem().provider() == target.getFileSystem().provider())) {
- implMoveTo(target, options);
- } else {
- // different providers so copy + delete
- copyToForeignTarget(target, convertMoveToCopyOptions(options));
- delete();
- }
- return target;
- }
-
- /**
- * Converts the given array of options for moving a file to options suitable
- * for copying the file when a move is implemented as copy + delete.
- */
- private static CopyOption[] convertMoveToCopyOptions(CopyOption... options)
- throws AtomicMoveNotSupportedException
- {
- int len = options.length;
- CopyOption[] newOptions = new CopyOption[len+2];
- for (int i=0; i<len; i++) {
- CopyOption option = options[i];
- if (option == StandardCopyOption.ATOMIC_MOVE) {
- throw new AtomicMoveNotSupportedException(null, null,
- "Atomic move between providers is not supported");
- }
- newOptions[i] = option;
- }
- newOptions[len] = LinkOption.NOFOLLOW_LINKS;
- newOptions[len+1] = StandardCopyOption.COPY_ATTRIBUTES;
- return newOptions;
- }
-
- /**
- * Parses the arguments for a file copy operation.
- */
- private static class CopyOptions {
- boolean replaceExisting = false;
- boolean copyAttributes = false;
- boolean followLinks = true;
-
- private CopyOptions() { }
-
- static CopyOptions parse(CopyOption... options) {
- CopyOptions result = new CopyOptions();
- for (CopyOption option: options) {
- if (option == StandardCopyOption.REPLACE_EXISTING) {
- result.replaceExisting = true;
- continue;
- }
- if (option == LinkOption.NOFOLLOW_LINKS) {
- result.followLinks = false;
- continue;
- }
- if (option == StandardCopyOption.COPY_ATTRIBUTES) {
- result.copyAttributes = true;
- continue;
- }
- if (option == null)
- throw new NullPointerException();
- throw new UnsupportedOperationException("'" + option +
- "' is not a recognized copy option");
- }
- return result;
- }
- }
-
- /**
- * Simple cross-provider copy where the target is a Path.
- */
- private void copyToForeignTarget(Path target, CopyOption... options)
- throws IOException
- {
- CopyOptions opts = CopyOptions.parse(options);
- LinkOption[] linkOptions = (opts.followLinks) ? new LinkOption[0] :
- new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
-
- // attributes of source file
- BasicFileAttributes attrs = Attributes
- .readBasicFileAttributes(this, linkOptions);
- if (attrs.isSymbolicLink())
- throw new IOException("Copying of symbolic links not supported");
-
- // check if target exists
- boolean exists;
- if (opts.replaceExisting) {
- try {
- target.deleteIfExists();
- exists = false;
- } catch (DirectoryNotEmptyException x) {
- // let exception translate to FileAlreadyExistsException (6895012)
- exists = true;
- }
- } else {
- exists = target.exists();
- }
- if (exists)
- throw new FileAlreadyExistsException(target.toString());
-
- // create directory or file
- if (attrs.isDirectory()) {
- target.createDirectory();
- } else {
- copyRegularFileToForeignTarget(target);
- }
-
- // copy basic attributes to target
- if (opts.copyAttributes) {
- BasicFileAttributeView view = target
- .getFileAttributeView(BasicFileAttributeView.class, linkOptions);
- try {
- view.setTimes(attrs.lastModifiedTime(),
- attrs.lastAccessTime(),
- attrs.creationTime());
- } catch (IOException x) {
- // rollback
- try {
- target.delete();
- } catch (IOException ignore) { }
- throw x;
- }
- }
- }
-
-
- /**
- * Simple copy of regular file to a target file that exists.
- */
- private void copyRegularFileToForeignTarget(Path target)
- throws IOException
- {
- ReadableByteChannel rbc = newByteChannel();
- try {
- // open target file for writing
- SeekableByteChannel sbc = target.newByteChannel(CREATE_NEW, WRITE);
-
- // simple copy loop
- try {
- ByteBuffer buf = ByteBuffer.wrap(new byte[8192]);
- int n = 0;
- for (;;) {
- n = rbc.read(buf);
- if (n < 0)
- break;
- assert n > 0;
- buf.flip();
- while (buf.hasRemaining()) {
- sbc.write(buf);
- }
- buf.rewind();
- }
-
- } finally {
- sbc.close();
- }
- } finally {
- rbc.close();
- }
- }
-
- /**
- * Splits the given attribute name into the name of an attribute view and
- * the attribute. If the attribute view is not identified then it assumed
- * to be "basic".
- */
- private static String[] split(String attribute) {
- String[] s = new String[2];
- int pos = attribute.indexOf(':');
- if (pos == -1) {
- s[0] = "basic";
- s[1] = attribute;
- } else {
- s[0] = attribute.substring(0, pos++);
- s[1] = (pos == attribute.length()) ? "" : attribute.substring(pos);
- }
- return s;
- }
-
- /**
- * Gets a DynamicFileAttributeView by name. Returns {@code null} if the
- * view is not available.
- */
- abstract DynamicFileAttributeView getFileAttributeView(String name,
- LinkOption... options);
-
- @Override
- public final void setAttribute(String attribute,
- Object value,
- LinkOption... options)
- throws IOException
- {
- String[] s = split(attribute);
- DynamicFileAttributeView view = getFileAttributeView(s[0], options);
- if (view == null)
- throw new UnsupportedOperationException("View '" + s[0] + "' not available");
- view.setAttribute(s[1], value);
- }
-
- @Override
- public final Object getAttribute(String attribute, LinkOption... options)
- throws IOException
- {
- String[] s = split(attribute);
- DynamicFileAttributeView view = getFileAttributeView(s[0], options);
- return (view == null) ? null : view.getAttribute(s[1]);
- }
-
- @Override
- public final Map<String,?> readAttributes(String attributes, LinkOption... options)
- throws IOException
- {
- String[] s = split(attributes);
- DynamicFileAttributeView view = getFileAttributeView(s[0], options);
- if (view == null)
- return Collections.emptyMap();
- return view.readAttributes(s[1].split(","));
+ return register(watcher, events, new WatchEvent.Modifier[0]);
}
}
--- a/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java Mon Feb 14 16:30:10 2011 -0800
@@ -92,7 +92,7 @@
/**
* Requests, and waits on, poller thread to register given file.
*/
- final WatchKey register(FileRef dir,
+ final WatchKey register(Path dir,
WatchEvent.Kind<?>[] events,
WatchEvent.Modifier... modifiers)
throws IOException
@@ -102,7 +102,7 @@
throw new NullPointerException();
if (events.length == 0)
throw new IllegalArgumentException("No events to register");
- Set<WatchEvent.Kind<?>> eventSet = new HashSet<WatchEvent.Kind<?>>(events.length);
+ Set<WatchEvent.Kind<?>> eventSet = new HashSet<>(events.length);
for (WatchEvent.Kind<?> event: events) {
// standard events
if (event == StandardWatchEventKind.ENTRY_CREATE ||
--- a/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -59,8 +59,7 @@
return "user";
}
- @Override
- public final Object getAttribute(String attribute) throws IOException {
+ private Object getAttribute(String attribute) throws IOException {
int size;
try {
size = size(attribute);
@@ -90,11 +89,11 @@
}
@Override
- public final Map<String,?> readAttributes(String[] attributes)
+ public final Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
// names of attributes to return
- List<String> names = new ArrayList<String>();
+ List<String> names = new ArrayList<>();
for (String name: attributes) {
if (name.equals("*")) {
@@ -106,7 +105,7 @@
}
// read each value and return in map
- Map<String,Object> result = new HashMap<String,Object>();
+ Map<String,Object> result = new HashMap<>();
for (String name: names) {
Object value = getAttribute(name);
if (value != null)
--- a/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java Mon Feb 14 16:30:10 2011 -0800
@@ -32,7 +32,7 @@
* Base implementation class for watch keys.
*/
-abstract class AbstractWatchKey extends WatchKey {
+abstract class AbstractWatchKey implements WatchKey {
/**
* Maximum size of event list (in the future this may be tunable)
@@ -53,6 +53,9 @@
// reference to watcher
private final AbstractWatchService watcher;
+ // reference to the original directory
+ private final Path dir;
+
// key state
private State state;
@@ -63,8 +66,9 @@
// event for the context is an ENTRY_MODIFY event).
private Map<Object,WatchEvent<?>> lastModifyEvents;
- protected AbstractWatchKey(AbstractWatchService watcher) {
+ protected AbstractWatchKey(Path dir, AbstractWatchService watcher) {
this.watcher = watcher;
+ this.dir = dir;
this.state = State.READY;
this.events = new ArrayList<WatchEvent<?>>();
this.lastModifyEvents = new HashMap<Object,WatchEvent<?>>();
@@ -75,6 +79,13 @@
}
/**
+ * Return the original watchable (Path)
+ */
+ Path watchable() {
+ return dir;
+ }
+
+ /**
* Enqueues this key to the watch service
*/
final void signal() {
@@ -175,7 +186,7 @@
/**
* WatchEvent implementation
*/
- private static class Event<T> extends WatchEvent<T> {
+ private static class Event<T> implements WatchEvent<T> {
private final WatchEvent.Kind<T> kind;
private final T context;
--- a/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java Mon Feb 14 16:30:10 2011 -0800
@@ -33,7 +33,7 @@
* Base implementation class for watch services.
*/
-abstract class AbstractWatchService extends WatchService {
+abstract class AbstractWatchService implements WatchService {
// signaled keys waiting to be dequeued
private final LinkedBlockingDeque<WatchKey> pendingKeys =
@@ -41,7 +41,7 @@
// special key to indicate that watch service is closed
private final WatchKey CLOSE_KEY =
- new AbstractWatchKey(null) {
+ new AbstractWatchKey(null, null) {
@Override
public boolean isValid() {
return true;
@@ -54,7 +54,7 @@
// used when closing watch service
private volatile boolean closed;
- private Object closeLock = new Object();
+ private final Object closeLock = new Object();
protected AbstractWatchService() {
}
@@ -93,7 +93,7 @@
}
@Override
- public final WatchKey poll() {
+ public final WatchKey poll() {
checkOpen();
WatchKey key = pendingKeys.poll();
checkKey(key);
--- a/jdk/src/share/classes/sun/nio/fs/DynamicFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/DynamicFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -35,11 +35,6 @@
interface DynamicFileAttributeView {
/**
- * Reads the value of an attribute.
- */
- Object getAttribute(String attribute) throws IOException;
-
- /**
* Sets/updates the value of an attribute.
*/
void setAttribute(String attribute, Object value) throws IOException;
@@ -47,5 +42,5 @@
/**
* Reads a set of file attributes as a bulk operation.
*/
- Map<String,?> readAttributes(String[] attributes) throws IOException;
+ Map<String,Object> readAttributes(String[] attributes) throws IOException;
}
--- a/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java Mon Feb 14 16:30:10 2011 -0800
@@ -58,13 +58,6 @@
}
@Override
- public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(OWNER_NAME))
- return getOwner();
- return null;
- }
-
- @Override
public void setAttribute(String attribute, Object value)
throws IOException
{
@@ -77,8 +70,8 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes) throws IOException {
- Map<String,Object> result = new HashMap<String,Object>();
+ public Map<String,Object> readAttributes(String[] attributes) throws IOException {
+ Map<String,Object> result = new HashMap<>();
for (String attribute: attributes) {
if (attribute.equals("*") || attribute.equals(OWNER_NAME)) {
result.put(OWNER_NAME, getOwner());
--- a/jdk/src/share/classes/sun/nio/fs/PollingWatchService.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/PollingWatchService.java Mon Feb 14 16:30:10 2011 -0800
@@ -146,7 +146,7 @@
throws IOException
{
// check file is a directory and get its file key if possible
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path);
+ BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
if (!attrs.isDirectory()) {
throw new NotDirectoryException(path.toString());
}
@@ -164,7 +164,7 @@
watchKey = map.get(fileKey);
if (watchKey == null) {
// new registration
- watchKey = new PollingWatchKey(this, path, fileKey);
+ watchKey = new PollingWatchKey(path, this, fileKey);
map.put(fileKey, watchKey);
} else {
// update to existing registration
@@ -228,7 +228,6 @@
* directory and queue keys when entries are added, modified, or deleted.
*/
private class PollingWatchKey extends AbstractWatchKey {
- private final Path dir;
private final Object fileKey;
// current event set
@@ -246,44 +245,28 @@
// map of entries in directory
private Map<Path,CacheEntry> entries;
- PollingWatchKey(PollingWatchService watcher,
- Path dir,
- Object fileKey)
+ PollingWatchKey(Path dir, PollingWatchService watcher, Object fileKey)
throws IOException
{
- super(watcher);
- this.dir = dir;
+ super(dir, watcher);
this.fileKey = fileKey;
this.valid = true;
this.tickCount = 0;
this.entries = new HashMap<Path,CacheEntry>();
// get the initial entries in the directory
- DirectoryStream<Path> stream = dir.newDirectoryStream();
- try {
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path entry: stream) {
// don't follow links
- long lastModified = Attributes
- .readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
- .lastModifiedTime().toMillis();
- entries.put(entry.getName(),
- new CacheEntry(lastModified, tickCount));
+ long lastModified =
+ Files.getLastModifiedTime(entry, LinkOption.NOFOLLOW_LINKS).toMillis();
+ entries.put(entry.getFileName(), new CacheEntry(lastModified, tickCount));
}
- } catch (ConcurrentModificationException cme) {
- // thrown if directory iteration fails
- Throwable cause = cme.getCause();
- if (cause != null && cause instanceof IOException)
- throw (IOException)cause;
- throw new AssertionError(cme);
- } finally {
- stream.close();
+ } catch (DirectoryIteratorException e) {
+ throw e.getCause();
}
}
- FileRef directory() {
- return dir;
- }
-
Object fileKey() {
return fileKey;
}
@@ -342,7 +325,7 @@
// open directory
DirectoryStream<Path> stream = null;
try {
- stream = dir.newDirectoryStream();
+ stream = Files.newDirectoryStream(watchable());
} catch (IOException x) {
// directory is no longer accessible so cancel key
cancel();
@@ -355,9 +338,8 @@
for (Path entry: stream) {
long lastModified = 0L;
try {
- lastModified = Attributes
- .readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
- .lastModifiedTime().toMillis();
+ lastModified =
+ Files.getLastModifiedTime(entry, LinkOption.NOFOLLOW_LINKS).toMillis();
} catch (IOException x) {
// unable to get attributes of entry. If file has just
// been deleted then we'll report it as deleted on the
@@ -366,15 +348,15 @@
}
// lookup cache
- CacheEntry e = entries.get(entry.getName());
+ CacheEntry e = entries.get(entry.getFileName());
if (e == null) {
// new file found
- entries.put(entry.getName(),
+ entries.put(entry.getFileName(),
new CacheEntry(lastModified, tickCount));
// queue ENTRY_CREATE if event enabled
if (events.contains(StandardWatchEventKind.ENTRY_CREATE)) {
- signalEvent(StandardWatchEventKind.ENTRY_CREATE, entry.getName());
+ signalEvent(StandardWatchEventKind.ENTRY_CREATE, entry.getFileName());
continue;
} else {
// if ENTRY_CREATE is not enabled and ENTRY_MODIFY is
@@ -382,7 +364,7 @@
// modifications to the file immediately after it is
// created.
if (events.contains(StandardWatchEventKind.ENTRY_MODIFY)) {
- signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getName());
+ signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getFileName());
}
}
continue;
@@ -391,15 +373,17 @@
// check if file has changed
if (e.lastModified != lastModified) {
if (events.contains(StandardWatchEventKind.ENTRY_MODIFY)) {
- signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getName());
+ signalEvent(StandardWatchEventKind.ENTRY_MODIFY,
+ entry.getFileName());
}
}
// entry in cache so update poll time
e.update(lastModified, tickCount);
}
- } catch (ConcurrentModificationException x) {
- // FIXME - should handle this
+ } catch (DirectoryIteratorException e) {
+ // ignore for now; if the directory is no longer accessible
+ // then the key will be cancelled on the next poll
} finally {
// close directory stream
--- a/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java Mon Feb 14 16:30:10 2011 -0800
@@ -173,7 +173,7 @@
}
Credentials getCreds() {
- return Objects.nonNull(creds, "Creds not available yet.");
+ return Objects.requireNonNull(creds, "Creds not available yet.");
}
sun.security.krb5.internal.ccache.Credentials getCCreds() {
--- a/jdk/src/share/classes/sun/security/provider/SeedGenerator.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/security/provider/SeedGenerator.java Mon Feb 14 16:30:10 2011 -0800
@@ -63,13 +63,14 @@
* @author Gadi Guy
*/
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
import java.security.*;
import java.io.*;
import java.util.Properties;
import java.util.Enumeration;
import java.net.*;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Random;
import sun.security.util.Debug;
@@ -177,37 +178,21 @@
// The temporary dir
File f = new File(p.getProperty("java.io.tmpdir"));
-
- // Go thru files in the tmp dir using NIO's
- // DirectoryStream. Fallback to File.list()
- // if NIO is not available.
- if (NIODirectoryStream.isAvailable()) {
- int count = 0;
- Iterable<?> stream =
- NIODirectoryStream.newDirectoryStream(f);
+ int count = 0;
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(f.toPath())) {
// We use a Random object to choose what file names
// should be used. Otherwise on a machine with too
// many files, the same first 1024 files always get
// used. Any, We make sure the first 512 files are
// always used.
Random r = new Random();
- try {
- for (Object entry: stream) {
- if (count < 512 || r.nextBoolean()) {
- md.update(NIODirectoryStream.getName(
- entry).getBytes());
- }
- if (count++ > 1024) {
- break;
- }
+ for (Path entry: stream) {
+ if (count < 512 || r.nextBoolean()) {
+ md.update(entry.getFileName().toString().getBytes());
}
- } finally {
- ((Closeable)stream).close();
- }
- } else {
- String[] sa = f.list();
- for(int i = 0; i < sa.length; i++) {
- md.update(sa[i].getBytes());
+ if (count++ > 1024) {
+ break;
+ }
}
}
} catch (Exception ex) {
@@ -553,77 +538,4 @@
}
}
-
- /**
- * A wrapper of NIO DirectoryStream using reflection.
- */
- private static class NIODirectoryStream {
- private static final Class<?> pathClass =
- getClass("java.nio.file.Path");
-
- private static final Method toPathMethod =
- (pathClass == null) ? null : getMethod(File.class, "toPath");
- private static final Method getNameMethod =
- getMethod(pathClass, "getName");
- private static final Method newDirectoryStreamMethod =
- getMethod(pathClass, "newDirectoryStream");
-
- private static Class<?> getClass(String name) {
- try {
- return Class.forName(name, true, null);
- } catch (ClassNotFoundException e) {
- return null;
- }
- }
-
- private static Method getMethod(Class<?> clazz,
- String name,
- Class<?>... paramTypes) {
- if (clazz != null) {
- try {
- return clazz.getMethod(name, paramTypes);
- } catch (NoSuchMethodException e) {
- throw new AssertionError(e);
- }
- } else {
- return null;
- }
- }
-
- static boolean isAvailable() {
- return pathClass != null;
- }
-
- static Iterable<?> newDirectoryStream(File dir) throws IOException {
- assert pathClass != null;
- try {
- Object path = toPathMethod.invoke(dir);
- return (Iterable<?>)newDirectoryStreamMethod.invoke(path);
- } catch (InvocationTargetException e) {
- Throwable cause = e.getCause();
- if (cause instanceof IOException)
- throw (IOException)cause;
- if (cause instanceof RuntimeException)
- throw (RuntimeException)cause;
- if (cause instanceof Error)
- throw (Error)cause;
- throw new AssertionError(e);
- } catch (IllegalAccessException iae) {
- throw new AssertionError(iae);
- }
- }
-
- static String getName(Object path) {
- assert pathClass != null;
- try {
- Object name = getNameMethod.invoke(path);
- return name.toString();
- } catch (InvocationTargetException e) {
- throw new AssertionError(e);
- } catch (IllegalAccessException iae) {
- throw new AssertionError(iae);
- }
- }
- }
}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.provider.certpath;
+
+import java.io.IOException;
+import java.util.Date;
+
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.cert.X509CertSelector;
+import java.security.cert.CertificateException;
+
+import sun.security.util.DerOutputStream;
+import sun.security.x509.SerialNumber;
+import sun.security.x509.KeyIdentifier;
+import sun.security.x509.AuthorityKeyIdentifierExtension;
+
+/**
+ * An adaptable X509 certificate selector for forward certification path
+ * building.
+ *
+ * @since 1.7
+ */
+class AdaptableX509CertSelector extends X509CertSelector {
+ // The start date of a validity period.
+ private Date startDate = null;
+
+ // The end date of a validity period.
+ private Date endDate = null;
+
+ AdaptableX509CertSelector() {
+ super();
+ }
+
+ /**
+ * Sets the criterion of the X509Certificate validity period.
+ *
+ * Normally, we may not have to check that a certificate validity period
+ * must fall within its issuer's certificate validity period. However,
+ * when we face root CA key updates for version 1 certificates, according
+ * to scheme of RFC 4210 or 2510, the validity periods should be checked
+ * to determine the right issuer's certificate.
+ *
+ * Conservatively, we will only check the validity periods for version
+ * 1 and version 2 certificates. For version 3 certificates, we can
+ * determine the right issuer by authority and subject key identifier
+ * extensions.
+ *
+ * @param startDate the start date of a validity period that must fall
+ * within the certificate validity period for the X509Certificate
+ * @param endDate the end date of a validity period that must fall
+ * within the certificate validity period for the X509Certificate
+ */
+ void setValidityPeriod(Date startDate, Date endDate) {
+ this.startDate = startDate;
+ this.endDate = endDate;
+ }
+
+ /**
+ * Parse the authority key identifier extension.
+ *
+ * If the keyIdentifier field of the extension is non-null, set the
+ * subjectKeyIdentifier criterion. If the authorityCertSerialNumber
+ * field is non-null, set the serialNumber criterion.
+ *
+ * Note that we will not set the subject criterion according to the
+ * authorityCertIssuer field of the extension. The caller MUST set
+ * the subject criterion before call match().
+ *
+ * @param akidext the authorityKeyIdentifier extension
+ */
+ void parseAuthorityKeyIdentifierExtension(
+ AuthorityKeyIdentifierExtension akidext) throws IOException {
+ if (akidext != null) {
+ KeyIdentifier akid = (KeyIdentifier)akidext.get(akidext.KEY_ID);
+ if (akid != null) {
+ DerOutputStream derout = new DerOutputStream();
+ derout.putOctetString(akid.getIdentifier());
+ super.setSubjectKeyIdentifier(derout.toByteArray());
+ }
+
+ SerialNumber asn =
+ (SerialNumber)akidext.get(akidext.SERIAL_NUMBER);
+ if (asn != null) {
+ super.setSerialNumber(asn.getNumber());
+ }
+
+ // the subject criterion should be set by the caller.
+ }
+ }
+
+ /**
+ * Decides whether a <code>Certificate</code> should be selected.
+ *
+ * For the purpose of compatibility, when a certificate is of
+ * version 1 and version 2, or the certificate does not include
+ * a subject key identifier extension, the selection criterion
+ * of subjectKeyIdentifier will be disabled.
+ */
+ @Override
+ public boolean match(Certificate cert) {
+ if (!(cert instanceof X509Certificate)) {
+ return false;
+ }
+
+ X509Certificate xcert = (X509Certificate)cert;
+ int version = xcert.getVersion();
+
+ // Check the validity period for version 1 and 2 certificate.
+ if (version < 3) {
+ if (startDate != null) {
+ try {
+ xcert.checkValidity(startDate);
+ } catch (CertificateException ce) {
+ return false;
+ }
+ }
+
+ if (endDate != null) {
+ try {
+ xcert.checkValidity(endDate);
+ } catch (CertificateException ce) {
+ return false;
+ }
+ }
+ }
+
+ if (version < 3 || xcert.getExtensionValue("2.5.29.14") == null) {
+ // If no SubjectKeyIdentifier extension, don't bother to check it.
+ setSubjectKeyIdentifier(null);
+ }
+
+ return super.match(cert);
+ }
+
+ @Override
+ public Object clone() {
+ AdaptableX509CertSelector copy =
+ (AdaptableX509CertSelector)super.clone();
+ if (startDate != null) {
+ copy.startDate = (Date)startDate.clone();
+ }
+
+ if (endDate != null) {
+ copy.endDate = (Date)endDate.clone();
+ }
+
+ return copy;
+ }
+}
--- a/jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,8 @@
import java.security.cert.CRLException;
import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertPathValidatorException.BasicReason;
+import java.security.cert.PKIXReason;
import java.io.IOException;
import java.security.interfaces.*;
import java.security.spec.*;
@@ -196,14 +198,16 @@
SIGNATURE_PRIMITIVE_SET,
currSigAlg, currSigAlgParams)) {
throw new CertPathValidatorException(
- "Algorithm constraints check failed: " + currSigAlg);
+ "Algorithm constraints check failed: " + currSigAlg,
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
// check the key usage and key size
boolean[] keyUsage = x509Cert.getKeyUsage();
if (keyUsage != null && keyUsage.length < 9) {
throw new CertPathValidatorException(
- "incorrect KeyUsage extension");
+ "incorrect KeyUsage extension",
+ null, null, -1, PKIXReason.INVALID_KEY_USAGE);
}
if (keyUsage != null) {
@@ -236,7 +240,8 @@
if (!primitives.isEmpty()) {
if (!constraints.permits(primitives, currPubKey)) {
throw new CertPathValidatorException(
- "algorithm constraints check failed");
+ "algorithm constraints check failed",
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
}
@@ -248,7 +253,8 @@
SIGNATURE_PRIMITIVE_SET,
currSigAlg, prevPubKey, currSigAlgParams)) {
throw new CertPathValidatorException(
- "Algorithm constraints check failed: " + currSigAlg);
+ "Algorithm constraints check failed: " + currSigAlg,
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -258,7 +264,7 @@
// Inherit DSA parameters from previous key
if (!(prevPubKey instanceof DSAPublicKey)) {
throw new CertPathValidatorException("Input key is not " +
- "of a appropriate type for inheriting parameters");
+ "of a appropriate type for inheriting parameters");
}
DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
@@ -352,7 +358,8 @@
if (!certPathDefaultConstraints.permits(
SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
throw new CertPathValidatorException(
- "algorithm check failed: " + sigAlgName + " is disabled");
+ "algorithm check failed: " + sigAlgName + " is disabled",
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -317,7 +317,7 @@
// we accept the case that a CRL issuer provide status
// information for itself.
- if (ForwardBuilder.issues(certImpl, crlImpl, provider)) {
+ if (issues(certImpl, crlImpl, provider)) {
// reset the public key used to verify the CRL's signature
prevKey = certImpl.getPublicKey();
} else {
@@ -338,7 +338,7 @@
if (!Arrays.equals(certAKID, crlAKID)) {
// we accept the case that a CRL issuer provide status
// information for itself.
- if (ForwardBuilder.issues(certImpl, crlImpl, provider)) {
+ if (issues(certImpl, crlImpl, provider)) {
// reset the public key used to verify the CRL's signature
prevKey = certImpl.getPublicKey();
} else {
@@ -687,4 +687,41 @@
fullNames.add(new GeneralName(fullName));
return fullNames;
}
+
+ /** Verifies whether a CRL is issued by a certain certificate
+ *
+ * @param cert the certificate
+ * @param crl the CRL to be verified
+ * @param provider the name of the signature provider
+ */
+ private static boolean issues(X509CertImpl cert, X509CRLImpl crl,
+ String provider) throws IOException {
+
+ AdaptableX509CertSelector issuerSelector =
+ new AdaptableX509CertSelector();
+
+ // check certificate's key usage
+ boolean[] usages = cert.getKeyUsage();
+ if (usages != null) {
+ usages[6] = true; // cRLSign
+ issuerSelector.setKeyUsage(usages);
+ }
+
+ // check certificate's subject
+ X500Principal crlIssuer = crl.getIssuerX500Principal();
+ issuerSelector.setSubject(crlIssuer);
+
+ /*
+ * Facilitate certification path construction with authority
+ * key identifier and subject key identifier.
+ *
+ * In practice, conforming CAs MUST use the key identifier method,
+ * and MUST include authority key identifier extension in all CRLs
+ * issued. [section 5.2.1, RFC 2459]
+ */
+ issuerSelector.parseAuthorityKeyIdentifierExtension(
+ crl.getAuthKeyIdExtension());
+
+ return issuerSelector.match(cert);
+ }
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,7 +77,7 @@
private final Set<X500Principal> trustedSubjectDNs;
private final Set<TrustAnchor> trustAnchors;
private X509CertSelector eeSelector;
- private X509CertSelector caSelector;
+ private AdaptableX509CertSelector caSelector;
private X509CertSelector caTargetSelector;
TrustAnchor trustAnchor;
private Comparator<X509Certificate> comparator;
@@ -230,9 +230,11 @@
targetCertConstraints.clone();
/*
- * Match on certificate validity date
+ * Since we don't check the validity period of trusted
+ * certificates, please don't set the certificate valid
+ * criterion unless the trusted certificate matching is
+ * completed.
*/
- caTargetSelector.setCertificateValid(date);
/*
* Policy processing optimizations
@@ -246,17 +248,19 @@
* at least as many CA certs that have already been traversed
*/
caTargetSelector.setBasicConstraints(currentState.traversedCACerts);
+
sel = caTargetSelector;
-
} else {
if (caSelector == null) {
caSelector = new AdaptableX509CertSelector();
/*
- * Match on certificate validity date.
+ * Since we don't check the validity period of trusted
+ * certificates, please don't set the certificate valid
+ * criterion unless the trusted certificate matching is
+ * completed.
*/
- caSelector.setCertificateValid(date);
/*
* Policy processing optimizations
@@ -290,42 +294,19 @@
*/
AuthorityKeyIdentifierExtension akidext =
currentState.cert.getAuthorityKeyIdentifierExtension();
- if (akidext != null) {
- KeyIdentifier akid = (KeyIdentifier)akidext.get(akidext.KEY_ID);
- if (akid != null) {
- DerOutputStream derout = new DerOutputStream();
- derout.putOctetString(akid.getIdentifier());
- caSelector.setSubjectKeyIdentifier(derout.toByteArray());
- }
+ caSelector.parseAuthorityKeyIdentifierExtension(akidext);
- SerialNumber asn =
- (SerialNumber)akidext.get(akidext.SERIAL_NUMBER);
- if (asn != null) {
- caSelector.setSerialNumber(asn.getNumber());
- }
- // the subject criterion was set previously.
- }
+ /*
+ * check the validity period
+ */
+ caSelector.setValidityPeriod(currentState.cert.getNotBefore(),
+ currentState.cert.getNotAfter());
sel = caSelector;
}
- /*
- * Check if any of the trusted certs could be a match.
- * Since we are not validating the trusted cert, we can't
- * re-use the selector we've built up (sel) - we need
- * to use a new selector (trustedSel)
- */
- X509CertSelector trustedSel = null;
- if (currentState.isInitial()) {
- trustedSel = targetCertConstraints;
- } else {
- trustedSel = new X509CertSelector();
- trustedSel.setSubject(currentState.issuerDN);
- }
-
- boolean foundMatchingCert = false;
for (X509Certificate trustedCert : trustedCerts) {
- if (trustedSel.match(trustedCert)) {
+ if (sel.match(trustedCert)) {
if (debug != null) {
debug.println("ForwardBuilder.getMatchingCACerts: "
+ "found matching trust anchor");
@@ -336,6 +317,11 @@
}
}
+ /*
+ * The trusted certificate matching is completed. We need to match
+ * on certificate validity date.
+ */
+ sel.setCertificateValid(date);
/*
* If we have already traversed as many CA certs as the maxPathLength
@@ -348,8 +334,8 @@
(buildParams.getMaxPathLength() == -1) ||
(buildParams.getMaxPathLength() > currentState.traversedCACerts))
{
- if (addMatchingCerts(sel, certStores, caCerts, searchAllCertStores)
- && !searchAllCertStores) {
+ if (addMatchingCerts(sel, certStores,
+ caCerts, searchAllCertStores) && !searchAllCertStores) {
return;
}
}
@@ -939,120 +925,4 @@
void removeFinalCertFromPath(LinkedList<X509Certificate> certPathList) {
certPathList.removeFirst();
}
-
- /** Verifies whether a CRL is issued by a certain certificate
- *
- * @param cert the certificate
- * @param crl the CRL to be verified
- * @param provider the name of the signature provider
- */
- static boolean issues(X509CertImpl cert, X509CRLImpl crl, String provider)
- throws IOException {
-
- boolean kidmatched = false;
-
- // check certificate's key usage
- boolean[] usages = cert.getKeyUsage();
- if (usages != null && !usages[6]) {
- return false;
- }
-
- // check certificate's SKID and CRL's AKID
- AuthorityKeyIdentifierExtension akidext = crl.getAuthKeyIdExtension();
- if (akidext != null) {
- // the highest priority, matching KID
- KeyIdentifier akid = (KeyIdentifier)akidext.get(akidext.KEY_ID);
- if (akid != null) {
- SubjectKeyIdentifierExtension skidext =
- cert.getSubjectKeyIdentifierExtension();
- if (skidext != null) {
- KeyIdentifier skid =
- (KeyIdentifier)skidext.get(skidext.KEY_ID);
- if (!akid.equals(skid)) {
- return false;
- }
-
- kidmatched = true;
- }
- // conservatively, in case of X509 V1 certificate,
- // does return false here if no SKID extension.
- }
-
- // the medium priority, matching issuer name/serial number
- SerialNumber asn = (SerialNumber)akidext.get(akidext.SERIAL_NUMBER);
- GeneralNames anames = (GeneralNames)akidext.get(akidext.AUTH_NAME);
- if (asn != null && anames != null) {
- X500Name subject = (X500Name)cert.getSubjectDN();
- BigInteger serial = cert.getSerialNumber();
-
- if (serial != null && subject != null) {
- if (serial.equals(asn.getNumber())) {
- return false;
- }
-
- for (GeneralName name : anames.names()) {
- GeneralNameInterface gni = name.getName();
- if (subject.equals(gni)) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- if (kidmatched) {
- return true;
- }
- }
-
- // the last priority, verify the CRL signature with the cert.
- X500Principal crlIssuer = crl.getIssuerX500Principal();
- X500Principal certSubject = cert.getSubjectX500Principal();
- if (certSubject != null && certSubject.equals(crlIssuer)) {
- try {
- crl.verify(cert.getPublicKey(), provider);
- return true;
- } catch (Exception e) {
- // ignore all exceptions.
- }
- }
-
- return false;
- }
-
- /**
- * An adaptable X509 certificate selector for forward certification path
- * building.
- */
- private static class AdaptableX509CertSelector extends X509CertSelector {
- public AdaptableX509CertSelector() {
- super();
- }
-
- /**
- * Decides whether a <code>Certificate</code> should be selected.
- *
- * For the purpose of compatibility, when a certificate is of
- * version 1 and version 2, or the certificate does not include
- * a subject key identifier extension, the selection criterion
- * of subjectKeyIdentifier will be disabled.
- *
- * @Override
- */
- public boolean match(Certificate cert) {
- if (!(cert instanceof X509Certificate)) {
- return false;
- }
- X509Certificate xcert = (X509Certificate)cert;
-
- if (xcert.getVersion() < 3 ||
- xcert.getExtensionValue("2.5.29.14") == null) {
- // disable the subjectKeyIdentifier criterion
- setSubjectKeyIdentifier(null);
- }
-
- return super.match(cert);
- }
- }
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,6 +50,9 @@
import sun.security.action.GetBooleanSecurityPropertyAction;
import sun.security.util.Debug;
+import sun.security.x509.X509CertImpl;
+
+
/**
* This class implements the PKIX validation algorithm for certification
* paths consisting exclusively of <code>X509Certificates</code>. It uses
@@ -162,6 +165,7 @@
debug.println("PKIXCertPathValidator.engineValidate() "
+ "anchor.getTrustedCert() != null");
}
+
// if this trust anchor is not worth trying,
// we move on to the next one
if (!isWorthTrying(trustedCert, firstCert)) {
@@ -211,8 +215,10 @@
* worth trying to validate in the chain.
*/
private boolean isWorthTrying(X509Certificate trustedCert,
- X509Certificate firstCert)
- {
+ X509Certificate firstCert) {
+
+ boolean worthy = false;
+
if (debug != null) {
debug.println("PKIXCertPathValidator.isWorthTrying() checking "
+ "if this trusted cert is worth trying ...");
@@ -222,19 +228,46 @@
return true;
}
- // the subject of the trusted cert should match the
- // issuer of the first cert in the certpath
+ AdaptableX509CertSelector issuerSelector =
+ new AdaptableX509CertSelector();
+
+ // check trusted certificate's key usage
+ boolean[] usages = trustedCert.getKeyUsage();
+ if (usages != null) {
+ usages[5] = true; // keyCertSign
+ issuerSelector.setKeyUsage(usages);
+ }
+
+ // check trusted certificate's subject
+ issuerSelector.setSubject(firstCert.getIssuerX500Principal());
+
+ // check the validity period
+ issuerSelector.setValidityPeriod(firstCert.getNotBefore(),
+ firstCert.getNotAfter());
- X500Principal trustedSubject = trustedCert.getSubjectX500Principal();
- if (trustedSubject.equals(firstCert.getIssuerX500Principal())) {
- if (debug != null)
+ /*
+ * Facilitate certification path construction with authority
+ * key identifier and subject key identifier.
+ */
+ try {
+ X509CertImpl firstCertImpl = X509CertImpl.toImpl(firstCert);
+ issuerSelector.parseAuthorityKeyIdentifierExtension(
+ firstCertImpl.getAuthorityKeyIdentifierExtension());
+
+ worthy = issuerSelector.match(trustedCert);
+ } catch (Exception e) {
+ // It is not worth trying.
+ }
+
+ if (debug != null) {
+ if (worthy) {
debug.println("YES - try this trustedCert");
- return true;
- } else {
- if (debug != null)
+ } else {
debug.println("NO - don't try this trustedCert");
- return false;
+ }
}
+
+ return worthy;
}
/**
--- a/jdk/src/share/classes/sun/security/validator/SimpleValidator.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/security/validator/SimpleValidator.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -156,8 +156,8 @@
// check certificate algorithm
try {
- // Algorithm checker don't care about the unresolved critical
- // extensions.
+ // Algorithm checker does not care about the unresolved
+ // critical extensions.
defaultAlgChecker.check(cert, Collections.<String>emptySet());
if (appAlgChecker != null) {
appAlgChecker.check(cert, Collections.<String>emptySet());
--- a/jdk/src/share/classes/sun/swing/AccumulativeRunnable.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/swing/AccumulativeRunnable.java Mon Feb 14 16:30:10 2011 -0800
@@ -120,6 +120,7 @@
* {@code Runnable} for execution.
* @param args the arguments to accumulate
*/
+ @SafeVarargs
public final synchronized void add(T... args) {
boolean isSubmitted = true;
if (arguments == null) {
--- a/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java Mon Feb 14 16:30:10 2011 -0800
@@ -120,6 +120,7 @@
buttons[i].setForeground(fgColor);
}
buttons[i].setMargin(new Insets(3, 2, 1, 2));
+ buttons[i].setFocusPainted(false);
buttons[i].setIconTextGap(0);
buttons[i].setHorizontalTextPosition(JToggleButton.CENTER);
buttons[i].setVerticalTextPosition(JToggleButton.BOTTOM);
--- a/jdk/src/share/classes/sun/tools/jar/Main.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/tools/jar/Main.java Mon Feb 14 16:30:10 2011 -0800
@@ -27,6 +27,7 @@
import java.io.*;
import java.nio.file.Path;
+import java.nio.file.Files;
import java.util.*;
import java.util.zip.*;
import java.util.jar.*;
@@ -1017,17 +1018,17 @@
Path jarPath = jarFile.toPath();
Path tmpPath = createTempFileInSameDirectoryAs(jarFile).toPath();
try {
- if (update(jarPath.newInputStream(),
- tmpPath.newOutputStream(),
+ if (update(Files.newInputStream(jarPath),
+ Files.newOutputStream(tmpPath),
null, index)) {
try {
- tmpPath.moveTo(jarPath, REPLACE_EXISTING);
+ Files.move(tmpPath, jarPath, REPLACE_EXISTING);
} catch (IOException e) {
throw new IOException(getMsg("error.write.file"), e);
}
}
} finally {
- tmpPath.deleteIfExists();
+ Files.deleteIfExists(tmpPath);
}
}
--- a/jdk/src/share/classes/sun/util/locale/LanguageTag.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/classes/sun/util/locale/LanguageTag.java Mon Feb 14 16:30:10 2011 -0800
@@ -421,11 +421,11 @@
String region = baseLocale.getRegion();
String variant = baseLocale.getVariant();
+ boolean hasSubtag = false;
+
String privuseVar = null; // store ill-formed variant subtags
- if (language.length() == 0 || !isLanguage(language)) {
- tag._language = UNDETERMINED;
- } else {
+ if (language.length() > 0 && isLanguage(language)) {
// Convert a deprecated language code used by Java to
// a new code
if (language.equals("iw")) {
@@ -440,10 +440,12 @@
if (script.length() > 0 && isScript(script)) {
tag._script = canonicalizeScript(script);
+ hasSubtag = true;
}
if (region.length() > 0 && isRegion(region)) {
tag._region = canonicalizeRegion(region);
+ hasSubtag = true;
}
// Special handling for no_NO_NY - use nn_NO for language tag
@@ -468,6 +470,7 @@
}
if (variants != null) {
tag._variants = variants;
+ hasSubtag = true;
}
if (!varitr.isDone()) {
// ill-formed variant subtags
@@ -508,6 +511,7 @@
if (extensions != null) {
tag._extensions = extensions;
+ hasSubtag = true;
}
// append ill-formed variant subtags to private use
@@ -521,8 +525,12 @@
if (privateuse != null) {
tag._privateuse = privateuse;
- } else if (tag._language.length() == 0) {
- // use "und" if neither language nor privateuse is available
+ }
+
+ if (tag._language.length() == 0 && (hasSubtag || privateuse == null)) {
+ // use lang "und" when 1) no language is available AND
+ // 2) any of other subtags other than private use are available or
+ // no private use tag is available
tag._language = UNDETERMINED;
}
--- a/jdk/src/share/demo/nio/zipfs/Demo.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/Demo.java Mon Feb 14 16:30:10 2011 -0800
@@ -33,6 +33,7 @@
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
+import java.nio.file.spi.*;
import java.nio.file.attribute.*;
import java.net.*;
import java.text.DateFormat;
@@ -144,78 +145,76 @@
}
public static void main(String[] args) throws Throwable {
+ FileSystemProvider provider = getZipFSProvider();
+ if (provider == null) {
+ System.err.println("ZIP filesystem provider is not installed");
+ System.exit(1);
+ }
Action action = Action.valueOf(args[0]);
Map<String, Object> env = env = new HashMap<>();
if (action == Action.create)
env.put("create", "true");
- if (action == Action.tlist || action == Action.twalk)
- env.put("buildDirTree", true);
- FileSystem fs = FileSystems.newFileSystem(Paths.get(args[1]), env, null);
-
- try {
- FileSystem fs2;
+ try (FileSystem fs = provider.newFileSystem(Paths.get(args[1]), env)) {
Path path, src, dst;
boolean isRename = false;
switch (action) {
case rename:
src = fs.getPath(args[2]);
dst = fs.getPath(args[3]);
- src.moveTo(dst);
+ Files.move(src, dst);
break;
case moveout:
src = fs.getPath(args[2]);
dst = Paths.get(args[3]);
- src.moveTo(dst);
+ Files.move(src, dst);
break;
case movein:
src = Paths.get(args[2]);
dst = fs.getPath(args[3]);
- src.moveTo(dst);
+ Files.move(src, dst);
break;
case copy:
src = fs.getPath(args[2]);
dst = fs.getPath(args[3]);
- src.copyTo(dst);
+ Files.copy(src, dst);
break;
case copyout:
src = fs.getPath(args[2]);
dst = Paths.get(args[3]);
- src.copyTo(dst);
+ Files.copy(src, dst);
break;
case copyin:
src = Paths.get(args[2]);
dst = fs.getPath(args[3]);
- src.copyTo(dst);
+ Files.copy(src, dst);
break;
case copyin_attrs:
src = Paths.get(args[2]);
dst = fs.getPath(args[3]);
- src.copyTo(dst, COPY_ATTRIBUTES);
+ Files.copy(src, dst, COPY_ATTRIBUTES);
break;
case copyout_attrs:
src = fs.getPath(args[2]);
dst = Paths.get(args[3]);
- src.copyTo(dst, COPY_ATTRIBUTES);
+ Files.copy(src, dst, COPY_ATTRIBUTES);
break;
case zzmove:
- fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
- //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3]));
- z2zmove(fs, fs2, args[3]);
- fs2.close();
+ try (FileSystem fs2 = provider.newFileSystem(Paths.get(args[2]), env)) {
+ z2zmove(fs, fs2, args[3]);
+ }
break;
case zzcopy:
- fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
- //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3]));
- z2zcopy(fs, fs2, args[3]);
- fs2.close();
+ try (FileSystem fs2 = provider.newFileSystem(Paths.get(args[2]), env)) {
+ z2zcopy(fs, fs2, args[3]);
+ }
break;
case attrs:
for (int i = 2; i < args.length; i++) {
path = fs.getPath(args[i]);
System.out.println(path);
System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
+ Files.readAttributes(path, BasicFileAttributes.class).toString());
}
break;
case setmtime:
@@ -223,10 +222,10 @@
Date newDatetime = df.parse(args[2]);
for (int i = 3; i < args.length; i++) {
path = fs.getPath(args[i]);
- path.setAttribute("lastModifiedTime",
- FileTime.fromMillis(newDatetime.getTime()));
+ Files.setAttribute(path, "lastModifiedTime",
+ FileTime.fromMillis(newDatetime.getTime()));
System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
+ Files.readAttributes(path, BasicFileAttributes.class).toString());
}
break;
case setctime:
@@ -234,10 +233,10 @@
newDatetime = df.parse(args[2]);
for (int i = 3; i < args.length; i++) {
path = fs.getPath(args[i]);
- path.setAttribute("creationTime",
- FileTime.fromMillis(newDatetime.getTime()));
+ Files.setAttribute(path, "creationTime",
+ FileTime.fromMillis(newDatetime.getTime()));
System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
+ Files.readAttributes(path, BasicFileAttributes.class).toString());
}
break;
case setatime:
@@ -245,25 +244,22 @@
newDatetime = df.parse(args[2]);
for (int i = 3; i < args.length; i++) {
path = fs.getPath(args[i]);
- path.setAttribute("lastAccessTime",
- FileTime.fromMillis(newDatetime.getTime()));
+ Files.setAttribute(path, "lastAccessTime",
+ FileTime.fromMillis(newDatetime.getTime()));
System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
+ Files.readAttributes(path, BasicFileAttributes.class).toString());
}
break;
case attrsspace:
path = fs.getPath("/");
- FileStore fstore = path.getFileStore();
- //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
- // .readAttributes());
- // or
+ FileStore fstore = Files.getFileStore(path);
System.out.printf("filestore[%s]%n", fstore.name());
System.out.printf(" totalSpace: %d%n",
- (Long)fstore.getAttribute("space:totalSpace"));
+ (Long)fstore.getAttribute("totalSpace"));
System.out.printf(" usableSpace: %d%n",
- (Long)fstore.getAttribute("space:usableSpace"));
+ (Long)fstore.getAttribute("usableSpace"));
System.out.printf(" unallocSpace: %d%n",
- (Long)fstore.getAttribute("space:unallocatedSpace"));
+ (Long)fstore.getAttribute("unallocatedSpace"));
break;
case list:
case tlist:
@@ -293,7 +289,7 @@
break;
case delete:
for (int i = 2; i < args.length; i++)
- fs.getPath(args[i]).delete();
+ Files.delete(fs.getPath(args[i]));
break;
case create:
case add:
@@ -305,17 +301,19 @@
case lsdir:
path = fs.getPath(args[2]);
final String fStr = (args.length > 3)?args[3]:"";
- DirectoryStream<Path> ds = path.newDirectoryStream(
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(path,
new DirectoryStream.Filter<Path>() {
public boolean accept(Path path) {
return path.toString().contains(fStr);
}
- });
- for (Path p : ds)
- System.out.println(p);
+ }))
+ {
+ for (Path p : ds)
+ System.out.println(p);
+ }
break;
case mkdir:
- fs.getPath(args[2]).createDirectory();
+ Files.createDirectory(fs.getPath(args[2]));
break;
case mkdirs:
mkdirs(fs.getPath(args[2]));
@@ -326,14 +324,14 @@
System.out.printf("%n%s%n", path);
System.out.println("-------(1)---------");
System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
+ Files.readAttributes(path, BasicFileAttributes.class).toString());
System.out.println("-------(2)---------");
- Map<String, ?> map = path.readAttributes("zip:*");
- for (Map.Entry<String, ?> e : map.entrySet()) {
+ Map<String, Object> map = Files.readAttributes(path, "zip:*");
+ for (Map.Entry<String, Object> e : map.entrySet()) {
System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
}
System.out.println("-------(3)---------");
- map = path.readAttributes("size,lastModifiedTime,isDirectory");
+ map = Files.readAttributes(path, "size,lastModifiedTime,isDirectory");
for (Map.Entry<String, ?> e : map.entrySet()) {
System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
}
@@ -349,12 +347,17 @@
}
} catch (Exception x) {
x.printStackTrace();
- } finally {
- if (fs != null)
- fs.close();
}
}
+ private static FileSystemProvider getZipFSProvider() {
+ for (FileSystemProvider provider : FileSystemProvider.installedProviders()) {
+ if ("jar".equals(provider.getScheme()))
+ return provider;
+ }
+ return null;
+ }
+
private static byte[] getBytes(String name) {
return name.getBytes();
}
@@ -380,7 +383,7 @@
BasicFileAttributes attrs)
{
indent();
- System.out.printf("%s%n", file.getName().toString());
+ System.out.printf("%s%n", file.getFileName().toString());
return FileVisitResult.CONTINUE;
}
@@ -406,35 +409,35 @@
private static void update(FileSystem fs, String path) throws Throwable{
Path src = FileSystems.getDefault().getPath(path);
- if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
- DirectoryStream<Path> ds = src.newDirectoryStream();
- for (Path child : ds)
- update(fs, child.toString());
- ds.close();
+ if (Files.isDirectory(src)) {
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(src)) {
+ for (Path child : ds)
+ update(fs, child.toString());
+ }
} else {
Path dst = fs.getPath(path);
Path parent = dst.getParent();
- if (parent != null && parent.notExists())
+ if (parent != null && Files.notExists(parent))
mkdirs(parent);
- src.copyTo(dst, REPLACE_EXISTING);
+ Files.copy(src, dst, REPLACE_EXISTING);
}
}
private static void extract(FileSystem fs, String path) throws Throwable{
Path src = fs.getPath(path);
- if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
- DirectoryStream<Path> ds = src.newDirectoryStream();
- for (Path child : ds)
- extract(fs, child.toString());
- ds.close();
+ if (Files.isDirectory(src)) {
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(src)) {
+ for (Path child : ds)
+ extract(fs, child.toString());
+ }
} else {
if (path.startsWith("/"))
path = path.substring(1);
Path dst = FileSystems.getDefault().getPath(path);
Path parent = dst.getParent();
- if (parent.notExists())
+ if (Files.notExists(parent))
mkdirs(parent);
- src.copyTo(dst, REPLACE_EXISTING);
+ Files.copy(src, dst, REPLACE_EXISTING);
}
}
@@ -445,21 +448,21 @@
Path srcPath = src.getPath(path);
Path dstPath = dst.getPath(path);
- if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
- if (!dstPath.exists()) {
+ if (Files.isDirectory(srcPath)) {
+ if (!Files.exists(dstPath)) {
try {
mkdirs(dstPath);
} catch (FileAlreadyExistsException x) {}
}
- DirectoryStream<Path> ds = srcPath.newDirectoryStream();
- for (Path child : ds) {
- z2zcopy(src, dst,
- path + (path.endsWith("/")?"":"/") + child.getName());
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(srcPath)) {
+ for (Path child : ds) {
+ z2zcopy(src, dst,
+ path + (path.endsWith("/")?"":"/") + child.getFileName());
+ }
}
- ds.close();
} else {
//System.out.println("copying..." + path);
- srcPath.copyTo(dstPath);
+ Files.copy(srcPath, dstPath);
}
}
@@ -480,9 +483,9 @@
dst = dstPath.resolve(dst);
try {
Path parent = dstPath.getParent();
- if (parent != null && parent.notExists())
+ if (parent != null && Files.notExists(parent))
mkdirs(parent);
- file.moveTo(dst);
+ Files.move(file, dst);
} catch (IOException x) {
x.printStackTrace();
}
@@ -497,7 +500,7 @@
dst = dstPath.resolve(dst);
try {
- if (dst.notExists())
+ if (Files.notExists(dst))
mkdirs(dst);
} catch (IOException x) {
x.printStackTrace();
@@ -511,7 +514,7 @@
throws IOException
{
try {
- dir.delete();
+ Files.delete(dir);
} catch (IOException x) {
//x.printStackTrace();
}
@@ -525,15 +528,15 @@
path = path.toAbsolutePath();
Path parent = path.getParent();
if (parent != null) {
- if (parent.notExists())
+ if (Files.notExists(parent))
mkdirs(parent);
}
- path.createDirectory();
+ Files.createDirectory(path);
}
private static void rmdirs(Path path) throws IOException {
while (path != null && path.getNameCount() != 0) {
- path.delete();
+ Files.delete(path);
path = path.getParent();
}
}
@@ -542,15 +545,15 @@
if (!"/".equals(path.toString())) {
System.out.printf(" %s%n", path.toString());
if (verbose)
- System.out.println(Attributes.readBasicFileAttributes(path).toString());
+ System.out.println(Files.readAttributes(path, BasicFileAttributes.class).toString());
}
- if (path.notExists())
+ if (Files.notExists(path))
return;
- if (Attributes.readBasicFileAttributes(path).isDirectory()) {
- DirectoryStream<Path> ds = path.newDirectoryStream();
- for (Path child : ds)
- list(child, verbose);
- ds.close();
+ if (Files.isDirectory(path)) {
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {
+ for (Path child : ds)
+ list(child, verbose);
+ }
}
}
@@ -561,12 +564,11 @@
// src.toString(), dst.toString());
//streams
- InputStream isSrc = src.newInputStream();
- InputStream isDst = dst.newInputStream();
byte[] bufSrc = new byte[8192];
byte[] bufDst = new byte[8192];
-
- try {
+ try (InputStream isSrc = Files.newInputStream(src);
+ InputStream isDst = Files.newInputStream(dst))
+ {
int nSrc = 0;
while ((nSrc = isSrc.read(bufSrc)) != -1) {
int nDst = 0;
@@ -588,24 +590,22 @@
nSrc--;
}
}
- } finally {
- isSrc.close();
- isDst.close();
}
// channels
- SeekableByteChannel chSrc = src.newByteChannel();
- SeekableByteChannel chDst = dst.newByteChannel();
- if (chSrc.size() != chDst.size()) {
- System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
- chSrc.toString(), chSrc.size(),
- chDst.toString(), chDst.size());
- throw new RuntimeException("CHECK FAILED!");
- }
- ByteBuffer bbSrc = ByteBuffer.allocate(8192);
- ByteBuffer bbDst = ByteBuffer.allocate(8192);
- try {
+ try (SeekableByteChannel chSrc = Files.newByteChannel(src);
+ SeekableByteChannel chDst = Files.newByteChannel(dst))
+ {
+ if (chSrc.size() != chDst.size()) {
+ System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
+ chSrc.toString(), chSrc.size(),
+ chDst.toString(), chDst.size());
+ throw new RuntimeException("CHECK FAILED!");
+ }
+ ByteBuffer bbSrc = ByteBuffer.allocate(8192);
+ ByteBuffer bbDst = ByteBuffer.allocate(8192);
+
int nSrc = 0;
while ((nSrc = chSrc.read(bbSrc)) != -1) {
int nDst = chDst.read(bbDst);
@@ -627,9 +627,6 @@
}
} catch (IOException x) {
x.printStackTrace();
- } finally {
- chSrc.close();
- chDst.close();
}
}
@@ -641,23 +638,15 @@
openwrite.add(CREATE_NEW);
openwrite.add(WRITE);
- FileChannel srcFc = src.getFileSystem()
- .provider()
- .newFileChannel(src, read);
- FileChannel dstFc = dst.getFileSystem()
- .provider()
- .newFileChannel(dst, openwrite);
-
- try {
+ try (FileChannel srcFc = src.getFileSystem().provider().newFileChannel(src, read);
+ FileChannel dstFc = dst.getFileSystem().provider().newFileChannel(dst, openwrite))
+ {
ByteBuffer bb = ByteBuffer.allocate(8192);
while (srcFc.read(bb) >= 0) {
bb.flip();
dstFc.write(bb);
bb.clear();
}
- } finally {
- srcFc.close();
- dstFc.close();
}
}
@@ -669,35 +658,28 @@
openwrite.add(CREATE_NEW);
openwrite.add(WRITE);
- SeekableByteChannel srcCh = src.newByteChannel(read);
- SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
-
- try {
+ try (SeekableByteChannel srcCh = Files.newByteChannel(src, read);
+ SeekableByteChannel dstCh = Files.newByteChannel(dst, openwrite))
+ {
ByteBuffer bb = ByteBuffer.allocate(8192);
while (srcCh.read(bb) >= 0) {
bb.flip();
dstCh.write(bb);
bb.clear();
}
- } finally {
- srcCh.close();
- dstCh.close();
}
}
private static void streamCopy(Path src, Path dst) throws IOException
{
- InputStream isSrc = src.newInputStream();
- OutputStream osDst = dst.newOutputStream();
byte[] buf = new byte[8192];
- try {
+ try (InputStream isSrc = Files.newInputStream(src);
+ OutputStream osDst = Files.newOutputStream(dst))
+ {
int n = 0;
while ((n = isSrc.read(buf)) != -1) {
osDst.write(buf, 0, n);
}
- } finally {
- isSrc.close();
- osDst.close();
}
}
}
--- a/jdk/src/share/demo/nio/zipfs/README.txt Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/README.txt Mon Feb 14 16:30:10 2011 -0800
@@ -5,9 +5,8 @@
used to create a FileSystem, eg:
// use file type detection
- Map<String,?> env = Collections.emptyMap();
Path jarfile = Paths.get("foo.jar");
- FileSystem fs = FileSystems.newFileSystem(jarfile, env, null);
+ FileSystem fs = FileSystems.newFileSystem(jarfile, null);
-or
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -32,11 +32,10 @@
package com.sun.nio.zipfs;
-import java.nio.file.attribute.BasicFileAttributeView;
-import java.nio.file.attribute.FileAttributeView;
-import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.*;
import java.io.IOException;
import java.util.LinkedHashMap;
+import java.util.Map;
/*
* @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
@@ -122,25 +121,19 @@
"' is unknown or read-only attribute");
}
- public Object getAttribute(String attribute, boolean domap)
+ Map<String, Object> readAttributes(String attributes)
throws IOException
{
ZipFileAttributes zfas = readAttributes();
- if (!domap) {
- try {
- return attribute(AttrID.valueOf(attribute), zfas);
- } catch (IllegalArgumentException x) {}
- return null;
- }
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
- if ("*".equals(attribute)) {
+ if ("*".equals(attributes)) {
for (AttrID id : AttrID.values()) {
try {
map.put(id.name(), attribute(id, zfas));
} catch (IllegalArgumentException x) {}
}
} else {
- String[] as = attribute.split(",");
+ String[] as = attributes.split(",");
for (String a : as) {
try {
map.put(a, attribute(AttrID.valueOf(a), zfas));
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileStore.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileStore.java Mon Feb 14 16:30:10 2011 -0800
@@ -32,14 +32,13 @@
package com.sun.nio.zipfs;
import java.io.IOException;
+import java.nio.file.Files;
import java.nio.file.FileStore;
import java.nio.file.FileSystems;
import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileStoreAttributeView;
-import java.nio.file.attribute.FileStoreSpaceAttributeView;
-import java.nio.file.attribute.FileStoreSpaceAttributes;
-import java.nio.file.attribute.Attributes;
import java.nio.file.attribute.BasicFileAttributeView;
import java.util.Formatter;
@@ -87,71 +86,61 @@
public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
if (type == null)
throw new NullPointerException();
- if (type == FileStoreSpaceAttributeView.class)
- return (V) new ZipFileStoreAttributeView(this);
- return null;
+ return (V)null;
+ }
+
+ @Override
+ public long getTotalSpace() throws IOException {
+ return new ZipFileStoreAttributes(this).totalSpace();
+ }
+
+ @Override
+ public long getUsableSpace() throws IOException {
+ return new ZipFileStoreAttributes(this).usableSpace();
+ }
+
+ @Override
+ public long getUnallocatedSpace() throws IOException {
+ return new ZipFileStoreAttributes(this).unallocatedSpace();
}
@Override
public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals("space:totalSpace"))
- return new ZipFileStoreAttributeView(this).readAttributes().totalSpace();
- if (attribute.equals("space:usableSpace"))
- return new ZipFileStoreAttributeView(this).readAttributes().usableSpace();
- if (attribute.equals("space:unallocatedSpace"))
- return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace();
+ if (attribute.equals("totalSpace"))
+ return getTotalSpace();
+ if (attribute.equals("usableSpace"))
+ return getUsableSpace();
+ if (attribute.equals("unallocatedSpace"))
+ return getUnallocatedSpace();
throw new UnsupportedOperationException("does not support the given attribute");
}
- private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView {
-
- private final ZipFileStore fileStore;
+ private static class ZipFileStoreAttributes {
+ final FileStore fstore;
+ final long size;
- public ZipFileStoreAttributeView(ZipFileStore fileStore) {
- this.fileStore = fileStore;
- }
-
- @Override
- public String name() {
- return "space";
+ public ZipFileStoreAttributes(ZipFileStore fileStore)
+ throws IOException
+ {
+ Path path = FileSystems.getDefault().getPath(fileStore.name());
+ this.size = Files.size(path);
+ this.fstore = Files.getFileStore(path);
}
- @Override
- public FileStoreSpaceAttributes readAttributes() throws IOException {
- final String file = fileStore.name();
- Path path = FileSystems.getDefault().getPath(file);
- final long size = Attributes.readBasicFileAttributes(path).size();
- final FileStore fstore = path.getFileStore();
- final FileStoreSpaceAttributes fstoreAttrs =
- Attributes.readFileStoreSpaceAttributes(fstore);
- return new FileStoreSpaceAttributes() {
- public long totalSpace() {
- return size;
- }
+ public long totalSpace() {
+ return size;
+ }
- public long usableSpace() {
- if (!fstore.isReadOnly())
- return fstoreAttrs.usableSpace();
- return 0;
- }
-
- public long unallocatedSpace() {
- if (!fstore.isReadOnly())
- return fstoreAttrs.unallocatedSpace();
- return 0;
- }
+ public long usableSpace() throws IOException {
+ if (!fstore.isReadOnly())
+ return fstore.getUsableSpace();
+ return 0;
+ }
- public String toString() {
- StringBuilder sb = new StringBuilder();
- Formatter fm = new Formatter(sb);
- fm.format("FileStoreSpaceAttributes[%s]%n", file);
- fm.format(" totalSpace: %d%n", totalSpace());
- fm.format(" usableSpace: %d%n", usableSpace());
- fm.format(" unallocSpace: %d%n", unallocatedSpace());
- fm.close();
- return sb.toString();
- }
- };
+ public long unallocatedSpace() throws IOException {
+ if (!fstore.isReadOnly())
+ return fstore.getUnallocatedSpace();
+ return 0;
}
}
}
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java Mon Feb 14 16:30:10 2011 -0800
@@ -101,24 +101,25 @@
this.provider = provider;
this.zfpath = zfpath;
- if (zfpath.notExists()) {
+ if (Files.notExists(zfpath)) {
if (createNew) {
- OutputStream os = zfpath.newOutputStream(CREATE_NEW, WRITE);
- new END().write(os, 0);
- os.close();
+ try (OutputStream os = Files.newOutputStream(zfpath, CREATE_NEW, WRITE)) {
+ new END().write(os, 0);
+ }
} else {
throw new FileSystemNotFoundException(zfpath.toString());
}
}
- zfpath.checkAccess(AccessMode.READ); // sm and existence check
+ // sm and existence check
+ zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ);
try {
- zfpath.checkAccess(AccessMode.WRITE);
+ zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.WRITE);
} catch (AccessDeniedException x) {
this.readOnly = true;
}
this.zc = ZipCoder.get(nameEncoding);
this.defaultdir = new ZipPath(this, getBytes(defaultDir));
- this.ch = zfpath.newByteChannel(READ);
+ this.ch = Files.newByteChannel(zfpath, READ);
this.cen = initCEN();
}
@@ -159,9 +160,22 @@
}
@Override
- public ZipPath getPath(String path) {
- if (path.length() == 0)
- throw new InvalidPathException(path, "path should not be empty");
+ public ZipPath getPath(String first, String... more) {
+ String path;
+ if (more.length == 0) {
+ path = first;
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append(first);
+ for (String segment: more) {
+ if (segment.length() > 0) {
+ if (sb.length() > 0)
+ sb.append('/');
+ sb.append(segment);
+ }
+ }
+ path = sb.toString();
+ }
return new ZipPath(this, getBytes(path));
}
@@ -268,16 +282,22 @@
def.end();
}
+ IOException ioe = null;
synchronized (tmppaths) {
for (Path p: tmppaths) {
try {
- p.deleteIfExists();
+ Files.deleteIfExists(p);
} catch (IOException x) {
- x.printStackTrace();
+ if (ioe == null)
+ ioe = x;
+ else
+ ioe.addSuppressed(x);
}
}
}
- provider.removeFileSystem(zfpath);
+ provider.removeFileSystem(zfpath, this);
+ if (ioe != null)
+ throw ioe;
}
ZipFileAttributes getFileAttributes(byte[] path)
@@ -444,7 +464,7 @@
u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
else if (eSrc.file != null) {
u.file = getTempPathForEntry(null);
- eSrc.file.copyTo(u.file, REPLACE_EXISTING);
+ Files.copy(eSrc.file, u.file, REPLACE_EXISTING);
}
}
}
@@ -778,7 +798,8 @@
fch.close();
if (forWrite) {
u.mtime = System.currentTimeMillis();
- u.size = Attributes.readBasicFileAttributes(u.file).size();
+ u.size = Files.size(u.file);
+
update(u);
} else {
if (!isFCH) // if this is a new fch for reading
@@ -805,13 +826,8 @@
if (path != null) {
Entry e = getEntry0(path);
if (e != null) {
- InputStream is = newInputStream(path);
- OutputStream os = tmpPath.newOutputStream(WRITE);
- try {
- copyStream(is, os);
- } finally {
- is.close();
- os.close();
+ try (InputStream is = newInputStream(path)) {
+ Files.copy(is, tmpPath, REPLACE_EXISTING);
}
}
}
@@ -819,7 +835,7 @@
}
private void removeTempPathForEntry(Path path) throws IOException {
- path.delete();
+ Files.delete(path);
tmppaths.remove(path);
}
@@ -1073,11 +1089,11 @@
// shared key. consumer guarantees the "writeLock" before use it.
private final IndexNode LOOKUPKEY = IndexNode.keyOf(null);
- private void updateDelete(Entry e) {
+ private void updateDelete(IndexNode inode) {
beginWrite();
try {
- removeFromTree(e);
- inodes.remove(e);
+ removeFromTree(inode);
+ inodes.remove(inode);
hasUpdate = true;
} finally {
endWrite();
@@ -1158,7 +1174,7 @@
for (ExChannelCloser ecc : exChClosers) {
if (ecc.streams.isEmpty()) {
ecc.ch.close();
- ecc.path.delete();
+ Files.delete(ecc.path);
exChClosers.remove(ecc);
}
}
@@ -1166,7 +1182,7 @@
if (!hasUpdate)
return;
Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
- OutputStream os = tmpFile.newOutputStream(WRITE);
+ OutputStream os = Files.newOutputStream(tmpFile, WRITE);
ArrayList<Entry> elist = new ArrayList<>(inodes.size());
long written = 0;
byte[] buf = new byte[8192];
@@ -1191,26 +1207,26 @@
os.write(e.bytes); // already
written += e.bytes.length;
} else if (e.file != null) { // tmp file
- InputStream is = e.file.newInputStream();
- int n;
- if (e.type == Entry.NEW) { // deflated already
- while ((n = is.read(buf)) != -1) {
- os.write(buf, 0, n);
- written += n;
+ try (InputStream is = Files.newInputStream(e.file)) {
+ int n;
+ if (e.type == Entry.NEW) { // deflated already
+ while ((n = is.read(buf)) != -1) {
+ os.write(buf, 0, n);
+ written += n;
+ }
+ } else if (e.type == Entry.FILECH) {
+ // the data are not deflated, use ZEOS
+ try (OutputStream os2 = new EntryOutputStream(e, os)) {
+ while ((n = is.read(buf)) != -1) {
+ os2.write(buf, 0, n);
+ }
+ }
+ written += e.csize;
+ if ((e.flag & FLAG_DATADESCR) != 0)
+ written += e.writeEXT(os);
}
- } else if (e.type == Entry.FILECH) {
- // the data are not deflated, use ZEOS
- OutputStream os2 = new EntryOutputStream(e, os);
- while ((n = is.read(buf)) != -1) {
- os2.write(buf, 0, n);
- }
- os2.close();
- written += e.csize;
- if ((e.flag & FLAG_DATADESCR) != 0)
- written += e.writeEXT(os);
}
- is.close();
- e.file.delete();
+ Files.delete(e.file);
tmppaths.remove(e.file);
} else {
// dir, 0-length data
@@ -1257,15 +1273,15 @@
createTempFileInSameDirectoryAs(zfpath),
ch,
streams);
- zfpath.moveTo(ecc.path, REPLACE_EXISTING);
+ Files.move(zfpath, ecc.path, REPLACE_EXISTING);
exChClosers.add(ecc);
streams = Collections.synchronizedSet(new HashSet<InputStream>());
} else {
ch.close();
- zfpath.delete();
+ Files.delete(zfpath);
}
- tmpFile.moveTo(zfpath, REPLACE_EXISTING);
+ Files.move(tmpFile, zfpath, REPLACE_EXISTING);
hasUpdate = false; // clear
/*
if (isOpen) {
@@ -1304,16 +1320,17 @@
throws IOException
{
checkWritable();
- Entry e = getEntry0(path);
- if (e == null) {
+
+ IndexNode inode = getInode(path);
+ if (inode == null) {
if (path != null && path.length == 0)
throw new ZipException("root directory </> can't not be delete");
if (failIfNotExists)
throw new NoSuchFileException(getString(path));
} else {
- if (e.isDir() && e.child != null)
+ if (inode.isDir() && inode.child != null)
throw new DirectoryNotEmptyException(getString(path));
- updateDelete(e);
+ updateDelete(inode);
}
}
@@ -1343,7 +1360,7 @@
OutputStream os;
if (useTempFile) {
e.file = getTempPathForEntry(null);
- os = e.file.newOutputStream(WRITE);
+ os = Files.newOutputStream(e.file, WRITE);
} else {
os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192);
}
@@ -1359,12 +1376,12 @@
if (e.bytes != null)
eis = new ByteArrayInputStream(e.bytes);
else if (e.file != null)
- eis = e.file.newInputStream();
+ eis = Files.newInputStream(e.file);
else
throw new ZipException("update entry data is missing");
} else if (e.type == Entry.FILECH) {
// FILECH result is un-compressed.
- eis = e.file.newInputStream();
+ eis = Files.newInputStream(e.file);
// TBD: wrap to hook close()
// streams.add(eis);
return eis;
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java Mon Feb 14 16:30:10 2011 -0800
@@ -31,23 +31,18 @@
package com.sun.nio.zipfs;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.file.FileRef;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystemNotFoundException;
-import java.nio.file.FileSystemAlreadyExistsException;
-import java.nio.file.OpenOption;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.ProviderMismatchException;
-import java.nio.file.attribute.FileAttribute;
+import java.io.*;
+import java.nio.channels.*;
+import java.nio.file.*;
+import java.nio.file.DirectoryStream.Filter;
+import java.nio.file.attribute.*;
import java.nio.file.spi.FileSystemProvider;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ExecutorService;
/*
*
@@ -87,28 +82,25 @@
public FileSystem newFileSystem(URI uri, Map<String, ?> env)
throws IOException
{
- return newFileSystem(uriToPath(uri), env);
+ return newFileSystem(uriToPath(uri), env, true);
}
@Override
- public FileSystem newFileSystem(FileRef file, Map<String, ?> env)
+ public FileSystem newFileSystem(Path path, Map<String, ?> env)
throws IOException
{
- if (!(file instanceof Path))
- throw new UnsupportedOperationException();
- Path path = (Path)file;
if (!path.toUri().getScheme().equalsIgnoreCase("file")) {
throw new UnsupportedOperationException();
}
- return newFileSystem(path, env);
+ return newFileSystem(path, env, false);
}
- private FileSystem newFileSystem(Path path, Map<String, ?> env)
+ private FileSystem newFileSystem(Path path, Map<String, ?> env, boolean checkIfFSExists)
throws IOException
{
synchronized(filesystems) {
Path realPath = null;
- if (path.exists()) {
+ if (checkIfFSExists && Files.exists(path)) {
realPath = path.toRealPath(true);
if (filesystems.containsKey(realPath))
throw new FileSystemAlreadyExistsException();
@@ -116,7 +108,8 @@
ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
if (realPath == null)
realPath = path.toRealPath(true);
- filesystems.put(realPath, zipfs);
+ if (!filesystems.containsKey(realPath))
+ filesystems.put(realPath, zipfs);
return zipfs;
}
}
@@ -133,18 +126,6 @@
return getFileSystem(uri).getPath(spec.substring(sep + 1));
}
- @Override
- public FileChannel newFileChannel(Path path,
- Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- if (path == null)
- throw new NullPointerException("path is null");
- if (path instanceof ZipPath)
- return ((ZipPath)path).newFileChannel(options, attrs);
- throw new ProviderMismatchException();
- }
@Override
public FileSystem getFileSystem(URI uri) {
@@ -161,9 +142,155 @@
}
}
- void removeFileSystem(Path zfpath) throws IOException {
+ // Checks that the given file is a UnixPath
+ static final ZipPath toZipPath(Path path) {
+ if (path == null)
+ throw new NullPointerException();
+ if (!(path instanceof ZipPath))
+ throw new ProviderMismatchException();
+ return (ZipPath)path;
+ }
+
+ @Override
+ public void checkAccess(Path path, AccessMode... modes) throws IOException {
+ toZipPath(path).checkAccess(modes);
+ }
+
+ @Override
+ public void copy(Path src, Path target, CopyOption... options)
+ throws IOException
+ {
+ toZipPath(src).copy(toZipPath(target), options);
+ }
+
+ @Override
+ public void createDirectory(Path path, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ toZipPath(path).createDirectory(attrs);
+ }
+
+ @Override
+ public final void delete(Path path) throws IOException {
+ toZipPath(path).delete();
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileAttributeView> V
+ getFileAttributeView(Path path, Class<V> type, LinkOption... options)
+ {
+ return (V)ZipFileAttributeView.get(toZipPath(path), type);
+ }
+
+ @Override
+ public FileStore getFileStore(Path path) throws IOException {
+ return toZipPath(path).getFileStore();
+ }
+
+ @Override
+ public boolean isHidden(Path path) {
+ return toZipPath(path).isHidden();
+ }
+
+ @Override
+ public boolean isSameFile(Path path, Path other) throws IOException {
+ return toZipPath(path).isSameFile(other);
+ }
+
+ @Override
+ public void move(Path src, Path target, CopyOption... options)
+ throws IOException
+ {
+ toZipPath(src).move(toZipPath(target), options);
+ }
+
+ @Override
+ public AsynchronousFileChannel newAsynchronousFileChannel(Path path,
+ Set<? extends OpenOption> options,
+ ExecutorService exec,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return toZipPath(path).newByteChannel(options, attrs);
+ }
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(
+ Path path, Filter<? super Path> filter) throws IOException
+ {
+ return toZipPath(path).newDirectoryStream(filter);
+ }
+
+ @Override
+ public FileChannel newFileChannel(Path path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return toZipPath(path).newFileChannel(options, attrs);
+ }
+
+ @Override
+ public InputStream newInputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ return toZipPath(path).newInputStream(options);
+ }
+
+ @Override
+ public OutputStream newOutputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ return toZipPath(path).newOutputStream(options);
+ }
+
+ @Override
+ public <A extends BasicFileAttributes> A
+ readAttributes(Path path, Class<A> type, LinkOption... options)
+ throws IOException
+ {
+ if (type == BasicFileAttributes.class || type == ZipFileAttributes.class)
+ return (A)toZipPath(path).getAttributes();
+ return null;
+ }
+
+ @Override
+ public Map<String, Object>
+ readAttributes(Path path, String attribute, LinkOption... options)
+ throws IOException
+ {
+ return toZipPath(path).readAttributes(attribute, options);
+ }
+
+ @Override
+ public Path readSymbolicLink(Path link) throws IOException {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void setAttribute(Path path, String attribute,
+ Object value, LinkOption... options)
+ throws IOException
+ {
+ toZipPath(path).setAttribute(attribute, value, options);
+ }
+
+ //////////////////////////////////////////////////////////////
+ void removeFileSystem(Path zfpath, ZipFileSystem zfs) throws IOException {
synchronized (filesystems) {
- filesystems.remove(zfpath.toRealPath(true));
+ zfpath = zfpath.toRealPath(true);
+ if (filesystems.get(zfpath) == zfs)
+ filesystems.remove(zfpath);
}
}
}
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java Mon Feb 14 16:30:10 2011 -0800
@@ -31,29 +31,23 @@
package com.sun.nio.zipfs;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
import java.net.URI;
-import java.nio.channels.FileChannel;
-import java.nio.channels.SeekableByteChannel;
+import java.nio.channels.*;
import java.nio.file.*;
import java.nio.file.DirectoryStream.Filter;
-import java.nio.file.attribute.BasicFileAttributeView;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.file.attribute.FileAttributeView;
-import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.*;
import java.util.*;
import static java.nio.file.StandardOpenOption.*;
import static java.nio.file.StandardCopyOption.*;
+
/**
*
* @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
*/
-public class ZipPath extends Path {
+public class ZipPath implements Path {
private final ZipFileSystem zfs;
private final byte[] path;
@@ -82,7 +76,7 @@
}
@Override
- public Path getName() {
+ public Path getFileName() {
initOffsets();
int count = offsets.length;
if (count == 0)
@@ -162,8 +156,7 @@
return realPath;
}
- @Override
- public boolean isHidden() {
+ boolean isHidden() {
return false;
}
@@ -230,7 +223,7 @@
public Path relativize(Path other) {
final ZipPath o = checkPath(other);
if (o.equals(this))
- return null;
+ return new ZipPath(getFileSystem(), new byte[0], true);
if (/* this.getFileSystem() != o.getFileSystem() || */
this.isAbsolute() != o.isAbsolute()) {
throw new IllegalArgumentException();
@@ -272,13 +265,11 @@
@Override
public boolean isAbsolute() {
- return (this.path[0] == '/');
+ return (this.path.length > 0 && path[0] == '/');
}
@Override
public ZipPath resolve(Path other) {
- if (other == null)
- return this;
final ZipPath o = checkPath(other);
if (o.isAbsolute())
return o;
@@ -297,39 +288,70 @@
}
@Override
- public ZipPath resolve(String other) {
- return resolve(getFileSystem().getPath(other));
+ public Path resolveSibling(Path other) {
+ if (other == null)
+ throw new NullPointerException();
+ Path parent = getParent();
+ return (parent == null) ? other : parent.resolve(other);
}
@Override
public boolean startsWith(Path other) {
final ZipPath o = checkPath(other);
- if (o.isAbsolute() != this.isAbsolute())
+ if (o.isAbsolute() != this.isAbsolute() ||
+ o.path.length > this.path.length)
return false;
- final int oCount = o.getNameCount();
- if (getNameCount() < oCount)
- return false;
- for (int i = 0; i < oCount; i++) {
- if (!o.getName(i).equals(getName(i)))
+ int olast = o.path.length;
+ for (int i = 0; i < olast; i++) {
+ if (o.path[i] != this.path[i])
return false;
}
- return true;
+ olast--;
+ return o.path.length == this.path.length ||
+ o.path[olast] == '/' ||
+ this.path[olast + 1] == '/';
}
@Override
public boolean endsWith(Path other) {
final ZipPath o = checkPath(other);
- if (o.isAbsolute())
- return this.isAbsolute() ? this.equals(o) : false;
- int i = o.getNameCount();
- int j = this.getNameCount();
- if (j < i)
+ int olast = o.path.length - 1;
+ if (olast > 0 && o.path[olast] == '/')
+ olast--;
+ int last = this.path.length - 1;
+ if (last > 0 && this.path[last] == '/')
+ last--;
+ if (olast == -1) // o.path.length == 0
+ return last == -1;
+ if ((o.isAbsolute() &&(!this.isAbsolute() || olast != last)) ||
+ (last < olast))
return false;
- for (--i, --j; i >= 0; i--, j--) {
- if (!o.getName(i).equals(this.getName(j)))
+ for (; olast >= 0; olast--, last--) {
+ if (o.path[olast] != this.path[last])
return false;
}
- return true;
+ return o.path[olast + 1] == '/' ||
+ last == -1 || this.path[last] == '/';
+ }
+
+ @Override
+ public ZipPath resolve(String other) {
+ return resolve(getFileSystem().getPath(other));
+ }
+
+ @Override
+ public final Path resolveSibling(String other) {
+ return resolveSibling(getFileSystem().getPath(other));
+ }
+
+ @Override
+ public final boolean startsWith(String other) {
+ return startsWith(getFileSystem().getPath(other));
+ }
+
+ @Override
+ public final boolean endsWith(String other) {
+ return endsWith(getFileSystem().getPath(other));
}
@Override
@@ -337,8 +359,6 @@
byte[] resolved = getResolved();
if (resolved == path) // no change
return this;
- if (resolved.length == 0)
- return null;
return new ZipPath(zfs, resolved, true);
}
@@ -548,198 +568,6 @@
return len1 - len2;
}
- @Override
- public Path createSymbolicLink(
- Path target, FileAttribute<?>... attrs) throws IOException {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public Path createLink(
- Path existing) throws IOException {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public Path readSymbolicLink() throws IOException {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public Path createDirectory(FileAttribute<?>... attrs)
- throws IOException
- {
- zfs.createDirectory(getResolvedPath(), attrs);
- return this;
- }
-
- public final Path createFile(FileAttribute<?>... attrs)
- throws IOException
- {
- OutputStream os = newOutputStream(CREATE_NEW, WRITE);
- try {
- os.close();
- } catch (IOException x) {}
- return this;
- }
-
- @Override
- public InputStream newInputStream(OpenOption... options)
- throws IOException {
- if (options.length > 0) {
- for (OpenOption opt : options) {
- if (opt != READ)
- throw new UnsupportedOperationException("'" + opt + "' not allowed");
- }
- }
- return zfs.newInputStream(getResolvedPath());
- }
-
- private static final DirectoryStream.Filter<Path> acceptAllFilter =
- new DirectoryStream.Filter<>() {
- @Override public boolean accept(Path entry) { return true; }
- };
-
- @Override
- public final DirectoryStream<Path> newDirectoryStream() throws IOException {
- return newDirectoryStream(acceptAllFilter);
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter)
- throws IOException
- {
- return new ZipDirectoryStream(this, filter);
- }
-
- @Override
- public final DirectoryStream<Path> newDirectoryStream(String glob)
- throws IOException
- {
- // avoid creating a matcher if all entries are required.
- if (glob.equals("*"))
- return newDirectoryStream();
-
- // create a matcher and return a filter that uses it.
- final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
- DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<>() {
- @Override
- public boolean accept(Path entry) {
- return matcher.matches(entry.getName());
- }
- };
- return newDirectoryStream(filter);
- }
-
- @Override
- public final void delete() throws IOException {
- zfs.deleteFile(getResolvedPath(), true);
- }
-
- @Override
- public final void deleteIfExists() throws IOException {
- zfs.deleteFile(getResolvedPath(), false);
- }
-
- ZipFileAttributes getAttributes() throws IOException
- {
- ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
- if (zfas == null)
- throw new NoSuchFileException(toString());
- return zfas;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
- LinkOption... options)
- {
- return (V)ZipFileAttributeView.get(this, type);
- }
-
- @Override
- public void setAttribute(String attribute,
- Object value,
- LinkOption... options)
- throws IOException
- {
- String type = null;
- String attr = null;
- int colonPos = attribute.indexOf(':');
- if (colonPos == -1) {
- type = "basic";
- attr = attribute;
- } else {
- type = attribute.substring(0, colonPos++);
- attr = attribute.substring(colonPos);
- }
- ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
- if (view == null)
- throw new UnsupportedOperationException("view <" + view + "> is not supported");
- view.setAttribute(attr, value);
- }
-
- void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
- throws IOException
- {
- zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
- }
-
- private Object getAttributesImpl(String attribute, boolean domap)
- throws IOException
- {
- String view = null;
- String attr = null;
- int colonPos = attribute.indexOf(':');
- if (colonPos == -1) {
- view = "basic";
- attr = attribute;
- } else {
- view = attribute.substring(0, colonPos++);
- attr = attribute.substring(colonPos);
- }
- ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
- if (zfv == null) {
- throw new UnsupportedOperationException("view not supported");
- }
- return zfv.getAttribute(attr, domap);
- }
-
- @Override
- public Object getAttribute(String attribute, LinkOption... options)
- throws IOException
- {
- return getAttributesImpl(attribute, false);
- }
-
- @Override
- public Map<String,?> readAttributes(String attribute, LinkOption... options)
- throws IOException
- {
- return (Map<String, ?>)getAttributesImpl(attribute, true);
- }
-
- @Override
- public FileStore getFileStore() throws IOException {
- // each ZipFileSystem only has one root (as requested for now)
- if (exists())
- return zfs.getFileStore(this);
- throw new NoSuchFileException(zfs.getString(path));
- }
-
- @Override
- public boolean isSameFile(Path other) throws IOException {
- if (this.equals(other))
- return true;
- if (other == null ||
- this.getFileSystem() != other.getFileSystem())
- return false;
- this.checkAccess();
- other.checkAccess();
- return Arrays.equals(this.getResolvedPath(),
- ((ZipPath)other).getResolvedPath());
- }
-
public WatchKey register(
WatchService watcher,
WatchEvent.Kind<?>[] events,
@@ -756,6 +584,11 @@
}
@Override
+ public final File toFile() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public Iterator<Path> iterator() {
return new Iterator<>() {
private int i = 0;
@@ -783,9 +616,115 @@
};
}
- @Override
- public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
+ /////////////////////////////////////////////////////////////////////
+
+
+ void createDirectory(FileAttribute<?>... attrs)
+ throws IOException
+ {
+ zfs.createDirectory(getResolvedPath(), attrs);
+ }
+
+ InputStream newInputStream(OpenOption... options) throws IOException
+ {
+ if (options.length > 0) {
+ for (OpenOption opt : options) {
+ if (opt != READ)
+ throw new UnsupportedOperationException("'" + opt + "' not allowed");
+ }
+ }
+ return zfs.newInputStream(getResolvedPath());
+ }
+
+ DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter)
+ throws IOException
+ {
+ return new ZipDirectoryStream(this, filter);
+ }
+
+ void delete() throws IOException {
+ zfs.deleteFile(getResolvedPath(), true);
+ }
+
+ void deleteIfExists() throws IOException {
+ zfs.deleteFile(getResolvedPath(), false);
+ }
+
+ ZipFileAttributes getAttributes() throws IOException
+ {
+ ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
+ if (zfas == null)
+ throw new NoSuchFileException(toString());
+ return zfas;
+ }
+
+ void setAttribute(String attribute, Object value, LinkOption... options)
+ throws IOException
+ {
+ String type = null;
+ String attr = null;
+ int colonPos = attribute.indexOf(':');
+ if (colonPos == -1) {
+ type = "basic";
+ attr = attribute;
+ } else {
+ type = attribute.substring(0, colonPos++);
+ attr = attribute.substring(colonPos);
+ }
+ ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
+ if (view == null)
+ throw new UnsupportedOperationException("view <" + view + "> is not supported");
+ view.setAttribute(attr, value);
+ }
+
+ void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
+ throws IOException
+ {
+ zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
+ }
+
+ Map<String, Object> readAttributes(String attributes, LinkOption... options)
+ throws IOException
+
+ {
+ String view = null;
+ String attrs = null;
+ int colonPos = attributes.indexOf(':');
+ if (colonPos == -1) {
+ view = "basic";
+ attrs = attributes;
+ } else {
+ view = attributes.substring(0, colonPos++);
+ attrs = attributes.substring(colonPos);
+ }
+ ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
+ if (zfv == null) {
+ throw new UnsupportedOperationException("view not supported");
+ }
+ return zfv.readAttributes(attrs);
+ }
+
+ FileStore getFileStore() throws IOException {
+ // each ZipFileSystem only has one root (as requested for now)
+ if (exists())
+ return zfs.getFileStore(this);
+ throw new NoSuchFileException(zfs.getString(path));
+ }
+
+ boolean isSameFile(Path other) throws IOException {
+ if (this.equals(other))
+ return true;
+ if (other == null ||
+ this.getFileSystem() != other.getFileSystem())
+ return false;
+ this.checkAccess();
+ ((ZipPath)other).checkAccess();
+ return Arrays.equals(this.getResolvedPath(),
+ ((ZipPath)other).getResolvedPath());
+ }
+
+ SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
throws IOException
{
return zfs.newByteChannel(getResolvedPath(), options, attrs);
@@ -799,16 +738,7 @@
return zfs.newFileChannel(getResolvedPath(), options, attrs);
}
- @Override
- public SeekableByteChannel newByteChannel(OpenOption... options)
- throws IOException {
- Set<OpenOption> set = new HashSet<>(options.length);
- Collections.addAll(set, options);
- return newByteChannel(set);
- }
-
- @Override
- public void checkAccess(AccessMode... modes) throws IOException {
+ void checkAccess(AccessMode... modes) throws IOException {
boolean w = false;
boolean x = false;
for (AccessMode mode : modes) {
@@ -834,11 +764,9 @@
}
if (x)
throw new AccessDeniedException(toString());
-
}
- @Override
- public boolean exists() {
+ boolean exists() {
if (path.length == 1 && path[0] == '/')
return true;
try {
@@ -847,15 +775,7 @@
return false;
}
- @Override
- public boolean notExists() {
- return !exists();
- }
-
-
- @Override
- public OutputStream newOutputStream(OpenOption... options)
- throws IOException
+ OutputStream newOutputStream(OpenOption... options) throws IOException
{
if (options.length == 0)
return zfs.newOutputStream(getResolvedPath(),
@@ -863,42 +783,32 @@
return zfs.newOutputStream(getResolvedPath(), options);
}
- @Override
- public Path moveTo(Path target, CopyOption... options)
+ void move(ZipPath target, CopyOption... options)
throws IOException
{
- if (this.zfs.provider() == target.getFileSystem().provider() &&
- this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
+ if (Files.isSameFile(this.zfs.getZipFile(), target.zfs.getZipFile()))
{
zfs.copyFile(true,
- getResolvedPath(),
- ((ZipPath)target).getResolvedPath(),
+ getResolvedPath(), target.getResolvedPath(),
options);
} else {
copyToTarget(target, options);
delete();
}
- return target;
}
- @Override
- public Path copyTo(Path target, CopyOption... options)
+ void copy(ZipPath target, CopyOption... options)
throws IOException
{
- if (this.zfs.provider() == target.getFileSystem().provider() &&
- this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
- {
+ if (Files.isSameFile(this.zfs.getZipFile(), target.zfs.getZipFile()))
zfs.copyFile(false,
- getResolvedPath(),
- ((ZipPath)target).getResolvedPath(),
+ getResolvedPath(), target.getResolvedPath(),
options);
- } else {
+ else
copyToTarget(target, options);
- }
- return target;
}
- private void copyToTarget(Path target, CopyOption... options)
+ private void copyToTarget(ZipPath target, CopyOption... options)
throws IOException
{
boolean replaceExisting = false;
@@ -948,7 +858,7 @@
}
if (copyAttrs) {
BasicFileAttributeView view =
- target.getFileAttributeView(BasicFileAttributeView.class);
+ ZipFileAttributeView.get(target, BasicFileAttributeView.class);
try {
view.setTimes(zfas.lastModifiedTime(),
zfas.lastAccessTime(),
--- a/jdk/src/share/demo/zipfs Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,703 +0,0 @@
-/*
- * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import java.io.*;
-import java.nio.*;
-import java.nio.channels.*;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.net.*;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.*;
-
-import static java.nio.file.StandardOpenOption.*;
-import static java.nio.file.StandardCopyOption.*;
-
-/*
- * ZipFileSystem usage demo
- *
- * java Demo action ZipfileName [...]
- *
- * @author Xueming Shen
- */
-
-public class Demo {
-
- static enum Action {
- rename, // <java Demo rename zipfile src dst>
- // rename entry src to dst inside zipfile
-
- movein, // <java Demo movein zipfile src dst>
- // move an external src file into zipfile
- // as entry dst
-
- moveout, // <java Demo moveout zipfile src dst>
- // move a zipfile entry src out to dst
-
- copy, // <java Demo copy zipfile src dst>
- // copy entry src to dst inside zipfile
-
- copyin, // <java Demo copyin zipfile src dst>
- // copy an external src file into zipfile
- // as entry dst
-
- copyin_attrs, // <java Demo copyin_attrs zipfile src dst>
- // copy an external src file into zipfile
- // as entry dst, with attributes (timestamp)
-
- copyout, // <java Demo copyout zipfile src dst>
- // copy zipfile entry src" out to file dst
-
- copyout_attrs, // <java Demo copyout_attrs zipfile src dst>
-
- zzmove, // <java Demo zzmove zfsrc zfdst path>
- // move entry path/dir from zfsrc to zfdst
-
- zzcopy, // <java Demo zzcopy zfsrc zfdst path>
- // copy path from zipfile zfsrc to zipfile
- // zfdst
-
- attrs, // <java Demo attrs zipfile path>
- // printout the attributes of entry path
-
- attrsspace, // <java Demo attrsspace zipfile path>
- // printout the storespace attrs of entry path
-
- setmtime, // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
- // set the lastModifiedTime of entry path
-
- setatime, // <java Demo setatime zipfile "MM/dd/yy-HH:mm:ss" path...>
- setctime, // <java Demo setctime zipfile "MM/dd/yy-HH:mm:ss" path...>
-
- lsdir, // <java Demo lsdir zipfile dir>
- // list dir's direct child files/dirs
-
- mkdir, // <java Demo mkdir zipfile dir>
-
- mkdirs, // <java Demo mkdirs zipfile dir>
-
- rmdirs, // <java Demo rmdirs zipfile dir>
-
- list, // <java Demo list zipfile [dir]>
- // recursively list all entries of dir
- // via DirectoryStream
-
- tlist, // <java Demo tlist zipfile [dir]>
- // list with buildDirTree=true
-
- vlist, // <java Demo vlist zipfile [dir]>
- // recursively verbose list all entries of
- // dir via DirectoryStream
-
- walk, // <java Demo walk zipfile [dir]>
- // recursively walk all entries of dir
- // via Files.walkFileTree
-
- twalk, // <java Demo twalk zipfile [dir]>
- // walk with buildDirTree=true
-
- extract, // <java Demo extract zipfile file [...]>
-
- update, // <java Demo extract zipfile file [...]>
-
- delete, // <java Demo delete zipfile file [...]>
-
- add, // <java Demo add zipfile file [...]>
-
- create, // <java Demo create zipfile file [...]>
- // create a new zipfile if it doesn't exit
- // and then add the file(s) into it.
-
- attrs2, // <java Demo attrs2 zipfile file [...]>
- // test different ways to print attrs
-
- prof,
- }
-
- public static void main(String[] args) throws Throwable {
-
- Action action = Action.valueOf(args[0]);
- Map<String, Object> env = env = new HashMap<>();
- if (action == Action.create)
- env.put("create", "true");
- if (action == Action.tlist || action == Action.twalk)
- env.put("buildDirTree", true);
- FileSystem fs = FileSystems.newFileSystem(Paths.get(args[1]), env, null);
-
- try {
- FileSystem fs2;
- Path path, src, dst;
- boolean isRename = false;
- switch (action) {
- case rename:
- src = fs.getPath(args[2]);
- dst = fs.getPath(args[3]);
- src.moveTo(dst);
- break;
- case moveout:
- src = fs.getPath(args[2]);
- dst = Paths.get(args[3]);
- src.moveTo(dst);
- break;
- case movein:
- src = Paths.get(args[2]);
- dst = fs.getPath(args[3]);
- src.moveTo(dst);
- break;
- case copy:
- src = fs.getPath(args[2]);
- dst = fs.getPath(args[3]);
- src.copyTo(dst);
- break;
- case copyout:
- src = fs.getPath(args[2]);
- dst = Paths.get(args[3]);
- src.copyTo(dst);
- break;
- case copyin:
- src = Paths.get(args[2]);
- dst = fs.getPath(args[3]);
- src.copyTo(dst);
- break;
- case copyin_attrs:
- src = Paths.get(args[2]);
- dst = fs.getPath(args[3]);
- src.copyTo(dst, COPY_ATTRIBUTES);
- break;
- case copyout_attrs:
- src = fs.getPath(args[2]);
- dst = Paths.get(args[3]);
- src.copyTo(dst, COPY_ATTRIBUTES);
- break;
- case zzmove:
- fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
- //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3]));
- z2zmove(fs, fs2, args[3]);
- fs2.close();
- break;
- case zzcopy:
- fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
- //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3]));
- z2zcopy(fs, fs2, args[3]);
- fs2.close();
- break;
- case attrs:
- for (int i = 2; i < args.length; i++) {
- path = fs.getPath(args[i]);
- System.out.println(path);
- System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
- }
- break;
- case setmtime:
- DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
- Date newDatetime = df.parse(args[2]);
- for (int i = 3; i < args.length; i++) {
- path = fs.getPath(args[i]);
- path.setAttribute("lastModifiedTime",
- FileTime.fromMillis(newDatetime.getTime()));
- System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
- }
- break;
- case setctime:
- df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
- newDatetime = df.parse(args[2]);
- for (int i = 3; i < args.length; i++) {
- path = fs.getPath(args[i]);
- path.setAttribute("creationTime",
- FileTime.fromMillis(newDatetime.getTime()));
- System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
- }
- break;
- case setatime:
- df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
- newDatetime = df.parse(args[2]);
- for (int i = 3; i < args.length; i++) {
- path = fs.getPath(args[i]);
- path.setAttribute("lastAccessTime",
- FileTime.fromMillis(newDatetime.getTime()));
- System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
- }
- break;
- case attrsspace:
- path = fs.getPath("/");
- FileStore fstore = path.getFileStore();
- //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
- // .readAttributes());
- // or
- System.out.printf("filestore[%s]%n", fstore.name());
- System.out.printf(" totalSpace: %d%n",
- (Long)fstore.getAttribute("space:totalSpace"));
- System.out.printf(" usableSpace: %d%n",
- (Long)fstore.getAttribute("space:usableSpace"));
- System.out.printf(" unallocSpace: %d%n",
- (Long)fstore.getAttribute("space:unallocatedSpace"));
- break;
- case list:
- case tlist:
- if (args.length < 3)
- list(fs.getPath("/"), false);
- else
- list(fs.getPath(args[2]), false);
- break;
- case vlist:
- if (args.length < 3)
- list(fs.getPath("/"), true);
- else
- list(fs.getPath(args[2]), true);
- break;
- case twalk:
- case walk:
- walk(fs.getPath((args.length > 2)? args[2] : "/"));
- break;
- case extract:
- if (args.length == 2) {
- extract(fs, "/");
- } else {
- for (int i = 2; i < args.length; i++) {
- extract(fs, args[i]);
- }
- }
- break;
- case delete:
- for (int i = 2; i < args.length; i++)
- fs.getPath(args[i]).delete();
- break;
- case create:
- case add:
- case update:
- for (int i = 2; i < args.length; i++) {
- update(fs, args[i]);
- }
- break;
- case lsdir:
- path = fs.getPath(args[2]);
- final String fStr = (args.length > 3)?args[3]:"";
- DirectoryStream<Path> ds = path.newDirectoryStream(
- new DirectoryStream.Filter<Path>() {
- public boolean accept(Path path) {
- return path.toString().contains(fStr);
- }
- });
- for (Path p : ds)
- System.out.println(p);
- break;
- case mkdir:
- fs.getPath(args[2]).createDirectory();
- break;
- case mkdirs:
- mkdirs(fs.getPath(args[2]));
- break;
- case attrs2:
- for (int i = 2; i < args.length; i++) {
- path = fs.getPath(args[i]);
- System.out.printf("%n%s%n", path);
- System.out.println("-------(1)---------");
- System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
- System.out.println("-------(2)---------");
- Map<String, ?> map = path.readAttributes("zip:*");
- for (Map.Entry<String, ?> e : map.entrySet()) {
- System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
- }
- System.out.println("-------(3)---------");
- map = path.readAttributes("size,lastModifiedTime,isDirectory");
- for (Map.Entry<String, ?> e : map.entrySet()) {
- System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
- }
- }
- break;
- case prof:
- list(fs.getPath("/"), false);
- while (true) {
- Thread.sleep(10000);
- //list(fs.getPath("/"), true);
- System.out.println("sleeping...");
- }
- }
- } catch (Exception x) {
- x.printStackTrace();
- } finally {
- if (fs != null)
- fs.close();
- }
- }
-
- private static byte[] getBytes(String name) {
- return name.getBytes();
- }
-
- private static String getString(byte[] name) {
- return new String(name);
- }
-
- private static void walk(Path path) throws IOException
- {
- Files.walkFileTree(
- path,
- new SimpleFileVisitor<Path>() {
- private int indent = 0;
- private void indent() {
- int n = 0;
- while (n++ < indent)
- System.out.printf(" ");
- }
-
- @Override
- public FileVisitResult visitFile(Path file,
- BasicFileAttributes attrs)
- {
- indent();
- System.out.printf("%s%n", file.getName().toString());
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path dir,
- BasicFileAttributes attrs)
- {
- indent();
- System.out.printf("[%s]%n", dir.toString());
- indent += 2;
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult postVisitDirectory(Path dir,
- IOException ioe)
- {
- indent -= 2;
- return FileVisitResult.CONTINUE;
- }
- });
- }
-
- private static void update(FileSystem fs, String path) throws Throwable{
- Path src = FileSystems.getDefault().getPath(path);
- if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
- DirectoryStream<Path> ds = src.newDirectoryStream();
- for (Path child : ds)
- update(fs, child.toString());
- ds.close();
- } else {
- Path dst = fs.getPath(path);
- Path parent = dst.getParent();
- if (parent != null && parent.notExists())
- mkdirs(parent);
- src.copyTo(dst, REPLACE_EXISTING);
- }
- }
-
- private static void extract(FileSystem fs, String path) throws Throwable{
- Path src = fs.getPath(path);
- if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
- DirectoryStream<Path> ds = src.newDirectoryStream();
- for (Path child : ds)
- extract(fs, child.toString());
- ds.close();
- } else {
- if (path.startsWith("/"))
- path = path.substring(1);
- Path dst = FileSystems.getDefault().getPath(path);
- Path parent = dst.getParent();
- if (parent.notExists())
- mkdirs(parent);
- src.copyTo(dst, REPLACE_EXISTING);
- }
- }
-
- // use DirectoryStream
- private static void z2zcopy(FileSystem src, FileSystem dst, String path)
- throws IOException
- {
- Path srcPath = src.getPath(path);
- Path dstPath = dst.getPath(path);
-
- if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
- if (!dstPath.exists()) {
- try {
- mkdirs(dstPath);
- } catch (FileAlreadyExistsException x) {}
- }
- DirectoryStream<Path> ds = srcPath.newDirectoryStream();
- for (Path child : ds) {
- z2zcopy(src, dst,
- path + (path.endsWith("/")?"":"/") + child.getName());
- }
- ds.close();
- } else {
- //System.out.println("copying..." + path);
- srcPath.copyTo(dstPath);
- }
- }
-
- // use TreeWalk to move
- private static void z2zmove(FileSystem src, FileSystem dst, String path)
- throws IOException
- {
- final Path srcPath = src.getPath(path).toAbsolutePath();
- final Path dstPath = dst.getPath(path).toAbsolutePath();
-
- Files.walkFileTree(srcPath, new SimpleFileVisitor<Path>() {
-
- @Override
- public FileVisitResult visitFile(Path file,
- BasicFileAttributes attrs)
- {
- Path dst = srcPath.relativize(file);
- dst = dstPath.resolve(dst);
- try {
- Path parent = dstPath.getParent();
- if (parent != null && parent.notExists())
- mkdirs(parent);
- file.moveTo(dst);
- } catch (IOException x) {
- x.printStackTrace();
- }
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path dir,
- BasicFileAttributes attrs)
- {
- Path dst = srcPath.relativize(dir);
- dst = dstPath.resolve(dst);
- try {
-
- if (dst.notExists())
- mkdirs(dst);
- } catch (IOException x) {
- x.printStackTrace();
- }
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult postVisitDirectory(Path dir,
- IOException ioe)
- throws IOException
- {
- try {
- dir.delete();
- } catch (IOException x) {
- //x.printStackTrace();
- }
- return FileVisitResult.CONTINUE;
- }
- });
-
- }
-
- private static void mkdirs(Path path) throws IOException {
- path = path.toAbsolutePath();
- Path parent = path.getParent();
- if (parent != null) {
- if (parent.notExists())
- mkdirs(parent);
- }
- path.createDirectory();
- }
-
- private static void rmdirs(Path path) throws IOException {
- while (path != null && path.getNameCount() != 0) {
- path.delete();
- path = path.getParent();
- }
- }
-
- private static void list(Path path, boolean verbose ) throws IOException {
- if (!"/".equals(path.toString())) {
- System.out.printf(" %s%n", path.toString());
- if (verbose)
- System.out.println(Attributes.readBasicFileAttributes(path).toString());
- }
- if (path.notExists())
- return;
- if (Attributes.readBasicFileAttributes(path).isDirectory()) {
- DirectoryStream<Path> ds = path.newDirectoryStream();
- for (Path child : ds)
- list(child, verbose);
- ds.close();
- }
- }
-
- // check the content of two paths are equal
- private static void checkEqual(Path src, Path dst) throws IOException
- {
- //System.out.printf("checking <%s> vs <%s>...%n",
- // src.toString(), dst.toString());
-
- //streams
- InputStream isSrc = src.newInputStream();
- InputStream isDst = dst.newInputStream();
- byte[] bufSrc = new byte[8192];
- byte[] bufDst = new byte[8192];
-
- try {
- int nSrc = 0;
- while ((nSrc = isSrc.read(bufSrc)) != -1) {
- int nDst = 0;
- while (nDst < nSrc) {
- int n = isDst.read(bufDst, nDst, nSrc - nDst);
- if (n == -1) {
- System.out.printf("checking <%s> vs <%s>...%n",
- src.toString(), dst.toString());
- throw new RuntimeException("CHECK FAILED!");
- }
- nDst += n;
- }
- while (--nSrc >= 0) {
- if (bufSrc[nSrc] != bufDst[nSrc]) {
- System.out.printf("checking <%s> vs <%s>...%n",
- src.toString(), dst.toString());
- throw new RuntimeException("CHECK FAILED!");
- }
- nSrc--;
- }
- }
- } finally {
- isSrc.close();
- isDst.close();
- }
-
- // channels
- SeekableByteChannel chSrc = src.newByteChannel();
- SeekableByteChannel chDst = dst.newByteChannel();
- if (chSrc.size() != chDst.size()) {
- System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
- chSrc.toString(), chSrc.size(),
- chDst.toString(), chDst.size());
- throw new RuntimeException("CHECK FAILED!");
- }
- ByteBuffer bbSrc = ByteBuffer.allocate(8192);
- ByteBuffer bbDst = ByteBuffer.allocate(8192);
-
- try {
- int nSrc = 0;
- while ((nSrc = chSrc.read(bbSrc)) != -1) {
- int nDst = chDst.read(bbDst);
- if (nSrc != nDst) {
- System.out.printf("checking <%s> vs <%s>...%n",
- src.toString(), dst.toString());
- throw new RuntimeException("CHECK FAILED!");
- }
- while (--nSrc >= 0) {
- if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
- System.out.printf("checking <%s> vs <%s>...%n",
- src.toString(), dst.toString());
- throw new RuntimeException("CHECK FAILED!");
- }
- nSrc--;
- }
- bbSrc.flip();
- bbDst.flip();
- }
- } catch (IOException x) {
- x.printStackTrace();
- } finally {
- chSrc.close();
- chDst.close();
- }
- }
-
- private static void fchCopy(Path src, Path dst) throws IOException
- {
- Set<OpenOption> read = new HashSet<>();
- read.add(READ);
- Set<OpenOption> openwrite = new HashSet<>();
- openwrite.add(CREATE_NEW);
- openwrite.add(WRITE);
-
- FileChannel srcFc = src.getFileSystem()
- .provider()
- .newFileChannel(src, read);
- FileChannel dstFc = dst.getFileSystem()
- .provider()
- .newFileChannel(dst, openwrite);
-
- try {
- ByteBuffer bb = ByteBuffer.allocate(8192);
- while (srcFc.read(bb) >= 0) {
- bb.flip();
- dstFc.write(bb);
- bb.clear();
- }
- } finally {
- srcFc.close();
- dstFc.close();
- }
- }
-
- private static void chCopy(Path src, Path dst) throws IOException
- {
- Set<OpenOption> read = new HashSet<>();
- read.add(READ);
- Set<OpenOption> openwrite = new HashSet<>();
- openwrite.add(CREATE_NEW);
- openwrite.add(WRITE);
-
- SeekableByteChannel srcCh = src.newByteChannel(read);
- SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
-
- try {
- ByteBuffer bb = ByteBuffer.allocate(8192);
- while (srcCh.read(bb) >= 0) {
- bb.flip();
- dstCh.write(bb);
- bb.clear();
- }
- } finally {
- srcCh.close();
- dstCh.close();
- }
- }
-
- private static void streamCopy(Path src, Path dst) throws IOException
- {
- InputStream isSrc = src.newInputStream();
- OutputStream osDst = dst.newOutputStream();
- byte[] buf = new byte[8192];
- try {
- int n = 0;
- while ((n = isSrc.read(buf)) != -1) {
- osDst.write(buf, 0, n);
- }
- } finally {
- isSrc.close();
- osDst.close();
- }
- }
-}
--- a/jdk/src/share/native/java/io/io_util.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/java/io/io_util.c Mon Feb 14 16:30:10 2011 -0800
@@ -44,7 +44,7 @@
JNU_ThrowIOException(env, "Stream Closed");
return -1;
}
- nread = IO_Read(fd, &ret, 1);
+ nread = (jint)IO_Read(fd, &ret, 1);
if (nread == 0) { /* EOF */
return -1;
} else if (nread == JVM_IO_ERR) { /* error */
@@ -108,7 +108,7 @@
JNU_ThrowIOException(env, "Stream Closed");
nread = -1;
} else {
- nread = IO_Read(fd, buf, len);
+ nread = (jint)IO_Read(fd, buf, len);
if (nread > 0) {
(*env)->SetByteArrayRegion(env, bytes, off, nread, (jbyte *)buf);
} else if (nread == JVM_IO_ERR) {
@@ -137,9 +137,9 @@
return;
}
if (append == JNI_TRUE) {
- n = IO_Append(fd, &c, 1);
+ n = (jint)IO_Append(fd, &c, 1);
} else {
- n = IO_Write(fd, &c, 1);
+ n = (jint)IO_Write(fd, &c, 1);
}
if (n == JVM_IO_ERR) {
JNU_ThrowIOExceptionWithLastError(env, "Write error");
@@ -190,9 +190,9 @@
break;
}
if (append == JNI_TRUE) {
- n = IO_Append(fd, buf+off, len);
+ n = (jint)IO_Append(fd, buf+off, len);
} else {
- n = IO_Write(fd, buf+off, len);
+ n = (jint)IO_Write(fd, buf+off, len);
}
if (n == JVM_IO_ERR) {
JNU_ThrowIOExceptionWithLastError(env, "Write error");
--- a/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp Mon Feb 14 16:30:10 2011 -0800
@@ -38,7 +38,7 @@
/*
* Throws an arbitrary Java exception.
*/
-void ThrowException(JNIEnv *env, char *exceptionName)
+void ThrowException(JNIEnv *env, const char *exceptionName)
{
jclass exceptionClazz = env->FindClass(exceptionName);
env->ThrowNew(exceptionClazz, NULL);
@@ -89,7 +89,7 @@
// Fill a new ECParams using the supplied OID
if (EC_DecodeParams(¶ms_item, &ecparams, 0) != SECSuccess) {
/* bad curve OID */
- ThrowException(env, (char *) INVALID_ALGORITHM_PARAMETER_EXCEPTION);
+ ThrowException(env, INVALID_ALGORITHM_PARAMETER_EXCEPTION);
goto cleanup;
}
@@ -101,7 +101,7 @@
// Generate the new keypair (using the supplied seed)
if (EC_NewKey(ecparams, &privKey, (unsigned char *) pSeedBuffer,
jSeedLength, 0) != SECSuccess) {
- ThrowException(env, (char *) KEY_EXCEPTION);
+ ThrowException(env, KEY_EXCEPTION);
goto cleanup;
}
--- a/jdk/src/share/native/sun/security/ec/impl/ec.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec.c Mon Feb 14 16:30:10 2011 -0800
@@ -51,12 +51,10 @@
*
*********************************************************************** */
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mplogic.h"
#include "ec.h"
#include "ecl.h"
@@ -67,6 +65,7 @@
#include <string.h>
#ifndef _WIN32
+#include <stdio.h>
#include <strings.h>
#endif /* _WIN32 */
@@ -116,7 +115,7 @@
ECGroup *group = NULL;
SECStatus rv = SECFailure;
mp_err err = MP_OKAY;
- int len;
+ unsigned int len;
#if EC_DEBUG
int i;
@@ -278,10 +277,6 @@
printf("ec_NewKey called\n");
#endif
-#ifndef _WIN32
-int printf();
-#endif /* _WIN32 */
-
if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@@ -361,8 +356,9 @@
cleanup:
mp_clear(&k);
- if (rv)
+ if (rv) {
PORT_FreeArena(arena, PR_TRUE);
+ }
#if EC_DEBUG
printf("ec_NewKey returning %s\n",
@@ -504,7 +500,7 @@
ECGroup *group = NULL;
SECStatus rv = SECFailure;
mp_err err = MP_OKAY;
- int len;
+ unsigned int len;
if (!ecParams || !publicValue) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -778,7 +774,7 @@
/* In the definition of EC signing, digests are truncated
* to the length of n in bits.
* (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
- if (digest->len*8 > ecParams->fieldID.size) {
+ if (digest->len*8 > (unsigned int)ecParams->fieldID.size) {
mpl_rsh(&s,&s,digest->len*8 - ecParams->fieldID.size);
}
@@ -993,7 +989,8 @@
/* In the definition of EC signing, digests are truncated
* to the length of n in bits.
* (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
- if (digest->len*8 > ecParams->fieldID.size) { /* u1 = HASH(M') */
+ /* u1 = HASH(M') */
+ if (digest->len*8 > (unsigned int)ecParams->fieldID.size) {
mpl_rsh(&u1,&u1,digest->len*8- ecParams->fieldID.size);
}
--- a/jdk/src/share/native/sun/security/ec/impl/ec.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec.h Mon Feb 14 16:30:10 2011 -0800
@@ -57,8 +57,6 @@
#ifndef __ec_h_
#define __ec_h_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#define EC_DEBUG 0
#define EC_POINT_FORM_COMPRESSED_Y0 0x02
#define EC_POINT_FORM_COMPRESSED_Y1 0x03
--- a/jdk/src/share/native/sun/security/ec/impl/ec2.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2.h Mon Feb 14 16:30:10 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _EC2_H
#define _EC2_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl-priv.h"
/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
--- a/jdk/src/share/native/sun/security/ec/impl/ec2_163.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_163.c Mon Feb 14 16:30:10 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ec2.h"
#include "mp_gf2m.h"
#include "mp_gf2m-priv.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ec2_193.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_193.c Mon Feb 14 16:30:10 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ec2.h"
#include "mp_gf2m.h"
#include "mp_gf2m-priv.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ec2_233.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_233.c Mon Feb 14 16:30:10 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ec2.h"
#include "mp_gf2m.h"
#include "mp_gf2m-priv.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ec2_aff.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_aff.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ec2.h"
#include "mplogic.h"
#include "mp_gf2m.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ec2_mont.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_mont.c Mon Feb 14 16:30:10 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ec2.h"
#include "mplogic.h"
#include "mp_gf2m.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ec_naf.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec_naf.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl-priv.h"
/* Returns 2^e as an integer. This is meant to be used for small powers of
--- a/jdk/src/share/native/sun/security/ec/impl/ecc_impl.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecc_impl.h Mon Feb 14 16:30:10 2011 -0800
@@ -51,15 +51,13 @@
*
*********************************************************************** */
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _ECC_IMPL_H
#define _ECC_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -82,6 +80,7 @@
typedef unsigned char uint8_t;
typedef unsigned long ulong_t;
typedef enum boolean { B_FALSE, B_TRUE } boolean_t;
+#define strdup _strdup /* Replace POSIX name with ISO C++ name */
#endif /* _WIN32 */
#ifndef _KERNEL
--- a/jdk/src/share/native/sun/security/ec/impl/ecdecode.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecdecode.c Mon Feb 14 16:30:10 2011 -0800
@@ -55,8 +55,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#ifndef _WIN32
@@ -90,7 +88,7 @@
{
int i = 0;
int byteval = 0;
- int tmp = strlen(str);
+ int tmp = (int)strlen(str);
if ((tmp % 2) != 0) return NULL;
@@ -134,7 +132,8 @@
/* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
- if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup;
+ if (((int)name < ECCurve_noName) || (name > ECCurve_pastLastCurve))
+ goto cleanup;
params->name = name;
curveParams = ecCurve_map[params->name];
CHECK_OK(curveParams);
--- a/jdk/src/share/native/sun/security/ec/impl/ecl-curve.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl-curve.h Mon Feb 14 16:30:10 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _ECL_CURVE_H
#define _ECL_CURVE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl-exp.h"
#ifndef _KERNEL
#include <stdlib.h>
--- a/jdk/src/share/native/sun/security/ec/impl/ecl-exp.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl-exp.h Mon Feb 14 16:30:10 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _ECL_EXP_H
#define _ECL_EXP_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* Curve field type */
typedef enum {
ECField_GFp,
--- a/jdk/src/share/native/sun/security/ec/impl/ecl-priv.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl-priv.h Mon Feb 14 16:30:10 2011 -0800
@@ -58,8 +58,6 @@
#ifndef _ECL_PRIV_H
#define _ECL_PRIV_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl.h"
#include "mpi.h"
#include "mplogic.h"
@@ -90,6 +88,10 @@
s = ACCUM(w); \
cout = CARRYOUT(w); }
+/* Handle case when carry-in value is zero */
+#define MP_ADD_CARRY_ZERO(a1, a2, s, cout) \
+ MP_ADD_CARRY(a1, a2, s, 0, cout);
+
#define MP_SUB_BORROW(a1, a2, s, bin, bout) \
{ mp_word w; \
w = ((mp_word)(a1)) - (a2) - (bin); \
@@ -111,6 +113,15 @@
s = sum += (cin); \
cout = tmp + (sum < (cin)); }
+/* Handle case when carry-in value is zero */
+#define MP_ADD_CARRY_ZERO(a1, a2, s, cout) \
+ { mp_digit tmp,sum; \
+ tmp = (a1); \
+ sum = tmp + (a2); \
+ tmp = (sum < tmp); /* detect overflow */ \
+ s = sum; \
+ cout = tmp; }
+
#define MP_SUB_BORROW(a1, a2, s, bin, bout) \
{ mp_digit tmp; \
tmp = (a1); \
--- a/jdk/src/share/native/sun/security/ec/impl/ecl.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi.h"
#include "mplogic.h"
#include "ecl.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ecl.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl.h Mon Feb 14 16:30:10 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _ECL_H
#define _ECL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* Although this is not an exported header file, code which uses elliptic
* curve point operations will need to include it. */
--- a/jdk/src/share/native/sun/security/ec/impl/ecl_curve.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl_curve.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl.h"
#include "ecl-curve.h"
#include "ecl-priv.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ecl_gf.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl_gf.c Mon Feb 14 16:30:10 2011 -0800
@@ -55,8 +55,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi.h"
#include "mp_gf2m.h"
#include "ecl-priv.h"
@@ -307,7 +305,7 @@
}
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(a0, r0, r0, carry);
MP_ADD_CARRY(a1, r1, r1, carry, carry);
MP_ADD_CARRY(a2, r2, r2, carry, carry);
#else
@@ -394,7 +392,7 @@
}
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(a0, r0, r0, carry);
MP_ADD_CARRY(a1, r1, r1, carry, carry);
MP_ADD_CARRY(a2, r2, r2, carry, carry);
MP_ADD_CARRY(a3, r3, r3, carry, carry);
@@ -491,7 +489,7 @@
r0 = MP_DIGIT(b,0);
}
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(a0, r0, r0, carry);
MP_ADD_CARRY(a1, r1, r1, carry, carry);
MP_ADD_CARRY(a2, r2, r2, carry, carry);
MP_ADD_CARRY(a3, r3, r3, carry, carry);
@@ -572,7 +570,7 @@
r0 = MP_DIGIT(b,0);
}
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(a0, r0, r0, carry);
MP_ADD_CARRY(a1, r1, r1, carry, carry);
MP_ADD_CARRY(a2, r2, r2, carry, carry);
MP_ADD_CARRY(a3, r3, r3, carry, carry);
@@ -675,7 +673,7 @@
b1 = MP_DIGIT(&meth->irr,1);
b0 = MP_DIGIT(&meth->irr,0);
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
+ MP_ADD_CARRY_ZERO(b0, r0, r0, borrow);
MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
#else
@@ -766,7 +764,7 @@
b1 = MP_DIGIT(&meth->irr,1);
b0 = MP_DIGIT(&meth->irr,0);
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
+ MP_ADD_CARRY_ZERO(b0, r0, r0, borrow);
MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
@@ -850,7 +848,7 @@
b2 = MP_DIGIT(&meth->irr,2);
b1 = MP_DIGIT(&meth->irr,1);
b0 = MP_DIGIT(&meth->irr,0);
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
+ MP_ADD_CARRY_ZERO(b0, r0, r0, borrow);
MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
@@ -924,7 +922,7 @@
b2 = MP_DIGIT(&meth->irr,2);
b1 = MP_DIGIT(&meth->irr,1);
b0 = MP_DIGIT(&meth->irr,0);
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
+ MP_ADD_CARRY_ZERO(b0, r0, r0, borrow);
MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
--- a/jdk/src/share/native/sun/security/ec/impl/ecl_mult.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl_mult.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi.h"
#include "mplogic.h"
#include "ecl.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ecp.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp.h Mon Feb 14 16:30:10 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _ECP_H
#define _ECP_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl-priv.h"
/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_192.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_192.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mpi.h"
#include "mplogic.h"
@@ -210,15 +208,15 @@
/* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(r0, a3, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, a3, r0, carry);
MP_ADD_CARRY(r1, a3, r1, carry, carry);
MP_ADD_CARRY(r2, a4, r2, carry, carry);
r3 = carry;
- MP_ADD_CARRY(r0, a5, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, a5, r0, carry);
MP_ADD_CARRY(r1, a5, r1, carry, carry);
MP_ADD_CARRY(r2, a5, r2, carry, carry);
r3 += carry;
- MP_ADD_CARRY(r1, a4, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1, a4, r1, carry);
MP_ADD_CARRY(r2, 0, r2, carry, carry);
r3 += carry;
@@ -251,7 +249,7 @@
/* reduce out the carry */
while (r3) {
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(r0, r3, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, r3, r0, carry);
MP_ADD_CARRY(r1, r3, r1, carry, carry);
MP_ADD_CARRY(r2, 0, r2, carry, carry);
r3 = carry;
@@ -335,7 +333,7 @@
}
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(a0, r0, r0, carry);
MP_ADD_CARRY(a1, r1, r1, carry, carry);
MP_ADD_CARRY(a2, r2, r2, carry, carry);
#else
@@ -357,7 +355,7 @@
((r1 == MP_DIGIT_MAX) ||
((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) {
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(r0, 1, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, 1, r0, carry);
MP_ADD_CARRY(r1, 1, r1, carry, carry);
MP_ADD_CARRY(r2, 0, r2, carry, carry);
#else
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_224.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_224.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mpi.h"
#include "mplogic.h"
@@ -251,10 +249,10 @@
+( 0, a6,a5b, 0)
-( 0 0, 0|a6b, a6a|a5b )
-( a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */
- MP_ADD_CARRY (r1, a3b, r1, 0, carry);
+ MP_ADD_CARRY_ZERO (r1, a3b, r1, carry);
MP_ADD_CARRY (r2, a4 , r2, carry, carry);
MP_ADD_CARRY (r3, a5a, r3, carry, carry);
- MP_ADD_CARRY (r1, a5b, r1, 0, carry);
+ MP_ADD_CARRY_ZERO (r1, a5b, r1, carry);
MP_ADD_CARRY (r2, a6 , r2, carry, carry);
MP_ADD_CARRY (r3, 0, r3, carry, carry);
@@ -275,7 +273,7 @@
r3b = (int)(r3 >>32);
while (r3b > 0) {
r3 &= 0xffffffff;
- MP_ADD_CARRY(r1,((mp_digit)r3b) << 32, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1,((mp_digit)r3b) << 32, r1, carry);
if (carry) {
MP_ADD_CARRY(r2, 0, r2, carry, carry);
MP_ADD_CARRY(r3, 0, r3, carry, carry);
@@ -290,7 +288,7 @@
}
while (r3b < 0) {
- MP_ADD_CARRY (r0, 1, r0, 0, carry);
+ MP_ADD_CARRY_ZERO (r0, 1, r0, carry);
MP_ADD_CARRY (r1, MP_DIGIT_MAX <<32, r1, carry, carry);
MP_ADD_CARRY (r2, MP_DIGIT_MAX, r2, carry, carry);
MP_ADD_CARRY (r3, MP_DIGIT_MAX >> 32, r3, carry, carry);
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_256.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_256.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mpi.h"
#include "mplogic.h"
@@ -303,32 +301,32 @@
r0 = MP_DIGIT(a,0);
/* sum 1 */
- MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1, a5h << 32, r1, carry);
MP_ADD_CARRY(r2, a6, r2, carry, carry);
MP_ADD_CARRY(r3, a7, r3, carry, carry);
r4 = carry;
- MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1, a5h << 32, r1, carry);
MP_ADD_CARRY(r2, a6, r2, carry, carry);
MP_ADD_CARRY(r3, a7, r3, carry, carry);
r4 += carry;
/* sum 2 */
- MP_ADD_CARRY(r1, a6l, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1, a6l, r1, carry);
MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
MP_ADD_CARRY(r3, a7h, r3, carry, carry);
r4 += carry;
- MP_ADD_CARRY(r1, a6l, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1, a6l, r1, carry);
MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
MP_ADD_CARRY(r3, a7h, r3, carry, carry);
r4 += carry;
/* sum 3 */
- MP_ADD_CARRY(r0, a4, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, a4, r0, carry);
MP_ADD_CARRY(r1, a5l >> 32, r1, carry, carry);
MP_ADD_CARRY(r2, 0, r2, carry, carry);
MP_ADD_CARRY(r3, a7, r3, carry, carry);
r4 += carry;
/* sum 4 */
- MP_ADD_CARRY(r0, a4h | a5l, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, a4h | a5l, r0, carry);
MP_ADD_CARRY(r1, a5h|(a6h<<32), r1, carry, carry);
MP_ADD_CARRY(r2, a7, r2, carry, carry);
MP_ADD_CARRY(r3, a6h | a4l, r3, carry, carry);
@@ -362,7 +360,7 @@
while (r4 > 0) {
mp_digit r4_long = r4;
mp_digit r4l = (r4_long << 32);
- MP_ADD_CARRY(r0, r4_long, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, r4_long, r0, carry);
MP_ADD_CARRY(r1, -r4l, r1, carry, carry);
MP_ADD_CARRY(r2, MP_DIGIT_MAX, r2, carry, carry);
MP_ADD_CARRY(r3, r4l-r4_long-1,r3, carry, carry);
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_384.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_384.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mpi.h"
#include "mplogic.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_521.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_521.c Mon Feb 14 16:30:10 2011 -0800
@@ -50,12 +50,10 @@
*
*********************************************************************** */
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mpi.h"
#include "mplogic.h"
@@ -74,7 +72,7 @@
{
mp_err res = MP_OKAY;
int a_bits = mpl_significant_bits(a);
- int i;
+ unsigned int i;
/* m1, m2 are statically-allocated mp_int of exactly the size we need */
mp_int m1;
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_aff.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_aff.c Mon Feb 14 16:30:10 2011 -0800
@@ -59,8 +59,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mplogic.h"
#ifndef _KERNEL
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_jac.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_jac.c Mon Feb 14 16:30:10 2011 -0800
@@ -59,8 +59,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mplogic.h"
#ifndef _KERNEL
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_jm.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_jm.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "ecl-priv.h"
#include "mplogic.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_mont.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_mont.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* Uses Montgomery reduction for field arithmetic. See mpi/mpmontg.c for
* code implementation. */
--- a/jdk/src/share/native/sun/security/ec/impl/logtab.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/logtab.h Mon Feb 14 16:30:10 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _LOGTAB_H
#define _LOGTAB_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
const float s_logv_2[] = {
0.000000000f, 0.000000000f, 1.000000000f, 0.630929754f, /* 0 1 2 3 */
0.500000000f, 0.430676558f, 0.386852807f, 0.356207187f, /* 4 5 6 7 */
--- a/jdk/src/share/native/sun/security/ec/impl/mp_gf2m-priv.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mp_gf2m-priv.h Mon Feb 14 16:30:10 2011 -0800
@@ -58,8 +58,6 @@
#ifndef _MP_GF2M_PRIV_H_
#define _MP_GF2M_PRIV_H_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi-priv.h"
extern const mp_digit mp_gf2m_sqr_tb[16];
--- a/jdk/src/share/native/sun/security/ec/impl/mp_gf2m.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mp_gf2m.c Mon Feb 14 16:30:10 2011 -0800
@@ -55,8 +55,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mp_gf2m.h"
#include "mp_gf2m-priv.h"
#include "mplogic.h"
--- a/jdk/src/share/native/sun/security/ec/impl/mp_gf2m.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mp_gf2m.h Mon Feb 14 16:30:10 2011 -0800
@@ -58,8 +58,6 @@
#ifndef _MP_GF2M_H_
#define _MP_GF2M_H_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi.h"
mp_err mp_badd(const mp_int *a, const mp_int *b, mp_int *c);
--- a/jdk/src/share/native/sun/security/ec/impl/mpi-config.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi-config.h Mon Feb 14 16:30:10 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _MPI_CONFIG_H
#define _MPI_CONFIG_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mpi-config.h,v 1.5 2004/04/25 15:03:10 gerv%gerv.net Exp $ */
/*
--- a/jdk/src/share/native/sun/security/ec/impl/mpi-priv.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi-priv.h Mon Feb 14 16:30:10 2011 -0800
@@ -63,8 +63,6 @@
#ifndef _MPI_PRIV_H
#define _MPI_PRIV_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mpi-priv.h,v 1.20 2005/11/22 07:16:43 relyea%netscape.com Exp $ */
#include "mpi.h"
--- a/jdk/src/share/native/sun/security/ec/impl/mpi.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi.c Mon Feb 14 16:30:10 2011 -0800
@@ -54,12 +54,10 @@
*
*********************************************************************** */
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mpi.c,v 1.45 2006/09/29 20:12:21 alexei.volkov.bugs%sun.com Exp $ */
#include "mpi-priv.h"
@@ -1148,7 +1146,7 @@
mp_int s, x;
mp_err res;
mp_digit d;
- int dig, bit;
+ unsigned int dig, bit;
ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
@@ -1523,7 +1521,7 @@
mp_int s, x, mu;
mp_err res;
mp_digit d;
- int dig, bit;
+ unsigned int dig, bit;
ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
@@ -2057,7 +2055,7 @@
{
mp_digit d;
mp_size n = 0;
- int ix;
+ unsigned int ix;
if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))
return n;
@@ -2900,9 +2898,9 @@
/* Allocate ni records of nb bytes each, and return a pointer to that */
void *s_mp_alloc(size_t nb, size_t ni, int kmflag)
{
- mp_int *mp;
++mp_allocs;
#ifdef _KERNEL
+ mp_int *mp;
mp = kmem_zalloc(nb * ni, kmflag);
if (mp != NULL)
FLAG(mp) = kmflag;
@@ -3112,7 +3110,7 @@
mp_err s_mp_mul_2(mp_int *mp)
{
mp_digit *pd;
- int ix, used;
+ unsigned int ix, used;
mp_digit kin = 0;
/* Shift digits leftward by 1 bit */
@@ -4663,7 +4661,7 @@
{
char ch;
- if(val >= r)
+ if(val >= (unsigned int)r)
return 0;
ch = s_dmap_1[val];
@@ -4778,7 +4776,7 @@
mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
{
int ix, pos = 0;
- int bytes;
+ unsigned int bytes;
ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
@@ -4810,7 +4808,7 @@
mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
{
int ix, pos = 0;
- int bytes;
+ unsigned int bytes;
ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
@@ -4850,7 +4848,7 @@
mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
{
int ix, pos = 0;
- int bytes;
+ unsigned int bytes;
ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
--- a/jdk/src/share/native/sun/security/ec/impl/mpi.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi.h Mon Feb 14 16:30:10 2011 -0800
@@ -60,8 +60,6 @@
#ifndef _MPI_H
#define _MPI_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mpi.h,v 1.22 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
#include "mpi-config.h"
--- a/jdk/src/share/native/sun/security/ec/impl/mplogic.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mplogic.c Mon Feb 14 16:30:10 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mplogic.c,v 1.15 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
#include "mpi-priv.h"
--- a/jdk/src/share/native/sun/security/ec/impl/mplogic.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mplogic.h Mon Feb 14 16:30:10 2011 -0800
@@ -59,8 +59,6 @@
#ifndef _MPLOGIC_H
#define _MPLOGIC_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mplogic.h,v 1.7 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
#include "mpi.h"
--- a/jdk/src/share/native/sun/security/ec/impl/mpmontg.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpmontg.c Mon Feb 14 16:30:10 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mpmontg.c,v 1.20 2006/08/29 02:41:38 nelson%bolyard.com Exp $ */
/* This file implements moduluar exponentiation using Montgomery's
--- a/jdk/src/share/native/sun/security/ec/impl/mpprime.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpprime.h Mon Feb 14 16:30:10 2011 -0800
@@ -60,8 +60,6 @@
#ifndef _MP_PRIME_H
#define _MP_PRIME_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi.h"
extern const int prime_tab_size; /* number of primes available */
--- a/jdk/src/share/native/sun/security/ec/impl/oid.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/oid.c Mon Feb 14 16:30:10 2011 -0800
@@ -50,12 +50,10 @@
*
*********************************************************************** */
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#ifndef _WIN32
@@ -433,8 +431,7 @@
SECOID_FindOID(const SECItem *oid)
{
SECOidData *po;
- SECOidData *ret;
- int i;
+ SECOidData *ret = NULL;
if (oid->len == 8) {
if (oid->data[6] == 0x00) {
@@ -454,8 +451,6 @@
po = &SECG_oids[oid->data[4]];
if (memcmp(oid->data, po->oid.data, 5) == 0)
ret = po;
- } else {
- ret = NULL;
}
return(ret);
}
--- a/jdk/src/share/native/sun/security/ec/impl/secitem.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/secitem.c Mon Feb 14 16:30:10 2011 -0800
@@ -53,8 +53,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Support routines for SECItem data structure.
*
--- a/jdk/src/share/native/sun/security/ec/impl/secoidt.h Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/secoidt.h Mon Feb 14 16:30:10 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _SECOIDT_H_
#define _SECOIDT_H_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* secoidt.h - public data structures for ASN.1 OID functions
*
--- a/jdk/src/share/sample/nio/file/AclEdit.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/sample/nio/file/AclEdit.java Mon Feb 14 16:30:10 2011 -0800
@@ -239,7 +239,7 @@
// read file's ACL
AclFileAttributeView view =
- file.getFileAttributeView(AclFileAttributeView.class);
+ Files.getFileAttributeView(file, AclFileAttributeView.class);
if (view == null) {
System.err.println("ACLs not supported on this platform");
System.exit(-1);
--- a/jdk/src/share/sample/nio/file/Chmod.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/sample/nio/file/Chmod.java Mon Feb 14 16:30:10 2011 -0800
@@ -264,11 +264,10 @@
/**
* Changes the permissions of the file using the given Changer.
*/
- static void chmod(FileRef file, Changer changer) {
+ static void chmod(Path file, Changer changer) {
try {
- Set<PosixFilePermission> perms = Attributes
- .readPosixFileAttributes(file).permissions();
- Attributes.setPosixFilePermissions(file, changer.change(perms));
+ Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file);
+ Files.setPosixFilePermissions(file, changer.change(perms));
} catch (IOException x) {
System.err.println(x);
}
@@ -277,7 +276,7 @@
/**
* Changes the permission of each file and directory visited
*/
- static class TreeVisitor implements FileVisitor<FileRef> {
+ static class TreeVisitor implements FileVisitor<Path> {
private final Changer changer;
TreeVisitor(Changer changer) {
@@ -285,26 +284,26 @@
}
@Override
- public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
chmod(dir, changer);
return CONTINUE;
}
@Override
- public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
chmod(file, changer);
return CONTINUE;
}
@Override
- public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
if (exc != null)
System.err.println("WARNING: " + exc);
return CONTINUE;
}
@Override
- public FileVisitResult visitFileFailed(FileRef file, IOException exc) {
+ public FileVisitResult visitFileFailed(Path file, IOException exc) {
System.err.println("WARNING: " + exc);
return CONTINUE;
}
--- a/jdk/src/share/sample/nio/file/Copy.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/sample/nio/file/Copy.java Mon Feb 14 16:30:10 2011 -0800
@@ -45,7 +45,7 @@
/**
* Returns {@code true} if okay to overwrite a file ("cp -i")
*/
- static boolean okayToOverwrite(FileRef file) {
+ static boolean okayToOverwrite(Path file) {
String answer = System.console().readLine("overwrite %s (yes/no)? ", file);
return (answer.equalsIgnoreCase("y") || answer.equalsIgnoreCase("yes"));
}
@@ -59,9 +59,9 @@
CopyOption[] options = (preserve) ?
new CopyOption[] { COPY_ATTRIBUTES, REPLACE_EXISTING } :
new CopyOption[] { REPLACE_EXISTING };
- if (!prompt || target.notExists() || okayToOverwrite(target)) {
+ if (!prompt || Files.notExists(target) || okayToOverwrite(target)) {
try {
- source.copyTo(target, options);
+ Files.copy(source, target, options);
} catch (IOException x) {
System.err.format("Unable to copy: %s: %s%n", source, x);
}
@@ -93,7 +93,7 @@
Path newdir = target.resolve(source.relativize(dir));
try {
- dir.copyTo(newdir, options);
+ Files.copy(dir, newdir, options);
} catch (FileAlreadyExistsException x) {
// ignore
} catch (IOException x) {
@@ -116,8 +116,8 @@
if (exc == null && preserve) {
Path newdir = target.resolve(source.relativize(dir));
try {
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir);
- Attributes.setLastModifiedTime(newdir, attrs.lastModifiedTime());
+ FileTime time = Files.getLastModifiedTime(dir);
+ Files.setLastModifiedTime(newdir, time);
} catch (IOException x) {
System.err.format("Unable to copy all attributes to: %s: %s%n", newdir, x);
}
@@ -180,16 +180,11 @@
Path target = Paths.get(args[argi]);
// check if target is a directory
- boolean isDir = false;
- try {
- isDir = Attributes.readBasicFileAttributes(target).isDirectory();
- } catch (IOException x) {
- // ignore (probably target does not exist)
- }
+ boolean isDir = Files.isDirectory(target);
// copy each source file/directory to target
for (i=0; i<source.length; i++) {
- Path dest = (isDir) ? target.resolve(source[i].getName()) : target;
+ Path dest = (isDir) ? target.resolve(source[i].getFileName()) : target;
if (recursive) {
// follow links when copying files
@@ -198,13 +193,9 @@
Files.walkFileTree(source[i], opts, Integer.MAX_VALUE, tc);
} else {
// not recursive so source must not be a directory
- try {
- if (Attributes.readBasicFileAttributes(source[i]).isDirectory()) {
- System.err.format("%s: is a directory%n", source[i]);
- continue;
- }
- } catch (IOException x) {
- // assume not directory
+ if (Files.isDirectory(source[i])) {
+ System.err.format("%s: is a directory%n", source[i]);
+ continue;
}
copyFile(source[i], dest, prompt, preserve);
}
--- a/jdk/src/share/sample/nio/file/DiskUsage.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/sample/nio/file/DiskUsage.java Mon Feb 14 16:30:10 2011 -0800
@@ -43,11 +43,9 @@
static final long K = 1024;
static void printFileStore(FileStore store) throws IOException {
- FileStoreSpaceAttributes attrs = Attributes.readFileStoreSpaceAttributes(store);
-
- long total = attrs.totalSpace() / K;
- long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / K;
- long avail = attrs.usableSpace() / K;
+ long total = store.getTotalSpace() / K;
+ long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / K;
+ long avail = store.getUsableSpace() / K;
String s = store.toString();
if (s.length() > 20) {
@@ -66,7 +64,7 @@
}
} else {
for (String file: args) {
- FileStore store = Paths.get(file).getFileStore();
+ FileStore store = Files.getFileStore(Paths.get(file));
printFileStore(store);
}
}
--- a/jdk/src/share/sample/nio/file/FileType.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/sample/nio/file/FileType.java Mon Feb 14 16:30:10 2011 -0800
@@ -30,7 +30,6 @@
*/
import java.nio.file.*;
-import java.nio.file.attribute.*;
import java.io.IOException;
public class FileType {
@@ -41,10 +40,8 @@
}
for (String arg: args) {
Path file = Paths.get(arg);
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
-
String type;
- if (attrs.isDirectory()) {
+ if (Files.isDirectory(file)) {
type = "directory";
} else {
type = Files.probeContentType(file);
--- a/jdk/src/share/sample/nio/file/WatchDir.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/sample/nio/file/WatchDir.java Mon Feb 14 16:30:10 2011 -0800
@@ -58,7 +58,7 @@
private void register(Path dir) throws IOException {
WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
if (trace) {
- FileRef prev = keys.get(key);
+ Path prev = keys.get(key);
if (prev == null) {
System.out.format("register: %s\n", dir);
} else {
@@ -147,7 +147,7 @@
// register it and its sub-directories
if (recursive && (kind == ENTRY_CREATE)) {
try {
- if (Attributes.readBasicFileAttributes(child, NOFOLLOW_LINKS).isDirectory()) {
+ if (Files.isDirectory(child, NOFOLLOW_LINKS)) {
registerAll(child);
}
} catch (IOException x) {
--- a/jdk/src/share/sample/nio/file/Xdd.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/share/sample/nio/file/Xdd.java Mon Feb 14 16:30:10 2011 -0800
@@ -58,14 +58,14 @@
Paths.get(args[0]) : Paths.get(args[2]);
// check that user defined attributes are supported by the file store
- FileStore store = file.getFileStore();
+ FileStore store = Files.getFileStore(file);
if (!store.supportsFileAttributeView(UserDefinedFileAttributeView.class)) {
System.err.format("UserDefinedFileAttributeView not supported on %s\n", store);
System.exit(-1);
}
- UserDefinedFileAttributeView view = file.
- getFileAttributeView(UserDefinedFileAttributeView.class);
+ UserDefinedFileAttributeView view =
+ Files.getFileAttributeView(file, UserDefinedFileAttributeView.class);
// list user defined attributes
if (args.length == 1) {
--- a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java Mon Feb 14 16:30:10 2011 -0800
@@ -725,7 +725,21 @@
XGlobalCursorManager.getCursorManager().updateCursorImmediately();
}
- public void pSetCursor(Cursor cursor) {
+ public final void pSetCursor(Cursor cursor) {
+ this.pSetCursor(cursor, true);
+ }
+
+ /*
+ * The method changes the cursor.
+ * @param cursor - a new cursor to change to.
+ * @param ignoreSubComponents - if {@code true} is passed then
+ * the new cursor will be installed on window.
+ * if {@code false} is passed then
+ * subsequent components will try to handle
+ * this request and install their cursor.
+ */
+ //ignoreSubComponents not used here
+ public void pSetCursor(Cursor cursor, boolean ignoreSubComponents) {
XToolkit.awtLock();
try {
long xcursor = XGlobalCursorManager.getCursor(cursor);
--- a/jdk/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java Mon Feb 14 16:30:10 2011 -0800
@@ -104,7 +104,9 @@
nativeContainer = new WeakReference<Component>(nc);
}
- ((XComponentPeer)nc_peer).pSetCursor(cur);
+ //6431076. A subcomponents (a XTextArea in particular)
+ //may want to override the cursor over some of their parts.
+ ((XComponentPeer)nc_peer).pSetCursor(cur, false);
// in case of grab we do for Swing we need to update keep cursor updated
// (we don't need this in case of AWT menus). Window Manager consider
// the grabber as a current window and use its cursor. So we need to
--- a/jdk/src/solaris/classes/sun/awt/X11/XSelection.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XSelection.java Mon Feb 14 16:30:10 2011 -0800
@@ -301,13 +301,8 @@
} finally {
XToolkit.awtUnlock();
}
- if (!dataGetter.isExecuted()) {
- throw new IOException("Owner timed out");
- }
- if (dataGetter.isDisposed()) {
- throw new IOException("Owner failed to convert data");
- }
+ validateDataGetter(dataGetter);
// Handle incremental transfer.
if (dataGetter.getActualType() ==
@@ -380,14 +375,7 @@
XToolkit.awtUnlock();
}
- // The owner didn't respond - terminate the transfer.
- if (!incrDataGetter.isExecuted()) {
- throw new IOException("Owner timed out");
- }
-
- if (incrDataGetter.isDisposed()) {
- throw new IOException("Owner failed to convert data");
- }
+ validateDataGetter(dataGetter);
if (incrDataGetter.getActualFormat() != 8) {
throw new IOException("Unsupported data format: " +
@@ -445,6 +433,23 @@
return data != null ? data : new byte[0];
}
+ void validateDataGetter(WindowPropertyGetter propertyGetter)
+ throws IOException
+ {
+ // The order of checks is important because a property getter
+ // has not been executed in case of timeout as well as in case of
+ // changed selection owner.
+
+ if (propertyGetter.isDisposed()) {
+ throw new IOException("Owner failed to convert data");
+ }
+
+ // The owner didn't respond - terminate the transfer.
+ if (!propertyGetter.isExecuted()) {
+ throw new IOException("Owner timed out");
+ }
+ }
+
// To be MT-safe this method should be called under awtLock.
boolean isOwner() {
return isOwner;
--- a/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java Mon Feb 14 16:30:10 2011 -0800
@@ -175,6 +175,34 @@
super.dispose();
}
+
+ /*
+ * The method overrides one from XComponentPeer
+ * If ignoreSubComponents=={@code true} it calls super.
+ * If ignoreSubComponents=={@code false} it uses the XTextArea machinery
+ * to change cursor appropriately. In particular it changes the cursor to
+ * default if over scrollbars.
+ */
+ @Override
+ public void pSetCursor(Cursor cursor, boolean ignoreSubComponents) {
+ Point onScreen = getLocationOnScreen();
+ if (ignoreSubComponents ||
+ javaMouseEventHandler == null ||
+ onScreen == null)
+ {
+ super.pSetCursor(cursor, true);
+ return;
+ }
+
+ Point cursorPos = new Point();
+ ((XGlobalCursorManager)XGlobalCursorManager.getCursorManager()).getCursorPos(cursorPos);
+
+ Point localPoint = new Point(cursorPos.x - onScreen.x, cursorPos.y - onScreen.y );
+
+ javaMouseEventHandler.setPointerToUnderPoint(localPoint);
+ javaMouseEventHandler.setCursor();
+ }
+
void setScrollBarVisibility() {
int visibility = ((TextArea)target).getScrollbarVisibility();
jtext.setLineWrap(false);
@@ -1264,13 +1292,13 @@
void handle( MouseEvent event ) {
if ( ! grabbed ) {
// dispatch() needs up-to-date pointer in ungrabbed case.
- setPointerToUnderEventPoint( event );
+ setPointerToUnderPoint( event.getPoint() );
}
dispatch( event );
boolean wasGrabbed = grabbed;
grabbed_update( event );
if ( wasGrabbed && ! grabbed ) {
- setPointerToUnderEventPoint( event );
+ setPointerToUnderPoint( event.getPoint() );
}
setCursor();
}
@@ -1338,7 +1366,7 @@
// 'target.getCursor()' is also applied from elsewhere
// (at least now), but only when mouse "entered", and
// before 'XTextAreaPeer.handleJavaMouseEvent' is invoked.
- outer.pSetCursor( outer.target.getCursor() );
+ outer.pSetCursor( outer.target.getCursor(), true );
}
else {
// We can write here a more intelligent cursor selection
@@ -1346,7 +1374,7 @@
// However, I see no point in doing so now. But if you feel
// like implementing it, you'll probably need to introduce
// 'Pointer.Type.PANEL'.
- outer.pSetCursor( outer.textPane.getCursor() );
+ outer.pSetCursor( outer.textPane.getCursor(), true );
}
}
@@ -1391,8 +1419,7 @@
return l;
}
- private void setPointerToUnderEventPoint( MouseEvent event ) {
- Point point = event.getPoint();
+ private void setPointerToUnderPoint( Point point ) {
if ( outer.textPane.getViewport().getBounds().contains( point ) ) {
current.setText();
}
--- a/jdk/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,7 +25,7 @@
package sun.nio.fs;
-import java.nio.file.FileRef;
+import java.nio.file.Path;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -57,7 +57,7 @@
}
@Override
- public String implProbeContentType(FileRef obj) throws IOException {
+ public String implProbeContentType(Path obj) throws IOException {
if (!gioAvailable && !gnomeVfsAvailable)
return null;
if (!(obj instanceof UnixPath))
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -67,19 +67,6 @@
}
@Override
- public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(READONLY_NAME))
- return readAttributes().isReadOnly();
- if (attribute.equals(ARCHIVE_NAME))
- return readAttributes().isArchive();
- if (attribute.equals(SYSTEM_NAME))
- return readAttributes().isSystem();
- if (attribute.equals(HIDDEN_NAME))
- return readAttributes().isHidden();
- return super.getAttribute(attribute);
- }
-
- @Override
public void setAttribute(String attribute, Object value)
throws IOException
{
@@ -103,7 +90,7 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes)
+ public Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java Mon Feb 14 16:30:10 2011 -0800
@@ -26,7 +26,6 @@
package sun.nio.fs;
import java.nio.file.*;
-import java.nio.file.attribute.*;
import java.io.IOException;
import java.util.*;
import java.security.AccessController;
@@ -76,39 +75,14 @@
}
}
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
- UnixPath file,
- LinkOption... options)
- {
- if (view == DosFileAttributeView.class)
- return (V) new LinuxDosFileAttributeView(file, followLinks(options));
- if (view == UserDefinedFileAttributeView.class)
- return (V) new LinuxUserDefinedFileAttributeView(file, followLinks(options));
- return super.newFileAttributeView(view, file, options);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public DynamicFileAttributeView newFileAttributeView(String name,
- UnixPath file,
- LinkOption... options)
- {
- if (name.equals("dos"))
- return new LinuxDosFileAttributeView(file, followLinks(options));
- if (name.equals("user"))
- return new LinuxUserDefinedFileAttributeView(file, followLinks(options));
- return super.newFileAttributeView(name, file, options);
- }
// lazy initialization of the list of supported attribute views
private static class SupportedFileFileAttributeViewsHolder {
static final Set<String> supportedFileAttributeViews =
supportedFileAttributeViews();
private static Set<String> supportedFileAttributeViews() {
- Set<String> result = new HashSet<String>();
- result.addAll(UnixFileSystem.standardFileAttributeViews());
+ Set<String> result = new HashSet<>();
+ result.addAll(standardFileAttributeViews());
// additional Linux-specific views
result.add("dos");
result.add("user");
@@ -130,7 +104,7 @@
* Returns object to iterate over the mount entries in the given fstab file.
*/
Iterable<UnixMountEntry> getMountEntries(String fstab) {
- ArrayList<UnixMountEntry> entries = new ArrayList<UnixMountEntry>();
+ ArrayList<UnixMountEntry> entries = new ArrayList<>();
try {
long fp = setmntent(fstab.getBytes(), "r".getBytes());
try {
@@ -159,10 +133,7 @@
return getMountEntries("/etc/mtab");
}
- @Override
- FileStore getFileStore(UnixPath path) throws IOException {
- return new LinuxFileStore(path);
- }
+
@Override
FileStore getFileStore(UnixMountEntry entry) throws IOException {
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,6 +25,10 @@
package sun.nio.fs;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
/**
* Linux implementation of FileSystemProvider
*/
@@ -38,4 +42,58 @@
LinuxFileSystem newFileSystem(String dir) {
return new LinuxFileSystem(this, dir);
}
+
+ @Override
+ LinuxFileStore getFileStore(UnixPath path) throws IOException {
+ return new LinuxFileStore(path);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileAttributeView> V getFileAttributeView(Path obj,
+ Class<V> type,
+ LinkOption... options)
+ {
+ if (type == DosFileAttributeView.class) {
+ return (V) new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ if (type == UserDefinedFileAttributeView.class) {
+ return (V) new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ return super.getFileAttributeView(obj, type, options);
+ }
+
+ @Override
+ public DynamicFileAttributeView getFileAttributeView(Path obj,
+ String name,
+ LinkOption... options)
+ {
+ if (name.equals("dos")) {
+ return new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ if (name.equals("user")) {
+ return new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ return super.getFileAttributeView(obj, name, options);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <A extends BasicFileAttributes> A readAttributes(Path file,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ if (type == DosFileAttributes.class) {
+ DosFileAttributeView view =
+ getFileAttributeView(file, DosFileAttributeView.class, options);
+ return (A) view.readAttributes();
+ } else {
+ return super.readAttributes(file, type, options);
+ }
+ }
}
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -63,7 +63,7 @@
// Parses buffer as array of NULL-terminated C strings.
private List<String> asList(long address, int size) {
- final List<String> list = new ArrayList<String>();
+ List<String> list = new ArrayList<>();
int start = 0;
int pos = 0;
while (pos < size) {
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java Mon Feb 14 16:30:10 2011 -0800
@@ -102,8 +102,8 @@
// watch descriptor
private volatile int wd;
- LinuxWatchKey(LinuxWatchService watcher, int ifd, int wd) {
- super(watcher);
+ LinuxWatchKey(UnixPath dir, LinuxWatchService watcher, int ifd, int wd) {
+ super(dir, watcher);
this.ifd = ifd;
this.wd = wd;
}
@@ -266,7 +266,7 @@
// ensure watch descriptor is in map
LinuxWatchKey key = wdToKey.get(wd);
if (key == null) {
- key = new LinuxWatchKey(watcher, ifd, wd);
+ key = new LinuxWatchKey(dir, watcher, ifd, wd);
wdToKey.put(wd, key);
}
return key;
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -198,7 +198,7 @@
* Decode the buffer, returning an ACL
*/
private static List<AclEntry> decode(long address, int n) {
- ArrayList<AclEntry> acl = new ArrayList<AclEntry>(n);
+ ArrayList<AclEntry> acl = new ArrayList<>(n);
for (int i=0; i<n; i++) {
long offset = address + i*SIZEOF_ACE_T;
@@ -244,7 +244,7 @@
assert false;
}
- HashSet<AclEntryPermission> aceMask = new HashSet<AclEntryPermission>();
+ Set<AclEntryPermission> aceMask = EnumSet.noneOf(AclEntryPermission.class);
if ((mask & ACE_READ_DATA) > 0)
aceMask.add(AclEntryPermission.READ_DATA);
if ((mask & ACE_WRITE_DATA) > 0)
@@ -274,7 +274,7 @@
if ((mask & ACE_SYNCHRONIZE) > 0)
aceMask.add(AclEntryPermission.SYNCHRONIZE);
- HashSet<AclEntryFlag> aceFlags = new HashSet<AclEntryFlag>();
+ Set<AclEntryFlag> aceFlags = EnumSet.noneOf(AclEntryFlag.class);
if ((flags & ACE_FILE_INHERIT_ACE) > 0)
aceFlags.add(AclEntryFlag.FILE_INHERIT);
if ((flags & ACE_DIRECTORY_INHERIT_ACE) > 0)
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java Mon Feb 14 16:30:10 2011 -0800
@@ -26,7 +26,6 @@
package sun.nio.fs;
import java.nio.file.*;
-import java.nio.file.attribute.*;
import java.io.IOException;
import java.util.*;
import java.security.AccessController;
@@ -71,38 +70,14 @@
}
}
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
- UnixPath file, LinkOption... options)
- {
- if (view == AclFileAttributeView.class)
- return (V) new SolarisAclFileAttributeView(file, followLinks(options));
- if (view == UserDefinedFileAttributeView.class) {
- return(V) new SolarisUserDefinedFileAttributeView(file, followLinks(options));
- }
- return super.newFileAttributeView(view, file, options);
- }
-
- @Override
- protected DynamicFileAttributeView newFileAttributeView(String name,
- UnixPath file,
- LinkOption... options)
- {
- if (name.equals("acl"))
- return new SolarisAclFileAttributeView(file, followLinks(options));
- if (name.equals("user"))
- return new SolarisUserDefinedFileAttributeView(file, followLinks(options));
- return super.newFileAttributeView(name, file, options);
- }
// lazy initialization of the list of supported attribute views
private static class SupportedFileFileAttributeViewsHolder {
static final Set<String> supportedFileAttributeViews =
supportedFileAttributeViews();
private static Set<String> supportedFileAttributeViews() {
- Set<String> result = new HashSet<String>();
- result.addAll(UnixFileSystem.standardFileAttributeViews());
+ Set<String> result = new HashSet<>();
+ result.addAll(standardFileAttributeViews());
// additional Solaris-specific views
result.add("acl");
result.add("user");
@@ -126,7 +101,7 @@
*/
@Override
Iterable<UnixMountEntry> getMountEntries() {
- ArrayList<UnixMountEntry> entries = new ArrayList<UnixMountEntry>();
+ ArrayList<UnixMountEntry> entries = new ArrayList<>();
try {
UnixPath mnttab = new UnixPath(this, "/etc/mnttab");
long fp = fopen(mnttab, "r");
@@ -148,11 +123,6 @@
}
@Override
- FileStore getFileStore(UnixPath path) throws IOException {
- return new SolarisFileStore(path);
- }
-
- @Override
FileStore getFileStore(UnixMountEntry entry) throws IOException {
return new SolarisFileStore(this, entry);
}
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,6 +25,10 @@
package sun.nio.fs;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
/**
* Solaris implementation of FileSystemProvider
*/
@@ -38,4 +42,41 @@
SolarisFileSystem newFileSystem(String dir) {
return new SolarisFileSystem(this, dir);
}
+
+ @Override
+ SolarisFileStore getFileStore(UnixPath path) throws IOException {
+ return new SolarisFileStore(path);
+ }
+
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileAttributeView> V getFileAttributeView(Path obj,
+ Class<V> type,
+ LinkOption... options)
+ {
+ if (type == AclFileAttributeView.class) {
+ return (V) new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ if (type == UserDefinedFileAttributeView.class) {
+ return(V) new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ return super.getFileAttributeView(obj, type, options);
+ }
+
+ @Override
+ public DynamicFileAttributeView getFileAttributeView(Path obj,
+ String name,
+ LinkOption... options)
+ {
+ if (name.equals("acl"))
+ return new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ if (name.equals("user"))
+ return new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ return super.getFileAttributeView(obj, name, options);
+ }
}
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -83,7 +83,7 @@
}
// read list of extended attributes
- final List<String> list = new ArrayList<String>();
+ List<String> list = new ArrayList<>();
try {
byte[] name;
while ((name = readdir(dp)) != null) {
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java Mon Feb 14 16:30:10 2011 -0800
@@ -128,7 +128,6 @@
private class SolarisWatchKey extends AbstractWatchKey
implements DirectoryNode
{
- private final UnixPath dir;
private final UnixFileKey fileKey;
// pointer to native file_obj object
@@ -147,15 +146,14 @@
long object,
Set<? extends WatchEvent.Kind<?>> events)
{
- super(watcher);
- this.dir = dir;
+ super(dir, watcher);
this.fileKey = fileKey;
this.object = object;
this.events = events;
}
- UnixPath getFileRef() {
- return dir;
+ UnixPath getDirectory() {
+ return (UnixPath)watchable();
}
UnixFileKey getFileKey() {
@@ -487,7 +485,7 @@
*/
void processDirectoryEvents(SolarisWatchKey key, int mask) {
if ((mask & (FILE_MODIFIED | FILE_ATTRIB)) != 0) {
- registerChildren(key.getFileRef(), key,
+ registerChildren(key.getDirectory(), key,
key.events().contains(StandardWatchEventKind.ENTRY_CREATE));
}
}
@@ -524,7 +522,7 @@
boolean removed = true;
try {
UnixFileAttributes
- .get(key.getFileRef().resolve(node.name()), false);
+ .get(key.getDirectory().resolve(node.name()), false);
removed = false;
} catch (UnixException x) { }
@@ -554,14 +552,14 @@
DirectoryStream<Path> stream = null;
try {
- stream = dir.newDirectoryStream();
+ stream = Files.newDirectoryStream(dir);
} catch (IOException x) {
// nothing we can do
return;
}
try {
for (Path entry: stream) {
- Path name = entry.getName();
+ Path name = entry.getFileName();
// skip entry if already registered
if (parent.getChild(name) != null)
@@ -582,9 +580,9 @@
}
// create node
- EntryNode node = new EntryNode(object, entry.getName(), parent);
+ EntryNode node = new EntryNode(object, entry.getFileName(), parent);
// tell the parent about it
- parent.addChild(entry.getName(), node);
+ parent.addChild(entry.getFileName(), node);
object2Node.put(object, node);
}
} catch (ConcurrentModificationException x) {
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java Mon Feb 14 16:30:10 2011 -0800
@@ -237,7 +237,7 @@
fo = open(target,
(O_WRONLY |
O_CREAT |
- O_TRUNC),
+ O_EXCL),
attrs.mode());
} catch (UnixException x) {
x.rethrowAsIOException(target);
@@ -435,10 +435,8 @@
if (targetAttrs.isDirectory() &&
(x.errno() == EEXIST || x.errno() == ENOTEMPTY))
{
- throw new FileAlreadyExistsException(
- source.getPathForExecptionMessage(),
- target.getPathForExecptionMessage(),
- x.getMessage());
+ throw new DirectoryNotEmptyException(
+ target.getPathForExecptionMessage());
}
x.rethrowAsIOException(target);
}
@@ -556,10 +554,8 @@
if (targetAttrs.isDirectory() &&
(x.errno() == EEXIST || x.errno() == ENOTEMPTY))
{
- throw new FileAlreadyExistsException(
- source.getPathForExecptionMessage(),
- target.getPathForExecptionMessage(),
- x.getMessage());
+ throw new DirectoryNotEmptyException(
+ target.getPathForExecptionMessage());
}
x.rethrowAsIOException(target);
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java Mon Feb 14 16:30:10 2011 -0800
@@ -149,17 +149,6 @@
}
@Override
- public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(PERMISSIONS_NAME))
- return readAttributes().permissions();
- if (attribute.equals(OWNER_NAME))
- return readAttributes().owner();
- if (attribute.equals(GROUP_NAME))
- return readAttributes().group();
- return super.getAttribute(attribute);
- }
-
- @Override
@SuppressWarnings("unchecked")
public void setAttribute(String attribute, Object value)
throws IOException
@@ -195,7 +184,7 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes)
+ public Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
@@ -308,27 +297,6 @@
}
@Override
- public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(MODE_NAME))
- return readAttributes().mode();
- if (attribute.equals(INO_NAME))
- return readAttributes().ino();
- if (attribute.equals(DEV_NAME))
- return readAttributes().dev();
- if (attribute.equals(RDEV_NAME))
- return readAttributes().rdev();
- if (attribute.equals(NLINK_NAME))
- return readAttributes().nlink();
- if (attribute.equals(UID_NAME))
- return readAttributes().uid();
- if (attribute.equals(GID_NAME))
- return readAttributes().gid();
- if (attribute.equals(CTIME_NAME))
- return readAttributes().ctime();
- return super.getAttribute(attribute);
- }
-
- @Override
public void setAttribute(String attribute, Object value)
throws IOException
{
@@ -348,7 +316,7 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes)
+ public Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java Mon Feb 14 16:30:10 2011 -0800
@@ -124,7 +124,7 @@
@Override
public FileTime creationTime() {
- return null;
+ return lastModifiedTime();
}
@Override
@@ -194,7 +194,7 @@
@Override
public Set<PosixFilePermission> permissions() {
int bits = (st_mode & UnixConstants.S_IAMB);
- HashSet<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
+ HashSet<PosixFilePermission> perms = new HashSet<>();
if ((bits & UnixConstants.S_IRUSR) > 0)
perms.add(PosixFilePermission.OWNER_READ);
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java Mon Feb 14 16:30:10 2011 -0800
@@ -103,28 +103,50 @@
return entry.isReadOnly();
}
+ // uses statvfs to read the file system information
+ private UnixFileStoreAttributes readAttributes() throws IOException {
+ try {
+ return UnixFileStoreAttributes.get(file);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(file);
+ return null; // keep compile happy
+ }
+ }
+
@Override
- @SuppressWarnings("unchecked")
+ public long getTotalSpace() throws IOException {
+ UnixFileStoreAttributes attrs = readAttributes();
+ return attrs.blockSize() * attrs.totalBlocks();
+ }
+
+ @Override
+ public long getUsableSpace() throws IOException {
+ UnixFileStoreAttributes attrs = readAttributes();
+ return attrs.blockSize() * attrs.availableBlocks();
+ }
+
+ @Override
+ public long getUnallocatedSpace() throws IOException {
+ UnixFileStoreAttributes attrs = readAttributes();
+ return attrs.blockSize() * attrs.freeBlocks();
+ }
+
+ @Override
public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> view)
{
if (view == null)
throw new NullPointerException();
- if (view == FileStoreSpaceAttributeView.class)
- return (V) new UnixFileStoreSpaceAttributeView(this);
return (V) null;
}
@Override
public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals("space:totalSpace"))
- return new UnixFileStoreSpaceAttributeView(this)
- .readAttributes().totalSpace();
- if (attribute.equals("space:usableSpace"))
- return new UnixFileStoreSpaceAttributeView(this)
- .readAttributes().usableSpace();
- if (attribute.equals("space:unallocatedSpace"))
- return new UnixFileStoreSpaceAttributeView(this)
- .readAttributes().unallocatedSpace();
+ if (attribute.equals("totalSpace"))
+ return getTotalSpace();
+ if (attribute.equals("usableSpace"))
+ return getUsableSpace();
+ if (attribute.equals("unallocatedSpace"))
+ return getUnallocatedSpace();
throw new UnsupportedOperationException("'" + attribute + "' not recognized");
}
@@ -181,50 +203,6 @@
return sb.toString();
}
- private static class UnixFileStoreSpaceAttributeView
- implements FileStoreSpaceAttributeView
- {
- private final UnixFileStore fs;
-
- UnixFileStoreSpaceAttributeView(UnixFileStore fs) {
- this.fs = fs;
- }
-
- @Override
- public String name() {
- return "space";
- }
-
- @Override
- public FileStoreSpaceAttributes readAttributes()
- throws IOException
- {
- UnixPath file = fs.file();
- final UnixFileStoreAttributes attrs;
- try {
- attrs = UnixFileStoreAttributes.get(file);
- } catch (UnixException x) {
- x.rethrowAsIOException(file);
- return null; // keep compile happy
- }
-
- return new FileStoreSpaceAttributes() {
- @Override
- public long totalSpace() {
- return attrs.blockSize() * attrs.totalBlocks();
- }
- @Override
- public long usableSpace() {
- return attrs.blockSize() * attrs.availableBlocks();
- }
- @Override
- public long unallocatedSpace() {
- return attrs.blockSize() * attrs.freeBlocks();
- }
- };
- }
- }
-
// -- fstypes.properties --
private static final Object loadLock = new Object();
@@ -277,11 +255,8 @@
String fstypes = System.getProperty("java.home") + "/lib/fstypes.properties";
Path file = Paths.get(fstypes);
try {
- ReadableByteChannel rbc = file.newByteChannel();
- try {
+ try (ReadableByteChannel rbc = Files.newByteChannel(file)) {
result.load(Channels.newReader(rbc, "UTF-8"));
- } finally {
- rbc.close();
}
} catch (IOException x) {
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java Mon Feb 14 16:30:10 2011 -0800
@@ -98,6 +98,10 @@
return false;
}
+ static List<String> standardFileAttributeViews() {
+ return Arrays.asList("basic", "posix", "unix", "owner");
+ }
+
@Override
public final FileSystemProvider provider() {
return provider;
@@ -169,12 +173,6 @@
abstract Iterable<UnixMountEntry> getMountEntries();
/**
- * Returns a FileStore to represent the file system where the given file
- * reside.
- */
- abstract FileStore getFileStore(UnixPath path) throws IOException;
-
- /**
* Returns a FileStore to represent the file system for the given mount
* mount.
*/
@@ -264,7 +262,22 @@
}
@Override
- public final UnixPath getPath(String path) {
+ public final Path getPath(String first, String... more) {
+ String path;
+ if (more.length == 0) {
+ path = first;
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append(first);
+ for (String segment: more) {
+ if (segment.length() > 0) {
+ if (sb.length() > 0)
+ sb.append('/');
+ sb.append(segment);
+ }
+ }
+ path = sb.toString();
+ }
return new UnixPath(this, path);
}
@@ -300,77 +313,30 @@
private static final String GLOB_SYNTAX = "glob";
private static final String REGEX_SYNTAX = "regex";
- protected boolean followLinks(LinkOption... options) {
- boolean followLinks = true;
- for (LinkOption option: options) {
- if (option == LinkOption.NOFOLLOW_LINKS) {
- followLinks = false;
- continue;
- }
- if (option == null)
- throw new NullPointerException();
- throw new AssertionError("Should not get here");
- }
- return followLinks;
- }
- @SuppressWarnings("unchecked")
- protected <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
- UnixPath file,
- LinkOption... options)
- {
- if (view == null)
- throw new NullPointerException();
- boolean followLinks = followLinks(options);
- Class<?> c = view;
- if (c == BasicFileAttributeView.class)
- return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
- if (c == PosixFileAttributeView.class)
- return (V) UnixFileAttributeViews.createPosixView(file, followLinks);
- if (c == FileOwnerAttributeView.class)
- return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
- return (V) null;
- }
-
- static List<String> standardFileAttributeViews() {
- return Arrays.asList("basic", "posix", "unix", "owner");
- }
-
- protected DynamicFileAttributeView newFileAttributeView(String name,
- UnixPath file,
- LinkOption... options)
- {
- boolean followLinks = followLinks(options);
- if (name.equals("basic"))
- return UnixFileAttributeViews.createBasicView(file, followLinks);
- if (name.equals("posix"))
- return UnixFileAttributeViews.createPosixView(file, followLinks);
- if (name.equals("unix"))
- return UnixFileAttributeViews.createUnixView(file, followLinks);
- if (name.equals("owner"))
- return UnixFileAttributeViews.createOwnerView(file, followLinks);
- return null;
- }
@Override
public final UserPrincipalLookupService getUserPrincipalLookupService() {
- return theLookupService;
+ return LookupService.instance;
}
- private static final UserPrincipalLookupService theLookupService =
- new UserPrincipalLookupService() {
- @Override
- public UserPrincipal lookupPrincipalByName(String name)
- throws IOException
- {
- return UnixUserPrincipals.lookupUser(name);
- }
+ private static class LookupService {
+ static final UserPrincipalLookupService instance =
+ new UserPrincipalLookupService() {
+ @Override
+ public UserPrincipal lookupPrincipalByName(String name)
+ throws IOException
+ {
+ return UnixUserPrincipals.lookupUser(name);
+ }
- @Override
- public GroupPrincipal lookupPrincipalByGroupName(String group)
- throws IOException
- {
- return UnixUserPrincipals.lookupGroup(group);
- }
- };
+ @Override
+ public GroupPrincipal lookupPrincipalByGroupName(String group)
+ throws IOException
+ {
+ return UnixUserPrincipals.lookupGroup(group);
+ }
+ };
+ }
+
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Mon Feb 14 16:30:10 2011 -0800
@@ -27,21 +27,25 @@
import java.nio.file.*;
import java.nio.file.attribute.*;
-import java.nio.file.spi.FileSystemProvider;
import java.nio.channels.*;
import java.net.URI;
import java.util.concurrent.ExecutorService;
import java.io.IOException;
+import java.io.FilePermission;
import java.util.*;
+import java.security.AccessController;
import sun.nio.ch.ThreadPool;
+import sun.security.util.SecurityConstants;
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
/**
* Base implementation of FileSystemProvider
*/
public abstract class UnixFileSystemProvider
- extends FileSystemProvider
+ extends AbstractFileSystemProvider
{
private static final String USER_DIR = "user.dir";
private final UnixFileSystem theFileSystem;
@@ -93,7 +97,7 @@
return UnixUriUtils.fromUri(theFileSystem, uri);
}
- protected UnixPath checkPath(Path obj) {
+ UnixPath checkPath(Path obj) {
if (obj == null)
throw new NullPointerException();
if (!(obj instanceof UnixPath))
@@ -101,6 +105,76 @@
return (UnixPath)obj;
}
+ boolean followLinks(LinkOption... options) {
+ boolean followLinks = true;
+ for (LinkOption option: options) {
+ if (option == LinkOption.NOFOLLOW_LINKS) {
+ followLinks = false;
+ continue;
+ }
+ if (option == null)
+ throw new NullPointerException();
+ throw new AssertionError("Should not get here");
+ }
+ return followLinks;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileAttributeView> V getFileAttributeView(Path obj,
+ Class<V> type,
+ LinkOption... options)
+ {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ boolean followLinks = followLinks(options);
+ if (type == BasicFileAttributeView.class)
+ return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
+ if (type == PosixFileAttributeView.class)
+ return (V) UnixFileAttributeViews.createPosixView(file, followLinks);
+ if (type == FileOwnerAttributeView.class)
+ return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
+ if (type == null)
+ throw new NullPointerException();
+ return (V) null;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <A extends BasicFileAttributes> A readAttributes(Path file,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ Class<? extends BasicFileAttributeView> view;
+ if (type == BasicFileAttributes.class)
+ view = BasicFileAttributeView.class;
+ else if (type == PosixFileAttributes.class)
+ view = PosixFileAttributeView.class;
+ else if (type == null)
+ throw new NullPointerException();
+ else
+ throw new UnsupportedOperationException();
+ return (A) getFileAttributeView(file, view, options).readAttributes();
+ }
+
+ @Override
+ protected DynamicFileAttributeView getFileAttributeView(Path obj,
+ String name,
+ LinkOption... options)
+ {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ boolean followLinks = followLinks(options);
+ if (name.equals("basic"))
+ return UnixFileAttributeViews.createBasicView(file, followLinks);
+ if (name.equals("posix"))
+ return UnixFileAttributeViews.createPosixView(file, followLinks);
+ if (name.equals("unix"))
+ return UnixFileAttributeViews.createUnixView(file, followLinks);
+ if (name.equals("owner"))
+ return UnixFileAttributeViews.createOwnerView(file, followLinks);
+ return null;
+ }
+
@Override
public FileChannel newFileChannel(Path obj,
Set<? extends OpenOption> options,
@@ -136,4 +210,303 @@
return null;
}
}
+
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path obj,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ int mode = UnixFileModeAttribute
+ .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
+ try {
+ return UnixChannelFactory.newFileChannel(file, options, mode);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(file);
+ return null; // keep compiler happy
+ }
+ }
+
+ @Override
+ boolean implDelete(Path obj, boolean failIfNotExists) throws IOException {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ file.checkDelete();
+
+ // need file attributes to know if file is directory
+ UnixFileAttributes attrs = null;
+ try {
+ attrs = UnixFileAttributes.get(file, false);
+ if (attrs.isDirectory()) {
+ rmdir(file);
+ } else {
+ unlink(file);
+ }
+ return true;
+ } catch (UnixException x) {
+ // no-op if file does not exist
+ if (!failIfNotExists && x.errno() == ENOENT)
+ return false;
+
+ // DirectoryNotEmptyException if not empty
+ if (attrs != null && attrs.isDirectory() &&
+ (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
+ throw new DirectoryNotEmptyException(file.getPathForExecptionMessage());
+
+ x.rethrowAsIOException(file);
+ return false;
+ }
+ }
+
+ @Override
+ public void copy(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ UnixCopyFile.copy(UnixPath.toUnixPath(source),
+ UnixPath.toUnixPath(target),
+ options);
+ }
+
+ @Override
+ public void move(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ UnixCopyFile.move(UnixPath.toUnixPath(source),
+ UnixPath.toUnixPath(target),
+ options);
+ }
+
+ @Override
+ public void checkAccess(Path obj, AccessMode... modes) throws IOException {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ boolean e = false;
+ boolean r = false;
+ boolean w = false;
+ boolean x = false;
+
+ if (modes.length == 0) {
+ e = true;
+ } else {
+ for (AccessMode mode: modes) {
+ switch (mode) {
+ case READ : r = true; break;
+ case WRITE : w = true; break;
+ case EXECUTE : x = true; break;
+ default: throw new AssertionError("Should not get here");
+ }
+ }
+ }
+
+ int mode = 0;
+ if (e || r) {
+ file.checkRead();
+ mode |= (r) ? R_OK : F_OK;
+ }
+ if (w) {
+ file.checkWrite();
+ mode |= W_OK;
+ }
+ if (x) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ // not cached
+ sm.checkExec(file.getPathForPermissionCheck());
+ }
+ mode |= X_OK;
+ }
+ try {
+ access(file, mode);
+ } catch (UnixException exc) {
+ exc.rethrowAsIOException(file);
+ }
+ }
+
+ @Override
+ public boolean isSameFile(Path obj1, Path obj2) throws IOException {
+ UnixPath file1 = UnixPath.toUnixPath(obj1);
+ if (file1.equals(obj2))
+ return true;
+ if (obj2 == null)
+ throw new NullPointerException();
+ if (!(obj2 instanceof UnixPath))
+ return false;
+ UnixPath file2 = (UnixPath)obj2;
+
+ // check security manager access to both files
+ file1.checkRead();
+ file2.checkRead();
+
+ UnixFileAttributes attrs1;
+ UnixFileAttributes attrs2;
+ try {
+ attrs1 = UnixFileAttributes.get(file1, true);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(file1);
+ return false; // keep compiler happy
+ }
+ try {
+ attrs2 = UnixFileAttributes.get(file2, true);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(file2);
+ return false; // keep compiler happy
+ }
+ return attrs1.isSameFile(attrs2);
+ }
+
+ @Override
+ public boolean isHidden(Path obj) {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ file.checkRead();
+ UnixPath name = file.getFileName();
+ if (name == null)
+ return false;
+ return (name.asByteArray()[0] == '.');
+ }
+
+ /**
+ * Returns a FileStore to represent the file system where the given file
+ * reside.
+ */
+ abstract FileStore getFileStore(UnixPath path) throws IOException;
+
+ @Override
+ public FileStore getFileStore(Path obj) throws IOException {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
+ file.checkRead();
+ }
+ return getFileStore(file);
+ }
+
+ @Override
+ public void createDirectory(Path obj, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ UnixPath dir = UnixPath.toUnixPath(obj);
+ dir.checkWrite();
+
+ int mode = UnixFileModeAttribute
+ .toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);
+ try {
+ mkdir(dir, mode);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(dir);
+ }
+ }
+
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ UnixPath dir = UnixPath.toUnixPath(obj);
+ dir.checkRead();
+ if (filter == null)
+ throw new NullPointerException();
+
+ // can't return SecureDirectoryStream on kernels that don't support
+ // openat, etc.
+ if (!supportsAtSysCalls()) {
+ try {
+ long ptr = opendir(dir);
+ return new UnixDirectoryStream(dir, ptr, filter);
+ } catch (UnixException x) {
+ if (x.errno() == ENOTDIR)
+ throw new NotDirectoryException(dir.getPathForExecptionMessage());
+ x.rethrowAsIOException(dir);
+ }
+ }
+
+ // open directory and dup file descriptor for use by
+ // opendir/readdir/closedir
+ int dfd1 = -1;
+ int dfd2 = -1;
+ long dp = 0L;
+ try {
+ dfd1 = open(dir, O_RDONLY, 0);
+ dfd2 = dup(dfd1);
+ dp = fdopendir(dfd1);
+ } catch (UnixException x) {
+ if (dfd1 != -1)
+ UnixNativeDispatcher.close(dfd1);
+ if (dfd2 != -1)
+ UnixNativeDispatcher.close(dfd2);
+ if (x.errno() == UnixConstants.ENOTDIR)
+ throw new NotDirectoryException(dir.getPathForExecptionMessage());
+ x.rethrowAsIOException(dir);
+ }
+ return new UnixSecureDirectoryStream(dir, dp, dfd2, filter);
+ }
+
+ @Override
+ public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ UnixPath link = UnixPath.toUnixPath(obj1);
+ UnixPath target = UnixPath.toUnixPath(obj2);
+
+ // no attributes supported when creating links
+ if (attrs.length > 0) {
+ UnixFileModeAttribute.toUnixMode(0, attrs); // may throw NPE or UOE
+ throw new UnsupportedOperationException("Initial file attributes" +
+ "not supported when creating symbolic link");
+ }
+
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new LinkPermission("symbolic"));
+ link.checkWrite();
+ }
+
+ // create link
+ try {
+ symlink(target.asByteArray(), link);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(link);
+ }
+ }
+
+ @Override
+ public void createLink(Path obj1, Path obj2) throws IOException {
+ UnixPath link = UnixPath.toUnixPath(obj1);
+ UnixPath existing = UnixPath.toUnixPath(obj2);
+
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new LinkPermission("hard"));
+ link.checkWrite();
+ existing.checkWrite();
+ }
+ try {
+ link(existing, link);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(link, existing);
+ }
+ }
+
+ @Override
+ public Path readSymbolicLink(Path obj1) throws IOException {
+ UnixPath link = UnixPath.toUnixPath(obj1);
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ FilePermission perm = new FilePermission(link.getPathForPermissionCheck(),
+ SecurityConstants.FILE_READLINK_ACTION);
+ AccessController.checkPermission(perm);
+ }
+ try {
+ byte[] target = readlink(link);
+ return new UnixPath(link.getFileSystem(), target);
+ } catch (UnixException x) {
+ if (x.errno() == UnixConstants.EINVAL)
+ throw new NotLinkException(link.getPathForExecptionMessage());
+ x.rethrowAsIOException(link);
+ return null; // keep compiler happy
+ }
+ }
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Mon Feb 14 16:30:10 2011 -0800
@@ -27,15 +27,11 @@
import java.nio.*;
import java.nio.file.*;
-import java.nio.file.attribute.*;
import java.nio.charset.*;
-import java.nio.channels.*;
-import java.security.AccessController;
import java.io.*;
import java.net.URI;
import java.util.*;
import java.lang.ref.SoftReference;
-import sun.security.util.SecurityConstants;
import static sun.nio.fs.UnixNativeDispatcher.*;
import static sun.nio.fs.UnixConstants.*;
@@ -79,8 +75,6 @@
// removes redundant slashes and check input for invalid characters
static String normalizeAndCheck(String input) {
int n = input.length();
- if (n == 0)
- throw new InvalidPathException(input, "Path is empty");
char prevChar = 0;
for (int i=0; i < n; i++) {
char c = input.charAt(i);
@@ -174,7 +168,13 @@
if (getFileSystem().needToResolveAgainstDefaultDirectory()) {
return resolve(getFileSystem().defaultDirectory(), path);
} else {
- return path;
+ if (!isEmpty()) {
+ return path;
+ } else {
+ // empty path case will access current directory
+ byte[] here = { '.' };
+ return here;
+ }
}
}
@@ -193,7 +193,7 @@
}
// Checks that the given file is a UnixPath
- private UnixPath checkPath(FileRef obj) {
+ static UnixPath toUnixPath(Path obj) {
if (obj == null)
throw new NullPointerException();
if (!(obj instanceof UnixPath))
@@ -209,12 +209,17 @@
// count names
count = 0;
index = 0;
- while (index < path.length) {
- byte c = path[index++];
- if (c != '/') {
- count++;
- while (index < path.length && path[index] != '/')
- index++;
+ if (isEmpty()) {
+ // empty path has one name
+ count = 1;
+ } else {
+ while (index < path.length) {
+ byte c = path[index++];
+ if (c != '/') {
+ count++;
+ while (index < path.length && path[index] != '/')
+ index++;
+ }
}
}
@@ -239,6 +244,16 @@
}
}
+ // returns {@code true} if this path is an empty path
+ private boolean isEmpty() {
+ return path.length == 0;
+ }
+
+ // returns an empty path
+ private UnixPath emptyPath() {
+ return new UnixPath(getFileSystem(), new byte[0]);
+ }
+
@Override
public UnixFileSystem getFileSystem() {
return fs;
@@ -246,7 +261,7 @@
@Override
public UnixPath getRoot() {
- if (path[0] == '/') {
+ if (path.length > 0 && path[0] == '/') {
return getFileSystem().rootDirectory();
} else {
return null;
@@ -254,14 +269,17 @@
}
@Override
- public UnixPath getName() {
+ public UnixPath getFileName() {
initOffsets();
int count = offsets.length;
+
+ // no elements so no name
if (count == 0)
- return null; // no elements so no name
+ return null;
- if (count == 1 && path[0] != '/')
+ // one name element and no root component
+ if (count == 1 && path.length > 0 && path[0] != '/')
return this;
int lastOffset = offsets[count-1];
@@ -349,57 +367,58 @@
@Override
public boolean isAbsolute() {
- return (path[0] == '/');
+ return (path.length > 0 && path[0] == '/');
}
// Resolve child against given base
private static byte[] resolve(byte[] base, byte[] child) {
- if (child[0] == '/')
+ int baseLength = base.length;
+ int childLength = child.length;
+ if (childLength == 0)
+ return base;
+ if (baseLength == 0 || child[0] == '/')
return child;
byte[] result;
- if (base.length == 1 && base[0] == '/') {
- result = new byte[child.length + 1];
+ if (baseLength == 1 && base[0] == '/') {
+ result = new byte[childLength + 1];
result[0] = '/';
- System.arraycopy(child, 0, result, 1, child.length);
+ System.arraycopy(child, 0, result, 1, childLength);
} else {
- result = new byte[base.length + 1 + child.length];
- System.arraycopy(base, 0, result, 0, base.length);
+ result = new byte[baseLength + 1 + childLength];
+ System.arraycopy(base, 0, result, 0, baseLength);
result[base.length] = '/';
- System.arraycopy(child, 0, result, base.length+1, child.length);
+ System.arraycopy(child, 0, result, baseLength+1, childLength);
}
return result;
}
@Override
public UnixPath resolve(Path obj) {
- if (obj == null)
- return this;
- byte[] other = checkPath(obj).path;
- if (other[0] == '/')
+ byte[] other = toUnixPath(obj).path;
+ if (other.length > 0 && other[0] == '/')
return ((UnixPath)obj);
byte[] result = resolve(path, other);
return new UnixPath(getFileSystem(), result);
}
- @Override
- public UnixPath resolve(String other) {
- return resolve(new UnixPath(getFileSystem(), other));
- }
-
UnixPath resolve(byte[] other) {
return resolve(new UnixPath(getFileSystem(), other));
}
@Override
public UnixPath relativize(Path obj) {
- UnixPath other = checkPath(obj);
+ UnixPath other = toUnixPath(obj);
if (other.equals(this))
- return null;
+ return emptyPath();
// can only relativize paths of the same type
if (this.isAbsolute() != other.isAbsolute())
throw new IllegalArgumentException("'other' is different type of Path");
+ // this path is the empty path
+ if (this.isEmpty())
+ return other;
+
int bn = this.getNameCount();
int cn = other.getNameCount();
@@ -419,14 +438,27 @@
if (dotdots == 0)
return remainder;
+ // other is the empty path
+ boolean isOtherEmpty = other.isEmpty();
+
// result is a "../" for each remaining name in base
- // followed by the remaining names in other
- byte[] result = new byte[dotdots*3 + remainder.path.length];
+ // followed by the remaining names in other. If the remainder is
+ // the empty path then we don't add the final trailing slash.
+ int len = dotdots*3 + remainder.path.length;
+ if (isOtherEmpty) {
+ assert remainder.isEmpty();
+ len--;
+ }
+ byte[] result = new byte[len];
int pos = 0;
while (dotdots > 0) {
result[pos++] = (byte)'.';
result[pos++] = (byte)'.';
- result[pos++] = (byte)'/';
+ if (isOtherEmpty) {
+ if (dotdots > 1) result[pos++] = (byte)'/';
+ } else {
+ result[pos++] = (byte)'/';
+ }
dotdots--;
}
System.arraycopy(remainder.path, 0, result, pos, remainder.path.length);
@@ -457,7 +489,7 @@
int[] size = new int[count]; // length of name
int remaining = count; // number of names remaining
boolean hasDotDot = false; // has at least one ..
- boolean isAbsolute = path[0] == '/';
+ boolean isAbsolute = isAbsolute();
// first pass:
// 1. compute length of names
@@ -542,7 +574,7 @@
// corner case - all names removed
if (remaining == 0) {
- return isAbsolute ? getFileSystem().rootDirectory() : null;
+ return isAbsolute ? getFileSystem().rootDirectory() : emptyPath();
}
// compute length of result
@@ -574,7 +606,7 @@
@Override
public boolean startsWith(Path other) {
- UnixPath that = checkPath(other);
+ UnixPath that = toUnixPath(other);
// other path is longer
if (that.path.length > path.length)
@@ -584,8 +616,9 @@
int thatOffsetCount = that.getNameCount();
// other path has no name elements
- if (thatOffsetCount == 0 && this.isAbsolute())
- return true;
+ if (thatOffsetCount == 0 && this.isAbsolute()) {
+ return that.isEmpty() ? false : true;
+ }
// given path has more elements that this path
if (thatOffsetCount > thisOffsetCount)
@@ -622,7 +655,7 @@
@Override
public boolean endsWith(Path other) {
- UnixPath that = checkPath(other);
+ UnixPath that = toUnixPath(other);
int thisLen = path.length;
int thatLen = that.path.length;
@@ -631,6 +664,10 @@
if (thatLen > thisLen)
return false;
+ // other path is the empty path
+ if (thisLen > 0 && thatLen == 0)
+ return false;
+
// other path is absolute so this path must be absolute
if (that.isAbsolute() && !this.isAbsolute())
return false;
@@ -721,32 +758,6 @@
return stringValue;
}
- @Override
- public Iterator<Path> iterator() {
- initOffsets();
- return new Iterator<Path>() {
- int i = 0;
- @Override
- public boolean hasNext() {
- return (i < offsets.length);
- }
- @Override
- public Path next() {
- if (i < offsets.length) {
- Path result = getName(i);
- i++;
- return result;
- } else {
- throw new NoSuchElementException();
- }
- }
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
-
// -- file operations --
// package-private
@@ -770,7 +781,6 @@
}
}
-
void checkRead() {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
@@ -790,296 +800,6 @@
}
@Override
- public FileStore getFileStore()
- throws IOException
- {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
- checkRead();
- }
- return getFileSystem().getFileStore(this);
- }
-
- @Override
- public void checkAccess(AccessMode... modes) throws IOException {
- boolean e = false;
- boolean r = false;
- boolean w = false;
- boolean x = false;
-
- if (modes.length == 0) {
- e = true;
- } else {
- for (AccessMode mode: modes) {
- switch (mode) {
- case READ : r = true; break;
- case WRITE : w = true; break;
- case EXECUTE : x = true; break;
- default: throw new AssertionError("Should not get here");
- }
- }
- }
-
- int mode = 0;
- if (e || r) {
- checkRead();
- mode |= (r) ? R_OK : F_OK;
- }
- if (w) {
- checkWrite();
- mode |= W_OK;
- }
- if (x) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- // not cached
- sm.checkExec(getPathForPermissionCheck());
- }
- mode |= X_OK;
- }
- try {
- access(this, mode);
- } catch (UnixException exc) {
- exc.rethrowAsIOException(this);
- }
- }
-
- @Override
- void implDelete(boolean failIfNotExists) throws IOException {
- checkDelete();
-
- // need file attributes to know if file is directory
- UnixFileAttributes attrs = null;
- try {
- attrs = UnixFileAttributes.get(this, false);
- if (attrs.isDirectory()) {
- rmdir(this);
- } else {
- unlink(this);
- }
- } catch (UnixException x) {
- // no-op if file does not exist
- if (!failIfNotExists && x.errno() == ENOENT)
- return;
-
- // DirectoryNotEmptyException if not empty
- if (attrs != null && attrs.isDirectory() &&
- (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
- throw new DirectoryNotEmptyException(getPathForExecptionMessage());
-
- x.rethrowAsIOException(this);
- }
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
- throws IOException
- {
- if (filter == null)
- throw new NullPointerException();
- checkRead();
-
- // can't return SecureDirectoryStream on kernels that don't support
- // openat, etc.
- if (!supportsAtSysCalls()) {
- try {
- long ptr = opendir(this);
- return new UnixDirectoryStream(this, ptr, filter);
- } catch (UnixException x) {
- if (x.errno() == ENOTDIR)
- throw new NotDirectoryException(getPathForExecptionMessage());
- x.rethrowAsIOException(this);
- }
- }
-
- // open directory and dup file descriptor for use by
- // opendir/readdir/closedir
- int dfd1 = -1;
- int dfd2 = -1;
- long dp = 0L;
- try {
- dfd1 = open(this, O_RDONLY, 0);
- dfd2 = dup(dfd1);
- dp = fdopendir(dfd1);
- } catch (UnixException x) {
- if (dfd1 != -1)
- close(dfd1);
- if (dfd2 != -1)
- close(dfd2);
- if (x.errno() == UnixConstants.ENOTDIR)
- throw new NotDirectoryException(getPathForExecptionMessage());
- x.rethrowAsIOException(this);
- }
- return new UnixSecureDirectoryStream(this, dp, dfd2, filter);
- }
-
- // invoked by AbstractPath#copyTo
- @Override
- public void implCopyTo(Path obj, CopyOption... options)
- throws IOException
- {
- UnixPath target = (UnixPath)obj;
- UnixCopyFile.copy(this, target, options);
- }
-
- @Override
- public void implMoveTo(Path obj, CopyOption... options)
- throws IOException
- {
- UnixPath target = (UnixPath)obj;
- UnixCopyFile.move(this, target, options);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileAttributeView> V
- getFileAttributeView(Class<V> type, LinkOption... options)
- {
- FileAttributeView view = getFileSystem()
- .newFileAttributeView(type, this, options);
- if (view == null)
- return null;
- return (V) view;
- }
-
- @Override
- public DynamicFileAttributeView getFileAttributeView(String name,
- LinkOption... options)
- {
- return getFileSystem().newFileAttributeView(name, this, options);
- }
-
- @Override
- public Path createDirectory(FileAttribute<?>... attrs)
- throws IOException
- {
- checkWrite();
-
- int mode = UnixFileModeAttribute
- .toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);
- try {
- mkdir(this, mode);
- } catch (UnixException x) {
- x.rethrowAsIOException(this);
- }
- return this;
- }
-
- @Override
- public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- int mode = UnixFileModeAttribute
- .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
- try {
- return UnixChannelFactory.newFileChannel(this, options, mode);
- } catch (UnixException x) {
- x.rethrowAsIOException(this);
- return null; // keep compiler happy
- }
- }
-
- @Override
- public boolean isSameFile(Path obj) throws IOException {
- if (this.equals(obj))
- return true;
- if (!(obj instanceof UnixPath)) // includes null check
- return false;
- UnixPath other = (UnixPath)obj;
-
- // check security manager access to both files
- this.checkRead();
- other.checkRead();
-
- UnixFileAttributes thisAttrs;
- UnixFileAttributes otherAttrs;
- try {
- thisAttrs = UnixFileAttributes.get(this, true);
- } catch (UnixException x) {
- x.rethrowAsIOException(this);
- return false; // keep compiler happy
- }
- try {
- otherAttrs = UnixFileAttributes.get(other, true);
- } catch (UnixException x) {
- x.rethrowAsIOException(other);
- return false; // keep compiler happy
- }
- return thisAttrs.isSameFile(otherAttrs);
- }
-
- @Override
- public Path createSymbolicLink(Path obj, FileAttribute<?>... attrs)
- throws IOException
- {
- UnixPath target = checkPath(obj);
-
- // no attributes supported when creating links
- if (attrs.length > 0) {
- UnixFileModeAttribute.toUnixMode(0, attrs); // may throw NPE or UOE
- throw new UnsupportedOperationException("Initial file attributes" +
- "not supported when creating symbolic link");
- }
-
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new LinkPermission("symbolic"));
- checkWrite();
- }
-
- // create link
- try {
- symlink(target.asByteArray(), this);
- } catch (UnixException x) {
- x.rethrowAsIOException(this);
- }
-
- return this;
- }
-
- @Override
- public Path createLink(Path obj) throws IOException {
- UnixPath existing = checkPath(obj);
-
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new LinkPermission("hard"));
- this.checkWrite();
- existing.checkWrite();
- }
- try {
- link(existing, this);
- } catch (UnixException x) {
- x.rethrowAsIOException(this, existing);
- }
- return this;
- }
-
- @Override
- public Path readSymbolicLink() throws IOException {
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- FilePermission perm = new FilePermission(getPathForPermissionCheck(),
- SecurityConstants.FILE_READLINK_ACTION);
- AccessController.checkPermission(perm);
- }
- try {
- byte[] target = readlink(this);
- return new UnixPath(getFileSystem(), target);
- } catch (UnixException x) {
- if (x.errno() == UnixConstants.EINVAL)
- throw new NotLinkException(getPathForExecptionMessage());
- x.rethrowAsIOException(this);
- return null; // keep compiler happy
- }
- }
-
- @Override
public UnixPath toAbsolutePath() {
if (isAbsolute()) {
return this;
@@ -1095,7 +815,7 @@
}
@Override
- public UnixPath toRealPath(boolean resolveLinks) throws IOException {
+ public Path toRealPath(boolean resolveLinks) throws IOException {
checkRead();
UnixPath absolute = toAbsolutePath();
@@ -1112,8 +832,7 @@
// if resolveLinks is false then eliminate "." and also ".."
// where the previous element is not a link.
- UnixPath root = getFileSystem().rootDirectory();
- UnixPath result = root;
+ UnixPath result = fs.rootDirectory();
for (int i=0; i<absolute.getNameCount(); i++) {
UnixPath element = absolute.getName(i);
@@ -1134,7 +853,7 @@
if (!attrs.isSymbolicLink()) {
result = result.getParent();
if (result == null) {
- result = root;
+ result = fs.rootDirectory();
}
continue;
}
@@ -1152,15 +871,6 @@
}
@Override
- public boolean isHidden() {
- checkRead();
- UnixPath name = getName();
- if (name == null)
- return false;
- return (name.asByteArray()[0] == '.');
- }
-
- @Override
public URI toUri() {
return UnixUriUtils.toUri(this);
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java Mon Feb 14 16:30:10 2011 -0800
@@ -40,7 +40,7 @@
*/
class UnixSecureDirectoryStream
- extends SecureDirectoryStream<Path>
+ implements SecureDirectoryStream<Path>
{
private final UnixDirectoryStream ds;
private final int dfd;
@@ -81,6 +81,20 @@
return (UnixPath)obj;
}
+ private boolean followLinks(LinkOption... options) {
+ boolean followLinks = true;
+ for (LinkOption option: options) {
+ if (option == LinkOption.NOFOLLOW_LINKS) {
+ followLinks = false;
+ continue;
+ }
+ if (option == null)
+ throw new NullPointerException();
+ throw new AssertionError("Should not get here");
+ }
+ return followLinks;
+ }
+
/**
* Opens sub-directory in this directory
*/
@@ -91,7 +105,7 @@
{
UnixPath file = getName(obj);
UnixPath child = ds.directory().resolve(file);
- boolean followLinks = file.getFileSystem().followLinks(options);
+ boolean followLinks = followLinks(options);
// permission check using name resolved against original path of directory
SecurityManager sm = System.getSecurityManager();
@@ -302,7 +316,7 @@
LinkOption... options)
{
UnixPath file = getName(obj);
- boolean followLinks = file.getFileSystem().followLinks(options);
+ boolean followLinks = followLinks(options);
return getFileAttributeViewImpl(file, type, followLinks);
}
@@ -336,7 +350,11 @@
private void checkWriteAccess() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ds.directory().resolve(file).checkWrite();
+ if (file == null) {
+ ds.directory().checkWrite();
+ } else {
+ ds.directory().resolve(file).checkWrite();
+ }
}
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixUriUtils.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixUriUtils.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,8 +25,11 @@
package sun.nio.fs;
+import java.nio.file.Path;
+import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.Arrays;
/**
* Unix specific Path <--> URI conversion
@@ -38,7 +41,7 @@
/**
* Converts URI to Path
*/
- static UnixPath fromUri(UnixFileSystem fs, URI uri) {
+ static Path fromUri(UnixFileSystem fs, URI uri) {
if (!uri.isAbsolute())
throw new IllegalArgumentException("URI is not absolute");
if (uri.isOpaque())
@@ -53,22 +56,41 @@
if (uri.getQuery() != null)
throw new IllegalArgumentException("URI has a query component");
- String path = uri.getPath();
- if (path.equals(""))
+ // compatability with java.io.File
+ if (!uri.toString().startsWith("file:///"))
+ return new File(uri).toPath();
+
+ // transformation use raw path
+ String p = uri.getRawPath();
+ int len = p.length();
+ if (len == 0)
throw new IllegalArgumentException("URI path component is empty");
- if (path.endsWith("/") && (path.length() > 1)) {
- // "/foo/" --> "/foo", but "/" --> "/"
- path = path.substring(0, path.length() - 1);
- }
- // preserve bytes
- byte[] result = new byte[path.length()];
- for (int i=0; i<path.length(); i++) {
- byte v = (byte)(path.charAt(i));
- if (v == 0)
- throw new IllegalArgumentException("Nul character not allowed");
- result[i] = v;
+ // transform escaped octets and unescaped characters to bytes
+ if (p.endsWith("/") && len > 1)
+ len--;
+ byte[] result = new byte[len];
+ int rlen = 0;
+ int pos = 0;
+ while (pos < len) {
+ char c = p.charAt(pos++);
+ byte b;
+ if (c == '%') {
+ assert (pos+2) <= len;
+ char c1 = p.charAt(pos++);
+ char c2 = p.charAt(pos++);
+ b = (byte)((decode(c1) << 4) | decode(c2));
+ if (b == 0)
+ throw new IllegalArgumentException("Nul character not allowed");
+ } else {
+ assert c < 0x80;
+ b = (byte)c;
+ }
+ result[rlen++] = b;
}
+ if (rlen != result.length)
+ result = Arrays.copyOf(result, rlen);
+
return new UnixPath(fs, result);
}
@@ -86,7 +108,7 @@
} else {
sb.append('%');
sb.append(hexDigits[(c >> 4) & 0x0f]);
- sb.append(hexDigits[(c >> 0) & 0x0f]);
+ sb.append(hexDigits[(c) & 0x0f]);
}
}
@@ -164,6 +186,17 @@
return false;
}
+ // decode
+ private static int decode(char c) {
+ if ((c >= '0') && (c <= '9'))
+ return c - '0';
+ if ((c >= 'a') && (c <= 'f'))
+ return c - 'a' + 10;
+ if ((c >= 'A') && (c <= 'F'))
+ return c - 'A' + 10;
+ throw new AssertionError();
+ }
+
// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
// "8" | "9"
private static final long L_DIGIT = lowMask('0', '9');
--- a/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Mon Feb 14 16:30:10 2011 -0800
@@ -55,12 +55,23 @@
#include "sun_nio_fs_UnixNativeDispatcher.h"
+/**
+ * Size of password or group entry when not available via sysconf
+ */
+#define ENT_BUF_SIZE 1024
+
#define RESTARTABLE(_cmd, _result) do { \
do { \
_result = _cmd; \
} while((_result == -1) && (errno == EINTR)); \
} while(0)
+#define RESTARTABLE_RETURN_PTR(_cmd, _result) do { \
+ do { \
+ _result = _cmd; \
+ } while((_result == NULL) && (errno == EINTR)); \
+} while(0)
+
static jfieldID attrs_st_mode;
static jfieldID attrs_st_ino;
static jfieldID attrs_st_dev;
@@ -858,37 +869,41 @@
{
jbyteArray result = NULL;
int buflen;
+ char* pwbuf;
+ /* allocate buffer for password record */
buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
+ pwbuf = (char*)malloc(buflen);
+ if (pwbuf == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "native heap");
} else {
- char* pwbuf = (char*)malloc(buflen);
- if (pwbuf == NULL) {
- JNU_ThrowOutOfMemoryError(env, "native heap");
- } else {
- struct passwd pwent;
- struct passwd* p;
- int res = 0;
+ struct passwd pwent;
+ struct passwd* p = NULL;
+ int res = 0;
-#ifdef __solaris__
- p = getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen);
-#else
- res = getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p);
-#endif
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen), p);
+ #else
+ RESTARTABLE(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p), res);
+ #endif
- if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
+ if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT)
throwUnixException(env, errno);
- } else {
- jsize len = strlen(p->pw_name);
- result = (*env)->NewByteArray(env, len);
- if (result != NULL) {
- (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
- }
+ } else {
+ jsize len = strlen(p->pw_name);
+ result = (*env)->NewByteArray(env, len);
+ if (result != NULL) {
+ (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
}
- free(pwbuf);
}
+ free(pwbuf);
}
+
return result;
}
@@ -898,36 +913,55 @@
{
jbyteArray result = NULL;
int buflen;
+ int retry;
+ /* initial size of buffer for group record */
buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
- } else {
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
+
+ do {
+ struct group grent;
+ struct group* g = NULL;
+ int res = 0;
+
char* grbuf = (char*)malloc(buflen);
if (grbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
- } else {
- struct group grent;
- struct group* g;
- int res = 0;
+ return NULL;
+ }
+
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen), g);
+ #else
+ RESTARTABLE(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g), res);
+ #endif
-#ifdef __solaris__
- g = getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen);
-#else
- res = getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g);
-#endif
- if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
- throwUnixException(env, errno);
- } else {
- jsize len = strlen(g->gr_name);
- result = (*env)->NewByteArray(env, len);
- if (result != NULL) {
- (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
+ retry = 0;
+ if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT) {
+ if (errno == ERANGE) {
+ /* insufficient buffer size so need larger buffer */
+ buflen += ENT_BUF_SIZE;
+ retry = 1;
+ } else {
+ throwUnixException(env, errno);
}
}
- free(grbuf);
+ } else {
+ jsize len = strlen(g->gr_name);
+ result = (*env)->NewByteArray(env, len);
+ if (result != NULL) {
+ (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
+ }
}
- }
+
+ free(grbuf);
+
+ } while (retry);
+
return result;
}
@@ -938,36 +972,37 @@
jint uid = -1;
int buflen;
char* pwbuf;
- struct passwd pwent;
- struct passwd* p;
- int res = 0;
- const char* name = (const char*)jlong_to_ptr(nameAddress);
+ /* allocate buffer for password record */
buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
- return -1;
- }
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
pwbuf = (char*)malloc(buflen);
if (pwbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
- return -1;
- }
+ } else {
+ struct passwd pwent;
+ struct passwd* p = NULL;
+ int res = 0;
+ const char* name = (const char*)jlong_to_ptr(nameAddress);
-#ifdef __solaris__
- p = getpwnam_r(name, &pwent, pwbuf, (size_t)buflen);
-#else
- res = getpwnam_r(name, &pwent, pwbuf, (size_t)buflen, &p);
-#endif
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen), p);
+ #else
+ RESTARTABLE(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen, &p), res);
+ #endif
- if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
- /* not found or error */
- } else {
- uid = p->pw_uid;
+ if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT)
+ throwUnixException(env, errno);
+ } else {
+ uid = p->pw_uid;
+ }
+ free(pwbuf);
}
- free(pwbuf);
-
return uid;
}
@@ -976,36 +1011,52 @@
jlong nameAddress)
{
jint gid = -1;
- int buflen;
- char* grbuf;
- struct group grent;
- struct group* g;
- int res = 0;
- const char* name = (const char*)jlong_to_ptr(nameAddress);
+ int buflen, retry;
+ /* initial size of buffer for group record */
buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
- return -1;
- }
- grbuf = (char*)malloc(buflen);
- if (grbuf == NULL) {
- JNU_ThrowOutOfMemoryError(env, "native heap");
- return -1;
- }
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
+
+ do {
+ struct group grent;
+ struct group* g = NULL;
+ int res = 0;
+ char *grbuf;
+ const char* name = (const char*)jlong_to_ptr(nameAddress);
+
+ grbuf = (char*)malloc(buflen);
+ if (grbuf == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "native heap");
+ return -1;
+ }
-#ifdef __solaris__
- g = getgrnam_r(name, &grent, grbuf, (size_t)buflen);
-#else
- res = getgrnam_r(name, &grent, grbuf, (size_t)buflen, &g);
-#endif
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getgrnam_r(name, &grent, grbuf, (size_t)buflen), g);
+ #else
+ RESTARTABLE(getgrnam_r(name, &grent, grbuf, (size_t)buflen, &g), res);
+ #endif
- if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
- /* not found or error */
- } else {
- gid = g->gr_gid;
- }
- free(grbuf);
+ retry = 0;
+ if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT) {
+ if (errno == ERANGE) {
+ /* insufficient buffer size so need larger buffer */
+ buflen += ENT_BUF_SIZE;
+ retry = 1;
+ } else {
+ throwUnixException(env, errno);
+ }
+ }
+ } else {
+ gid = g->gr_gid;
+ }
+
+ free(grbuf);
+
+ } while (retry);
return gid;
}
--- a/jdk/src/windows/classes/java/net/PlainSocketImpl.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/java/net/PlainSocketImpl.java Mon Feb 14 16:30:10 2011 -0800
@@ -138,6 +138,9 @@
protected synchronized void create(boolean stream) throws IOException {
impl.create(stream);
+
+ // set fd to delegate's fd to be compatible with older releases
+ this.fd = impl.fd;
}
protected void connect(String host, int port)
@@ -166,7 +169,7 @@
impl.doConnect(address, port, timeout);
}
- protected synchronized void bind(InetAddress address, int lport)
+ protected synchronized void bind(InetAddress address, int lport)
throws IOException
{
impl.bind(address, lport);
@@ -174,9 +177,13 @@
protected synchronized void accept(SocketImpl s) throws IOException {
// pass in the real impl not the wrapper.
- ((PlainSocketImpl)s).impl.address = new InetAddress();
- ((PlainSocketImpl)s).impl.fd = new FileDescriptor();
- impl.accept(((PlainSocketImpl)s).impl);
+ SocketImpl delegate = ((PlainSocketImpl)s).impl;
+ delegate.address = new InetAddress();
+ delegate.fd = new FileDescriptor();
+ impl.accept(delegate);
+
+ // set fd to delegate's fd to be compatible with older releases
+ s.fd = delegate.fd;
}
void setFileDescriptor(FileDescriptor fd) {
@@ -208,11 +215,21 @@
}
protected void close() throws IOException {
- impl.close();
+ try {
+ impl.close();
+ } finally {
+ // set fd to delegate's fd to be compatible with older releases
+ this.fd = null;
+ }
}
void reset() throws IOException {
- impl.reset();
+ try {
+ impl.reset();
+ } finally {
+ // set fd to delegate's fd to be compatible with older releases
+ this.fd = null;
+ }
}
protected void shutdownInput() throws IOException {
--- a/jdk/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java Mon Feb 14 16:30:10 2011 -0800
@@ -42,12 +42,12 @@
}
@Override
- public String implProbeContentType(FileRef file) throws IOException {
+ public String implProbeContentType(Path file) throws IOException {
if (!(file instanceof Path))
return null;
// get file extension
- Path name = ((Path)file).getName();
+ Path name = file.getFileName();
if (name == null)
return null;
String filename = name.toString();
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java Mon Feb 14 16:30:10 2011 -0800
@@ -167,22 +167,6 @@
}
@Override
- public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(READONLY_NAME))
- return readAttributes().isReadOnly();
- if (attribute.equals(ARCHIVE_NAME))
- return readAttributes().isArchive();
- if (attribute.equals(SYSTEM_NAME))
- return readAttributes().isSystem();
- if (attribute.equals(HIDDEN_NAME))
- return readAttributes().isHidden();
- // implementation specific
- if (attribute.equals(ATTRIBUTES_NAME))
- return readAttributes().attributes();
- return super.getAttribute(attribute);
- }
-
- @Override
public void setAttribute(String attribute, Object value)
throws IOException
{
@@ -206,7 +190,7 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes)
+ public Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java Mon Feb 14 16:30:10 2011 -0800
@@ -158,7 +158,7 @@
if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
x.lastError() == ERROR_ALREADY_EXISTS)
{
- throw new FileAlreadyExistsException(
+ throw new DirectoryNotEmptyException(
target.getPathForExceptionMessage());
}
}
@@ -369,7 +369,7 @@
if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
x.lastError() == ERROR_ALREADY_EXISTS)
{
- throw new FileAlreadyExistsException(
+ throw new DirectoryNotEmptyException(
target.getPathForExceptionMessage());
}
}
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java Mon Feb 14 16:30:10 2011 -0800
@@ -117,28 +117,47 @@
return ((volInfo.flags() & FILE_READ_ONLY_VOLUME) != 0);
}
+ // read the free space info
+ private DiskFreeSpace readDiskFreeSpace() throws IOException {
+ try {
+ return GetDiskFreeSpaceEx(root);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(root);
+ return null;
+ }
+ }
+
@Override
- @SuppressWarnings("unchecked")
+ public long getTotalSpace() throws IOException {
+ return readDiskFreeSpace().totalNumberOfBytes();
+ }
+
+ @Override
+ public long getUsableSpace() throws IOException {
+ return readDiskFreeSpace().freeBytesAvailable();
+ }
+
+ @Override
+ public long getUnallocatedSpace() throws IOException {
+ return readDiskFreeSpace().freeBytesAvailable();
+ }
+
+ @Override
public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
if (type == null)
throw new NullPointerException();
- if (type == FileStoreSpaceAttributeView.class)
- return (V) new WindowsFileStoreAttributeView(this);
return (V) null;
}
@Override
public Object getAttribute(String attribute) throws IOException {
// standard
- if (attribute.equals("space:totalSpace"))
- return new WindowsFileStoreAttributeView(this)
- .readAttributes().totalSpace();
- if (attribute.equals("space:usableSpace"))
- return new WindowsFileStoreAttributeView(this)
- .readAttributes().usableSpace();
- if (attribute.equals("space:unallocatedSpace"))
- return new WindowsFileStoreAttributeView(this)
- .readAttributes().unallocatedSpace();
+ if (attribute.equals("totalSpace"))
+ return getTotalSpace();
+ if (attribute.equals("usableSpace"))
+ return getUsableSpace();
+ if (attribute.equals("unallocatedSpace"))
+ return getUnallocatedSpace();
// windows specific for testing purposes
if (attribute.equals("volume:vsn"))
return volInfo.volumeSerialNumber();
@@ -202,48 +221,4 @@
sb.append(")");
return sb.toString();
}
-
- static class WindowsFileStoreAttributeView
- implements FileStoreSpaceAttributeView
- {
- private final WindowsFileStore fs;
-
- WindowsFileStoreAttributeView(WindowsFileStore fs) {
- this.fs = fs;
- }
-
- @Override
- public String name() {
- return "space";
- }
-
- @Override
- public FileStoreSpaceAttributes readAttributes()
- throws IOException
- {
- // read the free space info
- DiskFreeSpace info = null;
- try {
- info = GetDiskFreeSpaceEx(fs.root);
- } catch (WindowsException x) {
- x.rethrowAsIOException(fs.root);
- }
-
- final DiskFreeSpace result = info;
- return new FileStoreSpaceAttributes() {
- @Override
- public long totalSpace() {
- return result.totalNumberOfBytes();
- }
- @Override
- public long usableSpace() {
- return result.freeBytesAvailable();
- }
- @Override
- public long unallocatedSpace() {
- return result.totalNumberOfFreeBytes();
- }
- };
- }
- }
}
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java Mon Feb 14 16:30:10 2011 -0800
@@ -127,7 +127,7 @@
}
// iterate over roots, ignoring those that the security manager denies
- ArrayList<Path> result = new ArrayList<Path>();
+ ArrayList<Path> result = new ArrayList<>();
SecurityManager sm = System.getSecurityManager();
for (int i = 0; i <= 25; i++) { // 0->A, 1->B, 2->C...
if ((drives & (1 << i)) != 0) {
@@ -235,33 +235,50 @@
}
@Override
- public Path getPath(String path) {
+ public final Path getPath(String first, String... more) {
+ String path;
+ if (more.length == 0) {
+ path = first;
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append(first);
+ for (String segment: more) {
+ if (segment.length() > 0) {
+ if (sb.length() > 0)
+ sb.append('\\');
+ sb.append(segment);
+ }
+ }
+ path = sb.toString();
+ }
return WindowsPath.parse(this, path);
}
@Override
public UserPrincipalLookupService getUserPrincipalLookupService() {
- return theLookupService;
+ return LookupService.instance;
}
- private static final UserPrincipalLookupService theLookupService =
- new UserPrincipalLookupService() {
- @Override
- public UserPrincipal lookupPrincipalByName(String name)
- throws IOException
- {
- return WindowsUserPrincipals.lookup(name);
- }
- @Override
- public GroupPrincipal lookupPrincipalByGroupName(String group)
- throws IOException
- {
- UserPrincipal user = WindowsUserPrincipals.lookup(group);
- if (!(user instanceof GroupPrincipal))
- throw new UserPrincipalNotFoundException(group);
- return (GroupPrincipal)user;
- }
- };
+ private static class LookupService {
+ static final UserPrincipalLookupService instance =
+ new UserPrincipalLookupService() {
+ @Override
+ public UserPrincipal lookupPrincipalByName(String name)
+ throws IOException
+ {
+ return WindowsUserPrincipals.lookup(name);
+ }
+ @Override
+ public GroupPrincipal lookupPrincipalByGroupName(String group)
+ throws IOException
+ {
+ UserPrincipal user = WindowsUserPrincipals.lookup(group);
+ if (!(user instanceof GroupPrincipal))
+ throw new UserPrincipalNotFoundException(group);
+ return (GroupPrincipal)user;
+ }
+ };
+ }
@Override
public PathMatcher getPathMatcher(String syntaxAndInput) {
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Mon Feb 14 16:30:10 2011 -0800
@@ -26,19 +26,25 @@
package sun.nio.fs;
import java.nio.file.*;
-import java.nio.file.spi.*;
import java.nio.file.attribute.*;
import java.nio.channels.*;
import java.net.URI;
import java.util.concurrent.ExecutorService;
-import java.io.IOException;
+import java.io.*;
import java.util.*;
+import java.security.AccessController;
+import sun.misc.Unsafe;
+import sun.nio.ch.ThreadPool;
+import sun.security.util.SecurityConstants;
-import sun.nio.ch.ThreadPool;
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
public class WindowsFileSystemProvider
- extends FileSystemProvider
+ extends AbstractFileSystemProvider
{
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+
private static final String USER_DIR = "user.dir";
private final WindowsFileSystem theFileSystem;
@@ -143,4 +149,505 @@
sd.release();
}
}
+
+ private boolean followLinks(LinkOption... options) {
+ boolean followLinks = true;
+ for (LinkOption option: options) {
+ if (option == LinkOption.NOFOLLOW_LINKS) {
+ followLinks = false;
+ continue;
+ }
+ if (option == null)
+ throw new NullPointerException();
+ throw new AssertionError("Should not get here");
+ }
+ return followLinks;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileAttributeView> V
+ getFileAttributeView(Path obj, Class<V> view, LinkOption... options)
+ {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ if (view == null)
+ throw new NullPointerException();
+ boolean followLinks = followLinks(options);
+ if (view == BasicFileAttributeView.class)
+ return (V) WindowsFileAttributeViews.createBasicView(file, followLinks);
+ if (view == DosFileAttributeView.class)
+ return (V) WindowsFileAttributeViews.createDosView(file, followLinks);
+ if (view == AclFileAttributeView.class)
+ return (V) new WindowsAclFileAttributeView(file, followLinks);
+ if (view == FileOwnerAttributeView.class)
+ return (V) new FileOwnerAttributeViewImpl(
+ new WindowsAclFileAttributeView(file, followLinks));
+ if (view == UserDefinedFileAttributeView.class)
+ return (V) new WindowsUserDefinedFileAttributeView(file, followLinks);
+ return (V) null;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <A extends BasicFileAttributes> A readAttributes(Path file,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ Class<? extends BasicFileAttributeView> view;
+ if (type == BasicFileAttributes.class)
+ view = BasicFileAttributeView.class;
+ else if (type == DosFileAttributes.class)
+ view = DosFileAttributeView.class;
+ else if (type == null)
+ throw new NullPointerException();
+ else
+ throw new UnsupportedOperationException();
+ return (A) getFileAttributeView(file, view, options).readAttributes();
+ }
+
+ @Override
+ public DynamicFileAttributeView getFileAttributeView(Path obj, String name, LinkOption... options) {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ boolean followLinks = followLinks(options);
+ if (name.equals("basic"))
+ return WindowsFileAttributeViews.createBasicView(file, followLinks);
+ if (name.equals("dos"))
+ return WindowsFileAttributeViews.createDosView(file, followLinks);
+ if (name.equals("acl"))
+ return new WindowsAclFileAttributeView(file, followLinks);
+ if (name.equals("owner"))
+ return new FileOwnerAttributeViewImpl(
+ new WindowsAclFileAttributeView(file, followLinks));
+ if (name.equals("user"))
+ return new WindowsUserDefinedFileAttributeView(file, followLinks);
+ return null;
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path obj,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ WindowsSecurityDescriptor sd =
+ WindowsSecurityDescriptor.fromAttribute(attrs);
+ try {
+ return WindowsChannelFactory
+ .newFileChannel(file.getPathForWin32Calls(),
+ file.getPathForPermissionCheck(),
+ options,
+ sd.address());
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file);
+ return null; // keep compiler happy
+ } finally {
+ sd.release();
+ }
+ }
+
+ @Override
+ boolean implDelete(Path obj, boolean failIfNotExists) throws IOException {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ file.checkDelete();
+
+ WindowsFileAttributes attrs = null;
+ try {
+ // need to know if file is a directory or junction
+ attrs = WindowsFileAttributes.get(file, false);
+ if (attrs.isDirectory() || attrs.isDirectoryLink()) {
+ RemoveDirectory(file.getPathForWin32Calls());
+ } else {
+ DeleteFile(file.getPathForWin32Calls());
+ }
+ return true;
+ } catch (WindowsException x) {
+
+ // no-op if file does not exist
+ if (!failIfNotExists &&
+ (x.lastError() == ERROR_FILE_NOT_FOUND ||
+ x.lastError() == ERROR_PATH_NOT_FOUND)) return false;
+
+ if (attrs != null && attrs.isDirectory()) {
+ // ERROR_ALREADY_EXISTS is returned when attempting to delete
+ // non-empty directory on SAMBA servers.
+ if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
+ x.lastError() == ERROR_ALREADY_EXISTS)
+ {
+ throw new DirectoryNotEmptyException(
+ file.getPathForExceptionMessage());
+ }
+ }
+ x.rethrowAsIOException(file);
+ return false;
+ }
+ }
+
+ @Override
+ public void copy(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ WindowsFileCopy.copy(WindowsPath.toWindowsPath(source),
+ WindowsPath.toWindowsPath(target),
+ options);
+ }
+
+ @Override
+ public void move(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ WindowsFileCopy.move(WindowsPath.toWindowsPath(source),
+ WindowsPath.toWindowsPath(target),
+ options);
+ }
+
+ /**
+ * Returns buffer with SID_AND_ATTRIBUTES structure representing the user
+ * associated with the current thread access token.
+ * FIXME - this should be cached.
+ */
+ private static NativeBuffer getUserInfo(WindowsPath file) throws IOException {
+ try {
+ long hToken = WindowsSecurity.processTokenWithQueryAccess;
+ int size = GetTokenInformation(hToken, TokenUser, 0L, 0);
+ assert size > 0;
+
+ NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
+ try {
+ int newsize = GetTokenInformation(hToken, TokenUser,
+ buffer.address(), size);
+ if (newsize != size)
+ throw new AssertionError();
+ return buffer;
+ } catch (WindowsException x) {
+ buffer.release();
+ throw x;
+ }
+ } catch (WindowsException x) {
+ throw new IOException(x.getMessage());
+ }
+ }
+
+ /**
+ * Reads the file ACL and return the effective access as ACCESS_MASK
+ */
+ private static int getEffectiveAccess(WindowsPath file) throws IOException {
+ // read security descriptor continaing ACL (symlinks are followed)
+ String target = WindowsLinkSupport.getFinalPath(file, true);
+ NativeBuffer aclBuffer = WindowsAclFileAttributeView
+ .getFileSecurity(target, DACL_SECURITY_INFORMATION);
+
+ // retrieves DACL from security descriptor
+ long pAcl = GetSecurityDescriptorDacl(aclBuffer.address());
+
+ // Use GetEffectiveRightsFromAcl to get effective access to file
+ try {
+ NativeBuffer userBuffer = getUserInfo(file);
+ try {
+ try {
+ // SID_AND_ATTRIBUTES->pSid
+ long pSid = unsafe.getAddress(userBuffer.address());
+ long pTrustee = BuildTrusteeWithSid(pSid);
+ try {
+ return GetEffectiveRightsFromAcl(pAcl, pTrustee);
+ } finally {
+ LocalFree(pTrustee);
+ }
+ } catch (WindowsException x) {
+ throw new IOException("Unable to get effective rights from ACL: " +
+ x.getMessage());
+ }
+ } finally {
+ userBuffer.release();
+ }
+ } finally {
+ aclBuffer.release();
+ }
+ }
+
+ @Override
+ public void checkAccess(Path obj, AccessMode... modes) throws IOException {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ // if no access modes then simply file attributes
+ if (modes.length == 0) {
+ file.checkRead();
+ try {
+ WindowsFileAttributes.get(file, true);
+ } catch (WindowsException exc) {
+ exc.rethrowAsIOException(file);
+ }
+ return;
+ }
+
+ boolean r = false;
+ boolean w = false;
+ boolean x = false;
+ for (AccessMode mode: modes) {
+ switch (mode) {
+ case READ : r = true; break;
+ case WRITE : w = true; break;
+ case EXECUTE : x = true; break;
+ default: throw new AssertionError("Should not get here");
+ }
+ }
+
+ int mask = 0;
+ if (r) {
+ file.checkRead();
+ mask |= FILE_READ_DATA;
+ }
+ if (w) {
+ file.checkWrite();
+ mask |= FILE_WRITE_DATA;
+ }
+ if (x) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkExec(file.getPathForPermissionCheck());
+ mask |= FILE_EXECUTE;
+ }
+
+ if ((getEffectiveAccess(file) & mask) == 0)
+ throw new AccessDeniedException(
+ file.getPathForExceptionMessage(), null,
+ "Effective permissions does not allow requested access");
+
+ // for write access we neeed to check if the DOS readonly attribute
+ // and if the volume is read-only
+ if (w) {
+ try {
+ WindowsFileAttributes attrs = WindowsFileAttributes.get(file, true);
+ if (!attrs.isDirectory() && attrs.isReadOnly())
+ throw new AccessDeniedException(
+ file.getPathForExceptionMessage(), null,
+ "DOS readonly attribute is set");
+ } catch (WindowsException exc) {
+ exc.rethrowAsIOException(file);
+ }
+
+ if (WindowsFileStore.create(file).isReadOnly()) {
+ throw new AccessDeniedException(
+ file.getPathForExceptionMessage(), null, "Read-only file system");
+ }
+ return;
+ }
+ }
+
+ @Override
+ public boolean isSameFile(Path obj1, Path obj2) throws IOException {
+ WindowsPath file1 = WindowsPath.toWindowsPath(obj1);
+ if (file1.equals(obj2))
+ return true;
+ if (obj2 == null)
+ throw new NullPointerException();
+ if (!(obj2 instanceof WindowsPath))
+ return false;
+ WindowsPath file2 = (WindowsPath)obj2;
+
+ // check security manager access to both files
+ file1.checkRead();
+ file2.checkRead();
+
+ // open both files and see if they are the same
+ long h1 = 0L;
+ try {
+ h1 = file1.openForReadAttributeAccess(true);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file1);
+ }
+ try {
+ WindowsFileAttributes attrs1 = null;
+ try {
+ attrs1 = WindowsFileAttributes.readAttributes(h1);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file1);
+ }
+ long h2 = 0L;
+ try {
+ h2 = file2.openForReadAttributeAccess(true);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file2);
+ }
+ try {
+ WindowsFileAttributes attrs2 = null;
+ try {
+ attrs2 = WindowsFileAttributes.readAttributes(h2);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file2);
+ }
+ return WindowsFileAttributes.isSameFile(attrs1, attrs2);
+ } finally {
+ CloseHandle(h2);
+ }
+ } finally {
+ CloseHandle(h1);
+ }
+ }
+
+ @Override
+ public boolean isHidden(Path obj) throws IOException {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ file.checkRead();
+ WindowsFileAttributes attrs = null;
+ try {
+ attrs = WindowsFileAttributes.get(file, true);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file);
+ }
+ // DOS hidden attribute not meaningful when set on directories
+ if (attrs.isDirectory())
+ return false;
+ return attrs.isHidden();
+ }
+
+ @Override
+ public FileStore getFileStore(Path obj) throws IOException {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
+ file.checkRead();
+ }
+ return WindowsFileStore.create(file);
+ }
+
+
+ @Override
+ public void createDirectory(Path obj, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ WindowsPath dir = WindowsPath.toWindowsPath(obj);
+ dir.checkWrite();
+ WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.fromAttribute(attrs);
+ try {
+ CreateDirectory(dir.getPathForWin32Calls(), sd.address());
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(dir);
+ } finally {
+ sd.release();
+ }
+ }
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ WindowsPath dir = WindowsPath.toWindowsPath(obj);
+ dir.checkRead();
+ if (filter == null)
+ throw new NullPointerException();
+ return new WindowsDirectoryStream(dir, filter);
+ }
+
+ @Override
+ public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ WindowsPath link = WindowsPath.toWindowsPath(obj1);
+ WindowsPath target = WindowsPath.toWindowsPath(obj2);
+
+ if (!link.getFileSystem().supportsLinks()) {
+ throw new UnsupportedOperationException("Symbolic links not supported "
+ + "on this operating system");
+ }
+
+ // no attributes allowed
+ if (attrs.length > 0) {
+ WindowsSecurityDescriptor.fromAttribute(attrs); // may throw NPE or UOE
+ throw new UnsupportedOperationException("Initial file attributes" +
+ "not supported when creating symbolic link");
+ }
+
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new LinkPermission("symbolic"));
+ link.checkWrite();
+ }
+
+ /**
+ * Throw I/O exception for the drive-relative case because Windows
+ * creates a link with the resolved target for this case.
+ */
+ if (target.type() == WindowsPathType.DRIVE_RELATIVE) {
+ throw new IOException("Cannot create symbolic link to working directory relative target");
+ }
+
+ /*
+ * Windows treates symbolic links to directories differently than it
+ * does to other file types. For that reason we need to check if the
+ * target is a directory (or a directory junction).
+ */
+ WindowsPath resolvedTarget;
+ if (target.type() == WindowsPathType.RELATIVE) {
+ WindowsPath parent = link.getParent();
+ resolvedTarget = (parent == null) ? target : parent.resolve(target);
+ } else {
+ resolvedTarget = link.resolve(target);
+ }
+ int flags = 0;
+ try {
+ WindowsFileAttributes wattrs = WindowsFileAttributes.get(resolvedTarget, false);
+ if (wattrs.isDirectory() || wattrs.isDirectoryLink())
+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
+ } catch (WindowsException x) {
+ // unable to access target so assume target is not a directory
+ }
+
+ // create the link
+ try {
+ CreateSymbolicLink(link.getPathForWin32Calls(),
+ WindowsPath.addPrefixIfNeeded(target.toString()),
+ flags);
+ } catch (WindowsException x) {
+ if (x.lastError() == ERROR_INVALID_REPARSE_DATA) {
+ x.rethrowAsIOException(link, target);
+ } else {
+ x.rethrowAsIOException(link);
+ }
+ }
+ }
+
+ @Override
+ public void createLink(Path obj1, Path obj2) throws IOException {
+ WindowsPath link = WindowsPath.toWindowsPath(obj1);
+ WindowsPath existing = WindowsPath.toWindowsPath(obj2);
+
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new LinkPermission("hard"));
+ link.checkWrite();
+ existing.checkWrite();
+ }
+
+ // create hard link
+ try {
+ CreateHardLink(link.getPathForWin32Calls(),
+ existing.getPathForWin32Calls());
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(link, existing);
+ }
+ }
+
+ @Override
+ public Path readSymbolicLink(Path obj1) throws IOException {
+ WindowsPath link = WindowsPath.toWindowsPath(obj1);
+ WindowsFileSystem fs = link.getFileSystem();
+ if (!fs.supportsLinks()) {
+ throw new UnsupportedOperationException("symbolic links not supported");
+ }
+
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ FilePermission perm = new FilePermission(link.getPathForPermissionCheck(),
+ SecurityConstants.FILE_READLINK_ACTION);
+ AccessController.checkPermission(perm);
+ }
+
+ String target = WindowsLinkSupport.readLink(link);
+ return WindowsPath.createFromNormalizedPath(fs, target);
+ }
}
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java Mon Feb 14 16:30:10 2011 -0800
@@ -27,18 +27,13 @@
import java.nio.file.*;
import java.nio.file.attribute.*;
-import java.nio.channels.*;
import java.io.*;
import java.net.URI;
-import java.security.AccessController;
import java.util.*;
import java.lang.ref.WeakReference;
import com.sun.nio.file.ExtendedWatchEventModifier;
-import sun.security.util.SecurityConstants;
-import sun.misc.Unsafe;
-
import static sun.nio.fs.WindowsNativeDispatcher.*;
import static sun.nio.fs.WindowsConstants.*;
@@ -47,7 +42,6 @@
*/
class WindowsPath extends AbstractPath {
- private static final Unsafe unsafe = Unsafe.getUnsafe();
// The maximum path that does not require long path prefix. On Windows
// the maximum path is 260 minus 1 (NUL) but for directories it is 260
@@ -229,6 +223,8 @@
// Relative path ("foo" for example)
if (type == WindowsPathType.RELATIVE) {
String defaultDirectory = getFileSystem().defaultDirectory();
+ if (isEmpty())
+ return defaultDirectory;
if (defaultDirectory.endsWith("\\")) {
return defaultDirectory + path;
} else {
@@ -286,7 +282,7 @@
}
// Add long path prefix to path if required
- private static String addPrefixIfNeeded(String path) {
+ static String addPrefixIfNeeded(String path) {
if (path.length() > 248) {
if (path.startsWith("\\\\")) {
path = "\\\\?\\UNC" + path.substring(1, path.length());
@@ -304,10 +300,22 @@
// -- Path operations --
+ private boolean isEmpty() {
+ return path.length() == 0;
+ }
+
+ private WindowsPath emptyPath() {
+ return new WindowsPath(getFileSystem(), WindowsPathType.RELATIVE, "", "");
+ }
+
@Override
- public Path getName() {
+ public Path getFileName() {
+ int len = path.length();
+ // represents empty path
+ if (len == 0)
+ return this;
// represents root component only
- if (root.length() == path.length())
+ if (root.length() == len)
return null;
int off = path.lastIndexOf('\\');
if (off < root.length())
@@ -340,6 +348,11 @@
}
// package-private
+ WindowsPathType type() {
+ return type;
+ }
+
+ // package-private
boolean isUnc() {
return type == WindowsPathType.UNC;
}
@@ -355,7 +368,7 @@
return type == WindowsPathType.ABSOLUTE || type == WindowsPathType.UNC;
}
- private WindowsPath checkPath(FileRef path) {
+ static WindowsPath toWindowsPath(Path path) {
if (path == null)
throw new NullPointerException();
if (!(path instanceof WindowsPath)) {
@@ -366,9 +379,9 @@
@Override
public WindowsPath relativize(Path obj) {
- WindowsPath other = checkPath(obj);
+ WindowsPath other = toWindowsPath(obj);
if (this.equals(other))
- return null;
+ return emptyPath();
// can only relativize paths of the same type
if (this.type != other.type)
@@ -410,7 +423,7 @@
@Override
public Path normalize() {
final int count = getNameCount();
- if (count == 0)
+ if (count == 0 || isEmpty())
return this;
boolean[] ignore = new boolean[count]; // true => ignore name
@@ -488,7 +501,7 @@
// corner case - all names removed
if (remaining == 0) {
- return getRoot();
+ return (root.length() == 0) ? emptyPath() : getRoot();
}
// re-constitute the path from the remaining names.
@@ -497,7 +510,7 @@
result.append(root);
for (int i=0; i<count; i++) {
if (!ignore[i]) {
- result.append(getName(i).toString());
+ result.append(getName(i));
result.append("\\");
}
}
@@ -509,9 +522,9 @@
@Override
public WindowsPath resolve(Path obj) {
- if (obj == null)
+ WindowsPath other = toWindowsPath(obj);
+ if (other.isEmpty())
return this;
- WindowsPath other = checkPath(obj);
if (other.isAbsolute())
return other;
@@ -559,27 +572,27 @@
}
}
- @Override
- public WindowsPath resolve(String other) {
- return resolve(getFileSystem().getPath(other));
- }
-
// generate offset array
private void initOffsets() {
if (offsets == null) {
- ArrayList<Integer> list = new ArrayList<Integer>();
- int start = root.length();
- int off = root.length();
- while (off < path.length()) {
- if (path.charAt(off) != '\\') {
- off++;
- } else {
+ ArrayList<Integer> list = new ArrayList<>();
+ if (isEmpty()) {
+ // empty path considered to have one name element
+ list.add(0);
+ } else {
+ int start = root.length();
+ int off = root.length();
+ while (off < path.length()) {
+ if (path.charAt(off) != '\\') {
+ off++;
+ } else {
+ list.add(start);
+ start = ++off;
+ }
+ }
+ if (start != off)
list.add(start);
- start = ++off;
- }
}
- if (start != off)
- list.add(start);
synchronized (this) {
if (offsets == null)
offsets = list.toArray(new Integer[list.size()]);
@@ -633,11 +646,16 @@
@Override
public boolean startsWith(Path obj) {
- WindowsPath other = checkPath(obj);
+ WindowsPath other = toWindowsPath(obj);
// if this path has a root component the given path's root must match
- if (!this.root.equalsIgnoreCase(other.root))
+ if (!this.root.equalsIgnoreCase(other.root)) {
return false;
+ }
+
+ // empty path starts with itself
+ if (other.isEmpty())
+ return this.isEmpty();
// roots match so compare elements
int thisCount = getNameCount();
@@ -657,13 +675,18 @@
@Override
public boolean endsWith(Path obj) {
- WindowsPath other = checkPath(obj);
+ WindowsPath other = toWindowsPath(obj);
// other path is longer
- if (other.path.length() > path.length()) {
+ if (other.path.length() > this.path.length()) {
return false;
}
+ // empty path ends in itself
+ if (other.isEmpty()) {
+ return this.isEmpty();
+ }
+
int thisCount = this.getNameCount();
int otherCount = other.getNameCount();
@@ -742,31 +765,6 @@
return path;
}
- @Override
- public Iterator<Path> iterator() {
- return new Iterator<Path>() {
- private int i = 0;
- @Override
- public boolean hasNext() {
- return (i < getNameCount());
- }
- @Override
- public Path next() {
- if (i < getNameCount()) {
- Path result = getName(i);
- i++;
- return result;
- } else {
- throw new NoSuchElementException();
- }
- }
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
-
// -- file operations --
// package-private
@@ -806,453 +804,6 @@
}
@Override
- public FileStore getFileStore()
- throws IOException
- {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
- checkRead();
- }
- return WindowsFileStore.create(this);
- }
-
- /**
- * Returns buffer with SID_AND_ATTRIBUTES structure representing the user
- * associated with the current thread access token.
- * FIXME - this should be cached.
- */
- private NativeBuffer getUserInfo() throws IOException {
- try {
- long hToken = WindowsSecurity.processTokenWithQueryAccess;
- int size = GetTokenInformation(hToken, TokenUser, 0L, 0);
- assert size > 0;
-
- NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
- try {
- int newsize = GetTokenInformation(hToken, TokenUser,
- buffer.address(), size);
- if (newsize != size)
- throw new AssertionError();
- return buffer;
- } catch (WindowsException x) {
- buffer.release();
- throw x;
- }
- } catch (WindowsException x) {
- throw new IOException(x.getMessage());
- }
- }
-
- /**
- * Reads the file ACL and return the effective access as ACCESS_MASK
- */
- private int getEffectiveAccess() throws IOException {
- // read security descriptor continaing ACL (symlinks are followed)
- String target = WindowsLinkSupport.getFinalPath(this, true);
- NativeBuffer aclBuffer = WindowsAclFileAttributeView
- .getFileSecurity(target, DACL_SECURITY_INFORMATION);
-
- // retrieves DACL from security descriptor
- long pAcl = GetSecurityDescriptorDacl(aclBuffer.address());
-
- // Use GetEffectiveRightsFromAcl to get effective access to file
- try {
- NativeBuffer userBuffer = getUserInfo();
- try {
- try {
- // SID_AND_ATTRIBUTES->pSid
- long pSid = unsafe.getAddress(userBuffer.address());
- long pTrustee = BuildTrusteeWithSid(pSid);
- try {
- return GetEffectiveRightsFromAcl(pAcl, pTrustee);
- } finally {
- LocalFree(pTrustee);
- }
- } catch (WindowsException x) {
- throw new IOException("Unable to get effective rights from ACL: " +
- x.getMessage());
- }
- } finally {
- userBuffer.release();
- }
- } finally {
- aclBuffer.release();
- }
- }
-
- @Override
- public void checkAccess(AccessMode... modes) throws IOException {
- // if no access modes then simply file attributes
- if (modes.length == 0) {
- checkRead();
- try {
- WindowsFileAttributes.get(this, true);
- } catch (WindowsException exc) {
- exc.rethrowAsIOException(this);
- }
- return;
- }
-
- boolean r = false;
- boolean w = false;
- boolean x = false;
- for (AccessMode mode: modes) {
- switch (mode) {
- case READ : r = true; break;
- case WRITE : w = true; break;
- case EXECUTE : x = true; break;
- default: throw new AssertionError("Should not get here");
- }
- }
-
- int mask = 0;
- if (r) {
- checkRead();
- mask |= FILE_READ_DATA;
- }
- if (w) {
- checkWrite();
- mask |= FILE_WRITE_DATA;
- }
- if (x) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkExec(getPathForPermissionCheck());
- mask |= FILE_EXECUTE;
- }
-
- if ((getEffectiveAccess() & mask) == 0)
- throw new AccessDeniedException(
- this.getPathForExceptionMessage(), null,
- "Effective permissions does not allow requested access");
-
- // for write access we neeed to check if the DOS readonly attribute
- // and if the volume is read-only
- if (w) {
- try {
- WindowsFileAttributes attrs = WindowsFileAttributes.get(this, true);
- if (!attrs.isDirectory() && attrs.isReadOnly())
- throw new AccessDeniedException(
- this.getPathForExceptionMessage(), null,
- "DOS readonly attribute is set");
- } catch (WindowsException exc) {
- exc.rethrowAsIOException(this);
- }
-
- if (WindowsFileStore.create(this).isReadOnly()) {
- throw new AccessDeniedException(
- this.getPathForExceptionMessage(), null, "Read-only file system");
- }
- return;
- }
- }
-
- @Override
- void implDelete(boolean failIfNotExists) throws IOException {
- checkDelete();
-
- WindowsFileAttributes attrs = null;
- try {
- // need to know if file is a directory or junction
- attrs = WindowsFileAttributes.get(this, false);
- if (attrs.isDirectory() || attrs.isDirectoryLink()) {
- RemoveDirectory(getPathForWin32Calls());
- } else {
- DeleteFile(getPathForWin32Calls());
- }
- } catch (WindowsException x) {
-
- // no-op if file does not exist
- if (!failIfNotExists &&
- (x.lastError() == ERROR_FILE_NOT_FOUND ||
- x.lastError() == ERROR_PATH_NOT_FOUND)) return;
-
- if (attrs != null && attrs.isDirectory()) {
- // ERROR_ALREADY_EXISTS is returned when attempting to delete
- // non-empty directory on SAMBA servers.
- if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
- x.lastError() == ERROR_ALREADY_EXISTS)
- {
- throw new DirectoryNotEmptyException(
- getPathForExceptionMessage());
- }
- }
- x.rethrowAsIOException(this);
- }
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
- throws IOException
- {
- checkRead();
- if (filter == null)
- throw new NullPointerException();
- return new WindowsDirectoryStream(this, filter);
- }
-
- @Override
- public void implCopyTo(Path obj, CopyOption... options) throws IOException {
- WindowsPath target = (WindowsPath)obj;
- WindowsFileCopy.copy(this, target, options);
- }
-
- @Override
- public void implMoveTo(Path obj, CopyOption... options) throws IOException {
- WindowsPath target = (WindowsPath)obj;
- WindowsFileCopy.move(this, target, options);
- }
-
- private boolean followLinks(LinkOption... options) {
- boolean followLinks = true;
- for (LinkOption option: options) {
- if (option == LinkOption.NOFOLLOW_LINKS) {
- followLinks = false;
- continue;
- }
- if (option == null)
- throw new NullPointerException();
- throw new AssertionError("Should not get here");
- }
- return followLinks;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileAttributeView> V
- getFileAttributeView(Class<V> view, LinkOption... options)
- {
- if (view == null)
- throw new NullPointerException();
- boolean followLinks = followLinks(options);
- if (view == BasicFileAttributeView.class)
- return (V) WindowsFileAttributeViews.createBasicView(this, followLinks);
- if (view == DosFileAttributeView.class)
- return (V) WindowsFileAttributeViews.createDosView(this, followLinks);
- if (view == AclFileAttributeView.class)
- return (V) new WindowsAclFileAttributeView(this, followLinks);
- if (view == FileOwnerAttributeView.class)
- return (V) new FileOwnerAttributeViewImpl(
- new WindowsAclFileAttributeView(this, followLinks));
- if (view == UserDefinedFileAttributeView.class)
- return (V) new WindowsUserDefinedFileAttributeView(this, followLinks);
- return (V) null;
- }
-
- @Override
- public DynamicFileAttributeView getFileAttributeView(String name, LinkOption... options) {
- boolean followLinks = followLinks(options);
- if (name.equals("basic"))
- return WindowsFileAttributeViews.createBasicView(this, followLinks);
- if (name.equals("dos"))
- return WindowsFileAttributeViews.createDosView(this, followLinks);
- if (name.equals("acl"))
- return new WindowsAclFileAttributeView(this, followLinks);
- if (name.equals("owner"))
- return new FileOwnerAttributeViewImpl(
- new WindowsAclFileAttributeView(this, followLinks));
- if (name.equals("user"))
- return new WindowsUserDefinedFileAttributeView(this, followLinks);
- return null;
- }
-
- @Override
- public WindowsPath createDirectory(FileAttribute<?>... attrs)
- throws IOException
- {
- checkWrite();
- WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.fromAttribute(attrs);
- try {
- CreateDirectory(getPathForWin32Calls(), sd.address());
- } catch (WindowsException x) {
- x.rethrowAsIOException(this);
- } finally {
- sd.release();
- }
- return this;
- }
-
- @Override
- public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- WindowsSecurityDescriptor sd =
- WindowsSecurityDescriptor.fromAttribute(attrs);
- try {
- return WindowsChannelFactory
- .newFileChannel(getPathForWin32Calls(),
- getPathForPermissionCheck(),
- options,
- sd.address());
- } catch (WindowsException x) {
- x.rethrowAsIOException(this);
- return null; // keep compiler happy
- } finally {
- sd.release();
- }
- }
-
- @Override
- public boolean isSameFile(Path obj) throws IOException {
- if (this.equals(obj))
- return true;
- if (!(obj instanceof WindowsPath)) // includes null check
- return false;
- WindowsPath other = (WindowsPath)obj;
-
- // check security manager access to both files
- this.checkRead();
- other.checkRead();
-
- // open both files and see if they are the same
- long h1 = 0L;
- try {
- h1 = this.openForReadAttributeAccess(true);
- } catch (WindowsException x) {
- x.rethrowAsIOException(this);
- }
- try {
- WindowsFileAttributes attrs1 = null;
- try {
- attrs1 = WindowsFileAttributes.readAttributes(h1);
- } catch (WindowsException x) {
- x.rethrowAsIOException(this);
- }
- long h2 = 0L;
- try {
- h2 = other.openForReadAttributeAccess(true);
- } catch (WindowsException x) {
- x.rethrowAsIOException(other);
- }
- try {
- WindowsFileAttributes attrs2 = null;
- try {
- attrs2 = WindowsFileAttributes.readAttributes(h2);
- } catch (WindowsException x) {
- x.rethrowAsIOException(other);
- }
- return WindowsFileAttributes.isSameFile(attrs1, attrs2);
- } finally {
- CloseHandle(h2);
- }
- } finally {
- CloseHandle(h1);
- }
- }
-
- @Override
- public WindowsPath createSymbolicLink(Path obj, FileAttribute<?>... attrs)
- throws IOException
- {
- if (!getFileSystem().supportsLinks()) {
- throw new UnsupportedOperationException("Symbolic links not supported "
- + "on this operating system");
- }
-
- WindowsPath target = checkPath(obj);
-
- // no attributes allowed
- if (attrs.length > 0) {
- WindowsSecurityDescriptor.fromAttribute(attrs); // may throw NPE or UOE
- throw new UnsupportedOperationException("Initial file attributes" +
- "not supported when creating symbolic link");
- }
-
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new LinkPermission("symbolic"));
- this.checkWrite();
- }
-
- /**
- * Throw I/O exception for the drive-relative case because Windows
- * creates a link with the resolved target for this case.
- */
- if (target.type == WindowsPathType.DRIVE_RELATIVE) {
- throw new IOException("Cannot create symbolic link to working directory relative target");
- }
-
- /*
- * Windows treates symbolic links to directories differently than it
- * does to other file types. For that reason we need to check if the
- * target is a directory (or a directory junction).
- */
- WindowsPath resolvedTarget;
- if (target.type == WindowsPathType.RELATIVE) {
- WindowsPath parent = getParent();
- resolvedTarget = (parent == null) ? target : parent.resolve(target);
- } else {
- resolvedTarget = resolve(target);
- }
- int flags = 0;
- try {
- WindowsFileAttributes wattrs = WindowsFileAttributes.get(resolvedTarget, false);
- if (wattrs.isDirectory() || wattrs.isDirectoryLink())
- flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
- } catch (WindowsException x) {
- // unable to access target so assume target is not a directory
- }
-
- // create the link
- try {
- CreateSymbolicLink(getPathForWin32Calls(),
- addPrefixIfNeeded(target.toString()),
- flags);
- } catch (WindowsException x) {
- if (x.lastError() == ERROR_INVALID_REPARSE_DATA) {
- x.rethrowAsIOException(this, target);
- } else {
- x.rethrowAsIOException(this);
- }
- }
- return this;
- }
-
- @Override
- public Path createLink(Path obj) throws IOException {
- WindowsPath existing = checkPath(obj);
-
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new LinkPermission("hard"));
- this.checkWrite();
- existing.checkWrite();
- }
-
- // create hard link
- try {
- CreateHardLink(this.getPathForWin32Calls(),
- existing.getPathForWin32Calls());
- } catch (WindowsException x) {
- x.rethrowAsIOException(this, existing);
- }
-
- return this;
- }
-
- @Override
- public WindowsPath readSymbolicLink() throws IOException {
- if (!getFileSystem().supportsLinks()) {
- throw new UnsupportedOperationException("symbolic links not supported");
- }
-
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- FilePermission perm = new FilePermission(getPathForPermissionCheck(),
- SecurityConstants.FILE_READLINK_ACTION);
- AccessController.checkPermission(perm);
- }
-
- String target = WindowsLinkSupport.readLink(this);
- return createFromNormalizedPath(getFileSystem(), target);
- }
-
- @Override
public URI toUri() {
return WindowsUriSupport.toUri(this);
}
@@ -1283,21 +834,6 @@
}
@Override
- public boolean isHidden() throws IOException {
- checkRead();
- WindowsFileAttributes attrs = null;
- try {
- attrs = WindowsFileAttributes.get(this, true);
- } catch (WindowsException x) {
- x.rethrowAsIOException(this);
- }
- // DOS hidden attribute not meaningful when set on directories
- if (attrs.isDirectory())
- return false;
- return attrs.isHidden();
- }
-
- @Override
public WatchKey register(WatchService watcher,
WatchEvent.Kind<?>[] events,
WatchEvent.Modifier... modifiers)
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java Mon Feb 14 16:30:10 2011 -0800
@@ -74,8 +74,6 @@
* Parses the given input as a Windows path
*/
static Result parse(String input) {
- if (input == null || input.length() == 0)
- throw new InvalidPathException(input, "Empty or null path");
return parse(input, true);
}
@@ -135,7 +133,7 @@
}
}
if (off == 0) {
- if (isSlash(input.charAt(0))) {
+ if (len > 0 && isSlash(input.charAt(0))) {
type = WindowsPathType.DIRECTORY_RELATIVE;
root = "\\";
} else {
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java Mon Feb 14 16:30:10 2011 -0800
@@ -214,7 +214,7 @@
// map flags
byte aceFlags = unsafe.getByte(aceAddress + OFFSETOF_FLAGS);
- Set<AclEntryFlag> flags = new HashSet<AclEntryFlag>();
+ Set<AclEntryFlag> flags = EnumSet.noneOf(AclEntryFlag.class);
if ((aceFlags & OBJECT_INHERIT_ACE) != 0)
flags.add(AclEntryFlag.FILE_INHERIT);
if ((aceFlags & CONTAINER_INHERIT_ACE) != 0)
@@ -226,7 +226,7 @@
// map access mask
int mask = unsafe.getInt(aceAddress + OFFSETOF_ACCESS_MASK);
- Set<AclEntryPermission> perms = new HashSet<AclEntryPermission>();
+ Set<AclEntryPermission> perms = EnumSet.noneOf(AclEntryPermission.class);
if ((mask & FILE_READ_DATA) > 0)
perms.add(AclEntryPermission.READ_DATA);
if ((mask & FILE_WRITE_DATA) > 0)
@@ -378,7 +378,7 @@
AclInformation aclInfo = GetAclInformation(aclAddress);
aceCount = aclInfo.aceCount();
}
- ArrayList<AclEntry> result = new ArrayList<AclEntry>(aceCount);
+ ArrayList<AclEntry> result = new ArrayList<>(aceCount);
// decode each of the ACEs to AclEntry objects
for (int i=0; i<aceCount; i++) {
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java Mon Feb 14 16:30:10 2011 -0800
@@ -65,7 +65,7 @@
// enumerates the file streams using FindFirstStream/FindNextStream APIs.
private List<String> listUsingStreamEnumeration() throws IOException {
- List<String> list = new ArrayList<String>();
+ List<String> list = new ArrayList<>();
try {
FirstStream first = FindFirstStream(file.getPathForWin32Calls());
if (first != null) {
@@ -114,7 +114,7 @@
NativeBuffer buffer = null;
// result with names of alternative data streams
- final List<String> list = new ArrayList<String>();
+ final List<String> list = new ArrayList<>();
try {
buffer = NativeBuffers.getNativeBuffer(BUFFER_SIZE);
@@ -216,7 +216,7 @@
// wrap with channel
FileChannel fc = null;
try {
- Set<OpenOption> opts = new HashSet<OpenOption>();
+ Set<OpenOption> opts = new HashSet<>();
opts.add(READ);
if (!followLinks)
opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
@@ -243,7 +243,7 @@
// wrap with channel
FileChannel fc = null;
try {
- Set<OpenOption> opts = new HashSet<OpenOption>();
+ Set<OpenOption> opts = new HashSet<>();
opts.add(READ);
if (!followLinks)
opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
@@ -298,7 +298,7 @@
x.rethrowAsIOException(file);
}
try {
- Set<OpenOption> opts = new HashSet<OpenOption>();
+ Set<OpenOption> opts = new HashSet<>();
if (!followLinks)
opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
opts.add(CREATE);
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java Mon Feb 14 16:30:10 2011 -0800
@@ -106,8 +106,11 @@
// completion key (used to map I/O completion to WatchKey)
private int completionKey;
- WindowsWatchKey(AbstractWatchService watcher, FileKey fileKey) {
- super(watcher);
+ WindowsWatchKey(Path dir,
+ AbstractWatchService watcher,
+ FileKey fileKey)
+ {
+ super(dir, watcher);
this.fileKey = fileKey;
}
@@ -405,7 +408,7 @@
WindowsWatchKey watchKey;
if (existing == null) {
// not registered so create new watch key
- watchKey = new WindowsWatchKey(watcher, fk)
+ watchKey = new WindowsWatchKey(dir, watcher, fk)
.init(handle, events, watchSubtree, buffer, countAddress,
overlappedAddress, completionKey);
// map file key to watch key
--- a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c Mon Feb 14 16:30:10 2011 -0800
@@ -220,19 +220,19 @@
/*we estimate the max length of memory needed as
"currentDir. length + pathname.length"
*/
- int len = wcslen(path);
+ int len = (int)wcslen(path);
len += currentDirLength(path, len);
if (len > MAX_PATH_LENGTH - 1) {
WCHAR *cp = (WCHAR*)malloc(len * sizeof(WCHAR));
if (cp != NULL) {
if (wcanonicalize(path, cp, len) >= 0) {
- rv = (*env)->NewString(env, cp, wcslen(cp));
+ rv = (*env)->NewString(env, cp, (jsize)wcslen(cp));
}
free(cp);
}
} else
if (wcanonicalize(path, canonicalPath, MAX_PATH_LENGTH) >= 0) {
- rv = (*env)->NewString(env, canonicalPath, wcslen(canonicalPath));
+ rv = (*env)->NewString(env, canonicalPath, (jsize)wcslen(canonicalPath));
}
} END_UNICODE_STRING(env, path);
if (rv == NULL) {
@@ -251,14 +251,14 @@
WCHAR canonicalPath[MAX_PATH_LENGTH];
WITH_UNICODE_STRING(env, canonicalPrefixString, canonicalPrefix) {
WITH_UNICODE_STRING(env, pathWithCanonicalPrefixString, pathWithCanonicalPrefix) {
- int len = wcslen(canonicalPrefix) + MAX_PATH;
+ int len = (int)wcslen(canonicalPrefix) + MAX_PATH;
if (len > MAX_PATH_LENGTH) {
WCHAR *cp = (WCHAR*)malloc(len * sizeof(WCHAR));
if (cp != NULL) {
if (wcanonicalizeWithPrefix(canonicalPrefix,
pathWithCanonicalPrefix,
cp, len) >= 0) {
- rv = (*env)->NewString(env, cp, wcslen(cp));
+ rv = (*env)->NewString(env, cp, (jsize)wcslen(cp));
}
free(cp);
}
@@ -266,7 +266,7 @@
if (wcanonicalizeWithPrefix(canonicalPrefix,
pathWithCanonicalPrefix,
canonicalPath, MAX_PATH_LENGTH) >= 0) {
- rv = (*env)->NewString(env, canonicalPath, wcslen(canonicalPath));
+ rv = (*env)->NewString(env, canonicalPath, (jsize)wcslen(canonicalPath));
}
} END_UNICODE_STRING(env, pathWithCanonicalPrefix);
} END_UNICODE_STRING(env, canonicalPrefix);
@@ -358,7 +358,7 @@
} else { /* pagefile.sys is a special case */
if (GetLastError() == ERROR_SHARING_VIOLATION) {
rv = java_io_FileSystem_BA_EXISTS;
- if ((pathlen = wcslen(pathbuf)) >= SPECIALFILE_NAMELEN &&
+ if ((pathlen = (jint)wcslen(pathbuf)) >= SPECIALFILE_NAMELEN &&
(_wcsicmp(pathbuf + pathlen - SPECIALFILE_NAMELEN,
L"pagefile.sys") == 0) ||
(_wcsicmp(pathbuf + pathlen - SPECIALFILE_NAMELEN,
@@ -625,7 +625,7 @@
}
/* Remove trailing space chars from directory name */
- len = wcslen(search_path);
+ len = (int)wcslen(search_path);
while (search_path[len-1] == ' ') {
len--;
}
@@ -668,7 +668,7 @@
|| !wcscmp(find_data.cFileName, L".."))
continue;
name = (*env)->NewString(env, find_data.cFileName,
- wcslen(find_data.cFileName));
+ (jsize)wcslen(find_data.cFileName));
if (name == NULL)
return NULL; // error;
if (len == maxlen) {
@@ -819,7 +819,7 @@
jchar *pf = p;
if (p == NULL) return NULL;
if (iswalpha(*p) && (p[1] == L':')) p += 2;
- ret = (*env)->NewString(env, p, wcslen(p));
+ ret = (*env)->NewString(env, p, (jsize)wcslen(p));
free (pf);
return ret;
}
--- a/jdk/src/windows/native/java/io/canonicalize_md.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/native/java/io/canonicalize_md.c Mon Feb 14 16:30:10 2011 -0800
@@ -479,7 +479,7 @@
assert(*src == L'\\'); /* Invariant */
*p = L'\0'; /* Temporarily clear separator */
- if ((pathlen = wcslen(path)) > MAX_PATH - 1) {
+ if ((pathlen = (int)wcslen(path)) > MAX_PATH - 1) {
pathbuf = getPrefixed(path, pathlen);
h = FindFirstFileW(pathbuf, &fd); /* Look up prefix */
free(pathbuf);
@@ -538,7 +538,7 @@
dend = dst + size; /* Don't go to or past here */
- if ((pathlen=wcslen(pathWithCanonicalPrefix)) > MAX_PATH - 1) {
+ if ((pathlen=(int)wcslen(pathWithCanonicalPrefix)) > MAX_PATH - 1) {
pathbuf = getPrefixed(pathWithCanonicalPrefix, pathlen);
h = FindFirstFileW(pathbuf, &fd); /* Look up prefix */
free(pathbuf);
--- a/jdk/src/windows/native/java/io/io_util_md.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/native/java/io/io_util_md.c Mon Feb 14 16:30:10 2011 -0800
@@ -104,7 +104,7 @@
else return 0; /* invalid drive name. */
dir = currentDir(di);
if (dir != NULL){
- dirlen = wcslen(dir);
+ dirlen = (int)wcslen(dir);
free(dir);
}
return dirlen;
@@ -115,7 +115,7 @@
int dirlen = -1;
dir = _wgetcwd(NULL, MAX_PATH);
if (dir != NULL) {
- curDirLenCached = wcslen(dir);
+ curDirLenCached = (int)wcslen(dir);
free(dir);
}
}
@@ -165,7 +165,7 @@
int max_path = 248; /* CreateDirectoryW() has the limit of 248 */
WITH_UNICODE_STRING(env, path, ps) {
- pathlen = wcslen(ps);
+ pathlen = (int)wcslen(ps);
if (pathlen != 0) {
if (pathlen > 2 &&
(ps[0] == L'\\' && ps[1] == L'\\' || //UNC
--- a/jdk/src/windows/native/sun/nio/ch/Iocp.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/native/sun/nio/ch/Iocp.c Mon Feb 14 16:30:10 2011 -0800
@@ -72,9 +72,10 @@
Java_sun_nio_ch_Iocp_createIoCompletionPort(JNIEnv* env, jclass this,
jlong handle, jlong existingPort, jint completionKey, jint concurrency)
{
+ ULONG_PTR ck = completionKey;
HANDLE port = CreateIoCompletionPort((HANDLE)jlong_to_ptr(handle),
(HANDLE)jlong_to_ptr(existingPort),
- (DWORD)completionKey,
+ ck,
(DWORD)concurrency);
if (port == NULL) {
JNU_ThrowIOExceptionWithLastError(env, "CreateIoCompletionPort failed");
@@ -96,7 +97,7 @@
jlong completionPort, jobject obj)
{
DWORD bytesTransferred;
- DWORD completionKey;
+ ULONG_PTR completionKey;
OVERLAPPED *lpOverlapped;
BOOL res;
--- a/jdk/src/windows/native/sun/nio/fs/RegistryFileTypeDetector.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/native/sun/nio/fs/RegistryFileTypeDetector.c Mon Feb 14 16:30:10 2011 -0800
@@ -51,7 +51,7 @@
res = RegQueryValueExW(hKey, lpValueName, NULL, &type, (LPBYTE)&data, &size);
if (res == ERROR_SUCCESS) {
if (type == REG_SZ) {
- jsize len = wcslen((WCHAR*)data);
+ jsize len = (jsize)wcslen((WCHAR*)data);
result = (*env)->NewString(env, (const jchar*)&data, len);
}
}
--- a/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c Mon Feb 14 16:30:10 2011 -0800
@@ -368,7 +368,7 @@
HANDLE handle = FindFirstFileW(lpFileName, &data);
if (handle != INVALID_HANDLE_VALUE) {
- jstring name = (*env)->NewString(env, data.cFileName, wcslen(data.cFileName));
+ jstring name = (*env)->NewString(env, data.cFileName, (jsize)wcslen(data.cFileName));
if (name == NULL)
return;
(*env)->SetLongField(env, obj, findFirst_handle, ptr_to_jlong(handle));
@@ -401,7 +401,7 @@
WIN32_FIND_DATAW* data = (WIN32_FIND_DATAW*)jlong_to_ptr(dataAddress);
if (FindNextFileW(h, data) != 0) {
- return (*env)->NewString(env, data->cFileName, wcslen(data->cFileName));
+ return (*env)->NewString(env, data->cFileName, (jsize)wcslen(data->cFileName));
} else {
if (GetLastError() != ERROR_NO_MORE_FILES)
throwWindowsException(env, GetLastError());
@@ -424,7 +424,7 @@
handle = (*FindFirstStream_func)(lpFileName, FindStreamInfoStandard, &data, 0);
if (handle != INVALID_HANDLE_VALUE) {
- jstring name = (*env)->NewString(env, data.cStreamName, wcslen(data.cStreamName));
+ jstring name = (*env)->NewString(env, data.cStreamName, (jsize)wcslen(data.cStreamName));
if (name == NULL)
return;
(*env)->SetLongField(env, obj, findStream_handle, ptr_to_jlong(handle));
@@ -452,7 +452,7 @@
}
if ((*FindNextStream_func)(h, &data) != 0) {
- return (*env)->NewString(env, data.cStreamName, wcslen(data.cStreamName));
+ return (*env)->NewString(env, data.cStreamName, (jsize)wcslen(data.cStreamName));
} else {
if (GetLastError() != ERROR_HANDLE_EOF)
throwWindowsException(env, GetLastError());
@@ -1224,9 +1224,10 @@
Java_sun_nio_fs_WindowsNativeDispatcher_CreateIoCompletionPort(JNIEnv* env, jclass this,
jlong fileHandle, jlong existingPort, jint completionKey)
{
+ ULONG_PTR ck = completionKey;
HANDLE port = CreateIoCompletionPort((HANDLE)jlong_to_ptr(fileHandle),
(HANDLE)jlong_to_ptr(existingPort),
- (DWORD)completionKey,
+ ck,
0);
if (port == NULL) {
throwWindowsException(env, GetLastError());
@@ -1239,7 +1240,7 @@
jlong completionPort, jobject obj)
{
DWORD bytesTransferred;
- DWORD completionKey;
+ ULONG_PTR completionKey;
OVERLAPPED *lpOverlapped;
BOOL res;
--- a/jdk/src/windows/resource/java.manifest Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/src/windows/resource/java.manifest Mon Feb 14 16:30:10 2011 -0800
@@ -41,4 +41,12 @@
</asmv3:windowsSettings>
</asmv3:application>
+ <!-- Indicate this JDK version is Windows 7 compatible -->
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ </application>
+ </compatibility>
+
</assembly>
--- a/jdk/test/com/sun/jndi/ldap/LdapName/Case.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/com/sun/jndi/ldap/LdapName/Case.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/*
* @test
* @bug 4278094
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jndi/ldap/LdapName/EmptyNameSearch.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6997561
+ * @summary A request for better error handling in JNDI
+ */
+
+import java.net.Socket;
+import java.net.ServerSocket;
+import java.io.*;
+import javax.naming.*;
+import javax.naming.directory.*;
+import javax.naming.ldap.*;
+import java.util.Collections;
+import java.util.Hashtable;
+
+public class EmptyNameSearch {
+
+ public static void main(String[] args) throws Exception {
+
+ // Start the LDAP server
+ Server s = new Server();
+ s.start();
+ Thread.sleep(3000);
+
+ // Setup JNDI parameters
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
+ "com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, "ldap://localhost:" + s.getPortNumber());
+
+ try {
+
+ // Create initial context
+ System.out.println("Client: connecting...");
+ DirContext ctx = new InitialDirContext(env);
+
+ System.out.println("Client: performing search...");
+ ctx.search(new LdapName(Collections.EMPTY_LIST), "cn=*", null);
+ ctx.close();
+
+ // Exit
+ throw new RuntimeException();
+
+ } catch (NamingException e) {
+ System.err.println("Passed: caught the expected Exception - " + e);
+
+ } catch (Exception e) {
+ System.err.println("Failed: caught an unexpected Exception - " + e);
+ throw e;
+ }
+ }
+
+ static class Server extends Thread {
+
+ private int serverPort = 0;
+ private byte[] bindResponse = {
+ 0x30, 0x0C, 0x02, 0x01, 0x01, 0x61, 0x07, 0x0A,
+ 0x01, 0x00, 0x04, 0x00, 0x04, 0x00
+ };
+ private byte[] searchResponse = {
+ 0x30, 0x0C, 0x02, 0x01, 0x02, 0x65, 0x07, 0x0A,
+ 0x01, 0x02, 0x04, 0x00, 0x04, 0x00
+ };
+
+ Server() {
+ }
+
+ public int getPortNumber() {
+ return serverPort;
+ }
+
+ public void run() {
+ try {
+ ServerSocket serverSock = new ServerSocket(0);
+ serverPort = serverSock.getLocalPort();
+ System.out.println("Server: listening on port " + serverPort);
+
+ Socket socket = serverSock.accept();
+ System.out.println("Server: connection accepted");
+
+ InputStream in = socket.getInputStream();
+ OutputStream out = socket.getOutputStream();
+
+ // Read the LDAP BindRequest
+ System.out.println("Server: reading request...");
+ while (in.read() != -1) {
+ in.skip(in.available());
+ break;
+ }
+
+ // Write an LDAP BindResponse
+ System.out.println("Server: writing response...");
+ out.write(bindResponse);
+ out.flush();
+
+ // Read the LDAP SearchRequest
+ System.out.println("Server: reading request...");
+ while (in.read() != -1) {
+ in.skip(in.available());
+ break;
+ }
+
+ // Write an LDAP SearchResponse
+ System.out.println("Server: writing response...");
+ out.write(searchResponse);
+ out.flush();
+
+ in.close();
+ out.close();
+ socket.close();
+ serverSock.close();
+
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+}
--- a/jdk/test/com/sun/jndi/ldap/LdapName/UnescapeTest.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/com/sun/jndi/ldap/LdapName/UnescapeTest.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/*
* @test
* @bug 4892070
--- a/jdk/test/com/sun/jndi/ldap/ReadTimeoutTest.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/com/sun/jndi/ldap/ReadTimeoutTest.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/**
* @test
* @bug 6176036
--- a/jdk/test/demo/zipfs/Basic.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/demo/zipfs/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -48,9 +48,9 @@
if (!found)
throw new RuntimeException("'jar' provider not installed");
- // Test: FileSystems#newFileSystem(FileRef)
+ // Test: FileSystems#newFileSystem(Path)
Map<String,?> env = new HashMap<String,Object>();
- FileSystems.newFileSystem(zipfile, env, null).close();
+ FileSystems.newFileSystem(zipfile, null).close();
// Test: FileSystems#newFileSystem(URI)
URI uri = new URI("jar", zipfile.toUri().toString(), null);
@@ -69,14 +69,11 @@
// Test: DirectoryStream
found = false;
- DirectoryStream<Path> stream = fs.getPath("/").newDirectoryStream();
- try {
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(fs.getPath("/"))) {
for (Path entry: stream) {
found = entry.toString().equals("/META-INF/");
if (found) break;
}
- } finally {
- stream.close();
}
if (!found)
@@ -84,21 +81,21 @@
// Test: copy file from zip file to current (scratch) directory
Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider");
- if (source.exists()) {
- Path target = Paths.get(source.getName().toString());
- source.copyTo(target, StandardCopyOption.REPLACE_EXISTING);
+ if (Files.exists(source)) {
+ Path target = Paths.get(source.getFileName().toString());
+ Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
try {
- long s1 = Attributes.readBasicFileAttributes(source).size();
- long s2 = Attributes.readBasicFileAttributes(target).size();
+ long s1 = Files.readAttributes(source, BasicFileAttributes.class).size();
+ long s2 = Files.readAttributes(target, BasicFileAttributes.class).size();
if (s2 != s1)
throw new RuntimeException("target size != source size");
} finally {
- target.delete();
+ Files.delete(target);
}
}
// Test: FileStore
- FileStore store = fs.getPath("/").getFileStore();
+ FileStore store = Files.getFileStore(fs.getPath("/"));
if (!store.supportsFileAttributeView("basic"))
throw new RuntimeException("BasicFileAttributeView should be supported");
@@ -107,7 +104,7 @@
if (fs.isOpen())
throw new RuntimeException("FileSystem should be closed");
try {
- fs.getPath("/missing").checkAccess(AccessMode.READ);
+ fs.provider().checkAccess(fs.getPath("/missing"), AccessMode.READ);
} catch (ClosedFileSystemException x) { }
}
@@ -125,9 +122,9 @@
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs)
{
- if (dir.getName() != null) {
+ if (dir.getFileName() != null) {
indent();
- System.out.println(dir.getName() + "/");
+ System.out.println(dir.getFileName() + "/");
indent++;
}
return FileVisitResult.CONTINUE;
@@ -138,7 +135,7 @@
BasicFileAttributes attrs)
{
indent();
- System.out.print(file.getName());
+ System.out.print(file.getFileName());
if (attrs.isRegularFile())
System.out.format(" (%d)", attrs.size());
System.out.println();
@@ -151,7 +148,7 @@
{
if (exc != null)
super.postVisitDirectory(dir, exc);
- if (dir.getName() != null)
+ if (dir.getFileName() != null)
indent--;
return FileVisitResult.CONTINUE;
}
--- a/jdk/test/demo/zipfs/PathOps.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/demo/zipfs/PathOps.java Mon Feb 14 16:30:10 2011 -0800
@@ -100,7 +100,7 @@
PathOps name(String expected) {
out.println("check name");
checkPath();
- check(path.getName(), expected);
+ check(path.getFileName(), expected);
return this;
}
@@ -197,7 +197,7 @@
try {
out.println("check two paths are same");
checkPath();
- check(path.isSameFile(test(target).path()), true);
+ check(Files.isSameFile(path, test(target).path()), true);
} catch (IOException ioe) {
fail();
}
@@ -252,31 +252,41 @@
.name("foo");
// startsWith
+ test("")
+ .starts("")
+ .notStarts("/");
test("/")
.starts("/")
.notStarts("/foo");
test("/foo")
.starts("/")
.starts("/foo")
- .notStarts("/f");
+ .notStarts("/f")
+ .notStarts("");
test("/foo/bar")
.starts("/")
.starts("/foo")
+ .starts("/foo/")
.starts("/foo/bar")
.notStarts("/f")
.notStarts("foo")
- .notStarts("foo/bar");
+ .notStarts("foo/bar")
+ .notStarts("");
test("foo")
.starts("foo")
.notStarts("f");
test("foo/bar")
.starts("foo")
+ .starts("foo/")
.starts("foo/bar")
.notStarts("f")
.notStarts("/foo")
.notStarts("/foo/bar");
// endsWith
+ test("")
+ .ends("")
+ .notEnds("/");
test("/")
.ends("/")
.notEnds("foo")
@@ -288,14 +298,24 @@
test("/foo/bar")
.ends("bar")
.ends("foo/bar")
+ .ends("foo/bar/")
+ .ends("/foo/bar")
+ .notEnds("/bar");
+ test("/foo/bar/")
+ .ends("bar")
+ .ends("foo/bar")
+ .ends("foo/bar/")
.ends("/foo/bar")
.notEnds("/bar");
test("foo")
.ends("foo");
test("foo/bar")
.ends("bar")
+ .ends("bar/")
+ .ends("foo/bar/")
.ends("foo/bar");
+
// elements
test("a/b/c")
.element(0,"a")
@@ -309,6 +329,8 @@
.absolute();
test("tmp")
.notAbsolute();
+ test("")
+ .notAbsolute();
// resolve
test("/tmp")
@@ -320,7 +342,7 @@
// relativize
test("/a/b/c")
- .relativize("/a/b/c", null)
+ .relativize("/a/b/c", "")
.relativize("/a/b/c/d/e", "d/e")
.relativize("/a/x", "../../x");
@@ -332,7 +354,7 @@
test("/foo")
.normalize("/foo");
test(".")
- .normalize(null);
+ .normalize("");
test("..")
.normalize("..");
test("/..")
@@ -344,7 +366,7 @@
test("./foo")
.normalize("foo");
test("foo/..")
- .normalize(null);
+ .normalize("");
test("../foo")
.normalize("../foo");
test("../../foo")
@@ -411,13 +433,13 @@
}
try {
- path.startsWith(null);
+ path.startsWith((Path)null);
throw new RuntimeException("NullPointerException not thrown");
} catch (NullPointerException npe) {
}
try {
- path.endsWith(null);
+ path.endsWith((Path)null);
throw new RuntimeException("NullPointerException not thrown");
} catch (NullPointerException npe) {
}
@@ -427,8 +449,7 @@
public static void main(String[] args) throws Throwable {
Path zipfile = Paths.get(args[0]);
- Map<String,?> env = new HashMap<String,Object>();
- fs = FileSystems.newFileSystem(zipfile, env, null);
+ fs = FileSystems.newFileSystem(zipfile, null);
npes();
doPathOpTests();
fs.close();
--- a/jdk/test/demo/zipfs/ZipFSTester.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/demo/zipfs/ZipFSTester.java Mon Feb 14 16:30:10 2011 -0800
@@ -25,6 +25,7 @@
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
+import java.nio.file.spi.*;
import java.nio.file.attribute.*;
import java.net.*;
import java.util.*;
@@ -40,15 +41,13 @@
public class ZipFSTester {
public static void main(String[] args) throws Throwable {
- FileSystem fs = null;
- try {
- fs = newZipFileSystem(Paths.get(args[0]), new HashMap<String, Object>());
+
+ try (FileSystem fs = newZipFileSystem(Paths.get(args[0]),
+ new HashMap<String, Object>()))
+ {
test0(fs);
test1(fs);
test2(fs); // more tests
- } finally {
- if (fs != null)
- fs.close();
}
}
@@ -63,17 +62,17 @@
}
for (String pname : list) {
Path path = fs.getPath(pname);
- if (!path.exists())
+ if (!Files.exists(path))
throw new RuntimeException("path existence check failed!");
while ((path = path.getParent()) != null) {
- if (!path.exists())
+ if (!Files.exists(path))
throw new RuntimeException("parent existence check failed!");
}
}
}
}
- static void test1(FileSystem fs)
+ static void test1(FileSystem fs0)
throws Exception
{
Random rdm = new Random();
@@ -81,16 +80,26 @@
Path tmpfsPath = getTempPath();
Map<String, Object> env = new HashMap<String, Object>();
env.put("create", "true");
- FileSystem fs0 = newZipFileSystem(tmpfsPath, env);
- z2zcopy(fs, fs0, "/", 0);
- fs0.close(); // sync to file
+ try (FileSystem copy = newZipFileSystem(tmpfsPath, env)) {
+ z2zcopy(fs0, copy, "/", 0);
+ }
+
+ try (FileSystem fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>())) {
- fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>());
- try {
+ FileSystemProvider provider = fs.provider();
+ // newFileSystem(path...) should not throw exception
+ try (FileSystem fsPath = provider.newFileSystem(tmpfsPath, new HashMap<String, Object>())){}
+ try (FileSystem fsUri = provider.newFileSystem(
+ new URI("jar", tmpfsPath.toUri().toString(), null),
+ new HashMap<String, Object>()))
+ {
+ throw new RuntimeException("newFileSystem(uri...) does not throw exception");
+ } catch (FileSystemAlreadyExistsException fsaee) {}
+
// prepare a src
Path src = getTempPath();
String tmpName = src.toString();
- OutputStream os = src.newOutputStream();
+ OutputStream os = Files.newOutputStream(src);
byte[] bits = new byte[12345];
rdm.nextBytes(bits);
os.write(bits);
@@ -98,37 +107,37 @@
// copyin
Path dst = getPathWithParents(fs, tmpName);
- src.copyTo(dst);
+ Files.copy(src, dst);
checkEqual(src, dst);
// copy
Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) +
"/efg" + rdm.nextInt(100) + "/foo.class");
- dst.copyTo(dst2);
+ Files.copy(dst, dst2);
//dst.moveTo(dst2);
checkEqual(src, dst2);
// delete
- dst.delete();
- if (dst.exists())
+ Files.delete(dst);
+ if (Files.exists(dst))
throw new RuntimeException("Failed!");
// moveout
Path dst3 = Paths.get(tmpName + "_Tmp");
- dst2.moveTo(dst3);
+ Files.move(dst2, dst3);
checkEqual(src, dst3);
// delete
- if (dst2.exists())
+ if (Files.exists(dst2))
throw new RuntimeException("Failed!");
- dst3.delete();
- if (dst3.exists())
+ Files.delete(dst3);
+ if (Files.exists(dst3))
throw new RuntimeException("Failed!");
// newInputStream on dir
Path parent = dst2.getParent();
try {
- parent.newInputStream();
+ Files.newInputStream(parent);
throw new RuntimeException("Failed");
} catch (FileSystemException e) {
e.printStackTrace(); // expected fse
@@ -147,17 +156,15 @@
Path tmp = Paths.get(tmpName + "_Tmp");
fchCopy(dst, tmp); // out
checkEqual(src, tmp);
- tmp.delete();
+ Files.delete(tmp);
// test channels
channel(fs, dst);
- dst.delete();
- src.delete();
+ Files.delete(dst);
+ Files.delete(src);
} finally {
- if (fs != null)
- fs.close();
- if (tmpfsPath.exists())
- tmpfsPath.delete();
+ if (Files.exists(tmpfsPath))
+ Files.delete(tmpfsPath);
}
}
@@ -242,7 +249,7 @@
while (itr.hasNext()) {
String path = itr.next();
try {
- if (fs2.getPath(path).exists()) {
+ if (Files.exists(fs2.getPath(path))) {
z2zmove(fs2, fs3, path);
itr.remove();
}
@@ -296,15 +303,16 @@
fs4.close();
System.out.printf("failed=%d%n", failed);
- fs1Path.delete();
- fs2Path.delete();
- fs3Path.delete();
+ Files.delete(fs1Path);
+ Files.delete(fs2Path);
+ Files.delete(fs3Path);
}
private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
- throws IOException
+ throws Exception
{
- return FileSystems.newFileSystem(path, env, null);
+ return FileSystems.newFileSystem(
+ new URI("jar", path.toUri().toString(), null), env, null);
}
private static Path getTempPath() throws IOException
@@ -317,11 +325,11 @@
private static void list(Path path, List<String> files, List<String> dirs )
throws IOException
{
- if (Attributes.readBasicFileAttributes(path).isDirectory()) {
- DirectoryStream<Path> ds = path.newDirectoryStream();
- for (Path child : ds)
- list(child, files, dirs);
- ds.close();
+ if (Files.isDirectory(path)) {
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {
+ for (Path child : ds)
+ list(child, files, dirs);
+ }
dirs.add(path.toString());
} else {
files.add(path.toString());
@@ -335,26 +343,26 @@
Path srcPath = src.getPath(path);
Path dstPath = dst.getPath(path);
- if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
- if (!dstPath.exists()) {
+ if (Files.isDirectory(srcPath)) {
+ if (!Files.exists(dstPath)) {
try {
mkdirs(dstPath);
} catch (FileAlreadyExistsException x) {}
}
- DirectoryStream<Path> ds = srcPath.newDirectoryStream();
- for (Path child : ds) {
- z2zcopy(src, dst,
- path + (path.endsWith("/")?"":"/") + child.getName(),
- method);
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(srcPath)) {
+ for (Path child : ds) {
+ z2zcopy(src, dst,
+ path + (path.endsWith("/")?"":"/") + child.getFileName(),
+ method);
+ }
}
- ds.close();
} else {
try {
- if (dstPath.exists())
+ if (Files.exists(dstPath))
return;
switch (method) {
case 0:
- srcPath.copyTo(dstPath);
+ Files.copy(srcPath, dstPath);
break;
case 1:
chCopy(srcPath, dstPath);
@@ -374,21 +382,21 @@
Path srcPath = src.getPath(path);
Path dstPath = dst.getPath(path);
- if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
- if (!dstPath.exists())
+ if (Files.isDirectory(srcPath)) {
+ if (!Files.exists(dstPath))
mkdirs(dstPath);
- DirectoryStream<Path> ds = srcPath.newDirectoryStream();
- for (Path child : ds) {
- z2zmove(src, dst,
- path + (path.endsWith("/")?"":"/") + child.getName());
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(srcPath)) {
+ for (Path child : ds) {
+ z2zmove(src, dst,
+ path + (path.endsWith("/")?"":"/") + child.getFileName());
+ }
}
- ds.close();
} else {
//System.out.println("moving..." + path);
Path parent = dstPath.getParent();
- if (parent != null && parent.notExists())
+ if (parent != null && Files.notExists(parent))
mkdirs(parent);
- srcPath.moveTo(dstPath);
+ Files.move(srcPath, dstPath);
}
}
@@ -409,7 +417,7 @@
BasicFileAttributes attrs)
{
indent();
- System.out.printf("%s%n", file.getName().toString());
+ System.out.printf("%s%n", file.getFileName().toString());
return FileVisitResult.CONTINUE;
}
@@ -435,20 +443,20 @@
}
private static void mkdirs(Path path) throws IOException {
- if (path.exists())
+ if (Files.exists(path))
return;
path = path.toAbsolutePath();
Path parent = path.getParent();
if (parent != null) {
- if (parent.notExists())
+ if (Files.notExists(parent))
mkdirs(parent);
}
- path.createDirectory();
+ Files.createDirectory(path);
}
private static void rmdirs(Path path) throws IOException {
while (path != null && path.getNameCount() != 0) {
- path.delete();
+ Files.delete(path);
path = path.getParent();
}
}
@@ -460,12 +468,11 @@
// src.toString(), dst.toString());
//streams
- InputStream isSrc = src.newInputStream();
- InputStream isDst = dst.newInputStream();
byte[] bufSrc = new byte[8192];
byte[] bufDst = new byte[8192];
-
- try {
+ try (InputStream isSrc = Files.newInputStream(src);
+ InputStream isDst = Files.newInputStream(dst))
+ {
int nSrc = 0;
while ((nSrc = isSrc.read(bufSrc)) != -1) {
int nDst = 0;
@@ -487,24 +494,21 @@
nSrc--;
}
}
- } finally {
- isSrc.close();
- isDst.close();
}
// channels
- SeekableByteChannel chSrc = src.newByteChannel();
- SeekableByteChannel chDst = dst.newByteChannel();
- if (chSrc.size() != chDst.size()) {
- System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
- chSrc.toString(), chSrc.size(),
- chDst.toString(), chDst.size());
- throw new RuntimeException("CHECK FAILED!");
- }
- ByteBuffer bbSrc = ByteBuffer.allocate(8192);
- ByteBuffer bbDst = ByteBuffer.allocate(8192);
+ try (SeekableByteChannel chSrc = Files.newByteChannel(src);
+ SeekableByteChannel chDst = Files.newByteChannel(dst))
+ {
+ if (chSrc.size() != chDst.size()) {
+ System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
+ chSrc.toString(), chSrc.size(),
+ chDst.toString(), chDst.size());
+ throw new RuntimeException("CHECK FAILED!");
+ }
+ ByteBuffer bbSrc = ByteBuffer.allocate(8192);
+ ByteBuffer bbDst = ByteBuffer.allocate(8192);
- try {
int nSrc = 0;
while ((nSrc = chSrc.read(bbSrc)) != -1) {
int nDst = chDst.read(bbDst);
@@ -526,9 +530,6 @@
}
} catch (IOException x) {
x.printStackTrace();
- } finally {
- chSrc.close();
- chDst.close();
}
}
@@ -540,23 +541,19 @@
openwrite.add(CREATE_NEW);
openwrite.add(WRITE);
- FileChannel srcFc = src.getFileSystem()
- .provider()
- .newFileChannel(src, read);
- FileChannel dstFc = dst.getFileSystem()
- .provider()
- .newFileChannel(dst, openwrite);
-
- try {
+ try (FileChannel srcFc = src.getFileSystem()
+ .provider()
+ .newFileChannel(src, read);
+ FileChannel dstFc = dst.getFileSystem()
+ .provider()
+ .newFileChannel(dst, openwrite))
+ {
ByteBuffer bb = ByteBuffer.allocate(8192);
while (srcFc.read(bb) >= 0) {
bb.flip();
dstFc.write(bb);
bb.clear();
}
- } finally {
- srcFc.close();
- dstFc.close();
}
}
@@ -568,35 +565,29 @@
openwrite.add(CREATE_NEW);
openwrite.add(WRITE);
- SeekableByteChannel srcCh = src.newByteChannel(read);
- SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
+ try (SeekableByteChannel srcCh = Files.newByteChannel(src, read);
+ SeekableByteChannel dstCh = Files.newByteChannel(dst, openwrite))
+ {
- try {
ByteBuffer bb = ByteBuffer.allocate(8192);
while (srcCh.read(bb) >= 0) {
bb.flip();
dstCh.write(bb);
bb.clear();
}
- } finally {
- srcCh.close();
- dstCh.close();
}
}
private static void streamCopy(Path src, Path dst) throws IOException
{
- InputStream isSrc = src.newInputStream();
- OutputStream osDst = dst.newOutputStream();
byte[] buf = new byte[8192];
- try {
+ try (InputStream isSrc = Files.newInputStream(src);
+ OutputStream osDst = Files.newOutputStream(dst))
+ {
int n = 0;
while ((n = isSrc.read(buf)) != -1) {
osDst.write(buf, 0, n);
}
- } finally {
- isSrc.close();
- osDst.close();
}
}
@@ -604,31 +595,35 @@
throws Exception
{
System.out.println("test ByteChannel...");
- SeekableByteChannel sbc = path.newByteChannel();
Set<OpenOption> read = new HashSet<>();
read.add(READ);
- System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size());
- ByteBuffer bb = ByteBuffer.allocate((int)sbc.size());
- int n = sbc.read(bb);
- System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n",
- n, sbc.position(), sbc.size());
- ByteBuffer bb2 = ByteBuffer.allocate((int)sbc.size());
+ int n = 0;
+ ByteBuffer bb = null;
+ ByteBuffer bb2 = null;
int N = 120;
- sbc.close();
+
+ try (SeekableByteChannel sbc = Files.newByteChannel(path)) {
+ System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size());
+ bb = ByteBuffer.allocate((int)sbc.size());
+ n = sbc.read(bb);
+ System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n",
+ n, sbc.position(), sbc.size());
+ bb2 = ByteBuffer.allocate((int)sbc.size());
+ }
// sbc.position(pos) is not supported in current version
// try the FileChannel
- sbc = fs.provider().newFileChannel(path, read);
- sbc.position(N);
- System.out.printf(" sbc[2]: pos=%d, size=%d%n",
- sbc.position(), sbc.size());
- bb2.limit(100);
- n = sbc.read(bb2);
- System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n",
- n, sbc.position(), sbc.size());
- System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n",
- N, bb.get(N) & 0xff, bb2.get(0) & 0xff);
- sbc.close();
+ try (SeekableByteChannel sbc = fs.provider().newFileChannel(path, read)) {
+ sbc.position(N);
+ System.out.printf(" sbc[2]: pos=%d, size=%d%n",
+ sbc.position(), sbc.size());
+ bb2.limit(100);
+ n = sbc.read(bb2);
+ System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n",
+ n, sbc.position(), sbc.size());
+ System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n",
+ N, bb.get(N) & 0xff, bb2.get(0) & 0xff);
+ }
}
// create parents if does not exist
@@ -637,7 +632,7 @@
{
Path path = fs.getPath(name);
Path parent = path.getParent();
- if (parent != null && parent.notExists())
+ if (parent != null && Files.notExists(parent))
mkdirs(parent);
return path;
}
--- a/jdk/test/demo/zipfs/basic.sh Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/demo/zipfs/basic.sh Mon Feb 14 16:30:10 2011 -0800
@@ -21,7 +21,7 @@
# questions.
#
# @test
-# @bug 6990846 7009092 7009085
+# @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840
# @summary Test ZipFileSystem demo
# @build Basic PathOps ZipFSTester
# @run shell basic.sh
--- a/jdk/test/java/awt/Container/CheckZOrderChange/CheckZOrderChange.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/awt/Container/CheckZOrderChange/CheckZOrderChange.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/*
@test %I% %E%
@bug 2161766
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/KeyboardFocusmanager/DefaultPolicyChange/DefaultPolicyChange_AWT.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,44 @@
+/*
+ @test
+ @bug 6741526
+ @summary KeyboardFocusManager.setDefaultFocusTraversalPolicy(FocusTraversalPolicy) affects created components
+ @library ../../regtesthelpers
+ @build Sysout
+ @author Andrei Dmitriev : area=awt-focus
+ @run main DefaultPolicyChange_AWT
+*/
+
+import java.awt.*;
+import test.java.awt.regtesthelpers.Sysout;
+
+public class DefaultPolicyChange_AWT {
+ public static void main(String []s) {
+ DefaultPolicyChange_AWT.runTestAWT();
+ }
+
+ private static void runTestAWT(){
+ KeyboardFocusManager currentKFM = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ FocusTraversalPolicy defaultFTP = currentKFM.getDefaultFocusTraversalPolicy();
+ ContainerOrderFocusTraversalPolicy newFTP = new ContainerOrderFocusTraversalPolicy();
+
+ Frame frame = new Frame();
+ Window window = new Window(frame);
+
+ FocusTraversalPolicy resultFTP = window.getFocusTraversalPolicy();
+ Sysout.println("FocusTraversalPolicy on window = " + resultFTP);
+ /**
+ * Note: this call doesn't affect already created components as they have
+ * their policy initialized. Only new components will use this policy as
+ * their default policy.
+ **/
+ Sysout.println("Now will set another policy.");
+ currentKFM.setDefaultFocusTraversalPolicy(newFTP);
+ resultFTP = window.getFocusTraversalPolicy();
+ if (!resultFTP.equals(defaultFTP)) {
+ Sysout.println("Failure! FocusTraversalPolicy should not change");
+ Sysout.println("Was: " + defaultFTP);
+ Sysout.println("Become: " + resultFTP);
+ throw new RuntimeException("Failure! FocusTraversalPolicy should not change");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/KeyboardFocusmanager/DefaultPolicyChange/DefaultPolicyChange_Swing.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,69 @@
+/*
+ @test
+ @bug 6741526
+ @summary KeyboardFocusManager.setDefaultFocusTraversalPolicy(FocusTraversalPolicy) affects created components
+ @library ../../regtesthelpers
+ @build Sysout
+ @author Andrei Dmitriev : area=awt-focus
+ @run main DefaultPolicyChange_Swing
+*/
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.table.DefaultTableModel;
+import test.java.awt.regtesthelpers.Sysout;
+
+public class DefaultPolicyChange_Swing {
+ public static void main(String []s) {
+ EventQueue.invokeLater(new Runnable(){
+ public void run (){
+ DefaultPolicyChange_Swing.runTestSwing();
+ }
+ });
+ }
+ private static void runTestSwing(){
+ KeyboardFocusManager currentKFM = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ FocusTraversalPolicy defaultFTP = currentKFM.getDefaultFocusTraversalPolicy();
+ ContainerOrderFocusTraversalPolicy newFTP = new ContainerOrderFocusTraversalPolicy();
+
+
+ JFrame jf = new JFrame("Test1");
+ JWindow jw = new JWindow(jf);
+ JDialog jd = new JDialog(jf);
+ JPanel jp1 = new JPanel();
+ JButton jb1 = new JButton("jb1");
+ JTable jt1 = new JTable(new DefaultTableModel());
+
+ jf.add(jb1);
+ jf.add(jt1);
+ jf.add(jp1);
+ System.out.println("FTP current on jf= " + jf.getFocusTraversalPolicy());
+ System.out.println("FTP current on jw= " + jw.getFocusTraversalPolicy());
+ System.out.println("FTP current on jd= " + jd.getFocusTraversalPolicy());
+
+ if (!(jf.getFocusTraversalPolicy() instanceof LayoutFocusTraversalPolicy) ||
+ !(jw.getFocusTraversalPolicy() instanceof LayoutFocusTraversalPolicy) ||
+ !(jd.getFocusTraversalPolicy() instanceof LayoutFocusTraversalPolicy))
+ {
+ throw new RuntimeException("Failure! Swing toplevel must have LayoutFocusTraversalPolicy installed");
+ }
+
+ jf.setVisible(true);
+
+ System.out.println("Now will set another policy.");
+ currentKFM.setDefaultFocusTraversalPolicy(newFTP);
+
+ FocusTraversalPolicy resultFTP = jw.getFocusTraversalPolicy();
+
+ System.out.println("FTP current on jf= " + jf.getFocusTraversalPolicy());
+ System.out.println("FTP current on jw= " + jw.getFocusTraversalPolicy());
+ System.out.println("FTP current on jd= " + jd.getFocusTraversalPolicy());
+
+ if (!resultFTP.equals(defaultFTP)) {
+ Sysout.println("Failure! FocusTraversalPolicy should not change");
+ Sysout.println("Was: " + defaultFTP);
+ Sysout.println("Become: " + resultFTP);
+ throw new RuntimeException("Failure! FocusTraversalPolicy should not change");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,385 @@
+/*
+ @test
+ @bug 6431076
+ @summary Mouse cursor must remain DEFAULT over scrollbar when text is typed
+ @author Andrei Dmitriev: area=TextArea
+ @run main/manual Test
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class Test {
+ private static void init() {
+ Frame f = new Frame("Test for cursor");
+ final int dim = 100;
+ String line = "";
+ for( int i=0; i<dim; ++i ) {
+ line += "a";
+ }
+ String text = "";
+ for( int i=0; i<dim; ++i ) {
+ text += line;
+ if( i < dim-1 ) {
+ text += "\n";
+ }
+ }
+
+ f.setLayout( new BorderLayout () );
+ f.add( new TextArea( text ) );
+ f.setSize(400, 300);
+
+ f.setVisible(true);
+
+ String[] instructions = {
+ "1. Place keyboard cursor inside TextArea.",
+ "2. Repeat steps 2.* for each of two TextArea's scrollbars.",
+ "2.1. Place mouse cursor over TextArea's scrollbar.",
+ "2.2. If mouse cursor is not DEFAULT_CURSOR (arrow), test failed.",
+ "2.3. Type any symbol into TextArea.",
+ "2.4. Type ENTER symbol into TextArea.",
+ "2.5. If mouse cursor changes to TEXT_CURSOR (beam), test failed",
+ "(if cursor disappears on Windows, it's OK).",
+ "3. Test passed.",
+ };
+
+ Sysout.createDialogWithInstructions( instructions );
+ }
+
+
+
+ /*****************************************************
+ * Standard Test Machinery Section
+ * DO NOT modify anything in this section -- it's a
+ * standard chunk of code which has all of the
+ * synchronisation necessary for the test harness.
+ * By keeping it the same in all tests, it is easier
+ * to read and understand someone else's test, as
+ * well as insuring that all tests behave correctly
+ * with the test harness.
+ * There is a section following this for test-defined
+ * classes
+ ******************************************************/
+ private static boolean theTestPassed = false;
+ private static boolean testGeneratedInterrupt = false;
+ private static String failureMessage = "";
+
+ private static Thread mainThread = null;
+
+ private static int sleepTime = 300000;
+
+ public static void main( String args[] ) throws InterruptedException
+ {
+ mainThread = Thread.currentThread();
+ try
+ {
+ init();
+ }
+ catch( TestPassedException e )
+ {
+ //The test passed, so just return from main and harness will
+ // interepret this return as a pass
+ return;
+ }
+ //At this point, neither test passed nor test failed has been
+ // called -- either would have thrown an exception and ended the
+ // test, so we know we have multiple threads.
+
+ //Test involves other threads, so sleep and wait for them to
+ // called pass() or fail()
+ try
+ {
+ Thread.sleep( sleepTime );
+ //Timed out, so fail the test
+ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+ }
+ catch (InterruptedException e)
+ {
+ if( ! testGeneratedInterrupt ) throw e;
+
+ //reset flag in case hit this code more than once for some reason (just safety)
+ testGeneratedInterrupt = false;
+ if ( theTestPassed == false )
+ {
+ throw new RuntimeException( failureMessage );
+ }
+ }
+
+ }//main
+
+ public static synchronized void setTimeoutTo( int seconds )
+ {
+ sleepTime = seconds * 1000;
+ }
+
+ public static synchronized void pass()
+ {
+ Sysout.println( "The test passed." );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //first check if this is executing in main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //Still in the main thread, so set the flag just for kicks,
+ // and throw a test passed exception which will be caught
+ // and end the test.
+ theTestPassed = true;
+ throw new TestPassedException();
+ }
+ //pass was called from a different thread, so set the flag and interrupt
+ // the main thead.
+ theTestPassed = true;
+ testGeneratedInterrupt = true;
+ if (mainThread != null){
+ mainThread.interrupt();
+ }
+ }//pass()
+
+ public static synchronized void fail()
+ {
+ //test writer didn't specify why test failed, so give generic
+ fail( "it just plain failed! :-)" );
+ }
+
+ public static synchronized void fail( String whyFailed )
+ {
+ Sysout.println( "The test failed: " + whyFailed );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //check if this called from main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //If main thread, fail now 'cause not sleeping
+ throw new RuntimeException( whyFailed );
+ }
+ theTestPassed = false;
+ testGeneratedInterrupt = true;
+ failureMessage = whyFailed;
+ mainThread.interrupt();
+ }//fail()
+
+}// class
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+ static int newVar = 0;
+
+ public void eventDispatched(AWTEvent e)
+ {
+ //Counting events to see if we get enough
+ eventCount++;
+
+ if( eventCount == 20 )
+ {
+ //got enough events, so pass
+
+ ManualMainTest.pass();
+ }
+ else if( tries == 20 )
+ {
+ //tried too many times without getting enough events so fail
+
+ ManualMainTest.fail();
+ }
+
+ }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+ private static boolean numbering = false;
+ private static int messageNumber = 0;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ /* Enables message counting for the tester. */
+ public static void enableNumbering(boolean enable){
+ numbering = enable;
+ }
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ if (numbering) {
+ messageIn = "" + messageNumber + " " + messageIn;
+ messageNumber++;
+ }
+ dialog.displayMessage( messageIn );
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog implements ActionListener
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+ Panel buttonP = new Panel();
+ Button passB = new Button( "pass" );
+ Button failB = new Button( "fail" );
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ passB = new Button( "pass" );
+ passB.setActionCommand( "pass" );
+ passB.addActionListener( this );
+ buttonP.add( "East", passB );
+
+ failB = new Button( "fail" );
+ failB.setActionCommand( "fail" );
+ failB.addActionListener( this );
+ buttonP.add( "West", failB );
+
+ add( "South", buttonP );
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ System.out.println(messageIn);
+ }
+
+ //catch presses of the passed and failed buttons.
+ //simply call the standard pass() or fail() static methods of
+ //ManualMainTest
+ public void actionPerformed( ActionEvent e )
+ {
+ if( e.getActionCommand() == "pass" )
+ {
+ Test.pass();
+ }
+ else
+ {
+ Test.fail();
+ }
+ }
+
+}// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test1.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,386 @@
+/*
+ @test
+ @bug 6431076
+ @summary Mouse cursor must remain DEFAULT over scrollbar when text is typed
+ @author Andrei Dmitriev: area=TextArea
+ @run main/manual Test1
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class Test1 {
+ private static void init() {
+ Frame f = new Frame("Test1 for cursor");
+ final int dim = 100;
+ String line = "";
+ for( int i=0; i<dim; ++i ) {
+ line += "a";
+ }
+ String text = "";
+ for( int i=0; i<dim; ++i ) {
+ text += line;
+ if( i < dim-1 ) {
+ text += "\n";
+ }
+ }
+
+ f.setLayout( new BorderLayout () );
+ f.add( new TextArea( text ) );
+ f.setSize(400, 300);
+ f.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+
+ f.setVisible(true);
+
+ String[] instructions = {
+ "1. Place keyboard cursor inside TextArea.",
+ "2. Repeat steps 2.* for each of two TextArea's scrollbars.",
+ "2.1. Place mouse cursor over TextArea's scrollbar.",
+ "2.2. If mouse cursor is not HAND_CURSOR, test failed.",
+ "2.3. Type any symbol into TextArea.",
+ "2.4. Type ENTER symbol into TextArea.",
+ "2.5. If mouse cursor changes, test failed",
+ "(if cursor disappears on Windows, it's OK).",
+ "3. Test passed.",
+ };
+
+ Sysout.createDialogWithInstructions( instructions );
+ }
+
+
+
+ /*****************************************************
+ * Standard Test Machinery Section
+ * DO NOT modify anything in this section -- it's a
+ * standard chunk of code which has all of the
+ * synchronisation necessary for the test harness.
+ * By keeping it the same in all tests, it is easier
+ * to read and understand someone else's test, as
+ * well as insuring that all tests behave correctly
+ * with the test harness.
+ * There is a section following this for test-defined
+ * classes
+ ******************************************************/
+ private static boolean theTestPassed = false;
+ private static boolean testGeneratedInterrupt = false;
+ private static String failureMessage = "";
+
+ private static Thread mainThread = null;
+
+ private static int sleepTime = 300000;
+
+ public static void main( String args[] ) throws InterruptedException
+ {
+ mainThread = Thread.currentThread();
+ try
+ {
+ init();
+ }
+ catch( TestPassedException e )
+ {
+ //The test passed, so just return from main and harness will
+ // interepret this return as a pass
+ return;
+ }
+ //At this point, neither test passed nor test failed has been
+ // called -- either would have thrown an exception and ended the
+ // test, so we know we have multiple threads.
+
+ //Test involves other threads, so sleep and wait for them to
+ // called pass() or fail()
+ try
+ {
+ Thread.sleep( sleepTime );
+ //Timed out, so fail the test
+ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+ }
+ catch (InterruptedException e)
+ {
+ if( ! testGeneratedInterrupt ) throw e;
+
+ //reset flag in case hit this code more than once for some reason (just safety)
+ testGeneratedInterrupt = false;
+ if ( theTestPassed == false )
+ {
+ throw new RuntimeException( failureMessage );
+ }
+ }
+
+ }//main
+
+ public static synchronized void setTimeoutTo( int seconds )
+ {
+ sleepTime = seconds * 1000;
+ }
+
+ public static synchronized void pass()
+ {
+ Sysout.println( "The test passed." );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //first check if this is executing in main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //Still in the main thread, so set the flag just for kicks,
+ // and throw a test passed exception which will be caught
+ // and end the test.
+ theTestPassed = true;
+ throw new TestPassedException();
+ }
+ //pass was called from a different thread, so set the flag and interrupt
+ // the main thead.
+ theTestPassed = true;
+ testGeneratedInterrupt = true;
+ if (mainThread != null){
+ mainThread.interrupt();
+ }
+ }//pass()
+
+ public static synchronized void fail()
+ {
+ //test writer didn't specify why test failed, so give generic
+ fail( "it just plain failed! :-)" );
+ }
+
+ public static synchronized void fail( String whyFailed )
+ {
+ Sysout.println( "The test failed: " + whyFailed );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //check if this called from main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //If main thread, fail now 'cause not sleeping
+ throw new RuntimeException( whyFailed );
+ }
+ theTestPassed = false;
+ testGeneratedInterrupt = true;
+ failureMessage = whyFailed;
+ mainThread.interrupt();
+ }//fail()
+
+}// class
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+ static int newVar = 0;
+
+ public void eventDispatched(AWTEvent e)
+ {
+ //Counting events to see if we get enough
+ eventCount++;
+
+ if( eventCount == 20 )
+ {
+ //got enough events, so pass
+
+ ManualMainTest.pass();
+ }
+ else if( tries == 20 )
+ {
+ //tried too many times without getting enough events so fail
+
+ ManualMainTest.fail();
+ }
+
+ }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+ private static boolean numbering = false;
+ private static int messageNumber = 0;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ /* Enables message counting for the tester. */
+ public static void enableNumbering(boolean enable){
+ numbering = enable;
+ }
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ if (numbering) {
+ messageIn = "" + messageNumber + " " + messageIn;
+ messageNumber++;
+ }
+ dialog.displayMessage( messageIn );
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog implements ActionListener
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+ Panel buttonP = new Panel();
+ Button passB = new Button( "pass" );
+ Button failB = new Button( "fail" );
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ passB = new Button( "pass" );
+ passB.setActionCommand( "pass" );
+ passB.addActionListener( this );
+ buttonP.add( "East", passB );
+
+ failB = new Button( "fail" );
+ failB.setActionCommand( "fail" );
+ failB.addActionListener( this );
+ buttonP.add( "West", failB );
+
+ add( "South", buttonP );
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ System.out.println(messageIn);
+ }
+
+ //catch presses of the passed and failed buttons.
+ //simply call the standard pass() or fail() static methods of
+ //ManualMainTest
+ public void actionPerformed( ActionEvent e )
+ {
+ if( e.getActionCommand() == "pass" )
+ {
+ Test1.pass();
+ }
+ else
+ {
+ Test1.fail();
+ }
+ }
+
+}// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/geom/CubicCurve2D/ContainsTest.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4724552
+ * @summary Verifies that CubicCurve2D.contains(Rectangle2D) does not return
+ * true when the rectangle is only partially contained.
+ * @run main ContainsTest
+ */
+
+
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.Rectangle2D;
+
+public class ContainsTest {
+
+ public static void main(String[] args) throws Exception {
+ CubicCurve2D c = new CubicCurve2D.Double(0, 0, 4, -4, -2, -4, 2, 0);
+ Rectangle2D r = new Rectangle2D.Double(0.75, -2.5, 0.5, 2);
+
+ if (c.contains(r)) {
+ throw new Exception("The rectangle should not be contained in the curve");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/geom/CubicCurve2D/IntersectsTest.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4493128
+ * @summary Verifies that CubicCurve2D returns true for obvious intersection
+ * @run main IntersectsTest
+ */
+
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.Rectangle2D;
+
+public class IntersectsTest {
+
+ public static void main(String[] args) throws Exception {
+ CubicCurve2D c = new CubicCurve2D.Double(50.0, 300.0,
+ 150.0, 166.6666717529297,
+ 238.0, 456.66668701171875,
+ 350.0, 300.0);
+ Rectangle2D r = new Rectangle2D.Double(260, 300, 10, 10);
+
+ if (!c.intersects(r)) {
+ throw new Exception("The rectangle is contained. " +
+ "intersects(Rectangle2D) should return true");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/geom/CubicCurve2D/SolveCubicTest.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4645692
+ * @summary Verifies that SolveCubic doesn't miss any roots.
+ * @run main SolveCubicTest
+ */
+
+import static java.awt.geom.CubicCurve2D.solveCubic;
+
+public class SolveCubicTest {
+
+ public static void main(String[] args) throws Exception {
+
+ double[] eqn = {0, 0, 1, 1};
+ int numRoots = solveCubic(eqn, eqn);
+ if (numRoots < 2) {
+ throw new Exception("There are 2 roots. Only " + numRoots + " were found.");
+ }
+ }
+}
--- a/jdk/test/java/io/File/IsHidden.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/io/File/IsHidden.java Mon Feb 14 16:30:10 2011 -0800
@@ -27,6 +27,7 @@
*/
import java.io.*;
+import java.nio.file.Files;
import java.nio.file.attribute.DosFileAttributeView;
public class IsHidden {
@@ -42,7 +43,7 @@
}
private static void setHidden(File f, boolean value) throws IOException {
- f.toPath().getFileAttributeView(DosFileAttributeView.class).setHidden(value);
+ Files.getFileAttributeView(f.toPath(), DosFileAttributeView.class).setHidden(value);
}
private static void testWin32() throws Exception {
--- a/jdk/test/java/io/File/SetAccess.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/io/File/SetAccess.java Mon Feb 14 16:30:10 2011 -0800
@@ -27,6 +27,7 @@
*/
import java.io.*;
+import java.nio.file.*;
import java.nio.file.attribute.*;
public class SetAccess {
@@ -178,7 +179,7 @@
}
private static String permission(File f) throws Exception {
- PosixFileAttributes attrs = Attributes.readPosixFileAttributes(f.toPath());
+ PosixFileAttributes attrs = Files.readAttributes(f.toPath(), PosixFileAttributes.class);
String type = attrs.isDirectory() ? "d" : " ";
return type + PosixFilePermissions.toString(attrs.permissions());
}
--- a/jdk/test/java/io/File/SymLinks.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/io/File/SymLinks.java Mon Feb 14 16:30:10 2011 -0800
@@ -27,7 +27,7 @@
*/
import java.io.*;
-import java.nio.file.Path;
+import java.nio.file.*;
import java.nio.file.attribute.*;
import static java.nio.file.LinkOption.*;
@@ -80,39 +80,33 @@
if (file != null)
file.delete();
if (link2file != null)
- link2file.toPath().deleteIfExists();
+ Files.deleteIfExists(link2file.toPath());
if (link2link2file != null)
- link2link2file.toPath().deleteIfExists();
+ Files.deleteIfExists(link2link2file.toPath());
if (dir != null)
dir.delete();
if (link2dir != null)
- link2dir.toPath().deleteIfExists();
+ Files.deleteIfExists(link2dir.toPath());
if (link2link2dir != null)
- link2link2dir.toPath().deleteIfExists();
+ Files.deleteIfExists(link2link2dir.toPath());
if (link2nobody != null)
- link2nobody.toPath().deleteIfExists();
+ Files.deleteIfExists(link2nobody.toPath());
if (link2link2nobody != null)
- link2link2nobody.toPath().deleteIfExists();
+ Files.deleteIfExists(link2link2nobody.toPath());
}
/**
* Creates a sym link source->target
*/
static void mklink(File source, File target) throws IOException {
- source.toPath().createSymbolicLink(target.toPath());
+ Files.createSymbolicLink(source.toPath(), target.toPath());
}
/**
* Returns true if the "link" exists and is a sym link.
*/
static boolean isSymLink(File link) {
- try {
- BasicFileAttributes attrs =
- Attributes.readBasicFileAttributes(link.toPath(), NOFOLLOW_LINKS);
- return attrs.isSymbolicLink();
- } catch (IOException x) {
- return false;
- }
+ return Files.isSymbolicLink(link.toPath());
}
/**
@@ -120,7 +114,7 @@
*/
static long lastModifiedOfSymLink(File link) throws IOException {
BasicFileAttributes attrs =
- Attributes.readBasicFileAttributes(link.toPath(), NOFOLLOW_LINKS);
+ Files.readAttributes(link.toPath(), BasicFileAttributes.class, NOFOLLOW_LINKS);
assertTrue(attrs.isSymbolicLink());
return attrs.lastModifiedTime().toMillis();
}
@@ -133,8 +127,8 @@
Path link = dir.toPath().resolve("link");
Path target = dir.toPath().resolve("target");
try {
- link.createSymbolicLink(target);
- link.delete();
+ Files.createSymbolicLink(link, target);
+ Files.delete(link);
return true;
} catch (UnsupportedOperationException x) {
return false;
@@ -224,7 +218,7 @@
assertTrue(isSymLink(link2nobody));
} finally {
- link.toPath().deleteIfExists();
+ Files.deleteIfExists(link.toPath());
}
header("renameTo");
@@ -287,8 +281,8 @@
// on Windows we test with the DOS hidden attribute set
if (System.getProperty("os.name").startsWith("Windows")) {
- DosFileAttributeView view = file.toPath()
- .getFileAttributeView(DosFileAttributeView.class);
+ DosFileAttributeView view = Files
+ .getFileAttributeView(file.toPath(), DosFileAttributeView.class);
view.setHidden(true);
try {
assertTrue(file.isHidden());
--- a/jdk/test/java/io/FileInputStream/LargeFileAvailable.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/io/FileInputStream/LargeFileAvailable.java Mon Feb 14 16:30:10 2011 -0800
@@ -31,6 +31,7 @@
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
+import java.nio.file.Files;
import static java.nio.file.StandardOpenOption.*;
public class LargeFileAvailable {
@@ -85,7 +86,7 @@
// Create a large file as a sparse file if possible
File largefile = File.createTempFile("largefile", null);
// re-create as a sparse file
- largefile.toPath().delete();
+ Files.delete(largefile.toPath());
try (FileChannel fc =
FileChannel.open(largefile.toPath(),
CREATE_NEW, WRITE, SPARSE)) {
--- a/jdk/test/java/lang/Double/ParseDouble.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/lang/Double/ParseDouble.java Mon Feb 14 16:30:10 2011 -0800
@@ -23,11 +23,12 @@
/*
* @test
- * @bug 4160406 4705734 4707389 4826774 4895911
+ * @bug 4160406 4705734 4707389 4826774 4895911 4421494
* @summary Test for Double.parseDouble method and acceptance regex
*/
import java.util.regex.*;
+import java.math.BigDecimal;
public class ParseDouble {
@@ -416,7 +417,15 @@
"0x00100p1",
"0x00.100p1",
- "0x001.100p1"
+ "0x001.100p1",
+
+ // Limits
+
+ "1.7976931348623157E308", // Double.MAX_VALUE
+ "4.9e-324", // Double.MIN_VALUE
+ "2.2250738585072014e-308", // Double.MIN_NORMAL
+
+ "2.2250738585072012e-308", // near Double.MIN_NORMAL
};
static String paddedBadStrings[];
@@ -546,6 +555,32 @@
}
+ /**
+ * For each subnormal power of two, test at boundaries of
+ * region that should convert to that value.
+ */
+ private static void testSubnormalPowers() {
+ BigDecimal TWO = BigDecimal.valueOf(2);
+ // An ulp is the same for all subnormal values
+ BigDecimal ulp_BD = new BigDecimal(Double.MIN_VALUE);
+
+ // Test subnormal powers of two
+ for(int i = -1074; i <= -1022; i++) {
+ double d = Math.scalb(1.0, i);
+
+ /*
+ * The region [d - ulp/2, d + ulp/2] should round to d.
+ */
+ BigDecimal d_BD = new BigDecimal(d);
+
+ BigDecimal lowerBound = d_BD.subtract(ulp_BD.divide(TWO));
+ BigDecimal upperBound = d_BD.add(ulp_BD.divide(TWO));
+
+ double convertedLowerBound = Double.parseDouble(lowerBound.toString());
+ double convertedUpperBound = Double.parseDouble(upperBound.toString());
+ }
+ }
+
public static void main(String[] args) throws Exception {
rudimentaryTest();
@@ -558,5 +593,7 @@
testRegex(paddedGoodStrings, false);
testRegex(badStrings, true);
testRegex(paddedBadStrings, true);
+
+ testSubnormalPowers();
}
}
--- a/jdk/test/java/lang/Runtime/exec/Duped.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/lang/Runtime/exec/Duped.java Mon Feb 14 16:30:10 2011 -0800
@@ -38,8 +38,7 @@
public static void main(String args[]) throws Exception {
StringBuffer s = new StringBuffer();
int c;
- while ((System.in.available() != 0)
- && ((c = System.in.read()) != -1))
+ while ((c = System.in.read()) != -1)
s.append((char)c);
System.out.println(s);
}
--- a/jdk/test/java/net/Socks/SocksProxyVersion.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/net/Socks/SocksProxyVersion.java Mon Feb 14 16:30:10 2011 -0800
@@ -36,15 +36,22 @@
import java.io.IOException;
public class SocksProxyVersion implements Runnable {
- ServerSocket ss;
+ final ServerSocket ss;
volatile boolean failed;
public static void main(String[] args) throws Exception {
new SocksProxyVersion();
}
+ @SuppressWarnings("try")
public SocksProxyVersion() throws Exception {
ss = new ServerSocket(0);
+ try (ServerSocket socket = ss) {
+ runTest();
+ }
+ }
+
+ void runTest() throws Exception {
int port = ss.getLocalPort();
Thread serverThread = new Thread(this);
serverThread.start();
@@ -75,22 +82,21 @@
}
public void run() {
- try (ss) {
- Socket s = ss.accept();
- int version = (s.getInputStream()).read();
- if (version != 4) {
- System.out.println("Got " + version + ", expected 4");
- failed = true;
+ try {
+ try (Socket s = ss.accept()) {
+ int version = (s.getInputStream()).read();
+ if (version != 4) {
+ System.out.println("Got " + version + ", expected 4");
+ failed = true;
+ }
}
- s.close();
-
- s = ss.accept();
- version = (s.getInputStream()).read();
- if (version != 5) {
- System.out.println("Got " + version + ", expected 5");
- failed = true;
+ try (Socket s = ss.accept()) {
+ int version = (s.getInputStream()).read();
+ if (version != 5) {
+ System.out.println("Got " + version + ", expected 5");
+ failed = true;
+ }
}
- s.close();
} catch (IOException e) {
e.printStackTrace();
}
--- a/jdk/test/java/nio/MappedByteBuffer/Force.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/MappedByteBuffer/Force.java Mon Feb 14 16:30:10 2011 -0800
@@ -37,14 +37,17 @@
Random random = new Random();
long filesize = random.nextInt(3*1024*1024);
int cut = random.nextInt((int)filesize);
- File file = new File("Blah");
- RandomAccessFile raf = new RandomAccessFile(file, "rw");
- raf.setLength(filesize);
- FileChannel fc = raf.getChannel();
- MappedByteBuffer buf1 = fc.map(
- FileChannel.MapMode.READ_WRITE, cut, filesize-cut);
- buf1.force();
- fc.close();
- raf.close();
+ File file = File.createTempFile("Blah", null);
+ file.deleteOnExit();
+ try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
+ raf.setLength(filesize);
+ FileChannel fc = raf.getChannel();
+ MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, cut, filesize-cut);
+ mbb.force();
+ }
+
+ // improve chance that mapped buffer will be unmapped
+ System.gc();
+ Thread.sleep(500);
}
}
--- a/jdk/test/java/nio/MappedByteBuffer/ZeroMap.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/MappedByteBuffer/ZeroMap.java Mon Feb 14 16:30:10 2011 -0800
@@ -37,16 +37,19 @@
Random random = new Random();
long filesize = random.nextInt(1024*1024);
int cut = random.nextInt((int)filesize);
- File file = new File("Blah");
- RandomAccessFile raf = new RandomAccessFile(file, "rw");
- raf.setLength(filesize);
- FileChannel fc = raf.getChannel();
- MappedByteBuffer buf1 = fc.map(
- FileChannel.MapMode.READ_WRITE, cut, 0);
- buf1.force();
- buf1.load();
- buf1.isLoaded();
- fc.close();
- raf.close();
+ File file = File.createTempFile("Blah", null);
+ file.deleteOnExit();
+ try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
+ raf.setLength(filesize);
+ FileChannel fc = raf.getChannel();
+ MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, cut, 0);
+ mbb.force();
+ mbb.load();
+ mbb.isLoaded();
+ }
+
+ // improve chance that mapped buffer will be unmapped
+ System.gc();
+ Thread.sleep(500);
}
}
--- a/jdk/test/java/nio/channels/FileChannel/AtomicAppend.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/channels/FileChannel/AtomicAppend.java Mon Feb 14 16:30:10 2011 -0800
@@ -36,6 +36,7 @@
import java.util.concurrent.TimeUnit;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
+import java.nio.file.Files;
import static java.nio.file.StandardOpenOption.*;
public class AtomicAppend {
@@ -55,7 +56,7 @@
if (rand.nextBoolean()) {
return new FileOutputStream(file, true);
} else {
- return file.toPath().newOutputStream(APPEND);
+ return Files.newOutputStream(file.toPath(), APPEND);
}
}
--- a/jdk/test/java/nio/channels/FileChannel/Transfer.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/channels/FileChannel/Transfer.java Mon Feb 14 16:30:10 2011 -0800
@@ -276,7 +276,7 @@
while (fc == null) {
sink = File.createTempFile("sink", null);
// re-create as a sparse file
- sink.toPath().delete();
+ sink.delete();
try {
fc = FileChannel.open(sink.toPath(),
StandardOpenOption.CREATE_NEW,
--- a/jdk/test/java/nio/channels/FileChannel/Truncate.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/channels/FileChannel/Truncate.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,30 +58,31 @@
for(int i=0; i<100; i++) {
long testSize = generator.nextInt(1000) + 10;
initTestFile(blah, testSize);
- FileChannel fc = (i < 50) ?
- new RandomAccessFile(blah, "rw").getChannel() :
- FileChannel.open(blah.toPath(), READ, WRITE);
- try (fc) {
- if (fc.size() != testSize)
- throw new RuntimeException("Size failed");
- long position = generator.nextInt((int)testSize);
- fc.position(position);
+ try (FileChannel fc = (i < 50) ?
+ new RandomAccessFile(blah, "rw").getChannel() :
+ FileChannel.open(blah.toPath(), READ, WRITE))
+ {
+ if (fc.size() != testSize)
+ throw new RuntimeException("Size failed");
+
+ long position = generator.nextInt((int)testSize);
+ fc.position(position);
- long newSize = generator.nextInt((int)testSize);
- fc.truncate(newSize);
+ long newSize = generator.nextInt((int)testSize);
+ fc.truncate(newSize);
- if (fc.size() != newSize)
- throw new RuntimeException("Truncate failed");
+ if (fc.size() != newSize)
+ throw new RuntimeException("Truncate failed");
- if (position > newSize) {
- if (fc.position() != newSize)
- throw new RuntimeException("Position greater than size");
- } else {
- if (fc.position() != position)
- throw new RuntimeException("Truncate changed position");
- };
- }
+ if (position > newSize) {
+ if (fc.position() != newSize)
+ throw new RuntimeException("Position greater than size");
+ } else {
+ if (fc.position() != position)
+ throw new RuntimeException("Truncate changed position");
+ };
+ }
}
}
@@ -92,24 +93,24 @@
for (int i=0; i<10; i++) {
long testSize = generator.nextInt(1000) + 10;
initTestFile(blah, testSize);
- FileChannel fc = (i < 5) ?
- new FileOutputStream(blah, true).getChannel() :
- FileChannel.open(blah.toPath(), APPEND);
- try (fc) {
- // truncate file
- long newSize = generator.nextInt((int)testSize);
- fc.truncate(newSize);
- if (fc.size() != newSize)
- throw new RuntimeException("Truncate failed");
+ try (FileChannel fc = (i < 5) ?
+ new FileOutputStream(blah, true).getChannel() :
+ FileChannel.open(blah.toPath(), APPEND))
+ {
+ // truncate file
+ long newSize = generator.nextInt((int)testSize);
+ fc.truncate(newSize);
+ if (fc.size() != newSize)
+ throw new RuntimeException("Truncate failed");
- // write one byte
- ByteBuffer buf = ByteBuffer.allocate(1);
- buf.put((byte)'x');
- buf.flip();
- fc.write(buf);
- if (fc.size() != (newSize+1))
- throw new RuntimeException("Unexpected size");
- }
+ // write one byte
+ ByteBuffer buf = ByteBuffer.allocate(1);
+ buf.put((byte)'x');
+ buf.flip();
+ fc.write(buf);
+ if (fc.size() != (newSize+1))
+ throw new RuntimeException("Unexpected size");
+ }
}
}
--- a/jdk/test/java/nio/file/DirectoryStream/Basic.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/DirectoryStream/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -28,6 +28,7 @@
*/
import java.nio.file.*;
+import static java.nio.file.Files.*;
import java.util.*;
import java.io.IOException;
@@ -38,29 +39,26 @@
DirectoryStream<Path> stream;
// test that directory is empty
- stream = dir.newDirectoryStream();
- try {
- if (stream.iterator().hasNext())
+ try (DirectoryStream<Path> ds = newDirectoryStream(dir)) {
+ if (ds.iterator().hasNext())
throw new RuntimeException("directory not empty");
- } finally {
- stream.close();
}
// create file in directory
final Path foo = Paths.get("foo");
- dir.resolve(foo).createFile();
+ createFile(dir.resolve(foo));
// iterate over directory and check there is one entry
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
found = false;
try {
for (Path entry: stream) {
- if (entry.getName().equals(foo)) {
+ if (entry.getFileName().equals(foo)) {
if (found)
throw new RuntimeException("entry already found");
found = true;
} else {
- throw new RuntimeException("entry " + entry.getName() +
+ throw new RuntimeException("entry " + entry.getFileName() +
" not expected");
}
}
@@ -71,21 +69,18 @@
throw new RuntimeException("entry not found");
// check filtering: f* should match foo
- DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+ DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<>() {
private PathMatcher matcher =
dir.getFileSystem().getPathMatcher("glob:f*");
public boolean accept(Path file) {
return matcher.matches(file);
}
};
- stream = dir.newDirectoryStream(filter);
- try {
- for (Path entry: stream) {
- if (!entry.getName().equals(foo))
+ try (DirectoryStream<Path> ds = newDirectoryStream(dir, filter)) {
+ for (Path entry: ds) {
+ if (!entry.getFileName().equals(foo))
throw new RuntimeException("entry not expected");
}
- } finally {
- stream.close();
}
// check filtering: z* should not match any files
@@ -96,12 +91,9 @@
return matcher.matches(file);
}
};
- stream = dir.newDirectoryStream(filter);
- try {
- if (stream.iterator().hasNext())
+ try (DirectoryStream<Path> ds = newDirectoryStream(dir, filter)) {
+ if (ds.iterator().hasNext())
throw new RuntimeException("no matching entries expected");
- } finally {
- stream.close();
}
// check that an IOException thrown by a filter is propagated
@@ -110,7 +102,7 @@
throw new java.util.zip.ZipException();
}
};
- stream = dir.newDirectoryStream(filter);
+ stream = newDirectoryStream(dir, filter);
try {
stream.iterator().hasNext();
throw new RuntimeException("DirectoryIteratorException expected");
@@ -124,7 +116,7 @@
// check that exception or error thrown by filter is not thrown
// by newDirectoryStream or iterator method.
- stream = dir.newDirectoryStream(new DirectoryStream.Filter<Path>() {
+ stream = newDirectoryStream(dir, new DirectoryStream.Filter<Path>() {
public boolean accept(Path file) {
throw new RuntimeException("Should not be visible");
}
@@ -137,13 +129,13 @@
// test NotDirectoryException
try {
- dir.resolve(foo).newDirectoryStream();
+ newDirectoryStream(dir.resolve(foo));
throw new RuntimeException("NotDirectoryException not thrown");
} catch (NotDirectoryException x) {
}
// test UnsupportedOperationException
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
Iterator<Path> i = stream.iterator();
i.next();
try {
@@ -153,7 +145,7 @@
}
// test IllegalStateException
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
stream.iterator();
try {
// attempt to obtain second iterator
@@ -163,7 +155,7 @@
}
stream.close();
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
stream.close();
try {
// attempt to obtain iterator after stream is closed
@@ -173,13 +165,13 @@
}
// test that iterator reads to end of stream when closed
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
i = stream.iterator();
stream.close();
while (i.hasNext())
i.next();
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
i = stream.iterator();
stream.close();
try {
--- a/jdk/test/java/nio/file/DirectoryStream/DriveLetter.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/DirectoryStream/DriveLetter.java Mon Feb 14 16:30:10 2011 -0800
@@ -52,16 +52,14 @@
Path expected = Paths.get(drive).resolve(tempFile.getName());
boolean found = false;
- DirectoryStream<Path> stream = Paths.get(drive).newDirectoryStream();
- try {
+ Path dir = Paths.get(drive);
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path file : stream) {
if (file.equals(expected)) {
found = true;
break;
}
}
- } finally {
- stream.close();
}
if (!found)
throw new RuntimeException("Temporary file not found???");
--- a/jdk/test/java/nio/file/DirectoryStream/SecureDS.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/DirectoryStream/SecureDS.java Mon Feb 14 16:30:10 2011 -0800
@@ -28,6 +28,7 @@
*/
import java.nio.file.*;
+import static java.nio.file.Files.*;
import static java.nio.file.StandardOpenOption.*;
import static java.nio.file.LinkOption.*;
import java.nio.file.attribute.*;
@@ -41,7 +42,7 @@
public static void main(String[] args) throws IOException {
Path dir = TestUtil.createTemporaryDirectory();
try {
- DirectoryStream<Path> stream = dir.newDirectoryStream();
+ DirectoryStream<Path> stream = newDirectoryStream(dir);
stream.close();
if (!(stream instanceof SecureDirectoryStream)) {
System.out.println("SecureDirectoryStream not supported.");
@@ -62,28 +63,28 @@
// Exercise each of SecureDirectoryStream's method (except move)
static void doBasicTests(Path dir) throws IOException {
- Path dir1 = dir.resolve("dir1").createDirectory();
+ Path dir1 = createDirectory(dir.resolve("dir1"));
Path dir2 = dir.resolve("dir2");
// create a file, directory, and two sym links in the directory
Path fileEntry = Paths.get("myfile");
- dir1.resolve(fileEntry).createFile();
+ createFile(dir1.resolve(fileEntry));
Path dirEntry = Paths.get("mydir");
- dir1.resolve(dirEntry).createDirectory();
+ createDirectory(dir1.resolve(dirEntry));
// myfilelink -> myfile
Path link1Entry = Paths.get("myfilelink");
if (supportsLinks)
- dir1.resolve(link1Entry).createSymbolicLink(fileEntry);
+ createSymbolicLink(dir1.resolve(link1Entry), fileEntry);
// mydirlink -> mydir
Path link2Entry = Paths.get("mydirlink");
if (supportsLinks)
- dir1.resolve(link2Entry).createSymbolicLink(dirEntry);
+ createSymbolicLink(dir1.resolve(link2Entry), dirEntry);
// open directory and then move it so that it is no longer accessible
// via its original path.
SecureDirectoryStream<Path> stream =
- (SecureDirectoryStream<Path>)dir1.newDirectoryStream();
- dir1.moveTo(dir2);
+ (SecureDirectoryStream<Path>)newDirectoryStream(dir1);
+ move(dir1, dir2);
// Test: iterate over all entries
int count = 0;
@@ -138,7 +139,7 @@
if (supportsLinks) {
stream.newByteChannel(link1Entry, opts).close();
try {
- Set<OpenOption> mixed = new HashSet<OpenOption>();
+ Set<OpenOption> mixed = new HashSet<>();
mixed.add(READ);
mixed.add(NOFOLLOW_LINKS);
stream.newByteChannel(link1Entry, mixed).close();
@@ -168,51 +169,48 @@
// clean-up
stream.close();
- dir2.delete();
+ delete(dir2);
}
// Exercise SecureDirectoryStream's move method
static void doMoveTests(Path dir) throws IOException {
- Path dir1 = dir.resolve("dir1").createDirectory();
- Path dir2 = dir.resolve("dir2").createDirectory();
+ Path dir1 = createDirectory(dir.resolve("dir1"));
+ Path dir2 = createDirectory(dir.resolve("dir2"));
// create dir1/myfile, dir1/mydir, dir1/mylink
Path fileEntry = Paths.get("myfile");
- dir1.resolve(fileEntry).createFile();
+ createFile(dir1.resolve(fileEntry));
Path dirEntry = Paths.get("mydir");
- dir1.resolve(dirEntry).createDirectory();
+ createDirectory(dir1.resolve(dirEntry));
Path linkEntry = Paths.get("mylink");
if (supportsLinks)
- dir1.resolve(linkEntry).createSymbolicLink(Paths.get("missing"));
+ createSymbolicLink(dir1.resolve(linkEntry), Paths.get("missing"));
// target name
Path target = Paths.get("newfile");
// open stream to both directories
SecureDirectoryStream<Path> stream1 =
- (SecureDirectoryStream<Path>)dir1.newDirectoryStream();
+ (SecureDirectoryStream<Path>)newDirectoryStream(dir1);
SecureDirectoryStream<Path> stream2 =
- (SecureDirectoryStream<Path>)dir2.newDirectoryStream();
+ (SecureDirectoryStream<Path>)newDirectoryStream(dir2);
// Test: move dir1/myfile -> dir2/newfile
stream1.move(fileEntry, stream2, target);
- assertTrue(dir1.resolve(fileEntry).notExists());
- assertTrue(dir2.resolve(target).exists());
+ assertTrue(notExists(dir1.resolve(fileEntry)));
+ assertTrue(exists(dir2.resolve(target)));
stream2.deleteFile(target);
// Test: move dir1/mydir -> dir2/newfile
stream1.move(dirEntry, stream2, target);
- assertTrue(dir1.resolve(dirEntry).notExists());
- assertTrue(dir2.resolve(target).exists());
+ assertTrue(notExists(dir1.resolve(dirEntry)));
+ assertTrue(exists(dir2.resolve(target)));
stream2.deleteDirectory(target);
// Test: move dir1/mylink -> dir2/newfile
if (supportsLinks) {
stream1.move(linkEntry, stream2, target);
- assertTrue(dir2.resolve(target)
- .getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS)
- .readAttributes()
- .isSymbolicLink());
+ assertTrue(isSymbolicLink(dir2.resolve(target)));
stream2.deleteFile(target);
}
@@ -220,10 +218,10 @@
String testDirAsString = System.getProperty("test.dir");
if (testDirAsString != null) {
Path testDir = Paths.get(testDirAsString);
- if (!dir1.getFileStore().equals(testDir.getFileStore())) {
+ if (!getFileStore(dir1).equals(getFileStore(testDir))) {
SecureDirectoryStream<Path> ts =
- (SecureDirectoryStream<Path>)testDir.newDirectoryStream();
- dir1.resolve(fileEntry).createFile();
+ (SecureDirectoryStream<Path>)newDirectoryStream(testDir);
+ createFile(dir1.resolve(fileEntry));
try {
stream1.move(fileEntry, ts, target);
shouldNotGetHere();
@@ -234,17 +232,17 @@
}
// clean-up
- dir1.delete();
- dir2.delete();
+ delete(dir1);
+ delete(dir2);
}
// null and ClosedDirectoryStreamException
static void miscTests(Path dir) throws IOException {
Path file = Paths.get("file");
- dir.resolve(file).createFile();
+ createFile(dir.resolve(file));
SecureDirectoryStream<Path> stream =
- (SecureDirectoryStream<Path>)dir.newDirectoryStream();
+ (SecureDirectoryStream<Path>)newDirectoryStream(dir);
// NullPointerException
try {
@@ -319,7 +317,7 @@
} catch (ClosedDirectoryStreamException x) { }
// clean-up
- dir.resolve(file).delete();
+ delete(dir.resolve(file));
}
static void assertTrue(boolean b) {
--- a/jdk/test/java/nio/file/FileStore/Basic.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/FileStore/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -22,18 +22,21 @@
*/
/* @test
- * @bug 4313887 6873621 6979526
+ * @bug 4313887 6873621 6979526 7006126
* @summary Unit test for java.nio.file.FileStore
* @library ..
*/
import java.nio.file.*;
import java.nio.file.attribute.*;
+import java.io.File;
import java.io.IOException;
import java.util.*;
public class Basic {
+ static final long G = 1024L * 1024L * 1024L;
+
public static void main(String[] args) throws IOException {
Path dir = TestUtil.createTemporaryDirectory();
try {
@@ -48,17 +51,25 @@
throw new RuntimeException("Assertion failed");
}
+ static void checkWithin1GB(long value1, long value2) {
+ long diff = Math.abs(value1 - value2);
+ if (diff > G)
+ throw new RuntimeException("values differ by more than 1GB");
+ }
+
static void doTests(Path dir) throws IOException {
/**
* Test: Directory should be on FileStore that is writable
*/
- assertTrue(!dir.getFileStore().isReadOnly());
+ assertTrue(!Files.getFileStore(dir).isReadOnly());
/**
* Test: Two files should have the same FileStore
*/
- FileStore store1 = dir.resolve("foo").createFile().getFileStore();
- FileStore store2 = dir.resolve("bar").createFile().getFileStore();
+ Path file1 = Files.createFile(dir.resolve("foo"));
+ Path file2 = Files.createFile(dir.resolve("bar"));
+ FileStore store1 = Files.getFileStore(file1);
+ FileStore store2 = Files.getFileStore(file2);
assertTrue(store1.equals(store2));
assertTrue(store2.equals(store1));
assertTrue(store1.hashCode() == store2.hashCode());
@@ -78,6 +89,24 @@
store1.supportsFileAttributeView(UserDefinedFileAttributeView.class));
/**
+ * Test: Space atributes
+ */
+ File f = file1.toFile();
+ long total = f.getTotalSpace();
+ long free = f.getFreeSpace();
+ long usable = f.getUsableSpace();
+
+ // check values are "close"
+ checkWithin1GB(total, store1.getTotalSpace());
+ checkWithin1GB(free, store1.getUnallocatedSpace());
+ checkWithin1GB(usable, store1.getUsableSpace());
+
+ // get values by name
+ checkWithin1GB(total, (Long)store1.getAttribute("totalSpace"));
+ checkWithin1GB(free, (Long)store1.getAttribute("unallocatedSpace"));
+ checkWithin1GB(usable, (Long)store1.getAttribute("usableSpace"));
+
+ /**
* Test: Enumerate all FileStores
*/
FileStore prev = null;
@@ -85,8 +114,10 @@
System.out.format("%s (name=%s type=%s)\n", store, store.name(),
store.type());
- // check space attributes
- Attributes.readFileStoreSpaceAttributes(store);
+ // check space attributes are accessible
+ store.getTotalSpace();
+ store.getUnallocatedSpace();
+ store.getUsableSpace();
// two distinct FileStores should not be equal
assertTrue(!store.equals(prev));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/BytesAndLines.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 7006126
+ * @summary Unit test for methods for Files readAllBytes, readAllLines and
+ * and write methods.
+ */
+
+import java.nio.file.*;
+import static java.nio.file.Files.*;
+import java.io.*;
+import java.util.*;
+import java.nio.charset.*;
+
+public class BytesAndLines {
+ static final Random rand = new Random();
+
+ static final Charset US_ASCII = Charset.forName("US-ASCII");
+
+ public static void main(String[] args) throws IOException {
+ testReadAndWriteBytes();
+ testReadLines();
+ testWriteLines();
+ }
+
+ /**
+ * Test readAllBytes(Path) and write(Path, byte[], OpenOption...)
+ */
+ static void testReadAndWriteBytes() throws IOException {
+ // exercise methods with various sizes
+ testReadAndWriteBytes(0);
+ for (int i=0; i<100; i++) {
+ testReadAndWriteBytes(rand.nextInt(32000));
+ }
+
+ // NullPointerException
+ Path file = Paths.get("foo");
+ List<String> lines = Collections.emptyList();
+ try {
+ readAllBytes(null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(null, lines, Charset.defaultCharset());
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(file, null, Charset.defaultCharset());
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(file, lines, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(file, lines, Charset.defaultCharset(), (OpenOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ OpenOption[] opts = { null };
+ write(file, lines, Charset.defaultCharset(), opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ }
+
+
+ static void testReadAndWriteBytes(int size) throws IOException {
+ Path path = createTempFile("blah", null);
+ try {
+ boolean append = rand.nextBoolean();
+
+ byte[] b1 = new byte[size];
+ rand.nextBytes(b1);
+
+ byte[] b2 = (append) ? new byte[size] : new byte[0];
+ rand.nextBytes(b2);
+
+ // write method should create file if it doesn't exist
+ if (rand.nextBoolean())
+ delete(path);
+
+ // write bytes to file
+ Path target = write(path, b1);
+ assertTrue(target==path, "Unexpected path");
+ assertTrue(size(path) == b1.length, "Unexpected file size");
+
+ // append bytes to file (might be 0 bytes)
+ write(path, b2, StandardOpenOption.APPEND);
+ assertTrue(size(path) == b1.length + b2.length, "Unexpected file size");
+
+ // read entire file
+ byte[] read = readAllBytes(path);
+
+ // check bytes are correct
+ byte[] expected;
+ if (append) {
+ expected = new byte[b1.length + b2.length];
+ System.arraycopy(b1, 0, expected, 0, b1.length);
+ System.arraycopy(b2, 0, expected, b1.length, b2.length);
+ } else {
+ expected = b1;
+ }
+ assertTrue(Arrays.equals(read, expected),
+ "Bytes read not the same as bytes written");
+ } finally {
+ deleteIfExists(path);
+ }
+ }
+
+ /**
+ * Test readAllLines(Path,Charset)
+ */
+ static void testReadLines() throws IOException {
+ Path tmpfile = createTempFile("blah", "txt");
+ try {
+ List<String> lines;
+
+ // zero lines
+ assertTrue(size(tmpfile) == 0, "File should be empty");
+ lines = readAllLines(tmpfile, US_ASCII);
+ assertTrue(lines.isEmpty(), "No line expected");
+
+ // one line
+ byte[] hi = { (byte)'h', (byte)'i' };
+ write(tmpfile, hi);
+ lines = readAllLines(tmpfile, US_ASCII);
+ assertTrue(lines.size() == 1, "One line expected");
+ assertTrue(lines.get(0).equals("hi"), "'Hi' expected");
+
+ // two lines using platform's line separator
+ List<String> expected = Arrays.asList("hi", "there");
+ write(tmpfile, expected, US_ASCII);
+ assertTrue(size(tmpfile) > 0, "File is empty");
+ lines = readAllLines(tmpfile, US_ASCII);
+ assertTrue(lines.equals(expected), "Unexpected lines");
+
+ // MalformedInputException
+ byte[] bad = { (byte)0xff, (byte)0xff };
+ write(tmpfile, bad);
+ try {
+ readAllLines(tmpfile, US_ASCII);
+ throw new RuntimeException("MalformedInputException expected");
+ } catch (MalformedInputException ignore) { }
+
+
+ // NullPointerException
+ try {
+ readAllLines(null, US_ASCII);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ readAllLines(tmpfile, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+
+ } finally {
+ delete(tmpfile);
+ }
+ }
+
+ /**
+ * Test write(Path,Iterable<? extends CharSequence>,Charset,OpenOption...)
+ */
+ static void testWriteLines() throws IOException {
+ Path tmpfile = createTempFile("blah", "txt");
+ try {
+ // write method should create file if it doesn't exist
+ if (rand.nextBoolean())
+ delete(tmpfile);
+
+ // zero lines
+ Path result = write(tmpfile, Collections.<String>emptyList(), US_ASCII);
+ assert(size(tmpfile) == 0);
+ assert(result == tmpfile);
+
+ // two lines
+ List<String> lines = Arrays.asList("hi", "there");
+ write(tmpfile, lines, US_ASCII);
+ List<String> actual = readAllLines(tmpfile, US_ASCII);
+ assertTrue(actual.equals(lines), "Unexpected lines");
+
+ // append two lines
+ write(tmpfile, lines, US_ASCII, StandardOpenOption.APPEND);
+ List<String> expected = new ArrayList<String>();
+ expected.addAll(lines);
+ expected.addAll(lines);
+ assertTrue(expected.size() == 4, "List should have 4 elements");
+ actual = readAllLines(tmpfile, US_ASCII);
+ assertTrue(actual.equals(expected), "Unexpected lines");
+
+ // UnmappableCharacterException
+ try {
+ String s = "\u00A0\u00A1";
+ write(tmpfile, Arrays.asList(s), US_ASCII);
+ throw new RuntimeException("UnmappableCharacterException expected");
+ } catch (UnmappableCharacterException ignore) { }
+
+ // NullPointerException
+ try {
+ write(null, lines, US_ASCII);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(tmpfile, null, US_ASCII);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(tmpfile, lines, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(tmpfile, lines, US_ASCII, (OpenOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ OpenOption[] opts = { (OpenOption)null };
+ write(tmpfile, lines, US_ASCII, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+
+ } finally {
+ delete(tmpfile);
+ }
+
+ }
+
+ static void assertTrue(boolean expr, String errmsg) {
+ if (!expr)
+ throw new RuntimeException(errmsg);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/CheckPermissions.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,723 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 6866804 7006126
+ * @summary Unit test for java.nio.file.Files
+ * @library ..
+ * @build CheckPermissions
+ * @run main/othervm CheckPermissions
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.Files.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.security.Permission;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Checks each method that accesses the file system does the right permission
+ * check when there is a security manager set.
+ */
+
+public class CheckPermissions {
+
+ static class Checks {
+ private List<Permission> permissionsChecked = new ArrayList<>();
+ private Set<String> propertiesChecked = new HashSet<>();
+ private List<String> readsChecked = new ArrayList<>();
+ private List<String> writesChecked = new ArrayList<>();
+ private List<String> deletesChecked = new ArrayList<>();
+ private List<String> execsChecked = new ArrayList<>();
+
+ List<Permission> permissionsChecked() { return permissionsChecked; }
+ Set<String> propertiesChecked() { return propertiesChecked; }
+ List<String> readsChecked() { return readsChecked; }
+ List<String> writesChecked() { return writesChecked; }
+ List<String> deletesChecked() { return deletesChecked; }
+ List<String> execsChecked() { return execsChecked; }
+ }
+
+ static ThreadLocal<Checks> myChecks =
+ new ThreadLocal<Checks>() {
+ @Override protected Checks initialValue() {
+ return null;
+ }
+ };
+
+ static void prepare() {
+ myChecks.set(new Checks());
+ }
+
+ static void assertCheckPermission(Class<? extends Permission> type,
+ String name)
+ {
+ for (Permission perm: myChecks.get().permissionsChecked()) {
+ if (type.isInstance(perm) && perm.getName().equals(name))
+ return;
+ }
+ throw new RuntimeException(type.getName() + "(\"" + name + "\") not checked");
+ }
+
+ static void assertCheckPropertyAccess(String key) {
+ if (!myChecks.get().propertiesChecked().contains(key))
+ throw new RuntimeException("Property " + key + " not checked");
+ }
+
+ static void assertChecked(Path file, List<String> list) {
+ String s = file.toString();
+ for (String f: list) {
+ if (f.endsWith(s))
+ return;
+ }
+ throw new RuntimeException("Access not checked");
+ }
+
+ static void assertCheckRead(Path file) {
+ assertChecked(file, myChecks.get().readsChecked());
+ }
+
+ static void assertCheckWrite(Path file) {
+ assertChecked(file, myChecks.get().writesChecked());
+ }
+
+ static void assertCheckWriteToDirectory(Path dir) {
+ String s = dir.toString();
+ List<String> list = myChecks.get().writesChecked();
+ for (String f: list) {
+ if (f.startsWith(s)) {
+ return;
+ }
+ }
+ throw new RuntimeException("Access not checked");
+ }
+
+ static void assertCheckDelete(Path file) {
+ assertChecked(file, myChecks.get().deletesChecked());
+ }
+
+ static void assertCheckExec(Path file) {
+ assertChecked(file, myChecks.get().execsChecked());
+ }
+
+ static class LoggingSecurityManager extends SecurityManager {
+ static void install() {
+ System.setSecurityManager(new LoggingSecurityManager());
+ }
+
+ @Override
+ public void checkPermission(Permission perm) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.permissionsChecked().add(perm);
+ }
+
+ @Override
+ public void checkPropertyAccess(String key) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.propertiesChecked().add(key);
+ }
+
+ @Override
+ public void checkRead(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.readsChecked().add(file);
+ }
+
+ @Override
+ public void checkWrite(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.writesChecked().add(file);
+ }
+
+ @Override
+ public void checkDelete(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.deletesChecked().add(file);
+ }
+
+ @Override
+ public void checkExec(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.execsChecked().add(file);
+ }
+ }
+
+ static void testBasicFileAttributeView(BasicFileAttributeView view, Path file)
+ throws IOException
+ {
+ prepare();
+ view.readAttributes();
+ assertCheckRead(file);
+
+ prepare();
+ FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+ view.setTimes(null, now, now);
+ assertCheckWrite(file);
+ }
+
+ static void testPosixFileAttributeView(PosixFileAttributeView view, Path file)
+ throws IOException
+ {
+ prepare();
+ PosixFileAttributes attrs = view.readAttributes();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setPermissions(attrs.permissions());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(attrs.owner());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(attrs.owner());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ }
+
+ public static void main(String[] args) throws IOException {
+ final Path testdir = Paths.get(System.getProperty("test.dir", ".")).toAbsolutePath();
+ final Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
+
+ Path file = createFile(testdir.resolve("file1234"));
+ try {
+ LoggingSecurityManager.install();
+
+ // -- check access --
+
+ prepare();
+ exists(file);
+ assertCheckRead(file);
+
+ prepare();
+ isReadable(file);
+ assertCheckRead(file);
+
+ prepare();
+ isWritable(file);
+ assertCheckWrite(file);
+
+ prepare();
+ isExecutable(file);
+ assertCheckExec(file);
+
+ // -- copy --
+
+ Path target = testdir.resolve("target1234");
+ prepare();
+ copy(file, target);
+ try {
+ assertCheckRead(file);
+ assertCheckWrite(target);
+ } finally {
+ delete(target);
+ }
+
+ if (TestUtil.supportsLinks(testdir)) {
+ Path link = testdir.resolve("link1234");
+ createSymbolicLink(link, file);
+ try {
+ prepare();
+ copy(link, target, LinkOption.NOFOLLOW_LINKS);
+ try {
+ assertCheckRead(link);
+ assertCheckWrite(target);
+ assertCheckPermission(LinkPermission.class, "symbolic");
+ } finally {
+ delete(target);
+ }
+ } finally {
+ delete(link);
+ }
+ }
+
+ // -- createDirectory --
+
+ Path subdir = testdir.resolve("subdir1234");
+ prepare();
+ createDirectory(subdir);
+ try {
+ assertCheckWrite(subdir);
+ } finally {
+ delete(subdir);
+ }
+
+ // -- createFile --
+
+ Path fileToCreate = testdir.resolve("file7890");
+ prepare();
+ createFile(fileToCreate);
+ try {
+ assertCheckWrite(fileToCreate);
+ } finally {
+ delete(fileToCreate);
+ }
+
+ // -- createSymbolicLink --
+
+ if (TestUtil.supportsLinks(testdir)) {
+ prepare();
+ Path link = testdir.resolve("link1234");
+ createSymbolicLink(link, file);
+ try {
+ assertCheckWrite(link);
+ assertCheckPermission(LinkPermission.class, "symbolic");
+ } finally {
+ delete(link);
+ }
+ }
+
+ // -- createLink --
+
+ if (TestUtil.supportsLinks(testdir)) {
+ prepare();
+ Path link = testdir.resolve("entry234");
+ createLink(link, file);
+ try {
+ assertCheckWrite(link);
+ assertCheckPermission(LinkPermission.class, "hard");
+ } finally {
+ delete(link);
+ }
+ }
+
+ // -- createTempFile --
+
+ prepare();
+ Path tmpfile1 = createTempFile("foo", null);
+ try {
+ assertCheckWriteToDirectory(tmpdir);
+ } finally {
+ delete(tmpfile1);
+ }
+ prepare();
+ Path tmpfile2 = createTempFile(testdir, "foo", ".tmp");
+ try {
+ assertCheckWriteToDirectory(testdir);
+ } finally {
+ delete(tmpfile2);
+ }
+
+ // -- createTempDirectory --
+
+ prepare();
+ Path tmpdir1 = createTempDirectory("foo");
+ try {
+ assertCheckWriteToDirectory(tmpdir);
+ } finally {
+ delete(tmpdir1);
+ }
+ prepare();
+ Path tmpdir2 = createTempDirectory(testdir, "foo");
+ try {
+ assertCheckWriteToDirectory(testdir);
+ } finally {
+ delete(tmpdir2);
+ }
+
+ // -- delete/deleteIfExists --
+
+ Path fileToDelete = testdir.resolve("file7890");
+
+ createFile(fileToDelete);
+ prepare();
+ delete(fileToDelete);
+ assertCheckDelete(fileToDelete);
+
+ createFile(fileToDelete);
+ prepare();
+ deleteIfExists(fileToDelete); // file exists
+ assertCheckDelete(fileToDelete);
+
+ prepare();
+ deleteIfExists(fileToDelete); // file does not exist
+ assertCheckDelete(fileToDelete);
+
+ // -- exists/notExists --
+
+ prepare();
+ exists(file);
+ assertCheckRead(file);
+
+ prepare();
+ notExists(file);
+ assertCheckRead(file);
+
+ // -- getFileStore --
+
+ prepare();
+ getFileStore(file);
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes");
+
+ // -- isSameFile --
+
+ prepare();
+ isSameFile(file, testdir);
+ assertCheckRead(file);
+ assertCheckRead(testdir);
+
+ // -- move --
+
+ Path target2 = testdir.resolve("target1234");
+ prepare();
+ move(file, target2);
+ try {
+ assertCheckWrite(file);
+ assertCheckWrite(target2);
+ } finally {
+ // restore file
+ move(target2, file);
+ }
+
+ // -- newByteChannel --
+
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file)) {
+ assertCheckRead(file);
+ }
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file, WRITE)) {
+ assertCheckWrite(file);
+ }
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file, READ, WRITE)) {
+ assertCheckRead(file);
+ assertCheckWrite(file);
+ }
+
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file, DELETE_ON_CLOSE)) {
+ assertCheckRead(file);
+ assertCheckDelete(file);
+ }
+ createFile(file); // restore file
+
+
+ // -- newInputStream/newOutptuStream --
+
+ prepare();
+ try (InputStream in = newInputStream(file)) {
+ assertCheckRead(file);
+ }
+ prepare();
+ try (OutputStream out = newOutputStream(file)) {
+ assertCheckWrite(file);
+ }
+
+ // -- newDirectoryStream --
+
+ prepare();
+ try (DirectoryStream<Path> stream = newDirectoryStream(testdir)) {
+ assertCheckRead(testdir);
+
+ if (stream instanceof SecureDirectoryStream<?>) {
+ Path entry;
+ SecureDirectoryStream<Path> sds =
+ (SecureDirectoryStream<Path>)stream;
+
+ // newByteChannel
+ entry = file.getFileName();
+ prepare();
+ try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(READ))) {
+ assertCheckRead(file);
+ }
+ prepare();
+ try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(WRITE))) {
+ assertCheckWrite(file);
+ }
+
+ // deleteFile
+ entry = file.getFileName();
+ prepare();
+ sds.deleteFile(entry);
+ assertCheckDelete(file);
+ createFile(testdir.resolve(entry)); // restore file
+
+ // deleteDirectory
+ entry = Paths.get("subdir1234");
+ createDirectory(testdir.resolve(entry));
+ prepare();
+ sds.deleteDirectory(entry);
+ assertCheckDelete(testdir.resolve(entry));
+
+ // move
+ entry = Paths.get("tempname1234");
+ prepare();
+ sds.move(file.getFileName(), sds, entry);
+ assertCheckWrite(file);
+ assertCheckWrite(testdir.resolve(entry));
+ sds.move(entry, sds, file.getFileName()); // restore file
+
+ // newDirectoryStream
+ entry = Paths.get("subdir1234");
+ createDirectory(testdir.resolve(entry));
+ try {
+ prepare();
+ sds.newDirectoryStream(entry).close();
+ assertCheckRead(testdir.resolve(entry));
+ } finally {
+ delete(testdir.resolve(entry));
+ }
+
+ // getFileAttributeView to access attributes of directory
+ testBasicFileAttributeView(sds
+ .getFileAttributeView(BasicFileAttributeView.class), testdir);
+ testPosixFileAttributeView(sds
+ .getFileAttributeView(PosixFileAttributeView.class), testdir);
+
+ // getFileAttributeView to access attributes of entry
+ entry = file.getFileName();
+ testBasicFileAttributeView(sds
+ .getFileAttributeView(entry, BasicFileAttributeView.class), file);
+ testPosixFileAttributeView(sds
+ .getFileAttributeView(entry, PosixFileAttributeView.class), file);
+
+ } else {
+ System.out.println("SecureDirectoryStream not tested");
+ }
+ }
+
+ // -- toAbsolutePath --
+
+ prepare();
+ file.getFileName().toAbsolutePath();
+ assertCheckPropertyAccess("user.dir");
+
+ // -- toRealPath --
+
+ prepare();
+ file.toRealPath(true);
+ assertCheckRead(file);
+
+ prepare();
+ file.toRealPath(false);
+ assertCheckRead(file);
+
+ prepare();
+ Paths.get(".").toRealPath(true);
+ assertCheckPropertyAccess("user.dir");
+
+ prepare();
+ Paths.get(".").toRealPath(false);
+ assertCheckPropertyAccess("user.dir");
+
+ // -- register --
+
+ try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
+ prepare();
+ testdir.register(watcher, StandardWatchEventKind.ENTRY_DELETE);
+ assertCheckRead(testdir);
+ }
+
+ // -- getAttribute/setAttribute/readAttributes --
+
+ prepare();
+ getAttribute(file, "size");
+ assertCheckRead(file);
+
+ prepare();
+ setAttribute(file, "lastModifiedTime",
+ FileTime.fromMillis(System.currentTimeMillis()));
+ assertCheckWrite(file);
+
+ prepare();
+ readAttributes(file, "*");
+ assertCheckRead(file);
+
+ // -- BasicFileAttributeView --
+ testBasicFileAttributeView(
+ getFileAttributeView(file, BasicFileAttributeView.class), file);
+
+ // -- PosixFileAttributeView --
+
+ {
+ PosixFileAttributeView view =
+ getFileAttributeView(file, PosixFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(PosixFileAttributeView.class))
+ {
+ testPosixFileAttributeView(view, file);
+ } else {
+ System.out.println("PosixFileAttributeView not tested");
+ }
+ }
+
+ // -- DosFileAttributeView --
+
+ {
+ DosFileAttributeView view =
+ getFileAttributeView(file, DosFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(DosFileAttributeView.class))
+ {
+ prepare();
+ view.readAttributes();
+ assertCheckRead(file);
+
+ prepare();
+ view.setArchive(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setHidden(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setReadOnly(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setSystem(false);
+ assertCheckWrite(file);
+ } else {
+ System.out.println("DosFileAttributeView not tested");
+ }
+ }
+
+ // -- FileOwnerAttributeView --
+
+ {
+ FileOwnerAttributeView view =
+ getFileAttributeView(file, FileOwnerAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(FileOwnerAttributeView.class))
+ {
+ prepare();
+ UserPrincipal owner = view.getOwner();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(owner);
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ } else {
+ System.out.println("FileOwnerAttributeView not tested");
+ }
+ }
+
+ // -- UserDefinedFileAttributeView --
+
+ {
+ UserDefinedFileAttributeView view =
+ getFileAttributeView(file, UserDefinedFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(UserDefinedFileAttributeView.class))
+ {
+ prepare();
+ view.write("test", ByteBuffer.wrap(new byte[100]));
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.read("test", ByteBuffer.allocate(100));
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.size("test");
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.list();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.delete("test");
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+ } else {
+ System.out.println("UserDefinedFileAttributeView not tested");
+ }
+ }
+
+ // -- AclFileAttributeView --
+ {
+ AclFileAttributeView view =
+ getFileAttributeView(file, AclFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(AclFileAttributeView.class))
+ {
+ prepare();
+ List<AclEntry> acl = view.getAcl();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ prepare();
+ view.setAcl(acl);
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ } else {
+ System.out.println("AclFileAttributeView not tested");
+ }
+ }
+
+ // -- UserPrincipalLookupService
+
+ UserPrincipalLookupService lookupService =
+ FileSystems.getDefault().getUserPrincipalLookupService();
+ UserPrincipal owner = getOwner(file);
+
+ prepare();
+ lookupService.lookupPrincipalByName(owner.getName());
+ assertCheckPermission(RuntimePermission.class,
+ "lookupUserInformation");
+
+ try {
+ UserPrincipal group = readAttributes(file, PosixFileAttributes.class).group();
+ prepare();
+ lookupService.lookupPrincipalByGroupName(group.getName());
+ assertCheckPermission(RuntimePermission.class,
+ "lookupUserInformation");
+ } catch (UnsupportedOperationException ignore) {
+ System.out.println("lookupPrincipalByGroupName not tested");
+ }
+
+
+ } finally {
+ deleteIfExists(file);
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/ContentType.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887
- * @summary Unit test for probeContentType method
- * @library ..
- * @build ContentType SimpleFileTypeDetector
- * @run main/othervm ContentType
- */
-
-import java.nio.file.*;
-import java.io.*;
-
-/**
- * Uses Files.probeContentType to probe html file and custom file type.
- */
-
-public class ContentType {
-
- static Path createHtmlFile() throws IOException {
- Path file = File.createTempFile("foo", ".html").toPath();
- OutputStream out = file.newOutputStream();
- try {
- out.write("<html><body>foo</body></html>".getBytes());
- } finally {
- out.close();
- }
-
- return file;
- }
-
- static Path createGrapeFile() throws IOException {
- return File.createTempFile("red", ".grape").toPath();
- }
-
- public static void main(String[] args) throws IOException {
-
- // exercise default file type detector
- Path file = createHtmlFile();
- try {
- String type = Files.probeContentType(file);
- if (type == null) {
- System.err.println("Content type cannot be determined - test skipped");
- } else {
- if (!type.equals("text/html"))
- throw new RuntimeException("Unexpected type: " + type);
- }
- } finally {
- file.delete();
- }
-
- // exercise custom file type detector
- file = createGrapeFile();
- try {
- String type = Files.probeContentType(file);
- if (type == null)
- throw new RuntimeException("Custom file type detector not installed?");
- if (!type.equals("grape/unknown"))
- throw new RuntimeException("Unexpected type: " + type);
- } finally {
- file.delete();
- }
-
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/CopyAndMove.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,1194 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333 6917021 7006126
+ * @summary Unit test for java.nio.file.Files copy and move methods
+ * @library ..
+ * @build CopyAndMove PassThroughFileSystem
+ * @run main/othervm CopyAndMove
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.Files.*;
+import static java.nio.file.StandardCopyOption.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+import java.util.*;
+
+public class CopyAndMove {
+ static final Random rand = new Random();
+ static boolean heads() { return rand.nextBoolean(); }
+
+ public static void main(String[] args) throws Exception {
+ Path dir1 = TestUtil.createTemporaryDirectory();
+ try {
+
+ // Same directory
+ testCopyFileToFile(dir1, dir1, TestUtil.supportsLinks(dir1));
+ testMove(dir1, dir1, TestUtil.supportsLinks(dir1));
+
+ // Different directories. Use test.dir if possible as it might be
+ // a different volume/file system and so improve test coverage.
+ String testDir = System.getProperty("test.dir", ".");
+ Path dir2 = TestUtil.createTemporaryDirectory(testDir);
+ try {
+ boolean testSymbolicLinks =
+ TestUtil.supportsLinks(dir1) && TestUtil.supportsLinks(dir2);
+ testCopyFileToFile(dir1, dir2, testSymbolicLinks);
+ testMove(dir1, dir2, testSymbolicLinks);
+ } finally {
+ TestUtil.removeAll(dir2);
+ }
+
+ // Target is location associated with custom provider
+ Path dir3 = PassThroughFileSystem.create().getPath(dir1.toString());
+ testCopyFileToFile(dir1, dir3, false);
+ testMove(dir1, dir3, false);
+
+ // Test copy(InputStream,Path) and copy(Path,OutputStream)
+ testCopyInputStreamToFile();
+ testCopyFileToOuputStream();
+
+ } finally {
+ TestUtil.removeAll(dir1);
+ }
+ }
+
+ static void checkBasicAttributes(BasicFileAttributes attrs1,
+ BasicFileAttributes attrs2)
+ {
+ // check file type
+ assertTrue(attrs1.isRegularFile() == attrs2.isRegularFile());
+ assertTrue(attrs1.isDirectory() == attrs2.isDirectory());
+ assertTrue(attrs1.isSymbolicLink() == attrs2.isSymbolicLink());
+ assertTrue(attrs1.isOther() == attrs2.isOther());
+
+ // check last modified time
+ long time1 = attrs1.lastModifiedTime().toMillis();
+ long time2 = attrs2.lastModifiedTime().toMillis();
+ assertTrue(time1 == time2);
+
+ // check size
+ if (attrs1.isRegularFile())
+ assertTrue(attrs1.size() == attrs2.size());
+ }
+
+ static void checkPosixAttributes(PosixFileAttributes attrs1,
+ PosixFileAttributes attrs2)
+ {
+ assertTrue(attrs1.permissions().equals(attrs2.permissions()));
+ assertTrue(attrs1.owner().equals(attrs2.owner()));
+ assertTrue(attrs1.group().equals(attrs2.group()));
+ }
+
+ static void checkDosAttributes(DosFileAttributes attrs1,
+ DosFileAttributes attrs2)
+ {
+ assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly());
+ assertTrue(attrs1.isHidden() == attrs2.isHidden());
+ assertTrue(attrs1.isSystem() == attrs2.isSystem());
+ }
+
+ static void checkUserDefinedFileAttributes(Map<String,ByteBuffer> attrs1,
+ Map<String,ByteBuffer> attrs2)
+ {
+ assert attrs1.size() == attrs2.size();
+ for (String name: attrs1.keySet()) {
+ ByteBuffer bb1 = attrs1.get(name);
+ ByteBuffer bb2 = attrs2.get(name);
+ assertTrue(bb2 != null);
+ assertTrue(bb1.equals(bb2));
+ }
+ }
+
+ static Map<String,ByteBuffer> readUserDefinedFileAttributes(Path file)
+ throws IOException
+ {
+ UserDefinedFileAttributeView view =
+ getFileAttributeView(file, UserDefinedFileAttributeView.class);
+ Map<String,ByteBuffer> result = new HashMap<>();
+ for (String name: view.list()) {
+ int size = view.size(name);
+ ByteBuffer bb = ByteBuffer.allocate(size);
+ int n = view.read(name, bb);
+ assertTrue(n == size);
+ bb.flip();
+ result.put(name, bb);
+ }
+ return result;
+ }
+
+ // move source to target with verification
+ static void moveAndVerify(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ // read attributes before file is moved
+ BasicFileAttributes basicAttributes = null;
+ PosixFileAttributes posixAttributes = null;
+ DosFileAttributes dosAttributes = null;
+ Map<String,ByteBuffer> namedAttributes = null;
+
+ // get file attributes of source file
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS") || os.equals("Linux")) {
+ posixAttributes = readAttributes(source, PosixFileAttributes.class, NOFOLLOW_LINKS);
+ basicAttributes = posixAttributes;
+ }
+ if (os.startsWith("Windows")) {
+ dosAttributes = readAttributes(source, DosFileAttributes.class, NOFOLLOW_LINKS);
+ basicAttributes = dosAttributes;
+ }
+ if (basicAttributes == null)
+ basicAttributes = readAttributes(source, BasicFileAttributes.class, NOFOLLOW_LINKS);
+
+ // hash file contents if regular file
+ int hash = (basicAttributes.isRegularFile()) ? computeHash(source) : 0;
+
+ // record link target if symbolic link
+ Path linkTarget = null;
+ if (basicAttributes.isSymbolicLink())
+ linkTarget = readSymbolicLink(source);
+
+ // read named attributes if available (and file is not a sym link)
+ if (!basicAttributes.isSymbolicLink() &&
+ getFileStore(source).supportsFileAttributeView("xattr"))
+ {
+ namedAttributes = readUserDefinedFileAttributes(source);
+ }
+
+ // move file
+ Path result = move(source, target, options);
+ assertTrue(result == target);
+
+ // verify source does not exist
+ assertTrue(notExists(source));
+
+ // verify file contents
+ if (basicAttributes.isRegularFile()) {
+ if (computeHash(target) != hash)
+ throw new RuntimeException("Failed to verify move of regular file");
+ }
+
+ // verify link target
+ if (basicAttributes.isSymbolicLink()) {
+ if (!readSymbolicLink(target).equals(linkTarget))
+ throw new RuntimeException("Failed to verify move of symbolic link");
+ }
+
+ // verify basic attributes
+ checkBasicAttributes(basicAttributes,
+ readAttributes(target, BasicFileAttributes.class, NOFOLLOW_LINKS));
+
+ // verify other attributes when same provider
+ if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
+
+ // verify POSIX attributes
+ if (posixAttributes != null && !basicAttributes.isSymbolicLink()) {
+ checkPosixAttributes(posixAttributes,
+ readAttributes(target, PosixFileAttributes.class, NOFOLLOW_LINKS));
+ }
+
+ // verify DOS attributes
+ if (dosAttributes != null && !basicAttributes.isSymbolicLink()) {
+ DosFileAttributes attrs =
+ readAttributes(target, DosFileAttributes.class, NOFOLLOW_LINKS);
+ checkDosAttributes(dosAttributes, attrs);
+ }
+
+ // verify named attributes
+ if (namedAttributes != null &&
+ getFileStore(target).supportsFileAttributeView("xattr"))
+ {
+ checkUserDefinedFileAttributes(namedAttributes,
+ readUserDefinedFileAttributes(target));
+ }
+ }
+ }
+
+ /**
+ * Tests all possible ways to invoke move
+ */
+ static void testMove(Path dir1, Path dir2, boolean supportsLinks)
+ throws IOException
+ {
+ Path source, target, entry;
+
+ boolean sameDevice = getFileStore(dir1).equals(getFileStore(dir2));
+
+ // -- regular file --
+
+ /**
+ * Test: move regular file, target does not exist
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target);
+ delete(target);
+
+ /**
+ * Test: move regular file, target exists
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(target);
+ createDirectory(target);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: move regular file, target does not exist
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move regular file, target exists
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move regular file, target exists and is empty directory
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move regular file, target exists and is non-empty directory
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ entry = target.resolve("foo");
+ createFile(entry);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(entry);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test atomic move of regular file (same file store)
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir1);
+ moveAndVerify(source, target, ATOMIC_MOVE);
+ delete(target);
+
+ /**
+ * Test atomic move of regular file (different file store)
+ */
+ if (!sameDevice) {
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ try {
+ moveAndVerify(source, target, ATOMIC_MOVE);
+ throw new RuntimeException("AtomicMoveNotSupportedException expected");
+ } catch (AtomicMoveNotSupportedException x) {
+ }
+ delete(source);
+ }
+
+ // -- directories --
+
+ /*
+ * Test: move empty directory, target does not exist
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target);
+ delete(target);
+
+ /**
+ * Test: move empty directory, target exists
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(target);
+ createDirectory(target);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: move empty directory, target does not exist
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move empty directory, target exists
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move empty, target exists and is empty directory
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move empty directory, target exists and is non-empty directory
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ entry = target.resolve("foo");
+ createFile(entry);
+ try {
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ throw new RuntimeException("DirectoryNotEmptyException expected");
+ } catch (DirectoryNotEmptyException x) {
+ }
+ delete(entry);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: move non-empty directory (same file system)
+ */
+ source = createSourceDirectory(dir1);
+ createFile(source.resolve("foo"));
+ target = getTargetFile(dir1);
+ moveAndVerify(source, target);
+ delete(target.resolve("foo"));
+ delete(target);
+
+ /**
+ * Test: move non-empty directory (different file store)
+ */
+ if (!sameDevice) {
+ source = createSourceDirectory(dir1);
+ createFile(source.resolve("foo"));
+ target = getTargetFile(dir2);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("IOException expected");
+ } catch (IOException x) {
+ }
+ delete(source.resolve("foo"));
+ delete(source);
+ }
+
+ /**
+ * Test atomic move of directory (same file store)
+ */
+ source = createSourceDirectory(dir1);
+ createFile(source.resolve("foo"));
+ target = getTargetFile(dir1);
+ moveAndVerify(source, target, ATOMIC_MOVE);
+ delete(target.resolve("foo"));
+ delete(target);
+
+ // -- symbolic links --
+
+ /**
+ * Test: Move symbolic link to file, target does not exist
+ */
+ if (supportsLinks) {
+ Path tmp = createSourceFile(dir1);
+ source = dir1.resolve("link");
+ createSymbolicLink(source, tmp);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target);
+ delete(target);
+ delete(tmp);
+ }
+
+ /**
+ * Test: Move symbolic link to directory, target does not exist
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir2);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target);
+ delete(target);
+ }
+
+ /**
+ * Test: Move broken symbolic link, target does not exists
+ */
+ if (supportsLinks) {
+ Path tmp = Paths.get("doesnotexist");
+ source = dir1.resolve("link");
+ createSymbolicLink(source, tmp);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target);
+ delete(target);
+ }
+
+ /**
+ * Test: Move symbolic link, target exists
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir2);
+ target = getTargetFile(dir2);
+ createFile(target);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(source);
+ delete(target);
+ }
+
+ /**
+ * Test: Move regular file, target exists
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir2);
+ target = getTargetFile(dir2);
+ createFile(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+ }
+
+ /**
+ * Test: move symbolic link, target exists and is empty directory
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir2);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+ }
+
+ /**
+ * Test: symbolic link, target exists and is non-empty directory
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir2);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ entry = target.resolve("foo");
+ createFile(entry);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(entry);
+ delete(source);
+ delete(target);
+ }
+
+ /**
+ * Test atomic move of symbolic link (same file store)
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+ }
+
+ // -- misc. tests --
+
+ /**
+ * Test nulls
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ try {
+ move(null, target);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ try {
+ move(source, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ try {
+ move(source, target, (CopyOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ try {
+ CopyOption[] opts = { REPLACE_EXISTING, null };
+ move(source, target, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ delete(source);
+
+ /**
+ * Test UOE
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ try {
+ move(source, target, new CopyOption() { });
+ } catch (UnsupportedOperationException x) { }
+ try {
+ move(source, target, REPLACE_EXISTING, new CopyOption() { });
+ } catch (UnsupportedOperationException x) { }
+ delete(source);
+ }
+
+ // copy source to target with verification
+ static void copyAndVerify(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ Path result = copy(source, target, options);
+ assertTrue(result == target);
+
+ // get attributes of source and target file to verify copy
+ boolean followLinks = true;
+ LinkOption[] linkOptions = new LinkOption[0];
+ boolean copyAttributes = false;
+ for (CopyOption opt : options) {
+ if (opt == NOFOLLOW_LINKS) {
+ followLinks = false;
+ linkOptions = new LinkOption[] { NOFOLLOW_LINKS };
+ }
+ if (opt == COPY_ATTRIBUTES)
+ copyAttributes = true;
+ }
+ BasicFileAttributes basicAttributes =
+ readAttributes(source, BasicFileAttributes.class, linkOptions);
+
+ // check hash if regular file
+ if (basicAttributes.isRegularFile())
+ assertTrue(computeHash(source) == computeHash(target));
+
+ // check link target if symbolic link
+ if (basicAttributes.isSymbolicLink())
+ assert(readSymbolicLink(source).equals(readSymbolicLink(target)));
+
+ // check that attributes are copied
+ if (copyAttributes && followLinks) {
+ checkBasicAttributes(basicAttributes,
+ readAttributes(source, BasicFileAttributes.class, linkOptions));
+
+ // verify other attributes when same provider
+ if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
+
+ // check POSIX attributes are copied
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS") || os.equals("Linux")) {
+ checkPosixAttributes(
+ readAttributes(source, PosixFileAttributes.class, linkOptions),
+ readAttributes(target, PosixFileAttributes.class, linkOptions));
+ }
+
+ // check DOS attributes are copied
+ if (os.startsWith("Windows")) {
+ checkDosAttributes(
+ readAttributes(source, DosFileAttributes.class, linkOptions),
+ readAttributes(target, DosFileAttributes.class, linkOptions));
+ }
+
+ // check named attributes are copied
+ if (followLinks &&
+ getFileStore(source).supportsFileAttributeView("xattr") &&
+ getFileStore(target).supportsFileAttributeView("xattr"))
+ {
+ checkUserDefinedFileAttributes(readUserDefinedFileAttributes(source),
+ readUserDefinedFileAttributes(target));
+ }
+ }
+ }
+ }
+
+ /**
+ * Tests all possible ways to invoke copy to copy a file to a file
+ */
+ static void testCopyFileToFile(Path dir1, Path dir2, boolean supportsLinks)
+ throws IOException
+ {
+ Path source, target, link, entry;
+
+ // -- regular file --
+
+ /**
+ * Test: move regular file, target does not exist
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file, target exists
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ try {
+ copyAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(target);
+ createDirectory(target);
+ try {
+ copyAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file, target does not exist
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file, target exists
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file, target exists and is empty directory
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file, target exists and is non-empty directory
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ entry = target.resolve("foo");
+ createFile(entry);
+ try {
+ copyAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(entry);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file + attributes
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target, COPY_ATTRIBUTES);
+ delete(source);
+ delete(target);
+
+
+ // -- directory --
+
+ /*
+ * Test: copy directory, target does not exist
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy directory, target exists
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ try {
+ copyAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(target);
+ createDirectory(target);
+ try {
+ copyAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy directory, target does not exist
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy directory, target exists
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy directory, target exists and is empty directory
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy directory, target exists and is non-empty directory
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ entry = target.resolve("foo");
+ createFile(entry);
+ try {
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ throw new RuntimeException("DirectoryNotEmptyException expected");
+ } catch (DirectoryNotEmptyException x) {
+ }
+ delete(entry);
+ delete(source);
+ delete(target);
+
+ /*
+ * Test: copy directory + attributes
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target, COPY_ATTRIBUTES);
+ delete(source);
+ delete(target);
+
+ // -- symbolic links --
+
+ /**
+ * Test: Follow link
+ */
+ if (supportsLinks) {
+ source = createSourceFile(dir1);
+ link = dir1.resolve("link");
+ createSymbolicLink(link, source);
+ target = getTargetFile(dir2);
+ copyAndVerify(link, target);
+ delete(link);
+ delete(source);
+ }
+
+ /**
+ * Test: Copy link (to file)
+ */
+ if (supportsLinks) {
+ source = createSourceFile(dir1);
+ link = dir1.resolve("link");
+ createSymbolicLink(link, source);
+ target = getTargetFile(dir2);
+ copyAndVerify(link, target, NOFOLLOW_LINKS);
+ delete(link);
+ delete(source);
+ }
+
+ /**
+ * Test: Copy link (to directory)
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("mydir");
+ createDirectory(source);
+ link = dir1.resolve("link");
+ createSymbolicLink(link, source);
+ target = getTargetFile(dir2);
+ copyAndVerify(link, target, NOFOLLOW_LINKS);
+ delete(link);
+ delete(source);
+ }
+
+ /**
+ * Test: Copy broken link
+ */
+ if (supportsLinks) {
+ assertTrue(notExists(source));
+ link = dir1.resolve("link");
+ createSymbolicLink(link, source);
+ target = getTargetFile(dir2);
+ copyAndVerify(link, target, NOFOLLOW_LINKS);
+ delete(link);
+ }
+
+ /**
+ * Test: Copy link to UNC (Windows only)
+ */
+ if (supportsLinks &&
+ System.getProperty("os.name").startsWith("Windows"))
+ {
+ Path unc = Paths.get("\\\\rialto\\share\\file");
+ link = dir1.resolve("link");
+ createSymbolicLink(link, unc);
+ target = getTargetFile(dir2);
+ copyAndVerify(link, target, NOFOLLOW_LINKS);
+ delete(link);
+ }
+
+ // -- misc. tests --
+
+ /**
+ * Test nulls
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ try {
+ copy(source, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ try {
+ copy(source, target, (CopyOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ try {
+ CopyOption[] opts = { REPLACE_EXISTING, null };
+ copy(source, target, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ delete(source);
+
+ /**
+ * Test UOE
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ try {
+ copy(source, target, new CopyOption() { });
+ } catch (UnsupportedOperationException x) { }
+ try {
+ copy(source, target, REPLACE_EXISTING, new CopyOption() { });
+ } catch (UnsupportedOperationException x) { }
+ delete(source);
+ }
+
+ /**
+ * Test copy from an input stream to a file
+ */
+ static void testCopyInputStreamToFile() throws IOException {
+ testCopyInputStreamToFile(0);
+ for (int i=0; i<100; i++) {
+ testCopyInputStreamToFile(rand.nextInt(32000));
+ }
+
+ // FileAlreadyExistsException
+ Path target = createTempFile("blah", null);
+ try {
+ InputStream in = new ByteArrayInputStream(new byte[0]);
+ try {
+ copy(in, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException ignore) { }
+ } finally {
+ delete(target);
+ }
+ Path tmpdir = createTempDirectory("blah");
+ try {
+ if (TestUtil.supportsLinks(tmpdir)) {
+ Path link = createSymbolicLink(tmpdir.resolve("link"),
+ tmpdir.resolve("target"));
+ try {
+ InputStream in = new ByteArrayInputStream(new byte[0]);
+ try {
+ copy(in, link);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException ignore) { }
+ } finally {
+ delete(link);
+ }
+ }
+ } finally {
+ delete(tmpdir);
+ }
+
+
+ // nulls
+ try {
+ copy((InputStream)null, target);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ copy(new ByteArrayInputStream(new byte[0]), (Path)null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ }
+
+ static void testCopyInputStreamToFile(int size) throws IOException {
+ Path tmpdir = createTempDirectory("blah");
+ Path source = tmpdir.resolve("source");
+ Path target = tmpdir.resolve("target");
+ try {
+ boolean testReplaceExisting = rand.nextBoolean();
+
+ // create source file
+ byte[] b = new byte[size];
+ rand.nextBytes(b);
+ write(source, b);
+
+ // target file might already exist
+ if (testReplaceExisting && rand.nextBoolean()) {
+ write(target, new byte[rand.nextInt(512)]);
+ }
+
+ // copy from stream to file
+ InputStream in = new FileInputStream(source.toFile());
+ try {
+ long n;
+ if (testReplaceExisting) {
+ n = copy(in, target, StandardCopyOption.REPLACE_EXISTING);
+ } else {
+ n = copy(in, target);
+ }
+ assertTrue(in.read() == -1); // EOF
+ assertTrue(n == size);
+ assertTrue(size(target) == size);
+ } finally {
+ in.close();
+ }
+
+ // check file
+ byte[] read = readAllBytes(target);
+ assertTrue(Arrays.equals(read, b));
+
+ } finally {
+ deleteIfExists(source);
+ deleteIfExists(target);
+ delete(tmpdir);
+ }
+ }
+
+ /**
+ * Test copy from file to output stream
+ */
+ static void testCopyFileToOuputStream() throws IOException {
+ testCopyFileToOuputStream(0);
+ for (int i=0; i<100; i++) {
+ testCopyFileToOuputStream(rand.nextInt(32000));
+ }
+
+ // nulls
+ try {
+ copy((Path)null, new ByteArrayOutputStream());
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ Path source = createTempFile("blah", null);
+ delete(source);
+ copy(source, (OutputStream)null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ }
+
+ static void testCopyFileToOuputStream(int size) throws IOException {
+ Path source = createTempFile("blah", null);
+ try {
+ byte[] b = new byte[size];
+ rand.nextBytes(b);
+ write(source, b);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ long n = copy(source, out);
+ assertTrue(n == size);
+ assertTrue(out.size() == size);
+
+ byte[] read = out.toByteArray();
+ assertTrue(Arrays.equals(read, b));
+
+ // check output stream is open
+ out.write(0);
+ assertTrue(out.size() == size+1);
+ } finally {
+ delete(source);
+ }
+ }
+
+ static void assertTrue(boolean value) {
+ if (!value)
+ throw new RuntimeException("Assertion failed");
+ }
+
+ // computes simple hash of the given file
+ static int computeHash(Path file) throws IOException {
+ int h = 0;
+
+ try (InputStream in = newInputStream(file)) {
+ byte[] buf = new byte[1024];
+ int n;
+ do {
+ n = in.read(buf);
+ for (int i=0; i<n; i++) {
+ h = 31*h + (buf[i] & 0xff);
+ }
+ } while (n > 0);
+ }
+ return h;
+ }
+
+ // create file of random size in given directory
+ static Path createSourceFile(Path dir) throws IOException {
+ String name = "source" + Integer.toString(rand.nextInt());
+ Path file = dir.resolve(name);
+ createFile(file);
+ byte[] bytes = new byte[rand.nextInt(128*1024)];
+ rand.nextBytes(bytes);
+ try (OutputStream out = newOutputStream(file)) {
+ out.write(bytes);
+ }
+ randomizeAttributes(file);
+ return file;
+ }
+
+ // create directory in the given directory
+ static Path createSourceDirectory(Path dir) throws IOException {
+ String name = "sourcedir" + Integer.toString(rand.nextInt());
+ Path subdir = dir.resolve(name);
+ createDirectory(subdir);
+ randomizeAttributes(subdir);
+ return subdir;
+ }
+
+ // "randomize" the file attributes of the given file.
+ static void randomizeAttributes(Path file) throws IOException {
+ String os = System.getProperty("os.name");
+ boolean isWindows = os.startsWith("Windows");
+ boolean isUnix = os.equals("SunOS") || os.equals("Linux");
+ boolean isDirectory = isDirectory(file, NOFOLLOW_LINKS);
+
+ if (isUnix) {
+ Set<PosixFilePermission> perms =
+ getPosixFilePermissions(file, NOFOLLOW_LINKS);
+ PosixFilePermission[] toChange = {
+ PosixFilePermission.GROUP_READ,
+ PosixFilePermission.GROUP_WRITE,
+ PosixFilePermission.GROUP_EXECUTE,
+ PosixFilePermission.OTHERS_READ,
+ PosixFilePermission.OTHERS_WRITE,
+ PosixFilePermission.OTHERS_EXECUTE
+ };
+ for (PosixFilePermission perm: toChange) {
+ if (heads()) {
+ perms.add(perm);
+ } else {
+ perms.remove(perm);
+ }
+ }
+ setPosixFilePermissions(file, perms);
+ }
+
+ if (isWindows) {
+ DosFileAttributeView view =
+ getFileAttributeView(file, DosFileAttributeView.class, NOFOLLOW_LINKS);
+ // only set or unset the hidden attribute
+ view.setHidden(heads());
+ }
+
+ boolean addUserDefinedFileAttributes = heads() &&
+ getFileStore(file).supportsFileAttributeView("xattr");
+
+ // remove this when copying a direcory copies its named streams
+ if (isWindows && isDirectory) addUserDefinedFileAttributes = false;
+
+ if (addUserDefinedFileAttributes) {
+ UserDefinedFileAttributeView view =
+ getFileAttributeView(file, UserDefinedFileAttributeView.class);
+ int n = rand.nextInt(16);
+ while (n > 0) {
+ byte[] value = new byte[1 + rand.nextInt(100)];
+ view.write("user." + Integer.toString(n), ByteBuffer.wrap(value));
+ n--;
+ }
+ }
+ }
+
+ // create name for file in given directory
+ static Path getTargetFile(Path dir) throws IOException {
+ String name = "target" + Integer.toString(rand.nextInt());
+ return dir.resolve(name);
+ }
+ }
--- a/jdk/test/java/nio/file/Files/CreateFileTree.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Creates a file tree with possible cycles caused by symbolic links
- * to ancestor directories.
- */
-
-public class CreateFileTree {
-
- static final Random rand = new Random();
-
- public static Path createTemporaryDirectory() throws IOException {
- Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
- Path dir;
- do {
- dir = tmpdir.resolve("name" + rand.nextInt());
- } while (dir.exists());
- dir.createDirectory();
- return dir;
- }
-
- public static void main(String[] args) throws IOException {
- Path top = createTemporaryDirectory();
- if (!top.isAbsolute())
- top = top.toAbsolutePath();
-
- List<Path> dirs = new ArrayList<Path>();
-
- // create tree
- Queue<Path> queue = new ArrayDeque<Path>();
- queue.add(top);
- int total = 1 + rand.nextInt(20);
- int n = 0;
- Path dir;
- while (((dir = queue.poll()) != null) && (n < total)) {
- int r = Math.min((total-n), (1+rand.nextInt(3)));
- for (int i=0; i<r; i++) {
- String name = "dir" + (++n);
- Path subdir = dir.resolve(name).createDirectory();
- queue.offer(subdir);
- dirs.add(subdir);
- }
- }
- assert dirs.size() >= 2;
-
- // create a few regular files in the file tree
- int files = dirs.size() * 3;
- for (int i=0; i<files; i++) {
- String name = "file" + (i+1);
- int x = rand.nextInt(dirs.size());
- dirs.get(x).resolve(name).createFile();
- }
-
- // create a few sym links in the file tree so as to create cycles
- int links = 1 + rand.nextInt(5);
- for (int i=0; i<links; i++) {
- int x = rand.nextInt(dirs.size());
- int y;
- do {
- y = rand.nextInt(dirs.size());
- } while (y != x);
- String name = "link" + (i+1);
- Path link = dirs.get(x).resolve(name);
- Path target = dirs.get(y);
- link.createSymbolicLink(target);
- }
-
- // done
- System.out.println(top);
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/DeleteOnClose.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.io.*;
+import java.util.*;
+
+public class DeleteOnClose {
+
+ public static void main(String[] args) throws IOException {
+ // open file but do not close it. Its existance will be checked by
+ // the calling script.
+ Files.newByteChannel(Paths.get(args[0]), READ, WRITE, DELETE_ON_CLOSE);
+
+ // check temporary file has been deleted after closing it
+ Path file = Files.createTempFile("blah", "tmp");
+ Files.newByteChannel(file, READ, WRITE, DELETE_ON_CLOSE).close();
+ if (Files.exists(file))
+ throw new RuntimeException("Temporary file was not deleted");
+
+ Path dir = Files.createTempDirectory("blah");
+ try {
+ // check that DELETE_ON_CLOSE fails when file is a sym link
+ if (TestUtil.supportsLinks(dir)) {
+ file = dir.resolve("foo");
+ Files.createFile(file);
+ Path link = dir.resolve("link");
+ Files.createSymbolicLink(link, file);
+ try {
+ Files.newByteChannel(link, READ, WRITE, DELETE_ON_CLOSE);
+ throw new RuntimeException("IOException expected");
+ } catch (IOException ignore) { }
+ }
+
+ // check that DELETE_ON_CLOSE works with files created via open
+ // directories
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
+ if (stream instanceof SecureDirectoryStream) {
+ SecureDirectoryStream<Path> secure = (SecureDirectoryStream<Path>)stream;
+ file = Paths.get("foo");
+
+ Set<OpenOption> opts = new HashSet<>();
+ opts.add(WRITE);
+ opts.add(DELETE_ON_CLOSE);
+ secure.newByteChannel(file, opts).close();
+
+ if (Files.exists(dir.resolve(file)))
+ throw new RuntimeException("File not deleted");
+ }
+ }
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/FileAttributes.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333
+ * @summary Unit test for java.nio.file.Files
+ * @library ..
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Exercises getAttribute/setAttribute/readAttributes methods.
+ */
+
+public class FileAttributes {
+
+ static void assertTrue(boolean okay) {
+ if (!okay)
+ throw new RuntimeException("Assertion Failed");
+ }
+
+ static void checkEqual(Object o1, Object o2) {
+ if (o1 == null) {
+ assertTrue(o2 == null);
+ } else {
+ assertTrue (o1.equals(o2));
+ }
+ }
+
+ // checks that two time values are within 1s of each other
+ static void checkNearEqual(FileTime t1, FileTime t2) {
+ long diff = Math.abs(t1.toMillis() - t2.toMillis());
+ assertTrue(diff <= 1000);
+ }
+
+ // Exercise getAttribute/setAttribute/readAttributes on basic attributes
+ static void checkBasicAttributes(Path file, BasicFileAttributes attrs)
+ throws IOException
+ {
+ // getAttribute
+ checkEqual(attrs.size(), Files.getAttribute(file, "size"));
+ checkEqual(attrs.lastModifiedTime(), Files.getAttribute(file, "basic:lastModifiedTime"));
+ checkEqual(attrs.lastAccessTime(), Files.getAttribute(file, "lastAccessTime"));
+ checkEqual(attrs.creationTime(), Files.getAttribute(file, "basic:creationTime"));
+ assertTrue((Boolean)Files.getAttribute(file, "isRegularFile"));
+ assertTrue(!(Boolean)Files.getAttribute(file, "basic:isDirectory"));
+ assertTrue(!(Boolean)Files.getAttribute(file, "isSymbolicLink"));
+ assertTrue(!(Boolean)Files.getAttribute(file, "basic:isOther"));
+ checkEqual(attrs.fileKey(), Files.getAttribute(file, "basic:fileKey"));
+
+ // setAttribute
+ FileTime modTime = attrs.lastModifiedTime();
+ Files.setAttribute(file, "basic:lastModifiedTime", FileTime.fromMillis(0L));
+ checkEqual(Files.getLastModifiedTime(file),
+ FileTime.fromMillis(0L));
+ Files.setAttribute(file, "lastModifiedTime", modTime);
+ checkEqual(Files.getLastModifiedTime(file), modTime);
+
+ Map<String,Object> map;
+ map = Files.readAttributes(file, "*");
+ assertTrue(map.size() >= 9);
+ checkEqual(attrs.isRegularFile(), map.get("isRegularFile")); // check one
+
+ map = Files.readAttributes(file, "basic:*");
+ assertTrue(map.size() >= 9);
+ checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime")); // check one
+
+ map = Files.readAttributes(file, "size,lastModifiedTime");
+ assertTrue(map.size() == 2);
+ checkEqual(attrs.size(), map.get("size"));
+ checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
+
+ map = Files.readAttributes(file,
+ "basic:lastModifiedTime,lastAccessTime,ShouldNotExist");
+ assertTrue(map.size() == 2);
+ checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
+ checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime"));
+ }
+
+ // Exercise getAttribute/setAttribute/readAttributes on posix attributes
+ static void checkPosixAttributes(Path file, PosixFileAttributes attrs)
+ throws IOException
+ {
+ checkBasicAttributes(file, attrs);
+
+ // getAttribute
+ checkEqual(attrs.permissions(), Files.getAttribute(file, "posix:permissions"));
+ checkEqual(attrs.owner(), Files.getAttribute(file, "posix:owner"));
+ checkEqual(attrs.group(), Files.getAttribute(file, "posix:group"));
+
+ // setAttribute
+ Set<PosixFilePermission> orig = attrs.permissions();
+ Set<PosixFilePermission> newPerms = new HashSet<>(orig);
+ newPerms.remove(PosixFilePermission.OTHERS_READ);
+ newPerms.remove(PosixFilePermission.OTHERS_WRITE);
+ newPerms.remove(PosixFilePermission.OTHERS_EXECUTE);
+ Files.setAttribute(file, "posix:permissions", newPerms);
+ checkEqual(Files.getPosixFilePermissions(file), newPerms);
+ Files.setAttribute(file, "posix:permissions", orig);
+ checkEqual(Files.getPosixFilePermissions(file), orig);
+ Files.setAttribute(file, "posix:owner", attrs.owner());
+ Files.setAttribute(file, "posix:group", attrs.group());
+
+ // readAttributes
+ Map<String,Object> map;
+ map = Files.readAttributes(file, "posix:*");
+ assertTrue(map.size() >= 12);
+ checkEqual(attrs.permissions(), map.get("permissions")); // check one
+
+ map = Files.readAttributes(file, "posix:size,owner,ShouldNotExist");
+ assertTrue(map.size() == 2);
+ checkEqual(attrs.size(), map.get("size"));
+ checkEqual(attrs.owner(), map.get("owner"));
+ }
+
+ // Exercise getAttribute/readAttributes on unix attributes
+ static void checkUnixAttributes(Path file) throws IOException {
+ // getAttribute
+ int mode = (Integer)Files.getAttribute(file, "unix:mode");
+ long ino = (Long)Files.getAttribute(file, "unix:ino");
+ long dev = (Long)Files.getAttribute(file, "unix:dev");
+ long rdev = (Long)Files.getAttribute(file, "unix:rdev");
+ int nlink = (Integer)Files.getAttribute(file, "unix:nlink");
+ int uid = (Integer)Files.getAttribute(file, "unix:uid");
+ int gid = (Integer)Files.getAttribute(file, "unix:gid");
+ FileTime ctime = (FileTime)Files.getAttribute(file, "unix:ctime");
+
+ // readAttributes
+ Map<String,Object> map;
+ map = Files.readAttributes(file, "unix:*");
+ assertTrue(map.size() >= 20);
+
+ map = Files.readAttributes(file, "unix:size,uid,gid,ShouldNotExist");
+ assertTrue(map.size() == 3);
+ checkEqual(map.get("size"),
+ Files.readAttributes(file, BasicFileAttributes.class).size());
+ }
+
+ // Exercise getAttribute/setAttribute on dos attributes
+ static void checkDosAttributes(Path file, DosFileAttributes attrs)
+ throws IOException
+ {
+ checkBasicAttributes(file, attrs);
+
+ // getAttribute
+ checkEqual(attrs.isReadOnly(), Files.getAttribute(file, "dos:readonly"));
+ checkEqual(attrs.isHidden(), Files.getAttribute(file, "dos:hidden"));
+ checkEqual(attrs.isSystem(), Files.getAttribute(file, "dos:system"));
+ checkEqual(attrs.isArchive(), Files.getAttribute(file, "dos:archive"));
+
+ // setAttribute
+ boolean value;
+
+ value = attrs.isReadOnly();
+ Files.setAttribute(file, "dos:readonly", !value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isReadOnly(), !value);
+ Files.setAttribute(file, "dos:readonly", value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isReadOnly(), value);
+
+ value = attrs.isHidden();
+ Files.setAttribute(file, "dos:hidden", !value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isHidden(), !value);
+ Files.setAttribute(file, "dos:hidden", value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isHidden(), value);
+
+ value = attrs.isSystem();
+ Files.setAttribute(file, "dos:system", !value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isSystem(), !value);
+ Files.setAttribute(file, "dos:system", value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isSystem(), value);
+
+ value = attrs.isArchive();
+ Files.setAttribute(file, "dos:archive", !value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isArchive(), !value);
+ Files.setAttribute(file, "dos:archive", value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isArchive(), value);
+
+ // readAttributes
+ Map<String,Object> map;
+ map = Files.readAttributes(file, "dos:*");
+ assertTrue(map.size() >= 13);
+ checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one
+
+ map = Files.readAttributes(file, "dos:size,hidden,ShouldNotExist");
+ assertTrue(map.size() == 2);
+ checkEqual(attrs.size(), map.get("size"));
+ checkEqual(attrs.isHidden(), map.get("hidden"));
+ }
+
+ static void miscTests(Path file) throws IOException {
+ // NPE tests
+ try {
+ Files.getAttribute(file, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException npe) { }
+ try {
+ Files.getAttribute(file, "isRegularFile", (LinkOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException npe) { }
+ try {
+ Files.setAttribute(file, null, 0L);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException npe) { }
+ }
+
+ static void doTests(Path dir) throws IOException {
+ Path file = dir.resolve("foo");
+ Files.createFile(file);
+ FileStore store = Files.getFileStore(file);
+ try {
+ checkBasicAttributes(file,
+ Files.readAttributes(file, BasicFileAttributes.class));
+
+ if (store.supportsFileAttributeView("posix"))
+ checkPosixAttributes(file,
+ Files.readAttributes(file, PosixFileAttributes.class));
+
+ if (store.supportsFileAttributeView("unix"))
+ checkUnixAttributes(file);
+
+ if (store.supportsFileAttributeView("dos"))
+ checkDosAttributes(file,
+ Files.readAttributes(file, DosFileAttributes.class));
+
+ miscTests(file);
+ } finally {
+ Files.delete(file);
+ }
+ }
+
+
+ public static void main(String[] args) throws IOException {
+ Path dir = TestUtil.createTemporaryDirectory();
+ try {
+ doTests(dir);
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/ForceLoad.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887
- * @summary Test library dependencies by invoking Files.probeContentType
- * before other methods that would cause nio.dll to be loaded.
- */
-
-import java.nio.file.*;
-import java.io.IOException;
-
-public class ForceLoad {
-
- public static void main(String[] args) throws IOException {
- Files.probeContentType(Paths.get("."));
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/InterruptCopy.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6993267
+ * @summary Unit test for Sun-specific ExtendedCopyOption.INTERRUPTIBLE option
+ * @library ..
+ * @run main/othervm -XX:-UseVMInterruptibleIO InterruptCopy
+ */
+
+import java.nio.file.*;
+import java.io.*;
+import java.util.concurrent.*;
+import com.sun.nio.file.ExtendedCopyOption;
+
+public class InterruptCopy {
+
+ private static final long FILE_SIZE_TO_COPY = 512L * 1024L * 1024L;
+ private static final int DELAY_IN_MS = 500;
+ private static final int DURATION_MAX_IN_MS = 5000;
+
+ public static void main(String[] args) throws Exception {
+ Path dir = TestUtil.createTemporaryDirectory();
+ try {
+ FileStore store = Files.getFileStore(dir);
+ System.out.format("Checking space (%s)\n", store);
+ long usableSpace = store.getUsableSpace();
+ if (usableSpace < 2*FILE_SIZE_TO_COPY) {
+ System.out.println("Insufficient disk space to run test.");
+ return;
+ }
+ doTest(dir);
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
+
+ static void doTest(Path dir) throws Exception {
+ final Path source = dir.resolve("foo");
+ final Path target = dir.resolve("bar");
+
+ // create source file (don't create it as sparse file because we
+ // require the copy to take a long time)
+ System.out.println("Creating source file...");
+ byte[] buf = new byte[32*1024];
+ long total = 0;
+ try (OutputStream out = Files.newOutputStream(source)) {
+ do {
+ out.write(buf);
+ total += buf.length;
+ } while (total < FILE_SIZE_TO_COPY);
+ }
+ System.out.println("Source file created.");
+
+ ScheduledExecutorService pool =
+ Executors.newSingleThreadScheduledExecutor();
+ try {
+ // copy source to target in main thread, interrupting it after a delay
+ final Thread me = Thread.currentThread();
+ Future<?> wakeup = pool.schedule(new Runnable() {
+ public void run() {
+ me.interrupt();
+ }}, DELAY_IN_MS, TimeUnit.MILLISECONDS);
+ System.out.println("Copying file...");
+ try {
+ long start = System.currentTimeMillis();
+ Files.copy(source, target, ExtendedCopyOption.INTERRUPTIBLE);
+ long duration = System.currentTimeMillis() - start;
+ if (duration > DURATION_MAX_IN_MS)
+ throw new RuntimeException("Copy was not interrupted");
+ } catch (IOException e) {
+ boolean interrupted = Thread.interrupted();
+ if (!interrupted)
+ throw new RuntimeException("Interrupt status was not set");
+ System.out.println("Copy failed (this is expected)");
+ }
+ try {
+ wakeup.get();
+ } catch (InterruptedException ignore) { }
+ Thread.interrupted();
+
+ // copy source to target via task in thread pool, interrupting it after
+ // a delay using cancel(true)
+ Future<Void> result = pool.submit(new Callable<Void>() {
+ public Void call() throws IOException {
+ System.out.println("Copying file...");
+ Files.copy(source, target, ExtendedCopyOption.INTERRUPTIBLE,
+ StandardCopyOption.REPLACE_EXISTING);
+ return null;
+ }
+ });
+ Thread.sleep(DELAY_IN_MS);
+ boolean cancelled = result.cancel(true);
+ if (!cancelled)
+ result.get();
+ System.out.println("Copy cancelled.");
+ } finally {
+ pool.shutdown();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/Links.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333 6863864
+ * @summary Unit test for java.nio.file.Files createSymbolicLink,
+ * readSymbolicLink, and createLink methods
+ * @library ..
+ * @build Links
+ * @run main/othervm Links
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+
+public class Links {
+
+ static final boolean isWindows =
+ System.getProperty("os.name").startsWith("Windows");
+
+ static void assertTrue(boolean okay) {
+ if (!okay)
+ throw new RuntimeException("Assertion failed");
+ }
+
+ /**
+ * Exercise createSymbolicLink and readLink methods
+ */
+ static void testSymLinks(Path dir) throws IOException {
+ final Path link = dir.resolve("link");
+
+ // Check if sym links are supported
+ try {
+ Files.createSymbolicLink(link, Paths.get("foo"));
+ Files.delete(link);
+ } catch (UnsupportedOperationException x) {
+ // sym links not supported
+ return;
+ } catch (IOException x) {
+ // probably insufficient privileges to create sym links (Windows)
+ return;
+ }
+
+ // Test links to various targets
+ String[] windowsTargets =
+ { "foo", "C:\\foo", "\\foo", "\\\\server\\share\\foo" };
+ String[] otherTargets = { "relative", "/absolute" };
+
+ String[] targets = (isWindows) ? windowsTargets : otherTargets;
+ for (String s: targets) {
+ Path target = Paths.get(s);
+ Files.createSymbolicLink(link, target);
+ try {
+ assertTrue(Files.readSymbolicLink(link).equals(target));
+ } finally {
+ Files.delete(link);
+ }
+ }
+
+ // Test links to directory
+ Path mydir = dir.resolve("mydir");
+ Path myfile = mydir.resolve("myfile");
+ try {
+ Files.createDirectory(mydir);
+ Files.createFile(myfile);
+
+ // link -> "mydir"
+ Files.createSymbolicLink(link, mydir.getFileName());
+ assertTrue(Files.readSymbolicLink(link).equals(mydir.getFileName()));
+
+ // Test access to directory via link
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(link)) {
+ boolean found = false;
+ for (Path entry: stream) {
+ if (entry.getFileName().equals(myfile.getFileName())) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue(found);
+ }
+
+ // Test link2 -> link -> mydir
+ final Path link2 = dir.resolve("link2");
+ Path target2 = link.getFileName();
+ Files.createSymbolicLink(link2, target2);
+ try {
+ assertTrue(Files.readSymbolicLink(link2).equals(target2));
+ Files.newDirectoryStream(link2).close();
+ } finally {
+ Files.delete(link2);
+ }
+
+ // Remove mydir and re-create link2 before re-creating mydir
+ // (This is a useful test on Windows to ensure that creating a
+ // sym link to a directory sym link creates the right type of link).
+ Files.delete(myfile);
+ Files.delete(mydir);
+ Files.createSymbolicLink(link2, target2);
+ try {
+ assertTrue(Files.readSymbolicLink(link2).equals(target2));
+ Files.createDirectory(mydir);
+ Files.newDirectoryStream(link2).close();
+ } finally {
+ Files.delete(link2);
+ }
+
+ } finally {
+ Files.deleteIfExists(myfile);
+ Files.deleteIfExists(mydir);
+ Files.deleteIfExists(link);
+ }
+ }
+
+ /**
+ * Exercise createLink method
+ */
+ static void testHardLinks(Path dir) throws IOException {
+ Path foo = dir.resolve("foo");
+ Files.createFile(foo);
+ try {
+ Path bar = dir.resolve("bar");
+ try {
+ Files.createLink(bar, foo);
+ } catch (UnsupportedOperationException x) {
+ return;
+ } catch (IOException x) {
+ // probably insufficient privileges (Windows)
+ return;
+ }
+ try {
+ Object key1 = Files.readAttributes(foo, BasicFileAttributes.class).fileKey();
+ Object key2 = Files.readAttributes(bar, BasicFileAttributes.class).fileKey();
+ assertTrue((key1 == null) || (key1.equals(key2)));
+ } finally {
+ Files.delete(bar);
+ }
+
+
+ } finally {
+ Files.delete(foo);
+ }
+ }
+
+ public static void main(String[] args) throws IOException {
+ Path dir = TestUtil.createTemporaryDirectory();
+ try {
+ testSymLinks(dir);
+ testHardLinks(dir);
+
+ // repeat tests on Windows with long path
+ if (isWindows) {
+ Path dirWithLongPath = null;
+ try {
+ dirWithLongPath = TestUtil.createDirectoryWithLongPath(dir);
+ } catch (IOException x) {
+ System.out.println("Unable to create long path: " + x);
+ }
+ if (dirWithLongPath != null) {
+ System.out.println("");
+ System.out.println("** REPEAT TESTS WITH LONG PATH **");
+ testSymLinks(dirWithLongPath);
+ testHardLinks(dirWithLongPath);
+ }
+ }
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/META-INF/services/java.nio.file.spi.FileTypeDetector Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-SimpleFileTypeDetector
--- a/jdk/test/java/nio/file/Files/MaxDepth.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Unit test for Files.walkFileTree to test maxDepth parameter
- */
-
-public class MaxDepth {
- public static void main(String[] args) throws Exception {
- final Path top = Paths.get(args[0]);
-
- for (int i=0; i<5; i++) {
- Set<FileVisitOption> opts = Collections.emptySet();
- final int maxDepth = i;
- Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
- // compute depth based on relative path to top directory
- private int depth(Path file) {
- Path rp = file.relativize(top);
- return (rp == null) ? 0 : rp.getNameCount();
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- int d = depth(dir);
- if (d == maxDepth)
- throw new RuntimeException("Should not open directories at maxDepth");
- if (d > maxDepth)
- throw new RuntimeException("Too deep");
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- int d = depth(file);
- if (d > maxDepth)
- throw new RuntimeException("Too deep");
- return FileVisitResult.CONTINUE;
- }
- });
- }
- }
-}
--- a/jdk/test/java/nio/file/Files/Misc.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/Files/Misc.java Mon Feb 14 16:30:10 2011 -0800
@@ -22,122 +22,335 @@
*/
/* @test
- * @bug 4313887 6838333 6865748
- * @summary Unit test for java.nio.file.Files for miscellenous cases not
- * covered by other tests
+ * @bug 4313887 6838333
+ * @summary Unit test for miscellenous methods in java.nio.file.Files
* @library ..
*/
import java.nio.file.*;
-import java.nio.file.attribute.Attributes;
-import java.nio.file.attribute.BasicFileAttributes;
+import static java.nio.file.Files.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
import java.io.IOException;
import java.util.*;
public class Misc {
- static void npeExpected() {
- throw new RuntimeException("NullPointerException expected");
- }
-
public static void main(String[] args) throws IOException {
-
- // -- Files.createDirectories --
-
Path dir = TestUtil.createTemporaryDirectory();
try {
- // no-op
- Files.createDirectories(dir);
+ testCreateDirectories(dir);
+ testIsHidden(dir);
+ testIsSameFile(dir);
+ testFileTypeMethods(dir);
+ testAccessMethods(dir);
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
- // create one directory
- Path subdir = dir.resolve("a");
- Files.createDirectories(subdir);
- if (!subdir.exists())
- throw new RuntimeException("directory not created");
+ /**
+ * Tests createDirectories
+ */
+ static void testCreateDirectories(Path tmpdir) throws IOException {
+ // a no-op
+ createDirectories(tmpdir);
+
+ // create one directory
+ Path subdir = tmpdir.resolve("a");
+ createDirectories(subdir);
+ assertTrue(exists(subdir));
- // create parents
- subdir = subdir.resolve("b/c/d");
- Files.createDirectories(subdir);
- if (!subdir.exists())
- throw new RuntimeException("directory not created");
+ // create parents
+ subdir = subdir.resolve("b/c/d");
+ createDirectories(subdir);
+ assertTrue(exists(subdir));
- // existing file is not a directory
- Path file = dir.resolve("x").createFile();
+ // existing file is not a directory
+ Path file = createFile(tmpdir.resolve("x"));
+ try {
+ createDirectories(file);
+ throw new RuntimeException("failure expected");
+ } catch (FileAlreadyExistsException x) { }
+ try {
+ createDirectories(file.resolve("y"));
+ throw new RuntimeException("failure expected");
+ } catch (IOException x) { }
+ }
+
+ /**
+ * Tests isHidden
+ */
+ static void testIsHidden(Path tmpdir) throws IOException {
+ assertTrue(!isHidden(tmpdir));
+
+ Path file = tmpdir.resolve(".foo");
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ createFile(file);
try {
- Files.createDirectories(file);
- throw new RuntimeException("failure expected");
- } catch (FileAlreadyExistsException x) { }
- try {
- Files.createDirectories(file.resolve("y"));
- throw new RuntimeException("failure expected");
- } catch (IOException x) { }
+ setAttribute(file, "dos:hidden", true);
+ try {
+ assertTrue(isHidden(file));
+ } finally {
+ setAttribute(file, "dos:hidden", false);
+ }
+ } finally {
+ delete(file);
+ }
+ } else {
+ assertTrue(isHidden(file));
+ }
+ }
- } finally {
- TestUtil.removeAll(dir);
- }
+ /**
+ * Tests isSameFile
+ */
+ static void testIsSameFile(Path tmpdir) throws IOException {
+ Path thisFile = tmpdir.resolve("thisFile");
+ Path thatFile = tmpdir.resolve("thatFile");
- // --- NullPointerException --
+ /**
+ * Test: isSameFile for self
+ */
+ assertTrue(isSameFile(thisFile, thisFile));
+ /**
+ * Test: Neither files exist
+ */
try {
- Files.probeContentType(null);
- npeExpected();
- } catch (NullPointerException e) {
+ isSameFile(thisFile, thatFile);
+ throw new RuntimeException("IOException not thrown");
+ } catch (IOException x) {
}
try {
- Files.walkFileTree(null, EnumSet.noneOf(FileVisitOption.class),
- Integer.MAX_VALUE, new SimpleFileVisitor<Path>(){});
- npeExpected();
- } catch (NullPointerException e) {
+ isSameFile(thatFile, thisFile);
+ throw new RuntimeException("IOException not thrown");
+ } catch (IOException x) {
}
- try {
- Files.walkFileTree(Paths.get("."), null, Integer.MAX_VALUE,
- new SimpleFileVisitor<Path>(){});
- npeExpected();
- } catch (NullPointerException e) {
- }
+
+ createFile(thisFile);
try {
- Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
- -1, new SimpleFileVisitor<Path>(){});
- throw new RuntimeException("IllegalArgumentExpected expected");
- } catch (IllegalArgumentException e) {
- }
- try {
- Set<FileVisitOption> opts = new HashSet<FileVisitOption>(1);
- opts.add(null);
- Files.walkFileTree(Paths.get("."), opts, Integer.MAX_VALUE,
- new SimpleFileVisitor<Path>(){});
- npeExpected();
- } catch (NullPointerException e) {
- }
- try {
- Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
- Integer.MAX_VALUE, null);
- npeExpected();
- } catch (NullPointerException e) {
+ /**
+ * Test: One file exists
+ */
+ try {
+ isSameFile(thisFile, thatFile);
+ throw new RuntimeException("IOException not thrown");
+ } catch (IOException x) {
+ }
+ try {
+ isSameFile(thatFile, thisFile);
+ throw new RuntimeException("IOException not thrown");
+ } catch (IOException x) {
+ }
+
+ /**
+ * Test: Both file exists
+ */
+ createFile(thatFile);
+ try {
+ assertTrue(!isSameFile(thisFile, thatFile));
+ assertTrue(!isSameFile(thatFile, thisFile));
+ } finally {
+ delete(thatFile);
+ }
+
+ /**
+ * Test: Symbolic links
+ */
+ if (TestUtil.supportsLinks(tmpdir)) {
+ createSymbolicLink(thatFile, thisFile);
+ try {
+ assertTrue(isSameFile(thisFile, thatFile));
+ assertTrue(isSameFile(thatFile, thisFile));
+ } finally {
+ TestUtil.deleteUnchecked(thatFile);
+ }
+ }
+ } finally {
+ delete(thisFile);
}
- SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
- boolean ranTheGauntlet = false;
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(Paths.get("."));
+ // nulls
+ try {
+ isSameFile(thisFile, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ isSameFile(null, thatFile);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ }
+
+ /**
+ * Exercise isRegularFile, isDirectory, isSymbolicLink
+ */
+ static void testFileTypeMethods(Path tmpdir) throws IOException {
+ assertTrue(!isRegularFile(tmpdir));
+ assertTrue(!isRegularFile(tmpdir, NOFOLLOW_LINKS));
+ assertTrue(isDirectory(tmpdir));
+ assertTrue(isDirectory(tmpdir, NOFOLLOW_LINKS));
+ assertTrue(!isSymbolicLink(tmpdir));
+
+ Path file = createFile(tmpdir.resolve("foo"));
+ try {
+ assertTrue(isRegularFile(file));
+ assertTrue(isRegularFile(file, NOFOLLOW_LINKS));
+ assertTrue(!isDirectory(file));
+ assertTrue(!isDirectory(file, NOFOLLOW_LINKS));
+ assertTrue(!isSymbolicLink(file));
+
+ if (TestUtil.supportsLinks(tmpdir)) {
+ Path link = tmpdir.resolve("link");
+
+ createSymbolicLink(link, tmpdir);
+ try {
+ assertTrue(!isRegularFile(link));
+ assertTrue(!isRegularFile(link, NOFOLLOW_LINKS));
+ assertTrue(isDirectory(link));
+ assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
+ assertTrue(isSymbolicLink(link));
+ } finally {
+ delete(link);
+ }
+
+ createSymbolicLink(link, file);
+ try {
+ assertTrue(isRegularFile(link));
+ assertTrue(!isRegularFile(link, NOFOLLOW_LINKS));
+ assertTrue(!isDirectory(link));
+ assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
+ assertTrue(isSymbolicLink(link));
+ } finally {
+ delete(link);
+ }
+
+ createLink(link, file);
+ try {
+ assertTrue(isRegularFile(link));
+ assertTrue(isRegularFile(link, NOFOLLOW_LINKS));
+ assertTrue(!isDirectory(link));
+ assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
+ assertTrue(!isSymbolicLink(link));
+ } finally {
+ delete(link);
+ }
+ }
+
+ } finally {
+ delete(file);
+ }
+ }
+
+ /**
+ * Exercise isReadbale, isWritable, isExecutable, exists, notExists
+ */
+ static void testAccessMethods(Path tmpdir) throws IOException {
+ // should return false when file does not exist
+ Path doesNotExist = tmpdir.resolve("doesNotExist");
+ assertTrue(!isReadable(doesNotExist));
+ assertTrue(!isWritable(doesNotExist));
+ assertTrue(!isExecutable(doesNotExist));
+ assertTrue(!exists(doesNotExist));
+ assertTrue(notExists(doesNotExist));
- try { visitor.preVisitDirectory(null, attrs);
- } catch (NullPointerException x0) {
- try { visitor.preVisitDirectory(dir, null);
- } catch (NullPointerException x1) {
- try { visitor.visitFile(null, attrs);
- } catch (NullPointerException x2) {
- try { visitor.visitFile(dir, null);
- } catch (NullPointerException x3) {
- try { visitor.visitFileFailed(null, new IOException());
- } catch (NullPointerException x4) {
- try { visitor.visitFileFailed(dir, null);
- } catch (NullPointerException x5) {
- try { visitor.postVisitDirectory(null, new IOException());
- } catch (NullPointerException x6) {
- // if we get here then all visit* methods threw NPE as expected
- ranTheGauntlet = true;
- }}}}}}}
- if (!ranTheGauntlet)
- throw new RuntimeException("A visit method did not throw NPE");
+ Path file = createFile(tmpdir.resolve("foo"));
+ try {
+ // files exist
+ assertTrue(isReadable(file));
+ assertTrue(isWritable(file));
+ assertTrue(exists(file));
+ assertTrue(!notExists(file));
+ assertTrue(isReadable(tmpdir));
+ assertTrue(isWritable(tmpdir));
+ assertTrue(exists(tmpdir));
+ assertTrue(!notExists(tmpdir));
+
+
+ // sym link exists
+ if (TestUtil.supportsLinks(tmpdir)) {
+ Path link = tmpdir.resolve("link");
+
+ createSymbolicLink(link, file);
+ try {
+ assertTrue(isReadable(link));
+ assertTrue(isWritable(link));
+ assertTrue(exists(link));
+ assertTrue(!notExists(link));
+ } finally {
+ delete(link);
+ }
+
+ createSymbolicLink(link, doesNotExist);
+ try {
+ assertTrue(!isReadable(link));
+ assertTrue(!isWritable(link));
+ assertTrue(!exists(link));
+ assertTrue(exists(link, NOFOLLOW_LINKS));
+ assertTrue(notExists(link));
+ assertTrue(!notExists(link, NOFOLLOW_LINKS));
+ } finally {
+ delete(link);
+ }
+ }
+
+ /**
+ * Test: Edit ACL to deny WRITE and EXECUTE
+ */
+ if (getFileStore(file).supportsFileAttributeView("acl")) {
+ AclFileAttributeView view =
+ getFileAttributeView(file, AclFileAttributeView.class);
+ UserPrincipal owner = view.getOwner();
+ List<AclEntry> acl = view.getAcl();
+
+ // Insert entry to deny WRITE and EXECUTE
+ AclEntry entry = AclEntry.newBuilder()
+ .setType(AclEntryType.DENY)
+ .setPrincipal(owner)
+ .setPermissions(AclEntryPermission.WRITE_DATA,
+ AclEntryPermission.EXECUTE)
+ .build();
+ acl.add(0, entry);
+ view.setAcl(acl);
+ try {
+ assertTrue(!isWritable(file));
+ assertTrue(!isExecutable(file));
+ } finally {
+ // Restore ACL
+ acl.remove(0);
+ view.setAcl(acl);
+ }
+ }
+
+ /**
+ * Test: Windows DOS read-only attribute
+ */
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ setAttribute(file, "dos:readonly", true);
+ try {
+ assertTrue(!isWritable(file));
+ } finally {
+ setAttribute(file, "dos:readonly", false);
+ }
+
+ // Read-only attribute does not make direcory read-only
+ DosFileAttributeView view =
+ getFileAttributeView(tmpdir, DosFileAttributeView.class);
+ boolean save = view.readAttributes().isReadOnly();
+ view.setReadOnly(true);
+ try {
+ assertTrue(isWritable(file));
+ } finally {
+ view.setReadOnly(save);
+ }
+ }
+ } finally {
+ delete(file);
+ }
+ }
+
+ static void assertTrue(boolean okay) {
+ if (!okay)
+ throw new RuntimeException("Assertion Failed");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/PassThroughFileSystem.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.nio.channels.SeekableByteChannel;
+import java.net.URI;
+import java.util.*;
+import java.io.*;
+
+/**
+ * A "pass through" file system implementation that passes through, or delegates,
+ * everything to the default file system.
+ */
+
+class PassThroughFileSystem extends FileSystem {
+ private final FileSystemProvider provider;
+ private final FileSystem delegate;
+
+ PassThroughFileSystem(FileSystemProvider provider, FileSystem delegate) {
+ this.provider = provider;
+ this.delegate = delegate;
+ }
+
+ /**
+ * Creates a new "pass through" file system. Useful for test environments
+ * where the provider might not be deployed.
+ */
+ static FileSystem create() throws IOException {
+ FileSystemProvider provider = new PassThroughProvider();
+ Map<String,?> env = Collections.emptyMap();
+ URI uri = URI.create("pass:///");
+ return provider.newFileSystem(uri, env);
+ }
+
+ static Path unwrap(Path wrapper) {
+ if (wrapper == null)
+ throw new NullPointerException();
+ if (!(wrapper instanceof PassThroughPath))
+ throw new ProviderMismatchException();
+ return ((PassThroughPath)wrapper).delegate;
+ }
+
+ @Override
+ public FileSystemProvider provider() {
+ return provider;
+ }
+
+ @Override
+ public void close() throws IOException {
+ delegate.close();
+ }
+
+ @Override
+ public boolean isOpen() {
+ return delegate.isOpen();
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return delegate.isReadOnly();
+ }
+
+ @Override
+ public String getSeparator() {
+ return delegate.getSeparator();
+ }
+
+ @Override
+ public Iterable<Path> getRootDirectories() {
+ final Iterable<Path> roots = delegate.getRootDirectories();
+ return new Iterable<Path>() {
+ @Override
+ public Iterator<Path> iterator() {
+ final Iterator<Path> itr = roots.iterator();
+ return new Iterator<Path>() {
+ @Override
+ public boolean hasNext() {
+ return itr.hasNext();
+ }
+ @Override
+ public Path next() {
+ return new PassThroughPath(delegate, itr.next());
+ }
+ @Override
+ public void remove() {
+ itr.remove();
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public Iterable<FileStore> getFileStores() {
+ // assume that unwrapped objects aren't exposed
+ return delegate.getFileStores();
+ }
+
+ @Override
+ public Set<String> supportedFileAttributeViews() {
+ // assume that unwrapped objects aren't exposed
+ return delegate.supportedFileAttributeViews();
+ }
+
+ @Override
+ public Path getPath(String first, String... more) {
+ return new PassThroughPath(this, delegate.getPath(first, more));
+ }
+
+ @Override
+ public PathMatcher getPathMatcher(String syntaxAndPattern) {
+ final PathMatcher matcher = delegate.getPathMatcher(syntaxAndPattern);
+ return new PathMatcher() {
+ @Override
+ public boolean matches(Path path) {
+ return matcher.matches(unwrap(path));
+ }
+ };
+ }
+
+ @Override
+ public UserPrincipalLookupService getUserPrincipalLookupService() {
+ // assume that unwrapped objects aren't exposed
+ return delegate.getUserPrincipalLookupService();
+ }
+
+ @Override
+ public WatchService newWatchService() throws IOException {
+ // to keep it simple
+ throw new UnsupportedOperationException();
+ }
+
+ static class PassThroughProvider extends FileSystemProvider {
+ private static final String SCHEME = "pass";
+ private static volatile PassThroughFileSystem delegate;
+
+ public PassThroughProvider() { }
+
+ @Override
+ public String getScheme() {
+ return SCHEME;
+ }
+
+ private void checkScheme(URI uri) {
+ if (!uri.getScheme().equalsIgnoreCase(SCHEME))
+ throw new IllegalArgumentException();
+ }
+
+ private void checkUri(URI uri) {
+ checkScheme(uri);
+ if (!uri.getSchemeSpecificPart().equals("///"))
+ throw new IllegalArgumentException();
+ }
+
+ @Override
+ public FileSystem newFileSystem(URI uri, Map<String,?> env)
+ throws IOException
+ {
+ checkUri(uri);
+ synchronized (PassThroughProvider.class) {
+ if (delegate != null)
+ throw new FileSystemAlreadyExistsException();
+ PassThroughFileSystem result =
+ new PassThroughFileSystem(this, FileSystems.getDefault());
+ delegate = result;
+ return result;
+ }
+ }
+
+ @Override
+ public FileSystem getFileSystem(URI uri) {
+ checkUri(uri);
+ FileSystem result = delegate;
+ if (result == null)
+ throw new FileSystemNotFoundException();
+ return result;
+ }
+
+ @Override
+ public Path getPath(URI uri) {
+ checkScheme(uri);
+ if (delegate == null)
+ throw new FileSystemNotFoundException();
+ uri = URI.create(delegate.provider().getScheme() + ":" +
+ uri.getSchemeSpecificPart());
+ return new PassThroughPath(delegate, delegate.provider().getPath(uri));
+ }
+
+ @Override
+ public void setAttribute(Path file, String attribute, Object value, LinkOption... options)
+ throws IOException
+ {
+ Files.setAttribute(unwrap(file), attribute, value, options);
+ }
+
+ @Override
+ public Map<String,Object> readAttributes(Path file, String attributes, LinkOption... options)
+ throws IOException
+ {
+ return Files.readAttributes(unwrap(file), attributes, options);
+ }
+
+ @Override
+ public <V extends FileAttributeView> V getFileAttributeView(Path file,
+ Class<V> type,
+ LinkOption... options)
+ {
+ return Files.getFileAttributeView(unwrap(file), type, options);
+ }
+
+ @Override
+ public <A extends BasicFileAttributes> A readAttributes(Path file,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ return Files.readAttributes(unwrap(file), type, options);
+ }
+
+ @Override
+ public void delete(Path file) throws IOException {
+ Files.delete(unwrap(file));
+ }
+
+ @Override
+ public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ Files.createSymbolicLink(unwrap(link), unwrap(target), attrs);
+ }
+
+ @Override
+ public void createLink(Path link, Path existing) throws IOException {
+ Files.createLink(unwrap(link), unwrap(existing));
+ }
+
+ @Override
+ public Path readSymbolicLink(Path link) throws IOException {
+ Path target = Files.readSymbolicLink(unwrap(link));
+ return new PassThroughPath(delegate, target);
+ }
+
+
+ @Override
+ public void copy(Path source, Path target, CopyOption... options) throws IOException {
+ Files.copy(unwrap(source), unwrap(target), options);
+ }
+
+ @Override
+ public void move(Path source, Path target, CopyOption... options) throws IOException {
+ Files.move(unwrap(source), unwrap(target), options);
+ }
+
+ private DirectoryStream<Path> wrap(final DirectoryStream<Path> stream) {
+ return new DirectoryStream<Path>() {
+ @Override
+ public Iterator<Path> iterator() {
+ final Iterator<Path> itr = stream.iterator();
+ return new Iterator<Path>() {
+ @Override
+ public boolean hasNext() {
+ return itr.hasNext();
+ }
+ @Override
+ public Path next() {
+ return new PassThroughPath(delegate, itr.next());
+ }
+ @Override
+ public void remove() {
+ itr.remove();
+ }
+ };
+ }
+ @Override
+ public void close() throws IOException {
+ stream.close();
+ }
+ };
+ }
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ return wrap(Files.newDirectoryStream(dir, filter));
+ }
+
+ @Override
+ public void createDirectory(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ Files.createDirectory(unwrap(dir), attrs);
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path file,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return Files.newByteChannel(unwrap(file), options, attrs);
+ }
+
+
+ @Override
+ public boolean isHidden(Path file) throws IOException {
+ return Files.isHidden(unwrap(file));
+ }
+
+ @Override
+ public FileStore getFileStore(Path file) throws IOException {
+ return Files.getFileStore(unwrap(file));
+ }
+
+ @Override
+ public boolean isSameFile(Path file, Path other) throws IOException {
+ return Files.isSameFile(unwrap(file), unwrap(other));
+ }
+
+ @Override
+ public void checkAccess(Path file, AccessMode... modes)
+ throws IOException
+ {
+ // hack
+ if (modes.length == 0) {
+ if (Files.exists(unwrap(file)))
+ return;
+ else
+ throw new NoSuchFileException(file.toString());
+ }
+ throw new RuntimeException("not implemented yet");
+ }
+ }
+
+ static class PassThroughPath implements Path {
+ private final FileSystem fs;
+ private final Path delegate;
+
+ PassThroughPath(FileSystem fs, Path delegate) {
+ this.fs = fs;
+ this.delegate = delegate;
+ }
+
+ private Path wrap(Path path) {
+ return (path != null) ? new PassThroughPath(fs, path) : null;
+ }
+
+ @Override
+ public FileSystem getFileSystem() {
+ return fs;
+ }
+
+ @Override
+ public boolean isAbsolute() {
+ return delegate.isAbsolute();
+ }
+
+ @Override
+ public Path getRoot() {
+ return wrap(delegate.getRoot());
+ }
+
+ @Override
+ public Path getParent() {
+ return wrap(delegate.getParent());
+ }
+
+ @Override
+ public int getNameCount() {
+ return delegate.getNameCount();
+ }
+
+ @Override
+ public Path getFileName() {
+ return wrap(delegate.getFileName());
+ }
+
+ @Override
+ public Path getName(int index) {
+ return wrap(delegate.getName(index));
+ }
+
+ @Override
+ public Path subpath(int beginIndex, int endIndex) {
+ return wrap(delegate.subpath(beginIndex, endIndex));
+ }
+
+ @Override
+ public boolean startsWith(Path other) {
+ return delegate.startsWith(unwrap(other));
+ }
+
+ @Override
+ public boolean startsWith(String other) {
+ return delegate.startsWith(other);
+ }
+
+ @Override
+ public boolean endsWith(Path other) {
+ return delegate.endsWith(unwrap(other));
+ }
+
+ @Override
+ public boolean endsWith(String other) {
+ return delegate.endsWith(other);
+ }
+
+ @Override
+ public Path normalize() {
+ return wrap(delegate.normalize());
+ }
+
+ @Override
+ public Path resolve(Path other) {
+ return wrap(delegate.resolve(unwrap(other)));
+ }
+
+ @Override
+ public Path resolve(String other) {
+ return wrap(delegate.resolve(other));
+ }
+
+ @Override
+ public Path resolveSibling(Path other) {
+ return wrap(delegate.resolveSibling(unwrap(other)));
+ }
+
+ @Override
+ public Path resolveSibling(String other) {
+ return wrap(delegate.resolveSibling(other));
+ }
+
+ @Override
+ public Path relativize(Path other) {
+ return wrap(delegate.relativize(unwrap(other)));
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof PassThroughPath))
+ return false;
+ return delegate.equals(unwrap((PassThroughPath)other));
+ }
+
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+
+ @Override
+ public URI toUri() {
+ String ssp = delegate.toUri().getSchemeSpecificPart();
+ return URI.create(fs.provider().getScheme() + ":" + ssp);
+ }
+
+ @Override
+ public Path toAbsolutePath() {
+ return wrap(delegate.toAbsolutePath());
+ }
+
+ @Override
+ public Path toRealPath(boolean resolveLinks) throws IOException {
+ return wrap(delegate.toRealPath(resolveLinks));
+ }
+
+ @Override
+ public File toFile() {
+ return delegate.toFile();
+ }
+
+ @Override
+ public Iterator<Path> iterator() {
+ final Iterator<Path> itr = delegate.iterator();
+ return new Iterator<Path>() {
+ @Override
+ public boolean hasNext() {
+ return itr.hasNext();
+ }
+ @Override
+ public Path next() {
+ return wrap(itr.next());
+ }
+ @Override
+ public void remove() {
+ itr.remove();
+ }
+ };
+ }
+
+ @Override
+ public int compareTo(Path other) {
+ return delegate.compareTo(unwrap(other));
+ }
+
+ @Override
+ public WatchKey register(WatchService watcher,
+ WatchEvent.Kind<?>[] events,
+ WatchEvent.Modifier... modifiers)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public WatchKey register(WatchService watcher,
+ WatchEvent.Kind<?>... events)
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/PrintFileTree.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Invokes Files.walkFileTree to traverse a file tree and prints
- * each of the directories and files. The -follow option causes symbolic
- * links to be followed and the -printCycles option will print links
- * where the target of the link is an ancestor directory.
- */
-
-public class PrintFileTree {
-
- public static void main(String[] args) throws Exception {
- boolean followLinks = false;
- boolean printCycles = false;
- int i = 0;
- while (i < (args.length-1)) {
- switch (args[i]) {
- case "-follow" : followLinks = true; break;
- case "-printCycles" : printCycles = true; break;
- default:
- throw new RuntimeException(args[i] + " not recognized");
- }
- i++;
- }
- Path dir = Paths.get(args[i]);
-
- Set<FileVisitOption> options = new HashSet<FileVisitOption>();
- if (followLinks)
- options.add(FileVisitOption.FOLLOW_LINKS);
-
- final boolean reportCycles = printCycles;
- Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<FileRef>() {
- @Override
- public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
- System.out.println(dir);
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
- if (!attrs.isDirectory() || reportCycles)
- System.out.println(file);
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult postVisitDirectory(FileRef dir, IOException exc)
- throws IOException
- {
- if (exc != null)
- throw exc;
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult visitFileFailed(FileRef file, IOException exc)
- throws IOException
- {
- if (reportCycles && (exc instanceof FileSystemLoopException)) {
- System.out.println(file);
- return FileVisitResult.CONTINUE;
- }
- throw exc;
- }
- });
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/SBC.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.Files.newByteChannel
+ * @library ..
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import static com.sun.nio.file.ExtendedOpenOption.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.channels.*;
+import java.io.IOException;
+import java.util.*;
+
+public class SBC {
+
+ static boolean supportsLinks;
+
+ public static void main(String[] args) throws Exception {
+ Path dir = TestUtil.createTemporaryDirectory();
+ try {
+ supportsLinks = TestUtil.supportsLinks(dir);
+
+ // open options
+ createTests(dir);
+ appendTests(dir);
+ truncateExistingTests(dir);
+ noFollowLinksTests(dir);
+
+ // SeekableByteChannel methods
+ sizeTruncatePositionTests(dir);
+
+ // platform specific
+ if (System.getProperty("os.name").startsWith("Windows"))
+ dosSharingOptionTests(dir);
+
+ // misc. tests
+ badCombinations(dir);
+ unsupportedOptions(dir);
+ nullTests(dir);
+
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
+
+ // test CREATE and CREATE_NEW options
+ static void createTests(Path dir) throws Exception {
+ Path file = dir.resolve("foo");
+
+ // CREATE
+ try {
+ // create file (no existing file)
+ Files.newByteChannel(file, CREATE, WRITE).close();
+ if (Files.notExists(file))
+ throw new RuntimeException("File not created");
+
+ // create file (existing file)
+ Files.newByteChannel(file, CREATE, WRITE).close();
+
+ // create file where existing file is a sym link
+ if (supportsLinks) {
+ Path link = Files.createSymbolicLink(dir.resolve("link"), file);
+ try {
+ // file already exists
+ Files.newByteChannel(link, CREATE, WRITE).close();
+
+ // file does not exist
+ Files.delete(file);
+ Files.newByteChannel(link, CREATE, WRITE).close();
+ if (Files.notExists(file))
+ throw new RuntimeException("File not created");
+
+ } finally {
+ TestUtil.deleteUnchecked(link);
+ }
+ }
+
+ } finally {
+ TestUtil.deleteUnchecked(file);
+ }
+
+ // CREATE_NEW
+ try {
+ // create file
+ Files.newByteChannel(file, CREATE_NEW, WRITE).close();
+ if (Files.notExists(file))
+ throw new RuntimeException("File not created");
+
+ // create should fail
+ try {
+ SeekableByteChannel sbc =
+ Files.newByteChannel(file, CREATE_NEW, WRITE);
+ sbc.close();
+ throw new RuntimeException("FileAlreadyExistsException not thrown");
+ } catch (FileAlreadyExistsException x) { }
+
+ // create should fail
+ if (supportsLinks) {
+ Path link = dir.resolve("link");
+ Path target = dir.resolve("thisDoesNotExist");
+ Files.createSymbolicLink(link, target);
+ try {
+
+ try {
+ SeekableByteChannel sbc =
+ Files.newByteChannel(file, CREATE_NEW, WRITE);
+ sbc.close();
+ throw new RuntimeException("FileAlreadyExistsException not thrown");
+ } catch (FileAlreadyExistsException x) { }
+
+ } finally {
+ TestUtil.deleteUnchecked(link);
+ }
+ }
+
+
+ } finally {
+ TestUtil.deleteUnchecked(file);
+ }
+
+ // CREATE_NEW + SPARSE
+ try {
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, WRITE, SPARSE)) {
+ final long hole = 2L * 1024L * 1024L * 1024L;
+ sbc.position(hole);
+ write(sbc, "hello");
+ long size = sbc.size();
+ if (size != (hole + 5))
+ throw new RuntimeException("Unexpected size");
+ }
+ } finally {
+ TestUtil.deleteUnchecked(file);
+ }
+ }
+
+ // test APPEND option
+ static void appendTests(Path dir) throws Exception {
+ Path file = dir.resolve("foo");
+ try {
+ // "hello there" should be written to file
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, WRITE, APPEND)) {
+ write(sbc, "hello ");
+ sbc.position(0L);
+ write(sbc, "there");
+ }
+
+ // check file
+ try (Scanner s = new Scanner(file)) {
+ String line = s.nextLine();
+ if (!line.equals("hello there"))
+ throw new RuntimeException("Unexpected file contents");
+ }
+
+ // check that read is not allowed
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, APPEND)) {
+ sbc.read(ByteBuffer.allocate(100));
+ } catch (NonReadableChannelException x) {
+ }
+ } finally {
+ // clean-up
+ TestUtil.deleteUnchecked(file);
+ }
+ }
+
+ // test TRUNCATE_EXISTING option
+ static void truncateExistingTests(Path dir) throws Exception {
+ Path file = dir.resolve("foo");
+ try {
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, WRITE)) {
+ write(sbc, "Have a nice day!");
+ }
+
+ // re-open with truncate option
+ // write short message and check
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, WRITE, TRUNCATE_EXISTING)) {
+ write(sbc, "Hello there!");
+ }
+ try (Scanner s = new Scanner(file)) {
+ String line = s.nextLine();
+ if (!line.equals("Hello there!"))
+ throw new RuntimeException("Unexpected file contents");
+ }
+
+ // re-open with create + truncate option
+ // check file is of size 0L
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, WRITE, CREATE, TRUNCATE_EXISTING)) {
+ long size = ((FileChannel)sbc).size();
+ if (size != 0L)
+ throw new RuntimeException("File not truncated");
+ }
+
+ } finally {
+ // clean-up
+ TestUtil.deleteUnchecked(file);
+ }
+
+ }
+
+ // test NOFOLLOW_LINKS option
+ static void noFollowLinksTests(Path dir) throws Exception {
+ if (!supportsLinks)
+ return;
+ Path file = Files.createFile(dir.resolve("foo"));
+ try {
+ // ln -s foo link
+ Path link = dir.resolve("link");
+ Files.createSymbolicLink(link, file);
+
+ // open with NOFOLLOW_LINKS option
+ try {
+ Files.newByteChannel(link, READ, LinkOption.NOFOLLOW_LINKS);
+ throw new RuntimeException();
+ } catch (IOException x) {
+ } finally {
+ TestUtil.deleteUnchecked(link);
+ }
+
+ } finally {
+ // clean-up
+ TestUtil.deleteUnchecked(file);
+ }
+ }
+
+ // test size/truncate/position methods
+ static void sizeTruncatePositionTests(Path dir) throws Exception {
+ Path file = dir.resolve("foo");
+ try {
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, READ, WRITE)) {
+ if (sbc.size() != 0L)
+ throw new RuntimeException("Unexpected size");
+
+ // check size
+ write(sbc, "hello");
+ if (sbc.size() != 5L)
+ throw new RuntimeException("Unexpected size");
+
+ // truncate (size and position should change)
+ sbc.truncate(4L);
+ if (sbc.size() != 4L)
+ throw new RuntimeException("Unexpected size");
+ if (sbc.position() != 4L)
+ throw new RuntimeException("Unexpected position");
+
+ // truncate (position should not change)
+ sbc.position(2L).truncate(3L);
+ if (sbc.size() != 3L)
+ throw new RuntimeException("Unexpected size");
+ if (sbc.position() != 2L)
+ throw new RuntimeException("Unexpected position");
+ }
+ } finally {
+ TestUtil.deleteUnchecked(file);
+ }
+ }
+
+ // Windows specific options for the use by applications that really want
+ // to use legacy DOS sharing options
+ static void dosSharingOptionTests(Path dir) throws Exception {
+ Path file = Files.createFile(dir.resolve("foo"));
+ try {
+ // no sharing
+ try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_READ,
+ NOSHARE_WRITE, NOSHARE_DELETE))
+ {
+ try {
+ Files.newByteChannel(file, READ);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ try {
+ Files.newByteChannel(file, WRITE);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ try {
+ Files.delete(file);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ }
+
+ // read allowed
+ try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_WRITE, NOSHARE_DELETE)) {
+ Files.newByteChannel(file, READ).close();
+ try {
+ Files.newByteChannel(file, WRITE);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ try {
+ Files.delete(file);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ }
+
+ // write allowed
+ try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_READ, NOSHARE_DELETE)) {
+ try {
+ Files.newByteChannel(file, READ);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ Files.newByteChannel(file, WRITE).close();
+ try {
+ Files.delete(file);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ }
+
+ // delete allowed
+ try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_READ, NOSHARE_WRITE)) {
+ try {
+ Files.newByteChannel(file, READ);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ try {
+ Files.newByteChannel(file, WRITE);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ Files.delete(file);
+ }
+
+ } finally {
+ TestUtil.deleteUnchecked(file);
+ }
+ }
+
+ // invalid combinations of options
+ static void badCombinations(Path dir) throws Exception {
+ Path file = dir.resolve("bad");
+
+ try {
+ Files.newByteChannel(file, READ, APPEND);
+ throw new RuntimeException("IllegalArgumentException expected");
+ } catch (IllegalArgumentException x) { }
+
+ try {
+ Files.newByteChannel(file, WRITE, APPEND, TRUNCATE_EXISTING);
+ throw new RuntimeException("IllegalArgumentException expected");
+ } catch (IllegalArgumentException x) { }
+ }
+
+ // unsupported operations
+ static void unsupportedOptions(Path dir) throws Exception {
+ Path file = dir.resolve("bad");
+
+ OpenOption badOption = new OpenOption() { };
+ try {
+ Files.newByteChannel(file, badOption);
+ throw new RuntimeException("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) { }
+ try {
+ Files.newByteChannel(file, READ, WRITE, badOption);
+ throw new RuntimeException("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) { }
+ }
+
+ // null handling
+ static void nullTests(Path dir) throws Exception {
+ Path file = dir.resolve("foo");
+
+ try {
+ OpenOption[] opts = { READ, null };
+ Files.newByteChannel((Path)null, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ Files.newByteChannel(file, (OpenOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ OpenOption[] opts = { READ, null };
+ Files.newByteChannel(file, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ Files.newByteChannel(file, (Set<OpenOption>)null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ Set<OpenOption> opts = new HashSet<>();
+ opts.add(READ);
+ opts.add(null);
+ Files.newByteChannel(file, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
+ Files.newByteChannel(file, opts, (FileAttribute[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
+ FileAttribute[] attrs = { null };
+ Files.newByteChannel(file, opts, attrs);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ }
+
+ static void write(WritableByteChannel wbc, String msg) throws IOException {
+ ByteBuffer buf = ByteBuffer.wrap(msg.getBytes());
+ while (buf.hasRemaining())
+ wbc.write(buf);
+ }
+}
--- a/jdk/test/java/nio/file/Files/SimpleFileTypeDetector.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.spi.FileTypeDetector;
-import java.io.*;
-
-
-public class SimpleFileTypeDetector extends FileTypeDetector {
- public SimpleFileTypeDetector() {
- }
-
- public String probeContentType(FileRef file) throws IOException {
-
- System.out.println("probe " + file + "...");
-
- if (file instanceof Path) {
- String name = ((Path)file).toString();
- if (name.endsWith(".grape")) {
- return "grape/unknown";
- }
- }
-
- // unknown
- return null;
- }
-}
--- a/jdk/test/java/nio/file/Files/SkipSiblings.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Unit test for Files.walkFileTree to test SKIP_SIBLINGS return value.
- */
-
-public class SkipSiblings {
-
- static final Random rand = new Random();
- static final Set<Path> skipped = new HashSet<Path>();
-
- // check if this path's directory has been skipped
- static void check(Path path) {
- if (skipped.contains(path.getParent()))
- throw new RuntimeException(path + " should not have been visited");
- }
-
- // indicates if the siblings of this path should be skipped
- static boolean skip(Path path) {
- Path parent = path.getParent();
- if (parent != null && rand.nextBoolean()) {
- skipped.add(parent);
- return true;
- }
- return false;
- }
-
- public static void main(String[] args) throws Exception {
- Path dir = Paths.get(args[0]);
-
- Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- check(dir);
- if (skip(dir))
- return FileVisitResult.SKIP_SIBLINGS;
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- check(file);
- if (skip(file))
- return FileVisitResult.SKIP_SIBLINGS;
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult postVisitDirectory(Path dir, IOException x) {
- if (x != null)
- throw new RuntimeException(x);
- check(dir);
- return FileVisitResult.CONTINUE;
- }
- });
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/TemporaryFiles.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333 7006126
+ * @summary Unit test for Files.createTempXXX
+ * @library ..
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.Set;
+
+public class TemporaryFiles {
+
+ static void checkInDirectory(Path file, Path dir) {
+ if (dir == null)
+ dir = Paths.get(System.getProperty("java.io.tmpdir"));
+ if (!file.getParent().equals(dir))
+ throw new RuntimeException("Not in expected directory");
+ }
+
+ static void testTempFile(String prefix, String suffix, Path dir)
+ throws IOException
+ {
+ Path file = (dir == null) ?
+ Files.createTempFile(prefix, suffix) :
+ Files.createTempFile(dir, prefix, suffix);
+ try {
+ // check file name
+ String name = file.getFileName().toString();
+ if (prefix != null && !name.startsWith(prefix))
+ throw new RuntimeException("Should start with " + prefix);
+ if (suffix == null && !name.endsWith(".tmp"))
+ throw new RuntimeException("Should end with .tmp");
+ if (suffix != null && !name.endsWith(suffix))
+ throw new RuntimeException("Should end with " + suffix);
+
+ // check file is in expected directory
+ checkInDirectory(file, dir);
+
+ // check that file can be opened for reading and writing
+ Files.newByteChannel(file, READ).close();
+ Files.newByteChannel(file, WRITE).close();
+ Files.newByteChannel(file, READ,WRITE).close();
+
+ // check file permissions are 0600 or more secure
+ if (Files.getFileStore(file).supportsFileAttributeView("posix")) {
+ Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file);
+ perms.remove(PosixFilePermission.OWNER_READ);
+ perms.remove(PosixFilePermission.OWNER_WRITE);
+ if (!perms.isEmpty())
+ throw new RuntimeException("Temporary file is not secure");
+ }
+ } finally {
+ Files.delete(file);
+ }
+ }
+
+ static void testTempFile(String prefix, String suffix)
+ throws IOException
+ {
+ testTempFile(prefix, suffix, null);
+ }
+
+ static void testTempDirectory(String prefix, Path dir) throws IOException {
+ Path subdir = (dir == null) ?
+ Files.createTempDirectory(prefix) :
+ Files.createTempDirectory(dir, prefix);
+ try {
+ // check file name
+ String name = subdir.getFileName().toString();
+ if (prefix != null && !name.startsWith(prefix))
+ throw new RuntimeException("Should start with " + prefix);
+
+ // check directory is in expected directory
+ checkInDirectory(subdir, dir);
+
+ // check directory is empty
+ DirectoryStream<Path> stream = Files.newDirectoryStream(subdir);
+ try {
+ if (stream.iterator().hasNext())
+ throw new RuntimeException("Tempory directory not empty");
+ } finally {
+ stream.close();
+ }
+
+ // check that we can create file in directory
+ Path file = Files.createFile(subdir.resolve("foo"));
+ try {
+ Files.newByteChannel(file, READ,WRITE).close();
+ } finally {
+ Files.delete(file);
+ }
+
+ // check file permissions are 0700 or more secure
+ if (Files.getFileStore(subdir).supportsFileAttributeView("posix")) {
+ Set<PosixFilePermission> perms = Files.getPosixFilePermissions(subdir);
+ perms.remove(PosixFilePermission.OWNER_READ);
+ perms.remove(PosixFilePermission.OWNER_WRITE);
+ perms.remove(PosixFilePermission.OWNER_EXECUTE);
+ if (!perms.isEmpty())
+ throw new RuntimeException("Temporary directory is not secure");
+ }
+ } finally {
+ Files.delete(subdir);
+ }
+ }
+
+ static void testTempDirectory(String prefix) throws IOException {
+ testTempDirectory(prefix, null);
+ }
+
+ static void testInvalidFileTemp(String prefix, String suffix) throws IOException {
+ try {
+ Path file = Files.createTempFile(prefix, suffix);
+ Files.delete(file);
+ throw new RuntimeException("IllegalArgumentException expected");
+ } catch (IllegalArgumentException expected) { }
+ }
+
+ public static void main(String[] args) throws IOException {
+ // temporary-file directory
+ testTempFile("blah", ".dat");
+ testTempFile("blah", null);
+ testTempFile(null, ".dat");
+ testTempFile(null, null);
+ testTempDirectory("blah");
+ testTempDirectory(null);
+
+ // a given directory
+ Path dir = Files.createTempDirectory("tmpdir");
+ try {
+ testTempFile("blah", ".dat", dir);
+ testTempFile("blah", null, dir);
+ testTempFile(null, ".dat", dir);
+ testTempFile(null, null, dir);
+ testTempDirectory("blah", dir);
+ testTempDirectory(null, dir);
+ } finally {
+ Files.delete(dir);
+ }
+
+ // invalid prefix and suffix
+ testInvalidFileTemp("../blah", null);
+ testInvalidFileTemp("dir/blah", null);
+ testInvalidFileTemp("blah", ".dat/foo");
+ }
+}
--- a/jdk/test/java/nio/file/Files/TerminateWalk.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Unit test for Files.walkFileTree to test TERMINATE return value
- */
-
-public class TerminateWalk {
-
- static final Random rand = new Random();
- static boolean terminated;
-
- static FileVisitResult maybeTerminate() {
- if (terminated)
- throw new RuntimeException("FileVisitor invoked after termination");
- if (rand.nextInt(10) == 0) {
- terminated = true;
- return FileVisitResult.TERMINATE;
- } else {
- return FileVisitResult.CONTINUE;
- }
- }
-
- public static void main(String[] args) throws Exception {
- Path dir = Paths.get(args[0]);
-
- Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- return maybeTerminate();
- }
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- return maybeTerminate();
- }
- @Override
- public FileVisitResult postVisitDirectory(Path dir, IOException x) {
- return maybeTerminate();
- }
- });
- }
-}
--- a/jdk/test/java/nio/file/Files/WalkWithSecurity.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 6876541
- * @summary Test Files.walkFileTree in the presence of a security manager
- * @build WalkWithSecurity
- * @run main/othervm WalkWithSecurity grantAll.policy pass
- * @run main/othervm WalkWithSecurity denyAll.policy fail
- * @run main/othervm WalkWithSecurity grantTopOnly.policy top_only
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.io.IOException;
-
-public class WalkWithSecurity {
-
- public static void main(String[] args) throws IOException {
- String policyFile = args[0];
- ExpectedResult expectedResult = ExpectedResult.valueOf(args[1].toUpperCase());
-
- String here = System.getProperty("user.dir");
- String testSrc = System.getProperty("test.src");
- if (testSrc == null)
- throw new RuntimeException("This test must be run by jtreg");
- Path dir = Paths.get(testSrc);
-
- // Sanity check the environment
- if (Paths.get(here).isSameFile(dir))
- throw new RuntimeException("Working directory cannot be " + dir);
- DirectoryStream<Path> stream = dir.newDirectoryStream();
- try {
- if (!stream.iterator().hasNext())
- throw new RuntimeException(testSrc + " is empty");
- } finally {
- stream.close();
- }
-
- // Install security manager with the given policy file
- System.setProperty("java.security.policy",
- dir.resolve(policyFile).toString());
- System.setSecurityManager(new SecurityManager());
-
- // Walk the source tree
- CountingVisitor visitor = new CountingVisitor();
- SecurityException exception = null;
- try {
- Files.walkFileTree(dir, visitor);
- } catch (SecurityException se) {
- exception = se;
- }
-
- // Check result
- switch (expectedResult) {
- case PASS:
- if (exception != null) {
- exception.printStackTrace();
- throw new RuntimeException("SecurityException not expected");
- }
- if (visitor.count() == 0)
- throw new RuntimeException("No files visited");
- break;
- case FAIL:
- if (exception == null)
- throw new RuntimeException("SecurityException expected");
- if (visitor.count() > 0)
- throw new RuntimeException("Files were visited");
- break;
- case TOP_ONLY:
- if (exception != null) {
- exception.printStackTrace();
- throw new RuntimeException("SecurityException not expected");
- }
- if (visitor.count() == 0)
- throw new RuntimeException("Starting file not visited");
- if (visitor.count() > 1)
- throw new RuntimeException("More than starting file visited");
- break;
- default:
- throw new RuntimeException("Should not get here");
- }
- }
-
- static enum ExpectedResult {
- PASS,
- FAIL,
- TOP_ONLY;
- }
-
- static class CountingVisitor extends SimpleFileVisitor<Path> {
- private int count;
-
- int count() {
- return count;
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- System.out.println(dir);
- count++;
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- System.out.println(file);
- count++;
- return FileVisitResult.CONTINUE;
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/delete_on_close.sh Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 4313887
+# @summary Unit test for DELETE_ON_CLOSE open option
+# @library ..
+# @build DeleteOnClose
+# @run shell delete_on_close.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+ TESTSRC=.
+ TESTCLASSES=.
+ JAVA=java
+else
+ JAVA="${TESTJAVA}/bin/java"
+fi
+
+OS=`uname -s`
+case "$OS" in
+ Windows_* | CYGWIN* )
+ CLASSPATH="${TESTCLASSES};${TESTSRC}"
+ ;;
+ * )
+ CLASSPATH=${TESTCLASSES}:${TESTSRC}
+ ;;
+esac
+export CLASSPATH
+
+TMPFILE="$$.tmp"
+touch $TMPFILE
+$JAVA DeleteOnClose $TMPFILE 2>&1
+if [ $? != 0 ]; then exit 1; fi
+if [ -f $TMPFILE ]; then
+ echo "$TMPFILE was not deleted"
+ exit 1
+fi
+
+exit 0
--- a/jdk/test/java/nio/file/Files/denyAll.policy Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-// policy file that does not grant any permissions
-grant {
-};
--- a/jdk/test/java/nio/file/Files/grantAll.policy Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-// policy file that grants read access to source directory and all descendants
-grant {
- permission java.io.FilePermission "${test.src}", "read";
- permission java.io.FilePermission "${test.src}${file.separator}-", "read";
-};
--- a/jdk/test/java/nio/file/Files/grantTopOnly.policy Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-// policy file that grants read access to source directory
-grant {
- permission java.io.FilePermission "${test.src}", "read";
-};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for probeContentType method
+ * @library ../..
+ * @build Basic SimpleFileTypeDetector
+ * @run main/othervm Basic
+ */
+
+import java.nio.file.*;
+import java.io.*;
+
+/**
+ * Uses Files.probeContentType to probe html file and custom file type.
+ */
+
+public class Basic {
+
+ static Path createHtmlFile() throws IOException {
+ Path file = Files.createTempFile("foo", ".html");
+ try (OutputStream out = Files.newOutputStream(file)) {
+ out.write("<html><body>foo</body></html>".getBytes());
+ }
+
+ return file;
+ }
+
+ static Path createGrapeFile() throws IOException {
+ return Files.createTempFile("red", ".grape");
+ }
+
+ public static void main(String[] args) throws IOException {
+
+ // exercise default file type detector
+ Path file = createHtmlFile();
+ try {
+ String type = Files.probeContentType(file);
+ if (type == null) {
+ System.err.println("Content type cannot be determined - test skipped");
+ } else {
+ if (!type.equals("text/html"))
+ throw new RuntimeException("Unexpected type: " + type);
+ }
+ } finally {
+ Files.delete(file);
+ }
+
+ // exercise custom file type detector
+ file = createGrapeFile();
+ try {
+ String type = Files.probeContentType(file);
+ if (type == null)
+ throw new RuntimeException("Custom file type detector not installed?");
+ if (!type.equals("grape/unknown"))
+ throw new RuntimeException("Unexpected type: " + type);
+ } finally {
+ Files.delete(file);
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/ForceLoad.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Test library dependencies by invoking Files.probeContentType
+ * before other methods that would cause nio.dll to be loaded.
+ */
+
+import java.nio.file.*;
+import java.io.IOException;
+
+public class ForceLoad {
+
+ public static void main(String[] args) throws IOException {
+ Files.probeContentType(Paths.get("."));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/META-INF/services/java.nio.file.spi.FileTypeDetector Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,1 @@
+SimpleFileTypeDetector
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/SimpleFileTypeDetector.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.spi.FileTypeDetector;
+import java.io.*;
+
+
+public class SimpleFileTypeDetector extends FileTypeDetector {
+ public SimpleFileTypeDetector() {
+ }
+
+ public String probeContentType(Path file) throws IOException {
+ System.out.println("probe " + file + "...");
+ String name = file.toString();
+ return name.endsWith(".grape") ? "grape/unknown" : null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/CreateFileTree.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Creates a file tree with possible cycles caused by symbolic links
+ * to ancestor directories.
+ */
+
+public class CreateFileTree {
+
+ static final Random rand = new Random();
+
+ public static void main(String[] args) throws IOException {
+ Path top = Files.createTempDirectory("tree");
+ List<Path> dirs = new ArrayList<Path>();
+
+ // create tree
+ Queue<Path> queue = new ArrayDeque<Path>();
+ queue.add(top);
+ int total = 1 + rand.nextInt(20);
+ int n = 0;
+ Path dir;
+ while (((dir = queue.poll()) != null) && (n < total)) {
+ int r = Math.min((total-n), (1+rand.nextInt(3)));
+ for (int i=0; i<r; i++) {
+ String name = "dir" + (++n);
+ Path subdir = Files.createDirectory(dir.resolve(name));
+ queue.offer(subdir);
+ dirs.add(subdir);
+ }
+ }
+ assert dirs.size() >= 2;
+
+ // create a few regular files in the file tree
+ int files = dirs.size() * 3;
+ for (int i=0; i<files; i++) {
+ String name = "file" + (i+1);
+ int x = rand.nextInt(dirs.size());
+ Files.createFile(dirs.get(x).resolve(name));
+ }
+
+ // create a few sym links in the file tree so as to create cycles
+ int links = 1 + rand.nextInt(5);
+ for (int i=0; i<links; i++) {
+ int x = rand.nextInt(dirs.size());
+ int y;
+ do {
+ y = rand.nextInt(dirs.size());
+ } while (y != x);
+ String name = "link" + (i+1);
+ Path link = dirs.get(x).resolve(name);
+ Path target = dirs.get(y);
+ Files.createSymbolicLink(link, target);
+ }
+
+ // done
+ System.out.println(top);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/MaxDepth.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test maxDepth parameter
+ */
+
+public class MaxDepth {
+ public static void main(String[] args) throws Exception {
+ final Path top = Paths.get(args[0]);
+
+ for (int i=0; i<5; i++) {
+ Set<FileVisitOption> opts = Collections.emptySet();
+ final int maxDepth = i;
+ Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
+ // compute depth based on relative path to top directory
+ private int depth(Path file) {
+ Path rp = file.relativize(top);
+ return (rp.getFileName().toString().equals("")) ? 0 : rp.getNameCount();
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ int d = depth(dir);
+ if (d == maxDepth)
+ throw new RuntimeException("Should not open directories at maxDepth");
+ if (d > maxDepth)
+ throw new RuntimeException("Too deep");
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ int d = depth(file);
+ if (d > maxDepth)
+ throw new RuntimeException("Too deep");
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/Nulls.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6865748
+ * @summary Unit test for java.nio.file.Files.walkFileTree
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+import java.util.*;
+
+public class Nulls {
+
+ static void npeExpected() {
+ throw new RuntimeException("NullPointerException expected");
+ }
+
+ public static void main(String[] args) throws IOException {
+ try {
+ Files.walkFileTree(null, EnumSet.noneOf(FileVisitOption.class),
+ Integer.MAX_VALUE, new SimpleFileVisitor<Path>(){});
+ npeExpected();
+ } catch (NullPointerException e) {
+ }
+ try {
+ Files.walkFileTree(Paths.get("."), null, Integer.MAX_VALUE,
+ new SimpleFileVisitor<Path>(){});
+ npeExpected();
+ } catch (NullPointerException e) {
+ }
+ try {
+ Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
+ -1, new SimpleFileVisitor<Path>(){});
+ throw new RuntimeException("IllegalArgumentExpected expected");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ Set<FileVisitOption> opts = new HashSet<>(1);
+ opts.add(null);
+ Files.walkFileTree(Paths.get("."), opts, Integer.MAX_VALUE,
+ new SimpleFileVisitor<Path>(){});
+ npeExpected();
+ } catch (NullPointerException e) {
+ }
+ try {
+ Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
+ Integer.MAX_VALUE, null);
+ npeExpected();
+ } catch (NullPointerException e) {
+ }
+
+ SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
+ boolean ranTheGauntlet = false;
+ Path dir = Paths.get(".");
+ BasicFileAttributes attrs = Files.readAttributes(dir, BasicFileAttributes.class);
+
+ try { visitor.preVisitDirectory(null, attrs);
+ } catch (NullPointerException x0) {
+ try { visitor.preVisitDirectory(dir, null);
+ } catch (NullPointerException x1) {
+ try { visitor.visitFile(null, attrs);
+ } catch (NullPointerException x2) {
+ try { visitor.visitFile(dir, null);
+ } catch (NullPointerException x3) {
+ try { visitor.visitFileFailed(null, new IOException());
+ } catch (NullPointerException x4) {
+ try { visitor.visitFileFailed(dir, null);
+ } catch (NullPointerException x5) {
+ try { visitor.postVisitDirectory(null, new IOException());
+ } catch (NullPointerException x6) {
+ // if we get here then all visit* methods threw NPE as expected
+ ranTheGauntlet = true;
+ }}}}}}}
+ if (!ranTheGauntlet)
+ throw new RuntimeException("A visit method did not throw NPE");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/PrintFileTree.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Invokes Files.walkFileTree to traverse a file tree and prints
+ * each of the directories and files. The -follow option causes symbolic
+ * links to be followed and the -printCycles option will print links
+ * where the target of the link is an ancestor directory.
+ */
+
+public class PrintFileTree {
+
+ public static void main(String[] args) throws Exception {
+ boolean followLinks = false;
+ boolean printCycles = false;
+ int i = 0;
+ while (i < (args.length-1)) {
+ switch (args[i]) {
+ case "-follow" : followLinks = true; break;
+ case "-printCycles" : printCycles = true; break;
+ default:
+ throw new RuntimeException(args[i] + " not recognized");
+ }
+ i++;
+ }
+ Path dir = Paths.get(args[i]);
+
+ Set<FileVisitOption> options = new HashSet<FileVisitOption>();
+ if (followLinks)
+ options.add(FileVisitOption.FOLLOW_LINKS);
+
+ final boolean reportCycles = printCycles;
+ Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ System.out.println(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ if (!attrs.isDirectory() || reportCycles)
+ System.out.println(file);
+ return FileVisitResult.CONTINUE;
+ }
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+ throws IOException
+ {
+ if (exc != null)
+ throw exc;
+ return FileVisitResult.CONTINUE;
+ }
+ @Override
+ public FileVisitResult visitFileFailed(Path file, IOException exc)
+ throws IOException
+ {
+ if (reportCycles && (exc instanceof FileSystemLoopException)) {
+ System.out.println(file);
+ return FileVisitResult.CONTINUE;
+ }
+ throw exc;
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/SkipSiblings.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test SKIP_SIBLINGS return value.
+ */
+
+public class SkipSiblings {
+
+ static final Random rand = new Random();
+ static final Set<Path> skipped = new HashSet<Path>();
+
+ // check if this path's directory has been skipped
+ static void check(Path path) {
+ if (skipped.contains(path.getParent()))
+ throw new RuntimeException(path + " should not have been visited");
+ }
+
+ // indicates if the siblings of this path should be skipped
+ static boolean skip(Path path) {
+ Path parent = path.getParent();
+ if (parent != null && rand.nextBoolean()) {
+ skipped.add(parent);
+ return true;
+ }
+ return false;
+ }
+
+ public static void main(String[] args) throws Exception {
+ Path dir = Paths.get(args[0]);
+
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ check(dir);
+ if (skip(dir))
+ return FileVisitResult.SKIP_SIBLINGS;
+ return FileVisitResult.CONTINUE;
+ }
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ check(file);
+ if (skip(file))
+ return FileVisitResult.SKIP_SIBLINGS;
+ return FileVisitResult.CONTINUE;
+ }
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException x) {
+ if (x != null)
+ throw new RuntimeException(x);
+ check(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/TerminateWalk.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test TERMINATE return value
+ */
+
+public class TerminateWalk {
+
+ static final Random rand = new Random();
+ static boolean terminated;
+
+ static FileVisitResult maybeTerminate() {
+ if (terminated)
+ throw new RuntimeException("FileVisitor invoked after termination");
+ if (rand.nextInt(10) == 0) {
+ terminated = true;
+ return FileVisitResult.TERMINATE;
+ } else {
+ return FileVisitResult.CONTINUE;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ Path dir = Paths.get(args[0]);
+
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ return maybeTerminate();
+ }
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ return maybeTerminate();
+ }
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException x) {
+ return maybeTerminate();
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/WalkWithSecurity.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 6876541
+ * @summary Test Files.walkFileTree in the presence of a security manager
+ * @build WalkWithSecurity
+ * @run main/othervm WalkWithSecurity grantAll.policy pass
+ * @run main/othervm WalkWithSecurity denyAll.policy fail
+ * @run main/othervm WalkWithSecurity grantTopOnly.policy top_only
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+
+public class WalkWithSecurity {
+
+ public static void main(String[] args) throws IOException {
+ String policyFile = args[0];
+ ExpectedResult expectedResult = ExpectedResult.valueOf(args[1].toUpperCase());
+
+ String here = System.getProperty("user.dir");
+ String testSrc = System.getProperty("test.src");
+ if (testSrc == null)
+ throw new RuntimeException("This test must be run by jtreg");
+ Path dir = Paths.get(testSrc);
+
+ // Sanity check the environment
+ if (Files.isSameFile(Paths.get(here), dir))
+ throw new RuntimeException("Working directory cannot be " + dir);
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
+ if (!stream.iterator().hasNext())
+ throw new RuntimeException(testSrc + " is empty");
+ }
+
+ // Install security manager with the given policy file
+ System.setProperty("java.security.policy",
+ dir.resolve(policyFile).toString());
+ System.setSecurityManager(new SecurityManager());
+
+ // Walk the source tree
+ CountingVisitor visitor = new CountingVisitor();
+ SecurityException exception = null;
+ try {
+ Files.walkFileTree(dir, visitor);
+ } catch (SecurityException se) {
+ exception = se;
+ }
+
+ // Check result
+ switch (expectedResult) {
+ case PASS:
+ if (exception != null) {
+ exception.printStackTrace();
+ throw new RuntimeException("SecurityException not expected");
+ }
+ if (visitor.count() == 0)
+ throw new RuntimeException("No files visited");
+ break;
+ case FAIL:
+ if (exception == null)
+ throw new RuntimeException("SecurityException expected");
+ if (visitor.count() > 0)
+ throw new RuntimeException("Files were visited");
+ break;
+ case TOP_ONLY:
+ if (exception != null) {
+ exception.printStackTrace();
+ throw new RuntimeException("SecurityException not expected");
+ }
+ if (visitor.count() == 0)
+ throw new RuntimeException("Starting file not visited");
+ if (visitor.count() > 1)
+ throw new RuntimeException("More than starting file visited");
+ break;
+ default:
+ throw new RuntimeException("Should not get here");
+ }
+ }
+
+ static enum ExpectedResult {
+ PASS,
+ FAIL,
+ TOP_ONLY;
+ }
+
+ static class CountingVisitor extends SimpleFileVisitor<Path> {
+ private int count;
+
+ int count() {
+ return count;
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ System.out.println(dir);
+ count++;
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ System.out.println(file);
+ count++;
+ return FileVisitResult.CONTINUE;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/denyAll.policy Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,3 @@
+// policy file that does not grant any permissions
+grant {
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/grantAll.policy Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,5 @@
+// policy file that grants read access to source directory and all descendants
+grant {
+ permission java.io.FilePermission "${test.src}", "read";
+ permission java.io.FilePermission "${test.src}${file.separator}-", "read";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/grantTopOnly.policy Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,4 @@
+// policy file that grants read access to source directory
+grant {
+ permission java.io.FilePermission "${test.src}", "read";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/walk_file_tree.sh Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,98 @@
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 4313887 6907737
+# @summary Unit test for walkFileTree method
+# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
+# @run shell walk_file_tree.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+ TESTSRC=.
+ TESTCLASSES=.
+ JAVA=java
+else
+ JAVA="${TESTJAVA}/bin/java"
+fi
+
+OS=`uname -s`
+case "$OS" in
+ Windows_* | CYGWIN* )
+ echo "This test does not run on Windows"
+ exit 0
+ ;;
+ * )
+ CLASSPATH=${TESTCLASSES}:${TESTSRC}
+ ;;
+esac
+export CLASSPATH
+
+# create the file tree
+ROOT=`$JAVA CreateFileTree`
+if [ $? != 0 ]; then exit 1; fi
+
+failures=0
+
+# print the file tree and compare output with find(1)
+$JAVA PrintFileTree "$ROOT" > out1
+find "$ROOT" > out2
+diff out1 out2
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# repeat test following links. Some versions of find(1) output
+# cycles (sym links to ancestor directories), other versions do
+# not. For that reason we run PrintFileTree with the -printCycles
+# option when the output without this option differs to find(1).
+find "$ROOT" -follow > out1
+$JAVA PrintFileTree -follow "$ROOT" > out2
+diff out1 out2
+if [ $? != 0 ];
+ then
+ # re-run printing cycles to stdout
+ $JAVA PrintFileTree -follow -printCycles "$ROOT" > out2
+ diff out1 out2
+ if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+ fi
+
+# test SKIP_SIBLINGS
+$JAVA SkipSiblings "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# test TERMINATE
+$JAVA TerminateWalk "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# test maxDepth
+$JAVA MaxDepth "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# clean-up
+rm -r "$ROOT"
+
+echo ''
+if [ $failures -gt 0 ];
+ then echo "$failures test(s) failed";
+ else echo "Test passed"; fi
+exit $failures
--- a/jdk/test/java/nio/file/Files/walk_file_tree.sh Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-#
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 4313887 6907737
-# @summary Unit test for walkFileTree method
-# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
-# @run shell walk_file_tree.sh
-
-# if TESTJAVA isn't set then we assume an interactive run.
-
-if [ -z "$TESTJAVA" ]; then
- TESTSRC=.
- TESTCLASSES=.
- JAVA=java
-else
- JAVA="${TESTJAVA}/bin/java"
-fi
-
-OS=`uname -s`
-case "$OS" in
- Windows_* | CYGWIN* )
- echo "This test does not run on Windows"
- exit 0
- ;;
- * )
- CLASSPATH=${TESTCLASSES}:${TESTSRC}
- ;;
-esac
-export CLASSPATH
-
-# create the file tree
-ROOT=`$JAVA CreateFileTree`
-if [ $? != 0 ]; then exit 1; fi
-
-failures=0
-
-# print the file tree and compare output with find(1)
-$JAVA PrintFileTree "$ROOT" > out1
-find "$ROOT" > out2
-diff out1 out2
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# repeat test following links. Some versions of find(1) output
-# cycles (sym links to ancestor directories), other versions do
-# not. For that reason we run PrintFileTree with the -printCycles
-# option when the output without this option differs to find(1).
-find "$ROOT" -follow > out1
-$JAVA PrintFileTree -follow "$ROOT" > out2
-diff out1 out2
-if [ $? != 0 ];
- then
- # re-run printing cycles to stdout
- $JAVA PrintFileTree -follow -printCycles "$ROOT" > out2
- diff out1 out2
- if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
- fi
-
-# test SKIP_SIBLINGS
-$JAVA SkipSiblings "$ROOT"
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# test TERMINATE
-$JAVA TerminateWalk "$ROOT"
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# test maxDepth
-$JAVA MaxDepth "$ROOT"
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# clean-up
-rm -r "$ROOT"
-
-echo ''
-if [ $failures -gt 0 ];
- then echo "$failures test(s) failed";
- else echo "Test passed"; fi
-exit $failures
--- a/jdk/test/java/nio/file/Path/CheckPermissions.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,697 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 6866804
- * @summary Unit test for java.nio.file.Path
- * @library ..
- * @build CheckPermissions
- * @run main/othervm CheckPermissions
- */
-
-import java.nio.ByteBuffer;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.nio.channels.SeekableByteChannel;
-import java.security.Permission;
-import java.io.*;
-import java.util.*;
-
-/**
- * Checks each method that accesses the file system does the right permission
- * check when there is a security manager set.
- */
-
-public class CheckPermissions {
-
- static class Checks {
- private List<Permission> permissionsChecked = new ArrayList<Permission>();
- private Set<String> propertiesChecked = new HashSet<String>();
- private List<String> readsChecked = new ArrayList<String>();
- private List<String> writesChecked = new ArrayList<String>();
- private List<String> deletesChecked = new ArrayList<String>();
- private List<String> execsChecked = new ArrayList<String>();
-
- List<Permission> permissionsChecked() { return permissionsChecked; }
- Set<String> propertiesChecked() { return propertiesChecked; }
- List<String> readsChecked() { return readsChecked; }
- List<String> writesChecked() { return writesChecked; }
- List<String> deletesChecked() { return deletesChecked; }
- List<String> execsChecked() { return execsChecked; }
- }
-
- static ThreadLocal<Checks> myChecks =
- new ThreadLocal<Checks>() {
- @Override protected Checks initialValue() {
- return null;
- }
- };
-
- static void prepare() {
- myChecks.set(new Checks());
- }
-
- static void assertCheckPermission(Class<? extends Permission> type,
- String name)
- {
- for (Permission perm: myChecks.get().permissionsChecked()) {
- if (type.isInstance(perm) && perm.getName().equals(name))
- return;
- }
- throw new RuntimeException(type.getName() + "\"" + name + "\") not checked");
- }
-
- static void assertCheckPropertyAccess(String key) {
- if (!myChecks.get().propertiesChecked().contains(key))
- throw new RuntimeException("Property " + key + " not checked");
- }
-
- static void assertChecked(Path file, List<String> list) {
- String s = file.toString();
- for (String f: list) {
- if (f.endsWith(s))
- return;
- }
- throw new RuntimeException("Access not checked");
- }
-
- static void assertCheckRead(Path file) {
- assertChecked(file, myChecks.get().readsChecked());
- }
-
- static void assertCheckWrite(Path file) {
- assertChecked(file, myChecks.get().writesChecked());
- }
-
- static void assertCheckDelete(Path file) {
- assertChecked(file, myChecks.get().deletesChecked());
- }
-
- static void assertCheckExec(Path file) {
- assertChecked(file, myChecks.get().execsChecked());
- }
-
- static class LoggingSecurityManager extends SecurityManager {
- static void install() {
- System.setSecurityManager(new LoggingSecurityManager());
- }
-
- @Override
- public void checkPermission(Permission perm) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.permissionsChecked().add(perm);
- }
-
- @Override
- public void checkPropertyAccess(String key) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.propertiesChecked().add(key);
- }
-
- @Override
- public void checkRead(String file) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.readsChecked().add(file);
- }
-
- @Override
- public void checkWrite(String file) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.writesChecked().add(file);
- }
-
- @Override
- public void checkDelete(String file) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.deletesChecked().add(file);
- }
-
- @Override
- public void checkExec(String file) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.execsChecked().add(file);
- }
- }
-
- static void testBasicFileAttributeView(BasicFileAttributeView view, Path file)
- throws IOException
- {
- prepare();
- view.readAttributes();
- assertCheckRead(file);
-
- prepare();
- FileTime now = FileTime.fromMillis(System.currentTimeMillis());
- view.setTimes(null, now, now);
- assertCheckWrite(file);
- }
-
- static void testPosixFileAttributeView(PosixFileAttributeView view, Path file)
- throws IOException
- {
- prepare();
- PosixFileAttributes attrs = view.readAttributes();
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
- prepare();
- view.setPermissions(attrs.permissions());
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
- prepare();
- view.setOwner(attrs.owner());
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
- prepare();
- view.setOwner(attrs.owner());
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
- }
-
- public static void main(String[] args) throws IOException {
- Path dir = Paths.get(System.getProperty("test.dir", "."));
- Path file = dir.resolve("file1234").createFile();
- try {
- LoggingSecurityManager.install();
-
- // -- checkAccess --
-
- prepare();
- file.checkAccess();
- assertCheckRead(file);
-
- prepare();
- file.checkAccess(AccessMode.READ);
- assertCheckRead(file);
-
- prepare();
- file.checkAccess(AccessMode.WRITE);
- assertCheckWrite(file);
-
- prepare();
- try {
- file.checkAccess(AccessMode.EXECUTE);
- } catch (AccessDeniedException x) { }
- assertCheckExec(file);
-
- prepare();
- try {
- file.checkAccess(AccessMode.READ, AccessMode.WRITE, AccessMode.EXECUTE);
- } catch (AccessDeniedException x) { }
- assertCheckRead(file);
- assertCheckWrite(file);
- assertCheckExec(file);
-
- // -- copyTo --
-
- Path target = dir.resolve("target1234");
- prepare();
- file.copyTo(target);
- try {
- assertCheckRead(file);
- assertCheckWrite(target);
- } finally {
- target.delete();
- }
-
- if (TestUtil.supportsLinks(dir)) {
- Path link = dir.resolve("link1234").createSymbolicLink(file);
- try {
- prepare();
- link.copyTo(target, LinkOption.NOFOLLOW_LINKS);
- try {
- assertCheckRead(link);
- assertCheckWrite(target);
- assertCheckPermission(LinkPermission.class, "symbolic");
- } finally {
- target.delete();
- }
- } finally {
- link.delete();
- }
- }
-
- // -- createDirectory --
-
- Path subdir = dir.resolve("subdir1234");
- prepare();
- subdir.createDirectory();
- try {
- assertCheckWrite(subdir);
- } finally {
- subdir.delete();
- }
-
- // -- createFile --
-
- Path fileToCreate = dir.resolve("file7890");
- prepare();
- try {
- fileToCreate.createFile();
- assertCheckWrite(fileToCreate);
- } finally {
- fileToCreate.delete();
- }
-
- // -- createSymbolicLink --
-
- if (TestUtil.supportsLinks(dir)) {
- prepare();
- Path link = dir.resolve("link1234").createSymbolicLink(file);
- try {
- assertCheckWrite(link);
- assertCheckPermission(LinkPermission.class, "symbolic");
- } finally {
- link.delete();
- }
- }
-
- // -- delete/deleteIfExists --
-
- Path fileToDelete = dir.resolve("file7890");
-
- fileToDelete.createFile();
- prepare();
- fileToDelete.delete();
- assertCheckDelete(fileToDelete);
-
- fileToDelete.createFile();
- prepare();
- fileToDelete.deleteIfExists();
- assertCheckDelete(fileToDelete);
-
- // -- exists/notExists --
-
- prepare();
- file.exists();
- assertCheckRead(file);
-
- prepare();
- file.notExists();
- assertCheckRead(file);
-
- // -- getFileStore --
-
- prepare();
- file.getFileStore();
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes");
-
- // -- isSameFile --
-
- prepare();
- file.isSameFile(dir);
- assertCheckRead(file);
- assertCheckRead(dir);
-
- // -- moveTo --
-
- Path target2 = dir.resolve("target1234");
- prepare();
- file.moveTo(target2);
- try {
- assertCheckWrite(file);
- assertCheckWrite(target2);
- } finally {
- // restore file
- target2.moveTo(file);
- }
-
- // -- newByteChannel --
-
- SeekableByteChannel sbc;
-
- prepare();
- sbc = file.newByteChannel();
- try {
- assertCheckRead(file);
- } finally {
- sbc.close();
- }
- prepare();
- sbc = file.newByteChannel(StandardOpenOption.WRITE);
- try {
- assertCheckWrite(file);
- } finally {
- sbc.close();
- }
- prepare();
- sbc = file.newByteChannel(StandardOpenOption.READ, StandardOpenOption.WRITE);
- try {
- assertCheckRead(file);
- assertCheckWrite(file);
- } finally {
- sbc.close();
- }
-
- prepare();
- sbc = file.newByteChannel(StandardOpenOption.DELETE_ON_CLOSE);
- try {
- assertCheckRead(file);
- assertCheckDelete(file);
- } finally {
- sbc.close();
- }
- file.createFile(); // restore file
-
-
- // -- newInputStream/newOutptuStream --
-
- prepare();
- InputStream in = file.newInputStream();
- try {
- assertCheckRead(file);
- } finally {
- in.close();
- }
- prepare();
- OutputStream out = file.newOutputStream();
- try {
- assertCheckWrite(file);
- } finally {
- out.close();
- }
-
- // -- newDirectoryStream --
-
- prepare();
- DirectoryStream<Path> stream = dir.newDirectoryStream();
- try {
- assertCheckRead(dir);
-
- if (stream instanceof SecureDirectoryStream<?>) {
- Path entry;
- SecureDirectoryStream<Path> sds =
- (SecureDirectoryStream<Path>)stream;
-
- // newByteChannel
- entry = file.getName();
- prepare();
- sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.READ));
- try {
- assertCheckRead(file);
- } finally {
- sbc.close();
- }
- prepare();
- sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.WRITE));
- try {
- assertCheckWrite(file);
- } finally {
- sbc.close();
- }
-
- // deleteFile
- entry = file.getName();
- prepare();
- sds.deleteFile(entry);
- assertCheckDelete(file);
- dir.resolve(entry).createFile(); // restore file
-
- // deleteDirectory
- entry = Paths.get("subdir1234");
- dir.resolve(entry).createDirectory();
- prepare();
- sds.deleteDirectory(entry);
- assertCheckDelete(dir.resolve(entry));
-
- // move
- entry = Paths.get("tempname1234");
- prepare();
- sds.move(file.getName(), sds, entry);
- assertCheckWrite(file);
- assertCheckWrite(dir.resolve(entry));
- sds.move(entry, sds, file.getName()); // restore file
-
- // newDirectoryStream
- entry = Paths.get("subdir1234");
- dir.resolve(entry).createDirectory();
- try {
- prepare();
- sds.newDirectoryStream(entry).close();
- assertCheckRead(dir.resolve(entry));
- } finally {
- dir.resolve(entry).delete();
- }
-
- // getFileAttributeView to access attributes of directory
- testBasicFileAttributeView(sds
- .getFileAttributeView(BasicFileAttributeView.class), dir);
- testPosixFileAttributeView(sds
- .getFileAttributeView(PosixFileAttributeView.class), dir);
-
- // getFileAttributeView to access attributes of entry
- entry = file.getName();
- testBasicFileAttributeView(sds
- .getFileAttributeView(entry, BasicFileAttributeView.class), file);
- testPosixFileAttributeView(sds
- .getFileAttributeView(entry, PosixFileAttributeView.class), file);
-
- } else {
- System.out.println("SecureDirectoryStream not tested");
- }
-
- } finally {
- stream.close();
- }
-
- // -- toAbsolutePath --
-
- prepare();
- file.getName().toAbsolutePath();
- assertCheckPropertyAccess("user.dir");
-
- // -- toRealPath --
-
- prepare();
- file.toRealPath(true);
- assertCheckRead(file);
-
- prepare();
- file.toRealPath(false);
- assertCheckRead(file);
-
- prepare();
- Paths.get(".").toRealPath(true);
- assertCheckPropertyAccess("user.dir");
-
- prepare();
- Paths.get(".").toRealPath(false);
- assertCheckPropertyAccess("user.dir");
-
- // -- register --
-
- WatchService watcher = FileSystems.getDefault().newWatchService();
- try {
- prepare();
- dir.register(watcher, StandardWatchEventKind.ENTRY_DELETE);
- assertCheckRead(dir);
- } finally {
- watcher.close();
- }
-
- // -- getAttribute/setAttribute/readAttributes --
-
- prepare();
- file.getAttribute("size");
- assertCheckRead(file);
-
- prepare();
- file.setAttribute("lastModifiedTime",
- FileTime.fromMillis(System.currentTimeMillis()));
- assertCheckWrite(file);
-
- prepare();
- file.readAttributes("*");
- assertCheckRead(file);
-
- // -- BasicFileAttributeView --
- testBasicFileAttributeView(file
- .getFileAttributeView(BasicFileAttributeView.class), file);
-
- // -- PosixFileAttributeView --
-
- {
- PosixFileAttributeView view =
- file.getFileAttributeView(PosixFileAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView(PosixFileAttributeView.class))
- {
- testPosixFileAttributeView(view, file);
- } else {
- System.out.println("PosixFileAttributeView not tested");
- }
- }
-
- // -- DosFileAttributeView --
-
- {
- DosFileAttributeView view =
- file.getFileAttributeView(DosFileAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView(DosFileAttributeView.class))
- {
- prepare();
- view.readAttributes();
- assertCheckRead(file);
-
- prepare();
- view.setArchive(false);
- assertCheckWrite(file);
-
- prepare();
- view.setHidden(false);
- assertCheckWrite(file);
-
- prepare();
- view.setReadOnly(false);
- assertCheckWrite(file);
-
- prepare();
- view.setSystem(false);
- assertCheckWrite(file);
- } else {
- System.out.println("DosFileAttributeView not tested");
- }
- }
-
- // -- FileOwnerAttributeView --
-
- {
- FileOwnerAttributeView view =
- file.getFileAttributeView(FileOwnerAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView(FileOwnerAttributeView.class))
- {
- prepare();
- UserPrincipal owner = view.getOwner();
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
- prepare();
- view.setOwner(owner);
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
- } else {
- System.out.println("FileOwnerAttributeView not tested");
- }
- }
-
- // -- UserDefinedFileAttributeView --
-
- {
- UserDefinedFileAttributeView view =
- file.getFileAttributeView(UserDefinedFileAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView(UserDefinedFileAttributeView.class))
- {
- prepare();
- view.write("test", ByteBuffer.wrap(new byte[100]));
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class,
- "accessUserDefinedAttributes");
-
- prepare();
- view.read("test", ByteBuffer.allocate(100));
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class,
- "accessUserDefinedAttributes");
-
- prepare();
- view.size("test");
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class,
- "accessUserDefinedAttributes");
-
- prepare();
- view.list();
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class,
- "accessUserDefinedAttributes");
-
- prepare();
- view.delete("test");
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class,
- "accessUserDefinedAttributes");
- } else {
- System.out.println("UserDefinedFileAttributeView not tested");
- }
- }
-
- // -- AclFileAttributeView --
- {
- AclFileAttributeView view =
- file.getFileAttributeView(AclFileAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView(AclFileAttributeView.class))
- {
- prepare();
- List<AclEntry> acl = view.getAcl();
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
- prepare();
- view.setAcl(acl);
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
- } else {
- System.out.println("AclFileAttributeView not tested");
- }
- }
-
- // -- UserPrincipalLookupService
-
- UserPrincipalLookupService lookupService =
- FileSystems.getDefault().getUserPrincipalLookupService();
- UserPrincipal owner = Attributes.getOwner(file);
-
- prepare();
- lookupService.lookupPrincipalByName(owner.getName());
- assertCheckPermission(RuntimePermission.class,
- "lookupUserInformation");
-
- try {
- UserPrincipal group = Attributes.readPosixFileAttributes(file).group();
- prepare();
- lookupService.lookupPrincipalByGroupName(group.getName());
- assertCheckPermission(RuntimePermission.class,
- "lookupUserInformation");
- } catch (UnsupportedOperationException ignore) {
- System.out.println("lookupPrincipalByGroupName not tested");
- }
-
-
- } finally {
- file.deleteIfExists();
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/CopyAndMove.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1006 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333 6917021
- * @summary Unit test for java.nio.file.Path copyTo/moveTo methods
- * @library ..
- * @build CopyAndMove PassThroughFileSystem
- * @run main/othervm CopyAndMove
- */
-
-import java.nio.ByteBuffer;
-import java.nio.file.*;
-import static java.nio.file.StandardCopyOption.*;
-import static java.nio.file.LinkOption.*;
-import java.nio.file.attribute.*;
-import java.io.*;
-import java.util.*;
-
-public class CopyAndMove {
- static final Random rand = new Random();
- static boolean heads() { return rand.nextBoolean(); }
-
- public static void main(String[] args) throws Exception {
- Path dir1 = TestUtil.createTemporaryDirectory();
- try {
- // Same directory
- doCopyTests(dir1, dir1, TestUtil.supportsLinks(dir1));
- doMoveTests(dir1, dir1, TestUtil.supportsLinks(dir1));
-
- // Different directories. Use test.dir if possible as it might be
- // a different volume/file system and so improve test coverage.
- String testDir = System.getProperty("test.dir", ".");
- Path dir2 = TestUtil.createTemporaryDirectory(testDir);
- try {
- boolean testSymbolicLinks =
- TestUtil.supportsLinks(dir1) && TestUtil.supportsLinks(dir2);
- doCopyTests(dir1, dir2, testSymbolicLinks);
- doMoveTests(dir1, dir2, testSymbolicLinks);
- } finally {
- TestUtil.removeAll(dir2);
- }
-
- // Target is location associated with custom provider
- Path dir3 = PassThroughFileSystem.create().getPath(dir1.toString());
- doCopyTests(dir1, dir3, false);
- doMoveTests(dir1, dir3, false);
-
- } finally {
- TestUtil.removeAll(dir1);
- }
- }
-
- static void checkBasicAttributes(BasicFileAttributes attrs1,
- BasicFileAttributes attrs2)
- {
- // check file type
- assertTrue(attrs1.isRegularFile() == attrs2.isRegularFile());
- assertTrue(attrs1.isDirectory() == attrs2.isDirectory());
- assertTrue(attrs1.isSymbolicLink() == attrs2.isSymbolicLink());
- assertTrue(attrs1.isOther() == attrs2.isOther());
-
- // check last modified time
- long time1 = attrs1.lastModifiedTime().toMillis();
- long time2 = attrs2.lastModifiedTime().toMillis();
- assertTrue(time1 == time2);
-
- // check size
- if (attrs1.isRegularFile())
- assertTrue(attrs1.size() == attrs2.size());
- }
-
- static void checkPosixAttributes(PosixFileAttributes attrs1,
- PosixFileAttributes attrs2)
- {
- assertTrue(attrs1.permissions().equals(attrs2.permissions()));
- assertTrue(attrs1.owner().equals(attrs2.owner()));
- assertTrue(attrs1.group().equals(attrs2.group()));
- }
-
- static void checkDosAttributes(DosFileAttributes attrs1,
- DosFileAttributes attrs2)
- {
- assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly());
- assertTrue(attrs1.isHidden() == attrs2.isHidden());
- assertTrue(attrs1.isSystem() == attrs2.isSystem());
- }
-
- static void checkUserDefinedFileAttributes(Map<String,ByteBuffer> attrs1,
- Map<String,ByteBuffer> attrs2)
- {
- assert attrs1.size() == attrs2.size();
- for (String name: attrs1.keySet()) {
- ByteBuffer bb1 = attrs1.get(name);
- ByteBuffer bb2 = attrs2.get(name);
- assertTrue(bb2 != null);
- assertTrue(bb1.equals(bb2));
- }
- }
-
- static Map<String,ByteBuffer> readUserDefinedFileAttributes(Path file)
- throws IOException
- {
- UserDefinedFileAttributeView view = file
- .getFileAttributeView(UserDefinedFileAttributeView.class);
- Map<String,ByteBuffer> result = new HashMap<String,ByteBuffer>();
- for (String name: view.list()) {
- int size = view.size(name);
- ByteBuffer bb = ByteBuffer.allocate(size);
- int n = view.read(name, bb);
- assertTrue(n == size);
- bb.flip();
- result.put(name, bb);
- }
- return result;
- }
-
- // move source to target with verification
- static void moveAndVerify(Path source, Path target, CopyOption... options)
- throws IOException
- {
- // read attributes before file is moved
- BasicFileAttributes basicAttributes = null;
- PosixFileAttributes posixAttributes = null;
- DosFileAttributes dosAttributes = null;
- Map<String,ByteBuffer> namedAttributes = null;
-
- // get file attributes of source file
- String os = System.getProperty("os.name");
- if (os.equals("SunOS") || os.equals("Linux")) {
- posixAttributes = Attributes.readPosixFileAttributes(source, NOFOLLOW_LINKS);
- basicAttributes = posixAttributes;
- }
- if (os.startsWith("Windows")) {
- dosAttributes = Attributes.readDosFileAttributes(source, NOFOLLOW_LINKS);
- basicAttributes = dosAttributes;
- }
- if (basicAttributes == null)
- basicAttributes = Attributes.readBasicFileAttributes(source, NOFOLLOW_LINKS);
-
- // hash file contents if regular file
- int hash = (basicAttributes.isRegularFile()) ? computeHash(source) : 0;
-
- // record link target if symbolic link
- Path linkTarget = null;
- if (basicAttributes.isSymbolicLink())
- linkTarget = source.readSymbolicLink();
-
- // read named attributes if available (and file is not a sym link)
- if (!basicAttributes.isSymbolicLink() &&
- source.getFileStore().supportsFileAttributeView("xattr"))
- {
- namedAttributes = readUserDefinedFileAttributes(source);
- }
-
- // move file
- source.moveTo(target, options);
-
- // verify source does not exist
- assertTrue(source.notExists());
-
- // verify file contents
- if (basicAttributes.isRegularFile()) {
- if (computeHash(target) != hash)
- throw new RuntimeException("Failed to verify move of regular file");
- }
-
- // verify link target
- if (basicAttributes.isSymbolicLink()) {
- if (!target.readSymbolicLink().equals(linkTarget))
- throw new RuntimeException("Failed to verify move of symbolic link");
- }
-
- // verify basic attributes
- checkBasicAttributes(basicAttributes,
- Attributes.readBasicFileAttributes(target, NOFOLLOW_LINKS));
-
- // verify other attributes when same provider
- if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
-
- // verify POSIX attributes
- if (posixAttributes != null && !basicAttributes.isSymbolicLink()) {
- checkPosixAttributes(posixAttributes,
- Attributes.readPosixFileAttributes(target, NOFOLLOW_LINKS));
- }
-
- // verify DOS attributes
- if (dosAttributes != null && !basicAttributes.isSymbolicLink()) {
- checkDosAttributes(dosAttributes,
- Attributes.readDosFileAttributes(target, NOFOLLOW_LINKS));
- }
-
- // verify named attributes
- if (namedAttributes != null &&
- target.getFileStore().supportsFileAttributeView("xattr"))
- {
- checkUserDefinedFileAttributes(namedAttributes,
- readUserDefinedFileAttributes(target));
- }
- }
- }
-
- /**
- * Tests all possible ways to invoke moveTo
- */
- static void doMoveTests(Path dir1, Path dir2, boolean supportsLinks)
- throws IOException
- {
- Path source, target, entry;
-
- boolean sameDevice = dir1.getFileStore().equals(dir2.getFileStore());
-
- // -- regular file --
-
- /**
- * Test: move regular file, target does not exist
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- moveAndVerify(source, target);
- target.delete();
-
- /**
- * Test: move regular file, target exists
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createFile();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- target.delete();
- target.createDirectory();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- source.delete();
- target.delete();
-
- /**
- * Test: move regular file, target does not exist
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move regular file, target exists
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createFile();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move regular file, target exists and is empty directory
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createDirectory();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move regular file, target exists and is non-empty directory
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createDirectory();
- entry = target.resolve("foo").createFile();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- entry.delete();
- source.delete();
- target.delete();
-
- /**
- * Test atomic move of regular file (same file store)
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir1);
- moveAndVerify(source, target, ATOMIC_MOVE);
- target.delete();
-
- /**
- * Test atomic move of regular file (different file store)
- */
- if (!sameDevice) {
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- try {
- moveAndVerify(source, target, ATOMIC_MOVE);
- throw new RuntimeException("AtomicMoveNotSupportedException expected");
- } catch (AtomicMoveNotSupportedException x) {
- }
- source.delete();
- }
-
- // -- directories --
-
- /*
- * Test: move empty directory, target does not exist
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2);
- moveAndVerify(source, target);
- target.delete();
-
- /**
- * Test: move empty directory, target exists
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createFile();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- target.delete();
- target.createDirectory();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- source.delete();
- target.delete();
-
- /**
- * Test: move empty directory, target does not exist
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2);
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move empty directory, target exists
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createFile();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move empty, target exists and is empty directory
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createDirectory();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move empty directory, target exists and is non-empty directory
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createDirectory();
- entry = target.resolve("foo").createFile();
- try {
- moveAndVerify(source, target, REPLACE_EXISTING);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- entry.delete();
- source.delete();
- target.delete();
-
- /**
- * Test: move non-empty directory (same file system)
- */
- source = createSourceDirectory(dir1);
- source.resolve("foo").createFile();
- target = getTargetFile(dir1);
- moveAndVerify(source, target);
- target.resolve("foo").delete();
- target.delete();
-
- /**
- * Test: move non-empty directory (different file store)
- */
- if (!sameDevice) {
- source = createSourceDirectory(dir1);
- source.resolve("foo").createFile();
- target = getTargetFile(dir2);
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("IOException expected");
- } catch (IOException x) {
- }
- source.resolve("foo").delete();
- source.delete();
- }
-
- /**
- * Test atomic move of directory (same file store)
- */
- source = createSourceDirectory(dir1);
- source.resolve("foo").createFile();
- target = getTargetFile(dir1);
- moveAndVerify(source, target, ATOMIC_MOVE);
- target.resolve("foo").delete();
- target.delete();
-
- // -- symbolic links --
-
- /**
- * Test: Move symbolic link to file, target does not exist
- */
- if (supportsLinks) {
- Path tmp = createSourceFile(dir1);
- source = dir1.resolve("link").createSymbolicLink(tmp);
- target = getTargetFile(dir2);
- moveAndVerify(source, target);
- target.delete();
- tmp.delete();
- }
-
- /**
- * Test: Move symbolic link to directory, target does not exist
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir2);
- target = getTargetFile(dir2);
- moveAndVerify(source, target);
- target.delete();
- }
-
- /**
- * Test: Move broken symbolic link, target does not exists
- */
- if (supportsLinks) {
- Path tmp = Paths.get("doesnotexist");
- source = dir1.resolve("link").createSymbolicLink(tmp);
- target = getTargetFile(dir2);
- moveAndVerify(source, target);
- target.delete();
- }
-
- /**
- * Test: Move symbolic link, target exists
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir2);
- target = getTargetFile(dir2).createFile();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- source.delete();
- target.delete();
- }
-
- /**
- * Test: Move regular file, target exists
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir2);
- target = getTargetFile(dir2).createFile();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
- }
-
- /**
- * Test: move symbolic link, target exists and is empty directory
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir2);
- target = getTargetFile(dir2).createDirectory();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
- }
-
- /**
- * Test: symbolic link, target exists and is non-empty directory
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir2);
- target = getTargetFile(dir2).createDirectory();
- entry = target.resolve("foo").createFile();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- entry.delete();
- source.delete();
- target.delete();
- }
-
- /**
- * Test atomic move of symbolic link (same file store)
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir1);
- target = getTargetFile(dir2).createFile();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
- }
-
- // -- misc. tests --
-
- /**
- * Test nulls
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- try {
- source.moveTo(null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- try {
- source.moveTo(target, (CopyOption[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- try {
- CopyOption[] opts = { REPLACE_EXISTING, null };
- source.moveTo(target, opts);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- source.delete();
-
- /**
- * Test UOE
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- try {
- source.moveTo(target, new CopyOption() { });
- } catch (UnsupportedOperationException x) { }
- try {
- source.moveTo(target, REPLACE_EXISTING, new CopyOption() { });
- } catch (UnsupportedOperationException x) { }
- source.delete();
- }
-
- // copy source to target with verification
- static void copyAndVerify(Path source, Path target, CopyOption... options)
- throws IOException
- {
- source.copyTo(target, options);
-
- // get attributes of source and target file to verify copy
- boolean followLinks = true;
- LinkOption[] linkOptions = new LinkOption[0];
- boolean copyAttributes = false;
- for (CopyOption opt : options) {
- if (opt == NOFOLLOW_LINKS) {
- followLinks = false;
- linkOptions = new LinkOption[] { NOFOLLOW_LINKS };
- }
- if (opt == COPY_ATTRIBUTES)
- copyAttributes = true;
- }
- BasicFileAttributes basicAttributes = Attributes
- .readBasicFileAttributes(source, linkOptions);
-
- // check hash if regular file
- if (basicAttributes.isRegularFile())
- assertTrue(computeHash(source) == computeHash(target));
-
- // check link target if symbolic link
- if (basicAttributes.isSymbolicLink())
- assert( source.readSymbolicLink().equals(target.readSymbolicLink()));
-
- // check that attributes are copied
- if (copyAttributes && followLinks) {
- checkBasicAttributes(basicAttributes,
- Attributes.readBasicFileAttributes(source, linkOptions));
-
- // verify other attributes when same provider
- if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
-
- // check POSIX attributes are copied
- String os = System.getProperty("os.name");
- if (os.equals("SunOS") || os.equals("Linux")) {
- checkPosixAttributes(
- Attributes.readPosixFileAttributes(source, linkOptions),
- Attributes.readPosixFileAttributes(target, linkOptions));
- }
-
- // check DOS attributes are copied
- if (os.startsWith("Windows")) {
- checkDosAttributes(
- Attributes.readDosFileAttributes(source, linkOptions),
- Attributes.readDosFileAttributes(target, linkOptions));
- }
-
- // check named attributes are copied
- if (followLinks &&
- source.getFileStore().supportsFileAttributeView("xattr") &&
- target.getFileStore().supportsFileAttributeView("xattr"))
- {
- checkUserDefinedFileAttributes(readUserDefinedFileAttributes(source),
- readUserDefinedFileAttributes(target));
- }
- }
- }
- }
-
- /**
- * Tests all possible ways to invoke copyTo
- */
- static void doCopyTests(Path dir1, Path dir2, boolean supportsLinks)
- throws IOException
- {
- Path source, target, link, entry;
-
- // -- regular file --
-
- /**
- * Test: move regular file, target does not exist
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target);
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file, target exists
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createFile();
- try {
- copyAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- target.delete();
- target.createDirectory();
- try {
- copyAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file, target does not exist
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file, target exists
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createFile();
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file, target exists and is empty directory
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createDirectory();
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file, target exists and is non-empty directory
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createDirectory();
- entry = target.resolve("foo").createFile();
- try {
- copyAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- entry.delete();
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file + attributes
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target, COPY_ATTRIBUTES);
- source.delete();
- target.delete();
-
-
- // -- directory --
-
- /*
- * Test: copy directory, target does not exist
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target);
- source.delete();
- target.delete();
-
- /**
- * Test: copy directory, target exists
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createFile();
- try {
- copyAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- target.delete();
- target.createDirectory();
- try {
- copyAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- source.delete();
- target.delete();
-
- /**
- * Test: copy directory, target does not exist
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy directory, target exists
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createFile();
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy directory, target exists and is empty directory
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createDirectory();
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy directory, target exists and is non-empty directory
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createDirectory();
- entry = target.resolve("foo").createFile();
- try {
- copyAndVerify(source, target, REPLACE_EXISTING);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- entry.delete();
- source.delete();
- target.delete();
-
- /*
- * Test: copy directory + attributes
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target, COPY_ATTRIBUTES);
- source.delete();
- target.delete();
-
- // -- symbolic links --
-
- /**
- * Test: Follow link
- */
- if (supportsLinks) {
- source = createSourceFile(dir1);
- link = dir1.resolve("link").createSymbolicLink(source);
- target = getTargetFile(dir2);
- copyAndVerify(link, target);
- link.delete();
- source.delete();
- }
-
- /**
- * Test: Copy link (to file)
- */
- if (supportsLinks) {
- source = createSourceFile(dir1);
- link = dir1.resolve("link").createSymbolicLink(source);
- target = getTargetFile(dir2);
- copyAndVerify(link, target, NOFOLLOW_LINKS);
- link.delete();
- source.delete();
- }
-
- /**
- * Test: Copy link (to directory)
- */
- if (supportsLinks) {
- source = dir1.resolve("mydir").createDirectory();
- link = dir1.resolve("link").createSymbolicLink(source);
- target = getTargetFile(dir2);
- copyAndVerify(link, target, NOFOLLOW_LINKS);
- link.delete();
- source.delete();
- }
-
- /**
- * Test: Copy broken link
- */
- if (supportsLinks) {
- assertTrue(source.notExists());
- link = dir1.resolve("link").createSymbolicLink(source);
- target = getTargetFile(dir2);
- copyAndVerify(link, target, NOFOLLOW_LINKS);
- link.delete();
- }
-
- /**
- * Test: Copy link to UNC (Windows only)
- */
- if (supportsLinks &&
- System.getProperty("os.name").startsWith("Windows"))
- {
- Path unc = Paths.get("\\\\rialto\\share\\file");
- link = dir1.resolve("link").createSymbolicLink(unc);
- target = getTargetFile(dir2);
- copyAndVerify(link, target, NOFOLLOW_LINKS);
- link.delete();
- }
-
- // -- misc. tests --
-
- /**
- * Test nulls
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- try {
- source.copyTo(null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- try {
- source.copyTo(target, (CopyOption[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- try {
- CopyOption[] opts = { REPLACE_EXISTING, null };
- source.copyTo(target, opts);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- source.delete();
-
- /**
- * Test UOE
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- try {
- source.copyTo(target, new CopyOption() { });
- } catch (UnsupportedOperationException x) { }
- try {
- source.copyTo(target, REPLACE_EXISTING, new CopyOption() { });
- } catch (UnsupportedOperationException x) { }
- source.delete();
- }
-
-
- static void assertTrue(boolean value) {
- if (!value)
- throw new RuntimeException("Assertion failed");
- }
-
- // computes simple hash of the given file
- static int computeHash(Path file) throws IOException {
- int h = 0;
-
- InputStream in = file.newInputStream();
- try {
- byte[] buf = new byte[1024];
- int n;
- do {
- n = in.read(buf);
- for (int i=0; i<n; i++) {
- h = 31*h + (buf[i] & 0xff);
- }
- } while (n > 0);
- } finally {
- in.close();
- }
- return h;
- }
-
- // create file of random size in given directory
- static Path createSourceFile(Path dir) throws IOException {
- String name = "source" + Integer.toString(rand.nextInt());
- Path file = dir.resolve(name).createFile();
- byte[] bytes = new byte[rand.nextInt(128*1024)];
- rand.nextBytes(bytes);
- OutputStream out = file.newOutputStream();
- try {
- out.write(bytes);
- } finally {
- out.close();
- }
- randomizeAttributes(file);
- return file;
- }
-
- // create directory in the given directory
- static Path createSourceDirectory(Path dir) throws IOException {
- String name = "sourcedir" + Integer.toString(rand.nextInt());
- Path subdir = dir.resolve(name).createDirectory();
- randomizeAttributes(subdir);
- return subdir;
- }
-
- // "randomize" the file attributes of the given file.
- static void randomizeAttributes(Path file) throws IOException {
- String os = System.getProperty("os.name");
- boolean isWindows = os.startsWith("Windows");
- boolean isUnix = os.equals("SunOS") || os.equals("Linux");
- boolean isDirectory = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS)
- .isDirectory();
-
- if (isUnix) {
- Set<PosixFilePermission> perms = Attributes
- .readPosixFileAttributes(file, NOFOLLOW_LINKS).permissions();
- PosixFilePermission[] toChange = {
- PosixFilePermission.GROUP_READ,
- PosixFilePermission.GROUP_WRITE,
- PosixFilePermission.GROUP_EXECUTE,
- PosixFilePermission.OTHERS_READ,
- PosixFilePermission.OTHERS_WRITE,
- PosixFilePermission.OTHERS_EXECUTE
- };
- for (PosixFilePermission perm: toChange) {
- if (heads()) {
- perms.add(perm);
- } else {
- perms.remove(perm);
- }
- }
- Attributes.setPosixFilePermissions(file, perms);
- }
-
- if (isWindows) {
- DosFileAttributeView view = file
- .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS);
- // only set or unset the hidden attribute
- view.setHidden(heads());
- }
-
- boolean addUserDefinedFileAttributes = heads() &&
- file.getFileStore().supportsFileAttributeView("xattr");
-
- // remove this when copying a direcory copies its named streams
- if (isWindows && isDirectory) addUserDefinedFileAttributes = false;
-
- if (addUserDefinedFileAttributes) {
- UserDefinedFileAttributeView view = file
- .getFileAttributeView(UserDefinedFileAttributeView.class);
- int n = rand.nextInt(16);
- while (n > 0) {
- byte[] value = new byte[1 + rand.nextInt(100)];
- view.write("user." + Integer.toString(n), ByteBuffer.wrap(value));
- n--;
- }
- }
- }
-
- // create name for file in given directory
- static Path getTargetFile(Path dir) throws IOException {
- String name = "target" + Integer.toString(rand.nextInt());
- return dir.resolve(name);
- }
- }
--- a/jdk/test/java/nio/file/Path/DeleteOnClose.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import java.io.*;
-import java.util.*;
-
-public class DeleteOnClose {
-
- public static void main(String[] args) throws IOException {
- // open file but do not close it. Its existance will be checked by
- // the calling script.
- Paths.get(args[0]).newByteChannel(READ, WRITE, DELETE_ON_CLOSE);
-
- // check temporary file has been deleted after closing it
- Path file = File.createTempFile("blah", "tmp").toPath();
- file.newByteChannel(READ, WRITE, DELETE_ON_CLOSE).close();
- if (file.exists())
- throw new RuntimeException("Temporary file was not deleted");
-
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- // check that DELETE_ON_CLOSE fails when file is a sym link
- if (TestUtil.supportsLinks(dir)) {
- file = dir.resolve("foo").createFile();
- Path link = dir.resolve("link").createSymbolicLink(file);
- try {
- link.newByteChannel(READ, WRITE, DELETE_ON_CLOSE);
- throw new RuntimeException("IOException expected");
- } catch (IOException ignore) { }
- }
-
- // check that DELETE_ON_CLOSE works with files created via open
- // directories
- DirectoryStream stream = dir.newDirectoryStream();
- try {
- if (stream instanceof SecureDirectoryStream) {
- SecureDirectoryStream secure = (SecureDirectoryStream)stream;
- file = Paths.get("foo");
-
- Set<OpenOption> opts = new HashSet<OpenOption>();
- opts.add(WRITE);
- opts.add(DELETE_ON_CLOSE);
- secure.newByteChannel(file, opts).close();
-
- if (dir.resolve(file).exists())
- throw new RuntimeException("File not deleted");
- }
- } finally {
- stream.close();
- }
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/FileAttributes.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333
- * @summary Unit test for java.nio.file.Path
- * @library ..
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Exercises getAttribute/setAttribute/readAttributes methods.
- */
-
-public class FileAttributes {
-
- static void assertTrue(boolean okay) {
- if (!okay)
- throw new RuntimeException("Assertion Failed");
- }
-
- static void checkEqual(Object o1, Object o2) {
- if (o1 == null) {
- assertTrue(o2 == null);
- } else {
- assertTrue (o1.equals(o2));
- }
- }
-
- // checks that two time values are within 1s of each other
- static void checkNearEqual(FileTime t1, FileTime t2) {
- long diff = Math.abs(t1.toMillis() - t2.toMillis());
- assertTrue(diff <= 1000);
- }
-
- // Exercise getAttribute/setAttribute/readAttributes on basic attributes
- static void checkBasicAttributes(FileRef file, BasicFileAttributes attrs)
- throws IOException
- {
- // getAttribute
- checkEqual(attrs.size(), file.getAttribute("size"));
- checkEqual(attrs.lastModifiedTime(), file.getAttribute("basic:lastModifiedTime"));
- checkEqual(attrs.lastAccessTime(), file.getAttribute("lastAccessTime"));
- checkEqual(attrs.creationTime(), file.getAttribute("basic:creationTime"));
- assertTrue((Boolean)file.getAttribute("isRegularFile"));
- assertTrue(!(Boolean)file.getAttribute("basic:isDirectory"));
- assertTrue(!(Boolean)file.getAttribute("isSymbolicLink"));
- assertTrue(!(Boolean)file.getAttribute("basic:isOther"));
- checkEqual(attrs.fileKey(), file.getAttribute("basic:fileKey"));
-
- // setAttribute
- FileTime modTime = attrs.lastModifiedTime();
- file.setAttribute("basic:lastModifiedTime", FileTime.fromMillis(0L));
- checkEqual(Attributes.readBasicFileAttributes(file).lastModifiedTime(),
- FileTime.fromMillis(0L));
- file.setAttribute("lastModifiedTime", modTime);
- checkEqual(Attributes.readBasicFileAttributes(file).lastModifiedTime(), modTime);
-
- Map<String,?> map;
- map = file.readAttributes("*");
- assertTrue(map.size() >= 9);
- checkEqual(attrs.isRegularFile(), map.get("isRegularFile")); // check one
-
- map = file.readAttributes("basic:*");
- assertTrue(map.size() >= 9);
- checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime")); // check one
-
- map = file.readAttributes("size,lastModifiedTime");
- assertTrue(map.size() == 2);
- checkEqual(attrs.size(), map.get("size"));
- checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
-
- map = file.readAttributes(
- "basic:lastModifiedTime,lastAccessTime,ShouldNotExist");
- assertTrue(map.size() == 2);
- checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
- checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime"));
- }
-
- // Exercise getAttribute/setAttribute/readAttributes on posix attributes
- static void checkPosixAttributes(FileRef file, PosixFileAttributes attrs)
- throws IOException
- {
- checkBasicAttributes(file, attrs);
-
- // getAttribute
- checkEqual(attrs.permissions(), file.getAttribute("posix:permissions"));
- checkEqual(attrs.owner(), file.getAttribute("posix:owner"));
- checkEqual(attrs.group(), file.getAttribute("posix:group"));
-
- // setAttribute
- Set<PosixFilePermission> orig = attrs.permissions();
- Set<PosixFilePermission> newPerms = new HashSet<PosixFilePermission>(orig);
- newPerms.remove(PosixFilePermission.OTHERS_READ);
- newPerms.remove(PosixFilePermission.OTHERS_WRITE);
- newPerms.remove(PosixFilePermission.OTHERS_EXECUTE);
- file.setAttribute("posix:permissions", newPerms);
- checkEqual(Attributes.readPosixFileAttributes(file).permissions(), newPerms);
- file.setAttribute("posix:permissions", orig);
- checkEqual(Attributes.readPosixFileAttributes(file).permissions(), orig);
- file.setAttribute("posix:owner", attrs.owner());
- file.setAttribute("posix:group", attrs.group());
-
- // readAttributes
- Map<String,?> map;
- map = file.readAttributes("posix:*");
- assertTrue(map.size() >= 12);
- checkEqual(attrs.permissions(), map.get("permissions")); // check one
-
- map = file.readAttributes("posix:size,owner,ShouldNotExist");
- assertTrue(map.size() == 2);
- checkEqual(attrs.size(), map.get("size"));
- checkEqual(attrs.owner(), map.get("owner"));
- }
-
- // Exercise getAttribute/readAttributes on unix attributes
- static void checkUnixAttributes(FileRef file) throws IOException {
- // getAttribute
- int mode = (Integer)file.getAttribute("unix:mode");
- long ino = (Long)file.getAttribute("unix:ino");
- long dev = (Long)file.getAttribute("unix:dev");
- long rdev = (Long)file.getAttribute("unix:rdev");
- int nlink = (Integer)file.getAttribute("unix:nlink");
- int uid = (Integer)file.getAttribute("unix:uid");
- int gid = (Integer)file.getAttribute("unix:gid");
- FileTime ctime = (FileTime)file.getAttribute("unix:ctime");
-
- // readAttributes
- Map<String,?> map;
- map = file.readAttributes("unix:*");
- assertTrue(map.size() >= 20);
-
- map = file.readAttributes("unix:size,uid,gid,ShouldNotExist");
- assertTrue(map.size() == 3);
- checkEqual(map.get("size"),
- Attributes.readBasicFileAttributes(file).size());
- }
-
- // Exercise getAttribute/setAttribute on dos attributes
- static void checkDosAttributes(FileRef file, DosFileAttributes attrs)
- throws IOException
- {
- checkBasicAttributes(file, attrs);
-
- // getAttribute
- checkEqual(attrs.isReadOnly(), file.getAttribute("dos:readonly"));
- checkEqual(attrs.isHidden(), file.getAttribute("dos:hidden"));
- checkEqual(attrs.isSystem(), file.getAttribute("dos:system"));
- checkEqual(attrs.isArchive(), file.getAttribute("dos:archive"));
-
- // setAttribute
- boolean value;
-
- value = attrs.isReadOnly();
- file.setAttribute("dos:readonly", !value);
- checkEqual(Attributes.readDosFileAttributes(file).isReadOnly(), !value);
- file.setAttribute("dos:readonly", value);
- checkEqual(Attributes.readDosFileAttributes(file).isReadOnly(), value);
-
- value = attrs.isHidden();
- file.setAttribute("dos:hidden", !value);
- checkEqual(Attributes.readDosFileAttributes(file).isHidden(), !value);
- file.setAttribute("dos:hidden", value);
- checkEqual(Attributes.readDosFileAttributes(file).isHidden(), value);
-
- value = attrs.isSystem();
- file.setAttribute("dos:system", !value);
- checkEqual(Attributes.readDosFileAttributes(file).isSystem(), !value);
- file.setAttribute("dos:system", value);
- checkEqual(Attributes.readDosFileAttributes(file).isSystem(), value);
-
- value = attrs.isArchive();
- file.setAttribute("dos:archive", !value);
- checkEqual(Attributes.readDosFileAttributes(file).isArchive(), !value);
- file.setAttribute("dos:archive", value);
- checkEqual(Attributes.readDosFileAttributes(file).isArchive(), value);
-
- // readAttributes
- Map<String,?> map;
- map = file.readAttributes("dos:*");
- assertTrue(map.size() >= 13);
- checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one
-
- map = file.readAttributes("dos:size,hidden,ShouldNotExist");
- assertTrue(map.size() == 2);
- checkEqual(attrs.size(), map.get("size"));
- checkEqual(attrs.isHidden(), map.get("hidden"));
- }
-
- static void miscTests(Path file) throws IOException {
- // NPE tests
- try {
- file.getAttribute(null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException npe) { }
- try {
- file.getAttribute("isRegularFile", (LinkOption[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException npe) { }
- try {
- file.setAttribute(null, 0L);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException npe) { }
- }
-
- static void doTests(Path dir) throws IOException {
- Path file = dir.resolve("foo").createFile();
- FileStore store = file.getFileStore();
- try {
- checkBasicAttributes(file,
- Attributes.readBasicFileAttributes(file));
-
- if (store.supportsFileAttributeView("posix"))
- checkPosixAttributes(file,
- Attributes.readPosixFileAttributes(file));
-
- if (store.supportsFileAttributeView("unix"))
- checkUnixAttributes(file);
-
- if (store.supportsFileAttributeView("dos"))
- checkDosAttributes(file,
- Attributes.readDosFileAttributes(file));
-
- miscTests(file);
- } finally {
- file.delete();
- }
- }
-
-
- public static void main(String[] args) throws IOException {
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- doTests(dir);
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/InterruptCopy.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6993267
- * @summary Unit test for Sun-specific ExtendedCopyOption.INTERRUPTIBLE option
- * @library ..
- * @run main/othervm -XX:-UseVMInterruptibleIO InterruptCopy
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.Attributes;
-import java.io.*;
-import java.util.concurrent.*;
-import com.sun.nio.file.ExtendedCopyOption;
-
-public class InterruptCopy {
-
- private static final long FILE_SIZE_TO_COPY = 512L * 1024L * 1024L;
- private static final int DELAY_IN_MS = 500;
- private static final int DURATION_MAX_IN_MS = 5000;
-
- public static void main(String[] args) throws Exception {
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- FileStore store = dir.getFileStore();
- System.out.format("Checking space (%s)\n", store);
- long usableSpace = Attributes
- .readFileStoreSpaceAttributes(store).usableSpace();
- if (usableSpace < 2*FILE_SIZE_TO_COPY) {
- System.out.println("Insufficient disk space to run test.");
- return;
- }
- doTest(dir);
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-
- static void doTest(Path dir) throws Exception {
- final Path source = dir.resolve("foo");
- final Path target = dir.resolve("bar");
-
- // create source file (don't create it as sparse file because we
- // require the copy to take a long time)
- System.out.println("Creating source file...");
- byte[] buf = new byte[32*1024];
- long total = 0;
- OutputStream out = source.newOutputStream();
- try {
- do {
- out.write(buf);
- total += buf.length;
- } while (total < FILE_SIZE_TO_COPY);
- } finally {
- out.close();
- }
- System.out.println("Source file created.");
-
- ScheduledExecutorService pool =
- Executors.newSingleThreadScheduledExecutor();
- try {
- // copy source to target in main thread, interrupting it after a delay
- final Thread me = Thread.currentThread();
- Future<?> wakeup = pool.schedule(new Runnable() {
- public void run() {
- me.interrupt();
- }}, DELAY_IN_MS, TimeUnit.MILLISECONDS);
- System.out.println("Copying file...");
- try {
- long start = System.currentTimeMillis();
- source.copyTo(target, ExtendedCopyOption.INTERRUPTIBLE);
- long duration = System.currentTimeMillis() - start;
- if (duration > DURATION_MAX_IN_MS)
- throw new RuntimeException("Copy was not interrupted");
- } catch (IOException e) {
- boolean interrupted = Thread.interrupted();
- if (!interrupted)
- throw new RuntimeException("Interrupt status was not set");
- System.out.println("Copy failed (this is expected)");
- }
- try {
- wakeup.get();
- } catch (InterruptedException ignore) { }
- Thread.interrupted();
-
- // copy source to target via task in thread pool, interrupting it after
- // a delay using cancel(true)
- Future<Void> result = pool.submit(new Callable<Void>() {
- public Void call() throws IOException {
- System.out.println("Copying file...");
- source.copyTo(target, ExtendedCopyOption.INTERRUPTIBLE,
- StandardCopyOption.REPLACE_EXISTING);
- return null;
- }
- });
- Thread.sleep(DELAY_IN_MS);
- boolean cancelled = result.cancel(true);
- if (!cancelled)
- result.get();
- System.out.println("Copy cancelled.");
- } finally {
- pool.shutdown();
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/Links.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333 6863864
- * @summary Unit test for java.nio.file.Path createSymbolicLink,
- * readSymbolicLink, and createLink methods
- * @library ..
- * @build Links
- * @run main/othervm Links
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.*;
-
-public class Links {
-
- static final boolean isWindows =
- System.getProperty("os.name").startsWith("Windows");
-
- static void assertTrue(boolean okay) {
- if (!okay)
- throw new RuntimeException("Assertion failed");
- }
-
- /**
- * Exercise createSymbolicLink and readLink methods
- */
- static void testSymLinks(Path dir) throws IOException {
- final Path link = dir.resolve("link");
-
- // Check if sym links are supported
- try {
- link.createSymbolicLink(Paths.get("foo"));
- link.delete();
- } catch (UnsupportedOperationException x) {
- // sym links not supported
- return;
- } catch (IOException x) {
- // probably insufficient privileges to create sym links (Windows)
- return;
- }
-
- // Test links to various targets
- String[] windowsTargets =
- { "foo", "C:\\foo", "\\foo", "\\\\server\\share\\foo" };
- String[] otherTargets = { "relative", "/absolute" };
-
- String[] targets = (isWindows) ? windowsTargets : otherTargets;
- for (String s: targets) {
- Path target = Paths.get(s);
- link.createSymbolicLink(target);
- try {
- assertTrue(link.readSymbolicLink().equals(target));
- } finally {
- link.delete();
- }
- }
-
- // Test links to directory
- Path mydir = dir.resolve("mydir");
- Path myfile = mydir.resolve("myfile");
- try {
- mydir.createDirectory();
- myfile.createFile();
-
- // link -> "mydir"
- link.createSymbolicLink(mydir.getName());
- assertTrue(link.readSymbolicLink().equals(mydir.getName()));
-
- // Test access to directory via link
- DirectoryStream<Path> stream = link.newDirectoryStream();
- try {
- boolean found = false;
- for (Path entry: stream) {
- if (entry.getName().equals(myfile.getName())) {
- found = true;
- break;
- }
- }
- assertTrue(found);
- } finally {
- stream.close();
- }
-
- // Test link2 -> link -> mydir
- final Path link2 = dir.resolve("link2");
- Path target2 = link.getName();
- link2.createSymbolicLink(target2);
- try {
- assertTrue(link2.readSymbolicLink().equals(target2));
- link2.newDirectoryStream().close();
- } finally {
- link2.delete();
- }
-
- // Remove mydir and re-create link2 before re-creating mydir
- // (This is a useful test on Windows to ensure that creating a
- // sym link to a directory sym link creates the right type of link).
- myfile.delete();
- mydir.delete();
- link2.createSymbolicLink(target2);
- try {
- assertTrue(link2.readSymbolicLink().equals(target2));
- mydir.createDirectory();
- link2.newDirectoryStream().close();
- } finally {
- link2.delete();
- }
-
- } finally {
- myfile.deleteIfExists();
- mydir.deleteIfExists();
- link.deleteIfExists();
- }
- }
-
- /**
- * Exercise createLink method
- */
- static void testHardLinks(Path dir) throws IOException {
- Path foo = dir.resolve("foo").createFile();
- try {
- Path bar;
- try {
- bar = dir.resolve("bar").createLink(foo);
- } catch (UnsupportedOperationException x) {
- return;
- } catch (IOException x) {
- // probably insufficient privileges (Windows)
- return;
- }
- try {
- Object key1 = Attributes
- .readBasicFileAttributes(foo).fileKey();
- Object key2 = Attributes
- .readBasicFileAttributes(bar).fileKey();
- assertTrue((key1 == null) || (key1.equals(key2)));
- } finally {
- bar.delete();
- }
-
-
- } finally {
- foo.delete();
- }
- }
-
- public static void main(String[] args) throws IOException {
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- testSymLinks(dir);
- testHardLinks(dir);
-
- // repeat tests on Windows with long path
- if (isWindows) {
- Path dirWithLongPath = null;
- try {
- dirWithLongPath = TestUtil.createDirectoryWithLongPath(dir);
- } catch (IOException x) {
- System.out.println("Unable to create long path: " + x);
- }
- if (dirWithLongPath != null) {
- System.out.println("");
- System.out.println("** REPEAT TESTS WITH LONG PATH **");
- testSymLinks(dirWithLongPath);
- testHardLinks(dirWithLongPath);
- }
- }
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/Misc.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/Path/Misc.java Mon Feb 14 16:30:10 2011 -0800
@@ -22,17 +22,13 @@
*/
/* @test
- * @bug 4313887 6838333 6867101
- * @summary Unit test for java.nio.file.Path for miscellenous methods not
- * covered by other tests
+ * @bug 4313887 6838333
+ * @summary Unit test for miscellenous java.nio.file.Path methods
* @library ..
*/
import java.nio.file.*;
-import static java.nio.file.LinkOption.*;
-import java.nio.file.attribute.*;
import java.io.*;
-import java.util.*;
public class Misc {
static final boolean isWindows =
@@ -45,22 +41,14 @@
supportsLinks = TestUtil.supportsLinks(dir);
// equals and hashCode methods
- equalsAndHashCode();
+ testEqualsAndHashCode();
- // checkAccess method
- checkAccessTests(dir);
-
- // getFileAttributeView methods
- getFileAttributeViewTests(dir);
+ // toFile method
+ testToFile(dir);
// toRealPath method
- toRealPathTests(dir);
+ testToRealPath(dir);
- // isSameFile method
- isSameFileTests(dir);
-
- // isHidden method
- isHiddenTests(dir);
} finally {
TestUtil.removeAll(dir);
@@ -70,8 +58,7 @@
/**
* Exercise equals and hashCode methods
*/
- static void equalsAndHashCode() {
-
+ static void testEqualsAndHashCode() {
Path thisFile = Paths.get("this");
Path thatFile = Paths.get("that");
@@ -93,172 +80,25 @@
}
/**
- * Exercise checkAccess method
+ * Exercise toFile method
*/
- static void checkAccessTests(Path dir) throws IOException {
- final Path file = dir.resolve("foo").createFile();
-
- /**
- * Test: This directory should readable and writable
- */
- dir.checkAccess();
- dir.checkAccess(AccessMode.READ);
- dir.checkAccess(AccessMode.WRITE);
- dir.checkAccess(AccessMode.READ, AccessMode.WRITE);
-
- /**
- * Test: Check access to all files in all root directories.
- * (A useful test on Windows for special files such as pagefile.sys)
- */
- for (Path root: FileSystems.getDefault().getRootDirectories()) {
- DirectoryStream<Path> stream;
- try {
- stream = root.newDirectoryStream();
- } catch (IOException x) {
- continue; // skip root directories that aren't accessible
- }
- try {
- for (Path entry: stream) {
- try {
- entry.checkAccess();
- } catch (AccessDeniedException ignore) { }
- }
- } finally {
- stream.close();
- }
- }
-
- /**
- * Test: File does not exist
- */
- Path doesNotExist = dir.resolve("thisDoesNotExists");
- try {
- doesNotExist.checkAccess();
- throw new RuntimeException("NoSuchFileException expected");
- } catch (NoSuchFileException x) {
- }
- try {
- doesNotExist.checkAccess(AccessMode.READ);
- throw new RuntimeException("NoSuchFileException expected");
- } catch (NoSuchFileException x) {
- }
- try {
- doesNotExist.checkAccess(AccessMode.WRITE);
- throw new RuntimeException("NoSuchFileException expected");
- } catch (NoSuchFileException x) {
- }
- try {
- doesNotExist.checkAccess(AccessMode.EXECUTE);
- throw new RuntimeException("NoSuchFileException expected");
- } catch (NoSuchFileException x) {
- }
-
- /**
- * Test: Edit ACL to deny WRITE and EXECUTE
- */
- AclFileAttributeView view = file
- .getFileAttributeView(AclFileAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView("acl"))
- {
- UserPrincipal owner = view.getOwner();
- List<AclEntry> acl = view.getAcl();
-
- // Insert entry to deny WRITE and EXECUTE
- AclEntry entry = AclEntry.newBuilder()
- .setType(AclEntryType.DENY)
- .setPrincipal(owner)
- .setPermissions(AclEntryPermission.WRITE_DATA,
- AclEntryPermission.EXECUTE)
- .build();
- acl.add(0, entry);
- view.setAcl(acl);
-
- try {
- file.checkAccess(AccessMode.WRITE);
- throw new RuntimeException("AccessDeniedException expected");
- } catch (AccessDeniedException x) {
- }
-
- try {
- file.checkAccess(AccessMode.EXECUTE);
- throw new RuntimeException("AccessDeniedException expected");
- } catch (AccessDeniedException x) {
- }
-
-
- // Restore ACL
- acl.remove(0);
- view.setAcl(acl);
- }
-
- /**
- * Test: Windows DOS read-only attribute
- */
- if (isWindows) {
- DosFileAttributeView dview =
- file.getFileAttributeView(DosFileAttributeView.class);
- dview.setReadOnly(true);
- try {
- file.checkAccess(AccessMode.WRITE);
- throw new RuntimeException("AccessDeniedException expected");
- } catch (AccessDeniedException x) {
- }
- dview.setReadOnly(false);
-
- // Read-only attribute does not make direcory read-only
- dview = dir.getFileAttributeView(DosFileAttributeView.class);
- boolean save = dview.readAttributes().isReadOnly();
- dview.setReadOnly(true);
- dir.checkAccess(AccessMode.WRITE);
- dview.setReadOnly(save);
- }
-
- /**
- * Test: null
- */
- try {
- file.checkAccess((AccessMode)null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
-
- // clean-up
- file.delete();
+ static void testToFile(Path dir) throws IOException {
+ File d = dir.toFile();
+ assertTrue(d.toString().equals(dir.toString()));
+ assertTrue(d.toPath().equals(dir));
}
/**
- * Exercise getFileAttributeFile methods
- */
- static void getFileAttributeViewTests(Path dir) {
- assertTrue(dir.getFileAttributeView(BasicFileAttributeView.class)
- instanceof BasicFileAttributeView);
- assertTrue(dir.getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS)
- instanceof BasicFileAttributeView);
- assertTrue(dir.getFileAttributeView(BogusFileAttributeView.class) == null);
- try {
- dir.getFileAttributeView((Class<FileAttributeView>)null);
- } catch (NullPointerException ignore) { }
- try {
- dir.getFileAttributeView(BasicFileAttributeView.class, (LinkOption[])null);
- } catch (NullPointerException ignore) { }
- try {
- dir.getFileAttributeView(BasicFileAttributeView.class, (LinkOption)null);
- } catch (NullPointerException ignore) { }
-
- }
- interface BogusFileAttributeView extends FileAttributeView { }
-
- /**
* Exercise toRealPath method
*/
- static void toRealPathTests(Path dir) throws IOException {
- final Path file = dir.resolve("foo").createFile();
+ static void testToRealPath(Path dir) throws IOException {
+ final Path file = Files.createFile(dir.resolve("foo"));
final Path link = dir.resolve("link");
/**
- * Test: toRealPath(true) will access same file as toRealPath(false)
+ * Test: totRealPath(true) will access same file as toRealPath(false)
*/
- assertTrue(file.toRealPath(true).isSameFile(file.toRealPath(false)));
+ assertTrue(Files.isSameFile(file.toRealPath(true), file.toRealPath(false)));
/**
* Test: toRealPath should fail if file does not exist
@@ -279,29 +119,27 @@
* Test: toRealPath(true) should resolve links
*/
if (supportsLinks) {
- link.createSymbolicLink(file.toAbsolutePath());
+ Files.createSymbolicLink(link, file.toAbsolutePath());
assertTrue(link.toRealPath(true).equals(file.toRealPath(true)));
- link.delete();
+ Files.delete(link);
}
-
/**
* Test: toRealPath(false) should not resolve links
*/
if (supportsLinks) {
- link.createSymbolicLink(file.toAbsolutePath());
- assertTrue(link.toRealPath(false).getName().equals(link.getName()));
- link.delete();
+ Files.createSymbolicLink(link, file.toAbsolutePath());
+ assertTrue(link.toRealPath(false).getFileName().equals(link.getFileName()));
+ Files.delete(link);
}
/**
* Test: toRealPath(false) with broken link
*/
if (supportsLinks) {
- Path broken = dir.resolve("doesNotExist");
- link.createSymbolicLink(broken);
- assertTrue(link.toRealPath(false).getName().equals(link.getName()));
- link.delete();
+ Path broken = Files.createSymbolicLink(link, doesNotExist);
+ assertTrue(link.toRealPath(false).getFileName().equals(link.getFileName()));
+ Files.delete(link);
}
/**
@@ -314,105 +152,13 @@
* Test: toRealPath should eliminate ".." when it doesn't follow a
* symbolic link
*/
- Path subdir = dir.resolve("subdir").createDirectory();
+ Path subdir = Files.createDirectory(dir.resolve("subdir"));
assertTrue(subdir.resolve("..").toRealPath(true).equals(dir.toRealPath(true)));
assertTrue(subdir.resolve("..").toRealPath(false).equals(dir.toRealPath(false)));
- subdir.delete();
+ Files.delete(subdir);
// clean-up
- file.delete();
- }
-
- /**
- * Exercise isSameFile method
- */
- static void isSameFileTests(Path dir) throws IOException {
- Path thisFile = dir.resolve("thisFile");
- Path thatFile = dir.resolve("thatFile");
-
- /**
- * Test: isSameFile for self and null
- */
- assertTrue(thisFile.isSameFile(thisFile));
- assertTrue(!thisFile.isSameFile(null));
-
- /**
- * Test: Neither files exist
- */
- try {
- thisFile.isSameFile(thatFile);
- throw new RuntimeException("IOException not thrown");
- } catch (IOException x) {
- }
- try {
- thatFile.isSameFile(thisFile);
- throw new RuntimeException("IOException not thrown");
- } catch (IOException x) {
- }
-
- thisFile.createFile();
- try {
- /**
- * Test: One file exists
- */
- try {
- thisFile.isSameFile(thatFile);
- throw new RuntimeException("IOException not thrown");
- } catch (IOException x) {
- }
- try {
- thatFile.isSameFile(thisFile);
- throw new RuntimeException("IOException not thrown");
- } catch (IOException x) {
- }
-
- thatFile.createFile();
-
- /**
- * Test: Both file exists
- */
- try {
- assertTrue(!thisFile.isSameFile(thatFile));
- assertTrue(!thatFile.isSameFile(thisFile));
- } finally {
- TestUtil.deleteUnchecked(thatFile);
- }
-
- /**
- * Test: Symbolic links
- */
- if (supportsLinks) {
- thatFile.createSymbolicLink(thisFile);
- try {
- assertTrue(thisFile.isSameFile(thatFile));
- assertTrue(thatFile.isSameFile(thisFile));
- } finally {
- TestUtil.deleteUnchecked(thatFile);
- }
- }
- } finally {
- thisFile.delete();
- }
- }
-
- /**
- * Exercise isHidden method
- */
- static void isHiddenTests(Path dir) throws IOException {
- assertTrue(!dir.isHidden());
-
- Path file = dir.resolve(".foo");
- if (isWindows) {
- file.createFile();
- try {
- file.setAttribute("dos:hidden", true);
- assertTrue(file.isHidden());
- } finally {
- file.delete();
- }
- } else {
- assertTrue(file.isHidden());
- }
+ Files.delete(file);
}
static void assertTrue(boolean okay) {
--- a/jdk/test/java/nio/file/Path/PassThroughFileSystem.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,554 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.nio.file.spi.FileSystemProvider;
-import java.nio.channels.SeekableByteChannel;
-import java.net.URI;
-import java.util.*;
-import java.io.*;
-
-/**
- * A "pass through" file system implementation that passes through, or delegates,
- * everything to the default file system.
- */
-
-class PassThroughFileSystem extends FileSystem {
- private final FileSystemProvider provider;
- private final FileSystem delegate;
-
- PassThroughFileSystem(FileSystemProvider provider, FileSystem delegate) {
- this.provider = provider;
- this.delegate = delegate;
- }
-
- /**
- * Creates a new "pass through" file system. Useful for test environments
- * where the provider might not be deployed.
- */
- static FileSystem create() throws IOException {
- FileSystemProvider provider = new PassThroughProvider();
- Map<String,?> env = Collections.emptyMap();
- URI uri = URI.create("pass:///");
- return provider.newFileSystem(uri, env);
- }
-
- @Override
- public FileSystemProvider provider() {
- return provider;
- }
-
- @Override
- public void close() throws IOException {
- delegate.close();
- }
-
- @Override
- public boolean isOpen() {
- return delegate.isOpen();
- }
-
- @Override
- public boolean isReadOnly() {
- return delegate.isReadOnly();
- }
-
- @Override
- public String getSeparator() {
- return delegate.getSeparator();
- }
-
- @Override
- public Iterable<Path> getRootDirectories() {
- final Iterable<Path> roots = delegate.getRootDirectories();
- return new Iterable<Path>() {
- @Override
- public Iterator<Path> iterator() {
- final Iterator<Path> itr = roots.iterator();
- return new Iterator<Path>() {
- @Override
- public boolean hasNext() {
- return itr.hasNext();
- }
- @Override
- public Path next() {
- return new PassThroughPath(delegate, itr.next());
- }
- @Override
- public void remove() {
- itr.remove();
- }
- };
- }
- };
- }
-
- @Override
- public Iterable<FileStore> getFileStores() {
- // assume that unwrapped objects aren't exposed
- return delegate.getFileStores();
- }
-
- @Override
- public Set<String> supportedFileAttributeViews() {
- // assume that unwrapped objects aren't exposed
- return delegate.supportedFileAttributeViews();
- }
-
- @Override
- public Path getPath(String path) {
- return new PassThroughPath(this, delegate.getPath(path));
- }
-
- @Override
- public PathMatcher getPathMatcher(String syntaxAndPattern) {
- final PathMatcher matcher = delegate.getPathMatcher(syntaxAndPattern);
- return new PathMatcher() {
- @Override
- public boolean matches(Path path) {
- return matcher.matches(PassThroughPath.unwrap(path));
- }
- };
- }
-
- @Override
- public UserPrincipalLookupService getUserPrincipalLookupService() {
- // assume that unwrapped objects aren't exposed
- return delegate.getUserPrincipalLookupService();
- }
-
- @Override
- public WatchService newWatchService() throws IOException {
- // to keep it simple
- throw new UnsupportedOperationException();
- }
-
- static class PassThroughProvider extends FileSystemProvider {
- private static final String SCHEME = "pass";
- private static volatile PassThroughFileSystem delegate;
-
- public PassThroughProvider() { }
-
- @Override
- public String getScheme() {
- return SCHEME;
- }
-
- private void checkScheme(URI uri) {
- if (!uri.getScheme().equalsIgnoreCase(SCHEME))
- throw new IllegalArgumentException();
- }
-
- private void checkUri(URI uri) {
- checkScheme(uri);
- if (!uri.getSchemeSpecificPart().equals("///"))
- throw new IllegalArgumentException();
- }
-
- @Override
- public FileSystem newFileSystem(URI uri, Map<String,?> env)
- throws IOException
- {
- checkUri(uri);
- synchronized (PassThroughProvider.class) {
- if (delegate != null)
- throw new FileSystemAlreadyExistsException();
- PassThroughFileSystem result =
- new PassThroughFileSystem(this, FileSystems.getDefault());
- delegate = result;
- return result;
- }
- }
-
- @Override
- public FileSystem getFileSystem(URI uri) {
- checkUri(uri);
- FileSystem result = delegate;
- if (result == null)
- throw new FileSystemNotFoundException();
- return result;
- }
-
- @Override
- public Path getPath(URI uri) {
- checkScheme(uri);
- if (delegate == null)
- throw new FileSystemNotFoundException();
- uri = URI.create(delegate.provider().getScheme() + ":" +
- uri.getSchemeSpecificPart());
- return new PassThroughPath(delegate, delegate.provider().getPath(uri));
- }
- }
-
- static class PassThroughPath extends Path {
- private final FileSystem fs;
- private final Path delegate;
-
- PassThroughPath(FileSystem fs, Path delegate) {
- this.fs = fs;
- this.delegate = delegate;
- }
-
- private Path wrap(Path path) {
- return (path != null) ? new PassThroughPath(fs, path) : null;
- }
-
- static Path unwrap(Path wrapper) {
- if (!(wrapper instanceof PassThroughPath))
- throw new ProviderMismatchException();
- return ((PassThroughPath)wrapper).delegate;
- }
-
- @Override
- public FileSystem getFileSystem() {
- return fs;
- }
-
- @Override
- public boolean isAbsolute() {
- return delegate.isAbsolute();
- }
-
- @Override
- public Path getRoot() {
- return wrap(delegate.getRoot());
- }
-
-
- @Override
- public Path getName() {
- return wrap(delegate.getName());
- }
-
- @Override
- public Path getParent() {
- return wrap(delegate.getParent());
- }
-
- @Override
- public int getNameCount() {
- return delegate.getNameCount();
- }
-
- @Override
- public Path getName(int index) {
- return wrap(delegate.getName(index));
- }
-
- @Override
- public Path subpath(int beginIndex, int endIndex) {
- return wrap(delegate.subpath(beginIndex, endIndex));
- }
-
- @Override
- public boolean startsWith(Path other) {
- return delegate.startsWith(unwrap(other));
- }
-
- @Override
- public boolean endsWith(Path other) {
- return delegate.endsWith(unwrap(other));
- }
-
- @Override
- public Path normalize() {
- return wrap(delegate.normalize());
- }
-
- @Override
- public Path resolve(Path other) {
- return wrap(delegate.resolve(unwrap(other)));
- }
-
- @Override
- public Path resolve(String other) {
- return wrap(delegate.resolve(other));
- }
-
- @Override
- public Path relativize(Path other) {
- return wrap(delegate.relativize(unwrap(other)));
- }
-
- @Override
- public void setAttribute(String attribute, Object value, LinkOption... options)
- throws IOException
- {
- delegate.setAttribute(attribute, value, options);
- }
-
- @Override
- public Object getAttribute(String attribute, LinkOption... options)
- throws IOException
- {
- // assume that unwrapped objects aren't exposed
- return delegate.getAttribute(attribute, options);
- }
-
- @Override
- public Map<String,?> readAttributes(String attributes, LinkOption... options)
- throws IOException
- {
- // assume that unwrapped objects aren't exposed
- return delegate.readAttributes(attributes, options);
- }
-
- @Override
- public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
- LinkOption... options)
- {
- return delegate.getFileAttributeView(type, options);
- }
-
- @Override
- public void delete() throws IOException {
- delegate.delete();
- }
-
- @Override
- public void deleteIfExists() throws IOException {
- delegate.deleteIfExists();
- }
-
- @Override
- public Path createSymbolicLink(Path target, FileAttribute<?>... attrs)
- throws IOException
- {
- delegate.createSymbolicLink(unwrap(target), attrs);
- return this;
- }
-
- @Override
- public Path createLink(Path existing) throws IOException {
- delegate.createLink(unwrap(existing));
- return this;
- }
-
- @Override
- public Path readSymbolicLink() throws IOException {
- return wrap(delegate.readSymbolicLink());
- }
-
- @Override
- public URI toUri() {
- String ssp = delegate.toUri().getSchemeSpecificPart();
- return URI.create(fs.provider().getScheme() + ":" + ssp);
- }
-
- @Override
- public Path toAbsolutePath() {
- return wrap(delegate.toAbsolutePath());
- }
-
- @Override
- public Path toRealPath(boolean resolveLinks) throws IOException {
- return wrap(delegate.toRealPath(resolveLinks));
- }
-
- @Override
- public Path copyTo(Path target, CopyOption... options) throws IOException {
- return wrap(delegate.copyTo(unwrap(target), options));
- }
-
- @Override
- public Path moveTo(Path target, CopyOption... options) throws IOException {
- return wrap(delegate.copyTo(unwrap(target), options));
- }
-
- private DirectoryStream<Path> wrap(final DirectoryStream<Path> stream) {
- return new DirectoryStream<Path>() {
- @Override
- public Iterator<Path> iterator() {
- final Iterator<Path> itr = stream.iterator();
- return new Iterator<Path>() {
- @Override
- public boolean hasNext() {
- return itr.hasNext();
- }
- @Override
- public Path next() {
- return wrap(itr.next());
- }
- @Override
- public void remove() {
- itr.remove();
- }
- };
- }
- @Override
- public void close() throws IOException {
- stream.close();
- }
- };
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream() throws IOException {
- return wrap(delegate.newDirectoryStream());
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream(String glob)
- throws IOException
- {
- return wrap(delegate.newDirectoryStream(glob));
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
- throws IOException
- {
- return wrap(delegate.newDirectoryStream(filter));
- }
-
- @Override
- public Path createFile(FileAttribute<?>... attrs) throws IOException {
- delegate.createFile(attrs);
- return this;
- }
-
- @Override
- public Path createDirectory(FileAttribute<?>... attrs)
- throws IOException
- {
- delegate.createDirectory(attrs);
- return this;
- }
-
- @Override
- public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- return delegate.newByteChannel(options, attrs);
- }
-
- @Override
- public SeekableByteChannel newByteChannel(OpenOption... options)
- throws IOException
- {
- return delegate.newByteChannel(options);
- }
-
- @Override
- public InputStream newInputStream(OpenOption... options) throws IOException {
- return delegate.newInputStream();
- }
-
- @Override
- public OutputStream newOutputStream(OpenOption... options)
- throws IOException
- {
- return delegate.newOutputStream(options);
- }
-
- @Override
- public boolean isHidden() throws IOException {
- return delegate.isHidden();
- }
-
- @Override
- public void checkAccess(AccessMode... modes) throws IOException {
- delegate.checkAccess(modes);
- }
-
- @Override
- public boolean exists() {
- return delegate.exists();
- }
-
- @Override
- public boolean notExists() {
- return delegate.notExists();
- }
-
- @Override
- public FileStore getFileStore() throws IOException {
- return delegate.getFileStore();
- }
-
- @Override
- public WatchKey register(WatchService watcher,
- WatchEvent.Kind<?>[] events,
- WatchEvent.Modifier... modifiers)
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public WatchKey register(WatchService watcher,
- WatchEvent.Kind<?>... events)
- {
- throw new UnsupportedOperationException();
- }
-
-
- @Override
- public Iterator<Path> iterator() {
- final Iterator<Path> itr = delegate.iterator();
- return new Iterator<Path>() {
- @Override
- public boolean hasNext() {
- return itr.hasNext();
- }
- @Override
- public Path next() {
- return wrap(itr.next());
- }
- @Override
- public void remove() {
- itr.remove();
- }
- };
- }
-
- @Override
- public int compareTo(Path other) {
- return delegate.compareTo(unwrap(other));
- }
-
- @Override
- public boolean isSameFile(Path other) throws IOException {
- return delegate.isSameFile(unwrap(other));
- }
-
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof PassThroughPath))
- return false;
- return delegate.equals(unwrap((PassThroughPath)other));
- }
-
- @Override
- public int hashCode() {
- return delegate.hashCode();
- }
-
- @Override
- public String toString() {
- return delegate.toString();
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/PathOps.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/Path/PathOps.java Mon Feb 14 16:30:10 2011 -0800
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4313887 6838333 6925932
+ * @bug 4313887 6838333 6925932 7006126
* @summary Unit test for java.nio.file.Path path operations
*/
@@ -36,15 +36,15 @@
private Path path;
private Exception exc;
- private PathOps(String s) {
+ private PathOps(String first, String... more) {
out.println();
- input = s;
+ input = first;
try {
- path = FileSystems.getDefault().getPath(s);
- out.format("%s -> %s", s, path);
+ path = FileSystems.getDefault().getPath(first, more);
+ out.format("%s -> %s", first, path);
} catch (Exception x) {
exc = x;
- out.format("%s -> %s", s, x);
+ out.format("%s -> %s", first, x);
}
out.println();
}
@@ -97,7 +97,7 @@
PathOps name(String expected) {
out.println("check name");
checkPath();
- check(path.getName(), expected);
+ check(path.getFileName(), expected);
return this;
}
@@ -168,6 +168,13 @@
return this;
}
+ PathOps resolveSibling(String other, String expected) {
+ out.format("test resolveSibling %s\n", other);
+ checkPath();
+ check(path.resolveSibling(other), expected);
+ return this;
+ }
+
PathOps relativize(String other, String expected) {
out.format("test relativize %s\n", other);
checkPath();
@@ -198,8 +205,8 @@
return this;
}
- static PathOps test(String s) {
- return new PathOps(s);
+ static PathOps test(String first, String... more) {
+ return new PathOps(first, more);
}
// -- PathOpss --
@@ -213,6 +220,26 @@
static void doWindowsTests() {
header("Windows specific tests");
+ // construction
+ test("C:\\")
+ .string("C:\\");
+ test("C:\\", "")
+ .string("C:\\");
+ test("C:\\", "foo")
+ .string("C:\\foo");
+ test("C:\\", "\\foo")
+ .string("C:\\foo");
+ test("C:\\", "foo\\")
+ .string("C:\\foo");
+ test("foo", "bar", "gus")
+ .string("foo\\bar\\gus");
+ test("")
+ .string("");
+ test("", "C:\\")
+ .string("C:\\");
+ test("", "foo", "", "bar", "", "\\gus")
+ .string("foo\\bar\\gus");
+
// all components present
test("C:\\a\\b\\c")
.root("C:\\")
@@ -252,17 +279,23 @@
.root(null)
.parent(null)
.name("foo");
+ test("")
+ .root(null)
+ .parent(null)
+ .name("");
// startsWith
test("C:\\")
.starts("C:\\")
.starts("c:\\")
.notStarts("C")
- .notStarts("C:");
+ .notStarts("C:")
+ .notStarts("");
test("C:")
.starts("C:")
.starts("c:")
- .notStarts("C");
+ .notStarts("C")
+ .notStarts("");
test("\\")
.starts("\\");
test("C:\\foo\\bar")
@@ -273,7 +306,8 @@
.starts("C:\\Foo\\Bar")
.notStarts("C:")
.notStarts("C")
- .notStarts("C:foo");
+ .notStarts("C:foo")
+ .notStarts("");
test("\\foo\\bar")
.starts("\\")
.starts("\\foo")
@@ -281,26 +315,35 @@
.starts("\\foo\\bar")
.starts("\\fOo\\BaR")
.notStarts("foo")
- .notStarts("foo\\bar");
+ .notStarts("foo\\bar")
+ .notStarts("");
test("foo\\bar")
.starts("foo")
.starts("foo\\bar")
- .notStarts("\\");
+ .notStarts("\\")
+ .notStarts("");
test("\\\\server\\share")
.starts("\\\\server\\share")
.starts("\\\\server\\share\\")
+ .notStarts("\\")
+ .notStarts("");
+ test("")
+ .starts("")
.notStarts("\\");
// endsWith
test("C:\\")
.ends("C:\\")
.ends("c:\\")
- .notEnds("\\");
+ .notEnds("\\")
+ .notEnds("");
test("C:")
.ends("C:")
- .ends("c:");
+ .ends("c:")
+ .notEnds("");
test("\\")
- .ends("\\");
+ .ends("\\")
+ .notEnds("");
test("C:\\foo\\bar")
.ends("bar")
.ends("BAR")
@@ -309,7 +352,8 @@
.ends("C:\\foo\\bar")
.ends("c:\\foO\\baR")
.notEnds("r")
- .notEnds("\\foo\\bar");
+ .notEnds("\\foo\\bar")
+ .notEnds("");
test("\\foo\\bar")
.ends("bar")
.ends("BaR")
@@ -317,17 +361,23 @@
.ends("foO\\baR")
.ends("\\foo\\bar")
.ends("\\Foo\\Bar")
- .notEnds("oo\\bar");
+ .notEnds("oo\\bar")
+ .notEnds("");
test("foo\\bar")
.ends("bar")
.ends("BAR")
.ends("foo\\bar")
.ends("Foo\\Bar")
- .notEnds("ar");
+ .notEnds("ar")
+ .notEnds("");
test("\\\\server\\share")
.ends("\\\\server\\share")
.ends("\\\\server\\share\\")
.notEnds("shared")
+ .notEnds("\\")
+ .notEnds("");
+ test("")
+ .ends("")
.notEnds("\\");
// elements
@@ -338,6 +388,8 @@
test("foo.bar\\gus.alice")
.element(0, "foo.bar")
.element(1, "gus.alice");
+ test("")
+ .element(0, "");
// subpath
test("C:\\foo")
@@ -355,6 +407,8 @@
.subpath(2, 3, "gus");
test("\\\\server\\share\\foo")
.subpath(0, 1, "foo");
+ test("")
+ .subpath(0, 1, "");
// isAbsolute
test("foo").notAbsolute();
@@ -362,6 +416,7 @@
test("C:\\").absolute();
test("C:\\abc").absolute();
test("\\\\server\\share\\").absolute();
+ test("").notAbsolute();
// resolve
test("C:\\")
@@ -369,42 +424,99 @@
.resolve("D:\\bar", "D:\\bar")
.resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
.resolve("C:foo", "C:\\foo")
- .resolve("D:foo", "D:foo");
+ .resolve("D:foo", "D:foo")
+ .resolve("", "C:\\");
test("\\")
.resolve("foo", "\\foo")
.resolve("D:bar", "D:bar")
.resolve("C:\\bar", "C:\\bar")
.resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
- .resolve("\\foo", "\\foo");
+ .resolve("\\foo", "\\foo")
+ .resolve("", "\\");
test("\\foo")
.resolve("bar", "\\foo\\bar")
.resolve("D:bar", "D:bar")
.resolve("C:\\bar", "C:\\bar")
.resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
- .resolve("\\bar", "\\bar");
+ .resolve("\\bar", "\\bar")
+ .resolve("", "\\foo");
test("foo")
.resolve("bar", "foo\\bar")
.resolve("D:\\bar", "D:\\bar")
.resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
.resolve("C:bar", "C:bar")
- .resolve("D:foo", "D:foo");
+ .resolve("D:foo", "D:foo")
+ .resolve("", "foo");
test("C:")
- .resolve("foo", "C:foo");
+ .resolve("foo", "C:foo")
+ .resolve("", "C:");
test("\\\\server\\share\\foo")
.resolve("bar", "\\\\server\\share\\foo\\bar")
.resolve("\\bar", "\\\\server\\share\\bar")
.resolve("D:\\bar", "D:\\bar")
.resolve("\\\\other\\share\\bar", "\\\\other\\share\\bar")
- .resolve("D:bar", "D:bar");
+ .resolve("D:bar", "D:bar")
+ .resolve("", "\\\\server\\share\\foo");
+ test("")
+ .resolve("", "")
+ .resolve("foo", "foo")
+ .resolve("C:\\", "C:\\")
+ .resolve("C:foo", "C:foo")
+ .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar");
+
+ // resolveSibling
+ test("foo")
+ .resolveSibling("bar", "bar")
+ .resolveSibling("D:\\bar", "D:\\bar")
+ .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+ .resolveSibling("C:bar", "C:bar")
+ .resolveSibling("D:foo", "D:foo")
+ .resolveSibling("", "");
+ test("foo\\bar")
+ .resolveSibling("gus", "foo\\gus")
+ .resolveSibling("D:\\bar", "D:\\bar")
+ .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+ .resolveSibling("C:bar", "C:bar")
+ .resolveSibling("D:foo", "D:foo")
+ .resolveSibling("", "foo");
+ test("C:\\foo")
+ .resolveSibling("gus", "C:\\gus")
+ .resolveSibling("D:\\bar", "D:\\bar")
+ .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+ .resolveSibling("C:bar", "C:\\bar")
+ .resolveSibling("D:foo", "D:foo")
+ .resolveSibling("", "C:\\");
+ test("C:\\foo\\bar")
+ .resolveSibling("gus", "C:\\foo\\gus")
+ .resolveSibling("D:\\bar", "D:\\bar")
+ .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+ .resolveSibling("C:bar", "C:\\foo\\bar")
+ .resolveSibling("D:foo", "D:foo")
+ .resolveSibling("", "C:\\foo");
+ test("\\\\server\\share\\foo")
+ .resolveSibling("bar", "\\\\server\\share\\bar")
+ .resolveSibling("\\bar", "\\\\server\\share\\bar")
+ .resolveSibling("D:\\bar", "D:\\bar")
+ .resolveSibling("\\\\other\\share\\bar", "\\\\other\\share\\bar")
+ .resolveSibling("D:bar", "D:bar")
+ .resolveSibling("", "\\\\server\\share\\");
+ test("")
+ .resolveSibling("", "")
+ .resolveSibling("foo", "foo")
+ .resolveSibling("C:\\", "C:\\");
// relativize
test("foo\\bar")
- .relativize("foo\\bar", null)
+ .relativize("foo\\bar", "")
.relativize("foo", "..");
test("C:\\a\\b\\c")
- .relativize("C:\\a", "..\\..");
+ .relativize("C:\\a", "..\\..")
+ .relativize("C:\\a\\b\\c", "");
test("\\\\server\\share\\foo")
- .relativize("\\\\server\\share\\bar", "..\\bar");
+ .relativize("\\\\server\\share\\bar", "..\\bar")
+ .relativize("\\\\server\\share\\foo", "");
+ test("")
+ .relativize("", "");
// normalize
test("C:\\")
@@ -436,7 +548,7 @@
test("foo\\.")
.normalize("foo");
test("foo\\..")
- .normalize(null);
+ .normalize("");
test("C:\\foo")
.normalize("C:\\foo");
test("C:\\foo\\.")
@@ -478,7 +590,7 @@
test("\\..\\foo")
.normalize("\\foo");
test(".")
- .normalize(null);
+ .normalize("");
test("..")
.normalize("..");
test("\\..\\..")
@@ -493,6 +605,8 @@
.normalize("foo");
test(".\\foo\\.\\bar\\.\\gus\\..\\.\\..")
.normalize("foo");
+ test("")
+ .normalize("");
// UNC corner cases
test("\\\\server\\share\\")
@@ -557,6 +671,26 @@
static void doUnixTests() {
header("Unix specific tests");
+ // construction
+ test("/")
+ .string("/");
+ test("/", "")
+ .string("/");
+ test("/", "foo")
+ .string("/foo");
+ test("/", "/foo")
+ .string("/foo");
+ test("/", "foo/")
+ .string("/foo");
+ test("foo", "bar", "gus")
+ .string("foo/bar/gus");
+ test("")
+ .string("");
+ test("", "/")
+ .string("/");
+ test("", "foo", "", "bar", "", "/gus")
+ .string("foo/bar/gus");
+
// all components
test("/a/b/c")
.root("/")
@@ -580,10 +714,15 @@
.root(null)
.parent(null)
.name("foo");
+ test("")
+ .root(null)
+ .parent(null)
+ .name("");
// startsWith
test("/")
.starts("/")
+ .notStarts("")
.notStarts("/foo");
test("/foo")
.starts("/")
@@ -598,6 +737,7 @@
.notStarts("foo/bar");
test("foo")
.starts("foo")
+ .notStarts("")
.notStarts("f");
test("foo/bar")
.starts("foo")
@@ -605,10 +745,14 @@
.notStarts("f")
.notStarts("/foo")
.notStarts("/foo/bar");
+ test("")
+ .starts("")
+ .notStarts("/");
// endsWith
test("/")
.ends("/")
+ .notEnds("")
.notEnds("foo")
.notEnds("/foo");
test("/foo")
@@ -625,6 +769,7 @@
.notEnds("o/bar");
test("foo")
.ends("foo")
+ .notEnds("")
.notEnds("oo")
.notEnds("oola");
test("foo/bar")
@@ -642,12 +787,47 @@
.notEnds("r/gus")
.notEnds("barack/gus")
.notEnds("bar/gust");
+ test("")
+ .ends("")
+ .notEnds("/");
// elements
test("a/b/c")
- .element(0,"a")
- .element(1,"b")
- .element(2,"c");
+ .element(0, "a")
+ .element(1, "b")
+ .element(2, "c");
+ test("")
+ .element(0, "");
+
+ // subpath
+ test("/foo")
+ .subpath(0, 1, "foo");
+ test("foo")
+ .subpath(0, 1, "foo");
+ test("/foo/bar")
+ .subpath(0, 1, "foo")
+ .subpath(1, 2, "bar")
+ .subpath(0, 2, "foo/bar");
+ test("foo/bar")
+ .subpath(0, 1, "foo")
+ .subpath(1, 2, "bar")
+ .subpath(0, 2, "foo/bar");
+ test("/foo/bar/gus")
+ .subpath(0, 1, "foo")
+ .subpath(1, 2, "bar")
+ .subpath(2, 3, "gus")
+ .subpath(0, 2, "foo/bar")
+ .subpath(1, 3, "bar/gus")
+ .subpath(0, 3, "foo/bar/gus");
+ test("foo/bar/gus")
+ .subpath(0, 1, "foo")
+ .subpath(1, 2, "bar")
+ .subpath(2, 3, "gus")
+ .subpath(0, 2, "foo/bar")
+ .subpath(1, 3, "bar/gus")
+ .subpath(0, 3, "foo/bar/gus");
+ test("")
+ .subpath(0, 1, "");
// isAbsolute
test("/")
@@ -656,20 +836,61 @@
.absolute();
test("tmp")
.notAbsolute();
+ test("")
+ .notAbsolute();
+
// resolve
test("/tmp")
.resolve("foo", "/tmp/foo")
- .resolve("/foo", "/foo");
+ .resolve("/foo", "/foo")
+ .resolve("", "/tmp");
test("tmp")
.resolve("foo", "tmp/foo")
+ .resolve("/foo", "/foo")
+ .resolve("", "tmp");
+ test("")
+ .resolve("", "")
+ .resolve("foo", "foo")
.resolve("/foo", "/foo");
+ // resolveSibling
+ test("foo")
+ .resolveSibling("bar", "bar")
+ .resolveSibling("/bar", "/bar")
+ .resolveSibling("", "");
+ test("foo/bar")
+ .resolveSibling("gus", "foo/gus")
+ .resolveSibling("/gus", "/gus")
+ .resolveSibling("", "foo");
+ test("/foo")
+ .resolveSibling("gus", "/gus")
+ .resolveSibling("/gus", "/gus")
+ .resolveSibling("", "/");
+ test("/foo/bar")
+ .resolveSibling("gus", "/foo/gus")
+ .resolveSibling("/gus", "/gus")
+ .resolveSibling("", "/foo");
+ test("")
+ .resolveSibling("foo", "foo")
+ .resolveSibling("/foo", "/foo")
+ .resolve("", "");
+
// relativize
test("/a/b/c")
- .relativize("/a/b/c", null)
+ .relativize("/a/b/c", "")
.relativize("/a/b/c/d/e", "d/e")
- .relativize("/a/x", "../../x");
+ .relativize("/a/x", "../../x")
+ .relativize("/x", "../../../x");
+ test("a/b/c")
+ .relativize("a/b/c/d", "d")
+ .relativize("a/x", "../../x")
+ .relativize("x", "../../../x")
+ .relativize("", "../../..");
+ test("")
+ .relativize("a", "a")
+ .relativize("a/b/c", "a/b/c")
+ .relativize("", "");
// normalize
test("/")
@@ -679,7 +900,7 @@
test("/foo")
.normalize("/foo");
test(".")
- .normalize(null);
+ .normalize("");
test("..")
.normalize("..");
test("/..")
@@ -691,7 +912,7 @@
test("./foo")
.normalize("foo");
test("foo/..")
- .normalize(null);
+ .normalize("");
test("../foo")
.normalize("../foo");
test("../../foo")
@@ -717,7 +938,7 @@
test("//bar\u0000")
.invalid();
- // normalization
+ // normalization of input
test("//foo//bar")
.string("/foo/bar")
.root("/")
@@ -749,13 +970,13 @@
}
try {
- path.startsWith(null);
+ path.startsWith((Path)null);
throw new RuntimeException("NullPointerException not thrown");
} catch (NullPointerException npe) {
}
try {
- path.endsWith(null);
+ path.endsWith((Path)null);
throw new RuntimeException("NullPointerException not thrown");
} catch (NullPointerException npe) {
}
--- a/jdk/test/java/nio/file/Path/SBC.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,468 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887
- * @summary Unit test for java.nio.file.Path.newByteChannel
- * @library ..
- */
-
-import java.nio.ByteBuffer;
-import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import static com.sun.nio.file.ExtendedOpenOption.*;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.channels.*;
-import java.io.IOException;
-import java.util.*;
-
-public class SBC {
-
- static boolean supportsLinks;
-
- public static void main(String[] args) throws Exception {
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- supportsLinks = TestUtil.supportsLinks(dir);
-
- // open options
- createTests(dir);
- appendTests(dir);
- truncateExistingTests(dir);
- noFollowLinksTests(dir);
-
- // SeekableByteChannel methods
- sizeTruncatePositionTests(dir);
-
- // platform specific
- if (System.getProperty("os.name").startsWith("Windows"))
- dosSharingOptionTests(dir);
-
- // misc. tests
- badCombinations(dir);
- unsupportedOptions(dir);
- nullTests(dir);
-
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-
- // test CREATE and CREATE_NEW options
- static void createTests(Path dir) throws Exception {
- Path file = dir.resolve("foo");
-
- // CREATE
- try {
- // create file (no existing file)
- file.newByteChannel(CREATE, WRITE).close();
- if (file.notExists())
- throw new RuntimeException("File not created");
-
- // create file (existing file)
- file.newByteChannel(CREATE, WRITE).close();
-
- // create file where existing file is a sym link
- if (supportsLinks) {
- Path link = dir.resolve("link").createSymbolicLink(file);
- try {
- // file already exists
- link.newByteChannel(CREATE, WRITE).close();
-
- // file does not exist
- file.delete();
- link.newByteChannel(CREATE, WRITE).close();
- if (file.notExists())
- throw new RuntimeException("File not created");
-
- } finally {
- TestUtil.deleteUnchecked(link);
- }
- }
-
- } finally {
- TestUtil.deleteUnchecked(file);
- }
-
- // CREATE_NEW
- try {
- // create file
- file.newByteChannel(CREATE_NEW, WRITE).close();
- if (file.notExists())
- throw new RuntimeException("File not created");
-
- // create should fail
- try {
- SeekableByteChannel sbc =
- file.newByteChannel(CREATE_NEW, WRITE);
- sbc.close();
- throw new RuntimeException("FileAlreadyExistsException not thrown");
- } catch (FileAlreadyExistsException x) { }
-
- // create should fail
- if (supportsLinks) {
- Path link = dir.resolve("link");
- Path target = dir.resolve("thisDoesNotExist");
- link.createSymbolicLink(target);
- try {
-
- try {
- SeekableByteChannel sbc =
- file.newByteChannel(CREATE_NEW, WRITE);
- sbc.close();
- throw new RuntimeException("FileAlreadyExistsException not thrown");
- } catch (FileAlreadyExistsException x) { }
-
- } finally {
- TestUtil.deleteUnchecked(link);
- }
- }
-
-
- } finally {
- TestUtil.deleteUnchecked(file);
- }
-
- // CREATE_NEW + SPARSE
- try {
- SeekableByteChannel sbc = file
- .newByteChannel(CREATE_NEW, WRITE, SPARSE);
- try {
- final long hole = 2L * 1024L * 1024L * 1024L;
- sbc.position(hole);
- write(sbc, "hello");
- long size = sbc.size();
- if (size != (hole + 5))
- throw new RuntimeException("Unexpected size");
- } finally {
- sbc.close();
- }
- } finally {
- TestUtil.deleteUnchecked(file);
- }
- }
-
- // test APPEND option
- static void appendTests(Path dir) throws Exception {
- Path file = dir.resolve("foo");
- try {
- // "hello there" should be written to file
- SeekableByteChannel sbc = file
- .newByteChannel(CREATE_NEW, WRITE, APPEND);
- try {
- write(sbc, "hello ");
- sbc.position(0L);
- write(sbc, "there");
- } finally {
- sbc.close();
- }
-
- // check file
- Scanner s = new Scanner(file);
- try {
- String line = s.nextLine();
- if (!line.equals("hello there"))
- throw new RuntimeException("Unexpected file contents");
- } finally {
- s.close();
- }
-
- // check that read is not allowed
- sbc = file.newByteChannel(APPEND);
- try {
- sbc.read(ByteBuffer.allocate(100));
- } catch (NonReadableChannelException x) {
- } finally {
- sbc.close();
- }
- } finally {
- // clean-up
- TestUtil.deleteUnchecked(file);
- }
- }
-
- // test TRUNCATE_EXISTING option
- static void truncateExistingTests(Path dir) throws Exception {
- Path file = dir.resolve("foo");
- try {
- SeekableByteChannel sbc =
- file.newByteChannel(CREATE_NEW, WRITE);
- try {
- write(sbc, "Have a nice day!");
- } finally {
- sbc.close();
- }
-
- // re-open with truncate option
- // write short message and check
- sbc = file.newByteChannel(WRITE, TRUNCATE_EXISTING);
- try {
- write(sbc, "Hello there!");
- } finally {
- sbc.close();
- }
- Scanner s = new Scanner(file);
- try {
- String line = s.nextLine();
- if (!line.equals("Hello there!"))
- throw new RuntimeException("Unexpected file contents");
- } finally {
- s.close();
- }
-
- // re-open with create + truncate option
- // check file is of size 0L
- sbc = file.newByteChannel(WRITE, CREATE, TRUNCATE_EXISTING);
- try {
- long size = ((FileChannel)sbc).size();
- if (size != 0L)
- throw new RuntimeException("File not truncated");
- } finally {
- sbc.close();
- }
-
- } finally {
- // clean-up
- TestUtil.deleteUnchecked(file);
- }
-
- }
-
- // test NOFOLLOW_LINKS option
- static void noFollowLinksTests(Path dir) throws Exception {
- if (!supportsLinks)
- return;
- Path file = dir.resolve("foo").createFile();
- try {
- // ln -s foo link
- Path link = dir.resolve("link").createSymbolicLink(file);
-
- // open with NOFOLLOW_LINKS option
- try {
- link.newByteChannel(READ, LinkOption.NOFOLLOW_LINKS);
- throw new RuntimeException();
- } catch (IOException x) {
- } finally {
- TestUtil.deleteUnchecked(link);
- }
-
- } finally {
- // clean-up
- TestUtil.deleteUnchecked(file);
- }
- }
-
- // test size/truncate/position methods
- static void sizeTruncatePositionTests(Path dir) throws Exception {
- Path file = dir.resolve("foo");
- try {
- SeekableByteChannel sbc = file
- .newByteChannel(CREATE_NEW, READ, WRITE);
- try {
- if (sbc.size() != 0L)
- throw new RuntimeException("Unexpected size");
-
- // check size
- write(sbc, "hello");
- if (sbc.size() != 5L)
- throw new RuntimeException("Unexpected size");
-
- // truncate (size and position should change)
- sbc.truncate(4L);
- if (sbc.size() != 4L)
- throw new RuntimeException("Unexpected size");
- if (sbc.position() != 4L)
- throw new RuntimeException("Unexpected position");
-
- // truncate (position should not change)
- sbc.position(2L).truncate(3L);
- if (sbc.size() != 3L)
- throw new RuntimeException("Unexpected size");
- if (sbc.position() != 2L)
- throw new RuntimeException("Unexpected position");
- } finally {
- sbc.close();
- }
- } finally {
- TestUtil.deleteUnchecked(file);
- }
- }
-
- // Windows specific options for the use by applications that really want
- // to use legacy DOS sharing options
- static void dosSharingOptionTests(Path dir) throws Exception {
- Path file = dir.resolve("foo").createFile();
- try {
- SeekableByteChannel ch;
-
- // no sharing
- ch = file.newByteChannel(READ,
- NOSHARE_READ, NOSHARE_WRITE, NOSHARE_DELETE);
- try {
- try {
- file.newByteChannel(READ);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- try {
- file.newByteChannel(WRITE);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- try {
- file.delete();
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- } finally {
- ch.close();
- }
-
- // read allowed
- ch = file.newByteChannel(READ, NOSHARE_WRITE, NOSHARE_DELETE);
- try {
- file.newByteChannel(READ).close();
- try {
- file.newByteChannel(WRITE);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- try {
- file.delete();
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- } finally {
- ch.close();
- }
-
- // write allowed
- ch = file.newByteChannel(READ, NOSHARE_READ, NOSHARE_DELETE);
- try {
- try {
- file.newByteChannel(READ);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- file.newByteChannel(WRITE).close();
- try {
- file.delete();
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- } finally {
- ch.close();
- }
-
- // delete allowed
- ch = file.newByteChannel(READ, NOSHARE_READ, NOSHARE_WRITE);
- try {
- try {
- file.newByteChannel(READ);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- try {
- file.newByteChannel(WRITE);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- file.delete();
- } finally {
- ch.close();
- }
-
- } finally {
- TestUtil.deleteUnchecked(file);
- }
- }
-
- // invalid combinations of options
- static void badCombinations(Path dir) throws Exception {
- Path file = dir.resolve("bad");
-
- try {
- file.newByteChannel(READ, APPEND);
- throw new RuntimeException("IllegalArgumentException expected");
- } catch (IllegalArgumentException x) { }
-
- try {
- file.newByteChannel(WRITE, APPEND, TRUNCATE_EXISTING);
- throw new RuntimeException("IllegalArgumentException expected");
- } catch (IllegalArgumentException x) { }
- }
-
- // unsupported operations
- static void unsupportedOptions(Path dir) throws Exception {
- Path file = dir.resolve("bad");
-
- OpenOption badOption = new OpenOption() { };
- try {
- file.newByteChannel(badOption);
- throw new RuntimeException("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) { }
- try {
- file.newByteChannel(READ, WRITE, badOption);
- throw new RuntimeException("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) { }
- }
-
- // null handling
- static void nullTests(Path dir) throws Exception {
- Path file = dir.resolve("foo");
-
- try {
- file.newByteChannel((OpenOption[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
-
- try {
- OpenOption[] opts = { READ, null };
- file.newByteChannel(opts);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
-
- try {
- file.newByteChannel((Set<OpenOption>)null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
-
- try {
- Set<OpenOption> opts = new HashSet<OpenOption>();
- opts.add(READ);
- opts.add(null);
- file.newByteChannel(opts);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
-
- try {
- EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
- file.newByteChannel(opts, (FileAttribute[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
-
- try {
- EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
- FileAttribute[] attrs = { null };
- file.newByteChannel(opts, attrs);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- }
-
- static void write(WritableByteChannel wbc, String msg) throws IOException {
- ByteBuffer buf = ByteBuffer.wrap(msg.getBytes());
- while (buf.hasRemaining())
- wbc.write(buf);
- }
-}
--- a/jdk/test/java/nio/file/Path/TemporaryFiles.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333
- * @summary Unit test for File.createTemporaryXXX (to be be moved to test/java/io/File)
- * @library ..
- */
-
-import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import java.nio.file.attribute.*;
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-
-public class TemporaryFiles {
-
- static void checkInTempDirectory(Path file) {
- Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
- if (!file.getParent().equals(tmpdir))
- throw new RuntimeException("Not in temporary directory");
- }
-
- static void checkFile(Path file) throws IOException {
- // check file is in temporary directory
- checkInTempDirectory(file);
-
- // check that file can be opened for reading and writing
- file.newByteChannel(READ).close();
- file.newByteChannel(WRITE).close();
- file.newByteChannel(READ,WRITE).close();
-
- // check file permissions are 0600 or more secure
- if (file.getFileStore().supportsFileAttributeView("posix")) {
- Set<PosixFilePermission> perms = Attributes
- .readPosixFileAttributes(file).permissions();
- perms.remove(PosixFilePermission.OWNER_READ);
- perms.remove(PosixFilePermission.OWNER_WRITE);
- if (!perms.isEmpty())
- throw new RuntimeException("Temporary file is not secure");
- }
- }
-
- static void checkDirectory(Path dir) throws IOException {
- // check directory is in temporary directory
- checkInTempDirectory(dir);
-
- // check directory is empty
- DirectoryStream<Path> stream = dir.newDirectoryStream();
- try {
- if (stream.iterator().hasNext())
- throw new RuntimeException("Tempory directory not empty");
- } finally {
- stream.close();
- }
-
- // check file permissions are 0700 or more secure
- if (dir.getFileStore().supportsFileAttributeView("posix")) {
- Set<PosixFilePermission> perms = Attributes
- .readPosixFileAttributes(dir).permissions();
- perms.remove(PosixFilePermission.OWNER_READ);
- perms.remove(PosixFilePermission.OWNER_WRITE);
- perms.remove(PosixFilePermission.OWNER_EXECUTE);
- if (!perms.isEmpty())
- throw new RuntimeException("Temporary directory is not secure");
- }
- }
-
- public static void main(String[] args) throws IOException {
- Path file = File.createTemporaryFile("blah", null).toPath();
- try {
- checkFile(file);
- } finally {
- TestUtil.deleteUnchecked(file);
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/UriImportExport.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/Path/UriImportExport.java Mon Feb 14 16:30:10 2011 -0800
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4313887
+ * @bug 4313887 7003155
* @summary Unit test for java.nio.file.Path
*/
@@ -36,42 +36,105 @@
static final PrintStream log = System.out;
static int failures = 0;
- static void test(String fn, String expected) {
+ /**
+ * Test Path -> URI -> Path
+ */
+ static void testPath(String s) {
+ Path path = Paths.get(s);
+ log.println(path);
+ URI uri = path.toUri();
+ log.println(" --> " + uri);
+ Path result = Paths.get(uri);
+ log.println(" --> " + result);
+ if (!result.equals(path.toAbsolutePath())) {
+ log.println("FAIL: Expected " + path + ", got " + result);
+ failures++;
+ }
log.println();
- Path p = Paths.get(fn);
- log.println(p);
- URI u = p.toUri();
- log.println(" --> " + u);
- if (expected != null && !(u.toString().equals(expected))) {
- log.println("FAIL: Expected " + expected);
- failures++;
- return;
- }
- Path q = Paths.get(u);
- log.println(" --> " + q);
- if (!p.toAbsolutePath().equals(q)) {
- log.println("FAIL: Expected " + p + ", got " + q);
+ }
+
+ /**
+ * Test Path -> (expected) URI -> Path
+ */
+ static void testPath(String s, String expectedUri) {
+ Path path = Paths.get(s);
+ log.println(path);
+ URI uri = path.toUri();
+ log.println(" --> " + uri);
+ if (!uri.toString().equals(expectedUri)) {
+ log.println("FAILED: Expected " + expectedUri + ", got " + uri);
failures++;
return;
}
+ Path result = Paths.get(uri);
+ log.println(" --> " + result);
+ if (!result.equals(path.toAbsolutePath())) {
+ log.println("FAIL: Expected " + path + ", got " + result);
+ failures++;
+ }
+ log.println();
}
- static void test(String fn) {
- test(fn, null);
+ /**
+ * Test URI -> Path -> URI
+ */
+ static void testUri(String s) throws Exception {
+ URI uri = URI.create(s);
+ log.println(uri);
+ Path path = Paths.get(uri);
+ log.println(" --> " + path);
+ URI result = path.toUri();
+ log.println(" --> " + result);
+ if (!result.equals(uri)) {
+ log.println("FAIL: Expected " + uri + ", got " + result);
+ failures++;
+ }
+ log.println();
+ }
+
+ /**
+ * Test URI -> Path fails with IllegalArgumentException
+ */
+ static void testBadUri(String s) throws Exception {
+ URI uri = URI.create(s);
+ log.println(uri);
+ try {
+ Path path = Paths.get(uri);
+ log.format(" --> %s FAIL: Expected IllegalArgumentException\n", path);
+ failures++;
+ } catch (IllegalArgumentException expected) {
+ log.println(" --> IllegalArgumentException (expected)");
+ }
+ log.println();
}
public static void main(String[] args) throws Exception {
- test("foo");
- test("/foo");
- test("/foo bar");
+ testBadUri("file:foo");
+ testBadUri("file:/foo?q");
+ testBadUri("file:/foo#f");
String osname = System.getProperty("os.name");
if (osname.startsWith("Windows")) {
- test("C:\\foo");
- test("C:foo");
- test("\\\\rialto.dublin.com\\share\\");
- test("\\\\fe80--203-baff-fe5a-749ds1.ipv6-literal.net\\share\\missing",
+ testPath("C:\\doesnotexist");
+ testPath("C:doesnotexist");
+ testPath("\\\\server.nowhere.oracle.com\\share\\");
+ testPath("\\\\fe80--203-baff-fe5a-749ds1.ipv6-literal.net\\share\\missing",
"file://[fe80::203:baff:fe5a:749d%1]/share/missing");
+ } else {
+ testPath("doesnotexist");
+ testPath("/doesnotexist");
+ testPath("/does not exist");
+ testUri("file:///");
+ testUri("file:///foo/bar/doesnotexist");
+ testUri("file:/foo/bar/doesnotexist");
+
+ // file:///foo/bar/\u0440\u0443\u0441\u0441\u043A\u0438\u0439 (Russian)
+ testUri("file:///foo/bar/%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9");
+
+ // invalid
+ testBadUri("file:foo");
+ testBadUri("file://server/foo");
+ testBadUri("file:///foo%00");
}
if (failures > 0)
--- a/jdk/test/java/nio/file/Path/delete_on_close.sh Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-#
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 4313887
-# @summary Unit test for DELETE_ON_CLOSE open option
-# @library ..
-# @build DeleteOnClose
-# @run shell delete_on_close.sh
-
-# if TESTJAVA isn't set then we assume an interactive run.
-
-if [ -z "$TESTJAVA" ]; then
- TESTSRC=.
- TESTCLASSES=.
- JAVA=java
-else
- JAVA="${TESTJAVA}/bin/java"
-fi
-
-OS=`uname -s`
-case "$OS" in
- Windows_* | CYGWIN* )
- CLASSPATH="${TESTCLASSES};${TESTSRC}"
- ;;
- * )
- CLASSPATH=${TESTCLASSES}:${TESTSRC}
- ;;
-esac
-export CLASSPATH
-
-TMPFILE="$$.tmp"
-touch $TMPFILE
-$JAVA DeleteOnClose $TMPFILE 2>&1
-if [ $? != 0 ]; then exit 1; fi
-if [ -f $TMPFILE ]; then
- echo "$TMPFILE was not deleted"
- exit 1
-fi
-
-exit 0
--- a/jdk/test/java/nio/file/TestUtil.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/TestUtil.java Mon Feb 14 16:30:10 2011 -0800
@@ -31,17 +31,12 @@
}
static Path createTemporaryDirectory(String where) throws IOException {
- Path top = FileSystems.getDefault().getPath(where);
- Random r = new Random();
- Path dir;
- do {
- dir = top.resolve("name" + r.nextInt());
- } while (dir.exists());
- return dir.createDirectory();
+ Path dir = FileSystems.getDefault().getPath(where);
+ return Files.createTempDirectory(dir, "name");
}
static Path createTemporaryDirectory() throws IOException {
- return createTemporaryDirectory(System.getProperty("java.io.tmpdir"));
+ return Files.createTempDirectory("name");
}
static void removeAll(Path dir) throws IOException {
@@ -53,7 +48,7 @@
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
try {
- file.delete();
+ Files.delete(file);
} catch (IOException x) {
System.err.format("Unable to delete %s: %s\n", file, x);
}
@@ -62,7 +57,7 @@
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
try {
- dir.delete();
+ Files.delete(dir);
} catch (IOException x) {
System.err.format("Unable to delete %s: %s\n", dir, x);
}
@@ -78,7 +73,7 @@
static void deleteUnchecked(Path file) {
try {
- file.delete();
+ Files.delete(file);
} catch (IOException exc) {
System.err.format("Unable to delete %s: %s\n", file, exc);
}
@@ -99,7 +94,7 @@
String name = sb.toString();
do {
dir = dir.resolve(name).resolve(".");
- dir.createDirectory();
+ Files.createDirectory(dir);
} while (dir.toString().length() < 2048);
return dir;
}
@@ -111,8 +106,8 @@
Path link = dir.resolve("testlink");
Path target = dir.resolve("testtarget");
try {
- link.createSymbolicLink(target);
- link.delete();
+ Files.createSymbolicLink(link, target);
+ Files.delete(link);
return true;
} catch (UnsupportedOperationException x) {
return false;
--- a/jdk/test/java/nio/file/WatchService/Basic.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -41,8 +41,9 @@
public class Basic {
- static void createFile(Path file) throws IOException {
- file.newOutputStream().close();
+ static void checkKey(WatchKey key, Path dir) {
+ if (!key.isValid())
+ throw new RuntimeException("Key is not valid");
}
static void takeExpectedKey(WatchService watcher, WatchKey expected) {
@@ -80,19 +81,19 @@
FileSystem fs = FileSystems.getDefault();
Path name = fs.getPath("foo");
- WatchService watcher = fs.newWatchService();
- try {
+ try (WatchService watcher = fs.newWatchService()) {
// --- ENTRY_CREATE ---
// register for event
System.out.format("register %s for ENTRY_CREATE\n", dir);
WatchKey myKey = dir.register(watcher,
new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+ checkKey(myKey, dir);
// create file
Path file = dir.resolve("foo");
System.out.format("create %s\n", file);
- createFile(file);
+ Files.createFile(file);
// remove key and check that we got the ENTRY_CREATE event
takeExpectedKey(watcher, myKey);
@@ -112,9 +113,10 @@
new WatchEvent.Kind<?>[]{ ENTRY_DELETE });
if (deleteKey != myKey)
throw new RuntimeException("register did not return existing key");
+ checkKey(deleteKey, dir);
System.out.format("delete %s\n", file);
- file.delete();
+ Files.delete(file);
takeExpectedKey(watcher, myKey);
checkExpectedEvent(myKey.pollEvents(),
StandardWatchEventKind.ENTRY_DELETE, name);
@@ -126,7 +128,7 @@
System.out.println("OKAY");
// create the file for the next test
- createFile(file);
+ Files.createFile(file);
// --- ENTRY_MODIFY ---
@@ -135,13 +137,11 @@
new WatchEvent.Kind<?>[]{ ENTRY_MODIFY });
if (newKey != myKey)
throw new RuntimeException("register did not return existing key");
+ checkKey(newKey, dir);
System.out.format("update: %s\n", file);
- OutputStream out = file.newOutputStream(StandardOpenOption.APPEND);
- try {
+ try (OutputStream out = Files.newOutputStream(file, StandardOpenOption.APPEND)) {
out.write("I am a small file".getBytes("UTF-8"));
- } finally {
- out.close();
}
// remove key and check that we got the ENTRY_MODIFY event
@@ -151,10 +151,7 @@
System.out.println("OKAY");
// done
- file.delete();
-
- } finally {
- watcher.close();
+ Files.delete(file);
}
}
@@ -164,12 +161,12 @@
static void testCancel(Path dir) throws IOException {
System.out.println("-- Cancel --");
- WatchService watcher = FileSystems.getDefault().newWatchService();
- try {
+ try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
System.out.format("register %s for events\n", dir);
WatchKey myKey = dir.register(watcher,
new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+ checkKey(myKey, dir);
System.out.println("cancel key");
myKey.cancel();
@@ -177,7 +174,7 @@
// create a file in the directory
Path file = dir.resolve("mars");
System.out.format("create: %s\n", file);
- createFile(file);
+ Files.createFile(file);
// poll for keys - there will be none
System.out.println("poll...");
@@ -190,12 +187,9 @@
}
// done
- file.delete();
+ Files.delete(file);
System.out.println("OKAY");
-
- } finally {
- watcher.close();
}
}
@@ -206,17 +200,16 @@
static void testAutomaticCancel(Path dir) throws IOException {
System.out.println("-- Automatic Cancel --");
- Path subdir = dir.resolve("bar").createDirectory();
+ Path subdir = Files.createDirectory(dir.resolve("bar"));
- WatchService watcher = FileSystems.getDefault().newWatchService();
- try {
+ try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
System.out.format("register %s for events\n", subdir);
WatchKey myKey = subdir.register(watcher,
new WatchEvent.Kind<?>[]{ ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY });
System.out.format("delete: %s\n", subdir);
- subdir.delete();
+ Files.delete(subdir);
takeExpectedKey(watcher, myKey);
System.out.println("reset key");
@@ -227,8 +220,6 @@
System.out.println("OKAY");
- } finally {
- watcher.close();
}
}
@@ -411,7 +402,7 @@
// create gus1
Path file1 = dir.resolve(name1);
System.out.format("create %s\n", file1);
- createFile(file1);
+ Files.createFile(file1);
// register with both watch services (different events)
System.out.println("register for different events");
@@ -426,7 +417,7 @@
// create gus2
Path file2 = dir.resolve(name2);
System.out.format("create %s\n", file2);
- createFile(file2);
+ Files.createFile(file2);
// check that key1 got ENTRY_CREATE
takeExpectedKey(watcher1, key1);
@@ -439,7 +430,7 @@
throw new RuntimeException("key not expected");
// delete gus1
- file1.delete();
+ Files.delete(file1);
// check that key2 got ENTRY_DELETE
takeExpectedKey(watcher2, key2);
@@ -462,7 +453,7 @@
// create file and key2 should be queued
System.out.format("create %s\n", file1);
- createFile(file1);
+ Files.createFile(file1);
takeExpectedKey(watcher2, key2);
checkExpectedEvent(key2.pollEvents(),
StandardWatchEventKind.ENTRY_CREATE, name1);
--- a/jdk/test/java/nio/file/WatchService/FileTreeModifier.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/FileTreeModifier.java Mon Feb 14 16:30:10 2011 -0800
@@ -62,10 +62,7 @@
WatchService watcher = fs.newWatchService();
// create directories
- Path subdir = top
- .resolve("a").createDirectory()
- .resolve("b").createDirectory()
- .resolve("c").createDirectory();
+ Path subdir = Files.createDirectories(top.resolve("a").resolve("b").resolve("c"));
// Test ENTRY_CREATE with FILE_TREE modifier.
@@ -73,7 +70,7 @@
new WatchEvent.Kind<?>[]{ ENTRY_CREATE }, FILE_TREE);
// create file in a/b/c and check we get create event
- Path file = subdir.resolve("foo").createFile();
+ Path file = Files.createFile(subdir.resolve("foo"));
checkExpectedEvent(watcher, ENTRY_CREATE, top.relativize(file));
key.reset();
@@ -85,7 +82,7 @@
throw new RuntimeException("Existing key not returned");
// delete a/b/c/foo and check we get delete event
- file.delete();
+ Files.delete(file);
checkExpectedEvent(watcher, ENTRY_DELETE, top.relativize(file));
key.reset();
@@ -96,19 +93,20 @@
throw new RuntimeException("Existing key not returned");
// create a/b/c/foo
- file.createFile();
+ Files.createFile(file);
// check that key is not queued
+ WatchKey nextKey;
try {
- k = watcher.poll(3, TimeUnit.SECONDS);
+ nextKey = watcher.poll(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException();
}
- if (k != null)
+ if (nextKey != null)
throw new RuntimeException("WatchKey not expected to be polled");
// create bar and check we get create event
- file = top.resolve("bar").createFile();
+ file = Files.createFile(top.resolve("bar"));
checkExpectedEvent(watcher, ENTRY_CREATE, top.relativize(file));
key.reset();
@@ -121,11 +119,8 @@
throw new RuntimeException("Existing key not returned");
// modify bar and check we get modify event
- OutputStream out = file.newOutputStream();
- try {
+ try (OutputStream out = Files.newOutputStream(file)) {
out.write("Double shot expresso please".getBytes("UTF-8"));
- } finally {
- out.close();
}
checkExpectedEvent(watcher, ENTRY_MODIFY, top.relativize(file));
key.reset();
--- a/jdk/test/java/nio/file/WatchService/LotsOfEvents.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/LotsOfEvents.java Mon Feb 14 16:30:10 2011 -0800
@@ -55,15 +55,14 @@
static void testOverflowEvent(Path dir)
throws IOException, InterruptedException
{
- WatchService watcher = dir.getFileSystem().newWatchService();
- try {
+ try (WatchService watcher = dir.getFileSystem().newWatchService()) {
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE);
// create a lot of files
int n = 1024;
Path[] files = new Path[n];
for (int i=0; i<n; i++) {
- files[i] = dir.resolve("foo" + i).createFile();
+ files[i] = Files.createFile(dir.resolve("foo" + i));
}
// give time for events to accumulate (improve chance of overflow)
@@ -74,7 +73,7 @@
// delete the files
for (int i=0; i<n; i++) {
- files[i].delete();
+ Files.delete(files[i]);
}
// give time for events to accumulate (improve chance of overflow)
@@ -82,8 +81,6 @@
// check that we see the delete events (or overflow)
drainAndCheckOverflowEvents(watcher, ENTRY_DELETE, n);
- } finally {
- watcher.close();
}
}
@@ -147,8 +144,7 @@
entries[i].create();
}
- WatchService watcher = dir.getFileSystem().newWatchService();
- try {
+ try (WatchService watcher = dir.getFileSystem().newWatchService()) {
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
// do several rounds of noise and test
@@ -169,7 +165,7 @@
// events for the same file.
WatchKey key = watcher.poll(15, TimeUnit.SECONDS);
while (key != null) {
- Set<Path> modified = new HashSet<Path>();
+ Set<Path> modified = new HashSet<>();
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
Path file = (kind == OVERFLOW) ? null : (Path)event.context();
@@ -188,9 +184,6 @@
key = watcher.poll(2, TimeUnit.SECONDS);
}
}
-
- } finally {
- watcher.close();
}
}
@@ -200,20 +193,17 @@
this.file = file;
}
void create() throws IOException {
- if (file.notExists())
- file.createFile();
+ if (Files.notExists(file))
+ Files.createFile(file);
}
void deleteIfExists() throws IOException {
- file.deleteIfExists();
+ Files.deleteIfExists(file);
}
void modifyIfExists() throws IOException {
- if (file.exists()) {
- OutputStream out = file.newOutputStream(StandardOpenOption.APPEND);
- try {
+ if (Files.exists(file)) {
+ try (OutputStream out = Files.newOutputStream(file, StandardOpenOption.APPEND)) {
out.write("message".getBytes());
- } finally {
- out.close();
}
}
}
--- a/jdk/test/java/nio/file/WatchService/SensitivityModifier.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/SensitivityModifier.java Mon Feb 14 16:30:10 2011 -0800
@@ -51,6 +51,7 @@
}
}
+ @SuppressWarnings("unchecked")
static void doTest(Path top) throws Exception {
FileSystem fs = top.getFileSystem();
WatchService watcher = fs.newWatchService();
@@ -61,11 +62,11 @@
Path[] dirs = new Path[nDirs];
Path[] files = new Path[nFiles];
for (int i=0; i<nDirs; i++) {
- dirs[i] = top.resolve("dir" + i).createDirectory();
+ dirs[i] = Files.createDirectory(top.resolve("dir" + i));
}
for (int i=0; i<nFiles; i++) {
Path dir = dirs[rand.nextInt(nDirs)];
- files[i] = dir.resolve("file" + i).createFile();
+ files[i] = Files.createFile(dir.resolve("file" + i));
}
// register the directories (random sensitivity)
@@ -80,11 +81,8 @@
for (int i=0; i<10; i++) {
Path file = files[rand.nextInt(nFiles)];
System.out.println("Modify: " + file);
- OutputStream out = file.newOutputStream();
- try {
+ try (OutputStream out = Files.newOutputStream(file)) {
out.write(new byte[100]);
- } finally {
- out.close();
}
System.out.println("Waiting for event...");
WatchKey key = watcher.take();
@@ -92,7 +90,7 @@
if (event.kind() != ENTRY_MODIFY)
throw new RuntimeException("Unexpected event: " + event);
Path name = ((WatchEvent<Path>)event).context();
- if (!name.equals(file.getName()))
+ if (!name.equals(file.getFileName()))
throw new RuntimeException("Unexpected context: " + name);
System.out.println("Event OK");
--- a/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -47,11 +47,11 @@
// sanity check read and writing ACL
static void testReadWrite(Path dir) throws IOException {
Path file = dir.resolve("foo");
- if (file.notExists())
- file.createFile();
+ if (Files.notExists(file))
+ Files.createFile(file);
- AclFileAttributeView view = file
- .getFileAttributeView(AclFileAttributeView.class);
+ AclFileAttributeView view =
+ Files.getFileAttributeView(file, AclFileAttributeView.class);
// print existing ACL
List<AclEntry> acl = view.getAcl();
@@ -79,7 +79,7 @@
}
// if PosixFileAttributeView then repeat test with OWNER@
- if (file.getFileStore().supportsFileAttributeView("posix")) {
+ if (Files.getFileStore(file).supportsFileAttributeView("posix")) {
owner = file.getFileSystem().getUserPrincipalLookupService()
.lookupPrincipalByName("OWNER@");
entry = AclEntry.newBuilder(entry).setPrincipal(owner).build();
@@ -115,7 +115,8 @@
// sanity check create a file or directory with initial ACL
static void testCreateFile(Path dir) throws IOException {
- UserPrincipal user = Attributes.getOwner(dir);
+ UserPrincipal user = Files.getOwner(dir);
+ AclFileAttributeView view;
// create file with initial ACL
System.out.println("-- create file with initial ACL --");
@@ -127,8 +128,9 @@
.setPermissions(SYNCHRONIZE, READ_DATA, WRITE_DATA,
READ_ATTRIBUTES, READ_ACL, WRITE_ATTRIBUTES, DELETE)
.build());
- file.createFile(asAclAttribute(fileAcl));
- assertEquals(Attributes.getAcl(file), fileAcl);
+ Files.createFile(file, asAclAttribute(fileAcl));
+ view = Files.getFileAttributeView(file, AclFileAttributeView.class);
+ assertEquals(view.getAcl(), fileAcl);
// create directory with initial ACL
System.out.println("-- create directory with initial ACL --");
@@ -142,17 +144,18 @@
AclEntry.newBuilder(fileAcl.get(0))
.setFlags(FILE_INHERIT)
.build());
- subdir.createDirectory(asAclAttribute(dirAcl));
- assertEquals(Attributes.getAcl(subdir), dirAcl);
+ Files.createDirectory(subdir, asAclAttribute(dirAcl));
+ view = Files.getFileAttributeView(subdir, AclFileAttributeView.class);
+ assertEquals(view.getAcl(), dirAcl);
}
public static void main(String[] args) throws IOException {
// use work directory rather than system temporary directory to
// improve chances that ACLs are supported
- Path dir = Paths.get("./work" + new Random().nextInt())
- .createDirectory();
+ Path dir = Paths.get("./work" + new Random().nextInt());
+ Files.createDirectory(dir);
try {
- if (!dir.getFileStore().supportsFileAttributeView("acl")) {
+ if (!Files.getFileStore(dir).supportsFileAttributeView("acl")) {
System.out.println("ACLs not supported - test skipped!");
return;
}
--- a/jdk/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -43,7 +43,7 @@
static void checkAttributesOfDirectory(Path dir)
throws IOException
{
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir);
+ BasicFileAttributes attrs = Files.readAttributes(dir, BasicFileAttributes.class);
check(attrs.isDirectory(), "is a directory");
check(!attrs.isRegularFile(), "is not a regular file");
check(!attrs.isSymbolicLink(), "is not a link");
@@ -58,7 +58,7 @@
static void checkAttributesOfFile(Path dir, Path file)
throws IOException
{
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+ BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
check(attrs.isRegularFile(), "is a regular file");
check(!attrs.isDirectory(), "is not a directory");
check(!attrs.isSymbolicLink(), "is not a link");
@@ -73,8 +73,8 @@
// copy last-modified time and file create time from directory to file,
// re-read attribtues, and check they match
BasicFileAttributeView view =
- file.getFileAttributeView(BasicFileAttributeView.class);
- BasicFileAttributes dirAttrs = Attributes.readBasicFileAttributes(dir);
+ Files.getFileAttributeView(file, BasicFileAttributeView.class);
+ BasicFileAttributes dirAttrs = Files.readAttributes(dir, BasicFileAttributes.class);
view.setTimes(dirAttrs.lastModifiedTime(), null, null);
if (dirAttrs.creationTime() != null) {
view.setTimes(null, null, dirAttrs.creationTime());
@@ -95,8 +95,8 @@
static void checkAttributesOfLink(Path link)
throws IOException
{
- BasicFileAttributes attrs = Attributes
- .readBasicFileAttributes(link, LinkOption.NOFOLLOW_LINKS);
+ BasicFileAttributes attrs =
+ Files.readAttributes(link, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
check(attrs.isSymbolicLink(), "is a link");
check(!attrs.isDirectory(), "is a directory");
check(!attrs.isRegularFile(), "is not a regular file");
@@ -108,11 +108,8 @@
{
// create file
Path file = dir.resolve("foo");
- OutputStream out = file.newOutputStream();
- try {
+ try (OutputStream out = Files.newOutputStream(file)) {
out.write("this is not an empty file".getBytes("UTF-8"));
- } finally {
- out.close();
}
// check attributes of directory and file
@@ -122,7 +119,7 @@
// symbolic links may be supported
Path link = dir.resolve("link");
try {
- link.createSymbolicLink( file );
+ Files.createSymbolicLink(link, file);
} catch (UnsupportedOperationException x) {
return;
} catch (IOException x) {
--- a/jdk/test/java/nio/file/attribute/DosFileAttributeView/Basic.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/DosFileAttributeView/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -74,27 +74,25 @@
static void readWriteTests(Path dir) throws IOException {
// create "foo" and test that we can read/write each FAT attribute
- Path file = dir.resolve("foo");
- file.createFile();
+ Path file = Files.createFile(dir.resolve("foo"));
try {
- testAttributes(file
- .getFileAttributeView(DosFileAttributeView.class));
+ testAttributes(Files.getFileAttributeView(file, DosFileAttributeView.class));
// Following tests use a symbolic link so skip if not supported
if (!TestUtil.supportsLinks(dir))
return;
- Path link = dir.resolve("link").createSymbolicLink(file);
+ Path link = dir.resolve("link");
+ Files.createSymbolicLink(link, file);
// test following links
- testAttributes(link
- .getFileAttributeView(DosFileAttributeView.class));
+ testAttributes(Files.getFileAttributeView(link, DosFileAttributeView.class));
// test not following links
try {
try {
- testAttributes(link
- .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS));
+ testAttributes(Files
+ .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS));
} catch (IOException x) {
// access to link attributes not supported
return;
@@ -103,32 +101,32 @@
// set all attributes on link
// run test on target of link (which leaves them all un-set)
// check that attributes of link remain all set
- setAll(link
- .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS), true);
- testAttributes(link
- .getFileAttributeView(DosFileAttributeView.class));
- DosFileAttributes attrs = Attributes.readDosFileAttributes(link, NOFOLLOW_LINKS);
+ setAll(Files
+ .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS), true);
+ testAttributes(Files
+ .getFileAttributeView(link, DosFileAttributeView.class));
+ DosFileAttributes attrs =
+ Files.getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS)
+ .readAttributes();
check(attrs.isReadOnly());
check(attrs.isHidden());
check(attrs.isArchive());
check(attrs.isSystem());
- setAll(link
- .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS), false);
+ setAll(Files
+ .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS), false);
// set all attributes on target
// run test on link (which leaves them all un-set)
// check that attributes of target remain all set
- setAll(link
- .getFileAttributeView(DosFileAttributeView.class), true);
- testAttributes(link
- .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS));
- attrs = Attributes.readDosFileAttributes(link);
+ setAll(Files.getFileAttributeView(link, DosFileAttributeView.class), true);
+ testAttributes(Files
+ .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS));
+ attrs = Files.getFileAttributeView(link, DosFileAttributeView.class).readAttributes();
check(attrs.isReadOnly());
check(attrs.isHidden());
check(attrs.isArchive());
check(attrs.isSystem());
- setAll(link
- .getFileAttributeView(DosFileAttributeView.class), false);
+ setAll(Files.getFileAttributeView(link, DosFileAttributeView.class), false);
} finally {
TestUtil.deleteUnchecked(link);
}
@@ -143,7 +141,7 @@
try {
// skip test if DOS file attributes not supported
- if (!dir.getFileStore().supportsFileAttributeView("dos")) {
+ if (!Files.getFileStore(dir).supportsFileAttributeView("dos")) {
System.out.println("DOS file attribute not supported.");
return;
}
--- a/jdk/test/java/nio/file/attribute/FileStoreAttributeView/Basic.java Thu Feb 10 16:24:40 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333
- * @summary Unit test for java.nio.file.attribute.FileStoreAttributeView
- * @library ../..
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Simple unit test for FileStoreAttributeView that checks that the disk space
- * attribtues are "close" to the equivalent values reported by java.io.File.
- */
-
-public class Basic {
-
- static final long K = 1024L;
- static final long G = 1024L * 1024L * 1024L;
-
- /**
- * Print out the disk space information for the given file system
- */
- static void printFileStore(FileStore fs) throws IOException {
- FileStoreSpaceAttributeView view =
- fs.getFileStoreAttributeView(FileStoreSpaceAttributeView.class);
- FileStoreSpaceAttributes attrs = view.readAttributes();
-
- long total = attrs.totalSpace() / K;
- long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / K;
- long avail = attrs.usableSpace() / K;
-
- String s = fs.toString();
- if (s.length() > 20) {
- System.out.println(s);
- s = "";
- }
- System.out.format("%-20s %12d %12d %12d\n", s, total, used, avail);
- }
-
- /**
- * Check that two values are within 1GB of each other
- */
- static void checkWithin1GB(long value1, long value2) {
- long diff = Math.abs(value1 - value2);
- if (diff > G)
- throw new RuntimeException("values differ by more than 1GB");
- }
-
- /**
- * Check disk space on the file system of the given file
- */
- static void checkSpace(Path file) throws IOException {
- System.out.println(" -- check space -- ");
- System.out.println(file);
-
- FileStore fs = file.getFileStore();
- System.out.format("Filesystem: %s\n", fs);
-
- // get values reported by java.io.File
- File f = new File(file.toString());
- long total = f.getTotalSpace();
- long free = f.getFreeSpace();
- long usable = f.getUsableSpace();
- System.out.println("java.io.File");
- System.out.format(" Total: %d\n", total);
- System.out.format(" Free: %d\n", free);
- System.out.format(" Usable: %d\n", usable);
-
- // get values reported by the FileStoreSpaceAttributeView
- FileStoreSpaceAttributes attrs = fs
- .getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
- .readAttributes();
- System.out.println("java.nio.file.FileStoreSpaceAttributeView:");
- System.out.format(" Total: %d\n", attrs.totalSpace());
- System.out.format(" Free: %d\n", attrs.unallocatedSpace());
- System.out.format(" Usable: %d\n", attrs.usableSpace());
-
- // check values are "close"
- checkWithin1GB(total, attrs.totalSpace());
- checkWithin1GB(free, attrs.unallocatedSpace());
- checkWithin1GB(usable, attrs.usableSpace());
-
- // get values by name
- checkWithin1GB(total, (Long)fs.getAttribute("space:totalSpace"));
- checkWithin1GB(free, (Long)fs.getAttribute("space:unallocatedSpace"));
- checkWithin1GB(usable, (Long)fs.getAttribute("space:usableSpace"));
- }
-
- public static void main(String[] args) throws IOException {
- // print out the disk space information for all file systems
- FileSystem fs = FileSystems.getDefault();
- for (FileStore store: fs.getFileStores()) {
- printFileStore(store);
- }
-
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- // check space using directory
- checkSpace(dir);
-
- // check space using file
- Path file = dir.resolve("foo").createFile();
- checkSpace(file);
-
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-}
--- a/jdk/test/java/nio/file/attribute/FileTime/Basic.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/FileTime/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -29,13 +29,16 @@
import java.nio.file.attribute.FileTime;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.*;
-import java.io.IOException;
+import java.util.Random;
public class Basic {
- public static void main(String[] args) throws IOException {
+ static final Random rand = new Random();
+
+ public static void main(String[] args) {
long now = System.currentTimeMillis();
long tomorrowInDays = TimeUnit.DAYS.convert(now, MILLISECONDS) + 1;
+ long yesterdayInDays = TimeUnit.DAYS.convert(now, MILLISECONDS) - 1;
// equals
eq(now, MILLISECONDS, now, MILLISECONDS);
@@ -50,6 +53,29 @@
cmp(now, MILLISECONDS, now+1234, MILLISECONDS, -1);
cmp(tomorrowInDays, DAYS, now, MILLISECONDS, 1);
cmp(now, MILLISECONDS, tomorrowInDays, DAYS, -1);
+ cmp(yesterdayInDays, DAYS, now, MILLISECONDS, -1);
+ cmp(now, MILLISECONDS, yesterdayInDays, DAYS, 1);
+ cmp(yesterdayInDays, DAYS, now, MILLISECONDS, -1);
+ cmp(Long.MAX_VALUE, DAYS, Long.MAX_VALUE, NANOSECONDS, 1);
+ cmp(Long.MAX_VALUE, DAYS, Long.MIN_VALUE, NANOSECONDS, 1);
+ cmp(Long.MIN_VALUE, DAYS, Long.MIN_VALUE, NANOSECONDS, -1);
+ cmp(Long.MIN_VALUE, DAYS, Long.MAX_VALUE, NANOSECONDS, -1);
+
+ // to(TimeUnit)
+ to(MILLISECONDS.convert(1, DAYS) - 1, MILLISECONDS);
+ to(MILLISECONDS.convert(1, DAYS) + 0, MILLISECONDS);
+ to(MILLISECONDS.convert(1, DAYS) + 1, MILLISECONDS);
+ to(1, MILLISECONDS);
+ to(0, MILLISECONDS);
+ to(1, MILLISECONDS);
+ to(MILLISECONDS.convert(-1, DAYS) - 1, MILLISECONDS);
+ to(MILLISECONDS.convert(-1, DAYS) + 0, MILLISECONDS);
+ to(MILLISECONDS.convert(-1, DAYS) + 1, MILLISECONDS);
+ for (TimeUnit unit: TimeUnit.values()) {
+ for (int i=0; i<100; i++) { to(rand.nextLong(), unit); }
+ to(Long.MIN_VALUE, unit);
+ to(Long.MAX_VALUE, unit);
+ }
// toString
ts(1L, DAYS, "1970-01-02T00:00:00Z");
@@ -59,6 +85,8 @@
ts(1L, MILLISECONDS, "1970-01-01T00:00:00.001Z");
ts(1L, MICROSECONDS, "1970-01-01T00:00:00.000001Z");
ts(1L, NANOSECONDS, "1970-01-01T00:00:00.000000001Z");
+ ts(999999999L, NANOSECONDS, "1970-01-01T00:00:00.999999999Z");
+ ts(9999999999L, NANOSECONDS, "1970-01-01T00:00:09.999999999Z");
ts(-1L, DAYS, "1969-12-31T00:00:00Z");
ts(-1L, HOURS, "1969-12-31T23:00:00Z");
@@ -67,6 +95,8 @@
ts(-1L, MILLISECONDS, "1969-12-31T23:59:59.999Z");
ts(-1L, MICROSECONDS, "1969-12-31T23:59:59.999999Z");
ts(-1L, NANOSECONDS, "1969-12-31T23:59:59.999999999Z");
+ ts(-999999999L, NANOSECONDS, "1969-12-31T23:59:59.000000001Z");
+ ts(-9999999999L, NANOSECONDS, "1969-12-31T23:59:50.000000001Z");
ts(-62135596799999L, MILLISECONDS, "0001-01-01T00:00:00.001Z");
ts(-62135596800000L, MILLISECONDS, "0001-01-01T00:00:00Z");
@@ -114,9 +144,24 @@
throw new RuntimeException("should not be equal");
}
- static void ts(long v, TimeUnit y, String expected) {
- String s = FileTime.from(v, y).toString();
- if (!s.equals(expected))
- throw new RuntimeException("unexpected format");
+ static void to(long v, TimeUnit unit) {
+ FileTime t = FileTime.from(v, unit);
+ for (TimeUnit u: TimeUnit.values()) {
+ long result = t.to(u);
+ long expected = u.convert(v, unit);
+ if (result != expected) {
+ throw new RuntimeException("unexpected result");
+ }
+ }
+ }
+
+ static void ts(long v, TimeUnit unit, String expected) {
+ String result = FileTime.from(v, unit).toString();
+ if (!result.equals(expected)) {
+ System.err.format("FileTime.from(%d, %s).toString() failed\n", v, unit);
+ System.err.format("Expected: %s\n", expected);
+ System.err.format(" Got: %s\n", result);
+ throw new RuntimeException();
+ }
}
}
--- a/jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -49,9 +49,8 @@
Set<PosixFilePermission> perms = PosixFilePermissions.fromString(mode);
// change permissions and re-read them.
- Attributes.setPosixFilePermissions(file, perms);
- Set<PosixFilePermission> current = Attributes
- .readPosixFileAttributes(file).permissions();
+ Files.setPosixFilePermissions(file, perms);
+ Set<PosixFilePermission> current = Files.getPosixFilePermissions(file);
if (!current.equals(perms)) {
throw new RuntimeException("Actual permissions: " +
PosixFilePermissions.toString(current) + ", expected: " +
@@ -59,8 +58,8 @@
}
// repeat test using setAttribute/getAttribute
- file.setAttribute("posix:permissions", perms);
- current = (Set<PosixFilePermission>)file.getAttribute("posix:permissions");
+ Files.setAttribute(file, "posix:permissions", perms);
+ current = (Set<PosixFilePermission>)Files.getAttribute(file, "posix:permissions");
if (!current.equals(perms)) {
throw new RuntimeException("Actual permissions: " +
PosixFilePermissions.toString(current) + ", expected: " +
@@ -97,25 +96,25 @@
FileAttribute<Set<PosixFilePermission>> attr =
PosixFilePermissions.asFileAttribute(requested);
System.out.format("create file with mode: %s\n", mode);
- file.createFile(attr);
+ Files.createFile(file, attr);
try {
- checkSecure(requested, file
- .getFileAttributeView(PosixFileAttributeView.class)
- .readAttributes()
- .permissions());
+ checkSecure(requested,
+ Files.getFileAttributeView(file, PosixFileAttributeView.class)
+ .readAttributes()
+ .permissions());
} finally {
- file.delete();
+ Files.delete(file);
}
System.out.format("create directory with mode: %s\n", mode);
- file.createDirectory(attr);
+ Files.createDirectory(file, attr);
try {
- checkSecure(requested, file
- .getFileAttributeView(PosixFileAttributeView.class)
- .readAttributes()
- .permissions());
+ checkSecure(requested,
+ Files.getFileAttributeView(file, PosixFileAttributeView.class)
+ .readAttributes()
+ .permissions());
} finally {
- file.delete();
+ Files.delete(file);
}
}
@@ -130,11 +129,11 @@
// create file and test updating and reading its permissions
Path file = dir.resolve("foo");
System.out.format("create %s\n", file);
- file.createFile();
+ Files.createFile(file);
try {
// get initial permissions so that we can restore them later
- PosixFileAttributeView view = file
- .getFileAttributeView(PosixFileAttributeView.class);
+ PosixFileAttributeView view =
+ Files.getFileAttributeView(file, PosixFileAttributeView.class);
Set<PosixFilePermission> save = view.readAttributes()
.permissions();
@@ -165,7 +164,7 @@
view.setPermissions(save);
}
} finally {
- file.delete();
+ Files.delete(file);
}
// create link (to file that doesn't exist) and test reading of
@@ -173,15 +172,18 @@
if (TestUtil.supportsLinks(dir)) {
Path link = dir.resolve("link");
System.out.format("create link %s\n", link);
- link.createSymbolicLink(file);
+ Files.createSymbolicLink(link, file);
try {
- PosixFileAttributes attrs = Attributes
- .readPosixFileAttributes(link, NOFOLLOW_LINKS);
+ PosixFileAttributes attrs =
+ Files.getFileAttributeView(link,
+ PosixFileAttributeView.class,
+ NOFOLLOW_LINKS)
+ .readAttributes();
if (!attrs.isSymbolicLink()) {
throw new RuntimeException("not a link");
}
} finally {
- link.delete();
+ Files.delete(link);
}
}
@@ -235,12 +237,12 @@
Path file = dir.resolve("gus");
System.out.format("create %s\n", file);
- file.createFile();
+ Files.createFile(file);
try {
// read attributes of directory to get owner/group
- PosixFileAttributeView view = file
- .getFileAttributeView(PosixFileAttributeView.class);
+ PosixFileAttributeView view =
+ Files.getFileAttributeView(file, PosixFileAttributeView.class);
PosixFileAttributes attrs = view.readAttributes();
// set to existing owner/group
@@ -248,13 +250,13 @@
view.setGroup(attrs.group());
// repeat test using set/getAttribute
- UserPrincipal owner = (UserPrincipal)file.getAttribute("posix:owner");
- file.setAttribute("posix:owner", owner);
- UserPrincipal group = (UserPrincipal)file.getAttribute("posix:group");
- file.setAttribute("posix:group", group);
+ UserPrincipal owner = (UserPrincipal)Files.getAttribute(file, "posix:owner");
+ Files.setAttribute(file, "posix:owner", owner);
+ UserPrincipal group = (UserPrincipal)Files.getAttribute(file, "posix:group");
+ Files.setAttribute(file, "posix:group", group);
} finally {
- file.delete();
+ Files.delete(file);
}
System.out.println("OKAY");
@@ -272,7 +274,7 @@
.getUserPrincipalLookupService();
// read attributes of directory to get owner/group
- PosixFileAttributes attrs = Attributes.readPosixFileAttributes(dir);
+ PosixFileAttributes attrs = Files.readAttributes(dir, PosixFileAttributes.class);
// lookup owner and check it matches file's owner
System.out.format("lookup: %s\n", attrs.owner().getName());
@@ -322,8 +324,8 @@
{
System.out.println("-- Exceptions --");
- PosixFileAttributeView view = dir
- .getFileAttributeView(PosixFileAttributeView.class);
+ PosixFileAttributeView view =
+ Files.getFileAttributeView(dir,PosixFileAttributeView.class);
// NullPointerException
try {
@@ -355,7 +357,7 @@
} catch (NullPointerException x) {
}
try {
- Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
+ Set<PosixFilePermission> perms = new HashSet<>();
perms.add(null);
view.setPermissions(perms);
throw new RuntimeException("NullPointerException not thrown");
@@ -377,7 +379,7 @@
public static void main(String[] args) throws IOException {
Path dir = TestUtil.createTemporaryDirectory();
try {
- if (!dir.getFileStore().supportsFileAttributeView("posix")) {
+ if (!Files.getFileStore(dir).supportsFileAttributeView("posix")) {
System.out.println("PosixFileAttributeView not supported");
return;
}
--- a/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -79,8 +79,8 @@
}
static void test(Path file, LinkOption... options) throws IOException {
- final UserDefinedFileAttributeView view = file
- .getFileAttributeView(UserDefinedFileAttributeView.class, options);
+ final UserDefinedFileAttributeView view =
+ Files.getFileAttributeView(file, UserDefinedFileAttributeView.class, options);
ByteBuffer buf = rand.nextBoolean() ?
ByteBuffer.allocate(100) : ByteBuffer.allocateDirect(100);
@@ -131,24 +131,24 @@
// Test: dynamic access
String name = "user:" + ATTR_NAME;
byte[] valueAsBytes = ATTR_VALUE.getBytes();
- file.setAttribute(name, valueAsBytes);
- byte[] actualAsBytes = (byte[])file.getAttribute(name);
+ Files.setAttribute(file, name, valueAsBytes);
+ byte[] actualAsBytes = (byte[])Files.getAttribute(file, name);
if (!Arrays.equals(valueAsBytes, actualAsBytes))
throw new RuntimeException("Unexpected attribute value");
- Map<String,?> map = file.readAttributes(name);
+ Map<String,?> map = Files.readAttributes(file, name);
if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME)))
throw new RuntimeException("Unexpected attribute value");
- map = file.readAttributes("user:*");
+ map = Files.readAttributes(file, "user:*");
if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME)))
throw new RuntimeException("Unexpected attribute value");
- map = file.readAttributes("user:DoesNotExist");
+ map = Files.readAttributes(file, "user:DoesNotExist");
if (!map.isEmpty())
throw new RuntimeException("Map expected to be empty");
}
static void miscTests(final Path file) throws IOException {
- final UserDefinedFileAttributeView view = file
- .getFileAttributeView(UserDefinedFileAttributeView.class);
+ final UserDefinedFileAttributeView view =
+ Files.getFileAttributeView(file, UserDefinedFileAttributeView.class);
view.write(ATTR_NAME, ByteBuffer.wrap(ATTR_VALUE.getBytes()));
// NullPointerException
@@ -180,31 +180,31 @@
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.getAttribute(null);
+ Files.getAttribute(file, null);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.getAttribute("user:" + ATTR_NAME, (LinkOption[])null);
+ Files.getAttribute(file, "user:" + ATTR_NAME, (LinkOption[])null);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.setAttribute("user:" + ATTR_NAME, null);
+ Files.setAttribute(file, "user:" + ATTR_NAME, null);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.setAttribute(null, new byte[0]);
+ Files.setAttribute(file, null, new byte[0]);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.setAttribute("user: " + ATTR_NAME, new byte[0], (LinkOption[])null);
+ Files.setAttribute(file, "user: " + ATTR_NAME, new byte[0], (LinkOption[])null);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.readAttributes((String)null);
+ Files.readAttributes(file, (String)null);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.readAttributes("*", (LinkOption[])null);
+ Files.readAttributes(file, "*", (LinkOption[])null);
}});
// Read-only buffer
@@ -229,46 +229,50 @@
// create temporary directory to run tests
Path dir = TestUtil.createTemporaryDirectory();
try {
- if (!dir.getFileStore().supportsFileAttributeView("user")) {
+ if (!Files.getFileStore(dir).supportsFileAttributeView("user")) {
System.out.println("UserDefinedFileAttributeView not supported - skip test");
return;
}
// test access to user defined attributes of regular file
- Path file = dir.resolve("foo.html").createFile();
+ Path file = dir.resolve("foo.html");
+ Files.createFile(file);
try {
test(file);
} finally {
- file.delete();
+ Files.delete(file);
}
- // test access to user define attributes of directory
- file = dir.resolve("foo").createDirectory();
+ // test access to user defined attributes of directory
+ Path subdir = dir.resolve("foo");
+ Files.createDirectory(subdir);
try {
- test(file);
+ test(subdir);
} finally {
- file.delete();
+ Files.delete(subdir);
}
// test access to user defined attributes of sym link
if (TestUtil.supportsLinks(dir)) {
Path target = dir.resolve("doesnotexist");
- Path link = dir.resolve("link").createSymbolicLink(target);
+ Path link = dir.resolve("link");
+ Files.createSymbolicLink(link, target);
try {
test(link, NOFOLLOW_LINKS);
} catch (IOException x) {
// access to attributes of sym link may not be supported
} finally {
- link.delete();
+ Files.delete(link);
}
}
// misc. tests
try {
- file = dir.resolve("foo.txt").createFile();
+ file = dir.resolve("foo.txt");
+ Files.createFile(file);
miscTests(dir);
} finally {
- file.delete();
+ Files.delete(file);
}
} finally {
--- a/jdk/test/java/nio/file/spi/SetDefaultProvider.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/spi/SetDefaultProvider.java Mon Feb 14 16:30:10 2011 -0800
@@ -22,14 +22,13 @@
*/
/* @test
- * @bug 4313887
+ * @bug 4313887 7006126
* @summary Unit test for java.nio.file.spi.FileSystemProvider
* @build TestProvider SetDefaultProvider
* @run main/othervm -Djava.nio.file.spi.DefaultFileSystemProvider=TestProvider SetDefaultProvider
*/
import java.nio.file.*;
-import java.nio.file.spi.*;
public class SetDefaultProvider {
public static void main(String[] args) throws Exception {
--- a/jdk/test/java/nio/file/spi/TestProvider.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/nio/file/spi/TestProvider.java Mon Feb 14 16:30:10 2011 -0800
@@ -24,6 +24,7 @@
import java.nio.file.spi.FileSystemProvider;
import java.nio.file.*;
import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
import java.net.URI;
import java.util.*;
import java.io.IOException;
@@ -34,7 +35,6 @@
public TestProvider(FileSystemProvider defaultProvider) {
theFileSystem = new TestFileSystem(this);
-
}
@Override
@@ -57,6 +57,124 @@
throw new RuntimeException("not implemented");
}
+ @Override
+ public void setAttribute(Path file, String attribute, Object value,
+ LinkOption... options)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public Map<String,Object> readAttributes(Path file, String attributes,
+ LinkOption... options)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public <A extends BasicFileAttributes> A readAttributes(Path file,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public <V extends FileAttributeView> V getFileAttributeView(Path file,
+ Class<V> type,
+ LinkOption... options)
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+
+ @Override
+ public void delete(Path file) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public void createLink(Path link, Path existing) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public Path readSymbolicLink(Path link) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+
+ @Override
+ public void copy(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public void move(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(Path dir,
+ DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public void createDirectory(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path file,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+
+ @Override
+ public boolean isHidden(Path file) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public FileStore getFileStore(Path file) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public boolean isSameFile(Path file, Path other) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public void checkAccess(Path file, AccessMode... modes)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
static class TestFileSystem extends FileSystem {
private final TestProvider provider;
@@ -105,7 +223,7 @@
}
@Override
- public Path getPath(String path) {
+ public Path getPath(String first, String... more) {
throw new RuntimeException("not implemented");
}
@@ -124,5 +242,4 @@
throw new RuntimeException("not implemented");
}
}
-
}
--- a/jdk/test/java/util/Arrays/Sorting.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/util/Arrays/Sorting.java Mon Feb 14 16:30:10 2011 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6880672 6896573 6899694 6976036
+ * @bug 6880672 6896573 6899694 6976036 7013585 7018258
* @summary Exercise Arrays.sort
* @build Sorting
* @run main Sorting -shortrun
@@ -66,7 +66,7 @@
}
long end = System.currentTimeMillis();
- out.format("\nPASSED in %d sec.\n", Math.round((end - start) / 1E3));
+ out.format("PASSED in %d sec.\n", Math.round((end - start) / 1E3));
}
private static void testAndCheck(int[] lengths, long[] randoms) {
@@ -78,46 +78,19 @@
testEmptyAndNullFloatArray();
testEmptyAndNullDoubleArray();
- for (long random : randoms) {
- reset(random);
-
- for (int length : lengths) {
- testAndCheckWithInsertionSort(length, random);
- }
- reset(random);
-
- for (int length : lengths) {
- testAndCheckWithCheckSum(length, random);
- }
- reset(random);
-
- for (int length : lengths) {
- testAndCheckWithScrambling(length, random);
- }
- reset(random);
-
+ for (int length : lengths) {
+ testMergeSort(length);
+ testAndCheckRange(length);
+ testAndCheckSubArray(length);
+ }
+ for (long seed : randoms) {
for (int length : lengths) {
- testAndCheckFloat(length, random);
- }
- reset(random);
-
- for (int length : lengths) {
- testAndCheckDouble(length, random);
- }
- reset(random);
-
- for (int length : lengths) {
- testAndCheckRange(length, random);
- }
- reset(random);
-
- for (int length : lengths) {
- testAndCheckSubArray(length, random);
- }
- reset(random);
-
- for (int length : lengths) {
- testStable(length, random);
+ testAndCheckWithInsertionSort(length, new MyRandom(seed));
+ testAndCheckWithCheckSum(length, new MyRandom(seed));
+ testAndCheckWithScrambling(length, new MyRandom(seed));
+ testAndCheckFloat(length, new MyRandom(seed));
+ testAndCheckDouble(length, new MyRandom(seed));
+ testStable(length, new MyRandom(seed));
}
}
}
@@ -255,7 +228,7 @@
failed("Arrays.sort(double[]) shouldn't catch null array");
}
- private static void testAndCheckSubArray(int length, long random) {
+ private static void testAndCheckSubArray(int length) {
ourDescription = "Check sorting of subarray";
int[] golden = new int[length];
boolean newLine = false;
@@ -282,7 +255,7 @@
}
}
- private static void testAndCheckRange(int length, long random) {
+ private static void testAndCheckRange(int length) {
ourDescription = "Check range check";
int[] golden = new int[length];
@@ -300,15 +273,16 @@
out.println();
}
- private static void testStable(int length, long random) {
+ private static void testStable(int length, MyRandom random) {
ourDescription = "Check if sorting is stable";
- Pair[] a = build(length);
+ Pair[] a = build(length, random);
- out.println("Test 'stable': " + "random = " + random +
+ out.println("Test 'stable': " + "random = " + random.getSeed() +
", length = " + length);
Arrays.sort(a);
checkSorted(a);
checkStable(a);
+ out.println();
}
private static void checkSorted(Pair[] a) {
@@ -342,11 +316,11 @@
}
}
- private static Pair[] build(int length) {
+ private static Pair[] build(int length, Random random) {
Pair[] a = new Pair[length * 4];
for (int i = 0; i < a.length; ) {
- int key = ourRandom.nextInt();
+ int key = random.nextInt();
a[i++] = new Pair(key, 1);
a[i++] = new Pair(key, 2);
a[i++] = new Pair(key, 3);
@@ -389,7 +363,7 @@
}
- private static void testAndCheckWithInsertionSort(int length, long random) {
+ private static void testAndCheckWithInsertionSort(int length, MyRandom random) {
if (length > 1000) {
return;
}
@@ -398,13 +372,13 @@
for (int m = 1; m < 2 * length; m *= 2) {
for (UnsortedBuilder builder : UnsortedBuilder.values()) {
- builder.build(golden, m);
+ builder.build(golden, m, random);
int[] test = golden.clone();
for (TypeConverter converter : TypeConverter.values()) {
- out.println("Test 'insertion sort': " + converter + " " +
- builder + "random = " + random + ", length = " +
- length + ", m = " + m);
+ out.println("Test 'insertion sort': " + converter +
+ " " + builder + "random = " + random.getSeed() +
+ ", length = " + length + ", m = " + m);
Object convertedGolden = converter.convert(golden);
Object convertedTest1 = converter.convert(test);
Object convertedTest2 = converter.convert(test);
@@ -417,19 +391,44 @@
out.println();
}
- private static void testAndCheckWithCheckSum(int length, long random) {
+ private static void testMergeSort(int length) {
+ if (length < 1000) {
+ return;
+ }
+ ourDescription = "Check merge sorting";
+ int[] golden = new int[length];
+ int period = 67; // java.util.DualPivotQuicksort.MAX_RUN_COUNT
+
+ for (int m = period - 2; m <= period + 2; m++) {
+ for (MergeBuilder builder : MergeBuilder.values()) {
+ builder.build(golden, m);
+ int[] test = golden.clone();
+
+ for (TypeConverter converter : TypeConverter.values()) {
+ out.println("Test 'merge sort': " + converter + " " +
+ builder + "length = " + length + ", m = " + m);
+ Object convertedGolden = converter.convert(golden);
+ sort(convertedGolden);
+ checkSorted(convertedGolden);
+ }
+ }
+ }
+ out.println();
+ }
+
+ private static void testAndCheckWithCheckSum(int length, MyRandom random) {
ourDescription = "Check sorting with check sum";
int[] golden = new int[length];
for (int m = 1; m < 2 * length; m *= 2) {
for (UnsortedBuilder builder : UnsortedBuilder.values()) {
- builder.build(golden, m);
+ builder.build(golden, m, random);
int[] test = golden.clone();
for (TypeConverter converter : TypeConverter.values()) {
- out.println("Test 'check sum': " + converter + " " +
- builder + "random = " + random + ", length = " +
- length + ", m = " + m);
+ out.println("Test 'check sum': " + converter +
+ " " + builder + "random = " + random.getSeed() +
+ ", length = " + length + ", m = " + m);
Object convertedGolden = converter.convert(golden);
Object convertedTest = converter.convert(test);
sort(convertedTest);
@@ -440,7 +439,7 @@
out.println();
}
- private static void testAndCheckWithScrambling(int length, long random) {
+ private static void testAndCheckWithScrambling(int length, MyRandom random) {
ourDescription = "Check sorting with scrambling";
int[] golden = new int[length];
@@ -451,12 +450,12 @@
for (SortedBuilder builder : SortedBuilder.values()) {
builder.build(golden, m);
int[] test = golden.clone();
- scramble(test);
+ scramble(test, random);
for (TypeConverter converter : TypeConverter.values()) {
- out.println("Test 'scrambling': " + converter + " " +
- builder + "random = " + random + ", length = " +
- length + ", m = " + m);
+ out.println("Test 'scrambling': " + converter +
+ " " + builder + "random = " + random.getSeed() +
+ ", length = " + length + ", m = " + m);
Object convertedGolden = converter.convert(golden);
Object convertedTest = converter.convert(test);
sort(convertedTest);
@@ -467,7 +466,7 @@
out.println();
}
- private static void testAndCheckFloat(int length, long random) {
+ private static void testAndCheckFloat(int length, MyRandom random) {
ourDescription = "Check float sorting";
float[] golden = new float[length];
final int MAX = 10;
@@ -485,13 +484,12 @@
continue;
}
for (FloatBuilder builder : FloatBuilder.values()) {
- out.println("Test 'float': random = " + random +
- ", length = " + length + ", a = " + a +
- ", g = " + g + ", z = " + z + ", n = " + n +
- ", p = " + p);
- builder.build(golden, a, g, z, n, p);
+ out.println("Test 'float': random = " + random.getSeed() +
+ ", length = " + length + ", a = " + a + ", g = " +
+ g + ", z = " + z + ", n = " + n + ", p = " + p);
+ builder.build(golden, a, g, z, n, p, random);
float[] test = golden.clone();
- scramble(test);
+ scramble(test, random);
sort(test);
compare(test, golden, a, n, g);
}
@@ -506,7 +504,7 @@
}
}
- private static void testAndCheckDouble(int length, long random) {
+ private static void testAndCheckDouble(int length, MyRandom random) {
ourDescription = "Check double sorting";
double[] golden = new double[length];
final int MAX = 10;
@@ -524,12 +522,12 @@
continue;
}
for (DoubleBuilder builder : DoubleBuilder.values()) {
- out.println("Test 'double': random = " + random +
+ out.println("Test 'double': random = " + random.getSeed() +
", length = " + length + ", a = " + a + ", g = " +
g + ", z = " + z + ", n = " + n + ", p = " + p);
- builder.build(golden, a, g, z, n, p);
+ builder.build(golden, a, g, z, n, p, random);
double[] test = golden.clone();
- scramble(test);
+ scramble(test, random);
sort(test);
compare(test, golden, a, n, g);
}
@@ -546,31 +544,37 @@
private static void prepareSubArray(int[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- a[i] = 0xBABA;
+ a[i] = 0xDEDA;
}
- for (int i = fromIndex; i < toIndex; i++) {
- a[i] = -i + m;
+ int middle = (fromIndex + toIndex) >>> 1;
+ int k = 0;
+
+ for (int i = fromIndex; i < middle; i++) {
+ a[i] = k++;
+ }
+ for (int i = middle; i < toIndex; i++) {
+ a[i] = k--;
}
for (int i = toIndex; i < a.length; i++) {
- a[i] = 0xDEDA;
+ a[i] = 0xBABA;
}
}
- private static void scramble(int[] a) {
+ private static void scramble(int[] a, Random random) {
for (int i = 0; i < a.length * 7; i++) {
- swap(a, ourRandom.nextInt(a.length), ourRandom.nextInt(a.length));
+ swap(a, random.nextInt(a.length), random.nextInt(a.length));
}
}
- private static void scramble(float[] a) {
+ private static void scramble(float[] a, Random random) {
for (int i = 0; i < a.length * 7; i++) {
- swap(a, ourRandom.nextInt(a.length), ourRandom.nextInt(a.length));
+ swap(a, random.nextInt(a.length), random.nextInt(a.length));
}
}
- private static void scramble(double[] a) {
+ private static void scramble(double[] a, Random random) {
for (int i = 0; i < a.length * 7; i++) {
- swap(a, ourRandom.nextInt(a.length), ourRandom.nextInt(a.length));
+ swap(a, random.nextInt(a.length), random.nextInt(a.length));
}
}
@@ -683,10 +687,10 @@
private static enum FloatBuilder {
SIMPLE {
- void build(float[] x, int a, int g, int z, int n, int p) {
+ void build(float[] x, int a, int g, int z, int n, int p, Random random) {
int fromIndex = 0;
- float negativeValue = -ourRandom.nextFloat();
- float positiveValue = ourRandom.nextFloat();
+ float negativeValue = -random.nextFloat();
+ float positiveValue = random.nextFloat();
writeValue(x, negativeValue, fromIndex, n);
fromIndex += n;
@@ -704,15 +708,15 @@
}
};
- abstract void build(float[] x, int a, int g, int z, int n, int p);
+ abstract void build(float[] x, int a, int g, int z, int n, int p, Random random);
}
private static enum DoubleBuilder {
SIMPLE {
- void build(double[] x, int a, int g, int z, int n, int p) {
+ void build(double[] x, int a, int g, int z, int n, int p, Random random) {
int fromIndex = 0;
- double negativeValue = -ourRandom.nextFloat();
- double positiveValue = ourRandom.nextFloat();
+ double negativeValue = -random.nextFloat();
+ double positiveValue = random.nextFloat();
writeValue(x, negativeValue, fromIndex, n);
fromIndex += n;
@@ -730,7 +734,7 @@
}
};
- abstract void build(double[] x, int a, int g, int z, int n, int p);
+ abstract void build(double[] x, int a, int g, int z, int n, int p, Random random);
}
private static void writeValue(float[] a, float value, int fromIndex, int count) {
@@ -806,7 +810,6 @@
}
}
},
-
ORGAN_PIPES {
void build(int[] a, int m) {
int i = 0;
@@ -835,37 +838,85 @@
}
}
+ private static enum MergeBuilder {
+ ASCENDING {
+ void build(int[] a, int m) {
+ int period = a.length / m;
+ int v = 1, i = 0;
+
+ for (int k = 0; k < m; k++) {
+ v = 1;
+ for (int p = 0; p < period; p++) {
+ a[i++] = v++;
+ }
+ }
+ for (int j = i; j < a.length - 1; j++) {
+ a[j] = v++;
+ }
+ a[a.length - 1] = 0;
+ }
+ },
+ DESCENDING {
+ void build(int[] a, int m) {
+ int period = a.length / m;
+ int v = -1, i = 0;
+
+ for (int k = 0; k < m; k++) {
+ v = -1;
+ for (int p = 0; p < period; p++) {
+ a[i++] = v--;
+ }
+ }
+ for (int j = i; j < a.length - 1; j++) {
+ a[j] = v--;
+ }
+ a[a.length - 1] = 0;
+ }
+ };
+
+ abstract void build(int[] a, int m);
+
+ @Override public String toString() {
+ String name = name();
+
+ for (int i = name.length(); i < 12; i++) {
+ name += " ";
+ }
+ return name;
+ }
+ }
+
private static enum UnsortedBuilder {
RANDOM {
- void build(int[] a, int m) {
+ void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) {
- a[i] = ourRandom.nextInt();
+ a[i] = random.nextInt();
}
}
},
ASCENDING {
- void build(int[] a, int m) {
+ void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) {
a[i] = m + i;
}
}
},
DESCENDING {
- void build(int[] a, int m) {
+ void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) {
a[i] = a.length - m - i;
}
}
},
ALL_EQUAL {
- void build(int[] a, int m) {
+ void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) {
a[i] = m;
}
}
},
SAW {
- void build(int[] a, int m) {
+ void build(int[] a, int m, Random random) {
int incCount = 1;
int decCount = a.length;
int i = 0;
@@ -891,21 +942,21 @@
}
},
REPEATED {
- void build(int[] a, int m) {
+ void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) {
a[i] = i % m;
}
}
},
DUPLICATED {
- void build(int[] a, int m) {
+ void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) {
- a[i] = ourRandom.nextInt(m);
+ a[i] = random.nextInt(m);
}
}
},
ORGAN_PIPES {
- void build(int[] a, int m) {
+ void build(int[] a, int m, Random random) {
int middle = a.length / (m + 1);
for (int i = 0; i < middle; i++) {
@@ -917,28 +968,29 @@
}
},
STAGGER {
- void build(int[] a, int m) {
+ void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) {
a[i] = (i * m + i) % a.length;
}
}
},
PLATEAU {
- void build(int[] a, int m) {
+ void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) {
a[i] = Math.min(i, m);
}
}
},
SHUFFLE {
- void build(int[] a, int m) {
+ void build(int[] a, int m, Random random) {
+ int x = 0, y = 0;
for (int i = 0; i < a.length; i++) {
- a[i] = ourRandom.nextBoolean() ? (ourFirst += 2) : (ourSecond += 2);
+ a[i] = random.nextBoolean() ? (x += 2) : (y += 2);
}
}
};
- abstract void build(int[] a, int m);
+ abstract void build(int[] a, int m, Random random);
@Override public String toString() {
String name = name();
@@ -1518,9 +1570,9 @@
private static void checkSubArray(Integer[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i].intValue() != 0xBABA) {
+ if (a[i].intValue() != 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1531,18 +1583,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i].intValue() != 0xDEDA) {
+ if (a[i].intValue() != 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(int[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != 0xBABA) {
+ if (a[i] != 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1553,18 +1605,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != 0xDEDA) {
+ if (a[i] != 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(byte[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (byte) 0xBABA) {
+ if (a[i] != (byte) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1575,18 +1627,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (byte) 0xDEDA) {
+ if (a[i] != (byte) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(long[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (long) 0xBABA) {
+ if (a[i] != (long) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1597,18 +1649,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (long) 0xDEDA) {
+ if (a[i] != (long) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(char[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (char) 0xBABA) {
+ if (a[i] != (char) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1619,18 +1671,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (char) 0xDEDA) {
+ if (a[i] != (char) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(short[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (short) 0xBABA) {
+ if (a[i] != (short) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1641,18 +1693,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (short) 0xDEDA) {
+ if (a[i] != (short) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(float[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (float) 0xBABA) {
+ if (a[i] != (float) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1663,18 +1715,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (float) 0xDEDA) {
+ if (a[i] != (float) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(double[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (double) 0xBABA) {
+ if (a[i] != (double) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1685,9 +1737,9 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (double) 0xDEDA) {
+ if (a[i] != (double) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
@@ -1947,18 +1999,6 @@
}
}
- private static void prepareRandom(int[] a) {
- for (int i = 0; i < a.length; i++) {
- a[i] = ourRandom.nextInt();
- }
- }
-
- private static void reset(long seed) {
- ourRandom = new Random(seed);
- ourFirst = 0;
- ourSecond = 0;
- }
-
private static void outArray(Object[] a) {
for (int i = 0; i < a.length; i++) {
out.print(a[i] + " ");
@@ -1987,8 +2027,18 @@
out.println();
}
- private static int ourFirst;
- private static int ourSecond;
- private static Random ourRandom;
+ private static class MyRandom extends Random {
+ MyRandom(long seed) {
+ super(seed);
+ mySeed = seed;
+ }
+
+ long getSeed() {
+ return mySeed;
+ }
+
+ private long mySeed;
+ }
+
private static String ourDescription;
}
--- a/jdk/test/java/util/Locale/LocaleEnhanceTest.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/util/Locale/LocaleEnhanceTest.java Mon Feb 14 16:30:10 2011 -0800
@@ -478,6 +478,23 @@
Locale locale = new Locale(test[0], test[1], test[2]);
assertEquals("case " + i, test[3], locale.toLanguageTag());
}
+
+ // test locales created from forLanguageTag
+ String[][] tests1 = {
+ // case is normalized during the round trip
+ { "EN-us", "en-US" },
+ { "en-Latn-US", "en-Latn-US" },
+ // reordering Unicode locale extensions
+ { "de-u-co-phonebk-ca-gregory", "de-u-ca-gregory-co-phonebk" },
+ // private use only language tag is preserved (no extra "und")
+ { "x-elmer", "x-elmer" },
+ { "x-lvariant-JP", "x-lvariant-JP" },
+ };
+ for (String[] test : tests1) {
+ Locale locale = Locale.forLanguageTag(test[0]);
+ assertEquals("case " + test[0], test[1], locale.toLanguageTag());
+ }
+
}
public void testForLanguageTag() {
@@ -488,9 +505,9 @@
String[][] tests = {
// private use tags only
- { "x-abc", "und-x-abc" },
- { "x-a-b-c", "und-x-a-b-c" },
- { "x-a-12345678", "und-x-a-12345678" },
+ { "x-abc", "x-abc" },
+ { "x-a-b-c", "x-a-b-c" },
+ { "x-a-12345678", "x-a-12345678" },
// grandfathered tags with preferred mappings
{ "i-ami", "ami" },
@@ -517,7 +534,7 @@
// grandfathered irregular tags, no preferred mappings, drop illegal fields
// from end. If no subtag is mappable, fallback to 'und'
{ "i-default", "en-x-i-default" },
- { "i-enochian", "und-x-i-enochian" },
+ { "i-enochian", "x-i-enochian" },
{ "i-mingo", "see-x-i-mingo" },
{ "en-GB-oed", "en-GB-x-oed" },
{ "zh-min", "nan-x-zh-min" },
--- a/jdk/test/java/util/Objects/BasicObjectsTest.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/util/Objects/BasicObjectsTest.java Mon Feb 14 16:30:10 2011 -0800
@@ -164,7 +164,7 @@
// Test 1-arg variant
try {
- s = Objects.nonNull("pants");
+ s = Objects.requireNonNull("pants");
if (s != "pants") {
System.err.printf("1-arg non-null failed to return its arg");
errors++;
@@ -175,7 +175,7 @@
}
try {
- s = Objects.nonNull(null);
+ s = Objects.requireNonNull(null);
System.err.printf("1-arg nonNull failed to throw NPE");
errors++;
} catch (NullPointerException e) {
@@ -184,7 +184,7 @@
// Test 2-arg variant
try {
- s = Objects.nonNull("pants", "trousers");
+ s = Objects.requireNonNull("pants", "trousers");
if (s != "pants") {
System.err.printf("2-arg nonNull failed to return its arg");
errors++;
@@ -195,7 +195,7 @@
}
try {
- s = Objects.nonNull(null, "pantaloons");
+ s = Objects.requireNonNull(null, "pantaloons");
System.err.printf("2-arg nonNull failed to throw NPE");
errors++;
} catch (NullPointerException e) {
--- a/jdk/test/java/util/regex/RegExTest.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/java/util/regex/RegExTest.java Mon Feb 14 16:30:10 2011 -0800
@@ -32,7 +32,7 @@
* 4872664 4803179 4892980 4900747 4945394 4938995 4979006 4994840 4997476
* 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
* 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
- * 6350801 6676425 6878475 6919132 6931676 6948903
+ * 6350801 6676425 6878475 6919132 6931676 6948903 7014645
*/
import java.util.regex.*;
@@ -136,6 +136,7 @@
namedGroupCaptureTest();
nonBmpClassComplementTest();
unicodePropertiesTest();
+ unicodeHexNotationTest();
if (failure)
throw new RuntimeException("Failure in the RE handling.");
else
@@ -161,18 +162,19 @@
private static void check(Matcher m, String result, boolean expected) {
m.find();
- if (m.group().equals(result))
- failCount += (expected) ? 0 : 1;
- else
- failCount += (expected) ? 1 : 0;
+ if (m.group().equals(result) != expected)
+ failCount++;
}
private static void check(Pattern p, String s, boolean expected) {
- Matcher matcher = p.matcher(s);
- if (matcher.find())
- failCount += (expected) ? 0 : 1;
- else
- failCount += (expected) ? 1 : 0;
+ if (p.matcher(s).find() != expected)
+ failCount++;
+ }
+
+ private static void check(String p, String s, boolean expected) {
+ Matcher matcher = Pattern.compile(p).matcher(s);
+ if (matcher.find() != expected)
+ failCount++;
}
private static void check(String p, char c, boolean expected) {
@@ -3614,4 +3616,45 @@
}
report("unicodeProperties");
}
+
+ private static void unicodeHexNotationTest() throws Exception {
+
+ // negative
+ checkExpectedFail("\\x{-23}");
+ checkExpectedFail("\\x{110000}");
+ checkExpectedFail("\\x{}");
+ checkExpectedFail("\\x{AB[ef]");
+
+ // codepoint
+ check("^\\x{1033c}$", "\uD800\uDF3C", true);
+ check("^\\xF0\\x90\\x8C\\xBC$", "\uD800\uDF3C", false);
+ check("^\\x{D800}\\x{DF3c}+$", "\uD800\uDF3C", false);
+ check("^\\xF0\\x90\\x8C\\xBC$", "\uD800\uDF3C", false);
+
+ // in class
+ check("^[\\x{D800}\\x{DF3c}]+$", "\uD800\uDF3C", false);
+ check("^[\\xF0\\x90\\x8C\\xBC]+$", "\uD800\uDF3C", false);
+ check("^[\\x{D800}\\x{DF3C}]+$", "\uD800\uDF3C", false);
+ check("^[\\x{DF3C}\\x{D800}]+$", "\uD800\uDF3C", false);
+ check("^[\\x{D800}\\x{DF3C}]+$", "\uDF3C\uD800", true);
+ check("^[\\x{DF3C}\\x{D800}]+$", "\uDF3C\uD800", true);
+
+ for (int cp = 0; cp <= 0x10FFFF; cp++) {
+ String s = "A" + new String(Character.toChars(cp)) + "B";
+ String hexUTF16 = (cp <= 0xFFFF)? String.format("\\u%04x", cp)
+ : String.format("\\u%04x\\u%04x",
+ (int) Character.toChars(cp)[0],
+ (int) Character.toChars(cp)[1]);
+ String hexCodePoint = "\\x{" + Integer.toHexString(cp) + "}";
+ if (!Pattern.matches("A" + hexUTF16 + "B", s))
+ failCount++;
+ if (!Pattern.matches("A[" + hexUTF16 + "]B", s))
+ failCount++;
+ if (!Pattern.matches("A" + hexCodePoint + "B", s))
+ failCount++;
+ if (!Pattern.matches("A[" + hexCodePoint + "]B", s))
+ failCount++;
+ }
+ report("unicodeHexNotation");
+ }
}
--- a/jdk/test/javax/script/CauseExceptionTest.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/javax/script/CauseExceptionTest.java Mon Feb 14 16:30:10 2011 -0800
@@ -34,6 +34,10 @@
public static void main(String[] args) throws ScriptException, NoSuchMethodException {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("js");
+ if (engine == null) {
+ System.out.println("Warning: No js engine found; test vacuously passes.");
+ return;
+ }
engine.eval("function hello_world() { println('hello world'); throw 'out of here'; } ");
Invocable invocable = (Invocable) engine;
try {
--- a/jdk/test/javax/script/StringWriterPrintTest.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/javax/script/StringWriterPrintTest.java Mon Feb 14 16:30:10 2011 -0800
@@ -34,6 +34,10 @@
public static void main(String[] args) throws ScriptException {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("js");
+ if (engine == null) {
+ System.out.println("Warning: No js engine found; test vacuously passes.");
+ return;
+ }
StringWriter sw = new StringWriter();
engine.eval("print(\"hello world 1\\n\")");
engine.getContext().setWriter(sw);
--- a/jdk/test/javax/script/UnescapedBracketRegExTest.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/javax/script/UnescapedBracketRegExTest.java Mon Feb 14 16:30:10 2011 -0800
@@ -34,6 +34,10 @@
public static void main(String[] args) throws ScriptException {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("js");
+ if (engine == null) {
+ System.out.println("Warning: No js engine found; test vacuously passes.");
+ return;
+ }
// the following throws exception
engine.eval("var x = /[a-zA-Z+/=]/;");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/RepaintManager/7013453/bug7013453.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ @bug 7013453
+ @summary BufferStrategyPaintManager.dispose will cause IllegalMonitorStateException in event thread
+ @author Pavel Porvatov
+*/
+
+import javax.swing.*;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class bug7013453 {
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ try {
+ Method getPaintManagerMethod = RepaintManager.class.getDeclaredMethod("getPaintManager");
+
+ getPaintManagerMethod.setAccessible(true);
+
+ final Object paintManager = getPaintManagerMethod.invoke(RepaintManager.currentManager(new JLabel()));
+
+ String paintManagerName = paintManager.getClass().getCanonicalName();
+
+ if (!paintManagerName.equals("javax.swing.BufferStrategyPaintManager")) {
+ System.out.println("The test is not suitable for the " + paintManagerName +
+ " paint manager. The test skipped.");
+
+ return;
+ }
+
+ final Field showingField = paintManager.getClass().getDeclaredField("showing");
+
+ showingField.setAccessible(true);
+
+ synchronized (paintManager) {
+ showingField.setBoolean(paintManager, true);
+ }
+
+ // Postpone reset the showing field
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ synchronized (paintManager) {
+ try {
+ showingField.setBoolean(paintManager, false);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ });
+
+ thread.start();
+
+ Method disposeMethod = paintManager.getClass().getDeclaredMethod("dispose");
+
+ disposeMethod.setAccessible(true);
+
+ disposeMethod.invoke(paintManager);
+
+ System.out.println("The test passed.");
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/Basic.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6887710
+ * @summary Verify the impact of sun.misc.JarIndex.metaInfFilenames on Service loaders
+ * @run main/othervm Basic
+ */
+
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import com.sun.net.httpserver.Headers;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+/**
+ * Verifies the impact of sun.misc.JarIndex.metaInfFilenames on service loaders
+ * (sun.misc.Service & java.util.ServiceLoader), as well as finding resources
+ * through Class.getResouce.
+ *
+ * 1) Compile the test sources:
+ * jarA:
+ * META-INF/services/my.happy.land
+ * com/message/spi/MessageService.java
+ * a/A.java
+ * jarB:
+ * META-INF/JAVA2.DS
+ * META-INF/services/no.name.service
+ * b/B.java
+ * jarC:
+ * META-INF/fonts.mf
+ * META-INF/fonts/Company-corporate.ttf
+ * META-INF/fonts/kidpr.ttf
+ * META-INF/services/com.message.spi.MessageService
+ * my/impl/StandardMessageService.java
+ *
+ * 2) Build three jar files a.jar, b.jar, c.jar
+ *
+ * 3) Create an index in a.jar (jar -i a.jar b.jar c.jar)
+ * with sun.misc.JarIndex.metaInfFilenames=true
+ *
+ * 4) Start a HTTP server serving out the three jars.
+ *
+ * The test then tries to locate services/resources within the jars using
+ * URLClassLoader. Each request to the HTTP server is recorded to ensure
+ * only the correct amount of requests are being made.
+ *
+ * Note: Needs jdk/lib/tools.jar in the classpath to compile and run.
+ */
+
+public class Basic {
+ static final String slash = File.separator;
+ static final String[] testSources = {
+ "jarA" + slash + "a" + slash + "A.java",
+ "jarA" + slash + "com" + slash + "message" + slash + "spi" + slash + "MessageService.java",
+ "jarB" + slash + "b" + slash + "B.java",
+ "jarC" + slash + "my" + slash + "impl" + slash + "StandardMessageService.java"};
+
+ static final String testSrc = System.getProperty("test.src");
+ static final String testSrcDir = testSrc != null ? testSrc : ".";
+ static final String testClasses = System.getProperty("test.classes");
+ static final String testClassesDir = testClasses != null ? testClasses : ".";
+
+ static JarHttpServer httpServer;
+
+ public static void main(String[] args) throws Exception {
+
+ // Set global url cache to false so that we can track every jar request.
+ (new URL("http://localhost/")).openConnection().setDefaultUseCaches(false);
+
+ buildTest();
+
+ try {
+ httpServer = new JarHttpServer(testClassesDir);
+ httpServer.start();
+
+ doTest(httpServer.getAddress());
+
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ } finally {
+ if (httpServer != null) { httpServer.stop(2); }
+ }
+ }
+
+ static void buildTest() {
+ /* compile the source that will be used to generate the jars */
+ for (int i=0; i<testSources.length; i++)
+ testSources[i] = testSrcDir + slash + testSources[i];
+
+ compile("-d" , testClassesDir,
+ "-sourcepath", testSrcDir,
+ testSources[0], testSources[1], testSources[2], testSources[3]);
+
+ /* build the 3 jar files */
+ jar("-cf", testClassesDir + slash + "a.jar",
+ "-C", testClassesDir, "a",
+ "-C", testClassesDir, "com",
+ "-C", testSrcDir + slash + "jarA", "META-INF");
+ jar("-cf", testClassesDir + slash + "b.jar",
+ "-C", testClassesDir, "b",
+ "-C", testSrcDir + slash + "jarB", "META-INF");
+ jar("-cf", testClassesDir + slash + "c.jar",
+ "-C", testClassesDir, "my",
+ "-C", testSrcDir + slash + "jarC", "META-INF");
+
+ /* Create an index in a.jar for b.jar and c.jar */
+ createIndex(testClassesDir);
+ }
+
+ /* run jar <args> */
+ static void jar(String... args) {
+ debug("Running: jar " + Arrays.toString(args));
+ sun.tools.jar.Main jar = new sun.tools.jar.Main(System.out, System.err, "jar");
+ if (!jar.run(args)) {
+ throw new RuntimeException("jar failed: args=" + Arrays.toString(args));
+ }
+ }
+
+ /* run javac <args> */
+ static void compile(String... args) {
+ debug("Running: javac " + Arrays.toString(args));
+ com.sun.tools.javac.main.Main compiler = new com.sun.tools.javac.main.Main("javac");
+ if (compiler.compile(args) != 0) {
+ throw new RuntimeException("javac failed: args=" + Arrays.toString(args));
+ }
+ }
+
+ static String jar;
+ static {
+ String javaHome = System.getProperty("java.home");
+ if (javaHome.endsWith("jre")) {
+ int index = javaHome.lastIndexOf(slash);
+ if (index != -1)
+ javaHome = javaHome.substring(0, index);
+ }
+
+ jar = javaHome + slash+ "bin" + slash + "jar";
+ }
+
+ /* create the index */
+ static void createIndex(String workingDir) {
+ // ProcessBuilder is used so that the current directory can be set
+ // to the directory that directly contains the jars.
+ debug("Running jar to create the index");
+ ProcessBuilder pb = new ProcessBuilder(
+ jar, "-J-Dsun.misc.JarIndex.metaInfFilenames=true", "-i", "a.jar", "b.jar", "c.jar");
+ pb.directory(new File(workingDir));
+ //pd.inheritIO();
+ try {
+ Process p = pb.start();
+ if(p.waitFor() != 0)
+ throw new RuntimeException("jar indexing failed");
+
+ if(debug && p != null) {
+ String line = null;
+ BufferedReader reader =
+ new BufferedReader(new InputStreamReader(p.getInputStream()));
+ while((line = reader.readLine()) != null)
+ debug(line);
+ reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
+ while((line = reader.readLine()) != null)
+ debug(line);
+ }
+ } catch(InterruptedException ie) { throw new RuntimeException(ie);
+ } catch(IOException e) { throw new RuntimeException(e); }
+ }
+
+ static final boolean debug = true;
+
+ static void debug(Object message) { if (debug) System.out.println(message); }
+
+ /* service define in c.jar */
+ static final String messageService = "com.message.spi.MessageService";
+
+ /* a service that is not defined in any of the jars */
+ static final String unknownService = "java.lang.Object";
+
+ static void doTest(InetSocketAddress serverAddress) throws IOException {
+ URL baseURL = new URL("http://localhost:" + serverAddress.getPort() + "/");
+
+ int failed = 0;
+
+ // Tests using sun.misc.Service
+ if (!sunMiscServiceTest(baseURL, messageService, true, false, true)) {
+ System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");
+ failed++;
+ }
+ if (!sunMiscServiceTest(baseURL, unknownService, false, false, false)) {
+ System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");
+ failed++;
+ }
+
+ // Tests using java.util.SerivceLoader
+ if (!javaUtilServiceLoaderTest(baseURL, messageService, true, false, true)) {
+ System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");
+ failed++;
+ }
+ if (!javaUtilServiceLoaderTest(baseURL, unknownService, false, false, false)) {
+ System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");
+ failed++;
+ }
+
+ // Tests using java.lang.Class (similar to the FontManager in javafx)
+ if (!klassLoader(baseURL, "/META-INF/fonts.mf", true, false, true)) {
+ System.out.println("Test: klassLoader looking for /META-INF/fonts.mf failed");
+ failed++;
+ }
+ if (!klassLoader(baseURL, "/META-INF/unknown.mf", false, false, false)) {
+ System.out.println("Test: klassLoader looking for /META-INF/unknown.mf failed");
+ failed++;
+ }
+
+ if (failed > 0)
+ throw new RuntimeException("Failed: " + failed + " tests");
+ }
+
+ static boolean sunMiscServiceTest(URL baseURL,
+ String serviceClass,
+ boolean expectToFind,
+ boolean expectbDotJar,
+ boolean expectcDotJar) throws IOException {
+ debug("----------------------------------");
+ debug("Running test with sun.misc.Service looking for " + serviceClass);
+ URLClassLoader loader = getLoader(baseURL);
+ httpServer.reset();
+
+ Class messageServiceClass = null;
+ try {
+ messageServiceClass = loader.loadClass(serviceClass);
+ } catch (ClassNotFoundException cnfe) {
+ System.err.println(cnfe);
+ throw new RuntimeException("Error in test: " + cnfe);
+ }
+
+ Iterator<Class<?>> iterator = sun.misc.Service.providers(messageServiceClass, loader);
+ if (expectToFind && !iterator.hasNext()) {
+ debug(messageServiceClass + " NOT found.");
+ return false;
+ }
+
+ while (iterator.hasNext()) {
+ debug("found " + iterator.next() + " " + messageService);
+ }
+
+ debug("HttpServer: " + httpServer);
+
+ if (!expectbDotJar && httpServer.bDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for b.jar");
+ return false;
+ }
+ if (!expectcDotJar && httpServer.cDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for c.jar");
+ return false;
+ }
+
+ return true;
+ }
+
+ static boolean javaUtilServiceLoaderTest(URL baseURL,
+ String serviceClass,
+ boolean expectToFind,
+ boolean expectbDotJar,
+ boolean expectcDotJar) throws IOException {
+ debug("----------------------------------");
+ debug("Running test with java.util.ServiceLoader looking for " + serviceClass);
+ URLClassLoader loader = getLoader(baseURL);
+ httpServer.reset();
+
+ Class messageServiceClass = null;
+ try {
+ messageServiceClass = loader.loadClass(serviceClass);
+ } catch (ClassNotFoundException cnfe) {
+ System.err.println(cnfe);
+ throw new RuntimeException("Error in test: " + cnfe);
+ }
+
+ Iterator<Class<?>> iterator = (ServiceLoader.load(messageServiceClass, loader)).iterator();
+ if (expectToFind && !iterator.hasNext()) {
+ debug(messageServiceClass + " NOT found.");
+ return false;
+ }
+
+ while (iterator.hasNext()) {
+ debug("found " + iterator.next() + " " + messageService);
+ }
+
+ debug("HttpServer: " + httpServer);
+
+ if (!expectbDotJar && httpServer.bDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for b.jar");
+ return false;
+ }
+ if (!expectcDotJar && httpServer.cDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for c.jar");
+ return false;
+ }
+
+ return true;
+ }
+
+ /* Tries to find a resource in a similar way to the font manager in javafx
+ * com.sun.javafx.scene.text.FontManager */
+ static boolean klassLoader(URL baseURL,
+ String resource,
+ boolean expectToFind,
+ boolean expectbDotJar,
+ boolean expectcDotJar) throws IOException {
+ debug("----------------------------------");
+ debug("Running test looking for " + resource);
+ URLClassLoader loader = getLoader(baseURL);
+ httpServer.reset();
+
+ Class ADotAKlass = null;
+ try {
+ ADotAKlass = loader.loadClass("a.A");
+ } catch (ClassNotFoundException cnfe) {
+ System.err.println(cnfe);
+ throw new RuntimeException("Error in test: " + cnfe);
+ }
+
+ URL u = ADotAKlass.getResource(resource);
+ if (expectToFind && u == null) {
+ System.out.println("Expected to find " + resource + " but didn't");
+ return false;
+ }
+
+ debug("HttpServer: " + httpServer);
+
+ if (!expectbDotJar && httpServer.bDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for b.jar");
+ return false;
+ }
+ if (!expectcDotJar && httpServer.cDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for c.jar");
+ return false;
+ }
+
+ return true;
+ }
+
+ static URLClassLoader getLoader(URL baseURL) throws IOException {
+ ClassLoader loader = Basic.class.getClassLoader();
+
+ while (loader.getParent() != null)
+ loader = loader.getParent();
+
+ return new URLClassLoader( new URL[]{
+ new URL(baseURL, "a.jar"),
+ new URL(baseURL, "b.jar"),
+ new URL(baseURL, "c.jar")}, loader );
+ }
+
+ /**
+ * HTTP Server to server the jar files.
+ */
+ static class JarHttpServer implements HttpHandler {
+ final String docsDir;
+ final HttpServer httpServer;
+ int aDotJar, bDotJar, cDotJar;
+
+ JarHttpServer(String docsDir) throws IOException {
+ this.docsDir = docsDir;
+
+ httpServer = HttpServer.create(new InetSocketAddress(0), 0);
+ httpServer.createContext("/", this);
+ }
+
+ void start() throws IOException {
+ httpServer.start();
+ }
+
+ void stop(int delay) {
+ httpServer.stop(delay);
+ }
+
+ InetSocketAddress getAddress() {
+ return httpServer.getAddress();
+ }
+
+ void reset() {
+ aDotJar = bDotJar = cDotJar = 0;
+ }
+
+ @Override
+ public String toString() {
+ return "aDotJar=" + aDotJar + ", bDotJar=" + bDotJar + ", cDotJar=" + cDotJar;
+ }
+
+ public void handle(HttpExchange t) throws IOException {
+ InputStream is = t.getRequestBody();
+ Headers map = t.getRequestHeaders();
+ Headers rmap = t.getResponseHeaders();
+ URI uri = t.getRequestURI();
+
+ debug("Server: received request for " + uri);
+ String path = uri.getPath();
+ if (path.endsWith("a.jar"))
+ aDotJar++;
+ else if (path.endsWith("b.jar"))
+ bDotJar++;
+ else if (path.endsWith("c.jar"))
+ cDotJar++;
+ else
+ System.out.println("Unexpected resource request" + path);
+
+ while (is.read() != -1);
+ is.close();
+
+ File file = new File(docsDir, path);
+ if (!file.exists())
+ throw new RuntimeException("Error: request for " + file);
+ long clen = file.length();
+ t.sendResponseHeaders (200, clen);
+ OutputStream os = t.getResponseBody();
+ FileInputStream fis = new FileInputStream(file);
+ try {
+ byte[] buf = new byte [16 * 1024];
+ int len;
+ while ((len=fis.read(buf)) != -1) {
+ os.write (buf, 0, len);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ fis.close();
+ os.close();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarA/META-INF/services/my.happy.land Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# 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.
+
+# The contents of this file do not matter. It exists
+# simply to have a service defined in META-INF/services.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarA/a/A.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 a;
+
+public class A {
+ public static void hello() throws Exception {
+ System.out.println("Hello from a.A");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarA/com/message/spi/MessageService.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.message.spi;
+
+public interface MessageService {
+ String message();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarB/META-INF/JAVA2.DS Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# 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.
+
+# The contents of this file do not matter. It exists
+# simply to have a file under META-INF.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarB/META-INF/services/no.name.service Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# 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.
+
+# The contents of this file do not matter. It exists
+# simply to have a service defined in META-INF/services.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarB/b/B.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 b;
+
+public class B {
+ public static void hello() {
+ System.out.println("Hello from b.B");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/fonts.mf Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# 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.
+
+corporate=/fonts/Company-corporate.ttf
+crazy-looking=/fonts/kidpr.ttf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/fonts/Company-corporate.ttf Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+This is not a real font.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/fonts/kidpr.ttf Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+This is not a real font.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/services/com.message.spi.MessageService Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# 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.
+
+my.impl.StandardMessageService
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/my/impl/StandardMessageService.java Mon Feb 14 16:30:10 2011 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 my.impl;
+
+public class StandardMessageService implements com.message.spi.MessageService {
+ @Override
+ public String message() {
+ return "This is a message from the standard message service";
+ }
+}
--- a/jdk/test/sun/security/provider/SeedGenerator/SeedGeneratorChoice.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/sun/security/provider/SeedGenerator/SeedGeneratorChoice.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
--- a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorEndEntity.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorEndEntity.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,10 @@
/**
* @test
*
- * @bug 6861062
- * @summary Disable MD2 support
+ * @bug 6861062 7011497
+ * @summary Disable MD2 support.
+ * New CertPathValidatorException.BasicReason enum constant for
+ * constrained algorithm.
*
* @author Xuelei Fan
*/
@@ -35,6 +37,7 @@
import java.util.*;
import java.security.Security;
import java.security.cert.*;
+import java.security.cert.CertPathValidatorException.*;
public class CPValidatorEndEntity {
@@ -329,6 +332,13 @@
intermediate_SHA1withRSA_1024_1024);
throw new Exception("expected algorithm disabled exception");
} catch (CertPathValidatorException cpve) {
+ // we may get ClassCastException here
+ BasicReason reason = (BasicReason)cpve.getReason();
+ if (reason != BasicReason.ALGORITHM_CONSTRAINED) {
+ throw new Exception(
+ "Expect to get ALGORITHM_CONSTRAINED CPVE", cpve);
+ }
+
System.out.println("Get the expected exception " + cpve);
}
@@ -337,6 +347,13 @@
intermediate_SHA1withRSA_512_1024);
throw new Exception("expected algorithm disabled exception");
} catch (CertPathValidatorException cpve) {
+ // we may get ClassCastException here
+ BasicReason reason = (BasicReason)cpve.getReason();
+ if (reason != BasicReason.ALGORITHM_CONSTRAINED) {
+ throw new Exception(
+ "Expect to get ALGORITHM_CONSTRAINED CPVE", cpve);
+ }
+
System.out.println("Get the expected exception " + cpve);
}
}
--- a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorIntermediate.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorIntermediate.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,10 @@
/**
* @test
*
- * @bug 6861062
+ * @bug 6861062 7011497
* @summary Disable MD2 support
+ * new CertPathValidatorException.BasicReason enum constant for
+ * constrained algorithm
*
* @author Xuelei Fan
*/
@@ -35,6 +37,7 @@
import java.util.*;
import java.security.Security;
import java.security.cert.*;
+import java.security.cert.CertPathValidatorException.*;
public class CPValidatorIntermediate {
@@ -223,6 +226,13 @@
validate(intermediate_MD2withRSA_1024_1024);
throw new Exception("expected algorithm disabled exception");
} catch (CertPathValidatorException cpve) {
+ // we may get ClassCastException here
+ BasicReason reason = (BasicReason)cpve.getReason();
+ if (reason != BasicReason.ALGORITHM_CONSTRAINED) {
+ throw new Exception(
+ "Expect to get ALGORITHM_CONSTRAINED CPVE", cpve);
+ }
+
System.out.println("Get the expected exception " + cpve);
}
@@ -230,6 +240,13 @@
validate(intermediate_MD2withRSA_1024_512);
throw new Exception("expected algorithm disabled exception");
} catch (CertPathValidatorException cpve) {
+ // we may get ClassCastException here
+ BasicReason reason = (BasicReason)cpve.getReason();
+ if (reason != BasicReason.ALGORITHM_CONSTRAINED) {
+ throw new Exception(
+ "Expect to get ALGORITHM_CONSTRAINED CPVE", cpve);
+ }
+
System.out.println("Get the expected exception " + cpve);
}
}
--- a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorTrustAnchor.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorTrustAnchor.java Mon Feb 14 16:30:10 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,10 @@
/**
* @test
*
- * @bug 6861062
+ * @bug 6861062 7011497
* @summary Disable MD2 support
+ * new CertPathValidatorException.BasicReason enum constant for
+ * constrained algorithm
*
* @author Xuelei Fan
*/
@@ -35,6 +37,7 @@
import java.util.*;
import java.security.Security;
import java.security.cert.*;
+import java.security.cert.CertPathValidatorException.*;
public class CPValidatorTrustAnchor {
@@ -142,6 +145,13 @@
validate(trustAnchor_MD2withRSA_2048);
throw new Exception("expected algorithm disabled exception");
} catch (CertPathValidatorException cpve) {
+ // we may get ClassCastException here
+ BasicReason reason = (BasicReason)cpve.getReason();
+ if (reason != BasicReason.ALGORITHM_CONSTRAINED) {
+ throw new Exception(
+ "Expect to get ALGORITHM_CONSTRAINED CPVE", cpve);
+ }
+
System.out.println("Get the expected exception " + cpve);
}
}
--- a/jdk/test/tools/launcher/Arrrghs.java Thu Feb 10 16:24:40 2011 -0800
+++ b/jdk/test/tools/launcher/Arrrghs.java Mon Feb 14 16:30:10 2011 -0800
@@ -24,7 +24,7 @@
/**
* @test
* @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938
- * 6894719
+ * 6894719 6968053
* @summary Argument parsing validation.
* @compile -XDignore.symbol.file Arrrghs.java TestHelper.java
* @run main Arrrghs
@@ -250,13 +250,11 @@
TestHelper.createJar("MIA", new File("some.jar"), new File("Foo"),
(String[])null);
tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar");
- tr.contains("Error: Could not find main class MIA");
- tr.contains("java.lang.NoClassDefFoundError: MIA");
+ tr.contains("Error: Could not find or load main class MIA");
System.out.println(tr);
// use classpath to check
tr = TestHelper.doExec(TestHelper.javaCmd, "-cp", "some.jar", "MIA");
- tr.contains("Error: Could not find main class MIA");
- tr.contains("java.lang.NoClassDefFoundError: MIA");
+ tr.contains("Error: Could not find or load main class MIA");
System.out.println(tr);
// incorrect method access
@@ -305,12 +303,12 @@
// amongst a potpourri of kindred main methods, is the right one chosen ?
TestHelper.createJar(new File("some.jar"), new File("Foo"),
- "void main(Object[] args){}",
- "int main(Float[] args){return 1;}",
- "private void main() {}",
- "private static void main(int x) {}",
- "public int main(int argc, String[] argv) {return 1;}",
- "public static void main(String[] args) {System.out.println(\"THE_CHOSEN_ONE\");}");
+ "void main(Object[] args){}",
+ "int main(Float[] args){return 1;}",
+ "private void main() {}",
+ "private static void main(int x) {}",
+ "public int main(int argc, String[] argv) {return 1;}",
+ "public static void main(String[] args) {System.out.println(\"THE_CHOSEN_ONE\");}");
tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar");
tr.contains("THE_CHOSEN_ONE");
System.out.println(tr);
@@ -326,6 +324,30 @@
tr.checkPositive();
System.out.println(tr);
}
+ // tests 6968053, ie. we turn on the -Xdiag (for now) flag and check if
+ // the suppressed stack traces are exposed.
+ static void runDiagOptionTests() throws FileNotFoundException {
+ TestHelper.TestResult tr = null;
+ // a missing class
+ TestHelper.createJar("MIA", new File("some.jar"), new File("Foo"),
+ (String[])null);
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "-jar", "some.jar");
+ tr.contains("Error: Could not find or load main class MIA");
+ tr.contains("java.lang.ClassNotFoundException: MIA");
+ System.out.println(tr);
+
+ // use classpath to check
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "-cp", "some.jar", "MIA");
+ tr.contains("Error: Could not find or load main class MIA");
+ tr.contains("java.lang.ClassNotFoundException: MIA");
+ System.out.println(tr);
+
+ // a missing class on the classpath
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "NonExistentClass");
+ tr.contains("Error: Could not find or load main class NonExistentClass");
+ tr.contains("java.lang.ClassNotFoundException: NonExistentClass");
+ System.out.println(tr);
+ }
static void test6894719() {
// test both arguments to ensure they exist
@@ -352,6 +374,7 @@
runBasicErrorMessageTests();
runMainMethodTests();
test6894719();
+ runDiagOptionTests();
if (TestHelper.testExitValue > 0) {
System.out.println("Total of " + TestHelper.testExitValue + " failed");
System.exit(1);