1 23 24 package org.objectweb.fractal.julia.loader; 25 26 import org.objectweb.fractal.julia.asm.ClassGenerationException; 27 import org.objectweb.fractal.julia.asm.ClassGenerator; 28 29 import java.io.BufferedOutputStream ; 30 import java.io.ByteArrayInputStream ; 31 import java.io.File ; 32 import java.io.FileOutputStream ; 33 import java.io.FileWriter ; 34 import java.io.InputStream ; 35 import java.util.HashMap ; 36 import java.util.Map ; 37 38 49 50 public class DynamicLoader extends BasicLoader { 51 52 56 public DynamicLoader () { 57 } 58 59 63 private String genLog; 64 65 private String genDir; 66 67 public void init (final Map context) throws Exception { 68 super.init(context); 69 70 if (context.get("julia.loader.gen.dir") != null) { 71 genDir = (String )context.get("julia.loader.gen.dir"); 72 } else if (System.getProperty("julia.loader.gen.dir") != null) { 73 genDir = System.getProperty("julia.loader.gen.dir"); 74 } 75 76 if (context.get("julia.loader.gen.log") != null) { 77 genLog = (String )context.get("julia.loader.gen.log"); 78 } else if (System.getProperty("julia.loader.gen.log") != null) { 79 genLog = System.getProperty("julia.loader.gen.log"); 80 } 81 } 82 83 public Class loadClass (final String name, final Object loader) 84 throws ClassNotFoundException 85 { 86 return PublicClassLoader.getInstance(getClassLoader(loader)).loadClass(name); 87 } 88 89 protected Class generateClass ( 90 final String name, 91 final Tree classDescriptor, 92 final Object loader) throws ClassNotFoundException 93 { 94 ClassLoader cl = getClassLoader(loader); 95 ClassGenerator classGen = null; 96 try { 97 classGen = (ClassGenerator)newObject(classDescriptor.getSubTree(0), loader); 98 } catch (ClassCastException e) { 99 throw new ClassGenerationException( 100 null, 101 classDescriptor.toString(), 102 "The class generator is not an instance of ClassGenerator"); 103 } catch (Exception e) { 104 throw new ClassGenerationException( 105 e, classDescriptor.toString(), "Cannot create the class generator"); 106 } 107 byte[] b = classGen.generateClass(name, classDescriptor, this, cl); 108 if (genLog != null) { 109 String line = classDescriptor.toString(); 110 if (genLog.equals("out")) { 111 System.out.println(line); 112 } else if (genLog.equals("err")) { 113 System.err.println(line); 114 } else { 115 try { 116 FileWriter fw = new FileWriter (genLog, true); 117 fw.write(line); 118 fw.write('\n'); 119 fw.close(); 120 } catch (Exception e) { 121 e.printStackTrace(); 122 } 123 } 124 } 125 if (genDir != null) { 126 try { 127 String pkg; 128 String cls; 129 int dot = name.lastIndexOf('.'); 130 if (dot > 0) { 131 pkg = name.substring(0, dot).replace('.', File.separatorChar); 132 cls = name.substring(dot + 1); 133 } else { 134 pkg = ""; 135 cls = name; 136 } 137 File dirFile = new File (new File (genDir), pkg); 138 if (!dirFile.exists()) { 139 dirFile.mkdirs(); 140 } 141 File classFile = new File (dirFile, cls + ".class"); 142 BufferedOutputStream bos = 143 new BufferedOutputStream (new FileOutputStream (classFile)); 144 bos.write(b); 145 bos.close(); 146 } catch (Exception e) { 147 e.printStackTrace(); 148 } 149 } 150 return PublicClassLoader.getInstance(cl).defineClass(name, b); 151 } 152 153 private ClassLoader getClassLoader (final Object loader) { 154 if (loader instanceof ClassLoader ) { 155 return (ClassLoader )loader; 156 } else if (loader != null) { 157 return loader.getClass().getClassLoader(); 158 } else { 159 return getClass().getClassLoader(); 160 } 161 } 162 163 167 168 static class PublicClassLoader extends ClassLoader { 169 170 173 174 private final static Map INSTANCES = new HashMap (); 175 176 179 180 private Map bytecodes = new HashMap (); 181 182 188 189 private PublicClassLoader (final ClassLoader parent) { 190 super(parent); 191 } 192 193 201 202 public static PublicClassLoader getInstance (final ClassLoader parent) { 203 synchronized (INSTANCES) { 204 PublicClassLoader instance = (PublicClassLoader)INSTANCES.get(parent); 205 if (instance == null) { 206 instance = new PublicClassLoader(parent); 207 INSTANCES.put(parent, instance); 208 } 209 return instance; 210 } 211 } 212 213 220 221 public Class defineClass (final String name, final byte[] b) { 222 bytecodes.put(name.replace('.', '/') + ".class", b); 223 return defineClass(name, b, 0, b.length); 224 } 225 226 public InputStream getResourceAsStream (final String name) { 227 InputStream is = super.getResourceAsStream(name); 228 if (is == null) { 229 byte[] b = (byte[])bytecodes.get(name); 230 if (b != null) { 231 is = new ByteArrayInputStream (b); 232 } 233 } 234 return is; 235 } 236 } 237 } 238 | Popular Tags |