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