001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.commons.jci.monitor;
019:
020: import java.io.File;
021: import java.util.Collections;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.Map;
025:
026: import org.apache.commons.logging.Log;
027: import org.apache.commons.logging.LogFactory;
028:
029: /**
030: * It's a runnable that spawns of a monitoring thread triggering the
031: * the observers and managing the their listeners.
032: *
033: * @author tcurdt
034: */
035: public final class FilesystemAlterationMonitor implements Runnable {
036:
037: private final Log log = LogFactory
038: .getLog(FilesystemAlterationMonitor.class);
039:
040: private final Object observersLock = new Object();
041: private Map observers = Collections.unmodifiableMap(new HashMap());
042: private long delay = 3000;
043: private Thread thread;
044:
045: private volatile boolean running = true;
046:
047: public FilesystemAlterationMonitor() {
048: }
049:
050: public void start() {
051: thread = new Thread(this );
052: thread.start();
053: }
054:
055: public void stop() {
056: running = false;
057:
058: try {
059: thread.join(delay);
060: } catch (InterruptedException e) {
061: }
062: }
063:
064: public void setInterval(final long pDelay) {
065: delay = pDelay;
066: }
067:
068: public void addListener(final File pRoot,
069: final FilesystemAlterationListener pListener) {
070:
071: FilesystemAlterationObserver observer;
072:
073: synchronized (observersLock) {
074: observer = (FilesystemAlterationObserver) observers
075: .get(pRoot);
076:
077: if (observer == null) {
078: final Map newObservers = new HashMap(observers);
079: observer = new FilesystemAlterationObserverImpl(pRoot);
080: newObservers.put(pRoot, observer);
081: observers = Collections.unmodifiableMap(newObservers);
082: }
083: }
084:
085: observer.addListener(pListener);
086: }
087:
088: public void removeListener(
089: final FilesystemAlterationListener pListener) {
090: synchronized (observersLock) {
091: for (Iterator it = observers.values().iterator(); it
092: .hasNext();) {
093: final FilesystemAlterationObserver observer = (FilesystemAlterationObserver) it
094: .next();
095: observer.removeListener(pListener);
096: // FIXME: remove observer if there are no listeners?
097: }
098: }
099: }
100:
101: public FilesystemAlterationListener[] getListenersFor(
102: final File pRoot) {
103: final FilesystemAlterationObserver observer = (FilesystemAlterationObserver) observers
104: .get(pRoot);
105:
106: if (observer == null) {
107: return new FilesystemAlterationListener[0];
108: }
109:
110: return observer.getListeners();
111: }
112:
113: public void run() {
114: log.debug("fam running");
115:
116: while (true) {
117: if (!running) {
118: break;
119: }
120:
121: final Map currentObservers = observers;
122:
123: for (Iterator it = currentObservers.values().iterator(); it
124: .hasNext();) {
125: final FilesystemAlterationObserver observer = (FilesystemAlterationObserver) it
126: .next();
127: observer.checkAndNotify();
128: }
129:
130: try {
131: Thread.sleep(delay);
132: } catch (final InterruptedException e) {
133: }
134: }
135:
136: log.debug("fam exiting");
137: }
138:
139: }
|