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

📄 symlink.java

📁 ant源代码
💻 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. * *//* * Since the initial version of this file was developed on the clock on * an NSF grant I should say the following boilerplate: * * This material is based upon work supported by the National Science * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and * conclusions or recommendations expressed in this material are those * of the author and do not necessarily reflect the views of the * National Science Foundation. */package org.apache.tools.ant.taskdefs.optional.unix;import java.io.File;import java.io.IOException;import java.io.PrintStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileNotFoundException;import java.util.Vector;import java.util.HashSet;import java.util.Iterator;import java.util.Hashtable;import java.util.Properties;import org.apache.tools.ant.Project;import org.apache.tools.ant.BuildException;import org.apache.tools.ant.DirectoryScanner;import org.apache.tools.ant.dispatch.DispatchTask;import org.apache.tools.ant.dispatch.DispatchUtils;import org.apache.tools.ant.taskdefs.Execute;import org.apache.tools.ant.taskdefs.LogOutputStream;import org.apache.tools.ant.types.FileSet;import org.apache.tools.ant.types.Commandline;import org.apache.tools.ant.util.FileUtils;/** * Creates, Deletes, Records and Restores Symlinks. * * <p> This task performs several related operations. In the most trivial * and default usage, it creates a link specified in the link attribute to * a resource specified in the resource attribute. The second usage of this * task is to traverse a directory structure specified by a fileset, * and write a properties file in each included directory describing the * links found in that directory. The third usage is to traverse a * directory structure specified by a fileset, looking for properties files * (also specified as included in the fileset) and recreate the links * that have been previously recorded for each directory. Finally, it can be * used to remove a symlink without deleting the associated resource. * * <p> Usage examples: * * <p> Make a link named &quot;foo&quot; to a resource named * &quot;bar.foo&quot; in subdir: * <pre> * &lt;symlink link=&quot;${dir.top}/foo&quot; resource=&quot;${dir.top}/subdir/bar.foo&quot;/&gt; * </pre> * * <p> Record all links in subdir and its descendants in files named * &quot;dir.links&quot;: * <pre> * &lt;symlink action=&quot;record&quot; linkfilename=&quot;dir.links&quot;&gt; *    &lt;fileset dir=&quot;${dir.top}&quot; includes=&quot;subdir&#47;**&quot; /&gt; * &lt;/symlink&gt; * </pre> * * <p> Recreate the links recorded in the previous example: * <pre> * &lt;symlink action=&quot;recreate&quot;&gt; *    &lt;fileset dir=&quot;${dir.top}&quot; includes=&quot;subdir&#47;**&#47;dir.links&quot; /&gt; * &lt;/symlink&gt; * </pre> * * <p> Delete a link named &quot;foo&quot; to a resource named * &quot;bar.foo&quot; in subdir: * <pre> * &lt;symlink action=&quot;delete&quot; link=&quot;${dir.top}/foo&quot;/&gt; * </pre> * * <p><strong>LIMITATIONS:</strong> Because Java has no direct support for * handling symlinks this task divines them by comparing canonical and * absolute paths. On non-unix systems this may cause false positives. * Furthermore, any operating system on which the command * <code>ln -s link resource</code> is not a valid command on the command line * will not be able to use action=&quot;delete&quot;, action=&quot;single&quot; * or action=&quot;recreate&quot;, but action=&quot;record&quot; should still * work. Finally, the lack of support for symlinks in Java means that all links * are recorded as links to the <strong>canonical</strong> resource name. * Therefore the link: <code>link --> subdir/dir/../foo.bar</code> will be * recorded as <code>link=subdir/foo.bar</code> and restored as * <code>link --> subdir/foo.bar</code>. * */public class Symlink extends DispatchTask {    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();    private String resource;    private String link;    private Vector fileSets = new Vector();    private String linkFileName;    private boolean overwrite;    private boolean failonerror;    private boolean executing = false;    /**     * Initialize the task.     * @throws BuildException on error.     */    public void init() throws BuildException {        super.init();        setDefaults();    }    /**     * The standard method for executing any task.     * @throws BuildException on error.     */    public synchronized void execute() throws BuildException {        if (executing) {            throw new BuildException(                "Infinite recursion detected in Symlink.execute()");        }        try {            executing = true;            DispatchUtils.execute(this);        } finally {            executing = false;        }    }    /**     * Create a symlink.     * @throws BuildException on error.     * @since Ant 1.7     */    public void single() throws BuildException {        try {            if (resource == null) {                handleError("Must define the resource to symlink to!");                return;            }            if (link == null) {                handleError("Must define the link name for symlink!");                return;            }            doLink(resource, link);        } finally {            setDefaults();        }    }    /**     * Delete a symlink.     * @throws BuildException on error.     * @since Ant 1.7     */    public void delete() throws BuildException {        try {            if (link == null) {                handleError("Must define the link name for symlink!");                return;            }            log("Removing symlink: " + link);            deleteSymlink(link);        } catch (FileNotFoundException fnfe) {            handleError(fnfe.toString());        } catch (IOException ioe) {            handleError(ioe.toString());        } finally {            setDefaults();        }    }    /**     * Restore symlinks.     * @throws BuildException on error.     * @since Ant 1.7     */    public void recreate() throws BuildException {        try {            if (fileSets.isEmpty()) {                handleError("File set identifying link file(s) "                            + "required for action recreate");                return;            }            Properties links = loadLinks(fileSets);            for (Iterator kitr = links.keySet().iterator(); kitr.hasNext();) {                String lnk = (String) kitr.next();                String res = links.getProperty(lnk);                // handle the case where lnk points to a directory (bug 25181)                try {                    File test = new File(lnk);                    if (!FILE_UTILS.isSymbolicLink(null, lnk)) {                        doLink(res, lnk);                    } else if (!test.getCanonicalPath().equals(                        new File(res).getCanonicalPath())) {                        deleteSymlink(lnk);                        doLink(res, lnk);                    } // else lnk exists, do nothing                } catch (IOException ioe) {                    handleError("IO exception while creating link");                }            }        } finally {            setDefaults();        }    }    /**     * Record symlinks.     * @throws BuildException on error.     * @since Ant 1.7     */    public void record() throws BuildException {        try {            if (fileSets.isEmpty()) {                handleError("Fileset identifying links to record required");                return;            }            if (linkFileName == null) {                handleError("Name of file to record links in required");                return;            }            // create a hashtable to group them by parent directory:            Hashtable byDir = new Hashtable();            // get an Iterator of file objects representing links (canonical):            for (Iterator litr = findLinks(fileSets).iterator();                litr.hasNext();) {                File thisLink = (File) litr.next();                File parent = thisLink.getParentFile();                Vector v = (Vector) byDir.get(parent);                if (v == null) {                    v = new Vector();                    byDir.put(parent, v);                }                v.addElement(thisLink);            }            // write a Properties file in each directory:            for (Iterator dirs = byDir.keySet().iterator(); dirs.hasNext();) {                File dir = (File) dirs.next();                Vector linksInDir = (Vector) byDir.get(dir);                Properties linksToStore = new Properties();                // fill up a Properties object with link and resource names:                for (Iterator dlnk = linksInDir.iterator(); dlnk.hasNext();) {                    File lnk = (File) dlnk.next();                    try {                        linksToStore.put(lnk.getName(), lnk.getCanonicalPath());                    } catch (IOException ioe) {                        handleError("Couldn't get canonical name of parent link");                    }                }                writePropertyFile(linksToStore, dir);            }        } finally {            setDefaults();        }    }    /**     * Return all variables to their default state for the next invocation.     * @since Ant 1.7     */    private void setDefaults() {        resource = null;        link = null;        linkFileName = null;        failonerror = true;   // default behavior is to fail on an error        overwrite = false;    // default behavior is to not overwrite        setAction("single");      // default behavior is make a single link        fileSets.clear();    }    /**

⌨️ 快捷键说明

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