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:
019: package org.apache.tools.ant.types.selectors;
020:
021: import org.apache.tools.ant.util.FileUtils;
022: import org.apache.tools.ant.BuildException;
023:
024: import java.io.File;
025: import java.io.IOException;
026:
027: /**
028: * This selector selects files against a mapped set of target files, selecting
029: * all those files which are different.
030: * Files with different lengths are deemed different
031: * automatically
032: * Files with identical timestamps are viewed as matching by
033: * default, unless you specify otherwise.
034: * Contents are compared if the lengths are the same
035: * and the timestamps are ignored or the same,
036: * except if you decide to ignore contents to gain speed.
037: * <p>
038: * This is a useful selector to work with programs and tasks that don't handle
039: * dependency checking properly; Even if a predecessor task always creates its
040: * output files, followup tasks can be driven off copies made with a different
041: * selector, so their dependencies are driven on the absolute state of the
042: * files, not a timestamp.
043: * <p>
044: * Clearly, however, bulk file comparisons is inefficient; anything that can
045: * use timestamps is to be preferred. If this selector must be used, use it
046: * over as few files as possible, perhaps following it with an <uptodate;>
047: * to keep the descendent routines conditional.
048: *
049: */
050: public class DifferentSelector extends MappingSelector {
051:
052: private static final FileUtils FILE_UTILS = FileUtils
053: .getFileUtils();
054:
055: private boolean ignoreFileTimes = true;
056: private boolean ignoreContents = false;
057:
058: /**
059: * This flag tells the selector to ignore file times in the comparison
060: * @param ignoreFileTimes if true ignore file times
061: */
062: public void setIgnoreFileTimes(boolean ignoreFileTimes) {
063: this .ignoreFileTimes = ignoreFileTimes;
064: }
065:
066: /**
067: * This flag tells the selector to ignore contents
068: * @param ignoreContents if true ignore contents
069: * @since ant 1.6.3
070: */
071: public void setIgnoreContents(boolean ignoreContents) {
072: this .ignoreContents = ignoreContents;
073: }
074:
075: /**
076: * this test is our selection test that compared the file with the destfile
077: * @param srcfile the source file
078: * @param destfile the destination file
079: * @return true if the files are different
080: */
081: protected boolean selectionTest(File srcfile, File destfile) {
082:
083: //if either of them is missing, they are different
084: if (srcfile.exists() != destfile.exists()) {
085: return true;
086: }
087:
088: if (srcfile.length() != destfile.length()) {
089: // different size =>different files
090: return true;
091: }
092:
093: if (!ignoreFileTimes) {
094: //same date if dest timestamp is within granularity of the srcfile
095: boolean sameDate;
096: sameDate = destfile.lastModified() >= srcfile
097: .lastModified()
098: - granularity
099: && destfile.lastModified() <= srcfile
100: .lastModified()
101: + granularity;
102:
103: // different dates => different files
104: if (!sameDate) {
105: return true;
106: }
107: }
108: if (!ignoreContents) {
109: //here do a bulk comparison
110: try {
111: return !FILE_UTILS.contentEquals(srcfile, destfile);
112: } catch (IOException e) {
113: throw new BuildException("while comparing " + srcfile
114: + " and " + destfile, e);
115: }
116: } else {
117: return false;
118: }
119: }
120: }
|