// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.collide.server.filetree;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class FileTreeExperiment {
public static void main(String[] args) throws IOException, InterruptedException {
final Map<WatchKey, Path> map = new HashMap<WatchKey, Path>();
final Path rootPath = new File("").toPath();
final WatchService watcher = FileSystems.getDefault().newWatchService();
final Stack<Path> parents = new Stack<Path>();
final FileVisitor<Path> visitor = new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs)
throws IOException {
if (parents.isEmpty()) {
// root
System.out.println("scanning from: " + path.toAbsolutePath() + '/');
} else {
System.out.println("add: /" + path + '/');
}
parents.push(path);
WatchKey key = path.register(
watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.OVERFLOW);
map.put(key, path);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
System.out.println("add: /" + path);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
System.out.println("visitFileFailed: " + file);
throw exc;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
if (exc != null) {
System.out.println("postVisitDirectory failed: " + dir);
throw exc;
}
parents.pop();
return FileVisitResult.CONTINUE;
}
};
Files.walkFileTree(rootPath, visitor);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
Files.createDirectory(rootPath.resolve("tmp"));
Files.createDirectory(rootPath.resolve("tmp/dir"));
Files.createFile(rootPath.resolve("tmp/file"));
Files.createFile(rootPath.resolve("tmp/dir/file2"));
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
for (;;) {
// retrieve key
WatchKey key = watcher.take();
Path parent = map.get(key);
System.out.println("-----");
// process events
for (WatchEvent<?> event : key.pollEvents()) {
if (event.kind().type() == Path.class) {
Path path = (Path) event.context();
Path resolved = parent.resolve(path);
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
System.out.println("cre: /" + resolved);
parents.push(parent);
Files.walkFileTree(resolved, visitor);
parents.pop();
} else if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
System.out.println("mod: /" + resolved);
} else if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
System.out.println("del: /" + resolved);
} else {
assert false : "Unknown event type: " + event.kind().name();
}
} else {
assert event.kind() == StandardWatchEventKinds.OVERFLOW;
System.out.print(event.kind().name() + ": ");
System.out.println(event.count());
}
}
// reset the key
boolean valid = key.reset();
if (!valid) {
// object no longer registered
map.remove(key);
}
}
}
}