aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Touch.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Touch.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Touch.java381
1 files changed, 381 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Touch.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Touch.java
new file mode 100644
index 00000000..4a4118ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Touch.java
@@ -0,0 +1,381 @@
+/*
+ * 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.io.IOException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileList;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.Touchable;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Touch a file and/or fileset(s) and/or filelist(s);
+ * corresponds to the Unix touch command.
+ *
+ * <p>If the file to touch doesn't exist, an empty one is created.</p>
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="filesystem"
+ */
+public class Touch extends Task {
+
+ public interface DateFormatFactory {
+ DateFormat getPrimaryFormat();
+ DateFormat getFallbackFormat();
+ }
+
+ public static final DateFormatFactory DEFAULT_DF_FACTORY
+ = new DateFormatFactory() {
+ /*
+ * The initial version used DateFormat.SHORT for the
+ * time format, which ignores seconds. If we want
+ * seconds as well, we need DateFormat.MEDIUM, which
+ * in turn would break all old build files.
+ *
+ * First try to parse with DateFormat.SHORT and if
+ * that fails with MEDIUM - throw an exception if both
+ * fail.
+ */
+ public DateFormat getPrimaryFormat() {
+ return DateFormat.getDateTimeInstance(DateFormat.SHORT,
+ DateFormat.SHORT, Locale.US);
+ }
+ public DateFormat getFallbackFormat() {
+ return DateFormat.getDateTimeInstance(DateFormat.SHORT,
+ DateFormat.MEDIUM, Locale.US);
+ }
+ };
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private File file;
+ private long millis = -1;
+ private String dateTime;
+ private Vector filesets = new Vector();
+ private Union resources;
+ private boolean dateTimeConfigured;
+ private boolean mkdirs;
+ private boolean verbose = true;
+ private FileNameMapper fileNameMapper = null;
+ private DateFormatFactory dfFactory = DEFAULT_DF_FACTORY;
+
+ /**
+ * Construct a new <code>Touch</code> task.
+ */
+ public Touch() {
+ }
+
+ /**
+ * Sets a single source file to touch. If the file does not exist
+ * an empty file will be created.
+ * @param file the <code>File</code> to touch.
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * Set the new modification time of file(s) touched
+ * in milliseconds since midnight Jan 1 1970. Optional, default=now.
+ * @param millis the <code>long</code> timestamp to use.
+ */
+ public void setMillis(long millis) {
+ this.millis = millis;
+ }
+
+ /**
+ * Set the new modification time of file(s) touched
+ * in the format &quot;MM/DD/YYYY HH:MM AM <i>or</i> PM&quot;
+ * or &quot;MM/DD/YYYY HH:MM:SS AM <i>or</i> PM&quot;.
+ * Optional, default=now.
+ * @param dateTime the <code>String</code> date in the specified format.
+ */
+ public void setDatetime(String dateTime) {
+ if (this.dateTime != null) {
+ log("Resetting datetime attribute to " + dateTime, Project.MSG_VERBOSE);
+ }
+ this.dateTime = dateTime;
+ dateTimeConfigured = false;
+ }
+
+ /**
+ * Set whether nonexistent parent directories should be created
+ * when touching new files.
+ * @param mkdirs <code>boolean</code> whether to create parent directories.
+ * @since Ant 1.6.3
+ */
+ public void setMkdirs(boolean mkdirs) {
+ this.mkdirs = mkdirs;
+ }
+
+ /**
+ * Set whether the touch task will report every file it creates;
+ * defaults to <code>true</code>.
+ * @param verbose <code>boolean</code> flag.
+ * @since Ant 1.6.3
+ */
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ /**
+ * Set the format of the datetime attribute.
+ * @param pattern the <code>SimpleDateFormat</code>-compatible format pattern.
+ * @since Ant 1.6.3
+ */
+ public void setPattern(final String pattern) {
+ dfFactory = new DateFormatFactory() {
+ public DateFormat getPrimaryFormat() {
+ return new SimpleDateFormat(pattern);
+ }
+ public DateFormat getFallbackFormat() {
+ return null;
+ }
+ };
+ }
+
+ /**
+ * Add a <code>Mapper</code>.
+ * @param mapper the <code>Mapper</code> to add.
+ * @since Ant 1.6.3
+ */
+ public void addConfiguredMapper(Mapper mapper) {
+ add(mapper.getImplementation());
+ }
+
+ /**
+ * Add a <code>FileNameMapper</code>.
+ * @param fileNameMapper the <code>FileNameMapper</code> to add.
+ * @since Ant 1.6.3
+ * @throws BuildException if multiple mappers are added.
+ */
+ public void add(FileNameMapper fileNameMapper) throws BuildException {
+ if (this.fileNameMapper != null) {
+ throw new BuildException("Only one mapper may be added to the "
+ + getTaskName() + " task.");
+ }
+ this.fileNameMapper = fileNameMapper;
+ }
+
+ /**
+ * Add a set of files to touch.
+ * @param set the <code>Fileset</code> to add.
+ */
+ public void addFileset(FileSet set) {
+ filesets.add(set);
+ add(set);
+ }
+
+ /**
+ * Add a filelist to touch.
+ * @param list the <code>Filelist</code> to add.
+ */
+ public void addFilelist(FileList list) {
+ add(list);
+ }
+
+ /**
+ * Add a collection of resources to touch.
+ * @param rc the collection to add.
+ * @since Ant 1.7
+ */
+ public synchronized void add(ResourceCollection rc) {
+ resources = resources == null ? new Union() : resources;
+ resources.add(rc);
+ }
+
+ /**
+ * Check that this task has been configured properly.
+ * @throws BuildException if configuration errors are detected.
+ * @since Ant 1.6.3
+ */
+ protected synchronized void checkConfiguration() throws BuildException {
+ if (file == null && resources == null) {
+ throw new BuildException("Specify at least one source"
+ + "--a file or resource collection.");
+ }
+ if (file != null && file.exists() && file.isDirectory()) {
+ throw new BuildException("Use a resource collection to touch directories.");
+ }
+ if (dateTime != null && !dateTimeConfigured) {
+ long workmillis = millis;
+ if ("now".equalsIgnoreCase(dateTime)) {
+ workmillis = System.currentTimeMillis();
+ } else {
+ DateFormat df = dfFactory.getPrimaryFormat();
+ ParseException pe = null;
+ try {
+ workmillis = df.parse(dateTime).getTime();
+ } catch (ParseException peOne) {
+ df = dfFactory.getFallbackFormat();
+ if (df == null) {
+ pe = peOne;
+ } else {
+ try {
+ workmillis = df.parse(dateTime).getTime();
+ } catch (ParseException peTwo) {
+ pe = peTwo;
+ }
+ }
+ }
+ if (pe != null) {
+ throw new BuildException(pe.getMessage(), pe, getLocation());
+ }
+ if (workmillis < 0) {
+ throw new BuildException("Date of " + dateTime
+ + " results in negative " + "milliseconds value "
+ + "relative to epoch " + "(January 1, 1970, "
+ + "00:00:00 GMT).");
+ }
+ }
+ log("Setting millis to " + workmillis + " from datetime attribute",
+ ((millis < 0) ? Project.MSG_DEBUG : Project.MSG_VERBOSE));
+ setMillis(workmillis);
+ // only set if successful to this point:
+ dateTimeConfigured = true;
+ }
+ }
+
+ /**
+ * Execute the touch operation.
+ *
+ * @throws BuildException
+ * if an error occurs.
+ */
+ public void execute() throws BuildException {
+ checkConfiguration();
+ touch();
+ }
+
+ /**
+ * Does the actual work; assumes everything has been checked by now.
+ * @throws BuildException if an error occurs.
+ */
+ protected void touch() throws BuildException {
+ long defaultTimestamp = getTimestamp();
+
+ if (file != null) {
+ touch(new FileResource(file.getParentFile(), file.getName()),
+ defaultTimestamp);
+ }
+ if (resources == null) {
+ return;
+ }
+ // deal with the resource collections
+ for (Resource r : resources) {
+ Touchable t = r.as(Touchable.class);
+ if (t == null) {
+ throw new BuildException("Can't touch " + r);
+ }
+ touch(r, defaultTimestamp);
+ }
+
+ // deal with filesets in a special way since the task
+ // originally also used the directories and Union won't return
+ // them.
+ final int size = filesets.size();
+ for (int i = 0; i < size; i++) {
+ FileSet fs = (FileSet) filesets.elementAt(i);
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ File fromDir = fs.getDir(getProject());
+
+ String[] srcDirs = ds.getIncludedDirectories();
+
+ for (int j = 0; j < srcDirs.length; j++) {
+ touch(new FileResource(fromDir, srcDirs[j]), defaultTimestamp);
+ }
+ }
+ }
+
+ /**
+ * Touch a single file with the current timestamp (this.millis). This method
+ * does not interact with any nested mappers and remains for reasons of
+ * backwards-compatibility only.
+ * @param file file to touch
+ * @throws BuildException on error
+ * @deprecated since 1.6.x.
+ */
+ protected void touch(File file) {
+ touch(file, getTimestamp());
+ }
+
+ private long getTimestamp() {
+ return (millis < 0) ? System.currentTimeMillis() : millis;
+ }
+
+ private void touch(Resource r, long defaultTimestamp) {
+ if (fileNameMapper == null) {
+ FileProvider fp = r.as(FileProvider.class);
+ if (fp != null) {
+ // use this to create file and deal with non-writable files
+ touch(fp.getFile(), defaultTimestamp);
+ } else {
+ r.as(Touchable.class).touch(defaultTimestamp);
+ }
+ } else {
+ String[] mapped = fileNameMapper.mapFileName(r.getName());
+ if (mapped != null && mapped.length > 0) {
+ long modTime = defaultTimestamp;
+ if (millis < 0 && r.isExists()) {
+ modTime = r.getLastModified();
+ }
+ for (int i = 0; i < mapped.length; i++) {
+ touch(getProject().resolveFile(mapped[i]), modTime);
+ }
+ }
+ }
+ }
+
+ private void touch(File file, long modTime) {
+ if (!file.exists()) {
+ log("Creating " + file,
+ ((verbose) ? Project.MSG_INFO : Project.MSG_VERBOSE));
+ try {
+ FILE_UTILS.createNewFile(file, mkdirs);
+ } catch (IOException ioe) {
+ throw new BuildException("Could not create " + file, ioe,
+ getLocation());
+ }
+ }
+ if (!file.canWrite()) {
+ throw new BuildException("Can not change modification date of "
+ + "read-only file " + file);
+ }
+ FILE_UTILS.setFileLastModified(file, modTime);
+ }
+
+}