001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.vfs;
031:
032: import com.caucho.util.Alarm;
033:
034: import java.util.ArrayList;
035: import java.util.logging.Logger;
036:
037: /**
038: * Contains a set of dependencies.
039: */
040: public class BasicDependencyContainer implements Dependency {
041: private static Logger _log;
042:
043: private ArrayList<Dependency> _dependencyList = new ArrayList<Dependency>();
044:
045: // Marks if the last check returned modified
046: private boolean _isModified;
047:
048: // The interval for checking for a dependency.
049: private long _checkInterval = 2000L;
050:
051: // When the dependency check last occurred
052: private long _lastCheckTime = 0;
053:
054: private volatile boolean _isChecking;
055:
056: /**
057: * Adds a dependency.
058: */
059: public BasicDependencyContainer add(Dependency dependency) {
060: if (dependency == this )
061: throw new IllegalArgumentException(
062: "Can't add self as a dependency.");
063:
064: if (!_dependencyList.contains(dependency))
065: _dependencyList.add(dependency);
066:
067: // server/1d0w
068: // XXX: _lastCheckTime = 0;
069:
070: return this ;
071: }
072:
073: /**
074: * Removes a dependency.
075: */
076: public BasicDependencyContainer remove(Dependency dependency) {
077: if (dependency == this )
078: throw new IllegalArgumentException(
079: "Can't remove self as a dependency.");
080:
081: _dependencyList.remove(dependency);
082:
083: return this ;
084: }
085:
086: /**
087: * Sets the check modification check interval in milliseconds.
088: * Negative values mean never check. 0 means always check.
089: *
090: * @param checkInterval how often the dependency should be checked
091: */
092: public void setCheckInterval(long checkInterval) {
093: if (checkInterval < 0 || checkInterval > Long.MAX_VALUE / 2)
094: _checkInterval = Long.MAX_VALUE / 2;
095: else
096: _checkInterval = checkInterval;
097:
098: _lastCheckTime = 0;
099: }
100:
101: /**
102: * Gets the check modification check interval.
103: * Negative values mean never check. 0 means always check.
104: */
105: public long getCheckInterval() {
106: return _checkInterval;
107: }
108:
109: /**
110: * Sets the modified.
111: */
112: public void setModified(boolean isModified) {
113: _isModified = isModified;
114: _lastCheckTime = 0;
115: }
116:
117: /**
118: * Resets the check interval.
119: */
120: public void resetDependencyCheckInterval() {
121: _lastCheckTime = 0;
122: }
123:
124: /**
125: * Clears the modified flag and sets the last check time to now.
126: */
127: public void clearModified() {
128: _isModified = false;
129: _lastCheckTime = Alarm.getCurrentTime();
130: }
131:
132: /**
133: * Returns true if the underlying dependencies have changed.
134: */
135: public boolean isModified() {
136: synchronized (this ) {
137: if (_isChecking || _isModified) {
138: return _isModified;
139: }
140:
141: _isChecking = true;
142: }
143:
144: try {
145: long now = Alarm.getCurrentTime();
146:
147: if (now < _lastCheckTime + _checkInterval)
148: return _isModified;
149:
150: _lastCheckTime = now;
151:
152: for (int i = _dependencyList.size() - 1; i >= 0; i--) {
153: Dependency dependency = _dependencyList.get(i);
154:
155: if (dependency.isModified()) {
156: log().fine(dependency + " is modified");
157:
158: _isModified = true;
159:
160: return _isModified;
161: }
162: }
163:
164: // _isModified = false;
165:
166: return _isModified;
167: } finally {
168: _isChecking = false;
169: }
170: }
171:
172: /**
173: * Log the reason for the modification
174: */
175: public boolean logModified(Logger log) {
176: for (int i = _dependencyList.size() - 1; i >= 0; i--) {
177: Dependency dependency = _dependencyList.get(i);
178:
179: if (dependency.logModified(log))
180: return true;
181: }
182:
183: return false;
184: }
185:
186: /**
187: * Returns true if the underlying dependencies have changed, forcing a check.
188: */
189: public boolean isModifiedNow() {
190: _lastCheckTime = 0;
191:
192: return isModified();
193: }
194:
195: private Logger log() {
196: if (_log == null)
197: _log = Logger.getLogger(BasicDependencyContainer.class
198: .getName());
199:
200: return _log;
201: }
202:
203: public String toString() {
204: return "BasicDependencyContainer" + _dependencyList;
205: }
206: }
|