public static void main(String[] args) throws Exception {
    Path dir1 = TestUtil.createTemporaryDirectory();
    try {

      // Same directory
      testCopyFileToFile(dir1, dir1, TestUtil.supportsLinks(dir1));
      testMove(dir1, dir1, TestUtil.supportsLinks(dir1));

      // Different directories. Use test.dir if possible as it might be
      // a different volume/file system and so improve test coverage.
      String testDir = System.getProperty("test.dir", ".");
      Path dir2 = TestUtil.createTemporaryDirectory(testDir);
      try {
        boolean testSymbolicLinks = TestUtil.supportsLinks(dir1) && TestUtil.supportsLinks(dir2);
        testCopyFileToFile(dir1, dir2, testSymbolicLinks);
        testMove(dir1, dir2, testSymbolicLinks);
      } finally {
        TestUtil.removeAll(dir2);
      }

      // Target is location associated with custom provider
      Path dir3 = PassThroughFileSystem.create().getPath(dir1.toString());
      testCopyFileToFile(dir1, dir3, false);
      testMove(dir1, dir3, false);

      // Test copy(InputStream,Path) and copy(Path,OutputStream)
      testCopyInputStreamToFile();
      testCopyFileToOuputStream();

    } finally {
      TestUtil.removeAll(dir1);
    }
  }
  // copy source to target with verification
  static void copyAndVerify(Path source, Path target, CopyOption... options) throws IOException {
    Path result = copy(source, target, options);
    assertTrue(result == target);

    // get attributes of source and target file to verify copy
    boolean followLinks = true;
    LinkOption[] linkOptions = new LinkOption[0];
    boolean copyAttributes = false;
    for (CopyOption opt : options) {
      if (opt == NOFOLLOW_LINKS) {
        followLinks = false;
        linkOptions = new LinkOption[] {NOFOLLOW_LINKS};
      }
      if (opt == COPY_ATTRIBUTES) copyAttributes = true;
    }
    BasicFileAttributes basicAttributes =
        readAttributes(source, BasicFileAttributes.class, linkOptions);

    // check hash if regular file
    if (basicAttributes.isRegularFile()) assertTrue(computeHash(source) == computeHash(target));

    // check link target if symbolic link
    if (basicAttributes.isSymbolicLink())
      assert (readSymbolicLink(source).equals(readSymbolicLink(target)));

    // check that attributes are copied
    if (copyAttributes && followLinks) {
      checkBasicAttributes(
          basicAttributes, readAttributes(source, BasicFileAttributes.class, linkOptions));

      // verify other attributes when same provider
      if (source.getFileSystem().provider() == target.getFileSystem().provider()) {

        // check POSIX attributes are copied
        String os = System.getProperty("os.name");
        if ((os.equals("SunOS") || os.equals("Linux")) && testPosixAttributes) {
          checkPosixAttributes(
              readAttributes(source, PosixFileAttributes.class, linkOptions),
              readAttributes(target, PosixFileAttributes.class, linkOptions));
        }

        // check DOS attributes are copied
        if (os.startsWith("Windows")) {
          checkDosAttributes(
              readAttributes(source, DosFileAttributes.class, linkOptions),
              readAttributes(target, DosFileAttributes.class, linkOptions));
        }

        // check named attributes are copied
        if (followLinks
            && getFileStore(source).supportsFileAttributeView("xattr")
            && getFileStore(target).supportsFileAttributeView("xattr")) {
          checkUserDefinedFileAttributes(
              readUserDefinedFileAttributes(source), readUserDefinedFileAttributes(target));
        }
      }
    }
  }
  // "randomize" the file attributes of the given file.
  static void randomizeAttributes(Path file) throws IOException {
    String os = System.getProperty("os.name");
    boolean isWindows = os.startsWith("Windows");
    boolean isUnix = os.equals("SunOS") || os.equals("Linux");
    boolean isDirectory = isDirectory(file, NOFOLLOW_LINKS);

    if (isUnix) {
      Set<PosixFilePermission> perms = getPosixFilePermissions(file, NOFOLLOW_LINKS);
      PosixFilePermission[] toChange = {
        PosixFilePermission.GROUP_READ,
        PosixFilePermission.GROUP_WRITE,
        PosixFilePermission.GROUP_EXECUTE,
        PosixFilePermission.OTHERS_READ,
        PosixFilePermission.OTHERS_WRITE,
        PosixFilePermission.OTHERS_EXECUTE
      };
      for (PosixFilePermission perm : toChange) {
        if (heads()) {
          perms.add(perm);
        } else {
          perms.remove(perm);
        }
      }
      setPosixFilePermissions(file, perms);
    }

    if (isWindows) {
      DosFileAttributeView view =
          getFileAttributeView(file, DosFileAttributeView.class, NOFOLLOW_LINKS);
      // only set or unset the hidden attribute
      view.setHidden(heads());
    }

    boolean addUserDefinedFileAttributes =
        heads() && getFileStore(file).supportsFileAttributeView("xattr");

    // remove this when copying a direcory copies its named streams
    if (isWindows && isDirectory) addUserDefinedFileAttributes = false;

    if (addUserDefinedFileAttributes) {
      UserDefinedFileAttributeView view =
          getFileAttributeView(file, UserDefinedFileAttributeView.class);
      int n = rand.nextInt(16);
      while (n > 0) {
        byte[] value = new byte[1 + rand.nextInt(100)];
        view.write("user." + Integer.toString(n), ByteBuffer.wrap(value));
        n--;
      }
    }
  }
  // void processEvents() {
  public void run() {
    System.out.println("WatchDir Thread INFO: priority=" + Thread.currentThread().getPriority());
    for (; ; ) {
      // wait for key to be signalled
      System.out.println("WatchDir INFO: restarting loop...acquiring new key");
      WatchKey key;
      try {
        key = watcher.take();
      } catch (InterruptedException x) {
        return;
      }

      Path dir = keys.get(key);
      if (dir == null) {
        System.err.println("WatchKey not recognized!!");
        continue;
      }

      for (WatchEvent<?> event : key.pollEvents()) {
        WatchEvent.Kind kind = event.kind();
        // TBD - provide example of how OVERFLOW event is handled
        if (kind == OVERFLOW) {
          System.out.println("Encountered OVERFLOW Event - " + event);
          continue;
        }

        // Context for directory entry event is the file name of entry
        WatchEvent<Path> ev = cast(event);
        Path name = ev.context();
        Path child = dir.resolve(name);

        // print out event
        System.out.format("[WatchDir] %s: %s\n", event.kind().name(), child);

        // if directory is created, and watching recursively, then
        // register it and its sub-directories
        if (recursive && (kind == ENTRY_CREATE)) {
          try {
            if (Files.isDirectory(child, NOFOLLOW_LINKS)) {
              registerAll(child);
            }
          } catch (IOException x) {
            // ignore to keep sample readbale
          }
        }

        long t = System.currentTimeMillis();
        if (!Folder.dontWatch.contains(Folder.getInternalPath(child))) {
          Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
          System.out.println(
              "WatchDir#"
                  + key
                  + " INFO: path="
                  + child
                  + ", internal="
                  + Folder.getInternalPath(child)
                  + " is NOT in don't watch list. Forwarding it to other peers. @"
                  + Main.timeToString(t)); // DEBUG
          forwardToItopic(kind, child);
        } else {
          Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
          System.out.println(
              "WatchDir#"
                  + key
                  + " INFO: path="
                  + child
                  + ", internal="
                  + Folder.getInternalPath(child)
                  + " IS in the don't watch list. NOT forwarding. @"
                  + Main.timeToString(t)); // DEBUG
          // try{
          //     Thread.sleep(minDelayBtwnWatchEvents);
          // } catch(InterruptedException ex) {
          //     System.err.println("Exception:"+ex+" while trying to sleep WatchDir thread");
          //     ex.printStackTrace();
          // }
        }
      }

      // reset key and remove from set if directory no longer accessible
      boolean valid = key.reset();
      if (!valid) {
        keys.remove(key);

        // all directories are inaccessible
        if (keys.isEmpty()) {
          break;
        }
      }
    }
  }
  /** Tests all possible ways to invoke copy to copy a file to a file */
  static void testCopyFileToFile(Path dir1, Path dir2, boolean supportsLinks) throws IOException {
    Path source, target, link, entry;

    // -- regular file --

    /** Test: move regular file, target does not exist */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target);
    delete(source);
    delete(target);

    /** Test: copy regular file, target exists */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    try {
      copyAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(target);
    createDirectory(target);
    try {
      copyAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(source);
    delete(target);

    /** Test: copy regular file, target does not exist */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy regular file, target exists */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy regular file, target exists and is empty directory */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy regular file, target exists and is non-empty directory */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    entry = target.resolve("foo");
    createFile(entry);
    try {
      copyAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(entry);
    delete(source);
    delete(target);

    /** Test: copy regular file + attributes */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target, COPY_ATTRIBUTES);
    delete(source);
    delete(target);

    // -- directory --

    /*
     * Test: copy directory, target does not exist
     */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target);
    delete(source);
    delete(target);

    /** Test: copy directory, target exists */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    try {
      copyAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(target);
    createDirectory(target);
    try {
      copyAndVerify(source, target);
      throw new RuntimeException("FileAlreadyExistsException expected");
    } catch (FileAlreadyExistsException x) {
    }
    delete(source);
    delete(target);

    /** Test: copy directory, target does not exist */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy directory, target exists */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createFile(target);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy directory, target exists and is empty directory */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    copyAndVerify(source, target, REPLACE_EXISTING);
    delete(source);
    delete(target);

    /** Test: copy directory, target exists and is non-empty directory */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    createDirectory(target);
    entry = target.resolve("foo");
    createFile(entry);
    try {
      copyAndVerify(source, target, REPLACE_EXISTING);
      throw new RuntimeException("DirectoryNotEmptyException expected");
    } catch (DirectoryNotEmptyException x) {
    }
    delete(entry);
    delete(source);
    delete(target);

    /*
     * Test: copy directory + attributes
     */
    source = createSourceDirectory(dir1);
    target = getTargetFile(dir2);
    copyAndVerify(source, target, COPY_ATTRIBUTES);
    delete(source);
    delete(target);

    // -- symbolic links --

    /** Test: Follow link */
    if (supportsLinks) {
      source = createSourceFile(dir1);
      link = dir1.resolve("link");
      createSymbolicLink(link, source);
      target = getTargetFile(dir2);
      copyAndVerify(link, target);
      delete(link);
      delete(source);
    }

    /** Test: Copy link (to file) */
    if (supportsLinks) {
      source = createSourceFile(dir1);
      link = dir1.resolve("link");
      createSymbolicLink(link, source);
      target = getTargetFile(dir2);
      copyAndVerify(link, target, NOFOLLOW_LINKS);
      delete(link);
      delete(source);
    }

    /** Test: Copy link (to directory) */
    if (supportsLinks) {
      source = dir1.resolve("mydir");
      createDirectory(source);
      link = dir1.resolve("link");
      createSymbolicLink(link, source);
      target = getTargetFile(dir2);
      copyAndVerify(link, target, NOFOLLOW_LINKS);
      delete(link);
      delete(source);
    }

    /** Test: Copy broken link */
    if (supportsLinks) {
      assertTrue(notExists(source));
      link = dir1.resolve("link");
      createSymbolicLink(link, source);
      target = getTargetFile(dir2);
      copyAndVerify(link, target, NOFOLLOW_LINKS);
      delete(link);
    }

    /** Test: Copy link to UNC (Windows only) */
    if (supportsLinks && System.getProperty("os.name").startsWith("Windows")) {
      Path unc = Paths.get("\\\\rialto\\share\\file");
      link = dir1.resolve("link");
      createSymbolicLink(link, unc);
      target = getTargetFile(dir2);
      copyAndVerify(link, target, NOFOLLOW_LINKS);
      delete(link);
    }

    // -- misc. tests --

    /** Test nulls */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    try {
      copy(source, null);
      throw new RuntimeException("NullPointerException expected");
    } catch (NullPointerException x) {
    }
    try {
      copy(source, target, (CopyOption[]) null);
      throw new RuntimeException("NullPointerException expected");
    } catch (NullPointerException x) {
    }
    try {
      CopyOption[] opts = {REPLACE_EXISTING, null};
      copy(source, target, opts);
      throw new RuntimeException("NullPointerException expected");
    } catch (NullPointerException x) {
    }
    delete(source);

    /** Test UOE */
    source = createSourceFile(dir1);
    target = getTargetFile(dir2);
    try {
      copy(source, target, new CopyOption() {});
    } catch (UnsupportedOperationException x) {
    }
    try {
      copy(source, target, REPLACE_EXISTING, new CopyOption() {});
    } catch (UnsupportedOperationException x) {
    }
    delete(source);
  }
  // move source to target with verification
  static void moveAndVerify(Path source, Path target, CopyOption... options) throws IOException {
    // read attributes before file is moved
    BasicFileAttributes basicAttributes = null;
    PosixFileAttributes posixAttributes = null;
    DosFileAttributes dosAttributes = null;
    Map<String, ByteBuffer> namedAttributes = null;

    // get file attributes of source file
    String os = System.getProperty("os.name");
    if (os.startsWith("Windows")) {
      dosAttributes = readAttributes(source, DosFileAttributes.class, NOFOLLOW_LINKS);
      basicAttributes = dosAttributes;
    } else {
      posixAttributes = readAttributes(source, PosixFileAttributes.class, NOFOLLOW_LINKS);
      basicAttributes = posixAttributes;
    }
    if (basicAttributes == null)
      basicAttributes = readAttributes(source, BasicFileAttributes.class, NOFOLLOW_LINKS);

    // hash file contents if regular file
    int hash = (basicAttributes.isRegularFile()) ? computeHash(source) : 0;

    // record link target if symbolic link
    Path linkTarget = null;
    if (basicAttributes.isSymbolicLink()) linkTarget = readSymbolicLink(source);

    // read named attributes if available (and file is not a sym link)
    if (!basicAttributes.isSymbolicLink()
        && getFileStore(source).supportsFileAttributeView("xattr")) {
      namedAttributes = readUserDefinedFileAttributes(source);
    }

    // move file
    Path result = move(source, target, options);
    assertTrue(result == target);

    // verify source does not exist
    assertTrue(notExists(source));

    // verify file contents
    if (basicAttributes.isRegularFile()) {
      if (computeHash(target) != hash)
        throw new RuntimeException("Failed to verify move of regular file");
    }

    // verify link target
    if (basicAttributes.isSymbolicLink()) {
      if (!readSymbolicLink(target).equals(linkTarget))
        throw new RuntimeException("Failed to verify move of symbolic link");
    }

    // verify basic attributes
    checkBasicAttributes(
        basicAttributes, readAttributes(target, BasicFileAttributes.class, NOFOLLOW_LINKS));

    // verify other attributes when same provider
    if (source.getFileSystem().provider() == target.getFileSystem().provider()) {

      // verify POSIX attributes
      if (posixAttributes != null && !basicAttributes.isSymbolicLink() && testPosixAttributes) {
        checkPosixAttributes(
            posixAttributes, readAttributes(target, PosixFileAttributes.class, NOFOLLOW_LINKS));
      }

      // verify DOS attributes
      if (dosAttributes != null && !basicAttributes.isSymbolicLink()) {
        DosFileAttributes attrs = readAttributes(target, DosFileAttributes.class, NOFOLLOW_LINKS);
        checkDosAttributes(dosAttributes, attrs);
      }

      // verify named attributes
      if (namedAttributes != null && getFileStore(target).supportsFileAttributeView("xattr")) {
        checkUserDefinedFileAttributes(namedAttributes, readUserDefinedFileAttributes(target));
      }
    }
  }
Exemple #7
0
 static void usage() {
   System.err.println("usage: java WatchDir [-r] dir");
   System.exit(-1);
 }