⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sync.java

📁 Use the links below to download a source distribution of Ant from one of our mirrors. It is good pra
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* *  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.HashSet;import java.util.Iterator;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.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 &lt;copy&gt; 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;    // Override Task#init    /**     * Initialize the sync task.     * @throws BuildException if there is a problem.     * @see Task#init()     */    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()     */    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 ;-)        }        // 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);        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()) {            log("PASS#3: Removing empty directories from " + toDir,                Project.MSG_DEBUG);            int removedDirCount = removeEmptyDirectories(toDir, false);            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.     * @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) {        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 = new FileSet();            fs.setDir(toDir);            fs.setCaseSensitive(syncTarget.isCaseSensitive());            fs.setFollowSymlinks(syncTarget.isFollowSymlinks());            // 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]);            if (f.list().length < 1) {            log("Removing orphan directory: " + f, Project.MSG_DEBUG);            f.delete();            ++removedCount[0];            }        }        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>     *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -