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 java.util.logging.Level;
033: import java.util.logging.Logger;
034:
035: /**
036: * Class for keeping track of modifications.
037: */
038: public class Depend implements PersistentDependency {
039: private static final Logger log = Logger.getLogger(Depend.class
040: .getName());
041:
042: Path _source;
043: long _lastModified;
044: long _length;
045:
046: boolean _requireSource = true;
047: boolean _isDigestModified;
048:
049: /**
050: * Create a new dependency with an already known modified time and length.
051: *
052: * @param source the source file
053: */
054: public Depend(Path source, long lastModified, long length) {
055: _source = source;
056: _lastModified = lastModified;
057: _length = length;
058: }
059:
060: /**
061: * Create a new dependency.
062: *
063: * @param source the source file
064: */
065: public Depend(Path source) {
066: /* XXX:
067: if (source instanceof JarPath)
068: source = ((JarPath) source).getContainer();
069: */
070:
071: _source = source;
072: _lastModified = source.getLastModified();
073: _length = source.getLength();
074: }
075:
076: /**
077: * Create a new dependency with a given digest.
078: *
079: * @param source the source file
080: * @param digest the CRC64 digest
081: */
082: public Depend(Path source, long digest) {
083: this (source, digest, true);
084: }
085:
086: /**
087: * Create a new dependency with a given digest.
088: *
089: * @param source the source file
090: * @param digest the CRC64 digest
091: */
092: public Depend(Path source, long digest, boolean requireSource) {
093: _source = source;
094:
095: long newDigest = source.getCrc64();
096:
097: _requireSource = requireSource;
098:
099: if (newDigest == digest) {
100: } else if (!requireSource && newDigest == -1) {
101: } else if (newDigest == -1) {
102: if (log.isLoggable(Level.FINE))
103: log.fine(_source.getNativePath()
104: + " source is deleted.");
105:
106: _isDigestModified = true;
107: } else {
108: /*
109: if (log.isLoggable(Level.FINE))
110: log.fine(_source.getNativePath() + " digest is modified.");
111: */
112:
113: _isDigestModified = true;
114: }
115:
116: _lastModified = _source.getLastModified();
117: _length = _source.getLength();
118: }
119:
120: /**
121: * Returns the underlying source path.
122: */
123: public Path getPath() {
124: return _source;
125: }
126:
127: /**
128: * Returns the current last-modified time of the file.
129: */
130: public long getLastModified() {
131: return _source.getLastModified();
132: }
133:
134: /**
135: * Returns the current length time of the file.
136: */
137: public long getLength() {
138: return _source.getLength();
139: }
140:
141: /**
142: * If true, deleting the source counts as a change.
143: */
144: public boolean getRequireSource() {
145: return _requireSource;
146: }
147:
148: /**
149: * If true, deleting the source counts as a change.
150: */
151: public void setRequireSource(boolean requireSource) {
152: _requireSource = requireSource;
153: }
154:
155: /**
156: * If the source modified date changes at all, treat it as a modification.
157: * This protects against the case where multiple computers have
158: * misaligned dates and a '<' comparison may fail.
159: */
160: public boolean isModified() {
161: if (_isDigestModified) {
162: if (log.isLoggable(Level.FINE))
163: log.fine(_source.getNativePath()
164: + " digest is modified.");
165:
166: return true;
167: }
168:
169: long sourceLastModified = _source.getLastModified();
170: long sourceLength = _source.getLength();
171:
172: // if the source was deleted and we need the source
173: if (!_requireSource && sourceLastModified == 0)
174: return false;
175: // if the length changed
176: else if (sourceLength != _length) {
177: if (log.isLoggable(Level.FINE))
178: log.fine(_source.getNativePath()
179: + " length is modified (" + _length + " -> "
180: + sourceLength + ")");
181:
182: return true;
183: }
184: // if the source is newer than the old value
185: else if (sourceLastModified != _lastModified) {
186: if (log.isLoggable(Level.FINE))
187: log
188: .fine(_source.getNativePath()
189: + " time is modified.");
190:
191: return true;
192: } else
193: return false;
194: }
195:
196: /**
197: * Log the reason for modification
198: */
199: public boolean logModified(Logger log) {
200: if (_isDigestModified) {
201: log.info(_source.getNativePath() + " digest is modified.");
202:
203: return true;
204: }
205:
206: long sourceLastModified = _source.getLastModified();
207: long sourceLength = _source.getLength();
208:
209: // if the source was deleted and we need the source
210: if (!_requireSource && sourceLastModified == 0) {
211: return false;
212: }
213: // if the length changed
214: else if (sourceLength != _length) {
215: log.info(_source.getNativePath() + " length is modified ("
216: + _length + " -> " + sourceLength + ")");
217:
218: return true;
219: }
220: // if the source is newer than the old value
221: else if (sourceLastModified != _lastModified) {
222: log.info(_source.getNativePath() + " time is modified.");
223:
224: return true;
225: } else
226: return false;
227: }
228:
229: /**
230: * Returns the digest.
231: */
232: public long getDigest() {
233: return _source.getCrc64();
234: }
235:
236: /**
237: * Returns true if the test Dependency has the same source path as
238: * this dependency.
239: */
240: public boolean equals(Object obj) {
241: if (!(obj instanceof Depend))
242: return false;
243:
244: Depend depend = (Depend) obj;
245:
246: return _source.equals(depend._source);
247: }
248:
249: /**
250: * Returns the string to recreate the Dependency.
251: */
252: public String getJavaCreateString() {
253: return ("new com.caucho.vfs.Depend(com.caucho.vfs.Vfs.lookup(\""
254: + _source.getPath() + "\"), " + _source.getCrc64() + "L)");
255: }
256:
257: /**
258: * Returns a printable version of the dependency.
259: */
260: public String toString() {
261: return ("Depend[" + _source + " " + _lastModified + " "
262: + (_source.getLastModified() - _lastModified) + "]");
263: }
264: }
|