Search in sources :

Example 1 with Kind

use of java.nio.file.WatchEvent.Kind in project jetty.project by eclipse.

the class PathWatcher method run.

/** 
     * Forever loop.
     * 
     * Wait for the WatchService to report some filesystem events for the
     * watched paths.
     * 
     * When an event for a path first occurs, it is subjected to a quiet time.
     * Subsequent events that arrive for the same path during this quiet time are
     * accumulated and the timer reset. Only when the quiet time has expired are
     * the accumulated events sent. MODIFY events are handled slightly differently -
     * multiple MODIFY events arriving within a quiet time are coalesced into a
     * single MODIFY event. Both the accumulation of events and coalescing of MODIFY
     * events reduce the number and frequency of event reporting for "noisy" files (ie
     * those that are undergoing rapid change).
     * 
     * @see java.lang.Runnable#run()
     */
@Override
public void run() {
    List<PathWatchEvent> notifiableEvents = new ArrayList<PathWatchEvent>();
    // Start the java.nio watching
    if (LOG.isDebugEnabled()) {
        LOG.debug("Starting java.nio file watching with {}", watchService);
    }
    while (watchService != null && thread == Thread.currentThread()) {
        WatchKey key = null;
        try {
            //If no pending events, wait forever for new events
            if (pendingEvents.isEmpty()) {
                if (NOISY_LOG.isDebugEnabled())
                    NOISY_LOG.debug("Waiting for take()");
                key = watchService.take();
            } else {
                //only wait as long as the quiet time for any new events
                if (NOISY_LOG.isDebugEnabled())
                    NOISY_LOG.debug("Waiting for poll({}, {})", updateQuietTimeDuration, updateQuietTimeUnit);
                key = watchService.poll(updateQuietTimeDuration, updateQuietTimeUnit);
                //If no new events its safe to process the pendings
                if (key == null) {
                    long now = System.currentTimeMillis();
                    // no new event encountered.
                    for (Path path : new HashSet<Path>(pendingEvents.keySet())) {
                        PathPendingEvents pending = pendingEvents.get(path);
                        if (pending.isQuiet(now, updateQuietTimeDuration, updateQuietTimeUnit)) {
                            //so generate the events that were pent up
                            for (PathWatchEvent p : pending.getEvents()) {
                                notifiableEvents.add(p);
                            }
                            // remove from pending list
                            pendingEvents.remove(path);
                        }
                    }
                }
            }
        } catch (ClosedWatchServiceException e) {
            // Normal shutdown of watcher
            return;
        } catch (InterruptedException e) {
            if (isRunning()) {
                LOG.warn(e);
            } else {
                LOG.ignore(e);
            }
            return;
        }
        //If there was some new events to process
        if (key != null) {
            Config config = keys.get(key);
            if (config == null) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("WatchKey not recognized: {}", key);
                }
                continue;
            }
            for (WatchEvent<?> event : key.pollEvents()) {
                @SuppressWarnings("unchecked") WatchEvent.Kind<Path> kind = (Kind<Path>) event.kind();
                WatchEvent<Path> ev = cast(event);
                Path name = ev.context();
                Path child = config.dir.resolve(name);
                if (kind == ENTRY_CREATE) {
                    // recursively
                    if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS)) {
                        try {
                            prepareConfig(config.asSubConfig(child));
                        } catch (IOException e) {
                            LOG.warn(e);
                        }
                    } else if (config.matches(child)) {
                        addToPendingList(child, new PathWatchEvent(child, ev));
                    }
                } else if (config.matches(child)) {
                    addToPendingList(child, new PathWatchEvent(child, ev));
                }
            }
        }
        //Send any notifications generated this pass
        notifyOnPathWatchEvents(notifiableEvents);
        notifiableEvents.clear();
        if (key != null && !key.reset()) {
            keys.remove(key);
            if (keys.isEmpty()) {
                // all done, no longer monitoring anything
                return;
            }
        }
    }
}
Also used : Path(java.nio.file.Path) ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) WatchKey(java.nio.file.WatchKey) ClosedWatchServiceException(java.nio.file.ClosedWatchServiceException) IOException(java.io.IOException) Kind(java.nio.file.WatchEvent.Kind) WatchEvent(java.nio.file.WatchEvent) HashSet(java.util.HashSet)

Aggregations

IOException (java.io.IOException)1 ClosedWatchServiceException (java.nio.file.ClosedWatchServiceException)1 Path (java.nio.file.Path)1 WatchEvent (java.nio.file.WatchEvent)1 Kind (java.nio.file.WatchEvent.Kind)1 WatchKey (java.nio.file.WatchKey)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1