001: /*--
002:
003: Copyright (C) 2000-2003 Anthony Eden.
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: 1. Redistributions of source code must retain the above copyright
011: notice, this list of conditions, and the following disclaimer.
012:
013: 2. Redistributions in binary form must reproduce the above copyright
014: notice, this list of conditions, and the disclaimer that follows
015: these conditions in the documentation and/or other materials
016: provided with the distribution.
017:
018: 3. The name "EdenLib" must not be used to endorse or promote products
019: derived from this software without prior written permission. For
020: written permission, please contact me@anthonyeden.com.
021:
022: 4. Products derived from this software may not be called "EdenLib", nor
023: may "EdenLib" appear in their name, without prior written permission
024: from Anthony Eden (me@anthonyeden.com).
025:
026: In addition, I request (but do not require) that you include in the
027: end-user documentation provided with the redistribution and/or in the
028: software itself an acknowledgement equivalent to the following:
029: "This product includes software developed by
030: Anthony Eden (http://www.anthonyeden.com/)."
031:
032: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
033: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
034: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
035: DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
036: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
037: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
038: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
039: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
040: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
041: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
042: POSSIBILITY OF SUCH DAMAGE.
043: For more information on EdenLib, please see <http://edenlib.sf.net/>.
044:
045: */
046:
047: package com.anthonyeden.lib.resource;
048:
049: import java.io.File;
050: import java.io.FileInputStream;
051:
052: import org.apache.commons.logging.Log;
053: import org.apache.commons.logging.LogFactory;
054:
055: import com.anthonyeden.lib.util.IOUtilities;
056:
057: /** Monitors the given File for changes.
058:
059: @author Anthony Eden
060: */
061:
062: public class ResourceFileMonitor implements Runnable, ResourceMonitor {
063:
064: private static final Log log = LogFactory
065: .getLog(ResourceFileMonitor.class);
066:
067: private File file;
068: private int delay;
069: private long lastModified;
070: private ResourceRecipient handler;
071:
072: private Thread thread;
073: private boolean running = false;
074:
075: /** Construct a ResourceFileMonitor for the given file.
076:
077: @param file The file
078: @param delay The delay
079: @param handler The handler
080: ?*/
081:
082: public ResourceFileMonitor(File file, int delay,
083: ResourceRecipient handler) {
084: this .file = file;
085: this .delay = delay;
086: this .handler = handler;
087: }
088:
089: /** Start the monitoring thread. If the thread is already running then
090: this method will not attempt to start a new thread.
091: */
092:
093: public void startMonitor() {
094: if (!running) {
095: log.debug("Starting FileMonitor");
096:
097: running = true;
098: thread = new Thread(this );
099: thread.setDaemon(true);
100: thread.start();
101: }
102: }
103:
104: /** Stop the monitoring thread. If the monitoring thread is not running
105: then this method will do nothing.
106: */
107:
108: public void stopMonitor() {
109: if (thread != null && running) {
110: log.debug("Stopping FileMonitor");
111:
112: running = false;
113: thread.interrupt();
114: }
115: }
116:
117: /** The thread's run method. This method should not be executed directly
118: nor should a thread be manually created, rather the <code>startMonitor()</code>
119: and <code>stopMonitor()</code> methods should be used to start and stop
120: the monitor.
121: */
122:
123: public void run() {
124: log.debug("FileMonitor start.");
125: lastModified = file.lastModified();
126: while (running) {
127: long currentLastModified = file.lastModified();
128: if (currentLastModified != lastModified) {
129: log.info("Reloading " + file);
130:
131: FileInputStream in = null;
132: try {
133: in = new FileInputStream(file);
134: handler.load(in);
135: } catch (Exception e) {
136: e.printStackTrace();
137: } finally {
138: IOUtilities.close(in);
139: }
140:
141: lastModified = currentLastModified;
142: }
143:
144: try {
145: Thread.sleep(delay);
146: } catch (InterruptedException e) {
147: // do nothing
148: }
149: }
150: log.debug("FileMonitor stopped.");
151: }
152:
153: }
|