KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > DependSet


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19 package org.apache.tools.ant.taskdefs;
20
21 import java.io.File JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import org.apache.tools.ant.BuildException;
24 import org.apache.tools.ant.Project;
25 import org.apache.tools.ant.types.Path;
26 import org.apache.tools.ant.types.FileSet;
27 import org.apache.tools.ant.types.FileList;
28 import org.apache.tools.ant.types.Resource;
29 import org.apache.tools.ant.types.TimeComparison;
30 import org.apache.tools.ant.types.ResourceCollection;
31 import org.apache.tools.ant.types.resources.Sort;
32 import org.apache.tools.ant.types.resources.Union;
33 import org.apache.tools.ant.types.resources.Restrict;
34 import org.apache.tools.ant.types.resources.Resources;
35 import org.apache.tools.ant.types.resources.FileResource;
36 import org.apache.tools.ant.types.resources.selectors.Not;
37 import org.apache.tools.ant.types.resources.selectors.Exists;
38 import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
39 import org.apache.tools.ant.types.resources.comparators.Reverse;
40 import org.apache.tools.ant.types.resources.comparators.ResourceComparator;
41
42 /**
43  * Examines and removes out of date target files. If any of the target files
44  * are out of date with respect to any of the source files, all target
45  * files are removed. This is useful where dependencies cannot be
46  * computed (for example, dynamically interpreted parameters or files
47  * that need to stay in synch but are not directly linked) or where
48  * the ant task in question could compute them but does not (for
49  * example, the linked DTD for an XML file using the XSLT task).
50  *
51  * nested arguments:
52  * <ul>
53  * <li>sources (resource union describing the source resources to examine)
54  * <li>srcfileset (fileset describing the source files to examine)
55  * <li>srcfilelist (filelist describing the source files to examine)
56  * <li>targets (path describing the target files to examine)
57  * <li>targetfileset (fileset describing the target files to examine)
58  * <li>targetfilelist (filelist describing the target files to examine)
59  * </ul>
60  * At least one of both source and target entities is required.
61  * <p>
62  * This task will examine each of the sources against each of the target files. If
63  * any target files are out of date with respect to any of the sources, all targets
64  * are removed. If any sources or targets do not exist, all targets are removed.
65  * Hint: If missing files should be ignored, specify them as include patterns
66  * in filesets, rather than using filelists.
67  * </p><p>
68  * This task attempts to optimize speed of dependency checking
69  * by comparing only the dates of the oldest target file and the newest source.
70  * </p><p>
71  * Example uses:
72  * <ul><li>
73  * Record the fact that an XML file must be up to date with respect to its XSD
74  * (Schema file), even though the XML file itself includes no reference to its XSD.
75  * </li><li>
76  * Record the fact that an XSL stylesheet includes other sub-stylesheets
77  * </li><li>
78  * Record the fact that java files must be recompiled if the ant build file changes
79  * </li></ul>
80  *
81  * @ant.task category="filesystem"
82  * @since Ant 1.4
83  */

