/* * See whether any registered extension provides the class requested. If not * throw an IOException. */ public URLConnection openConnection(URL url) throws IOException { String path = url.getPath(); if (path.trim().equals("/")) { return new URLHandlersBundleURLConnection(url); } Bundle[] extensions = m_extensionsCache; URL result = null; for (Bundle extBundle : extensions) { try { BundleRevisionImpl bri = (BundleRevisionImpl) extBundle.adapt(BundleRevision.class); if (bri != null) { result = bri.getResourceLocal(path); } } catch (Exception ex) { // Maybe the bundle went away, so ignore this exception. } if (result != null) { return result.openConnection(); } } return new URLConnection(url) { public void connect() throws IOException { throw new IOException("Resource not provided by any extension!"); } }; }
/** * Add an extension bundle. The bundle will be added to the parent classloader and it's exported * packages will be added to the module definition exports of this instance. Subsequently, they * are available form the instance in it's role as content loader. * * @param felix the framework instance the given extension bundle comes from. * @param bundle the extension bundle to add. * @throws BundleException if extension bundles are not supported or this is not a framework * extension. * @throws SecurityException if the caller does not have the needed * AdminPermission.EXTENSIONLIFECYCLE and security is enabled. * @throws Exception in case something goes wrong. */ synchronized void addExtensionBundle(Felix felix, BundleImpl bundle) throws SecurityException, BundleException, Exception { Object sm = System.getSecurityManager(); if (sm != null) { ((SecurityManager) sm) .checkPermission(new AdminPermission(bundle, AdminPermission.EXTENSIONLIFECYCLE)); } if (!((BundleProtectionDomain) bundle.getProtectionDomain()) .impliesDirect(new AllPermission())) { throw new SecurityException("Extension Bundles must have AllPermission"); } String directive = ManifestParser.parseExtensionBundleHeader( (String) ((BundleRevisionImpl) bundle.adapt(BundleRevision.class)) .getHeaders() .get(Constants.FRAGMENT_HOST)); // We only support classpath extensions (not bootclasspath). if (!Constants.EXTENSION_FRAMEWORK.equals(directive)) { throw new BundleException( "Unsupported Extension Bundle type: " + directive, new UnsupportedOperationException("Unsupported Extension Bundle type!")); } try { // Merge the exported packages with the exported packages of the systembundle. List<BundleCapability> exports = null; try { exports = ManifestParser.parseExportHeader( m_logger, m_systemBundleRevision, (String) ((BundleRevisionImpl) bundle.adapt(BundleRevision.class)) .getHeaders() .get(Constants.EXPORT_PACKAGE), m_systemBundleRevision.getSymbolicName(), m_systemBundleRevision.getVersion()); exports = aliasSymbolicName(exports); } catch (Exception ex) { m_logger.log( bundle, Logger.LOG_ERROR, "Error parsing extension bundle export statement: " + ((BundleRevisionImpl) bundle.adapt(BundleRevision.class)) .getHeaders() .get(Constants.EXPORT_PACKAGE), ex); return; } // Add the bundle as extension if we support extensions if (m_extensionManager != null) { // This needs to be the private instance. m_extensionManager.addExtension(felix, bundle); } else { // We don't support extensions (i.e., the parent is not an URLClassLoader). m_logger.log( bundle, Logger.LOG_WARNING, "Unable to add extension bundle to FrameworkClassLoader - Maybe not an URLClassLoader?"); throw new UnsupportedOperationException( "Unable to add extension bundle to FrameworkClassLoader - Maybe not an URLClassLoader?"); } appendCapabilities(exports); } catch (Exception ex) { throw ex; } BundleRevisionImpl bri = (BundleRevisionImpl) bundle.adapt(BundleRevision.class); List<BundleRequirement> reqs = bri.getDeclaredRequirements(BundleRevision.HOST_NAMESPACE); List<BundleCapability> caps = getCapabilities(BundleRevision.HOST_NAMESPACE); BundleWire bw = new BundleWireImpl(bri, reqs.get(0), m_systemBundleRevision, caps.get(0)); bri.resolve( new BundleWiringImpl( m_logger, m_configMap, null, bri, null, Collections.singletonList(bw), Collections.EMPTY_MAP, Collections.EMPTY_MAP)); felix.getDependencies().addDependent(bw); felix.setBundleStateAndNotify(bundle, Bundle.RESOLVED); }