KickJava   Java API By Example, From Geeks To Geeks.

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


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.Enumeration JavaDoc;
23 import java.util.Vector JavaDoc;
24 import org.apache.tools.ant.BuildException;
25 import org.apache.tools.ant.DirectoryScanner;
26 import org.apache.tools.ant.Project;
27 import org.apache.tools.ant.Task;
28 import org.apache.tools.ant.taskdefs.condition.Condition;
29 import org.apache.tools.ant.types.Resource;
30 import org.apache.tools.ant.types.FileSet;
31 import org.apache.tools.ant.types.resources.Union;
32 import org.apache.tools.ant.types.Mapper;
33 import org.apache.tools.ant.util.FileNameMapper;
34 import org.apache.tools.ant.util.MergingMapper;
35 import org.apache.tools.ant.util.ResourceUtils;
36 import org.apache.tools.ant.util.SourceFileScanner;
37
38 /**
39  * Sets the given property if the specified target has a timestamp
40  * greater than all of the source files.
41  *
42  * @since Ant 1.2
43  *
44  * @ant.task category="control"
45  */

46
47 public class UpToDate extends Task implements Condition {
48
49     private String JavaDoc property;
50     private String JavaDoc value;
51     private File JavaDoc sourceFile;
52     private File JavaDoc targetFile;
53     private Vector JavaDoc sourceFileSets = new Vector JavaDoc();
54     private Union sourceResources = new Union();
55
56     // CheckStyle:VisibilityModifier OFF - bc
57
protected Mapper mapperElement = null;
58     // CheckStyle:VisibilityModifier ON
59

60     /**
61      * The property to set if the target file is more up-to-date than
62      * (each of) the source file(s).
63      *
64      * @param property the name of the property to set if Target is up-to-date.
65      */

66     public void setProperty(final String JavaDoc property) {
67         this.property = property;
68     }
69
70     /**
71      * The value to set the named property to if the target file is more
72      * up-to-date than (each of) the source file(s). Defaults to 'true'.
73      *
74      * @param value the value to set the property to if Target is up-to-date
75      */

76     public void setValue(final String JavaDoc value) {
77         this.value = value;
78     }
79
80     /**
81      * Returns the value, or "true" if a specific value wasn't provided.
82      */

83     private String JavaDoc getValue() {
84         return (value != null) ? value : "true";
85     }
86
87     /**
88      * The file which must be more up-to-date than (each of) the source file(s)
89      * if the property is to be set.
90      *
91      * @param file the file we are checking against.
92      */

93     public void setTargetFile(final File JavaDoc file) {
94         this.targetFile = file;
95     }
96
97     /**
98      * The file that must be older than the target file
99      * if the property is to be set.
100      *
101      * @param file the file we are checking against the target file.
102      */

103     public void setSrcfile(final File JavaDoc file) {
104         this.sourceFile = file;
105     }
106
107     /**
108      * Nested <srcfiles> element.
109      * @param fs the source files
110      */

111     public void addSrcfiles(final FileSet fs) {
112         sourceFileSets.addElement(fs);
113     }
114
115     /**
116      * Nested resource collections as sources.
117      * @return the source resources to configure.
118      * @since Ant 1.7
119      */

120     public Union createSrcResources() {
121         return sourceResources;
122     }
123
124     /**
125      * Defines the FileNameMapper to use (nested mapper element).
126      * @return a mapper to be configured
127      * @throws BuildException if more than one mapper is defined
128      */

129     public Mapper createMapper() throws BuildException {
130         if (mapperElement != null) {
131             throw new BuildException("Cannot define more than one mapper",
132                                      getLocation());
133         }
134         mapperElement = new Mapper(getProject());
135         return mapperElement;
136     }
137
138     /**
139      * A nested filenamemapper
140      * @param fileNameMapper the mapper to add
141      * @since Ant 1.6.3
142      */

143     public void add(FileNameMapper fileNameMapper) {
144         createMapper().add(fileNameMapper);
145     }
146
147     /**
148      * Evaluate (all) target and source file(s) to
149      * see if the target(s) is/are up-to-date.
150      * @return true if the target(s) is/are up-to-date
151      */

152     public boolean eval() {
153         if (sourceFileSets.size() == 0 && sourceResources.size() == 0
154             && sourceFile == null) {
155             throw new BuildException("At least one srcfile or a nested "
156                                      + "<srcfiles> or <srcresources> element "
157                                      + "must be set.");
158         }
159
160         if ((sourceFileSets.size() > 0 || sourceResources.size() > 0)
161             && sourceFile != null) {
162             throw new BuildException("Cannot specify both the srcfile "
163                                      + "attribute and a nested <srcfiles> "
164                                      + "or <srcresources> element.");
165         }
166
167         if (targetFile == null && mapperElement == null) {
168             throw new BuildException("The targetfile attribute or a nested "
169                                      + "mapper element must be set.");
170         }
171
172         // if the target file is not there, then it can't be up-to-date
173
if (targetFile != null && !targetFile.exists()) {
174             log("The targetfile \"" + targetFile.getAbsolutePath()
175                     + "\" does not exist.", Project.MSG_VERBOSE);
176             return false;
177         }
178
179         // if the source file isn't there, throw an exception
180
if (sourceFile != null && !sourceFile.exists()) {
181             throw new BuildException(sourceFile.getAbsolutePath()
182                                      + " not found.");
183         }
184
185         boolean upToDate = true;
186         if (sourceFile != null) {
187             if (mapperElement == null) {
188                 upToDate = upToDate
189                     && (targetFile.lastModified() >= sourceFile.lastModified());
190             } else {
191                 SourceFileScanner sfs = new SourceFileScanner(this);
192                 upToDate = upToDate
193                     && (sfs.restrict(new String JavaDoc[] {sourceFile.getAbsolutePath()},
194                                   null, null,
195                                   mapperElement.getImplementation()).length == 0);
196             }
197         }
198
199         // filesets are separate from the rest for performance
200
// reasons. If we use the code for union below, we'll always
201
// scan all filesets, even if we know the target is out of
202
// date after the first test.
203
Enumeration JavaDoc e = sourceFileSets.elements();
204         while (upToDate && e.hasMoreElements()) {
205             FileSet fs = (FileSet) e.nextElement();
206             DirectoryScanner ds = fs.getDirectoryScanner(getProject());
207             upToDate = upToDate && scanDir(fs.getDir(getProject()),
208                                            ds.getIncludedFiles());
209         }
210
211         if (upToDate) {
212             Resource[] r = sourceResources.listResources();
213             upToDate = upToDate
214                 && (ResourceUtils.selectOutOfDateSources(
215                         this, r, getMapper(), getProject()).length == 0);
216         }
217
218         return upToDate;
219     }
220
221
222     /**
223      * Sets property to true if target file(s) have a more recent timestamp
224      * than (each of) the corresponding source file(s).
225      * @throws BuildException on error
226      */

227     public void execute() throws BuildException {
228         if (property == null) {
229             throw new BuildException("property attribute is required.",
230                                      getLocation());
231         }
232         boolean upToDate = eval();
233         if (upToDate) {
234             getProject().setNewProperty(property, getValue());
235             if (mapperElement == null) {
236                 log("File \"" + targetFile.getAbsolutePath()
237                     + "\" is up-to-date.", Project.MSG_VERBOSE);
238             } else {
239                 log("All target files are up-to-date.",
240                     Project.MSG_VERBOSE);
241             }
242         }
243     }
244
245     /**
246      * Scan a directory for files to check for "up to date"ness
247      * @param srcDir the directory
248      * @param files the files to scan for
249      * @return true if the files are up to date
250      */

251     protected boolean scanDir(File JavaDoc srcDir, String JavaDoc[] files) {
252         SourceFileScanner sfs = new SourceFileScanner(this);
253         FileNameMapper mapper = getMapper();
254         File JavaDoc dir = srcDir;
255         if (mapperElement == null) {
256             dir = null;
257         }
258         return sfs.restrict(files, srcDir, dir, mapper).length == 0;
259     }
260
261     private FileNameMapper getMapper() {
262         FileNameMapper mapper = null;
263         if (mapperElement == null) {
264             MergingMapper mm = new MergingMapper();
265             mm.setTo(targetFile.getAbsolutePath());
266             mapper = mm;
267         } else {
268             mapper = mapperElement.getImplementation();
269         }
270         return mapper;
271     }
272 }
273
Popular Tags