1 11 12 package org.eclipse.osgi.baseadaptor.loader; 13 14 import java.io.*; 15 import java.net.URL ; 16 import java.security.ProtectionDomain ; 17 import java.util.*; 18 import org.eclipse.osgi.baseadaptor.BaseData; 19 import org.eclipse.osgi.baseadaptor.bundlefile.*; 20 import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook; 21 import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingStatsHook; 22 import org.eclipse.osgi.framework.adaptor.BundleData; 23 import org.eclipse.osgi.framework.debug.Debug; 24 import org.eclipse.osgi.internal.baseadaptor.AdaptorMsg; 25 import org.eclipse.osgi.util.NLS; 26 import org.osgi.framework.BundleException; 27 import org.osgi.framework.FrameworkEvent; 28 29 40 public class ClasspathManager { 41 private static final FragmentClasspath[] emptyFragments = new FragmentClasspath[0]; 42 43 private BaseData data; 44 private String [] classpath; 45 private ClasspathEntry[] entries; 46 private BaseClassLoader classloader; 47 private FragmentClasspath[] fragments = emptyFragments; 48 private Collection loadedLibraries = null; 50 51 57 public ClasspathManager(BaseData data, String [] classpath, BaseClassLoader classloader) { 58 this.data = data; 59 this.classpath = classpath; 60 this.classloader = classloader; 61 } 62 63 71 public void initialize() { 72 entries = buildClasspath(classpath, this, data, classloader.getDomain()); 73 ClassLoadingHook[] hooks = data.getAdaptor().getHookRegistry().getClassLoadingHooks(); 74 for (int i = 0; i < hooks.length; i++) 75 hooks[i].initializedClassLoader(classloader, data); 76 } 77 78 82 public void close() { 83 if (entries != null) { 84 for (int i = 0; i < entries.length; i++) { 85 if (entries[i] != null) { 86 try { 87 entries[i].getBundleFile().close(); 88 } catch (IOException e) { 89 data.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, data.getBundle(), e); 90 } 91 } 92 } 93 } 94 for (int i = 0; i < fragments.length; i++) 95 fragments[i].close(); 96 } 97 98 104 public void attachFragment(BundleData sourcedata, ProtectionDomain sourcedomain, String [] sourceclasspath) { 105 try { 106 sourcedata.open(); 107 } catch (IOException e) { 108 ((BaseData) sourcedata).getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, ((BaseData) sourcedata).getBundle(), e); 109 } 110 ClasspathEntry[] fragEntries = buildClasspath(sourceclasspath, this, (BaseData) sourcedata, sourcedomain); 111 FragmentClasspath fragClasspath = new FragmentClasspath((BaseData) sourcedata, fragEntries, sourcedomain); 112 insertFragment(fragClasspath); 113 } 114 115 private synchronized void insertFragment(FragmentClasspath fragClasspath) { 116 FragmentClasspath[] newFragments = new FragmentClasspath[fragments.length + 1]; 117 long fragID = fragClasspath.getBundleData().getBundleID(); 119 int insert = 0; 120 for (int i = 0; i < fragments.length; i++) { 121 long otherID = fragments[i].getBundleData().getBundleID(); 122 if (insert == 0 && fragID < otherID) { 123 newFragments[i] = fragClasspath; 124 insert = 1; 125 } 126 newFragments[i + insert] = fragments[i]; 127 } 128 if (insert == 0) 130 newFragments[fragments.length] = fragClasspath; 131 fragments = newFragments; 132 } 133 134 private static ClasspathEntry[] buildClasspath(String [] cp, ClasspathManager hostloader, BaseData sourcedata, ProtectionDomain sourcedomain) { 135 ArrayList result = new ArrayList(cp.length); 136 for (int i = 0; i < cp.length; i++) 138 findClassPathEntry(result, cp[i], hostloader, sourcedata, sourcedomain); 139 return (ClasspathEntry[]) result.toArray(new ClasspathEntry[result.size()]); 140 } 141 142 154 public static void findClassPathEntry(ArrayList result, String cp, ClasspathManager hostloader, BaseData sourcedata, ProtectionDomain sourcedomain) { 155 ClassLoadingHook[] loaderHooks = sourcedata.getAdaptor().getHookRegistry().getClassLoadingHooks(); 157 boolean hookAdded = false; 158 for (int i = 0; i < loaderHooks.length; i++) 159 hookAdded |= loaderHooks[i].addClassPathEntry(result, cp, hostloader, sourcedata, sourcedomain); 160 if (!addClassPathEntry(result, cp, hostloader, sourcedata, sourcedomain) && !hookAdded) { 161 BundleException be = new BundleException(NLS.bind(AdaptorMsg.BUNDLE_CLASSPATH_ENTRY_NOT_FOUND_EXCEPTION, cp, sourcedata.getLocation())); 162 sourcedata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.INFO, sourcedata.getBundle(), be); 163 } 164 } 165 166 177 public static boolean addClassPathEntry(ArrayList result, String cp, ClasspathManager hostloader, BaseData sourcedata, ProtectionDomain sourcedomain) { 178 if (cp.equals(".")) { result.add(hostloader.createClassPathEntry(sourcedata.getBundleFile(), sourcedomain)); 180 return true; 181 } 182 Object element = hostloader.getClasspath(cp, sourcedata, sourcedomain); 183 if (element != null) { 184 result.add(element); 185 return true; 186 } 187 if (hostloader.data == sourcedata) 190 for (int i = 0; i < hostloader.fragments.length; i++) { 191 FragmentClasspath fragCP = hostloader.fragments[i]; 192 element = hostloader.getClasspath(cp, fragCP.getBundleData(), fragCP.getDomain()); 193 if (element != null) { 194 result.add(element); 195 return true; 196 } 197 } 198 return false; 199 } 200 201 208 public ClasspathEntry getClasspath(String cp, BaseData sourcedata, ProtectionDomain sourcedomain) { 209 BundleFile bundlefile = null; 210 File file; 211 BundleEntry cpEntry = sourcedata.getBundleFile().getEntry(cp); 212 if (cpEntry != null && cpEntry.getName().endsWith("/")) bundlefile = createBundleFile(cp, sourcedata); 215 else if ((file = sourcedata.getBundleFile().getFile(cp, false)) != null) 217 bundlefile = createBundleFile(file, sourcedata); 218 if (bundlefile != null) 219 return createClassPathEntry(bundlefile, sourcedomain); 220 return null; 221 } 222 223 230 public ClasspathEntry getExternalClassPath(String cp, BaseData sourcedata, ProtectionDomain sourcedomain) { 231 File file = new File(cp); 232 if (!file.isAbsolute()) 233 return null; 234 BundleFile bundlefile = createBundleFile(file, sourcedata); 235 if (bundlefile != null) 236 return createClassPathEntry(bundlefile, sourcedomain); 237 return null; 238 } 239 240 private static BundleFile createBundleFile(Object content, BaseData sourcedata) { 241 if (content == null || (content instanceof File && !((File) content).exists())) 242 return null; 243 try { 244 return sourcedata.getAdaptor().createBundleFile(content, sourcedata); 245 } catch (IOException e) { 246 sourcedata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, sourcedata.getBundle(), e); 247 } 248 return null; 249 } 250 251 private ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain cpDomain) { 252 return classloader.createClassPathEntry(bundlefile, cpDomain); 253 } 254 255 264 public URL findLocalResource(String resource) { 265 ClassLoadingStatsHook[] hooks = data.getAdaptor().getHookRegistry().getClassLoadingStatsHooks(); 266 for (int i = 0; i < hooks.length; i++) 267 hooks[i].preFindLocalResource(resource, this); 268 URL result = null; 269 try { 270 result = findLocalResourceImpl(resource); 271 return result; 272 } finally { 273 for (int i = 0; i < hooks.length; i++) 274 hooks[i].postFindLocalResource(resource, result, this); 275 } 276 } 277 278 private URL findLocalResourceImpl(String resource) { 279 URL result = null; 280 for (int i = 0; i < entries.length; i++) { 281 if (entries[i] != null) { 282 result = findResourceImpl(resource, entries[i].getBundleFile()); 283 if (result != null) 284 return result; 285 } 286 } 287 for (int i = 0; i < fragments.length; i++) { 289 ClasspathEntry[] fragEntries = fragments[i].getEntries(); 290 for (int j = 0; j < fragEntries.length; j++) { 291 result = findResourceImpl(resource, fragEntries[j].getBundleFile()); 292 if (result != null) 293 return result; 294 } 295 } 296 return null; 297 } 298 299 304 public Enumeration findLocalResources(String resource) { 305 Vector resources = new Vector(6); for (int i = 0; i < entries.length; i++) { 307 if (entries[i] != null) { 308 URL url = findResourceImpl(resource, entries[i].getBundleFile(), resources.size()); 309 if (url != null) 310 resources.addElement(url); 311 } 312 } 313 for (int i = 0; i < fragments.length; i++) { 315 ClasspathEntry[] fragEntries = fragments[i].getEntries(); 316 for (int j = 0; j < fragEntries.length; j++) { 317 URL url = findResourceImpl(resource, fragEntries[j].getBundleFile(), resources.size()); 318 if (url != null) 319 resources.addElement(url); 320 } 321 } 322 if (resources.size() > 0) 323 return resources.elements(); 324 return null; 325 } 326 327 private URL findResourceImpl(String name, BundleFile bundlefile) { 328 return findResourceImpl(name, bundlefile, 0); 329 } 330 331 private URL findResourceImpl(String name, BundleFile bundlefile, int index) { 332 return bundlefile.getResourceURL(name, data.getBundleID(), index); 333 } 334 335 340 public BundleEntry findLocalEntry(String path) { 341 BundleEntry result = null; 342 for (int i = 0; i < entries.length; i++) { 343 if (entries[i] != null) { 344 result = findEntryImpl(path, entries[i].getBundleFile()); 345 if (result != null) 346 return result; 347 } 348 } 349 for (int i = 0; i < fragments.length; i++) { 351 ClasspathEntry[] fragEntries = fragments[i].getEntries(); 352 for (int j = 0; j < fragEntries.length; j++) { 353 result = findEntryImpl(path, fragEntries[j].getBundleFile()); 354 if (result != null) 355 return result; 356 } 357 } 358 return null; 359 } 360 361 366 public Enumeration findLocalEntries(String path) { 367 Vector objects = new Vector(6); for (int i = 0; i < entries.length; i++) { 369 if (entries[i] != null) { 370 BundleEntry result = findEntryImpl(path, entries[i].getBundleFile()); 371 if (result != null) 372 objects.addElement(result); 373 } 374 } 375 for (int i = 0; i < fragments.length; i++) { 377 ClasspathEntry[] fragEntries = fragments[i].getEntries(); 378 for (int j = 0; j < fragEntries.length; j++) { 379 BundleEntry result = findEntryImpl(path, fragEntries[j].getBundleFile()); 380 if (result != null) 381 objects.addElement(result); 382 } 383 } 384 if (objects.size() > 0) 385 return objects.elements(); 386 return null; 387 } 388 389 private BundleEntry findEntryImpl(String path, BundleFile bundleFile) { 390 return bundleFile.getEntry(path); 391 } 392 393 407 public Class findLocalClass(String classname) throws ClassNotFoundException { 408 Class result = null; 409 ClassLoadingStatsHook[] hooks = data.getAdaptor().getHookRegistry().getClassLoadingStatsHooks(); 410 try { 411 for (int i = 0; i < hooks.length; i++) 412 hooks[i].preFindLocalClass(classname, this); 413 result = findLocalClassImpl(classname, hooks); 414 return result; 415 } finally { 416 for (int i = 0; i < hooks.length; i++) 417 hooks[i].postFindLocalClass(classname, result, this); 418 } 419 } 420 421 private Class findLocalClassImpl(String classname, ClassLoadingStatsHook[] hooks) throws ClassNotFoundException { 422 synchronized (classloader) { 425 Class result = classloader.publicFindLoaded(classname); 426 if (result != null) 427 return result; 428 for (int i = 0; i < entries.length; i++) { 429 if (entries[i] != null) { 430 result = findClassImpl(classname, entries[i], hooks); 431 if (result != null) 432 return result; 433 } 434 } 435 for (int i = 0; i < fragments.length; i++) { 437 ClasspathEntry[] fragEntries = fragments[i].getEntries(); 438 for (int j = 0; j < fragEntries.length; j++) { 439 result = findClassImpl(classname, fragEntries[j], hooks); 440 if (result != null) 441 return result; 442 } 443 } 444 } 445 throw new ClassNotFoundException (classname); 446 } 447 448 private Class findClassImpl(String name, ClasspathEntry classpathEntry, ClassLoadingStatsHook[] hooks) { 449 if (Debug.DEBUG && Debug.DEBUG_LOADER) 450 Debug.println("BundleClassLoader[" + data + "].findClass(" + name + ")"); String filename = name.replace('.', '/').concat(".class"); BundleEntry entry = classpathEntry.getBundleFile().getEntry(filename); 453 if (entry == null) 454 return null; 455 456 byte[] classbytes; 457 try { 458 classbytes = entry.getBytes(); 459 } catch (IOException e) { 460 if (Debug.DEBUG && Debug.DEBUG_LOADER) 461 Debug.println(" IOException reading " + filename + " from " + data); return null; 463 } 464 465 if (Debug.DEBUG && Debug.DEBUG_LOADER) { 466 Debug.println(" read " + classbytes.length + " bytes from " + filename); Debug.println(" defining class " + name); } 469 470 try { 471 return defineClass(name, classbytes, classpathEntry, entry, hooks); 472 } catch (Error e) { 473 if (Debug.DEBUG && Debug.DEBUG_LOADER) 474 Debug.println(" error defining class " + name); throw e; 476 } 477 } 478 479 492 private Class defineClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClassLoadingStatsHook[] statsHooks) { 493 ClassLoadingHook[] hooks = data.getAdaptor().getHookRegistry().getClassLoadingHooks(); 494 byte[] modifiedBytes = classbytes; 495 for (int i = 0; i < hooks.length; i++) { 496 modifiedBytes = hooks[i].processClass(name, classbytes, classpathEntry, entry, this); 497 if (modifiedBytes != null) 498 classbytes = modifiedBytes; 499 } 500 501 Class result = classloader.defineClass(name, classbytes, classpathEntry, entry); 502 503 for (int i = 0; i < statsHooks.length; i++) 504 statsHooks[i].recordClassDefine(name, result, classbytes, classpathEntry, entry, this); 505 return result; 506 } 507 508 512 public BaseData getBaseData() { 513 return data; 514 } 515 516 520 public FragmentClasspath[] getFragmentClasspaths() { 521 return fragments; 522 } 523 524 528 public ClasspathEntry[] getHostClasspathEntries() { 529 return entries; 530 } 531 532 536 public BaseClassLoader getBaseClassLoader() { 537 return classloader; 538 } 539 540 public String findLibrary(String libname) { 541 synchronized (this) { 542 if (loadedLibraries == null) 543 loadedLibraries = new ArrayList(1); 544 } 545 synchronized (loadedLibraries) { 546 for (Iterator libs = loadedLibraries.iterator(); libs.hasNext();) { 550 String [] libNameResult = (String []) libs.next(); 551 if (libNameResult[0].equals(libname)) 552 return libNameResult[1]; 553 } 554 555 String result = classloader.getDelegate().findLibrary(libname); 556 if (result != null) 557 loadedLibraries.add(new String [] {libname, result}); 558 return result; 559 } 560 } 561 562 } 563 | Popular Tags |