1 11 12 package org.eclipse.osgi.framework.adaptor.core; 13 14 import java.io.*; 15 import java.net.MalformedURLException ; 16 import java.net.URL ; 17 import java.security.*; 18 import java.security.cert.Certificate ; 19 import java.util.*; 20 import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate; 21 import org.eclipse.osgi.framework.debug.Debug; 22 import org.eclipse.osgi.util.NLS; 23 import org.osgi.framework.BundleException; 24 import org.osgi.framework.FrameworkEvent; 25 26 34 public class DefaultClassLoader extends AbstractClassLoader { 35 38 static final PermissionCollection ALLPERMISSIONS; 39 static { 40 AllPermission allPerm = new AllPermission(); 41 ALLPERMISSIONS = allPerm.newPermissionCollection(); 42 if (ALLPERMISSIONS != null) 43 ALLPERMISSIONS.add(allPerm); 44 } 45 48 protected AbstractBundleData hostdata; 49 50 54 protected ClasspathEntry[] classpathEntries; 55 56 59 protected Vector fragClasspaths; 61 65 protected int buffersize = 8 * 1024; 67 77 public DefaultClassLoader(ClassLoaderDelegate delegate, ProtectionDomain domain, String [] classpath, ClassLoader parent, AbstractBundleData bundledata) { 78 super(delegate, domain, classpath, parent); 79 this.hostdata = bundledata; 80 81 try { 82 hostdata.open(); 83 } catch (IOException e) { 84 hostdata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, hostdata.getBundle(), e); 85 } 86 } 87 88 91 public void initialize() { 92 classpathEntries = buildClasspath(hostclasspath, hostdata, hostdomain); 93 } 94 95 98 public void attachFragment(org.eclipse.osgi.framework.adaptor.BundleData bundledata, ProtectionDomain domain, String [] classpath) { 99 AbstractBundleData abstractbundledata = (AbstractBundleData) bundledata; 100 try { 101 bundledata.open(); 102 } catch (IOException e) { 103 104 abstractbundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, abstractbundledata.getBundle(), e); 105 } 106 ClasspathEntry[] fragEntries = buildClasspath(classpath, abstractbundledata, domain); 107 FragmentClasspath fragClasspath = new FragmentClasspath(fragEntries, abstractbundledata, domain); 108 insertFragment(fragClasspath); 109 } 110 111 117 protected synchronized void insertFragment(FragmentClasspath fragClasspath) { 118 if (fragClasspaths == null) { 119 fragClasspaths = new Vector(10); 121 fragClasspaths.addElement(fragClasspath); 122 return; 123 } 124 125 int size = fragClasspaths.size(); 127 long fragID = fragClasspath.bundledata.getBundleID(); 128 for (int i = 0; i < size; i++) { 129 long otherID = ((FragmentClasspath) fragClasspaths.elementAt(i)).bundledata.getBundleID(); 130 if (fragID < otherID) { 131 fragClasspaths.insertElementAt(fragClasspath, i); 132 return; 133 } 134 } 135 fragClasspaths.addElement(fragClasspath); 137 } 138 139 143 protected String getBundleSymbolicName() { 144 return hostdata.getSymbolicName() + "_" + hostdata.getVersion(); } 146 147 151 public AbstractBundleData getHostData() { 152 return hostdata; 153 } 154 155 159 public FragmentClasspath[] getFragClasspaths() { 160 if (fragClasspaths == null) 161 return null; 162 return (FragmentClasspath[]) fragClasspaths.toArray(new FragmentClasspath[fragClasspaths.size()]); 163 } 164 165 172 protected ClasspathEntry getClasspath(String cp, AbstractBundleData bundledata, ProtectionDomain domain) { 173 BundleFile bundlefile = null; 174 File file; 175 if ((file = bundledata.getBaseBundleFile().getFile(cp)) != null) 177 bundlefile = createBundleFile(file, bundledata); 178 if (bundlefile == null && bundledata.getBaseBundleFile().containsDir(cp)) 180 bundlefile = new BundleFile.NestedDirBundleFile(bundledata.getBaseBundleFile(), cp); 181 if (bundlefile == null && DevClassPathHelper.inDevelopmentMode()) 183 return getExternalClassPath(cp, bundledata, domain); 184 if (bundlefile != null) 185 return createClassPathEntry(bundlefile, domain); 186 return null; 187 } 188 189 197 protected ClasspathEntry getExternalClassPath(String cp, AbstractBundleData bundledata, ProtectionDomain domain) { 198 File file = new File(cp); 199 if (!file.isAbsolute()) 200 return null; 201 BundleFile bundlefile = createBundleFile(file, bundledata); 202 if (bundlefile != null) 203 return createClassPathEntry(bundlefile, domain); 204 return null; 205 } 206 207 213 protected BundleFile createBundleFile(File file, AbstractBundleData bundledata) { 214 if (file == null || !file.exists()) 215 return null; 216 try { 217 return hostdata.getAdaptor().createBundleFile(file, bundledata); 218 } catch (IOException e) { 219 bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e); 220 } 221 return null; 222 } 223 224 227 protected synchronized Class findClass(String name) throws ClassNotFoundException { 228 Class result = findLoadedClass(name); 231 if (result != null) 232 return result; 233 for (int i = 0; i < classpathEntries.length; i++) { 234 if (classpathEntries[i] != null) { 235 result = findClassImpl(name, classpathEntries[i]); 236 if (result != null) 237 return result; 238 } 239 } 240 if (fragClasspaths != null) { 242 int size = fragClasspaths.size(); 243 for (int i = 0; i < size; i++) { 244 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 245 for (int j = 0; j < fragCP.classpathEntries.length; j++) { 246 result = findClassImpl(name, fragCP.classpathEntries[j]); 247 if (result != null) 248 return result; 249 } 250 } 251 } 252 throw new ClassNotFoundException (name); 253 } 254 255 262 protected Class findClassImpl(String name, ClasspathEntry classpathEntry) { 263 if (Debug.DEBUG && Debug.DEBUG_LOADER) { 264 Debug.println("BundleClassLoader[" + hostdata + "].findClass(" + name + ")"); } 266 267 String filename = name.replace('.', '/').concat(".class"); 269 BundleEntry entry = classpathEntry.getBundleFile().getEntry(filename); 270 271 if (entry == null) { 272 return null; 273 } 274 275 InputStream in; 276 try { 277 in = entry.getInputStream(); 278 } catch (IOException e) { 279 return null; 280 } 281 282 int length = (int) entry.getSize(); 283 byte[] classbytes; 284 int bytesread = 0; 285 int readcount; 286 287 if (Debug.DEBUG && Debug.DEBUG_LOADER) { 288 Debug.println(" about to read " + length + " bytes from " + filename); } 290 291 try { 292 try { 293 if (length > 0) { 294 classbytes = new byte[length]; 295 296 readloop: for (; bytesread < length; bytesread += readcount) { 297 readcount = in.read(classbytes, bytesread, length - bytesread); 298 299 if (readcount <= 0) { 300 break readloop; 301 } 302 } 303 } else { 304 length = buffersize; 305 classbytes = new byte[length]; 306 307 readloop: while (true) { 308 for (; bytesread < length; bytesread += readcount) { 309 readcount = in.read(classbytes, bytesread, length - bytesread); 310 311 if (readcount <= 0) { 312 break readloop; 313 } 314 } 315 316 byte[] oldbytes = classbytes; 317 length += buffersize; 318 classbytes = new byte[length]; 319 System.arraycopy(oldbytes, 0, classbytes, 0, bytesread); 320 } 321 } 322 } catch (IOException e) { 323 if (Debug.DEBUG && Debug.DEBUG_LOADER) { 324 Debug.println(" IOException reading " + filename + " from " + hostdata); } 326 327 return null; 328 } 329 } finally { 330 try { 331 in.close(); 332 } catch (IOException ee) { 333 } 335 } 336 337 if (Debug.DEBUG && Debug.DEBUG_LOADER) { 338 Debug.println(" read " + bytesread + " bytes from " + filename); Debug.println(" defining class " + name); } 341 342 try { 343 return (defineClass(name, classbytes, 0, bytesread, classpathEntry)); 344 } catch (Error e) { 345 if (Debug.DEBUG && Debug.DEBUG_LOADER) { 346 Debug.println(" error defining class " + name); } 348 349 throw e; 350 } 351 } 352 353 363 protected Class defineClass(String name, byte[] classbytes, int off, int len, ClasspathEntry classpathEntry) throws ClassFormatError { 364 if (name != null && name.startsWith("java.")) { name = null; 369 } 370 return defineClass(name, classbytes, off, len, classpathEntry.getProtectionDomain()); 371 } 372 373 376 protected URL findResource(String name) { 377 URL result = null; 378 for (int i = 0; i < classpathEntries.length; i++) { 379 if (classpathEntries[i] != null) { 380 result = findResourceImpl(name, classpathEntries[i].getBundleFile()); 381 if (result != null) 382 return result; 383 } 384 } 385 if (fragClasspaths != null) { 387 int size = fragClasspaths.size(); 388 for (int i = 0; i < size; i++) { 389 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 390 for (int j = 0; j < fragCP.classpathEntries.length; j++) { 391 result = findResourceImpl(name, fragCP.classpathEntries[j].getBundleFile()); 392 if (result != null) 393 return result; 394 } 395 } 396 } 397 return null; 398 } 399 400 406 protected URL findResourceImpl(String name, BundleFile bundlefile) { 407 return findResourceImpl(name, bundlefile, 0); 408 } 409 410 417 protected URL findResourceImpl(String name, BundleFile bundlefile, int index) { 418 return bundlefile.getResourceURL(name, hostdata.getBundleID(), index); 419 } 420 421 424 public Enumeration findLocalResources(String resource) { 425 Vector resources = new Vector(6); for (int i = 0; i < classpathEntries.length; i++) { 427 if (classpathEntries[i] != null) { 428 URL url = findResourceImpl(resource, classpathEntries[i].getBundleFile(), resources.size()); 429 if (url != null) 430 resources.addElement(url); 431 } 432 } 433 if (fragClasspaths != null) { 435 int size = fragClasspaths.size(); 436 for (int i = 0; i < size; i++) { 437 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 438 for (int j = 0; j < fragCP.classpathEntries.length; j++) { 439 URL url = findResourceImpl(resource, fragCP.classpathEntries[j].getBundleFile(), resources.size()); 440 if (url != null) 441 resources.addElement(url); 442 } 443 } 444 } 445 if (resources.size() > 0) 446 return resources.elements(); 447 return null; 448 } 449 450 453 public Object findLocalObject(String object) { 454 BundleEntry result = null; 455 for (int i = 0; i < classpathEntries.length; i++) { 456 if (classpathEntries[i] != null) { 457 result = findObjectImpl(object, classpathEntries[i].getBundleFile()); 458 if (result != null) { 459 return result; 460 } 461 } 462 } 463 if (fragClasspaths != null) { 465 int size = fragClasspaths.size(); 466 for (int i = 0; i < size; i++) { 467 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 468 for (int j = 0; j < fragCP.classpathEntries.length; j++) { 469 result = findObjectImpl(object, fragCP.classpathEntries[j].getBundleFile()); 470 if (result != null) { 471 return result; 472 } 473 } 474 } 475 } 476 return null; 477 } 478 479 482 public Enumeration findLocalObjects(String object) { 483 Vector objects = new Vector(6); for (int i = 0; i < classpathEntries.length; i++) { 485 if (classpathEntries[i] != null) { 486 Object result = findObjectImpl(object, classpathEntries[i].getBundleFile()); 487 if (result != null) 488 objects.addElement(result); 489 } 490 } 491 if (fragClasspaths != null) { 493 int size = fragClasspaths.size(); 494 for (int i = 0; i < size; i++) { 495 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 496 for (int j = 0; j < fragCP.classpathEntries.length; j++) { 497 Object result = findObjectImpl(object, fragCP.classpathEntries[j].getBundleFile()); 498 if (result != null) 499 objects.addElement(result); 500 } 501 } 502 } 503 if (objects.size() > 0) 504 return objects.elements(); 505 return null; 506 } 507 508 515 protected BundleEntry findObjectImpl(String object, BundleFile bundleFile) { 516 return bundleFile.getEntry(object); 517 } 518 519 522 public void close() { 523 super.close(); 524 if (classpathEntries != null) { 525 for (int i = 0; i < classpathEntries.length; i++) { 526 if (classpathEntries[i] != null) { 527 try { 528 classpathEntries[i].getBundleFile().close(); 529 } catch (IOException e) { 530 hostdata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, hostdata.getBundle(), e); 531 } 532 } 533 } 534 } 535 if (fragClasspaths != null) { 536 int size = fragClasspaths.size(); 537 for (int i = 0; i < size; i++) { 538 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 539 fragCP.close(); 540 } 541 } 542 } 543 544 551 protected ClasspathEntry[] buildClasspath(String [] classpath, AbstractBundleData bundledata, ProtectionDomain domain) { 552 ArrayList result = new ArrayList(classpath.length); 553 addDefaultDevEntries(result, bundledata, domain); 555 for (int i = 0; i < classpath.length; i++) 557 findClassPathEntry(result, classpath[i], bundledata, domain); 558 return (ClasspathEntry[]) result.toArray(new ClasspathEntry[result.size()]); 559 } 560 561 568 protected void addDefaultDevEntries(ArrayList result, AbstractBundleData bundledata, ProtectionDomain domain) { 569 String [] devClassPath = !DevClassPathHelper.inDevelopmentMode() ? null : DevClassPathHelper.getDevClassPath(bundledata.getSymbolicName()); 570 if (devClassPath == null) 571 return; for (int i = 0; i < devClassPath.length; i++) 573 findClassPathEntry(result, devClassPath[i], bundledata, domain); 574 } 575 576 584 protected void findClassPathEntry(ArrayList result, String entry, AbstractBundleData bundledata, ProtectionDomain domain) { 585 if (!addClassPathEntry(result, entry, bundledata, domain)) { 586 String [] devCP = !DevClassPathHelper.inDevelopmentMode() ? null : DevClassPathHelper.getDevClassPath(bundledata.getSymbolicName()); 587 if (devCP == null || devCP.length == 0) { 588 BundleException be = new BundleException(NLS.bind(AdaptorMsg.BUNDLE_CLASSPATH_ENTRY_NOT_FOUND_EXCEPTION, entry, bundledata.getLocation())); 589 bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.INFO, bundledata.getBundle(), be); 590 } 591 } 592 } 593 594 604 protected boolean addClassPathEntry(ArrayList result, String entry, AbstractBundleData bundledata, ProtectionDomain domain) { 605 if (entry.equals(".")) { result.add(createClassPathEntry(bundledata.getBaseBundleFile(), domain)); 607 return true; 608 } 609 Object element = getClasspath(entry, bundledata, domain); 610 if (element != null) { 611 result.add(element); 612 return true; 613 } 614 if (fragClasspaths != null && hostdata == bundledata) { 617 int size = fragClasspaths.size(); 618 for (int i = 0; i < size; i++) { 619 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 620 element = getClasspath(entry, fragCP.bundledata, fragCP.domain); 621 if (element != null) { 622 result.add(element); 623 return true; 624 } 625 } 626 } 627 return false; 628 } 629 630 636 protected ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain domain) { 637 return new ClasspathEntry(bundlefile, domain); 638 } 639 640 643 protected class FragmentClasspath { 644 645 protected ClasspathEntry[] classpathEntries; 646 647 protected AbstractBundleData bundledata; 648 649 protected ProtectionDomain domain; 650 651 protected FragmentClasspath(ClasspathEntry[] classpathEntries, AbstractBundleData bundledata, ProtectionDomain domain) { 652 this.classpathEntries = classpathEntries; 653 this.bundledata = bundledata; 654 this.domain = domain; 655 } 656 657 protected void close() { 658 for (int i = 0; i < classpathEntries.length; i++) { 659 try { 660 classpathEntries[i].getBundleFile().close(); 661 } catch (IOException e) { 662 bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e); 663 } 664 } 665 } 666 667 public AbstractBundleData getBundleData() { 668 return bundledata; 669 } 670 } 671 672 675 protected class ClasspathEntry { 676 protected BundleFile bundlefile; 677 protected ProtectionDomain domain; 678 679 protected ClasspathEntry(BundleFile bundlefile, ProtectionDomain domain) { 680 this.bundlefile = bundlefile; 681 this.domain = createProtectionDomain(domain); 682 } 683 684 public BundleFile getBundleFile() { 685 return bundlefile; 686 } 687 688 public ProtectionDomain getProtectionDomain() { 689 return domain; 690 } 691 692 695 protected ProtectionDomain createProtectionDomain(ProtectionDomain baseDomain) { 696 try { 698 PermissionCollection permissions; 700 if (baseDomain != null) 701 permissions = baseDomain.getPermissions(); 702 else 703 permissions = ALLPERMISSIONS; 706 return new ClasspathDomain(bundlefile.getBaseFile().toURL(), permissions); 707 } catch (MalformedURLException e) { 708 return baseDomain; 710 } 711 } 712 } 713 714 717 protected class ClasspathDomain extends ProtectionDomain { 718 public ClasspathDomain(URL codeLocation, PermissionCollection permissions) { 719 super(new CodeSource(codeLocation, (Certificate []) null), permissions); 720 } 721 } 722 } 723 | Popular Tags |