FileDocCategorySizeDatePackage
Locator.javaAPI DocApache Ant 1.7017287Wed Dec 13 06:16:18 GMT 2006org.apache.tools.ant.launch

Locator

public final class Locator extends Object
The Locator is a utility class which is used to find certain items in the environment.
since
Ant 1.6

Fields Summary
public static final String
URI_ENCODING
encoding used to represent URIs
private static boolean[]
gNeedEscaping
private static char[]
gAfterEscaping1
private static char[]
gAfterEscaping2
private static char[]
gHexChs
Constructors Summary
private Locator()
Not instantiable

    // initialize the above 3 arrays
     
        for (int i = 0; i <= 0x1f; i++) {
            gNeedEscaping[i] = true;
            gAfterEscaping1[i] = gHexChs[i >> 4];
            gAfterEscaping2[i] = gHexChs[i & 0xf];
        }
        gNeedEscaping[0x7f] = true;
        gAfterEscaping1[0x7f] = '7";
        gAfterEscaping2[0x7f] = 'F";
        char[] escChs = {' ", '<", '>", '#", '%", '"", '{", '}",
                         '|", '\\", '^", '~", '[", ']", '`"};
        int len = escChs.length;
        char ch;
        for (int i = 0; i < len; i++) {
            ch = escChs[i];
            gNeedEscaping[ch] = true;
            gAfterEscaping1[ch] = gHexChs[ch >> 4];
            gAfterEscaping2[ch] = gHexChs[ch & 0xf];
        }
    
    
Methods Summary
public static java.lang.StringdecodeUri(java.lang.String uri)
Decodes an Uri with % characters. The URI is escaped

param
uri String with the uri possibly containing % characters.
return
The decoded Uri
throws
UnsupportedEncodingException if UTF-8 is not available
since
Ant 1.7

        if (uri.indexOf('%") == -1) {
            return uri;
        }
        ByteArrayOutputStream sb = new ByteArrayOutputStream(uri.length());
        CharacterIterator iter = new StringCharacterIterator(uri);
        for (char c = iter.first(); c != CharacterIterator.DONE;
             c = iter.next()) {
            if (c == '%") {
                char c1 = iter.next();
                if (c1 != CharacterIterator.DONE) {
                    int i1 = Character.digit(c1, 16);
                    char c2 = iter.next();
                    if (c2 != CharacterIterator.DONE) {
                        int i2 = Character.digit(c2, 16);
                        sb.write((char) ((i1 << 4) + i2));
                    }
                }
            } else {
                sb.write(c);
            }
        }
        return sb.toString(URI_ENCODING);
    
public static java.lang.StringencodeURI(java.lang.String path)
Encodes an Uri with % characters. The URI is escaped

param
path String to encode.
return
The encoded string, according to URI norms
throws
UnsupportedEncodingException if UTF-8 is not available
since
Ant 1.7

        int i = 0;
        int len = path.length();
        int ch = 0;
        StringBuffer sb = null;
        for (; i < len; i++) {
            ch = path.charAt(i);
            // if it's not an ASCII character, break here, and use UTF-8 encoding
            if (ch >= 128) {
                break;
            }
            if (gNeedEscaping[ch]) {
                if (sb == null) {
                    sb = new StringBuffer(path.substring(0, i));
                }
                sb.append('%");
                sb.append(gAfterEscaping1[ch]);
                sb.append(gAfterEscaping2[ch]);
                // record the fact that it's escaped
            } else if (sb != null) {
                sb.append((char) ch);
            }
        }

        // we saw some non-ascii character
        if (i < len) {
            if (sb == null) {
                sb = new StringBuffer(path.substring(0, i));
            }
            // get UTF-8 bytes for the remaining sub-string
            byte[] bytes = null;
            byte b;
            bytes = path.substring(i).getBytes(URI_ENCODING);
            len = bytes.length;

            // for each byte
            for (i = 0; i < len; i++) {
                b = bytes[i];
                // for non-ascii character: make it positive, then escape
                if (b < 0) {
                    ch = b + 256;
                    sb.append('%");
                    sb.append(gHexChs[ch >> 4]);
                    sb.append(gHexChs[ch & 0xf]);
                } else if (gNeedEscaping[b]) {
                    sb.append('%");
                    sb.append(gAfterEscaping1[b]);
                    sb.append(gAfterEscaping2[b]);
                } else {
                    sb.append((char) b);
                }
            }
        }
        return sb == null ? path : sb.toString();
    
public static java.net.URLfileToURL(java.io.File file)
Convert a File to a URL. File.toURL() does not encode characters like #. File.toURI() has been introduced in java 1.4, so ANT cannot use it (except by reflection) FileUtils.toURI() cannot be used by Locator.java Implemented this way. File.toURL() adds file: and changes '\' to '/' for dos OSes encodeURI converts characters like ' ' and '#' to %DD

param
file the file to convert
return
URL the converted File
throws
MalformedURLException on error

        try {
            return new URL(encodeURI(file.toURL().toString()));
        } catch (UnsupportedEncodingException ex) {
            throw new MalformedURLException(ex.toString());
        }
    
public static java.lang.StringfromURI(java.lang.String uri)
Constructs a file path from a file: URI.

Will be an absolute path if the given URI is absolute.

Prior to Java 1.4, swallows '%' that are not followed by two characters.

See dt-sysid which makes some mention of how characters not supported by URI Reference syntax should be escaped.

param
uri the URI designating a file in the local filesystem.
return
the local file system path for the file.
throws
IllegalArgumentException if the URI is malformed or not a legal file: URL
since
Ant 1.6

        // #8031: first try Java 1.4.
        Class uriClazz = null;
        try {
            uriClazz = Class.forName("java.net.URI");
        } catch (ClassNotFoundException cnfe) {
            // Fine, Java 1.3 or earlier, do it by hand.
        }
        // Also check for properly formed URIs. Ant formerly recommended using
        // nonsense URIs such as "file:./foo.xml" in XML includes. You shouldn't
        // do that (just "foo.xml" is correct) but for compatibility we special-case
        // things when the path is not absolute, and fall back to the old parsing behavior.
        if (uriClazz != null && uri.startsWith("file:/")) {
            try {
                java.lang.reflect.Method createMethod
                    = uriClazz.getMethod("create", new Class[] {String.class});
                Object uriObj = createMethod.invoke(null, new Object[] {uri});
                java.lang.reflect.Constructor fileConst
                    = File.class.getConstructor(new Class[] {uriClazz});
                File f = (File) fileConst.newInstance(new Object[] {uriObj});
                return f.getAbsolutePath();
            } catch (java.lang.reflect.InvocationTargetException e) {
                Throwable e2 = e.getTargetException();
                if (e2 instanceof IllegalArgumentException) {
                    // Bad URI, pass this on.
                    throw (IllegalArgumentException) e2;
                } else {
                    // Unexpected target exception? Should not happen.
                    e2.printStackTrace();
                }
            } catch (Exception e) {
                // Reflection problems? Should not happen, debug.
                e.printStackTrace();
            }
        }

        // Fallback method for Java 1.3 or earlier.

        URL url = null;
        try {
            url = new URL(uri);
        } catch (MalformedURLException emYouEarlEx) {
            // Ignore malformed exception
        }
        if (url == null || !("file".equals(url.getProtocol()))) {
            throw new IllegalArgumentException("Can only handle valid file: URIs");
        }
        StringBuffer buf = new StringBuffer(url.getHost());
        if (buf.length() > 0) {
            buf.insert(0, File.separatorChar).insert(0, File.separatorChar);
        }
        String file = url.getFile();
        int queryPos = file.indexOf('?");
        buf.append((queryPos < 0) ? file : file.substring(0, queryPos));

        uri = buf.toString().replace('/", File.separatorChar);

        if (File.pathSeparatorChar == ';" && uri.startsWith("\\") && uri.length() > 2
            && Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':") > -1) {
            uri = uri.substring(1);
        }
        String path = null;
        try {
            path = decodeUri(uri);
            String cwd = System.getProperty("user.dir");
            int posi = cwd.indexOf(":");
            if ((posi > 0) && path.startsWith(File.separator)) {
               path = cwd.substring(0, posi + 1) + path;
            }
        } catch (UnsupportedEncodingException exc) {
            // not sure whether this is clean, but this method is
            // declared not to throw exceptions.
            throw new IllegalStateException("Could not convert URI to path: "
                                            + exc.getMessage());
        }
        return path;
    
public static java.io.FilegetClassSource(java.lang.Class c)
Find the directory or jar file the class has been loaded from.

param
c the class whose location is required.
return
the file or jar with the class or null if we cannot determine the location.
since
Ant 1.6

        String classResource = c.getName().replace('.", '/") + ".class";
        return getResourceSource(c.getClassLoader(), classResource);
    
public static java.net.URL[]getLocationURLs(java.io.File location, java.lang.String[] extensions)
Get an array of URLs representing all of the files of a given set of extensions in the given location. If the location is a file, it is returned as the only element of the array. If the location is a directory, it is scanned for matching files.

param
location the location to scan for files.
param
extensions an array of extension that are to match in the directory search.
return
an array of URLs of matching files.
exception
MalformedURLException if the URLs for the files cannot be formed.

        URL[] urls = new URL[0];

        if (!location.exists()) {
            return urls;
        }
        if (!location.isDirectory()) {
            urls = new URL[1];
            String path = location.getPath();
            for (int i = 0; i < extensions.length; ++i) {
                if (path.toLowerCase().endsWith(extensions[i])) {
                    urls[0] = fileToURL(location);
                    break;
                }
            }
            return urls;
        }
        File[] matches = location.listFiles(
            new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    for (int i = 0; i < extensions.length; ++i) {
                        if (name.toLowerCase().endsWith(extensions[i])) {
                            return true;
                        }
                    }
                    return false;
                }
            });
        urls = new URL[matches.length];
        for (int i = 0; i < matches.length; ++i) {
            urls[i] = fileToURL(matches[i]);
        }
        return urls;
    
public static java.net.URL[]getLocationURLs(java.io.File location)
Get an array of URLs representing all of the jar files in the given location. If the location is a file, it is returned as the only element of the array. If the location is a directory, it is scanned for jar files.

param
location the location to scan for Jars.
return
an array of URLs for all jars in the given location.
exception
MalformedURLException if the URLs for the jars cannot be formed.

        return getLocationURLs(location, new String[]{".jar"});
    
public static java.io.FilegetResourceSource(java.lang.ClassLoader c, java.lang.String resource)
Find the directory or jar a given resource has been loaded from.

param
c the classloader to be consulted for the source.
param
resource the resource whose location is required.
return
the file with the resource source or null if we cannot determine the location.
since
Ant 1.6

        if (c == null) {
            c = Locator.class.getClassLoader();
        }
        URL url = null;
        if (c == null) {
            url = ClassLoader.getSystemResource(resource);
        } else {
            url = c.getResource(resource);
        }
        if (url != null) {
            String u = url.toString();
            if (u.startsWith("jar:file:")) {
                int pling = u.indexOf("!");
                String jarName = u.substring(4, pling);
                return new File(fromURI(jarName));
            } else if (u.startsWith("file:")) {
                int tail = u.indexOf(resource);
                String dirName = u.substring(0, tail);
                return new File(fromURI(dirName));
            }
        }
        return null;
    
public static java.io.FilegetToolsJar()
Get the File necessary to load the Sun compiler tools. If the classes are available to this class, then no additional URL is required and null is returned. This may be because the classes are explicitly in the class path or provided by the JVM directly.

return
the tools jar as a File if required, null otherwise.

        // firstly check if the tools jar is already in the classpath
        boolean toolsJarAvailable = false;
        try {
            // just check whether this throws an exception
            Class.forName("com.sun.tools.javac.Main");
            toolsJarAvailable = true;
        } catch (Exception e) {
            try {
                Class.forName("sun.tools.javac.Main");
                toolsJarAvailable = true;
            } catch (Exception e2) {
                // ignore
            }
        }
        if (toolsJarAvailable) {
            return null;
        }
        // couldn't find compiler - try to find tools.jar
        // based on java.home setting
        String javaHome = System.getProperty("java.home");
        File toolsJar = new File(javaHome + "/lib/tools.jar");
        if (toolsJar.exists()) {
            // Found in java.home as given
            return toolsJar;
        }
        if (javaHome.toLowerCase(Locale.US).endsWith(File.separator + "jre")) {
            javaHome = javaHome.substring(0, javaHome.length() - 4);
            toolsJar = new File(javaHome + "/lib/tools.jar");
        }
        if (!toolsJar.exists()) {
            System.out.println("Unable to locate tools.jar. "
                 + "Expected to find it in " + toolsJar.getPath());
            return null;
        }
        return toolsJar;