diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DependSet.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DependSet.java | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DependSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DependSet.java new file mode 100644 index 00000000..dc42beb1 --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DependSet.java @@ -0,0 +1,299 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.tools.ant.taskdefs; + +import java.io.File; +import java.util.Date; +import java.util.Iterator; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.FileList; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.Resource; +import org.apache.tools.ant.types.ResourceCollection; +import org.apache.tools.ant.types.TimeComparison; +import org.apache.tools.ant.types.resources.Resources; +import org.apache.tools.ant.types.resources.Restrict; +import org.apache.tools.ant.types.resources.Union; +import org.apache.tools.ant.types.resources.comparators.ResourceComparator; +import org.apache.tools.ant.types.resources.comparators.Reverse; +import org.apache.tools.ant.types.resources.selectors.Exists; +import org.apache.tools.ant.types.resources.selectors.Not; +import org.apache.tools.ant.types.resources.selectors.ResourceSelector; + +/** + * Examines and removes out of date target files. If any of the target files + * are out of date with respect to any of the source files, all target + * files are removed. This is useful where dependencies cannot be + * computed (for example, dynamically interpreted parameters or files + * that need to stay in synch but are not directly linked) or where + * the ant task in question could compute them but does not (for + * example, the linked DTD for an XML file using the XSLT task). + * + * nested arguments: + * <ul> + * <li>sources (resource union describing the source resources to examine) + * <li>srcfileset (fileset describing the source files to examine) + * <li>srcfilelist (filelist describing the source files to examine) + * <li>targets (path describing the target files to examine) + * <li>targetfileset (fileset describing the target files to examine) + * <li>targetfilelist (filelist describing the target files to examine) + * </ul> + * At least one of both source and target entities is required. + * <p> + * This task will examine each of the sources against each of the target files. If + * any target files are out of date with respect to any of the sources, all targets + * are removed. If any sources or targets do not exist, all targets are removed. + * Hint: If missing files should be ignored, specify them as include patterns + * in filesets, rather than using filelists. + * </p><p> + * This task attempts to optimize speed of dependency checking + * by comparing only the dates of the oldest target file and the newest source. + * </p><p> + * Example uses: + * <ul><li> + * Record the fact that an XML file must be up to date with respect to its XSD + * (Schema file), even though the XML file itself includes no reference to its XSD. + * </li><li> + * Record the fact that an XSL stylesheet includes other sub-stylesheets + * </li><li> + * Record the fact that java files must be recompiled if the ant build file changes + * </li></ul> + * + * @ant.task category="filesystem" + * @since Ant 1.4 + */ +public class DependSet extends MatchingTask { + + private static final ResourceSelector NOT_EXISTS = new Not(new Exists()); + private static final ResourceComparator DATE + = new org.apache.tools.ant.types.resources.comparators.Date(); + private static final ResourceComparator REVERSE_DATE = new Reverse(DATE); + + private static final class NonExistent extends Restrict { + private NonExistent(ResourceCollection rc) { + super.add(rc); + super.add(NOT_EXISTS); + } + } + + private static final class HideMissingBasedir + implements ResourceCollection { + private FileSet fs; + + private HideMissingBasedir(FileSet fs) { + this.fs = fs; + } + public Iterator<Resource> iterator() { + return basedirExists() ? fs.iterator() : Resources.EMPTY_ITERATOR; + } + public int size() { + return basedirExists() ? fs.size() : 0; + } + public boolean isFilesystemOnly() { + return true; + } + private boolean basedirExists() { + File basedir = fs.getDir(); + //trick to evoke "basedir not set" if null: + return basedir == null || basedir.exists(); + } + } + + private Union sources = null; + private Path targets = null; + + private boolean verbose; + + /** + * Create a nested sources element. + * @return a Union instance. + */ + public synchronized Union createSources() { + sources = (sources == null) ? new Union() : sources; + return sources; + } + + /** + * Add a set of source files. + * @param fs the FileSet to add. + */ + public void addSrcfileset(FileSet fs) { + createSources().add(fs); + } + + /** + * Add a list of source files. + * @param fl the FileList to add. + */ + public void addSrcfilelist(FileList fl) { + createSources().add(fl); + } + + /** + * Create a nested targets element. + * @return a Union instance. + */ + public synchronized Path createTargets() { + targets = (targets == null) ? new Path(getProject()) : targets; + return targets; + } + + /** + * Add a set of target files. + * @param fs the FileSet to add. + */ + public void addTargetfileset(FileSet fs) { + createTargets().add(new HideMissingBasedir(fs)); + } + + /** + * Add a list of target files. + * @param fl the FileList to add. + */ + public void addTargetfilelist(FileList fl) { + createTargets().add(fl); + } + + /** + * In verbose mode missing targets and sources as well as the + * modification times of the newest source and latest target will + * be logged as info. + * + * <p>All deleted files will be logged as well.</p> + * + * @since Ant 1.8.0 + */ + public void setVerbose(boolean b) { + verbose = b; + } + + /** + * Execute the task. + * @throws BuildException if errors occur. + */ + public void execute() throws BuildException { + if (sources == null) { + throw new BuildException( + "At least one set of source resources must be specified"); + } + if (targets == null) { + throw new BuildException( + "At least one set of target files must be specified"); + } + //no sources = nothing to compare; no targets = nothing to delete: + if (sources.size() > 0 && targets.size() > 0 && !uptodate(sources, targets)) { + log("Deleting all target files.", Project.MSG_VERBOSE); + if (verbose) { + String[] t = targets.list(); + for (int i = 0; i < t.length; i++) { + log("Deleting " + t[i]); + } + } + Delete delete = new Delete(); + delete.bindToOwner(this); + delete.add(targets); + delete.perform(); + } + } + + private boolean uptodate(ResourceCollection src, ResourceCollection target) { + org.apache.tools.ant.types.resources.selectors.Date datesel + = new org.apache.tools.ant.types.resources.selectors.Date(); + datesel.setMillis(System.currentTimeMillis()); + datesel.setWhen(TimeComparison.AFTER); + // don't whine because a file has changed during the last + // second (or whathever our current granularity may be) + datesel.setGranularity(0); + logFuture(targets, datesel); + + NonExistent missingTargets = new NonExistent(targets); + int neTargets = missingTargets.size(); + if (neTargets > 0) { + log(neTargets + " nonexistent targets", Project.MSG_VERBOSE); + logMissing(missingTargets, "target"); + return false; + } + Resource oldestTarget = getOldest(targets); + logWithModificationTime(oldestTarget, "oldest target file"); + + logFuture(sources, datesel); + + NonExistent missingSources = new NonExistent(sources); + int neSources = missingSources.size(); + if (neSources > 0) { + log(neSources + " nonexistent sources", Project.MSG_VERBOSE); + logMissing(missingSources, "source"); + return false; + } + Resource newestSource = (Resource) getNewest(sources); + logWithModificationTime(newestSource, "newest source"); + return oldestTarget.getLastModified() >= newestSource.getLastModified(); + } + + private void logFuture(ResourceCollection rc, ResourceSelector rsel) { + Restrict r = new Restrict(); + r.add(rsel); + r.add(rc); + for (Resource res : r) { + log("Warning: " + res + " modified in the future.", Project.MSG_WARN); + } + } + + private Resource getXest(ResourceCollection rc, ResourceComparator c) { + Iterator<Resource> i = rc.iterator(); + if (!i.hasNext()) { + return null; + + } + Resource xest = i.next(); + while (i.hasNext()) { + Resource next = i.next(); + if (c.compare(xest, next) < 0) { + xest = next; + } + } + return xest; + } + + private Resource getOldest(ResourceCollection rc) { + return getXest(rc, REVERSE_DATE); + } + + private Resource getNewest(ResourceCollection rc) { + return getXest(rc, DATE); + } + + private void logWithModificationTime(Resource r, String what) { + log(r.toLongString() + " is " + what + ", modified at " + + new Date(r.getLastModified()), + verbose ? Project.MSG_INFO : Project.MSG_VERBOSE); + } + + private void logMissing(ResourceCollection missing, String what) { + if (verbose) { + for (Resource r : missing) { + log("Expected " + what + " " + r.toLongString() + + " is missing."); + } + } + } +} |