diff options
author | Ashlee Young <ashlee@onosfw.com> | 2015-10-23 10:00:02 -0700 |
---|---|---|
committer | Ashlee Young <ashlee@onosfw.com> | 2015-10-23 10:00:02 -0700 |
commit | 753a6c60f47f3ac4f270005b65e9d6481de8eb68 (patch) | |
tree | 3d0a1ae3b4d994550f6614b417b991eee3eb8911 /framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java | |
parent | c62d20eb3b4620c06d833be06f50b2600d96dd42 (diff) |
Adding maven and ant source trees
Change-Id: I0a39b9add833a31b9c3f98d193983ae2f3a5a445
Signed-off-by: Ashlee Young <ashlee@onosfw.com>
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java new file mode 100644 index 00000000..3bc9918e --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java @@ -0,0 +1,296 @@ +/* + * 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.util; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FilenameFilter; +import java.io.IOException; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.Execute; + +/** + * Contains methods related to symbolic links - or what Ant thinks is + * a symbolic link based on the absent support for them in Java. + * + * @since Ant 1.8.0 + */ +public class SymbolicLinkUtils { + private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); + + /** + * Shared instance. + */ + private static final SymbolicLinkUtils PRIMARY_INSTANCE = + new SymbolicLinkUtils(); + + /** + * Method to retrieve The SymbolicLinkUtils, which is shared by + * all users of this method. + * @return an instance of SymbolicLinkUtils. + */ + public static SymbolicLinkUtils getSymbolicLinkUtils() { + // keep the door open for Java X.Y specific subclass if symbolic + // links ever become supported in the classlib + return PRIMARY_INSTANCE; + } + + /** + * Empty constructor. + */ + protected SymbolicLinkUtils() { + } + + /** + * Checks whether a given file is a symbolic link. + * + * <p>It doesn't really test for symbolic links but whether the + * canonical and absolute paths of the file are identical--this + * may lead to false positives on some platforms.</p> + * + * @param file the file to test. Must not be null. + * + * @return true if the file is a symbolic link. + * @throws IOException on error. + */ + public boolean isSymbolicLink(final File file) throws IOException { + return isSymbolicLink(file.getParentFile(), file.getName()); + } + + /** + * Checks whether a given file is a symbolic link. + * + * <p>It doesn't really test for symbolic links but whether the + * canonical and absolute paths of the file are identical--this + * may lead to false positives on some platforms.</p> + * + * @param name the name of the file to test. + * + * @return true if the file is a symbolic link. + * @throws IOException on error. + */ + public boolean isSymbolicLink(final String name) throws IOException { + return isSymbolicLink(new File(name)); + } + + /** + * Checks whether a given file is a symbolic link. + * + * <p>It doesn't really test for symbolic links but whether the + * canonical and absolute paths of the file are identical--this + * may lead to false positives on some platforms.</p> + * + * @param parent the parent directory of the file to test + * @param name the name of the file to test. + * + * @return true if the file is a symbolic link. + * @throws IOException on error. + */ + public boolean isSymbolicLink(final File parent, final String name) + throws IOException { + final File toTest = parent != null + ? new File(parent.getCanonicalPath(), name) + : new File(name); + return !toTest.getAbsolutePath().equals(toTest.getCanonicalPath()); + } + + /** + * Checks whether a given file is a broken symbolic link. + * + * <p>It doesn't really test for symbolic links but whether Java + * reports that the File doesn't exist but its parent's child list + * contains it--this may lead to false positives on some + * platforms.</p> + * + * <p>Note that #isSymbolicLink returns false if this method + * returns true since Java won't produce a canonical name + * different from the abolute one if the link is broken.</p> + * + * @param name the name of the file to test. + * + * @return true if the file is a broken symbolic link. + * @throws IOException on error. + */ + public boolean isDanglingSymbolicLink(final String name) throws IOException { + return isDanglingSymbolicLink(new File(name)); + } + + /** + * Checks whether a given file is a broken symbolic link. + * + * <p>It doesn't really test for symbolic links but whether Java + * reports that the File doesn't exist but its parent's child list + * contains it--this may lead to false positives on some + * platforms.</p> + * + * <p>Note that #isSymbolicLink returns false if this method + * returns true since Java won't produce a canonical name + * different from the abolute one if the link is broken.</p> + * + * @param file the file to test. + * + * @return true if the file is a broken symbolic link. + * @throws IOException on error. + */ + public boolean isDanglingSymbolicLink(final File file) throws IOException { + return isDanglingSymbolicLink(file.getParentFile(), file.getName()); + } + + /** + * Checks whether a given file is a broken symbolic link. + * + * <p>It doesn't really test for symbolic links but whether Java + * reports that the File doesn't exist but its parent's child list + * contains it--this may lead to false positives on some + * platforms.</p> + * + * <p>Note that #isSymbolicLink returns false if this method + * returns true since Java won't produce a canonical name + * different from the abolute one if the link is broken.</p> + * + * @param parent the parent directory of the file to test + * @param name the name of the file to test. + * + * @return true if the file is a broken symbolic link. + * @throws IOException on error. + */ + public boolean isDanglingSymbolicLink(final File parent, final String name) + throws IOException { + final File f = new File(parent, name); + if (!f.exists()) { + final String localName = f.getName(); + final String[] c = parent.list(new FilenameFilter() { + public boolean accept(final File d, final String n) { + return localName.equals(n); + } + }); + return c != null && c.length > 0; + } + return false; + } + + /** + * Delete a symlink (without deleting the associated resource). + * + * <p>This is a utility method that removes a unix symlink without + * removing the resource that the symlink points to. If it is + * accidentally invoked on a real file, the real file will not be + * harmed, but silently ignored.</p> + * + * <p>Normally this method works by + * getting the canonical path of the link, using the canonical path to + * rename the resource (breaking the link) and then deleting the link. + * The resource is then returned to its original name inside a finally + * block to ensure that the resource is unharmed even in the event of + * an exception.</p> + * + * <p>There may be cases where the algorithm described above doesn't work, + * in that case the method tries to use the native "rm" command on + * the symlink instead.</p> + * + * @param link A <code>File</code> object of the symlink to delete. + * @param task An Ant Task required if "rm" needs to be invoked. + * + * @throws IOException If calls to <code>File.rename</code>, + * <code>File.delete</code> or <code>File.getCanonicalPath</code> + * fail. + * @throws BuildException if the execution of "rm" failed. + */ + public void deleteSymbolicLink(File link, final Task task) + throws IOException { + if (isDanglingSymbolicLink(link)) { + if (!link.delete()) { + throw new IOException("failed to remove dangling symbolic link " + + link); + } + return; + } + + if (!isSymbolicLink(link)) { + // plain file, not a link + return; + } + + if (!link.exists()) { + throw new FileNotFoundException("No such symbolic link: " + link); + } + + // find the resource of the existing link: + final File target = link.getCanonicalFile(); + + // no reason to try the renaming algorithm if we aren't allowed to + // write to the target's parent directory. Let's hope that + // File.canWrite works on all platforms. + + if (task == null || target.getParentFile().canWrite()) { + + // rename the resource, thus breaking the link: + final File temp = FILE_UTILS.createTempFile("symlink", ".tmp", + target.getParentFile(), false, + false); + + if (FILE_UTILS.isLeadingPath(target, link)) { + // link points to a parent directory, renaming the parent + // will rename the file + link = new File(temp, + FILE_UTILS.removeLeadingPath(target, link)); + } + + boolean renamedTarget = false; + try { + try { + FILE_UTILS.rename(target, temp); + renamedTarget = true; + } catch (final IOException e) { + throw new IOException("Couldn't rename resource when " + + "attempting to delete '" + link + + "'. Reason: " + e.getMessage()); + } + // delete the (now) broken link: + if (!link.delete()) { + throw new IOException("Couldn't delete symlink: " + + link + + " (was it a real file? is this " + + "not a UNIX system?)"); + } + } finally { + if (renamedTarget) { + // return the resource to its original name: + try { + FILE_UTILS.rename(temp, target); + } catch (final IOException e) { + throw new IOException("Couldn't return resource " + + temp + + " to its original name: " + + target.getAbsolutePath() + + ". Reason: " + e.getMessage() + + "\n THE RESOURCE'S NAME ON DISK" + + " HAS BEEN CHANGED BY THIS" + + " ERROR!\n"); + } + } + } + } else { + Execute.runCommand(task, + new String[] {"rm", link.getAbsolutePath()}); + } + } + +} |