diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sync.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sync.java | 606 |
1 files changed, 0 insertions, 606 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sync.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sync.java deleted file mode 100644 index c1c75529..00000000 --- a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sync.java +++ /dev/null @@ -1,606 +0,0 @@ -/* - * 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.Enumeration; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -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.AbstractFileSet; -import org.apache.tools.ant.types.FileSet; -import org.apache.tools.ant.types.PatternSet; -import org.apache.tools.ant.types.Resource; -import org.apache.tools.ant.types.ResourceCollection; -import org.apache.tools.ant.types.resources.Resources; -import org.apache.tools.ant.types.resources.Restrict; -import org.apache.tools.ant.types.resources.selectors.Exists; -import org.apache.tools.ant.types.selectors.FileSelector; -import org.apache.tools.ant.types.selectors.NoneSelector; - -/** - * Synchronize a local target directory from the files defined - * in one or more filesets. - * - * <p>Uses a <copy> task internally, but forbidding the use of - * mappers and filter chains. Files of the destination directory not - * present in any of the source fileset are removed.</p> - * - * @since Ant 1.6 - * - * revised by <a href="mailto:daniel.armbrust@mayo.edu">Dan Armbrust</a> - * to remove orphaned directories. - * - * @ant.task category="filesystem" - */ -public class Sync extends Task { - - // Same as regular <copy> task... see at end-of-file! - private MyCopy myCopy; - - // Similar to a fileset, but doesn't allow dir attribute to be set - private SyncTarget syncTarget; - - private Resources resources = null; - - // Override Task#init - /** - * Initialize the sync task. - * @throws BuildException if there is a problem. - * @see Task#init() - */ - @Override - public void init() - throws BuildException { - // Instantiate it - myCopy = new MyCopy(); - configureTask(myCopy); - - // Default config of <mycopy> for our purposes. - myCopy.setFiltering(false); - myCopy.setIncludeEmptyDirs(false); - myCopy.setPreserveLastModified(true); - } - - private void configureTask(Task helper) { - helper.setProject(getProject()); - helper.setTaskName(getTaskName()); - helper.setOwningTarget(getOwningTarget()); - helper.init(); - } - - // Override Task#execute - /** - * Execute the sync task. - * @throws BuildException if there is an error. - * @see Task#execute() - */ - @Override - public void execute() - throws BuildException { - // The destination of the files to copy - File toDir = myCopy.getToDir(); - - // The complete list of files to copy - Set allFiles = myCopy.nonOrphans; - - // If the destination directory didn't already exist, - // or was empty, then no previous file removal is necessary! - boolean noRemovalNecessary = !toDir.exists() || toDir.list().length < 1; - - // Copy all the necessary out-of-date files - log("PASS#1: Copying files to " + toDir, Project.MSG_DEBUG); - myCopy.execute(); - - // Do we need to perform further processing? - if (noRemovalNecessary) { - log("NO removing necessary in " + toDir, Project.MSG_DEBUG); - return; // nope ;-) - } - - // will hold the directories matched by SyncTarget in reversed - // lexicographic order (order is important, that's why we use - // a LinkedHashSet - Set preservedDirectories = new LinkedHashSet(); - - // Get rid of all files not listed in the source filesets. - log("PASS#2: Removing orphan files from " + toDir, Project.MSG_DEBUG); - int[] removedFileCount = removeOrphanFiles(allFiles, toDir, - preservedDirectories); - logRemovedCount(removedFileCount[0], "dangling director", "y", "ies"); - logRemovedCount(removedFileCount[1], "dangling file", "", "s"); - - // Get rid of empty directories on the destination side - if (!myCopy.getIncludeEmptyDirs() - || getExplicitPreserveEmptyDirs() == Boolean.FALSE) { - log("PASS#3: Removing empty directories from " + toDir, - Project.MSG_DEBUG); - - int removedDirCount = 0; - if (!myCopy.getIncludeEmptyDirs()) { - removedDirCount = - removeEmptyDirectories(toDir, false, preservedDirectories); - } else { // must be syncTarget.preserveEmptydirs == FALSE - removedDirCount = - removeEmptyDirectories(preservedDirectories); - } - logRemovedCount(removedDirCount, "empty director", "y", "ies"); - } - } - - private void logRemovedCount(int count, String prefix, - String singularSuffix, String pluralSuffix) { - File toDir = myCopy.getToDir(); - - String what = (prefix == null) ? "" : prefix; - what += (count < 2) ? singularSuffix : pluralSuffix; - - if (count > 0) { - log("Removed " + count + " " + what + " from " + toDir, - Project.MSG_INFO); - } else { - log("NO " + what + " to remove from " + toDir, - Project.MSG_VERBOSE); - } - } - - /** - * Removes all files and folders not found as keys of a table - * (used as a set!). - * - * <p>If the provided file is a directory, it is recursively - * scanned for orphaned files which will be removed as well.</p> - * - * <p>If the directory is an orphan, it will also be removed.</p> - * - * @param nonOrphans the table of all non-orphan <code>File</code>s. - * @param file the initial file or directory to scan or test. - * @param preservedDirectories will be filled with the directories - * matched by preserveInTarget - if any. Will not be - * filled unless preserveEmptyDirs and includeEmptyDirs - * conflict. - * @return the number of orphaned files and directories actually removed. - * Position 0 of the array is the number of orphaned directories. - * Position 1 of the array is the number or orphaned files. - */ - private int[] removeOrphanFiles(Set nonOrphans, File toDir, - Set preservedDirectories) { - int[] removedCount = new int[] {0, 0}; - String[] excls = - (String[]) nonOrphans.toArray(new String[nonOrphans.size() + 1]); - // want to keep toDir itself - excls[nonOrphans.size()] = ""; - - DirectoryScanner ds = null; - if (syncTarget != null) { - FileSet fs = syncTarget.toFileSet(false); - fs.setDir(toDir); - - // preserveInTarget would find all files we want to keep, - // but we need to find all that we want to delete - so the - // meaning of all patterns and selectors must be inverted - PatternSet ps = syncTarget.mergePatterns(getProject()); - fs.appendExcludes(ps.getIncludePatterns(getProject())); - fs.appendIncludes(ps.getExcludePatterns(getProject())); - fs.setDefaultexcludes(!syncTarget.getDefaultexcludes()); - - // selectors are implicitly ANDed in DirectoryScanner. To - // revert their logic we wrap them into a <none> selector - // instead. - FileSelector[] s = syncTarget.getSelectors(getProject()); - if (s.length > 0) { - NoneSelector ns = new NoneSelector(); - for (int i = 0; i < s.length; i++) { - ns.appendSelector(s[i]); - } - fs.appendSelector(ns); - } - ds = fs.getDirectoryScanner(getProject()); - } else { - ds = new DirectoryScanner(); - ds.setBasedir(toDir); - } - ds.addExcludes(excls); - - ds.scan(); - String[] files = ds.getIncludedFiles(); - for (int i = 0; i < files.length; i++) { - File f = new File(toDir, files[i]); - log("Removing orphan file: " + f, Project.MSG_DEBUG); - f.delete(); - ++removedCount[1]; - } - String[] dirs = ds.getIncludedDirectories(); - // ds returns the directories in lexicographic order. - // iterating through the array backwards means we are deleting - // leaves before their parent nodes - thus making sure (well, - // more likely) that the directories are empty when we try to - // delete them. - for (int i = dirs.length - 1; i >= 0; --i) { - File f = new File(toDir, dirs[i]); - String[] children = f.list(); - if (children == null || children.length < 1) { - log("Removing orphan directory: " + f, Project.MSG_DEBUG); - f.delete(); - ++removedCount[0]; - } - } - - Boolean ped = getExplicitPreserveEmptyDirs(); - if (ped != null && ped.booleanValue() != myCopy.getIncludeEmptyDirs()) { - FileSet fs = syncTarget.toFileSet(true); - fs.setDir(toDir); - String[] preservedDirs = - fs.getDirectoryScanner(getProject()).getIncludedDirectories(); - for (int i = preservedDirs.length - 1; i >= 0; --i) { - preservedDirectories.add(new File(toDir, preservedDirs[i])); - } - } - - return removedCount; - } - - /** - * Removes all empty directories from a directory. - * - * <p><em>Note that a directory that contains only empty - * directories, directly or not, will be removed!</em></p> - * - * <p>Recurses depth-first to find the leaf directories - * which are empty and removes them, then unwinds the - * recursion stack, removing directories which have - * become empty themselves, etc...</p> - * - * @param dir the root directory to scan for empty directories. - * @param removeIfEmpty whether to remove the root directory - * itself if it becomes empty. - * @param preservedEmptyDirectories directories matched by - * syncTarget - * @return the number of empty directories actually removed. - */ - private int removeEmptyDirectories(File dir, boolean removeIfEmpty, - Set preservedEmptyDirectories) { - int removedCount = 0; - if (dir.isDirectory()) { - File[] children = dir.listFiles(); - for (int i = 0; i < children.length; ++i) { - File file = children[i]; - // Test here again to avoid method call for non-directories! - if (file.isDirectory()) { - removedCount += - removeEmptyDirectories(file, true, - preservedEmptyDirectories); - } - } - if (children.length > 0) { - // This directory may have become empty... - // We need to re-query its children list! - children = dir.listFiles(); - } - if (children.length < 1 && removeIfEmpty - && !preservedEmptyDirectories.contains(dir)) { - log("Removing empty directory: " + dir, Project.MSG_DEBUG); - dir.delete(); - ++removedCount; - } - } - return removedCount; - } - - /** - * Removes all empty directories preserved by preserveInTarget in - * the preserveEmptyDirs == FALSE case. - * - * <p>Relies on the set to be ordered in reversed lexicographic - * order so that directories will be removed depth-first.</p> - * - * @param preservedEmptyDirectories directories matched by - * syncTarget - * @return the number of empty directories actually removed. - * - * @since Ant 1.8.0 - */ - private int removeEmptyDirectories(Set preservedEmptyDirectories) { - int removedCount = 0; - for (Iterator iter = preservedEmptyDirectories.iterator(); - iter.hasNext();) { - File f = (File) iter.next(); - String[] s = f.list(); - if (s == null || s.length == 0) { - log("Removing empty directory: " + f, Project.MSG_DEBUG); - f.delete(); - ++removedCount; - } - } - return removedCount; - } - - // - // Various copy attributes/subelements of <copy> passed thru to <mycopy> - // - - /** - * Sets the destination directory. - * @param destDir the destination directory - */ - public void setTodir(File destDir) { - myCopy.setTodir(destDir); - } - - /** - * Used to force listing of all names of copied files. - * @param verbose if true force listing of all names of copied files. - */ - public void setVerbose(boolean verbose) { - myCopy.setVerbose(verbose); - } - - /** - * Overwrite any existing destination file(s). - * @param overwrite if true overwrite any existing destination file(s). - */ - public void setOverwrite(boolean overwrite) { - myCopy.setOverwrite(overwrite); - } - - /** - * Used to copy empty directories. - * @param includeEmpty If true copy empty directories. - */ - public void setIncludeEmptyDirs(boolean includeEmpty) { - myCopy.setIncludeEmptyDirs(includeEmpty); - } - - /** - * If false, note errors to the output but keep going. - * @param failonerror true or false - */ - public void setFailOnError(boolean failonerror) { - myCopy.setFailOnError(failonerror); - } - - /** - * Adds a set of files to copy. - * @param set a fileset - */ - public void addFileset(FileSet set) { - add(set); - } - - /** - * Adds a collection of filesystem resources to copy. - * @param rc a resource collection - * @since Ant 1.7 - */ - public void add(ResourceCollection rc) { - if (rc instanceof FileSet && rc.isFilesystemOnly()) { - // receives special treatment in copy that this task relies on - myCopy.add(rc); - } else { - if (resources == null) { - Restrict r = new Restrict(); - r.add(new Exists()); - r.add(resources = new Resources()); - myCopy.add(r); - } - resources.add(rc); - } - } - - /** - * The number of milliseconds leeway to give before deciding a - * target is out of date. - * - * <p>Default is 0 milliseconds, or 2 seconds on DOS systems.</p> - * @param granularity a <code>long</code> value - * @since Ant 1.6.2 - */ - public void setGranularity(long granularity) { - myCopy.setGranularity(granularity); - } - - /** - * A container for patterns and selectors that can be used to - * specify files that should be kept in the target even if they - * are not present in any source directory. - * - * <p>You must not invoke this method more than once.</p> - * @param s a preserveintarget nested element - * @since Ant 1.7 - */ - public void addPreserveInTarget(SyncTarget s) { - if (syncTarget != null) { - throw new BuildException("you must not specify multiple " - + "preserveintarget elements."); - } - syncTarget = s; - } - - /** - * The value of preserveTarget's preserveEmptyDirs attribute if - * specified and preserveTarget has been used in the first place. - * - * @since Ant 1.8.0. - */ - private Boolean getExplicitPreserveEmptyDirs() { - return syncTarget == null ? null : syncTarget.getPreserveEmptyDirs(); - } - - /** - * Subclass Copy in order to access it's file/dir maps. - */ - public static class MyCopy extends Copy { - - // List of files that must be copied, irrelevant from the - // fact that they are newer or not than the destination. - private Set nonOrphans = new HashSet(); - - /** Constructor for MyCopy. */ - public MyCopy() { - } - - /** - * @see Copy#scan(File, File, String[], String[]) - */ - /** {@inheritDoc} */ - @Override - protected void scan(File fromDir, File toDir, String[] files, - String[] dirs) { - assertTrue("No mapper", mapperElement == null); - - super.scan(fromDir, toDir, files, dirs); - - for (int i = 0; i < files.length; ++i) { - nonOrphans.add(files[i]); - } - for (int i = 0; i < dirs.length; ++i) { - nonOrphans.add(dirs[i]); - } - } - - /** - * @see Copy#scan(Resource[], File) - */ - /** {@inheritDoc} */ - @Override - protected Map scan(Resource[] resources, File toDir) { - assertTrue("No mapper", mapperElement == null); - - for (int i = 0; i < resources.length; i++) { - nonOrphans.add(resources[i].getName()); - } - return super.scan(resources, toDir); - } - - /** - * Get the destination directory. - * @return the destination directory - */ - public File getToDir() { - return destDir; - } - - /** - * Get the includeEmptyDirs attribute. - * @return true if emptyDirs are to be included - */ - public boolean getIncludeEmptyDirs() { - return includeEmpty; - } - - /** - * Yes, we can. - * @return true always. - * @since Ant 1.7 - */ - @Override - protected boolean supportsNonFileResources() { - return true; - } - } - - /** - * Inner class used to hold exclude patterns and selectors to save - * stuff that happens to live in the target directory but should - * not get removed. - * - * @since Ant 1.7 - */ - public static class SyncTarget extends AbstractFileSet { - - private Boolean preserveEmptyDirs; - - /** - * Constructor for SyncTarget. - * This just changes the default value of "defaultexcludes" from - * true to false. - */ - public SyncTarget() { - super(); - } - - /** - * Override AbstractFileSet#setDir(File) to disallow - * setting the directory. - * @param dir ignored - * @throws BuildException always - */ - @Override - public void setDir(File dir) throws BuildException { - throw new BuildException("preserveintarget doesn't support the dir " - + "attribute"); - } - - /** - * Whether empty directories matched by this fileset should be - * preserved. - * - * @since Ant 1.8.0 - */ - public void setPreserveEmptyDirs(boolean b) { - preserveEmptyDirs = Boolean.valueOf(b); - } - - /** - * Whether empty directories matched by this fileset should be - * preserved. - * - * @since Ant 1.8.0 - */ - public Boolean getPreserveEmptyDirs() { - return preserveEmptyDirs; - } - - private FileSet toFileSet(boolean withPatterns) { - FileSet fs = new FileSet(); - fs.setCaseSensitive(isCaseSensitive()); - fs.setFollowSymlinks(isFollowSymlinks()); - fs.setMaxLevelsOfSymlinks(getMaxLevelsOfSymlinks()); - fs.setProject(getProject()); - - if (withPatterns) { - PatternSet ps = mergePatterns(getProject()); - fs.appendIncludes(ps.getIncludePatterns(getProject())); - fs.appendExcludes(ps.getExcludePatterns(getProject())); - for (Enumeration e = selectorElements(); e.hasMoreElements();) { - fs.appendSelector((FileSelector) e.nextElement()); - } - fs.setDefaultexcludes(getDefaultexcludes()); - } - return fs; - } - } - - /** - * Pseudo-assert method. - */ - private static void assertTrue(String message, boolean condition) { - if (!condition) { - throw new BuildException("Assertion Error: " + message); - } - } - -} |