MacroExtension.java

 package macrolanguage; import sun.tools.javac.Main; import java.util.*; import java.lang.*; import java.io.*; import macrolanguage.SimpleStream;

/** * To use the MacroExtension you simply add it to your program * and add an interface for selecting the macro, then use the simple * methods of this class to compile and execute a macro. * The class offers several features: * 1. Interaction with your application. * 2. The full power you had writing the application will be available *   to your users. * 3. You can add a sandbox to block some functionality. * 4. You can ship upgrades/fixes as plugins. * 5. Other vendors and users can easily write plugins. * 6. Plugins will be fully integrate, cross platform and run in the *   same speed as the VM. * It is recommended you expose some of your software's internals * to your users to make this tool more effective. class MacroExtension extends ClassLoader { MacroExtension {   compilerClass = new sun.tools.javac.Main(dataStream,""); }

/**  * This method accepts a class file as parameter * and returns an instance of it. **/ public Object getObject(String fileName) throws java.lang.ClassNotFoundException, java.lang.InstantiationException, java.lang.IllegalAccessException {   Class classInstance = getClass; return(classInstance.forName(fileName).newInstance); }

/**  * This method accepts a java file as parameter and compiles it. * It returns true if compilation was successful and false otherwise. **/ public boolean compile(String fileName) {   String [] stringArr = new String[1]; stringArr[0] = fileName; return(compilerClass.compile(stringArr)); }

/**  * This method returns a vector in which all * the compilation errors are stored as strings. **/ public Vector getCompilationErrors {   return(dataStream.getStringsWritten); }

/**  * The main method is conveniently located here for testing purposes. **/ public static void main(String argv[]) {   MacroExtension m = new MacroExtension; m.compile("HelloWorld.java"); m.loadObject("HelloWorld"); }

/**  * creates an instance of a class by getting its name * and returns that instance, or null if none were found. **/ public Object loadObject(String className) {   try {     loadClass(className, true); return(getObject(className)); }   catch(java.lang.ClassNotFoundException e)    { System.out.println("Class not found exception: " + e.getMessage); }   catch(java.lang.InstantiationException e)    { System.out.println("Instantiation exception: " + e.getMessage); }   catch(java.lang.IllegalAccessException e)    { System.out.println("Illegal access exception : " + e.getMessage); }   catch(Exception e)    { System.out.println("An exception was thrown: " + e.getMessage); }   return(null); }

protected Class loadClass(String className, boolean callReslove) {   Class returnValue = (Class) classCache.get(className);

if(returnValue != null) return(returnValue);

String classFullName;

try {     File classFile; if (!className.endsWith(".class")) classFullName = className + ".class"; else {       className = className.substring(0, className.length - 5); System.out.println("Class name is: " + className); classFullName = className + ".class"; }

classFile = new File(classFullName);

FileInputStream inFile = new FileInputStream(classFile); byte[] classData = new byte[(int)classFile.length];

inFile.read(classData);

inFile.close;

returnValue = defineClass(className, classData, 0, classData.length);

classCache.put(className, returnValue); }   catch(IOException ioerr) {     try {       returnValue = findSystemClass(className); return(returnValue); }     catch (Exception anyException) {       System.out.println("File access error: " + anyException.getMessage); return(null); }   }

if(callReslove) {     resolveClass(returnValue); }

return(returnValue); }

/**  * Notice the long name. It's here to avoid namespace * problems with another Main **/ private sun.tools.javac.Main compilerClass; private SimpleStream dataStream = new SimpleStream; private Hashtable classCache = new Hashtable; } 