KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > cs > drjava > model > repl > DynamicJavaAdapter


1 /*BEGIN_COPYRIGHT_BLOCK
2  *
3  * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/
4  * or http://sourceforge.net/projects/drjava/
5  *
6  * DrJava Open Source License
7  *
8  * Copyright (C) 2001-2005 JavaPLT group at Rice University (javaplt@rice.edu). All rights reserved.
9  *
10  * Developed by: Java Programming Languages Team, Rice University, http://www.cs.rice.edu/~javaplt/
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13  * documentation files (the "Software"), to deal with the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15  * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16  *
17  * - Redistributions of source code must retain the above copyright notice, this list of conditions and the
18  * following disclaimers.
19  * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
20  * following disclaimers in the documentation and/or other materials provided with the distribution.
21  * - Neither the names of DrJava, the JavaPLT, Rice University, nor the names of its contributors may be used to
22  * endorse or promote products derived from this Software without specific prior written permission.
23  * - Products derived from this software may not be called "DrJava" nor use the term "DrJava" as part of their
24  * names without prior written permission from the JavaPLT group. For permission, write to javaplt@rice.edu.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
27  * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
29  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30  * WITH THE SOFTWARE.
31  *
32 END_COPYRIGHT_BLOCK*/

33
34 package edu.rice.cs.drjava.model.repl;
35
36 import java.util.List JavaDoc;
37 import java.io.StringReader JavaDoc;
38 import java.io.Reader JavaDoc;
39 import java.net.URL JavaDoc;
40 import edu.rice.cs.drjava.model.repl.newjvm.ClassPathManager;
41 import koala.dynamicjava.interpreter.*;
42 import koala.dynamicjava.interpreter.context.*;
43 import koala.dynamicjava.interpreter.error.*;
44 import koala.dynamicjava.interpreter.throwable.*;
45 import koala.dynamicjava.parser.wrapper.*;
46 import koala.dynamicjava.tree.*;
47
48 import edu.rice.cs.util.classloader.StickyClassLoader;
49 import edu.rice.cs.util.*;
50
51 // NOTE: Do NOT import/use the config framework in this class!
52
// (This class runs in a different JVM, and will not share the config object)
53

54
55 /** An implementation of the interpreter for the repl pane.
56  *
57  * This class is loaded in the Interpreter JVM, not the Main JVM.
58  * (Do not use DrJava's config framework here.)
59  *
60  * @version $Id: DynamicJavaAdapter.java 4028 2006-11-07 00:21:48Z rcartwright $
61  */

