/* * This file is part of aion-unique <aion-unique.org>. * * aion-unique is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * aion-unique is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with aion-unique. If not, see <http://www.gnu.org/licenses/>. */ package com.aionemu.commons.versionning; import java.io.File; import java.io.FilenameFilter; import java.net.MalformedURLException; import java.net.URL; import java.text.CharacterIterator; import java.text.StringCharacterIterator; import java.util.Locale; /** * The Locator is a utility class which is used to find certain items in the environment. * * @since Ant 1.6 */ public final class Locator { /** * Not instantiable */ private Locator() { } /** * 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 */ public static File getClassSource(Class<?> c) { String classResource = c.getName().replace('.', '/') + ".class"; return getResourceSource(c.getClassLoader(), classResource); } /** * 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 */ public static File getResourceSource(ClassLoader c, String resource) { 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; } /** * Constructs a file path from a <code>file:</code> URI. * * <p> * Will be an absolute path if the given URI is absolute. * </p> * * <p> * Swallows '%' that are not followed by two characters, doesn't deal with non-ASCII characters. * </p> * * @param uri * the URI designating a file in the local filesystem. * @return the local file system path for the file. * @since Ant 1.6 */ public static String fromURI(String uri) { 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 = decodeUri(uri); return path; } /** * Decodes an Uri with % characters. * * @param uri * String with the uri possibly containing % characters. * @return The decoded Uri */ private static String decodeUri(String uri) { if(uri.indexOf('%') == -1) { return uri; } StringBuffer sb = new StringBuffer(); 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.append((char) ((i1 << 4) + i2)); } } } else { sb.append(c); } } String path = sb.toString(); return path; } /** * 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. */ public static File getToolsJar() { // 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"); if(javaHome.toLowerCase(Locale.US).endsWith("jre")) { javaHome = javaHome.substring(0, javaHome.length() - 4); } File 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; } /** * 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. */ public static URL[] getLocationURLs(File location) throws MalformedURLException { return getLocationURLs(location, new String[] { ".jar" }); } /** * 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. */ public static URL[] getLocationURLs(File location, final String[] extensions) throws MalformedURLException { 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] = location.toURI().toURL(); 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] = matches[i].toURI().toURL(); } return urls; } }