1 /* 2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.io.IOException; 25 import java.nio.file.FileSystem; 26 import java.nio.file.FileSystems; 27 import java.nio.file.Files; 28 import java.nio.file.InvalidPathException; 29 import java.nio.file.Path; 30 31 /** 32 * 33 * @test 34 * @bug 8038500 8040059 8139956 8146754 35 * @summary Tests path operations for zip provider. 36 * 37 * @run main PathOps 38 * @run main/othervm/java.security.policy=test.policy PathOps 39 * @modules jdk.zipfs 40 */ 41 42 public class PathOps { 43 44 static final java.io.PrintStream out = System.out; 45 static FileSystem fs; 46 47 private String input; 48 private Path path; 49 private Exception exc; 50 51 private PathOps(String first, String... more) { 52 out.println(); 53 input = first; 54 try { 55 path = fs.getPath(first, more); 56 out.format("%s -> %s", first, path); 57 } catch (Exception x) { 58 exc = x; 59 out.format("%s -> %s", first, x); 60 } 61 out.println(); 62 } 63 64 Path path() { 65 return path; 66 } 67 68 void fail() { 69 throw new RuntimeException("PathOps failed"); 70 } 71 72 void checkPath() { 73 if (path == null) { 74 throw new InternalError("path is null"); 75 } 76 } 77 78 void check(Object result, String expected) { 79 out.format("\tExpected: %s\n", expected); 80 out.format("\tActual: %s\n", result); 81 if (result == null) { 82 if (expected == null) return; 83 } else { 84 // compare string representations 85 if (expected != null && result.toString().equals(expected.toString())) 86 return; 87 } 88 fail(); 89 } 90 91 void check(Object result, boolean expected) { 92 check(result, Boolean.toString(expected)); 93 } 94 95 PathOps root(String expected) { 96 out.println("check root"); 97 checkPath(); 98 check(path.getRoot(), expected); 99 return this; 100 } 101 102 PathOps parent(String expected) { 103 out.println("check parent"); 104 checkPath(); 105 check(path.getParent(), expected); 106 return this; 107 } 108 109 PathOps name(String expected) { 110 out.println("check name"); 111 checkPath(); 112 check(path.getFileName(), expected); 113 return this; 114 } 115 116 PathOps element(int index, String expected) { 117 out.format("check element %d\n", index); 118 checkPath(); 119 check(path.getName(index), expected); 120 return this; 121 } 122 123 PathOps subpath(int startIndex, int endIndex, String expected) { 124 out.format("test subpath(%d,%d)\n", startIndex, endIndex); 125 checkPath(); 126 check(path.subpath(startIndex, endIndex), expected); 127 return this; 128 } 129 130 PathOps starts(String prefix) { 131 out.format("test startsWith with %s\n", prefix); 132 checkPath(); 133 Path s = fs.getPath(prefix); 134 check(path.startsWith(s), true); 135 return this; 136 } 137 138 PathOps notStarts(String prefix) { 139 out.format("test not startsWith with %s\n", prefix); 140 checkPath(); 141 Path s = fs.getPath(prefix); 142 check(path.startsWith(s), false); 143 return this; 144 } 145 146 PathOps ends(String suffix) { 147 out.format("test endsWith %s\n", suffix); 148 checkPath(); 149 Path s = fs.getPath(suffix); 150 check(path.endsWith(s), true); 151 return this; 152 } 153 154 PathOps notEnds(String suffix) { 155 out.format("test not endsWith %s\n", suffix); 156 checkPath(); 157 Path s = fs.getPath(suffix); 158 check(path.endsWith(s), false); 159 return this; 160 } 161 162 PathOps absolute() { 163 out.println("check path is absolute"); 164 checkPath(); 165 check(path.isAbsolute(), true); 166 return this; 167 } 168 169 PathOps notAbsolute() { 170 out.println("check path is not absolute"); 171 checkPath(); 172 check(path.isAbsolute(), false); 173 return this; 174 } 175 176 PathOps resolve(String other, String expected) { 177 out.format("test resolve %s\n", other); 178 checkPath(); 179 check(path.resolve(other), expected); 180 return this; 181 } 182 183 PathOps resolveSibling(String other, String expected) { 184 out.format("test resolveSibling %s\n", other); 185 checkPath(); 186 check(path.resolveSibling(other), expected); 187 return this; 188 } 189 190 PathOps relativize(String other, String expected) { 191 out.format("test relativize %s\n", other); 192 checkPath(); 193 Path that = fs.getPath(other); 194 check(path.relativize(that), expected); 195 return this; 196 } 197 198 PathOps normalize(String expected) { 199 out.println("check normalized path"); 200 checkPath(); 201 check(path.normalize(), expected); 202 return this; 203 } 204 205 PathOps string(String expected) { 206 out.println("check string representation"); 207 checkPath(); 208 check(path, expected); 209 return this; 210 } 211 212 PathOps isSameFile(String target) { 213 try { 214 out.println("check two paths are same"); 215 checkPath(); 216 check(Files.isSameFile(path, test(target).path()), true); 217 } catch (IOException ioe) { 218 fail(); 219 } 220 return this; 221 } 222 223 PathOps invalid() { 224 if (!(exc instanceof InvalidPathException)) { 225 out.println("InvalidPathException not thrown as expected"); 226 fail(); 227 } 228 return this; 229 } 230 231 static PathOps test(String s) { 232 return new PathOps(s); 233 } 234 235 static PathOps test(String first, String... more) { 236 return new PathOps(first, more); 237 } 238 239 // -- PathOpss -- 240 241 static void header(String s) { 242 out.println(); 243 out.println(); 244 out.println("-- " + s + " --"); 245 } 246 247 static void doPathOpTests() { 248 header("Path operations"); 249 250 // construction 251 test("/") 252 .string("/"); 253 test("/", "") 254 .string("/"); 255 test("/", "foo") 256 .string("/foo"); 257 test("/", "/foo") 258 .string("/foo"); 259 test("/", "foo/") 260 .string("/foo"); 261 test("foo", "bar", "gus") 262 .string("foo/bar/gus"); 263 test("") 264 .string(""); 265 test("", "/") 266 .string("/"); 267 test("", "foo", "", "bar", "", "/gus") 268 .string("foo/bar/gus"); 269 270 // all components 271 test("/a/b/c") 272 .root("/") 273 .parent("/a/b") 274 .name("c"); 275 276 // root component only 277 test("/") 278 .root("/") 279 .parent(null) 280 .name(null); 281 282 // no root component 283 test("a/b") 284 .root(null) 285 .parent("a") 286 .name("b"); 287 288 // name component only 289 test("foo") 290 .root(null) 291 .parent(null) 292 .name("foo"); 293 294 // startsWith 295 test("") 296 .starts("") 297 .notStarts("/"); 298 test("/") 299 .starts("/") 300 .notStarts("/foo"); 301 test("/foo") 302 .starts("/") 303 .starts("/foo") 304 .notStarts("/f") 305 .notStarts(""); 306 test("/foo/bar") 307 .starts("/") 308 .starts("/foo") 309 .starts("/foo/") 310 .starts("/foo/bar") 311 .notStarts("/f") 312 .notStarts("foo") 313 .notStarts("foo/bar") 314 .notStarts(""); 315 test("foo") 316 .starts("foo") 317 .notStarts("f"); 318 test("foo/bar") 319 .starts("foo") 320 .starts("foo/") 321 .starts("foo/bar") 322 .notStarts("f") 323 .notStarts("/foo") 324 .notStarts("/foo/bar"); 325 326 // endsWith 327 test("") 328 .ends("") 329 .notEnds("/"); 330 test("/") 331 .ends("/") 332 .notEnds("foo") 333 .notEnds("/foo"); 334 test("/foo") 335 .ends("foo") 336 .ends("/foo") 337 .notEnds("/"); 338 test("/foo/bar") 339 .ends("bar") 340 .ends("foo/bar") 341 .ends("foo/bar/") 342 .ends("/foo/bar") 343 .notEnds("/bar"); 344 test("/foo/bar/") 345 .ends("bar") 346 .ends("foo/bar") 347 .ends("foo/bar/") 348 .ends("/foo/bar") 349 .notEnds("/bar"); 350 test("foo") 351 .ends("foo"); 352 test("foo/bar") 353 .ends("bar") 354 .ends("bar/") 355 .ends("foo/bar/") 356 .ends("foo/bar"); 357 358 // elements 359 test("a/b/c") 360 .element(0,"a") 361 .element(1,"b") 362 .element(2,"c"); 363 364 // isAbsolute 365 test("/") 366 .absolute(); 367 test("/tmp") 368 .absolute(); 369 test("tmp") 370 .notAbsolute(); 371 test("") 372 .notAbsolute(); 373 374 // resolve 375 test("/tmp") 376 .resolve("foo", "/tmp/foo") 377 .resolve("/foo", "/foo") 378 .resolve("", "/tmp"); 379 test("tmp") 380 .resolve("foo", "tmp/foo") 381 .resolve("/foo", "/foo") 382 .resolve("", "tmp"); 383 test("") 384 .resolve("", "") 385 .resolve("foo", "foo") 386 .resolve("/foo", "/foo"); 387 388 // resolveSibling 389 test("foo") 390 .resolveSibling("bar", "bar") 391 .resolveSibling("/bar", "/bar") 392 .resolveSibling("", ""); 393 test("foo/bar") 394 .resolveSibling("gus", "foo/gus") 395 .resolveSibling("/gus", "/gus") 396 .resolveSibling("", "foo"); 397 test("/foo") 398 .resolveSibling("gus", "/gus") 399 .resolveSibling("/gus", "/gus") 400 .resolveSibling("", "/"); 401 test("/foo/bar") 402 .resolveSibling("gus", "/foo/gus") 403 .resolveSibling("/gus", "/gus") 404 .resolveSibling("", "/foo"); 405 test("") 406 .resolveSibling("foo", "foo") 407 .resolveSibling("/foo", "/foo") 408 .resolve("", ""); 409 410 // relativize 411 test("/a/b/c") 412 .relativize("/a/b/c", "") 413 .relativize("/a/b/c/d/e", "d/e") 414 .relativize("/a/x", "../../x") 415 .relativize("/x", "../../../x"); 416 test("a/b/c") 417 .relativize("a/b/c/d", "d") 418 .relativize("a/x", "../../x") 419 .relativize("x", "../../../x") 420 .relativize("", "../../.."); 421 test("") 422 .relativize("a", "a") 423 .relativize("a/b/c", "a/b/c") 424 .relativize("", ""); 425 test("/") 426 .relativize("/a", "a") 427 .relativize("/a/c", "a/c"); 428 // 8146754 429 test("/tmp/path") 430 .relativize("/tmp/path/a.txt", "a.txt"); 431 test("/tmp/path/") 432 .relativize("/tmp/path/a.txt", "a.txt"); 433 434 // normalize 435 test("/") 436 .normalize("/"); 437 test("foo") 438 .normalize("foo"); 439 test("/foo") 440 .normalize("/foo"); 441 test(".") 442 .normalize(""); 443 test("..") 444 .normalize(".."); 445 test("/..") 446 .normalize("/"); 447 test("/../..") 448 .normalize("/"); 449 test("foo/.") 450 .normalize("foo"); 451 test("./foo") 452 .normalize("foo"); 453 test("foo/..") 454 .normalize(""); 455 test("../foo") 456 .normalize("../foo"); 457 test("../../foo") 458 .normalize("../../foo"); 459 test("foo/bar/..") 460 .normalize("foo"); 461 test("foo/bar/gus/../..") 462 .normalize("foo"); 463 test("/foo/bar/gus/../..") 464 .normalize("/foo"); 465 test("/./.") 466 .normalize("/"); 467 test("/.") 468 .normalize("/"); 469 test("/./abc") 470 .normalize("/abc"); 471 // invalid 472 test("foo\u0000bar") 473 .invalid(); 474 test("\u0000foo") 475 .invalid(); 476 test("bar\u0000") 477 .invalid(); 478 test("//foo\u0000bar") 479 .invalid(); 480 test("//\u0000foo") 481 .invalid(); 482 test("//bar\u0000") 483 .invalid(); 484 485 // normalization 486 test("//foo//bar") 487 .string("/foo/bar") 488 .root("/") 489 .parent("/foo") 490 .name("bar"); 491 492 // isSameFile 493 test("/fileDoesNotExist") 494 .isSameFile("/fileDoesNotExist"); 495 496 // 8139956 497 out.println("check getNameCount"); 498 int nc = fs.getPath("/").relativize(fs.getPath("/")).getNameCount(); 499 if (nc != 1) { 500 out.format("\tExpected: 1\n"); 501 out.format("\tActual: %d\n", nc); 502 throw new RuntimeException("getNameCount of empty path failed"); 503 } 504 } 505 506 static void npes() { 507 header("NullPointerException"); 508 509 Path path = fs.getPath("foo"); 510 511 try { 512 path.resolve((String)null); 513 throw new RuntimeException("NullPointerException not thrown"); 514 } catch (NullPointerException npe) { 515 } 516 517 try { 518 path.relativize(null); 519 throw new RuntimeException("NullPointerException not thrown"); 520 } catch (NullPointerException npe) { 521 } 522 523 try { 524 path.compareTo(null); 525 throw new RuntimeException("NullPointerException not thrown"); 526 } catch (NullPointerException npe) { 527 } 528 529 try { 530 path.startsWith((Path)null); 531 throw new RuntimeException("NullPointerException not thrown"); 532 } catch (NullPointerException npe) { 533 } 534 535 try { 536 path.endsWith((Path)null); 537 throw new RuntimeException("NullPointerException not thrown"); 538 } catch (NullPointerException npe) { 539 } 540 541 } 542 543 public static void main(String[] args) throws IOException { 544 // create empty JAR file, test doesn't require any contents 545 Path emptyJar = Utils.createJarFile("empty.jar"); 546 547 fs = FileSystems.newFileSystem(emptyJar, null); 548 try { 549 npes(); 550 doPathOpTests(); 551 } finally { 552 fs.close(); 553 } 554 } 555 }