62 public class DynamicJavaAdapter implements JavaInterpreter {
63   private static Log _log = new Log("MasterSlave.txt", false);
64   private InterpreterExtension _djInterpreter;
65
66   ClassPathManager cpm;
67   
68    /** Constructor */
69   public DynamicJavaAdapter(ClassPathManager c) {
70     cpm = c;
71     _djInterpreter = new InterpreterExtension(c);
72   }
73
74   /** Interprets a string as Java source.
75    * @param s the string to interpret
76    * @return the Object generated by the running of s
77    */

78   public Object JavaDoc interpret(String JavaDoc s) throws ExceptionReturnedException {
79     boolean print = false;
80     
81     /* Trims the whitespace from beginning and end of string
82      * Checks the end to see if it is a semicolon
83      * Adds a semicolon if necessary
84      */

85     s = s.trim();
86     if (!s.endsWith(";")) {
87       //s += ";";
88
print = true;
89     }
90
91     StringReader JavaDoc reader = new StringReader JavaDoc(s);
92     try {
93       Object JavaDoc result = _djInterpreter.interpret(reader, "DrJava");
94       if (print) return result;
95       else return JavaInterpreter.NO_RESULT;
96     }
97     catch (InterpreterException ie) {
98       Throwable JavaDoc cause = ie.getException();
99       if (cause instanceof ThrownException) cause = ((ThrownException) cause).getException();
100       else if (cause instanceof CatchedExceptionError) cause = ((CatchedExceptionError) cause).getException();
101
102       throw new ExceptionReturnedException(cause);
103     }
104     catch (CatchedExceptionError cee) {
105       throw new ExceptionReturnedException(cee.getException());
106     }
107     catch (InterpreterInterruptedException iie) {
108       return JavaInterpreter.NO_RESULT;
109     }
110     catch (ExitingNotAllowedException enae) {
111       return JavaInterpreter.NO_RESULT;
112     }
113 // catch (Throwable ie) {
114
// System.err.print(new Date() + ": ");
115
// System.err.println(ie);
116
// ie.printStackTrace();
117
// System.err.println("\n");
118
// throw new RuntimeException(ie.toString());
119
//
120
//// throw new ExceptionReturnedException(ie);
121
// }
122
}
123
124   public List JavaDoc<Node> parse(String JavaDoc input) { return _djInterpreter.parse(input); }
125
126   /** Adds a path to the current classpath.
127    * @param path the path to add
128    */

129 // public void addClassPath(String path) {
130
// //DrJava.consoleErr().println("Added class path: " + path);
131
// _djInterpreter.addClassPath(path);
132
// }
133

134   public void addProjectClassPath(URL JavaDoc path) { cpm.addProjectCP(path); }
135
136   public void addBuildDirectoryClassPath(URL JavaDoc path) { cpm.addBuildDirectoryCP(path); }
137
138   public void addProjectFilesClassPath(URL JavaDoc path) { cpm.addProjectFilesCP(path); }
139
140   public void addExternalFilesClassPath(URL JavaDoc path) { cpm.addExternalFilesCP(path); }
141   
142   public void addExtraClassPath(URL JavaDoc path) { cpm.addExtraCP(path); }
143   
144   /** Set the scope for unqualified names to the given package.
145    * @param packageName Package to assume scope of.
146    */

147   public void setPackageScope(String JavaDoc packageName) {
148     StringReader JavaDoc reader = new StringReader JavaDoc("package " + packageName + ";");
149     _djInterpreter.interpret(reader, "DrJava");
150   }
151
152   /** Returns the value of the variable with the given name in the interpreter.
153    * @param name Name of the variable
154    * @return Value of the variable
155    */

156   public Object JavaDoc getVariable(String JavaDoc name) { return _djInterpreter.getVariable(name); }
157
158   /** Returns the class of the variable with the given name in the interpreter.
159    * @param name Name of the variable
160    * @return class of the variable
161    */

162   public Class JavaDoc<?> getVariableClass(String JavaDoc name) { return _djInterpreter.getVariableClass(name); }
163
164   /** Assigns the given value to the given name in the interpreter. If type == null, we assume that the type of
165    * this variable has not been loaded so we set it to Object.
166    * @param name Name of the variable
167    * @param value Value to assign
168    * @param type the type of the variable
169    */

170   public void defineVariable(String JavaDoc name, Object JavaDoc value, Class JavaDoc<?> type) {
171     if (type == null) type = java.lang.Object JavaDoc.class;
172     ((TreeInterpreter)_djInterpreter).defineVariable(name, value, type);
173   }
174
175   /** Assigns the given value to the given name in the interpreter.
176    * @param name Name of the variable
177    * @param value Value to assign
178    */

179   public void defineVariable(String JavaDoc name, Object JavaDoc value) {
180     ((TreeInterpreter)_djInterpreter).defineVariable(name, value);
181   }
182
183   /** Assigns the given value to the given name in the interpreter.
184    * @param name Name of the variable
185    * @param value boolean to assign
186    */

187   public void defineVariable(String JavaDoc name, boolean value) {
188     ((TreeInterpreter)_djInterpreter).defineVariable(name, value);
189   }
190
191   /** Assigns the given value to the given name in the interpreter.
192    * @param name Name of the variable
193    * @param value byte to assign
194    */

195   public void defineVariable(String JavaDoc name, byte value) {
196     ((TreeInterpreter)_djInterpreter).defineVariable(name, value);
197   }
198
199   /** Assigns the given value to the given name in the interpreter.
200    * @param name Name of the variable
201    * @param value char to assign
202    */

203   public void defineVariable(String JavaDoc name, char value) {
204     ((TreeInterpreter)_djInterpreter).defineVariable(name, value);
205   }
206
207   /** Assigns the given value to the given name in the interpreter.
208    * @param name Name of the variable
209    * @param value double to assign
210    */

211   public void defineVariable(String JavaDoc name, double value) {
212     ((TreeInterpreter)_djInterpreter).defineVariable(name, value);
213   }
214
215   /** Assigns the given value to the given name in the interpreter.
216    * @param name Name of the variable
217    * @param value float to assign
218    */

219   public void defineVariable(String JavaDoc name, float value) {
220     ((TreeInterpreter)_djInterpreter).defineVariable(name, value);
221   }
222
223
224   /** Assigns the given value to the given name in the interpreter.
225    * @param name Name of the variable
226    * @param value int to assign
227    */

228   public void defineVariable(String JavaDoc name, int value) {
229     ((TreeInterpreter)_djInterpreter).defineVariable(name, value);
230   }
231
232   /** Assigns the given value to the given name in the interpreter.
233    * @param name Name of the variable
234    * @param value long to assign
235    */

236   public void defineVariable(String JavaDoc name, long value) {
237     ((TreeInterpreter)_djInterpreter).defineVariable(name, value);
238   }
239
240   /** Assigns the given value to the given name in the interpreter.
241    * @param name Name of the variable
242    * @param value short to assign
243    */

244   public void defineVariable(String JavaDoc name, short value) {
245     ((TreeInterpreter)_djInterpreter).defineVariable(name, value);
246   }
247
248   /** Assigns the given value to the given name in the interpreter.
249    * @param name Name of the variable
250    * @param value Value to assign
251    */

252   public void defineConstant(String JavaDoc name, Object JavaDoc value) {
253     _djInterpreter.defineConstant(name, value);
254   }
255
256   /** Assigns the given value to the given name as a constant in the interpreter.
257    * @param name Name of the variable
258    * @param value boolean to assign
259    */

260   public void defineConstant(String JavaDoc name, boolean value) {
261     _djInterpreter.defineConstant(name, value);
262   }
263
264   /** Assigns the given value to the given name as a constant in the interpreter.
265    * @param name Name of the variable
266    * @param value byte to assign
267    */

268   public void defineConstant(String JavaDoc name, byte value) {
269     _djInterpreter.defineConstant(name, value);
270   }
271
272   /** Assigns the given value to the given name as a constant in the interpreter.
273    * @param name Name of the variable
274    * @param value char to assign
275    */

276   public void defineConstant(String JavaDoc name, char value) {
277     _djInterpreter.defineConstant(name, value);
278   }
279
280   /** Assigns the given value to the given name as a constant in the interpreter.
281    * @param name Name of the variable
282    * @param value double to assign
283    */

284   public void defineConstant(String JavaDoc name, double value) {
285     _djInterpreter.defineConstant(name, value);
286   }
287
288   /** Assigns the given value to the given name as a constant in the interpreter.
289    * @param name Name of the variable
290    * @param value float to assign
291    */

292   public void defineConstant(String JavaDoc name, float value) {
293     _djInterpreter.defineConstant(name, value);
294   }
295
296   /** Assigns the given value to the given name as a constant in the interpreter.
297    * @param name Name of the variable
298    * @param value int to assign
299    */

300   public void defineConstant(String JavaDoc name, int value) {
301     _djInterpreter.defineConstant(name, value);
302   }
303
304   /** Assigns the given value to the given name as a constant in the interpreter.
305    * @param name Name of the variable
306    * @param value long to assign
307    */

308   public void defineConstant(String JavaDoc name, long value) {
309     _djInterpreter.defineConstant(name, value);
310   }
311   /** Assigns the given value to the given name as a constant in the interpreter.
312    * @param name Name of the variable
313    * @param value short to assign
314    */

315   public void defineConstant(String JavaDoc name, short value) {
316     _djInterpreter.defineConstant(name, value);
317   }
318
319   /** Sets whether protected and private variables should be accessible in the interpreter.
320    * @param accessible Whether protected and private variable are accessible
321    */

322   public void setPrivateAccessible(boolean accessible) {
323     _djInterpreter.setAccessible(accessible);
324   }
325
326   /** Gets whether protected and private variables should be accessible in the interpreter. */
327   public boolean getPrivateAccessible() { return _djInterpreter.getAccessible(); }
328   
329   /** Factory method to make a new NameVisitor.
330    * @param nameContext the context
331    * @return visitor the visitor
332    */

333   public NameVisitor makeNameVisitor(Context nameContext) { return new NameVisitor(nameContext); }
334
335   /** Factory method to make a new TypeChecker.
336    * @param nameContext Context for the NameVisitor
337    * @param typeContext Context being used for the TypeChecker. This is necessary because we want to perform partial
338    * type checking for the right hand side of a VariableDeclaration.
339    * @return visitor the visitor
340    */

341 // public AbstractTypeChecker makeTypeChecker(Context context) {
342
// // TO DO: move this into its own class if more methods need to be added
343
// return AbstractTypeChecker.makeTypeChecker(context);
344
// }
345
// Removed because AbstractTypeChecker contains a makeTypeChecker method
346

347   /** Factory method to make a new EvaluationVisitor.
348    * @param context the context
349    * @return visitor the visitor
350    */

351   public EvaluationVisitor makeEvaluationVisitor(Context context) {
352     return new EvaluationVisitorExtension(context);
353   }
354
355   /** Processes the tree before evaluating it, if necessary.
356    * @param node Tree to process
357    */

358   public Node processTree(Node node) { return node; }
359
360   public GlobalContext makeGlobalContext(TreeInterpreter i) { return new GlobalContext(i); }
361
362   /** An extension of DynamicJava's interpreter that makes sure classes are not loaded by the system class loader
363    * (when possible) so that future interpreters will be able to reload the classes. This extension also ensures
364    * that classes on "extra.classpath" will be loaded if referenced by user defined classes. (Without this, classes
365    * on "extra.classpath" can only be referred to directly, and cannot be extended, etc.) <p>
366    * We also override the evaluation visitor to allow the interpreter to be interrupted and to return NO_RESULT if
367    * there was no result.
368    */

369   public class InterpreterExtension extends TreeInterpreter {
370
371     /** Only constructor. */
372     public InterpreterExtension(ClassPathManager cpm) {
373       super(new JavaCCParserFactory());
374
375       classLoader = new ClassLoaderExtension(this, cpm);
376       // We have to reinitialize these variables because they automatically
377
// fetch pointers to classLoader in their constructors.
378
nameVisitorContext = makeGlobalContext(this);
379       ClassLoaderContainer clc = new ClassLoaderContainer() {
380         public ClassLoader JavaDoc getClassLoader() { return classLoader; }
381       };
382       nameVisitorContext.setAdditionalClassLoaderContainer(clc);
383       checkVisitorContext = makeGlobalContext(this);
384       checkVisitorContext.setAdditionalClassLoaderContainer(clc);
385       evalVisitorContext = makeGlobalContext(this);
386       evalVisitorContext.setAdditionalClassLoaderContainer(clc);
387       //System.err.println("set loader: " + classLoader);
388

389     }
390
391     /** Extends the interpret method to deal with possible interrupted exceptions.
392      * Unfortunately we have to copy all of this method to override it.
393      * @param r the reader from which the statements are read
394      * @param fname the name of the parsed stream
395      * @return the result of the evaluation of the last statement
396      */

397     public Object JavaDoc interpret(Reader JavaDoc r, String JavaDoc fname) throws InterpreterException {
398       List JavaDoc<Node> statements;
399       try {
400         SourceCodeParser p = parserFactory.createParser(r, fname);
401         statements = p.parseStream();
402 // Utilities.showDebug("Interpreting: " + statements);
403
}
404       catch (ParseError e) {
405         //throw new InteractionsException("There was a syntax error in the " +
406
// "previous input.");
407
throw new InterpreterException(e);
408       }
409       
410       Object JavaDoc result = JavaInterpreter.NO_RESULT;
411       
412       nameVisitorContext.setRevertPoint();
413       checkVisitorContext.setRevertPoint();
414       evalVisitorContext.setRevertPoint();
415       
416       try {
417         for (Node n : statements) {
418           n = processTree(n);
419           
420           NameVisitor nv = makeNameVisitor(nameVisitorContext);
421           Node o = n.acceptVisitor(nv);
422           if (o != null) n = o;
423           
424           AbstractTypeChecker tc = AbstractTypeChecker.makeTypeChecker(checkVisitorContext);
425           
426           n.acceptVisitor(tc);
427           
428           evalVisitorContext.defineVariables(checkVisitorContext.getCurrentScopeVariables());
429           
430           EvaluationVisitor ev = makeEvaluationVisitor(evalVisitorContext);
431           _log.log("Ready to interpret " + ev);
432           result = n.acceptVisitor(ev);
433           _log.log("Interpreted result is: " + result);
434         }
435       }
436       catch (ExecutionError e) {
437         // revert the contexts just in case a binding was made in
438
// one context before this error was thrown.
439
nameVisitorContext.revert();
440         checkVisitorContext.revert();
441         evalVisitorContext.revert();
442         
443         //e.printStackTrace(); // For Loop....
444
throw new InterpreterException(e);
445       }
446       
447       if (result instanceof String JavaDoc) return "\"" + result + "\"";
448       if (result instanceof Character JavaDoc) return "'" + result + "'";
449       return result;
450     }
451     
452     /**
453      * Assigns the given value to the given name in the interpreter.
454      * @param name Name of the variable
455      * @param value Value to assign
456      */

457     public void defineConstant(String JavaDoc name, Object JavaDoc value) {
458       Class JavaDoc<?> c = (value == null) ? null : value.getClass();
459       nameVisitorContext.defineConstant(name, c);
460       checkVisitorContext.defineConstant(name, c);
461       evalVisitorContext.defineConstant(name, value);
462     }
463
464     /** Assigns the given value to the given name as a constant in the interpreter.
465      * @param name Name of the variable
466      * @param value boolean to assign
467      */

468     public void defineConstant(String JavaDoc name, boolean value) {
469       Class JavaDoc<?> c = boolean.class;
470       nameVisitorContext.defineConstant(name, c);
471       checkVisitorContext.defineConstant(name, c);
472       evalVisitorContext.defineConstant(name, Boolean.valueOf(value));
473     }
474
475     /** Assigns the given value to the given name as a constant in the interpreter.
476      * @param name Name of the variable
477      * @param value byte to assign
478      */

479     public void defineConstant(String JavaDoc name, byte value) {
480       Class JavaDoc<?> c = byte.class;
481       nameVisitorContext.defineConstant(name, c);
482       checkVisitorContext.defineConstant(name, c);
483       evalVisitorContext.defineConstant(name, new Byte JavaDoc(value));
484     }
485
486     /** Assigns the given value to the given name as a constant in the interpreter.
487      * @param name Name of the variable
488      * @param value char to assign
489      */

490     public void defineConstant(String JavaDoc name, char value) {
491       Class JavaDoc<?> c = char.class;
492       nameVisitorContext.defineConstant(name, c);
493       checkVisitorContext.defineConstant(name, c);
494       evalVisitorContext.defineConstant(name, new Character JavaDoc(value));
495     }
496
497     /** Assigns the given value to the given name as a constant in the interpreter.
498      * @param name Name of the variable
499      * @param value double to assign
500      */

501     public void defineConstant(String JavaDoc name, double value) {
502       Class JavaDoc<?> c = double.class;
503       nameVisitorContext.defineConstant(name, c);
504       checkVisitorContext.defineConstant(name, c);
505       evalVisitorContext.defineConstant(name, new Double JavaDoc(value));
506     }
507
508     /** Assigns the given value to the given name as a constant in the interpreter.
509      * @param name Name of the variable
510      * @param value float to assign
511      */

512     public void defineConstant(String JavaDoc name, float value) {
513       Class JavaDoc<?> c = float.class;
514       nameVisitorContext.defineConstant(name, c);
515       checkVisitorContext.defineConstant(name, c);
516       evalVisitorContext.defineConstant(name, new Float JavaDoc(value));
517     }
518
519     /** Assigns the given value to the given name as a constant in the interpreter.
520      * @param name Name of the variable
521      * @param value int to assign
522      */

523     public void defineConstant(String JavaDoc name, int value) {
524       Class JavaDoc<?> c = int.class;
525       nameVisitorContext.defineConstant(name, c);
526       checkVisitorContext.defineConstant(name, c);
527       evalVisitorContext.defineConstant(name, new Integer JavaDoc(value));
528     }
529
530     /** Assigns the given value to the given name as a constant in the interpreter.
531      * @param name Name of the variable
532      * @param value long to assign
533      */

534     public void defineConstant(String JavaDoc name, long value) {
535       Class JavaDoc<?> c = long.class;
536       nameVisitorContext.defineConstant(name, c);
537       checkVisitorContext.defineConstant(name, c);
538       evalVisitorContext.defineConstant(name, new Long JavaDoc(value));
539     }
540     
541     /** Assigns the given value to the given name as a constant in the interpreter.
542      * @param name Name of the variable
543      * @param value short to assign
544      */

545     public void defineConstant(String JavaDoc name, short value) {
546       Class JavaDoc<?> c = short.class;
547       nameVisitorContext.defineConstant(name, c);
548       checkVisitorContext.defineConstant(name, c);
549       evalVisitorContext.defineConstant(name, new Short JavaDoc(value));
550     }
551   }
552
553   /** A class loader for the interpreter. */
554   public static class ClassLoaderExtension extends TreeClassLoader {
555     
556     // the classpath is augmented by calling addURL(URL url) on this class
557
// this will update the classloader variable to contain the new classpath entry
558

559   private static boolean classLoaderCreated = false;
560   
561   private static StickyClassLoader _stickyLoader;
562   
563   // manages the classpath for the interpreter
564
ClassPathManager cpm;
565   
566   /** Constructor.
567    * @param i the object used to interpret the classes
568    */

569   public ClassLoaderExtension(koala.dynamicjava.interpreter.Interpreter i, ClassPathManager c) {
570     super(i);
571     cpm = c;
572     // The protected variable classLoader contains the class loader to use
573
// to find classes. When a new class path is added to the loader,
574
// it adds on an auxilary classloader and chains the old classLoader
575
// onto the end.
576
// Here we initialize classLoader to be the system class loader, and wrap it to not load edu.rice.cs classes
577
classLoader = new WrapperClassLoader(getClass().getClassLoader()); // classLoader is only used in getResource()
578
// NOTE that the superclass of ClassLoaderExtension (TreeClassLoader) adds (appends)
579
// URLs to the classpath of this classloader
580

581     // don't load the dynamic java stuff using the sticky loader!
582
// without this, interpreter-defined classes don't work.
583
String JavaDoc[] excludes = {
584       "edu.rice.cs.drjava.model.repl.DynamicJavaAdapter$InterpreterExtension",
585       "edu.rice.cs.drjava.model.repl.DynamicJavaAdapter$ClassLoaderExtension"
586     };
587     
588     if (!classLoaderCreated) {
589       _stickyLoader = new StickyClassLoader(this, // Sticky's newLoader, indirectly points to the (dynamic) classLoader
590
classLoader, // Sticky's oldLoader
591
excludes);
592       classLoaderCreated = true;
593     }
594     
595     // we will use this to getResource classes
596
}
597   
598   /** Delegates all resource requests to {@link #classLoader} (the system class loader by default).
599    * This method is called by the {@link StickyClassLoader}.
600    */

601   public URL JavaDoc getResource(String JavaDoc name) {
602     // use the cpm to get the resource for the specified name
603
return cpm.getClassLoader().getResource(name);
604     //return classLoader.getResource(name);
605
}
606   
607   protected Class JavaDoc<?> loadClass(String JavaDoc name, boolean resolve) throws ClassNotFoundException JavaDoc{
608     Class JavaDoc<?> clazz;
609     
610     // check the cache
611
if (classes.containsKey(name)) clazz = (Class JavaDoc<?>) classes.get(name);
612     else {
613       try {
614         clazz = _stickyLoader.loadClass(name);
615       }
616       catch (ClassNotFoundException JavaDoc e) {
617         // If it exceptions, just fall through to here to try the interpreter.
618
// If all else fails, try loading the class through the interpreter.
619
// That's used for classes defined in the interpreter.
620
clazz = interpreter.loadClass(name);
621       }
622     }
623     
624     if (resolve) resolveClass(clazz);
625     
626     return clazz;
627   }
628   
629   
630 // /** Adds a URL to the class path. DynamicJava's version of this creates a
631
// * new URLClassLoader with the given URL, using the old loader as a parent.
632
// * This seems to cause problems for us in certain cases, such as accessing
633
// * static fields or methods in a class that extends a superclass which is
634
// * loaded by "child" classloader...
635
// *
636
// * Instead, we'll replace the old URLClassLoader with a new one containing
637
// * all the known URLs.
638
// *
639
// * (I don't know if this really works yet, so I'm not including it in
640
// * the current release. CSR, 3-13-2003)
641
// */
642
// public void addURL(URL url) {
643
// if (classLoader == null) {
644
// classLoader = new URLClassLoader(new URL[] { url });
645
// }
646
// else if (classLoader instanceof URLClassLoader) {
647
// URL[] oldURLs = ((URLClassLoader)classLoader).getURLs();
648
// URL[] newURLs = new URL[oldURLs.length + 1];
649
// System.arraycopy(oldURLs, 0, newURLs, 0, oldURLs.length);
650
// newURLs[oldURLs.length] = url;
651
//
652
// // Create a new class loader with all the URLs
653
// classLoader = new URLClassLoader(newURLs);
654
// }
655
// else {
656
// classLoader = new URLClassLoader(new URL[] { url }, classLoader);
657
// }
658
// }
659

660 // public Class defineClass(String name, byte[] code) {
661
// File file = new File("debug-" + name + ".class");
662
//
663
// try {
664
// FileOutputStream out = new FileOutputStream(file);
665
// out.write(code);
666
// out.close();
667
// DrJava.consoleErr().println("debug class " + name + " to " + file.getAbsolutePath());
668
// }
669
// catch (Throwable t) { }
670
//
671
// Class c = super.defineClass(name, code);
672
// return c;
673
// }
674

675   }
676 }
677
Popular Tags