Object setContextFinder() { if (!SET_TCCL) return Boolean.FALSE; Thread currentThread = Thread.currentThread(); ClassLoader previousTCCL = currentThread.getContextClassLoader(); ClassLoader contextFinder = framework.getContextFinder(); if (previousTCCL != contextFinder) { currentThread.setContextClassLoader(framework.getContextFinder()); return previousTCCL; } return Boolean.FALSE; }
/** * Remove a service listener. The listener is removed from the context bundle's list of listeners. * See {@link #getBundle() getBundle()} for a definition of context bundle. * * <p>If this method is called with a listener which is not registered, then this method does * nothing. * * @param listener The service listener to remove. * @exception java.lang.IllegalStateException If the bundle context has stopped. */ public void removeServiceListener(ServiceListener listener) { checkValid(); if (listener == null) { throw new IllegalArgumentException(); } framework.getServiceRegistry().removeServiceListener(this, listener); }
/** * Retrieve the value of the named environment property. * * @param key The name of the requested property. * @return The value of the requested property, or <code>null</code> if the property is undefined. */ public String getProperty(String key) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPropertyAccess(key); } return (framework.getProperty(key)); }
/** * Add a service listener with a filter. {@link ServiceListener}s are notified when a service has * a lifecycle state change. See {@link #getServiceReferences(String, String) * getServiceReferences} for a description of the filter syntax. The listener is added to the * context bundle's list of listeners. See {@link #getBundle() getBundle()} for a definition of * context bundle. * * <p>The listener is called if the filter criteria is met. To filter based upon the class of the * service, the filter should reference the "objectClass" property. If the filter paramater is * <code>null</code>, all services are considered to match the filter. * * <p>If the Java runtime environment supports permissions, then additional filtering is done. * {@link AbstractBundle#hasPermission(Object) Bundle.hasPermission} is called for the bundle * which defines the listener to validate that the listener has the {@link ServicePermission} * permission to <code>"get"</code> the service using at least one of the named classes the * service was registered under. * * @param listener The service listener to add. * @param filter The filter criteria. * @exception InvalidSyntaxException If the filter parameter contains an invalid filter string * which cannot be parsed. * @see ServiceEvent * @see ServiceListener * @exception java.lang.IllegalStateException If the bundle context has stopped. */ public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException { checkValid(); if (listener == null) { throw new IllegalArgumentException(); } framework.getServiceRegistry().addServiceListener(this, listener, filter); }
/** Destroy the wrapper. This is called when the bundle is stopped. */ protected void close() { valid = false; /* invalidate context */ final ServiceRegistry registry = framework.getServiceRegistry(); registry.removeAllServiceListeners(this); framework.removeAllListeners(this); /* service's registered by the bundle, if any, are unregistered. */ registry.unregisterServices(this); /* service's used by the bundle, if any, are released. */ registry.releaseServicesInUse(this); synchronized (contextLock) { servicesInUse = null; } }
private static PermissionInfo[] getPermissionInfos(URL resource, Framework framework) { if (resource == null) return null; PermissionInfo[] info = EMPTY_PERM_INFO; DataInputStream in = null; try { in = new DataInputStream(resource.openStream()); ArrayList permissions = new ArrayList(); BufferedReader reader; try { reader = new BufferedReader(new InputStreamReader(in, "UTF8")); // $NON-NLS-1$ } catch (UnsupportedEncodingException e) { reader = new BufferedReader(new InputStreamReader(in)); } while (true) { String line = reader.readLine(); if (line == null) /* EOF */ break; line = line.trim(); if ((line.length() == 0) || line.startsWith("#") || line.startsWith("//")) /* comments */ // $NON-NLS-1$ //$NON-NLS-2$ continue; try { permissions.add(new PermissionInfo(line)); } catch (IllegalArgumentException iae) { /* incorrectly encoded permission */ if (framework != null) framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.getBundle(0), iae); } } int size = permissions.size(); if (size > 0) info = (PermissionInfo[]) permissions.toArray(new PermissionInfo[size]); } catch (IOException e) { // do nothing } finally { try { if (in != null) in.close(); } catch (IOException ee) { // do nothing } } return info; }
/** * Get a service's service object. Retrieves the service object for a service. A bundle's use of a * service is tracked by a use count. Each time a service's service object is returned by {@link * #getService}, the context bundle's use count for the service is incremented by one. Each time * the service is release by {@link #ungetService}, the context bundle's use count for the service * is decremented by one. When a bundle's use count for a service drops to zero, the bundle should * no longer use the service. See {@link #getBundle()} for a definition of context bundle. * * <p>This method will always return <code>null</code> when the service associated with this * reference has been unregistered. * * <p>The following steps are followed to get the service object: * * <ol> * <li>If the service has been unregistered, <code>null</code> is returned. * <li>The context bundle's use count for this service is incremented by one. * <li>If the context bundle's use count for the service is now one and the service was * registered with a {@link ServiceFactory}, the {@link ServiceFactory#getService * ServiceFactory.getService} method is called to create a service object for the context * bundle. This service object is cached by the framework. While the context bundle's use * count for the service is greater than zero, subsequent calls to get the services's * service object for the context bundle will return the cached service object. <br> * If the service object returned by the {@link ServiceFactory} is not an <code>instanceof * </code> all the classes named when the service was registered or the {@link * ServiceFactory} throws an exception, <code>null</code> is returned and a {@link * FrameworkEvent} of type {@link FrameworkEvent#ERROR} is broadcast. * <li>The service object for the service is returned. * </ol> * * @param reference A reference to the service whose service object is desired. * @return A service object for the service associated with this reference, or <code>null</code> * if the service is not registered. * @exception java.lang.SecurityException If the caller does not have {@link ServicePermission} * permission to "get" the service using at least one of the named classes the service was * registered under and the Java runtime environment supports permissions. * @exception java.lang.IllegalStateException If the bundle context has stopped. * @see #ungetService * @see ServiceFactory */ public <S> S getService(ServiceReference<S> reference) { checkValid(); if (reference == null) throw new NullPointerException("A null service reference is not allowed."); // $NON-NLS-1$ synchronized (contextLock) { if (servicesInUse == null) // Cannot predict how many services a bundle will use, start with a small table. servicesInUse = new HashMap<ServiceRegistrationImpl<?>, ServiceUse<?>>(10); } @SuppressWarnings("unchecked") S service = (S) framework.getServiceRegistry().getService(this, (ServiceReferenceImpl<S>) reference); return service; }
/** * Remove a framework listener. The listener is removed from the context bundle's list of * listeners. See {@link #getBundle() getBundle()} for a definition of context bundle. * * <p>If this method is called with a listener which is not registered, then this method does * nothing. * * @param listener The framework listener to remove. * @exception java.lang.IllegalStateException If the bundle context has stopped. */ public void removeFrameworkListener(FrameworkListener listener) { checkValid(); if (listener == null) { throw new IllegalArgumentException(); } if (Debug.DEBUG_EVENTS) { String listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); // $NON-NLS-1$ Debug.println( "removeFrameworkListener[" + bundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } framework.removeFrameworkListener(listener, this); }
/** * Creates a <code>File</code> object for a file in the persistent storage area provided for the * bundle by the framework. If the adaptor does not have file system support, this method will * return <code>null</code>. * * <p>A <code>File</code> object for the base directory of the persistent storage area provided * for the context bundle by the framework can be obtained by calling this method with the empty * string ("") as the parameter. See {@link #getBundle()} for a definition of context bundle. * * <p>If the Java runtime environment supports permissions, the framework the will ensure that the * bundle has <code>java.io.FilePermission</code> with actions "read","write","execute","delete" * for all files (recursively) in the persistent storage area provided for the context bundle by * the framework. * * @param filename A relative name to the file to be accessed. * @return A <code>File</code> object that represents the requested file or <code>null</code> if * the adaptor does not have file system support. * @exception java.lang.IllegalStateException If the bundle context has stopped. */ public File getDataFile(String filename) { checkValid(); return (framework.getDataFile(bundle, filename)); }
/** * Unget a service's service object. Releases the service object for a service. If the context * bundle's use count for the service is zero, this method returns <code>false</code>. Otherwise, * the context bundle's use count for the service is decremented by one. See {@link #getBundle()} * for a definition of context bundle. * * <p>The service's service object should no longer be used and all references to it should be * destroyed when a bundle's use count for the service drops to zero. * * <p>The following steps are followed to unget the service object: * * <ol> * <li>If the context bundle's use count for the service is zero or the service has been * unregistered, <code>false</code> is returned. * <li>The context bundle's use count for this service is decremented by one. * <li>If the context bundle's use count for the service is now zero and the service was * registered with a {@link ServiceFactory}, the {@link ServiceFactory#ungetService * ServiceFactory.ungetService} method is called to release the service object for the * context bundle. * <li><code>true</code> is returned. * </ol> * * @param reference A reference to the service to be released. * @return <code>false</code> if the context bundle's use count for the service is zero or if the * service has been unregistered, otherwise <code>true</code>. * @exception java.lang.IllegalStateException If the bundle context has stopped. * @see #getService * @see ServiceFactory */ public boolean ungetService(ServiceReference<?> reference) { checkValid(); return framework.getServiceRegistry().ungetService(this, (ServiceReferenceImpl<?>) reference); }
/** * Get a service reference. Retrieves a {@link ServiceReference} for a service which implements * the named class. * * <p>This reference is valid at the time of the call to this method, but since the framework is a * very dynamic environment, services can be modified or unregistered at anytime. * * <p>This method is provided as a convenience for when the caller is interested in any service * which implements a named class. This method is the same as calling {@link #getServiceReferences * getServiceReferences} with a <code>null</code> filter string but only a single {@link * ServiceReference} is returned. * * @param clazz The class name which the service must implement. * @return A {@link ServiceReference} object, or <code>null</code> if no services are registered * which implement the named class. * @see #getServiceReferences */ public ServiceReference<?> getServiceReference(String clazz) { checkValid(); return framework.getServiceRegistry().getServiceReference(this, clazz); }
/** * Retrieve the bundle that has the given unique identifier. * * @param id The identifier of the bundle to retrieve. * @return A Bundle object, or <code>null</code> if the identifier doesn't match any installed * bundle. */ public Bundle getBundle(long id) { return framework.getBundle(this, id); }
/** * Retrieve a list of all installed bundles. The list is valid at the time of the call to * getBundles, but the framework is a very dynamic environment and bundles can be installed or * uninstalled at anytime. * * @return An array of {@link AbstractBundle} objects, one object per installed bundle. */ public Bundle[] getBundles() { return framework.getBundles(this); }
/** * Retrieve the bundle that has the given location. * * @param location The location string of the bundle to retrieve. * @return A Bundle object, or <code>null</code> if the location doesn't match any installed * bundle. */ public AbstractBundle getBundleByLocation(String location) { return (framework.getBundleByLocation(location)); }
public Bundle getBundle(String location) { return framework.getBundleByLocation(location); }
/** * Bottom level event dispatcher for the BundleContext. * * @param originalListener listener object registered under. * @param l listener to call (may be filtered). * @param action Event class type * @param object Event object */ public void dispatchEvent(Object originalListener, Object l, int action, Object object) { // save the bundle ref to a local variable // to avoid interference from another thread closing this context AbstractBundle tmpBundle = bundle; Object previousTCCL = setContextFinder(); try { if (isValid()) /* if context still valid */ { switch (action) { case Framework.BUNDLEEVENT: case Framework.BUNDLEEVENTSYNC: { BundleListener listener = (BundleListener) l; if (Debug.DEBUG_EVENTS) { String listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); // $NON-NLS-1$ Debug.println( "dispatchBundleEvent[" + tmpBundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } BundleEvent event = (BundleEvent) object; switch (event.getType()) { case Framework.BATCHEVENT_BEGIN: { if (listener instanceof BatchBundleListener) ((BatchBundleListener) listener).batchBegin(); break; } case Framework.BATCHEVENT_END: { if (listener instanceof BatchBundleListener) ((BatchBundleListener) listener).batchEnd(); break; } default: { listener.bundleChanged((BundleEvent) object); } } break; } case ServiceRegistry.SERVICEEVENT: { ServiceEvent event = (ServiceEvent) object; ServiceListener listener = (ServiceListener) l; if (Debug.DEBUG_EVENTS) { String listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); // $NON-NLS-1$ Debug.println( "dispatchServiceEvent[" + tmpBundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } listener.serviceChanged(event); break; } case Framework.FRAMEWORKEVENT: { FrameworkListener listener = (FrameworkListener) l; if (Debug.DEBUG_EVENTS) { String listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); // $NON-NLS-1$ Debug.println( "dispatchFrameworkEvent[" + tmpBundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } listener.frameworkEvent((FrameworkEvent) object); break; } default: { throw new InternalError(); } } } } catch (Throwable t) { if (Debug.DEBUG_GENERAL) { Debug.println( "Exception in bottom level event dispatcher: " + t.getMessage()); // $NON-NLS-1$ Debug.printStackTrace(t); } // allow the adaptor to handle this unexpected error framework.adaptor.handleRuntimeError(t); publisherror: { if (action == Framework.FRAMEWORKEVENT) { FrameworkEvent event = (FrameworkEvent) object; if (event.getType() == FrameworkEvent.ERROR) { break publisherror; // avoid infinite loop } } framework.publishFrameworkEvent(FrameworkEvent.ERROR, tmpBundle, t); } } finally { if (previousTCCL != Boolean.FALSE) Thread.currentThread().setContextClassLoader((ClassLoader) previousTCCL); } }
/** * Register a service with multiple names. This method registers the given service object with the * given properties under the given class names. A {@link ServiceRegistration} object is returned. * The {@link ServiceRegistration} object is for the private use of the bundle registering the * service and should not be shared with other bundles. The registering bundle is defined to be * the context bundle. See {@link #getBundle()} for a definition of context bundle. Other bundles * can locate the service by using either the {@link #getServiceReferences getServiceReferences} * or {@link #getServiceReference getServiceReference} method. * * <p>A bundle can register a service object that implements the {@link ServiceFactory} interface * to have more flexiblity in providing service objects to different bundles. * * <p>The following steps are followed to register a service: * * <ol> * <li>If the service parameter is not a {@link ServiceFactory}, an <code> * IllegalArgumentException</code> is thrown if the service parameter is not an <code> * instanceof</code> all the classes named. * <li>The service is added to the framework's service registry and may now be used by other * bundles. * <li>A {@link ServiceEvent} of type {@link ServiceEvent#REGISTERED} is synchronously sent. * <li>A {@link ServiceRegistration} object for this registration is returned. * </ol> * * @param clazzes The class names under which the service can be located. The class names in this * array will be stored in the service's properties under the key "objectClass". * @param service The service object or a {@link ServiceFactory} object. * @param properties The properties for this service. The keys in the properties object must all * be Strings. Changes should not be made to this object after calling this method. To update * the service's properties call the {@link ServiceRegistration#setProperties * ServiceRegistration.setProperties} method. This parameter may be <code>null</code> if the * service has no properties. * @return A {@link ServiceRegistration} object for use by the bundle registering the service to * update the service's properties or to unregister the service. * @exception java.lang.IllegalArgumentException If one of the following is true: * <ul> * <li>The service parameter is null. * <li>The service parameter is not a {@link ServiceFactory} and is not an <code>instanceof * </code> all the named classes in the clazzes parameter. * </ul> * * @exception java.lang.SecurityException If the caller does not have {@link ServicePermission} * permission to "register" the service for all the named classes and the Java runtime * environment supports permissions. * @exception java.lang.IllegalStateException If the bundle context has stopped. * @see ServiceRegistration * @see ServiceFactory */ public ServiceRegistration<?> registerService( String[] clazzes, Object service, Dictionary<String, ?> properties) { checkValid(); return framework.getServiceRegistry().registerService(this, clazzes, service, properties); }
public ServiceReference<?>[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException { checkValid(); return framework.getServiceRegistry().getServiceReferences(this, clazz, filter, true); }
public Bundle installBundle(String location, InputStream in) throws BundleException { checkValid(); // note AdminPermission is checked after bundle is loaded return framework.installBundle(location, in, this); }