private void scanFilesForChanges ( ) { MessageDigest digest ; try { digest = MessageDigest . getInstance ( "SHA-256" ) ; } catch ( NoSuchAlgorithmException e ) { // This should never happen, all JVM implementations must support SHA-256 according to Oracle docs. throw new RuntimeException ( e ) ; } ImmutableSet . Builder < File > modifiedFilesBuilder = ImmutableSet . builder ( ) ; Map < File , FileMetadata > metadataCache = Maps . newHashMap ( metadataCacheRef . get ( ) ) ; for ( File file : watchedFiles ) { try { FileMetadata meta = new FileMetadata ( file , digest ) ; if ( ! meta . equals ( metadataCache . get ( file ) ) ) { metadataCache . put ( file , meta ) ; modifiedFilesBuilder . add ( file ) ; } } catch ( IOException | SecurityException e ) { // I/O error, file not found, or access to file not allowed log . warn ( "Error trying to stat or read file %s: %s: %s" , file . toString ( ) , e . getClass ( ) . getName ( ) , e . getMessage ( ) ) ; metadataCache . remove ( file ) ; } } // We need to swallow exceptions from the user callback, otherwise an uncaught exception could kill the // poller thread. Set < File > modifiedFiles = modifiedFilesBuilder . build ( ) ; boolean callbackCalled = false ; boolean callbackSucceeded = false ; try { if ( ! modifiedFiles . isEmpty ( ) ) { callbackCalled = true ; callback . accept ( modifiedFiles ) ; callbackSucceeded = true ; } // Only update the metadata cache if all callbacks succeeded. metadataCacheRef . set ( ImmutableMap . copyOf ( metadataCache ) ) ; } catch ( Exception e ) { log . warn ( "Error from user callback: %s: %s" , e . getClass ( ) . toString ( ) , e . getMessage ( ) ) ; } // Update stats if ( ! modifiedFiles . isEmpty ( ) ) { stats . fileChangesDetected . getAndAdd ( modifiedFiles . size ( ) ) ; } if ( callbackCalled ) { stats . callbacksInvoked . getAndIncrement ( ) ; if ( callbackSucceeded ) { stats . callbacksSucceeded . getAndIncrement ( ) ; } else { stats . callbacksFailed . getAndIncrement ( ) ; } } stats . pollCycles . getAndIncrement ( ) ; }
Scans the watched files for changes . If any changes are detected calls the user callback with the set of all files that were modified since the last successful update attempt . Note that when a watched file is deleted it will not be considered modified .