forked from jbake-org/jbake
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9ff9fed
commit 76606eb
Showing
4 changed files
with
251 additions
and
84 deletions.
There are no files selected for viewing
This file contains 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 file contains 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 file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package br.com.ingenieux.mojo.jbake; | ||
|
||
/* | ||
* Copyright 2013 ingenieux Labs | ||
* | ||
* 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. | ||
*/ | ||
|
||
import java.io.BufferedReader; | ||
import java.io.InputStreamReader; | ||
import java.nio.file.Paths; | ||
import java.util.concurrent.atomic.AtomicBoolean; | ||
|
||
import org.apache.maven.plugin.MojoExecutionException; | ||
import org.apache.maven.plugins.annotations.Mojo; | ||
|
||
import br.com.ingenieux.mojo.jbake.util.DirWatcher; | ||
|
||
/** | ||
* Runs jbake on a folder while watching for changes | ||
*/ | ||
@Mojo(name = "watch", requiresDirectInvocation = true) | ||
public class WatchMojo extends GenerateMojo { | ||
public void execute() throws MojoExecutionException { | ||
super.execute(); | ||
|
||
getLog().info( | ||
"Now listening for changes on path " + inputDirectory.getPath()); | ||
|
||
initServer(); | ||
|
||
try { | ||
final AtomicBoolean done = new AtomicBoolean(false); | ||
final BufferedReader reader = new BufferedReader( | ||
new InputStreamReader(System.in)); | ||
|
||
(new Thread() { | ||
@Override | ||
public void run() { | ||
try { | ||
getLog().info("Running. Hit <ENTER> to finish"); | ||
reader.readLine(); | ||
} catch (Exception exc) { | ||
} finally { | ||
done.set(true); | ||
} | ||
} | ||
}).start(); | ||
|
||
DirWatcher dirWatcher = new DirWatcher(Paths.get(inputDirectory | ||
.getPath())); | ||
|
||
do { | ||
Boolean result = dirWatcher.processEvents(); | ||
|
||
if (Boolean.FALSE.equals(result)) { | ||
Thread.sleep(1000); | ||
} else if (Boolean.TRUE.equals(result)) { | ||
getLog().info("Refreshing"); | ||
|
||
super.execute(); | ||
} else if (null == result) { | ||
break; | ||
} | ||
} while (!done.get()); | ||
} catch (Exception exc) { | ||
getLog().info("Oops", exc); | ||
|
||
throw new MojoExecutionException("Oops", exc); | ||
} finally { | ||
getLog().info("Finishing"); | ||
|
||
stopServer(); | ||
} | ||
} | ||
|
||
protected void stopServer() { | ||
} | ||
|
||
protected void initServer() throws MojoExecutionException { | ||
} | ||
} |
146 changes: 146 additions & 0 deletions
146
src/main/java/br/com/ingenieux/mojo/jbake/util/DirWatcher.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package br.com.ingenieux.mojo.jbake.util; | ||
|
||
import static java.nio.file.LinkOption.NOFOLLOW_LINKS; | ||
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; | ||
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; | ||
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; | ||
import static java.nio.file.StandardWatchEventKinds.OVERFLOW; | ||
|
||
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.SimpleFileVisitor; | ||
import java.nio.file.WatchEvent; | ||
import java.nio.file.WatchEvent.Kind; | ||
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.concurrent.TimeUnit; | ||
|
||
/** | ||
* Example to watch a directory (or tree) for changes to files. | ||
*/ | ||
|
||
public class DirWatcher { | ||
private final WatchService watcher; | ||
|
||
private final Map<WatchKey, Path> keys; | ||
|
||
@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_CREATE, ENTRY_DELETE, | ||
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; | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Creates a WatchService and registers the given directory | ||
*/ | ||
public DirWatcher(Path dir) throws IOException { | ||
this.watcher = FileSystems.getDefault().newWatchService(); | ||
this.keys = new HashMap<WatchKey, Path>(); | ||
|
||
registerAll(dir); | ||
} | ||
|
||
/** | ||
* Process all events for keys queued to the watcher | ||
*/ | ||
public Boolean processEvents() { | ||
// wait for key to be signalled | ||
WatchKey key; | ||
try { | ||
key = watcher.poll(1L, TimeUnit.SECONDS); | ||
} catch (InterruptedException x) { | ||
return Boolean.FALSE; | ||
} | ||
|
||
if (null == key) | ||
return Boolean.FALSE; | ||
|
||
Path dir = keys.get(key); | ||
if (dir == null) | ||
throw new IllegalStateException("WatchKey not recognized!!"); | ||
|
||
for (WatchEvent<?> event : key.pollEvents()) { | ||
Kind<?> kind = event.kind(); | ||
|
||
// TBD - provide example of how OVERFLOW event is handled | ||
if (kind == OVERFLOW) { | ||
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); | ||
|
||
// if directory is created, and watching recursively, then | ||
// register it and its sub-directories | ||
if (kind == ENTRY_CREATE) { | ||
try { | ||
if (Files.isDirectory(child, NOFOLLOW_LINKS)) { | ||
registerAll(child); | ||
} | ||
} catch (IOException x) { | ||
// ignore to keep sample readbale | ||
} | ||
} | ||
} | ||
|
||
// 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()) { | ||
return null; | ||
} | ||
} | ||
|
||
return Boolean.TRUE; | ||
} | ||
|
||
static void usage() { | ||
System.err.println("usage: java WatchDir [-r] dir"); | ||
System.exit(-1); | ||
} | ||
} |