package org.anodyneos.xpImpl.runtime; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import org.anodyneos.xpImpl.translater.TranslaterContext; public class XpClassLoader extends ClassLoader { private String root; private ClassLoader parent; public XpClassLoader(ClassLoader parent){ super(parent); this.parent = parent; } public String getRoot() { return root; } public void setRoot(String root) { this.root = root; } protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class clazz = null; clazz = findLoadedClass(name); if (clazz != null){ if (resolve){ resolveClass(clazz); } return clazz; } if (name.startsWith(TranslaterContext.DEFAULT_PACKAGE + ".")){ return findClass(name); }else{ clazz = parent.loadClass(name); if (resolve){ resolveClass(clazz); } return clazz; } } public Class findClass(String name) throws ClassNotFoundException{ byte[] b = loadClassData(name); if (b == null){ throw new ClassNotFoundException(getFileNameFromClassName(getRoot(),name)); }else{ return defineClass(name, b, 0, b.length); } } private byte[] loadClassData(String name) { try{ File classFile = new File(getFileNameFromClassName(getRoot(),name)); if (classFile.exists() && classFile.canRead()){ return getBytesFromFile(classFile); } }catch (IOException ioe){ ioe.printStackTrace(); } return null; } public static String getFileNameFromClassName(String root, String className){ if (!(root.endsWith("/") || root.endsWith("\\"))){ root += File.separator; } String fileName = root + className.replace('.',File.separatorChar) + ".class"; return fileName; } private static byte[] getBytesFromFile(File file) throws IOException { InputStream is = new FileInputStream(file); // Get the size of the file long length = file.length(); // You cannot create an array using a long type. // It needs to be an int type. // Before converting to an int type, check // to ensure that file is not larger than Integer.MAX_VALUE. if (length > Integer.MAX_VALUE) { // File is too large } // Create the byte array to hold the data byte[] bytes = new byte[(int)length]; // Read in the bytes int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { offset += numRead; } // Ensure all the bytes have been read in if (offset < bytes.length) { throw new IOException("Could not completely read file "+file.getName()); } // Close the input stream and return bytes is.close(); return bytes; } }