package codechicken.lib.tool; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; import java.nio.ByteBuffer; import java.util.LinkedList; import java.util.List; public class LibDownloader { private static String[] libs = new String[] { "org/ow2/asm/asm-debug-all/5.0.3/asm-debug-all-5.0.3.jar", "com/google/guava/guava/14.0/guava-14.0.jar", "net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar", "org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar", "org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar" }; private static File libDir = new File("lib"); private static ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(1 << 23); public static void load() { if (!libDir.exists()) { libDir.mkdir(); } if (!libDir.isDirectory()) { throw new RuntimeException("/lib is not a directory"); } List<String> missing = checkExists(); for (String lib : missing) { download(lib); } addPaths(libs); } private static void addPaths(String[] libs) { try { URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader(); Method m_addURL = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class }); m_addURL.setAccessible(true); for (String lib : libs) { m_addURL.invoke(cl, new File(libDir, fileName(lib)).toURI().toURL()); } } catch (Exception e) { throw new RuntimeException("Failed to add libraries to classpath", e); } } private static void download(String lib) { File libFile = new File(libDir, fileName(lib)); try { URL libDownload = new URL("http://repo1.maven.org/maven2/" + lib); URLConnection connection = libDownload.openConnection(); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); connection.setRequestProperty("User-Agent", "CodeChickenLib Downloader"); int sizeGuess = connection.getContentLength(); download(connection.getInputStream(), sizeGuess, libFile); } catch (Exception e) { libFile.delete(); throw new RuntimeException("A download error occured", e); } } private static void download(InputStream is, int sizeGuess, File target) throws Exception { String name = target.getName(); if (sizeGuess > downloadBuffer.capacity()) { throw new Exception(String.format("The file %s is too large to be downloaded", name)); } downloadBuffer.clear(); int bytesRead, fullLength = 0; System.out.format("Downloading lib %s", name); byte[] smallBuffer = new byte[1024]; while ((bytesRead = is.read(smallBuffer)) >= 0) { downloadBuffer.put(smallBuffer, 0, bytesRead); fullLength += bytesRead; System.out.format("\rDownloading lib %s %d%%", name, (int) (fullLength * 100 / sizeGuess)); } System.out.format("\rDownloaded lib %s \n", name); is.close(); downloadBuffer.limit(fullLength); if (!target.exists()) { target.createNewFile(); } downloadBuffer.position(0); FileOutputStream fos = new FileOutputStream(target); fos.getChannel().write(downloadBuffer); fos.close(); } private static String fileName(String lib) { return lib.replaceAll(".+/", ""); } private static List<String> checkExists() { LinkedList<String> list = new LinkedList<String>(); for (String lib : libs) { File file = new File(libDir, fileName(lib)); if (!file.exists()) { list.add(lib); } } return list; } }