1 11 12 package org.eclipse.osgi.framework.internal.defaultadaptor; 13 14 import java.io.*; 15 import java.net.URL ; 16 import java.security.ProtectionDomain ; 17 import java.util.*; 18 import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate; 19 import org.eclipse.osgi.framework.adaptor.core.*; 20 import org.eclipse.osgi.framework.debug.Debug; 21 import org.osgi.framework.BundleException; 22 import org.osgi.framework.FrameworkEvent; 23 24 28 public class DefaultClassLoader extends AbstractClassLoader { 29 32 protected AbstractBundleData hostdata; 33 34 38 protected ClasspathEntry[] classpathEntries; 39 40 protected Vector fragClasspaths; 42 46 protected int buffersize = 8 * 1024; 47 48 58 public DefaultClassLoader(ClassLoaderDelegate delegate, ProtectionDomain domain, String [] classpath, ClassLoader parent, AbstractBundleData bundledata) { 59 super(delegate, domain, classpath, parent); 60 this.hostdata = bundledata; 61 62 try { 63 hostdata.open(); 64 } catch (IOException e) { 65 hostdata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, hostdata.getBundle(), e); 66 } 67 } 68 69 public void initialize() { 70 classpathEntries = buildClasspath(hostclasspath, hostdata, hostdomain); 71 } 72 73 86 public void attachFragment(org.eclipse.osgi.framework.adaptor.BundleData bundledata, ProtectionDomain domain, String [] classpath) { 87 AbstractBundleData abstractbundledata = (AbstractBundleData) bundledata; 88 try { 89 bundledata.open(); 90 } catch (IOException e) { 91 92 abstractbundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, abstractbundledata.getBundle(), e); 93 } 94 ClasspathEntry[] fragEntries = buildClasspath(classpath, abstractbundledata, domain); 95 FragmentClasspath fragClasspath = new FragmentClasspath(fragEntries, abstractbundledata, domain); 96 insertFragment(fragClasspath); 97 } 98 99 105 protected synchronized void insertFragment(FragmentClasspath fragClasspath) { 106 if (fragClasspaths == null) { 107 fragClasspaths = new Vector(10); 109 fragClasspaths.addElement(fragClasspath); 110 return; 111 } 112 113 int size = fragClasspaths.size(); 115 long fragID = fragClasspath.bundledata.getBundleID(); 116 for (int i = 0; i < size; i++) { 117 long otherID = ((FragmentClasspath) fragClasspaths.elementAt(i)).bundledata.getBundleID(); 118 if (fragID < otherID) { 119 fragClasspaths.insertElementAt(fragClasspath, i); 120 return; 121 } 122 } 123 fragClasspaths.addElement(fragClasspath); 125 } 126 127 134 protected ClasspathEntry getClasspath(String cp, AbstractBundleData bundledata, ProtectionDomain domain) { 135 BundleFile bundlefile = null; 136 File file = bundledata.getBaseBundleFile().getFile(cp); 137 if (file != null && file.exists()) { 138 try { 139 bundlefile = hostdata.getAdaptor().createBundleFile(file, bundledata); 140 } catch (IOException e) { 141 bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e); 142 } 143 } else if (bundledata.getBaseBundleFile().containsDir(cp)) { 144 bundlefile = new BundleFile.NestedDirBundleFile(bundledata.getBaseBundleFile(), cp); 146 } 147 148 if (bundlefile == null && DevClassPathHelper.inDevelopmentMode()) { 150 file = new File(cp); 151 if (file.exists() && file.isAbsolute()) 152 try { 154 bundlefile = hostdata.getAdaptor().createBundleFile(file, bundledata); 155 } catch (IOException e) { 156 bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e); 157 } 158 } 159 160 if (bundlefile != null) 161 return createClassPathEntry(bundlefile, domain); 162 else 163 return null; 164 } 165 166 protected synchronized Class findClass(String name) throws ClassNotFoundException { 167 Class result = findLoadedClass(name); 168 if (result != null) 169 return result; 170 for (int i = 0; i < classpathEntries.length; i++) { 171 if (classpathEntries[i] != null) { 172 result = findClassImpl(name, classpathEntries[i]); 173 if (result != null) { 174 return result; 175 } 176 } 177 } 178 if (fragClasspaths != null) { 180 int size = fragClasspaths.size(); 181 for (int i = 0; i < size; i++) { 182 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 183 for (int j = 0; j < fragCP.classpathEntries.length; j++) { 184 result = findClassImpl(name, fragCP.classpathEntries[j]); 185 if (result != null) { 186 return result; 187 } 188 } 189 } 190 } 191 throw new ClassNotFoundException (name); 192 } 193 194 201 protected Class findClassImpl(String name, ClasspathEntry classpathEntry) { 202 if (Debug.DEBUG && Debug.DEBUG_LOADER) { 203 Debug.println("BundleClassLoader[" + hostdata + "].findClass(" + name + ")"); } 205 206 String filename = name.replace('.', '/').concat(".class"); 208 BundleEntry entry = classpathEntry.getBundleFile().getEntry(filename); 209 210 if (entry == null) { 211 return null; 212 } 213 214 InputStream in; 215 try { 216 in = entry.getInputStream(); 217 } catch (IOException e) { 218 return null; 219 } 220 221 int length = (int) entry.getSize(); 222 byte[] classbytes; 223 int bytesread = 0; 224 int readcount; 225 226 if (Debug.DEBUG && Debug.DEBUG_LOADER) { 227 Debug.println(" about to read " + length + " bytes from " + filename); } 229 230 try { 231 try { 232 if (length > 0) { 233 classbytes = new byte[length]; 234 235 readloop: for (; bytesread < length; bytesread += readcount) { 236 readcount = in.read(classbytes, bytesread, length - bytesread); 237 238 if (readcount <= 0) { 239 break readloop; 240 } 241 } 242 } else { 243 length = buffersize; 244 classbytes = new byte[length]; 245 246 readloop: while (true) { 247 for (; bytesread < length; bytesread += readcount) { 248 readcount = in.read(classbytes, bytesread, length - bytesread); 249 250 if (readcount <= 0) { 251 break readloop; 252 } 253 } 254 255 byte[] oldbytes = classbytes; 256 length += buffersize; 257 classbytes = new byte[length]; 258 System.arraycopy(oldbytes, 0, classbytes, 0, bytesread); 259 } 260 } 261 } catch (IOException e) { 262 if (Debug.DEBUG && Debug.DEBUG_LOADER) { 263 Debug.println(" IOException reading " + filename + " from " + hostdata); } 265 266 return null; 267 } 268 } finally { 269 try { 270 in.close(); 271 } catch (IOException ee) { 272 } 273 } 274 275 if (Debug.DEBUG && Debug.DEBUG_LOADER) { 276 Debug.println(" read " + bytesread + " bytes from " + filename); Debug.println(" defining class " + name); } 279 280 try { 281 return (defineClass(name, classbytes, 0, bytesread, classpathEntry)); 282 } catch (Error e) { 283 if (Debug.DEBUG && Debug.DEBUG_LOADER) { 284 Debug.println(" error defining class " + name); } 286 287 throw e; 288 } 289 } 290 291 protected Class defineClass(String name, byte[] classbytes, int off, int len, ClasspathEntry classpathEntry) throws ClassFormatError { 292 if (name != null && name.startsWith("java.")) { name = null; 297 } 298 return defineClass(name, classbytes, off, len, classpathEntry.getProtectionDomain()); 299 } 300 301 protected URL findResource(String name) { 302 URL result = null; 303 for (int i = 0; i < classpathEntries.length; i++) { 304 if (classpathEntries[i] != null) { 305 result = findResourceImpl(name, classpathEntries[i].getBundleFile()); 306 if (result != null) { 307 return result; 308 } 309 } 310 } 311 if (fragClasspaths != null) { 313 int size = fragClasspaths.size(); 314 for (int i = 0; i < size; i++) { 315 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 316 for (int j = 0; j < fragCP.classpathEntries.length; j++) { 317 result = findResourceImpl(name, fragCP.classpathEntries[j].getBundleFile()); 318 if (result != null) { 319 return result; 320 } 321 } 322 } 323 } 324 return null; 325 } 326 327 333 protected URL findResourceImpl(String name, BundleFile bundlefile) { 334 return bundlefile.getResourceURL(name, hostdata.getBundleID()); 335 } 336 337 340 public Enumeration findLocalResources(String resource) { 341 Vector resources = new Vector(6); 342 for (int i = 0; i < classpathEntries.length; i++) { 343 if (classpathEntries[i] != null) { 344 URL url = findResourceImpl(resource, classpathEntries[i].getBundleFile()); 345 if (url != null) { 346 resources.addElement(url); 347 } 348 } 349 } 350 if (fragClasspaths != null) { 352 int size = fragClasspaths.size(); 353 for (int i = 0; i < size; i++) { 354 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 355 for (int j = 0; j < fragCP.classpathEntries.length; j++) { 356 URL url = findResourceImpl(resource, fragCP.classpathEntries[j].getBundleFile()); 357 if (url != null) { 358 resources.addElement(url); 359 } 360 } 361 } 362 } 363 if (resources.size() > 0) { 364 return resources.elements(); 365 } 366 return null; 367 } 368 369 public Object findLocalObject(String object) { 370 BundleEntry result = null; 371 for (int i = 0; i < classpathEntries.length; i++) { 372 if (classpathEntries[i] != null) { 373 result = findObjectImpl(object, classpathEntries[i].getBundleFile()); 374 if (result != null) { 375 return result; 376 } 377 } 378 } 379 if (fragClasspaths != null) { 381 int size = fragClasspaths.size(); 382 for (int i = 0; i < size; i++) { 383 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 384 for (int j = 0; j < fragCP.classpathEntries.length; j++) { 385 result = findObjectImpl(object, fragCP.classpathEntries[j].getBundleFile()); 386 if (result != null) { 387 return result; 388 } 389 } 390 } 391 } 392 return null; 393 } 394 395 protected BundleEntry findObjectImpl(String object, BundleFile bundleFile) { 396 return bundleFile.getEntry(object); 397 } 398 399 402 public void close() { 403 if (closed || hostdata.getAdaptor().isStopping()) 405 return; 406 407 super.close(); 408 if (classpathEntries != null) { 409 for (int i = 0; i < classpathEntries.length; i++) { 410 if (classpathEntries[i] != null) { 411 try { 412 if (classpathEntries[i].getBundleFile() != hostdata.getBaseBundleFile()) { 413 classpathEntries[i].getBundleFile().close(); 414 } 415 } catch (IOException e) { 416 hostdata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, hostdata.getBundle(), e); 417 } 418 } 419 } 420 } 421 if (fragClasspaths != null) { 422 int size = fragClasspaths.size(); 423 for (int i = 0; i < size; i++) { 424 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 425 fragCP.close(); 426 } 427 } 428 } 429 430 protected ClasspathEntry[] buildClasspath(String [] classpath, AbstractBundleData bundledata, ProtectionDomain domain) { 431 ArrayList result = new ArrayList(10); 432 433 if (!DevClassPathHelper.inDevelopmentMode()) { 435 for (int i = 0; i < classpath.length; i++) 436 findClassPathEntry(result, classpath[i], bundledata, domain); 437 return (ClasspathEntry[]) result.toArray(new ClasspathEntry[result.size()]); 438 } 439 440 addDefaultDevEntries(result, bundledata, domain); 445 for (int i = 0; i < classpath.length; i++) { 446 String [] devEntries = getDevEntries(classpath[i], bundledata); 447 if (devEntries != null && devEntries.length > 0) { 448 for (int j = 0; j < devEntries.length; j++) 449 findClassPathEntry(result, devEntries[j], bundledata, domain); 450 } else 451 findClassPathEntry(result, classpath[i], bundledata, domain); 452 } 453 return (ClasspathEntry[]) result.toArray(new ClasspathEntry[result.size()]); 454 } 455 456 protected void addDefaultDevEntries(ArrayList result, AbstractBundleData bundledata, ProtectionDomain domain) { 457 String [] devClassPath = DevClassPathHelper.getDevClassPath(bundledata.getSymbolicName()); 458 if (devClassPath == null) 459 return; 460 for (int i = 0; i < devClassPath.length; i++) 461 findClassPathEntry(result, devClassPath[i], bundledata, domain); 462 } 463 464 protected void findClassPathEntry(ArrayList result, String entry, AbstractBundleData bundledata, ProtectionDomain domain) { 465 if (!addClassPathEntry(result, entry, bundledata, domain)) { 466 } 471 } 472 473 protected boolean addClassPathEntry(ArrayList result, String entry, AbstractBundleData bundledata, ProtectionDomain domain) { 474 if (entry.equals(".")) { result.add(createClassPathEntry(bundledata.getBaseBundleFile(), domain)); 476 return true; 477 } 478 Object element = getClasspath(entry, bundledata, domain); 479 if (element != null) { 480 result.add(element); 481 return true; 482 } 483 if (fragClasspaths != null && hostdata == bundledata) { 486 int size = fragClasspaths.size(); 487 for (int i = 0; i < size; i++) { 488 FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i); 489 element = getClasspath(entry, fragCP.bundledata, fragCP.domain); 490 if (element != null) { 491 result.add(element); 492 return true; 493 } 494 } 495 } 496 return false; 497 } 498 499 protected String [] getDevEntries(String classpathEntry, AbstractBundleData bundledata) { 500 File propLocation = bundledata.getBaseBundleFile().getFile(classpathEntry + ".properties"); if (propLocation == null) 502 return null; 503 try { 504 InputStream in = new FileInputStream(propLocation); 505 try { 506 Properties devProps = new Properties(); 507 devProps.load(in); 508 return DevClassPathHelper.getArrayFromList(devProps.getProperty("bin")); } finally { 510 in.close(); 511 } 512 } catch (IOException e) { 513 BundleException be = new BundleException(AdaptorMsg.formatter.getString("BUNDLE_CLASSPATH_PROPERTIES_ERROR", propLocation), e); bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), be); 515 } 516 return null; 517 } 518 519 525 protected ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain domain) { 526 return new ClasspathEntry(bundlefile, domain); 527 } 528 529 532 protected class FragmentClasspath { 533 534 protected ClasspathEntry[] classpathEntries; 535 536 protected AbstractBundleData bundledata; 537 538 protected ProtectionDomain domain; 539 540 protected FragmentClasspath(ClasspathEntry[] classpathEntries, AbstractBundleData bundledata, ProtectionDomain domain) { 541 this.classpathEntries = classpathEntries; 542 this.bundledata = bundledata; 543 this.domain = domain; 544 } 545 546 protected void close() { 547 for (int i = 0; i < classpathEntries.length; i++) { 548 try { 549 if (classpathEntries[i].getBundleFile() != bundledata.getBaseBundleFile()) { 550 classpathEntries[i].getBundleFile().close(); 551 } 552 } catch (IOException e) { 553 bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e); 554 } 555 } 556 } 557 } 558 559 562 protected class ClasspathEntry { 563 protected BundleFile bundlefile; 564 protected ProtectionDomain domain; 565 566 protected ClasspathEntry(BundleFile bundlefile, ProtectionDomain domain) { 567 this.bundlefile = bundlefile; 568 this.domain = domain; 569 } 570 571 public BundleFile getBundleFile() { 572 return bundlefile; 573 } 574 575 public ProtectionDomain getProtectionDomain() { 576 return domain; 577 } 578 } 579 } | Popular Tags |