diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java new file mode 100644 index 00000000..4a4f2312 --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java @@ -0,0 +1,180 @@ +/* + * 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.UnsupportedEncodingException; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.launch.Locator; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.FileUtils; + +/** + * Converts a Path into a property suitable as a Manifest classpath. + * + * @since Ant 1.7 + * + * @ant.task category="property" + */ +public class ManifestClassPath extends Task { + + /** The property name to hold the classpath value. */ + private String name; + + /** The directory the classpath will be relative from. */ + private File dir; + + /** The maximum parent directory level to traverse. */ + private int maxParentLevels = 2; + + /** The classpath to convert. */ + private Path path; + + /** + * Sets a property, which must not already exist, with a space + * separated list of files and directories relative to the jar + * file's parent directory. + */ + public void execute() { + if (name == null) { + throw new BuildException("Missing 'property' attribute!"); + } + if (dir == null) { + throw new BuildException("Missing 'jarfile' attribute!"); + } + if (getProject().getProperty(name) != null) { + throw new BuildException("Property '" + name + "' already set!"); + } + if (path == null) { + throw new BuildException("Missing nested <classpath>!"); + } + + StringBuffer tooLongSb = new StringBuffer(); + for (int i = 0; i < maxParentLevels + 1; i++) { + tooLongSb.append("../"); + } + final String tooLongPrefix = tooLongSb.toString(); + + // Normalize the reference directory (containing the jar) + final FileUtils fileUtils = FileUtils.getFileUtils(); + dir = fileUtils.normalize(dir.getAbsolutePath()); + + String[] elements = path.list(); + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < elements.length; ++i) { + // Normalize the current file + File pathEntry = new File(elements[i]); + String fullPath = pathEntry.getAbsolutePath(); + pathEntry = fileUtils.normalize(fullPath); + + String relPath = null; + String canonicalPath = null; + try { + if (dir.equals(pathEntry)) { + relPath = "."; + } else { + relPath = FileUtils.getRelativePath(dir, pathEntry); + } + + canonicalPath = pathEntry.getCanonicalPath(); + // getRelativePath always uses '/' as separator, adapt + if (File.separatorChar != '/') { + canonicalPath = + canonicalPath.replace(File.separatorChar, '/'); + } + } catch (Exception e) { + throw new BuildException("error trying to get the relative path" + + " from " + dir + " to " + fullPath, + e); + } + + // No match, so bail out! + if (relPath.equals(canonicalPath) + || relPath.startsWith(tooLongPrefix)) { + throw new BuildException("No suitable relative path from " + + dir + " to " + fullPath); + } + + if (pathEntry.isDirectory() && !relPath.endsWith("/")) { + relPath = relPath + '/'; + } + try { + relPath = Locator.encodeURI(relPath); + } catch (UnsupportedEncodingException exc) { + throw new BuildException(exc); + } + // Manifest's ClassPath: attribute always uses forward + // slashes '/', and is space-separated. Ant will properly + // format it on 72 columns with proper line continuation + buffer.append(relPath); + buffer.append(' '); + } + + // Finally assign the property with the manifest classpath + getProject().setNewProperty(name, buffer.toString().trim()); + } + + /** + * Sets the property name to hold the classpath value. + * + * @param name the property name + */ + public void setProperty(String name) { + this.name = name; + } + + /** + * The JAR file to contain the classpath attribute in its manifest. + * + * @param jarfile the JAR file. Need not exist yet, but its parent + * directory must exist on the other hand. + */ + public void setJarFile(File jarfile) { + File parent = jarfile.getParentFile(); + if (!parent.isDirectory()) { + throw new BuildException("Jar's directory not found: " + parent); + } + this.dir = parent; + } + + /** + * Sets the maximum parent directory levels allowed when computing + * a relative path. + * + * @param levels the max level. Defaults to 2. + */ + public void setMaxParentLevels(int levels) { + if (levels < 0) { + throw new BuildException("maxParentLevels must not be a negative" + + " number"); + } + this.maxParentLevels = levels; + } + + /** + * Adds the classpath to convert. + * + * @param path the classpath to convert. + */ + public void addClassPath(Path path) { + this.path = path; + } + +} |