+package org.simantics.fileimport.dropins;\r
+\r
+import static java.nio.file.StandardWatchEventKinds.OVERFLOW;\r
+import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;\r
+import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;\r
+import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;\r
+\r
+import java.io.IOException;\r
+import java.nio.file.FileSystem;\r
+import java.nio.file.FileVisitResult;\r
+import java.nio.file.Files;\r
+import java.nio.file.Path;\r
+import java.nio.file.SimpleFileVisitor;\r
+import java.nio.file.WatchEvent;\r
+import java.nio.file.WatchEvent.Kind;\r
+import java.nio.file.attribute.BasicFileAttributes;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.Optional;\r
+import java.util.concurrent.atomic.AtomicBoolean;\r
+import java.nio.file.WatchKey;\r
+import java.nio.file.WatchService;\r
+\r
+import org.simantics.fileimport.Activator;\r
+import org.simantics.fileimport.FileImportService;\r
+\r
+public class FileImportDropins {\r
+ \r
+ private static Thread watcherThread = null;\r
+ private static DropinsFolderWatcher watcher = null;\r
+\r
+ public static void watchDropinsFolder() {\r
+ if (watcher == null && watcherThread == null) {\r
+ try {\r
+ watcher = new DropinsFolderWatcher(Activator.getDropinsFolder());\r
+ watcherThread = new Thread(watcher, "Simantics Dropins Folder watcher thread");\r
+ watcherThread.setDaemon(true);\r
+ watcherThread.start();\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+ \r
+ public static void unwatchDropinsFolder() {\r
+ watcher.stop();\r
+ try {\r
+ watcherThread.join(500);\r
+ if (watcherThread.isAlive())\r
+ watcherThread.interrupt();\r
+ } catch (InterruptedException e) {\r
+ e.printStackTrace();\r
+ }\r
+ watcherThread = null;\r
+ watcher = null;\r
+ }\r
+ \r
+ private static class DropinsFolderWatcher implements Runnable {\r
+\r
+ private final Path dropinsFolder;\r
+ private final WatchService ws;\r
+ private final AtomicBoolean stopped = new AtomicBoolean(true);\r
+ \r
+ private final Map<WatchKey, Path> keys = new HashMap<>();\r
+ \r
+ public DropinsFolderWatcher(Path dropinsFolder) throws IOException {\r
+ this.dropinsFolder = dropinsFolder;\r
+ FileSystem fs = dropinsFolder.getFileSystem();\r
+ this.ws = fs.newWatchService();\r
+ registerAll(this.dropinsFolder);\r
+ }\r
+ \r
+ @Override\r
+ public void run() {\r
+ stopped.set(false);\r
+\r
+ while (!stopped.get()) {\r
+ try {\r
+ WatchKey key = ws.take();\r
+ for (WatchEvent<?> watchEvent : key.pollEvents()) {\r
+ if (OVERFLOW == watchEvent.kind())\r
+ continue; // loop\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ WatchEvent<Path> pathEvent = (WatchEvent<Path>) watchEvent;\r
+ Kind<Path> kind = pathEvent.kind();\r
+ \r
+ Path parent = keys.get(key);\r
+ Path newPath = parent.resolve(pathEvent.context());\r
+ if (FileImportService.DB_FILE.equals(newPath.getFileName().toString()))\r
+ continue;\r
+ if (ENTRY_CREATE == kind) {\r
+ System.out.println("New path created: " + newPath);\r
+ FileImportService.performFileImport(newPath, Optional.empty());\r
+ register(newPath);\r
+ } else if (ENTRY_MODIFY == kind) {\r
+ System.out.println("New path modified: " + newPath);\r
+ } else if (ENTRY_DELETE == kind) {\r
+ System.out.println("New path deleted: " + newPath);\r
+ FileImportService.removeResourceForFile(newPath.toAbsolutePath(), Optional.empty());\r
+ }\r
+ }\r
+ if (!key.reset()) {\r
+ keys.remove(key);\r
+// break; // loop\r
+ }\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ } catch (InterruptedException e) {\r
+ if (!stopped.get())\r
+ e.printStackTrace();\r
+ } catch (Throwable t) {\r
+ t.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+ \r
+ public void stop() {\r
+ stopped.set(true);\r
+ }\r
+ \r
+ private void registerAll(Path path) throws IOException {\r
+ Files.walkFileTree(path, new SimpleFileVisitor<Path>() {\r
+ \r
+ @Override\r
+ public FileVisitResult preVisitDirectory(Path file, BasicFileAttributes attrs) throws IOException {\r
+ register(file);\r
+ return FileVisitResult.CONTINUE;\r
+ }\r
+ });\r
+ }\r
+\r
+ private void register(Path path) throws IOException {\r
+ if (Files.isDirectory(path)) {\r
+ WatchKey key = path.toAbsolutePath().register(ws, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);\r
+ keys.put(key, path);\r
+ }\r
+ }\r
+ }\r
+}\r