1 23 24 package org.objectweb.fractal.julia.loader; 25 26 import java.io.FileInputStream ; 27 import java.io.IOException ; 28 import java.io.InputStream ; 29 import java.util.ArrayList ; 30 import java.util.HashMap ; 31 import java.util.List ; 32 import java.util.Map ; 33 34 44 45 public class BasicLoader implements Loader { 46 47 51 public BasicLoader () { 52 } 53 54 58 62 63 private String config; 64 65 70 71 private boolean checkClassParameters; 72 73 77 78 private String genPkg; 79 80 83 84 private Map definitions; 85 86 89 90 private InputStream is; 91 92 95 96 private int line; 97 98 101 102 private int car; 103 104 108 public void init (final Map context) throws Exception { 109 if (context.get("julia.config") != null) { 110 config = (String )context.get("julia.config"); 111 } else if (System.getProperty("julia.config") != null) { 112 config = System.getProperty("julia.config"); 113 } else { 114 throw new Exception ( 115 "The julia.config system property is not defined"); 116 } 117 118 if (context.get("julia.loader.check") != null) { 119 checkClassParameters = true; 120 } else if (System.getProperty("julia.loader.check") != null) { 121 checkClassParameters = true; 122 } 123 124 genPkg = "org.objectweb.fractal.julia.generated"; 125 if (context.get("julia.loader.gen.pkg") != null) { 126 genPkg = (String )context.get("julia.loader.gen.pkg"); 127 } else if (System.getProperty("julia.loader.gen.pkg") != null) { 128 genPkg = System.getProperty("julia.loader.gen.pkg"); 129 } 130 } 131 132 public Tree loadTree (final String name) throws Exception { 133 if (definitions == null) { 134 definitions = new HashMap (); 135 int b = 0; 136 int i; 137 do { 138 i = config.indexOf(',', b); 139 String file; 140 if (i == -1) { 141 file = config.substring(b); 142 } else { 143 file = config.substring(b, i); 144 b = i + 1; 145 } 146 InputStream is; 147 try { 148 is = getInputStream(file); 149 } catch (IOException ioe) { 150 is = getClass().getResourceAsStream("/" + file); 151 if (is == null) { 152 throw new Exception ("Cannot find or open the '" + file + "' file"); 153 } 154 } 155 try { 156 line = 1; 157 while (true) { 158 Tree def; 159 try { 160 def = parseTree(is); 161 } catch (Throwable e) { 162 throw new Exception ( 163 "File '" + file + "', line " + line + ": " + e.getMessage()); 164 } 165 if (def == null) { 166 break; 167 } else { 168 definitions.put(def.getSubTree(0).toString(), def.getSubTree(1)); 169 } 170 } 171 } finally { 172 try { 173 is.close(); 174 } catch (IOException ignored) { 175 } 176 } 177 } while (i != -1); 178 } 179 Tree t = (Tree)definitions.get(name); 180 if (t == null) { 181 throw new Exception ( 182 "Cannot find the '" + name + 183 "' descriptor in the '" + config + 184 "' file(s) specified in the julia.loader.config system property"); 185 } 186 return t; 187 } 188 189 public Tree evalTree (final Tree tree, final Map context) 190 throws Exception 191 { 192 if (tree.getSize() == 0) { 193 String var = tree.toString(); 194 if (var.startsWith("'")) { 195 var = var.substring(1); 196 Tree val = (Tree)context.get(var); 197 if (val == null) { 198 val = loadTree(var); 199 } 200 if (val == null) { 201 throw new Exception (var); 202 } 203 if (!val.toString().equals("QUOTE")) { 204 return evalTree(val, context); 205 } 206 } 207 return tree; 208 } else { 209 boolean ok = true; 210 Tree[] subTrees = tree.getSubTrees(); 211 for (int i = 0; i < subTrees.length; ++i) { 212 Tree oldSubTree = subTrees[i]; 213 Tree newSubTree = evalTree(oldSubTree, context); 214 if (newSubTree != oldSubTree) { 215 if (ok) { 216 Tree[] newSubTrees = new Tree[subTrees.length]; 217 System.arraycopy(subTrees, 0, newSubTrees, 0, subTrees.length); 218 subTrees = newSubTrees; 219 ok = false; 220 } 221 subTrees[i] = newSubTree; 222 } 223 } 224 return (ok ? tree : new Tree(subTrees)); 225 } 226 } 227 228 public Object newObject (final Tree objectDescriptor, final Object loader) 229 throws Exception 230 { 231 if (objectDescriptor.getSize() == 0) { 232 return loadClass(objectDescriptor.toString(), loader).newInstance(); 233 } else { 234 Object o; 235 o = loadClass(objectDescriptor.getSubTree(0), loader).newInstance(); 236 if (objectDescriptor.getSize() > 1) { 237 Tree[] trees = objectDescriptor.getSubTrees(); 238 Tree[] args = new Tree[trees.length - 1]; 239 System.arraycopy(trees, 1, args, 0, args.length); 240 ((Initializable)o).initialize(new Tree(args)); 241 } 242 return o; 243 } 244 } 245 246 public Class loadClass (final String name, final Object loader) 247 throws ClassNotFoundException 248 { 249 return Class.forName(name); 250 } 251 252 public Class loadClass (final Tree classDescriptor, final Object loader) 253 throws ClassNotFoundException 254 { 255 if (classDescriptor.getSize() == 0) { 256 return loadClass(classDescriptor.toString(), loader); 257 } 258 int n = 0; 259 String s = genPkg + ".C" + Integer.toHexString(classDescriptor.hashCode()) + "_"; 260 while (true) { 261 String name = s + n; 262 Class c; 263 try { 264 c = loadClass(name, loader); 265 } catch (ClassNotFoundException e) { 266 return generateClass(name, classDescriptor, loader); 267 } 268 if (!checkClassParameters) { 269 return c; 270 } 271 try { 272 Generated gen = (Generated)c.newInstance(); 273 if (gen != null && 274 classDescriptor.equals(gen.getFcGeneratorParameters())) 275 { 276 return c; 277 } 278 } catch (Exception ignored) { 279 } 280 ++n; 281 } 282 } 283 284 288 292 293 private InputStream getInputStream (String file) throws IOException { 294 return new FileInputStream (file); 295 } 296 297 317 318 private Tree parseTree (final InputStream is) throws Exception { 319 try { 320 this.is = is; 321 read(); 322 parseSpaces(); 323 if (car == -1) { 324 return null; 325 } else { 326 return parseTree(); 327 } 328 } finally { 329 this.is = null; 330 } 331 } 332 333 344 345 private Tree parseTree () throws IOException , Exception { 346 int c = car; 347 if (c == -1) { 348 throw new Exception ("Unexpected end of file"); 349 } else if (c == ')') { 350 throw new Exception ("Unmatched closing parenthesis"); 351 } else if (c == '(') { 352 read(); 354 List subTrees = new ArrayList (); 355 while (true) { 356 c = parseSpaces(); 357 if (c == ')') { 358 read(); 359 return new Tree((Tree[])subTrees.toArray(new Tree[subTrees.size()])); 360 } else { 361 subTrees.add(parseTree()); 362 } 363 } 364 } else { 365 StringBuffer buf = new StringBuffer (); 367 while (true) { 368 buf.append((char)c); 369 c = read(); 370 if (c == -1 || c == ' ' || c == '\t' || c == '\n' || 371 c == '\r' || c == '#' || c == '(' || c == ')') 372 { 373 car = c; 374 return new Tree(buf.toString()); 375 } 376 } 377 } 378 } 379 380 387 388 private int parseSpaces () throws IOException { 389 int c = car; 390 while (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '#') { 391 if (c == '#') { 392 do { 394 c = read(); 395 } while (c != '\n' && c != '\r'); 396 } 397 c = read(); 398 } 399 return car = c; 400 } 401 402 408 409 private int read () throws IOException { 410 car = is.read(); 411 if (car == '\n' || car == '\r') { 412 ++line; 413 } 414 return car; 415 } 416 417 421 438 439 protected Class generateClass ( 440 final String name, 441 final Tree classDescriptor, 442 final Object loader) throws ClassNotFoundException 443 { 444 throw new ClassNotFoundException (name); 445 } 446 447 451 } 452 | Popular Tags |