/* * 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.Path; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.FileList; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.TimeComparison; import org.apache.tools.ant.types.ResourceCollection; import org.apache.tools.ant.types.resources.Union; import org.apache.tools.ant.types.resources.Restrict; import org.apache.tools.ant.types.resources.Resources; import org.apache.tools.ant.types.resources.selectors.Not; import org.apache.tools.ant.types.resources.selectors.Exists; import org.apache.tools.ant.types.resources.selectors.ResourceSelector; import org.apache.tools.ant.types.resources.comparators.Reverse; import org.apache.tools.ant.types.resources.comparators.ResourceComparator; /** * 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: *
* 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. *
* This task attempts to optimize speed of dependency checking * by comparing only the dates of the oldest target file and the newest source. *
* Example uses: *
All deleted files will be logged as well.
* * @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