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