1 33 34 package bsh.classpath; 35 36 import java.net.*; 37 import java.util.*; 38 import java.lang.ref.*; 39 import java.io.IOException ; 40 import java.io.*; 41 import bsh.classpath.BshClassPath.ClassSource; 42 import bsh.classpath.BshClassPath.JarClassSource; 43 import bsh.classpath.BshClassPath.GeneratedClassSource; 44 import bsh.BshClassManager; 45 import bsh.ClassPathException; 46 import bsh.Interpreter; import bsh.UtilEvalError; 48 49 95 public class ClassManagerImpl extends BshClassManager 96 { 97 static final String BSH_PACKAGE = "bsh"; 98 105 private BshClassPath baseClassPath; 106 private boolean superImport; 107 108 120 private BshClassPath fullClassPath; 121 122 private Vector listeners = new Vector(); 124 private ReferenceQueue refQueue = new ReferenceQueue(); 125 126 132 private BshClassLoader baseLoader; 133 134 137 private Map loaderMap; 138 139 142 public ClassManagerImpl() { 143 reset(); 144 } 145 146 149 public Class classForName( String name ) 150 { 151 Class c = (Class )absoluteClassCache.get(name); 153 if (c != null ) 154 return c; 155 156 if ( absoluteNonClasses.get(name)!=null ) { 158 if ( Interpreter.DEBUG ) 159 Interpreter.debug("absoluteNonClass list hit: "+name); 160 return null; 161 } 162 163 if ( Interpreter.DEBUG ) 164 Interpreter.debug("Trying to load class: "+name); 165 166 ClassLoader overlayLoader = getLoaderForClass( name ); 168 if ( overlayLoader != null ) 169 { 170 try { 171 c = overlayLoader.loadClass(name); 172 } catch ( Exception e ) { 173 } catch ( NoClassDefFoundError e2 ) { 176 throw noClassDefFound( name, e2 ); 177 } 178 179 } 182 183 if ( c == null ) { 185 if ( name.startsWith( BSH_PACKAGE ) ) 186 try { 187 c = Interpreter.class.getClassLoader().loadClass( name ); 188 } catch ( ClassNotFoundException e ) {} 189 } 190 191 if ( c == null ) { 193 if ( baseLoader != null ) 194 try { 195 c = baseLoader.loadClass( name ); 196 } catch ( ClassNotFoundException e ) {} 197 } 198 199 if ( c == null ) { 201 if ( externalClassLoader != null ) 202 try { 203 c = externalClassLoader.loadClass( name ); 204 } catch ( ClassNotFoundException e ) {} 205 } 206 207 if ( c == null ) 212 { 213 try { 214 ClassLoader contextClassLoader = 215 Thread.currentThread().getContextClassLoader(); 216 if ( contextClassLoader != null ) 217 c = Class.forName( name, true, contextClassLoader ); 218 } catch ( ClassNotFoundException e ) { } catch ( SecurityException e ) { } } 221 222 if ( c == null ) 224 try { 225 c = plainClassForName( name ); 226 } catch ( ClassNotFoundException e ) {} 227 228 if ( c == null ) 230 c = loadSourceClass( name ); 231 232 cacheClassInfo( name, c ); 236 237 return c; 238 } 239 240 244 public URL getResource( String path ) 245 { 246 URL url = null; 247 if ( baseLoader != null ) 248 url = baseLoader.getResource( path.substring(1) ); 250 if ( url == null ) 251 url = super.getResource( path ); 252 return url; 253 } 254 255 259 public InputStream getResourceAsStream( String path ) 260 { 261 InputStream in = null; 262 if ( baseLoader != null ) 263 { 264 in = baseLoader.getResourceAsStream( path.substring(1) ); 266 } 267 if ( in == null ) 268 { 269 in = super.getResourceAsStream( path ); 270 } 271 return in; 272 } 273 274 ClassLoader getLoaderForClass( String name ) { 275 return (ClassLoader )loaderMap.get( name ); 276 } 277 278 280 282 public void addClassPath( URL path ) 283 throws IOException 284 { 285 if ( baseLoader == null ) 286 setClassPath( new URL [] { path } ); 287 else { 288 baseLoader.addURL( path ); 290 baseClassPath.add( path ); 291 classLoaderChanged(); 292 } 293 } 294 295 299 public void reset() 300 { 301 baseClassPath = new BshClassPath("baseClassPath"); 302 baseLoader = null; 303 loaderMap = new HashMap(); 304 classLoaderChanged(); } 306 307 311 public void setClassPath( URL [] cp ) { 312 baseClassPath.setPath( cp ); 313 initBaseLoader(); 314 loaderMap = new HashMap(); 315 classLoaderChanged(); 316 } 317 318 324 public void reloadAllClasses() throws ClassPathException 325 { 326 BshClassPath bcp = new BshClassPath("temp"); 327 bcp.addComponent( baseClassPath ); 328 bcp.addComponent( BshClassPath.getUserClassPath() ); 329 setClassPath( bcp.getPathComponents() ); 330 } 331 332 335 private void initBaseLoader() { 336 baseLoader = new BshClassLoader( this, baseClassPath ); 337 } 338 339 341 346 public void reloadClasses( String [] classNames ) 347 throws ClassPathException 348 { 349 351 if ( baseLoader == null ) 353 initBaseLoader(); 354 355 DiscreteFilesClassLoader.ClassSourceMap map = 356 new DiscreteFilesClassLoader.ClassSourceMap(); 357 358 for (int i=0; i< classNames.length; i++) { 359 String name = classNames[i]; 360 361 ClassSource classSource = baseClassPath.getClassSource( name ); 363 364 if ( classSource == null ) { 366 BshClassPath.getUserClassPath().insureInitialized(); 367 classSource = BshClassPath.getUserClassPath().getClassSource( 368 name ); 369 } 370 371 374 if ( classSource == null ) 375 throw new ClassPathException("Nothing known about class: " 376 +name ); 377 378 if ( classSource instanceof JarClassSource ) 382 throw new ClassPathException("Cannot reload class: "+name+ 383 " from source: "+ classSource ); 384 385 map.put( name, classSource ); 386 } 387 388 ClassLoader cl = new DiscreteFilesClassLoader( this, map ); 390 391 Iterator it = map.keySet().iterator(); 393 while ( it.hasNext() ) 394 loaderMap.put( (String )it.next(), cl ); 395 396 classLoaderChanged(); 397 } 398 399 405 public void reloadPackage( String pack ) 406 throws ClassPathException 407 { 408 Collection classes = 409 baseClassPath.getClassesForPackage( pack ); 410 411 if ( classes == null ) 412 classes = 413 BshClassPath.getUserClassPath().getClassesForPackage( pack ); 414 415 417 if ( classes == null ) 418 throw new ClassPathException("No classes found for package: "+pack); 419 420 reloadClasses( (String [])classes.toArray( new String [0] ) ); 421 } 422 423 431 432 434 437 public BshClassPath getClassPath() throws ClassPathException 438 { 439 if ( fullClassPath != null ) 440 return fullClassPath; 441 442 fullClassPath = new BshClassPath("BeanShell Full Class Path"); 443 fullClassPath.addComponent( BshClassPath.getUserClassPath() ); 444 try { 445 fullClassPath.addComponent( BshClassPath.getBootClassPath() ); 446 } catch ( ClassPathException e ) { 447 System.err.println("Warning: can't get boot class path"); 448 } 449 fullClassPath.addComponent( baseClassPath ); 450 451 return fullClassPath; 452 } 453 454 458 public void doSuperImport() 459 throws UtilEvalError 460 { 461 463 try { 464 getClassPath().insureInitialized(); 465 getClassNameByUnqName( "" ) ; 467 468 471 } catch ( ClassPathException e ) { 472 throw new UtilEvalError("Error importing classpath "+ e ); 473 } 474 475 superImport = true; 476 } 477 478 protected boolean hasSuperImport() { return superImport; } 479 480 484 public String getClassNameByUnqName( String name ) 485 throws ClassPathException 486 { 487 return getClassPath().getClassNameByUnqName( name ); 488 } 489 490 public void addListener( Listener l ) { 491 listeners.addElement( new WeakReference( l, refQueue) ); 492 493 Reference deadref; 495 while ( (deadref = refQueue.poll()) != null ) { 496 boolean ok = listeners.removeElement( deadref ); 497 if ( ok ) { 498 } else { 500 if ( Interpreter.DEBUG ) Interpreter.debug( 501 "tried to remove non-existent weak ref: "+deadref); 502 } 503 } 504 } 505 506 public void removeListener( Listener l ) { 507 throw new Error ("unimplemented"); 508 } 509 510 public ClassLoader getBaseLoader() { 511 return baseLoader; 512 } 513 514 519 520 528 public Class defineClass( String name, byte [] code ) 529 { 530 baseClassPath.setClassSource( name, new GeneratedClassSource( code ) ); 531 try { 532 reloadClasses( new String [] { name } ); 533 } catch ( ClassPathException e ) { 534 throw new bsh.InterpreterError("defineClass: "+e); 535 } 536 return classForName( name ); 537 } 538 539 546 protected void classLoaderChanged() 547 { 548 clearCaches(); 550 551 Vector toRemove = new Vector(); for ( Enumeration e = listeners.elements(); e.hasMoreElements(); ) 553 { 554 WeakReference wr = (WeakReference)e.nextElement(); 555 Listener l = (Listener)wr.get(); 556 if ( l == null ) toRemove.add( wr ); 558 else 559 l.classLoaderChanged(); 560 } 561 for( Enumeration e = toRemove.elements(); e.hasMoreElements(); ) 562 listeners.removeElement( e.nextElement() ); 563 } 564 565 public void dump( PrintWriter i ) 566 { 567 i.println("Bsh Class Manager Dump: "); 568 i.println("----------------------- "); 569 i.println("baseLoader = "+baseLoader); 570 i.println("loaderMap= "+loaderMap); 571 i.println("----------------------- "); 572 i.println("baseClassPath = "+baseClassPath); 573 } 574 575 } 576 | Popular Tags |