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 24import java.io.IOException; 25import java.nio.file.FileSystem; 26import java.nio.file.FileSystems; 27import java.nio.file.Files; 28import java.nio.file.InvalidPathException; 29import java.nio.file.Path; 30 31/** 32 * 33 * @test 34 * @bug 8038500 8040059 8139956 8146754 8172921 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 42public 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 resolvePath(String other, String expected) { 184 out.format("test resolve %s\n", other); 185 checkPath(); 186 check(path.resolve(fs.getPath(other)), expected); 187 return this; 188 } 189 190 PathOps resolveSibling(String other, String expected) { 191 out.format("test resolveSibling %s\n", other); 192 checkPath(); 193 check(path.resolveSibling(other), expected); 194 return this; 195 } 196 197 PathOps relativize(String other, String expected) { 198 out.format("test relativize %s\n", other); 199 checkPath(); 200 Path that = fs.getPath(other); 201 check(path.relativize(that), expected); 202 return this; 203 } 204 205 PathOps normalize(String expected) { 206 out.println("check normalized path"); 207 checkPath(); 208 check(path.normalize(), expected); 209 return this; 210 } 211 212 PathOps string(String expected) { 213 out.println("check string representation"); 214 checkPath(); 215 check(path, expected); 216 return this; 217 } 218 219 PathOps isSameFile(String target) { 220 try { 221 out.println("check two paths are same"); 222 checkPath(); 223 check(Files.isSameFile(path, test(target).path()), true); 224 } catch (IOException ioe) { 225 fail(); 226 } 227 return this; 228 } 229 230 PathOps invalid() { 231 if (!(exc instanceof InvalidPathException)) { 232 out.println("InvalidPathException not thrown as expected"); 233 fail(); 234 } 235 return this; 236 } 237 238 static PathOps test(String s) { 239 return new PathOps(s); 240 } 241 242 static PathOps test(String first, String... more) { 243 return new PathOps(first, more); 244 } 245 246 // -- PathOpss -- 247 248 static void header(String s) { 249 out.println(); 250 out.println(); 251 out.println("-- " + s + " --"); 252 } 253 254 static void doPathOpTests() { 255 header("Path operations"); 256 257 // construction 258 test("/") 259 .string("/"); 260 test("/", "") 261 .string("/"); 262 test("/", "foo") 263 .string("/foo"); 264 test("/", "/foo") 265 .string("/foo"); 266 test("/", "foo/") 267 .string("/foo"); 268 test("foo", "bar", "gus") 269 .string("foo/bar/gus"); 270 test("") 271 .string(""); 272 test("", "/") 273 .string("/"); 274 test("", "foo", "", "bar", "", "/gus") 275 .string("foo/bar/gus"); 276 277 // all components 278 test("/a/b/c") 279 .root("/") 280 .parent("/a/b") 281 .name("c"); 282 283 // root component only 284 test("/") 285 .root("/") 286 .parent(null) 287 .name(null); 288 289 // no root component 290 test("a/b") 291 .root(null) 292 .parent("a") 293 .name("b"); 294 295 // name component only 296 test("foo") 297 .root(null) 298 .parent(null) 299 .name("foo"); 300 301 // startsWith 302 test("") 303 .starts("") 304 .notStarts("/"); 305 test("/") 306 .starts("/") 307 .notStarts("/foo"); 308 test("/foo") 309 .starts("/") 310 .starts("/foo") 311 .notStarts("/f") 312 .notStarts(""); 313 test("/foo/bar") 314 .starts("/") 315 .starts("/foo") 316 .starts("/foo/") 317 .starts("/foo/bar") 318 .notStarts("/f") 319 .notStarts("foo") 320 .notStarts("foo/bar") 321 .notStarts(""); 322 test("foo") 323 .starts("foo") 324 .notStarts("f"); 325 test("foo/bar") 326 .starts("foo") 327 .starts("foo/") 328 .starts("foo/bar") 329 .notStarts("f") 330 .notStarts("/foo") 331 .notStarts("/foo/bar"); 332 333 // endsWith 334 test("") 335 .ends("") 336 .notEnds("/"); 337 test("/") 338 .ends("/") 339 .notEnds("foo") 340 .notEnds("/foo"); 341 test("/foo") 342 .ends("foo") 343 .ends("/foo") 344 .notEnds("/"); 345 test("/foo/bar") 346 .ends("bar") 347 .ends("foo/bar") 348 .ends("foo/bar/") 349 .ends("/foo/bar") 350 .notEnds("/bar"); 351 test("/foo/bar/") 352 .ends("bar") 353 .ends("foo/bar") 354 .ends("foo/bar/") 355 .ends("/foo/bar") 356 .notEnds("/bar"); 357 test("foo") 358 .ends("foo"); 359 test("foo/bar") 360 .ends("bar") 361 .ends("bar/") 362 .ends("foo/bar/") 363 .ends("foo/bar"); 364 365 // elements 366 test("a/b/c") 367 .element(0,"a") 368 .element(1,"b") 369 .element(2,"c"); 370 371 // isAbsolute 372 test("/") 373 .absolute(); 374 test("/tmp") 375 .absolute(); 376 test("tmp") 377 .notAbsolute(); 378 test("") 379 .notAbsolute(); 380 381 // resolve 382 test("/tmp") 383 .resolve("foo", "/tmp/foo") 384 .resolve("/foo", "/foo") 385 .resolve("", "/tmp"); 386 test("tmp") 387 .resolve("foo", "tmp/foo") 388 .resolve("/foo", "/foo") 389 .resolve("", "tmp"); 390 test("") 391 .resolve("", "") 392 .resolve("foo", "foo") 393 .resolve("/foo", "/foo"); 394 test("/") 395 .resolve("", "/") 396 .resolve("foo", "/foo") 397 .resolve("/foo", "/foo") 398 .resolve("/foo/", "/foo"); 399 400 // resolve(Path) 401 test("/tmp") 402 .resolvePath("foo", "/tmp/foo") 403 .resolvePath("/foo", "/foo") 404 .resolvePath("", "/tmp"); 405 test("tmp") 406 .resolvePath("foo", "tmp/foo") 407 .resolvePath("/foo", "/foo") 408 .resolvePath("", "tmp"); 409 test("") 410 .resolvePath("", "") 411 .resolvePath("foo", "foo") 412 .resolvePath("/foo", "/foo"); 413 test("/") 414 .resolvePath("", "/") 415 .resolvePath("foo", "/foo") 416 .resolvePath("/foo", "/foo") 417 .resolvePath("/foo/", "/foo"); 418 419 // resolveSibling 420 test("foo") 421 .resolveSibling("bar", "bar") 422 .resolveSibling("/bar", "/bar") 423 .resolveSibling("", ""); 424 test("foo/bar") 425 .resolveSibling("gus", "foo/gus") 426 .resolveSibling("/gus", "/gus") 427 .resolveSibling("", "foo"); 428 test("/foo") 429 .resolveSibling("gus", "/gus") 430 .resolveSibling("/gus", "/gus") 431 .resolveSibling("", "/"); 432 test("/foo/bar") 433 .resolveSibling("gus", "/foo/gus") 434 .resolveSibling("/gus", "/gus") 435 .resolveSibling("", "/foo"); 436 test("") 437 .resolveSibling("foo", "foo") 438 .resolveSibling("/foo", "/foo") 439 .resolve("", ""); 440 441 // relativize 442 test("/a/b/c") 443 .relativize("/a/b/c", "") 444 .relativize("/a/b/c/d/e", "d/e") 445 .relativize("/a/x", "../../x") 446 .relativize("/x", "../../../x"); 447 test("a/b/c") 448 .relativize("a/b/c/d", "d") 449 .relativize("a/x", "../../x") 450 .relativize("x", "../../../x") 451 .relativize("", "../../.."); 452 test("") 453 .relativize("a", "a") 454 .relativize("a/b/c", "a/b/c") 455 .relativize("", ""); 456 test("/") 457 .relativize("/a", "a") 458 .relativize("/a/c", "a/c"); 459 // 8146754 460 test("/tmp/path") 461 .relativize("/tmp/path/a.txt", "a.txt"); 462 test("/tmp/path/") 463 .relativize("/tmp/path/a.txt", "a.txt"); 464 465 // normalize 466 test("/") 467 .normalize("/"); 468 test("foo") 469 .normalize("foo"); 470 test("/foo") 471 .normalize("/foo"); 472 test(".") 473 .normalize(""); 474 test("..") 475 .normalize(".."); 476 test("/..") 477 .normalize("/"); 478 test("/../..") 479 .normalize("/"); 480 test("foo/.") 481 .normalize("foo"); 482 test("./foo") 483 .normalize("foo"); 484 test("foo/..") 485 .normalize(""); 486 test("../foo") 487 .normalize("../foo"); 488 test("../../foo") 489 .normalize("../../foo"); 490 test("foo/bar/..") 491 .normalize("foo"); 492 test("foo/bar/gus/../..") 493 .normalize("foo"); 494 test("/foo/bar/gus/../..") 495 .normalize("/foo"); 496 test("/./.") 497 .normalize("/"); 498 test("/.") 499 .normalize("/"); 500 test("/./abc") 501 .normalize("/abc"); 502 // invalid 503 test("foo\u0000bar") 504 .invalid(); 505 test("\u0000foo") 506 .invalid(); 507 test("bar\u0000") 508 .invalid(); 509 test("//foo\u0000bar") 510 .invalid(); 511 test("//\u0000foo") 512 .invalid(); 513 test("//bar\u0000") 514 .invalid(); 515 516 // normalization 517 test("//foo//bar") 518 .string("/foo/bar") 519 .root("/") 520 .parent("/foo") 521 .name("bar"); 522 523 // isSameFile 524 test("/fileDoesNotExist") 525 .isSameFile("/fileDoesNotExist"); 526 527 // 8139956 528 out.println("check getNameCount"); 529 int nc = fs.getPath("/").relativize(fs.getPath("/")).getNameCount(); 530 if (nc != 1) { 531 out.format("\tExpected: 1\n"); 532 out.format("\tActual: %d\n", nc); 533 throw new RuntimeException("getNameCount of empty path failed"); 534 } 535 } 536 537 static void npes() { 538 header("NullPointerException"); 539 540 Path path = fs.getPath("foo"); 541 542 try { 543 path.resolve((String)null); 544 throw new RuntimeException("NullPointerException not thrown"); 545 } catch (NullPointerException npe) { 546 } 547 548 try { 549 path.relativize(null); 550 throw new RuntimeException("NullPointerException not thrown"); 551 } catch (NullPointerException npe) { 552 } 553 554 try { 555 path.compareTo(null); 556 throw new RuntimeException("NullPointerException not thrown"); 557 } catch (NullPointerException npe) { 558 } 559 560 try { 561 path.startsWith((Path)null); 562 throw new RuntimeException("NullPointerException not thrown"); 563 } catch (NullPointerException npe) { 564 } 565 566 try { 567 path.endsWith((Path)null); 568 throw new RuntimeException("NullPointerException not thrown"); 569 } catch (NullPointerException npe) { 570 } 571 572 } 573 574 public static void main(String[] args) throws IOException { 575 // create empty JAR file, test doesn't require any contents 576 Path emptyJar = Utils.createJarFile("empty.jar"); 577 578 fs = FileSystems.newFileSystem(emptyJar, null); 579 try { 580 npes(); 581 doPathOpTests(); 582 } finally { 583 fs.close(); 584 } 585} 586} 587