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.listeners;
019:
020: import java.io.File;
021: import java.util.ArrayList;
022: import java.util.Collection;
023:
024: import org.apache.commons.jci.monitor.FilesystemAlterationListener;
025: import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
026: import org.apache.commons.logging.Log;
027: import org.apache.commons.logging.LogFactory;
028:
029: /**
030: * AbstractFilesystemAlterationListener provides some convenience methods helping to
031: * implement a FilesystemAlterationListener.
032: * @author tcurdt
033: */
034: public abstract class AbstractFilesystemAlterationListener implements
035: FilesystemAlterationListener {
036:
037: private final Log log = LogFactory
038: .getLog(AbstractFilesystemAlterationListener.class);
039:
040: private final Collection createdFiles = new ArrayList();
041: private final Collection changedFiles = new ArrayList();
042: private final Collection deletedFiles = new ArrayList();
043: private final Collection createdDirectories = new ArrayList();
044: private final Collection changedDirectories = new ArrayList();
045: private final Collection deletedDirectories = new ArrayList();
046:
047: private final static class Signal {
048: public boolean triggered;
049: }
050:
051: private final Signal eventSignal = new Signal();
052: private final Signal checkSignal = new Signal();
053:
054: protected FilesystemAlterationObserver observer;
055:
056: public void onDirectoryCreate(final File pDir) {
057: createdDirectories.add(pDir);
058: }
059:
060: public void onDirectoryChange(final File pDir) {
061: changedDirectories.add(pDir);
062: }
063:
064: public void onDirectoryDelete(final File pDir) {
065: deletedDirectories.add(pDir);
066: }
067:
068: public void onFileCreate(final File pFile) {
069: createdFiles.add(pFile);
070: }
071:
072: public void onFileChange(final File pFile) {
073: changedFiles.add(pFile);
074: }
075:
076: public void onFileDelete(final File pFile) {
077: deletedFiles.add(pFile);
078: }
079:
080: public Collection getChangedDirectories() {
081: return changedDirectories;
082: }
083:
084: public Collection getChangedFiles() {
085: return changedFiles;
086: }
087:
088: public Collection getCreatedDirectories() {
089: return createdDirectories;
090: }
091:
092: public Collection getCreatedFiles() {
093: return createdFiles;
094: }
095:
096: public Collection getDeletedDirectories() {
097: return deletedDirectories;
098: }
099:
100: public Collection getDeletedFiles() {
101: return deletedFiles;
102: }
103:
104: protected void signals() {
105: if (createdFiles.size() > 0 || createdDirectories.size() > 0
106: || changedFiles.size() > 0
107: || changedDirectories.size() > 0
108: || deletedFiles.size() > 0
109: || deletedDirectories.size() > 0) {
110:
111: log.debug("event signal");
112:
113: synchronized (eventSignal) {
114: eventSignal.triggered = true;
115: eventSignal.notifyAll();
116: }
117: }
118:
119: log.debug("check signal");
120:
121: synchronized (checkSignal) {
122: checkSignal.triggered = true;
123: checkSignal.notifyAll();
124: }
125: }
126:
127: public void onStart(final FilesystemAlterationObserver pObserver) {
128: observer = pObserver;
129:
130: createdFiles.clear();
131: changedFiles.clear();
132: deletedFiles.clear();
133: createdDirectories.clear();
134: changedDirectories.clear();
135: deletedDirectories.clear();
136: }
137:
138: public void onStop(final FilesystemAlterationObserver pObserver) {
139: signals();
140: observer = null;
141: }
142:
143: public void waitForEvent() throws Exception {
144: synchronized (eventSignal) {
145: eventSignal.triggered = false;
146: }
147: log.debug("waiting for change");
148: if (!waitForSignal(eventSignal, 10)) {
149: throw new Exception("timeout");
150: }
151: }
152:
153: /**
154: * we don't reset the signal so if there was a check it is
155: * already true and exit immediatly otherwise it will behave just
156: * like waitForCheck()
157: *
158: * @throws Exception in case of a timeout
159: */
160: public void waitForFirstCheck() throws Exception {
161: log.debug("waiting for first check");
162: if (!waitForSignal(checkSignal, 10)) {
163: throw new Exception("timeout");
164: }
165: }
166:
167: /**
168: * wait for the next filesystem check to happen
169: *
170: * @throws Exception in case of a timeout
171: */
172: public void waitForCheck() throws Exception {
173: synchronized (checkSignal) {
174: checkSignal.triggered = false;
175: }
176: log.debug("waiting for check");
177: if (!waitForSignal(checkSignal, 10)) {
178: throw new Exception("timeout");
179: }
180: }
181:
182: private boolean waitForSignal(final Signal pSignal,
183: final int pSecondsTimeout) {
184: int i = 0;
185: while (true) {
186: synchronized (pSignal) {
187: if (!pSignal.triggered) {
188: try {
189: pSignal.wait(1000);
190: } catch (InterruptedException e) {
191: }
192:
193: if (++i > pSecondsTimeout) {
194: log.error("timeout after " + pSecondsTimeout
195: + "s");
196: return false;
197: }
198:
199: } else {
200: pSignal.triggered = false;
201: break;
202: }
203: }
204: }
205: return true;
206: }
207:
208: }
|