FileDocCategorySizeDatePackage
ManifestClassPath.javaAPI DocApache Ant 1.706437Wed Dec 13 06:16:24 GMT 2006org.apache.tools.ant.taskdefs

ManifestClassPath

public class ManifestClassPath extends org.apache.tools.ant.Task
Converts a Path into a property suitable as a Manifest classpath.
since
Ant 1.7
ant.task
category="property"

Fields Summary
private String
name
The property name to hold the classpath value.
private File
dir
The directory the classpath will be relative from.
private int
maxParentLevels
The maximum parent directory level to traverse.
private org.apache.tools.ant.types.Path
path
The classpath to convert.
Constructors Summary
Methods Summary
public voidaddClassPath(org.apache.tools.ant.types.Path path)
Adds the classpath to convert.

param
path the classpath to convert.

        this.path = path;
    
public voidexecute()
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.


                                 
       
        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>!");
        }

        // Normalize the reference directory (containing the jar)
        final FileUtils fileUtils = FileUtils.getFileUtils();
        dir = fileUtils.normalize(dir.getAbsolutePath());

        // Create as many directory prefixes as parent levels to traverse,
        // in addition to the reference directory itself
        File currDir = dir;
        String[] dirs = new String[maxParentLevels + 1];
        for (int i = 0; i < maxParentLevels + 1; ++i) {
            dirs[i] = currDir.getAbsolutePath() + File.separatorChar;
            currDir = currDir.getParentFile();
            if (currDir == null) {
                maxParentLevels = i + 1;
                break;
            }
        }

        String[] elements = path.list();
        StringBuffer buffer = new StringBuffer();
        StringBuffer element = new StringBuffer();
        for (int i = 0; i < elements.length; ++i) {
            // Normalize the current file
            File pathEntry = new File(elements[i]);
            pathEntry = fileUtils.normalize(pathEntry.getAbsolutePath());
            String fullPath = pathEntry.getAbsolutePath();

            // Find the longest prefix shared by the current file
            // and the reference directory.
            String relPath = null;
            for (int j = 0; j <= maxParentLevels; ++j) {
                String dir = dirs[j];
                if (!fullPath.startsWith(dir)) {
                    continue;
                }

                // We have a match! Add as many ../ as parent
                // directory traversed to get the relative path
                element.setLength(0);
                for (int k = 0; k < j; ++k) {
                    element.append("..");
                    element.append(File.separatorChar);
                }
                element.append(fullPath.substring(dir.length()));
                relPath = element.toString();
                break;
            }

            // No match, so bail out!
            if (relPath == null) {
                throw new BuildException(
                    "No suitable relative path from "
                    + dir + " to " + fullPath);
            }

            // Manifest's ClassPath: attribute always uses forward
            // slashes '/', and is space-separated. Ant will properly
            // format it on 72 columns with proper line continuation
            if (File.separatorChar != '/") {
                relPath = relPath.replace(File.separatorChar, '/");
            }
            if (pathEntry.isDirectory()) {
                relPath = relPath + '/";
            }
            try {
                relPath = Locator.encodeURI(relPath);
            } catch (UnsupportedEncodingException exc) {
                throw new BuildException(exc);
            }
            buffer.append(relPath);
            buffer.append(' ");
        }

        // Finally assign the property with the manifest classpath
        getProject().setNewProperty(name, buffer.toString().trim());
    
public voidsetJarFile(java.io.File jarfile)
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.

        File parent = jarfile.getParentFile();
        if (!parent.isDirectory()) {
            throw new BuildException("Jar's directory not found: " + parent);
        }
        this.dir = parent;
    
public voidsetMaxParentLevels(int levels)
Sets the maximum parent directory levels allowed when computing a relative path.

param
levels the max level. Defaults to 2.

        this.maxParentLevels = levels;
    
public voidsetProperty(java.lang.String name)
Sets the property name to hold the classpath value.

param
name the property name

        this.name = name;