'use strict'; /*global setTimeout, exports, require*/ var File = java.io.File; /************************************************************************ ## The watcher Module This module exposes functions for watching for changes to files or directories. ### watcher.watchFile() function Watches for changes to the given file or directory and calls the function provided when the file changes. #### Parameters * File - the file to watch (can be a file or directory) * Callback - The callback to invoke when the file has changed. The callback takes the changed file as a parameter. #### Example ```javascript var watcher = require('watcher'); watcher.watchFile( 'test.txt', function( file ) { console.log( file + ' has changed'); }); ``` ***/ var filesWatched = {}; var dirsWatched = {}; exports.watchFile = function( file, callback ) { if ( typeof file == 'string' ) { file = new File(file); } filesWatched[file.canonicalPath] = { callback: callback, lastModified: file.lastModified() }; }; /************************************************************************ ### watcher.watchDir() function Watches for changes to the given directory and calls the function provided when the directory changes. It works by calling watchFile/watchDir for each file/subdirectory. #### Parameters * Dir - the file to watch (can be a file or directory) * Callback - The callback to invoke when the directory has changed. The callback takes the changed file as a parameter. For each change inside the directory the callback will also be called. #### Example ```javascript var watcher = require('watcher'); watcher.watchDir( 'players/_ial', function( dir ) { console.log( dir + ' has changed'); }); ``` ***/ exports.watchDir = function( dir, callback ) { if ( typeof dir == 'string' ) { dir = new File(dir); } dirsWatched[dir.canonicalPath] = { callback: callback, lastModified: dir.lastModified() }; var files = dir.listFiles(),file; if ( !files ) { return; } for ( var i = 0; i < files.length; i++ ) { file = files[i]; if (file.isDirectory( )) { exports.watchDir(file,callback); }else{ exports.watchFile(file,callback); } } }; /************************************************************************ ### watcher.unwatchFile() function Removes a file from the watch list. #### Example ```javascript var watcher = require('watcher'); watcher.unwatchFile('test.txt'); ``` ***/ exports.unwatchFile = function( file, callback ) { if ( typeof file == 'string' ) { file = new File(file); } delete filesWatched[file.canonicalPath]; }; /************************************************************************ ### watcher.unwatchDir() function Removes a directory from the watch list and all files inside the directory are also "unwatched" #### Example ```javascript var watcher = require('watcher'); watcher.unwatchDir ('players/_ial'); ``` Would cause also ```javascript watcher.unwatchFile (file); ``` for each file inside directory (and unwatchDir for each directory inside it) ***/ exports.unwatchDir = function( dir, callback ) { if ( typeof dir == 'string' ) { dir = new File(dir); } delete dirsWatched[dir.canonicalPath]; var files = dir.listFiles(),file; if ( !files ) { return; } for ( var i = 0; i < files.length; i++ ) { file = files[i]; if (file.isDirectory( )) { exports.unwatchDir(file,callback); }else{ exports.unwatchFile(file,callback); } } }; function fileWatcher(calledCallbacks) { for (var file in filesWatched) { var fileObject = new File(file); var lm = fileObject.lastModified(); if ( lm != filesWatched[file].lastModified ) { filesWatched[file].lastModified = lm; filesWatched[file].callback(fileObject); if (!fileObject.exists()) { exports.unwatchFile(file,filesWatched[file].callback); } } } }; //monitors directories for time change //when a change is detected watchFiles are invoked for each of the files in directory //and callback is called function dirWatcher(calledCallbacks) { for (var dir in dirsWatched) { var dirObject = new File(dir); var lm = dirObject.lastModified(); var dw = dirsWatched[dir]; if ( lm != dirsWatched[dir].lastModified ) { dirsWatched[dir].lastModified = lm; dirsWatched[dir].callback(dirObject); exports.unwatchDir(dir, dw.callback); //causes all files to be rewatched if (dirObject.exists()) { exports.watchDir(dir, dw.callback); } } } }; //guarantees that a callback is only called once for each change function monitorDirAndFiles() { fileWatcher (); dirWatcher (); setTimeout( monitorDirAndFiles, 3000 ); }; setTimeout( monitorDirAndFiles, 3000 );