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.nio.file.*;
  25 import java.net.*;
  26 import java.util.*;
  27 import java.io.IOException;
  28 
  29 /**
  30  *
  31  * @test
  32  * @bug 8038500
  33  * @summary Tests path operations for zip provider.
  34  */
  35 
  36 public class PathOps {
  37 
  38     static final java.io.PrintStream out = System.out;
  39     static FileSystem fs;
  40 
  41     private String input;
  42     private Path path;
  43     private Exception exc;
  44 
  45     private PathOps(String s) {
  46         out.println();
  47         input = s;
  48         try {
  49             path = fs.getPath(s);
  50             out.format("%s -> %s", s, path);
  51         } catch (Exception x) {
  52             exc = x;
  53             out.format("%s -> %s", s, x);
  54         }
  55         out.println();
  56     }
  57 
  58     Path path() {
  59         return path;
  60     }
  61 
  62     void fail() {
  63         throw new RuntimeException("PathOps failed");
  64     }
  65 
  66     void checkPath() {
  67         if (path == null) {
  68             throw new InternalError("path is null");
  69         }
  70     }
  71 
  72     void check(Object result, String expected) {
  73         out.format("\tExpected: %s\n", expected);
  74         out.format("\tActual: %s\n",  result);
  75         if (result == null) {
  76             if (expected == null) return;
  77         } else {
  78             // compare string representations
  79             if (expected != null && result.toString().equals(expected.toString()))
  80                 return;
  81         }
  82         fail();
  83     }
  84 
  85     void check(Object result, boolean expected) {
  86         check(result, Boolean.toString(expected));
  87     }
  88 
  89     PathOps root(String expected) {
  90         out.println("check root");
  91         checkPath();
  92         check(path.getRoot(), expected);
  93         return this;
  94     }
  95 
  96     PathOps parent(String expected) {
  97         out.println("check parent");
  98         checkPath();
  99         check(path.getParent(), expected);
 100         return this;
 101     }
 102 
 103     PathOps name(String expected) {
 104         out.println("check name");
 105         checkPath();
 106         check(path.getFileName(), expected);
 107         return this;
 108     }
 109 
 110     PathOps element(int index, String expected) {
 111         out.format("check element %d\n", index);
 112         checkPath();
 113         check(path.getName(index), expected);
 114         return this;
 115     }
 116 
 117     PathOps subpath(int startIndex, int endIndex, String expected) {
 118         out.format("test subpath(%d,%d)\n", startIndex, endIndex);
 119         checkPath();
 120         check(path.subpath(startIndex, endIndex), expected);
 121         return this;
 122     }
 123 
 124     PathOps starts(String prefix) {
 125         out.format("test startsWith with %s\n", prefix);
 126         checkPath();
 127         Path s = fs.getPath(prefix);
 128         check(path.startsWith(s), true);
 129         return this;
 130     }
 131 
 132     PathOps notStarts(String prefix) {
 133         out.format("test not startsWith with %s\n", prefix);
 134         checkPath();
 135         Path s = fs.getPath(prefix);
 136         check(path.startsWith(s), false);
 137         return this;
 138     }
 139 
 140     PathOps ends(String suffix) {
 141         out.format("test endsWith %s\n", suffix);
 142         checkPath();
 143         Path s = fs.getPath(suffix);
 144         check(path.endsWith(s), true);
 145         return this;
 146     }
 147 
 148     PathOps notEnds(String suffix) {
 149         out.format("test not endsWith %s\n", suffix);
 150         checkPath();
 151         Path s = fs.getPath(suffix);
 152         check(path.endsWith(s), false);
 153         return this;
 154     }
 155 
 156     PathOps absolute() {
 157         out.println("check path is absolute");
 158         checkPath();
 159         check(path.isAbsolute(), true);
 160         return this;
 161     }
 162 
 163     PathOps notAbsolute() {
 164         out.println("check path is not absolute");
 165         checkPath();
 166         check(path.isAbsolute(), false);
 167         return this;
 168     }
 169 
 170     PathOps resolve(String other, String expected) {
 171         out.format("test resolve %s\n", other);
 172         checkPath();
 173         check(path.resolve(other), expected);
 174         return this;
 175     }
 176 
 177     PathOps relativize(String other, String expected) {
 178         out.format("test relativize %s\n", other);
 179         checkPath();
 180         Path that = fs.getPath(other);
 181         check(path.relativize(that), expected);
 182         return this;
 183     }
 184 
 185     PathOps normalize(String expected) {
 186         out.println("check normalized path");
 187         checkPath();
 188         check(path.normalize(), expected);
 189         return this;
 190     }
 191 
 192     PathOps string(String expected) {
 193         out.println("check string representation");
 194         checkPath();
 195         check(path, expected);
 196         return this;
 197     }
 198 
 199     PathOps isSameFile(String target) {
 200         try {
 201             out.println("check two paths are same");
 202             checkPath();
 203             check(Files.isSameFile(path, test(target).path()), true);
 204         } catch (IOException ioe) {
 205             fail();
 206         }
 207         return this;
 208     }
 209 
 210     PathOps invalid() {
 211         if (!(exc instanceof InvalidPathException)) {
 212             out.println("InvalidPathException not thrown as expected");
 213             fail();
 214         }
 215         return this;
 216     }
 217 
 218     static PathOps test(String s) {
 219         return new PathOps(s);
 220     }
 221 
 222     // -- PathOpss --
 223 
 224     static void header(String s) {
 225         out.println();
 226         out.println();
 227         out.println("-- " + s + " --");
 228     }
 229 
 230     static void doPathOpTests() {
 231         header("Path operations");
 232 
 233         // all components
 234         test("/a/b/c")
 235             .root("/")
 236             .parent("/a/b")
 237             .name("c");
 238 
 239         // root component only
 240         test("/")
 241             .root("/")
 242             .parent(null)
 243             .name(null);
 244 
 245         // no root component
 246         test("a/b")
 247             .root(null)
 248             .parent("a")
 249             .name("b");
 250 
 251         // name component only
 252         test("foo")
 253             .root(null)
 254             .parent(null)
 255             .name("foo");
 256 
 257         // startsWith
 258         test("")
 259             .starts("")
 260             .notStarts("/");
 261         test("/")
 262             .starts("/")
 263             .notStarts("/foo");
 264         test("/foo")
 265             .starts("/")
 266             .starts("/foo")
 267             .notStarts("/f")
 268             .notStarts("");
 269         test("/foo/bar")
 270             .starts("/")
 271             .starts("/foo")
 272             .starts("/foo/")
 273             .starts("/foo/bar")
 274             .notStarts("/f")
 275             .notStarts("foo")
 276             .notStarts("foo/bar")
 277             .notStarts("");
 278         test("foo")
 279             .starts("foo")
 280             .notStarts("f");
 281         test("foo/bar")
 282             .starts("foo")
 283             .starts("foo/")
 284             .starts("foo/bar")
 285             .notStarts("f")
 286             .notStarts("/foo")
 287             .notStarts("/foo/bar");
 288 
 289         // endsWith
 290         test("")
 291             .ends("")
 292             .notEnds("/");
 293         test("/")
 294             .ends("/")
 295             .notEnds("foo")
 296             .notEnds("/foo");
 297         test("/foo")
 298             .ends("foo")
 299             .ends("/foo")
 300             .notEnds("/");
 301         test("/foo/bar")
 302             .ends("bar")
 303             .ends("foo/bar")
 304             .ends("foo/bar/")
 305             .ends("/foo/bar")
 306             .notEnds("/bar");
 307         test("/foo/bar/")
 308             .ends("bar")
 309             .ends("foo/bar")
 310             .ends("foo/bar/")
 311             .ends("/foo/bar")
 312             .notEnds("/bar");
 313         test("foo")
 314             .ends("foo");
 315         test("foo/bar")
 316             .ends("bar")
 317             .ends("bar/")
 318             .ends("foo/bar/")
 319             .ends("foo/bar");
 320 
 321 
 322         // elements
 323         test("a/b/c")
 324             .element(0,"a")
 325             .element(1,"b")
 326             .element(2,"c");
 327 
 328         // isAbsolute
 329         test("/")
 330             .absolute();
 331         test("/tmp")
 332             .absolute();
 333         test("tmp")
 334             .notAbsolute();
 335         test("")
 336             .notAbsolute();
 337 
 338         // resolve
 339         test("/tmp")
 340             .resolve("foo", "/tmp/foo")
 341             .resolve("/foo", "/foo");
 342         test("tmp")
 343             .resolve("foo", "tmp/foo")
 344             .resolve("/foo", "/foo");
 345 
 346         // relativize
 347         test("/a/b/c")
 348             .relativize("/a/b/c", "")
 349             .relativize("/a/b/c/d/e", "d/e")
 350             .relativize("/a/x", "../../x");
 351 
 352         // normalize
 353         test("/")
 354             .normalize("/");
 355         test("foo")
 356             .normalize("foo");
 357         test("/foo")
 358             .normalize("/foo");
 359         test(".")
 360             .normalize("");
 361         test("..")
 362             .normalize("..");
 363         test("/..")
 364             .normalize("/");
 365         test("/../..")
 366             .normalize("/");
 367         test("foo/.")
 368             .normalize("foo");
 369         test("./foo")
 370             .normalize("foo");
 371         test("foo/..")
 372             .normalize("");
 373         test("../foo")
 374             .normalize("../foo");
 375         test("../../foo")
 376             .normalize("../../foo");
 377         test("foo/bar/..")
 378             .normalize("foo");
 379         test("foo/bar/gus/../..")
 380             .normalize("foo");
 381         test("/foo/bar/gus/../..")
 382             .normalize("/foo");
 383         test("/./.")
 384             .normalize("/");
 385         test("/.")
 386             .normalize("/");
 387         test("/./abc")
 388             .normalize("/abc");
 389         // invalid
 390         test("foo\u0000bar")
 391             .invalid();
 392         test("\u0000foo")
 393             .invalid();
 394         test("bar\u0000")
 395             .invalid();
 396         test("//foo\u0000bar")
 397             .invalid();
 398         test("//\u0000foo")
 399             .invalid();
 400         test("//bar\u0000")
 401             .invalid();
 402 
 403         // normalization
 404         test("//foo//bar")
 405             .string("/foo/bar")
 406             .root("/")
 407             .parent("/foo")
 408             .name("bar");
 409 
 410         // isSameFile
 411         test("/fileDoesNotExist")
 412             .isSameFile("/fileDoesNotExist");
 413     }
 414 
 415     static void npes() {
 416         header("NullPointerException");
 417 
 418         Path path = fs.getPath("foo");
 419 
 420         try {
 421             path.resolve((String)null);
 422             throw new RuntimeException("NullPointerException not thrown");
 423         } catch (NullPointerException npe) {
 424         }
 425 
 426         try {
 427             path.relativize(null);
 428             throw new RuntimeException("NullPointerException not thrown");
 429         } catch (NullPointerException npe) {
 430         }
 431 
 432         try {
 433             path.compareTo(null);
 434             throw new RuntimeException("NullPointerException not thrown");
 435         } catch (NullPointerException npe) {
 436         }
 437 
 438         try {
 439             path.startsWith((Path)null);
 440             throw new RuntimeException("NullPointerException not thrown");
 441         } catch (NullPointerException npe) {
 442         }
 443 
 444         try {
 445             path.endsWith((Path)null);
 446             throw new RuntimeException("NullPointerException not thrown");
 447         } catch (NullPointerException npe) {
 448         }
 449 
 450     }
 451 
 452     public static void main(String[] args) throws Throwable {
 453         Path zipfile = Paths.get(System.getProperty("test.jdk"),
 454                                  "jre/lib/ext/zipfs.jar");
 455         fs = FileSystems.newFileSystem(zipfile, null);
 456         npes();
 457         doPathOpTests();
 458         fs.close();
 459     }
 460 }