84 public class DependSet extends MatchingTask {
85
86     private static final ResourceSelector NOT_EXISTS = new Not(new Exists());
87     private static final ResourceComparator DATE_ASC
88         = new org.apache.tools.ant.types.resources.comparators.Date();
89     private static final ResourceComparator DATE_DESC = new Reverse(DATE_ASC);
90
91     private static class NonExistent extends Restrict {
92         private NonExistent(ResourceCollection rc) {
93             super.add(rc);
94             super.add(NOT_EXISTS);
95         }
96     }
97     private static class Xest extends Sort {
98         private Xest(ResourceCollection rc, ResourceComparator c) {
99             super.add(c);
100             super.add(rc);
101         }
102     }
103     private static class Oldest extends Xest {
104         private Oldest(ResourceCollection rc) {
105             super(rc, DATE_ASC);
106         }
107     }
108     private static class Newest extends Xest {
109         private Newest(ResourceCollection rc) {
110             super(rc, DATE_DESC);
111         }
112     }
113     private static class HideMissingBasedir implements ResourceCollection {
114         private FileSet fs;
115
116         private HideMissingBasedir(FileSet fs) {
117             this.fs = fs;
118         }
119         public Iterator JavaDoc iterator() {
120             return basedirExists() ? fs.iterator() : Resources.EMPTY_ITERATOR;
121         }
122         public int size() {
123             return basedirExists() ? fs.size() : 0;
124         }
125         public boolean isFilesystemOnly() {
126             return true;
127         }
128         private boolean basedirExists() {
129             File JavaDoc basedir = fs.getDir();
130             //trick to evoke "basedir not set" if null:
131
return basedir == null || basedir.exists();
132         }
133     }
134
135     private Union sources = null;
136     private Path targets = null;
137
138     /**
139      * Create a nested sources element.
140      * @return a Union instance.
141      */

142     public synchronized Union createSources() {
143         sources = (sources == null) ? new Union() : sources;
144         return sources;
145     }
146
147     /**
148      * Add a set of source files.
149      * @param fs the FileSet to add.
150      */

151     public void addSrcfileset(FileSet fs) {
152         createSources().add(fs);
153     }
154
155     /**
156      * Add a list of source files.
157      * @param fl the FileList to add.
158      */

159     public void addSrcfilelist(FileList fl) {
160         createSources().add(fl);
161     }
162
163     /**
164      * Create a nested targets element.
165      * @return a Union instance.
166      */

167     public synchronized Path createTargets() {
168         targets = (targets == null) ? new Path(getProject()) : targets;
169         return targets;
170     }
171
172     /**
173      * Add a set of target files.
174      * @param fs the FileSet to add.
175      */

176     public void addTargetfileset(FileSet fs) {
177         createTargets().add(new HideMissingBasedir(fs));
178     }
179
180     /**
181      * Add a list of target files.
182      * @param fl the FileList to add.
183      */

184     public void addTargetfilelist(FileList fl) {
185         createTargets().add(fl);
186     }
187
188     /**
189      * Execute the task.
190      * @throws BuildException if errors occur.
191      */

192     public void execute() throws BuildException {
193         if (sources == null) {
194           throw new BuildException(
195               "At least one set of source resources must be specified");
196         }
197         if (targets == null) {
198           throw new BuildException(
199               "At least one set of target files must be specified");
200         }
201         //no sources = nothing to compare; no targets = nothing to delete:
202
if (sources.size() > 0 && targets.size() > 0 && !uptodate(sources, targets)) {
203            log("Deleting all target files.", Project.MSG_VERBOSE);
204            Delete delete = new Delete();
205            delete.bindToOwner(this);
206            delete.add(targets);
207            delete.perform();
208         }
209     }
210
211     private boolean uptodate(ResourceCollection src, ResourceCollection target) {
212         org.apache.tools.ant.types.resources.selectors.Date datesel
213             = new org.apache.tools.ant.types.resources.selectors.Date();
214         datesel.setMillis(System.currentTimeMillis());
215         datesel.setWhen(TimeComparison.AFTER);
216         logFuture(targets, datesel);
217
218         int neTargets = new NonExistent(targets).size();
219         if (neTargets > 0) {
220             log(neTargets + " nonexistent targets", Project.MSG_VERBOSE);
221             return false;
222         }
223         FileResource oldestTarget = (FileResource) (new Oldest(targets).iterator().next());
224         log(oldestTarget + " is oldest target file", Project.MSG_VERBOSE);
225
226         logFuture(sources, datesel);
227
228         int neSources = new NonExistent(sources).size();
229         if (neSources > 0) {
230             log(neSources + " nonexistent sources", Project.MSG_VERBOSE);
231             return false;
232         }
233         Resource newestSource = (Resource) (new Newest(sources).iterator().next());
234         log(newestSource.toLongString() + " is newest source", Project.MSG_VERBOSE);
235         return oldestTarget.getLastModified() >= newestSource.getLastModified();
236     }
237
238     private void logFuture(ResourceCollection rc, ResourceSelector rsel) {
239         Restrict r = new Restrict();
240         r.add(rsel);
241         r.add(rc);
242         for (Iterator JavaDoc i = r.iterator(); i.hasNext();) {
243             log("Warning: " + i.next() + " modified in the future.", Project.MSG_WARN);
244         }
245     }
246 }
247
Popular Tags