Created
June 21, 2016 12:39
-
-
Save monkstone/66ec63d2091545c60d1d447ebe703907 to your computer and use it in GitHub Desktop.
Code Listener in java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.monkstone; | |
import java.nio.file.WatchEvent; | |
interface CodeListener { | |
public void code_event(WatchEvent<?> event); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.nio.file.WatchEvent; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
/** | |
* | |
* @author tux | |
*/ | |
public class CodeListenerTest { | |
WatchSketchDir watcher; | |
public CodeListenerTest() { | |
try { | |
watcher = WatchSketchDir.watch("/home/tux/test"); | |
watcher.addListener(new CodeListenerImpl()); | |
} catch (IOException ex) { | |
Logger.getLogger(CodeListenerTest.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
public class CodeListenerImpl implements CodeListener { | |
@Override | |
public void code_event(WatchEvent<?> event) { | |
if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) { | |
System.out.println("bingo"); | |
} | |
} | |
} | |
public static void main(String[] args) { | |
CodeListenerTest test = new CodeListenerTest(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This class allows JRubyArt to watch for changes to sketch files | |
* specifically those with a 'rb' or 'glsl' extension requires user to supply | |
* a path String and code listener to constructor. The code listener should | |
* accept a filesystem WatchEvent | |
*/ | |
/* | |
* This code is a modified version of WatchDir.java | |
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions | |
* are met: | |
* | |
* - Redistributions of source code must retain the above copyright | |
* notice, this list of conditions and the following disclaimer. | |
* | |
* - Redistributions in binary form must reproduce the above copyright | |
* notice, this list of conditions and the following disclaimer in the | |
* documentation and/or other materials provided with the distribution. | |
* | |
* - Neither the name of Oracle nor the names of its | |
* contributors may be used to endorse or promote products derived | |
* from this software without specific prior written permission. | |
* | |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
*/ | |
package org.monkstone; | |
import java.io.IOException; | |
import java.nio.file.FileSystems; | |
import java.nio.file.FileVisitResult; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.Paths; | |
import java.nio.file.SimpleFileVisitor; | |
import static 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; | |
/** | |
* Example to watch a directory (or tree) for changes to files. | |
*/ | |
public class WatchSketchDir { | |
private final WatchService watcher; | |
private final Map<WatchKey, Path> keys; | |
private boolean trace = false; | |
static WatchSketchDir sketchWatcher; | |
@SuppressWarnings("unchecked") | |
static <T> WatchEvent<T> cast(WatchEvent<?> event) { | |
return (WatchEvent<T>) event; | |
} | |
/** | |
* Register the given directory with the WatchService | |
*/ | |
private void register(Path dir) throws IOException { | |
WatchKey key = dir.register(watcher, ENTRY_MODIFY); | |
if (trace) { | |
Path prev = keys.get(key); | |
if (prev == null) { | |
System.out.format("register: %s\n", dir); | |
} else if (!dir.equals(prev)) { | |
System.out.format("update: %s -> %s\n", prev, dir); | |
} | |
} | |
keys.put(key, dir); | |
} | |
/** | |
* Register the given directory, and all its sub-directories, with the | |
* WatchService. | |
*/ | |
private void registerAll(final Path start) throws IOException { | |
// register directory and sub-directories | |
Files.walkFileTree(start, new SimpleFileVisitor<Path>() { | |
@Override | |
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) | |
throws IOException { | |
register(dir); | |
return FileVisitResult.CONTINUE; | |
} | |
}); | |
} | |
static final WatchSketchDir watch(String dir) throws IOException{ | |
sketchWatcher = new WatchSketchDir(dir); | |
return sketchWatcher; | |
} | |
/** | |
* Creates a WatchService and registers the given directory | |
* @param dir String | |
* @param obj CodeListener | |
* @throws IOException | |
*/ | |
private WatchSketchDir(String dir) throws IOException { | |
this(Paths.get(dir)); | |
} | |
/** | |
* Creates a WatchService and registers the given directory | |
* | |
* @param dir Path | |
* @param obj CodeListener | |
* @throws java.io.IOException | |
*/ | |
private WatchSketchDir(Path dir) throws IOException { | |
this.watcher = FileSystems.getDefault().newWatchService(); | |
this.keys = new HashMap<>(); | |
System.out.format("Scanning Codebase\n", dir); | |
registerAll(dir); | |
System.out.format("Watching %s\n", dir); | |
// enable trace after initial registration | |
this.trace = true; | |
} | |
/** | |
* Process all events for keys queued to the watcher | |
*/ | |
void addListener(CodeListener obj) { | |
for (;;) { | |
// wait for key to be signalled | |
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; | |
} | |
key.pollEvents().stream().forEach((WatchEvent<?> event) -> { | |
WatchEvent.Kind kind = event.kind(); | |
// TBD - provide example of how OVERFLOW event is handled | |
if (!(kind == OVERFLOW)) { | |
// 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); | |
if (child.toFile().getAbsolutePath().endsWith(".rb") | |
|| child.toFile().getAbsolutePath().endsWith(".glsl")) { | |
obj.code_event(event); | |
} | |
// if directory is created, and watching recursively, then | |
// register it and its sub-directories | |
} | |
}); | |
// 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; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment