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);
  }
  /** 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;
    }
  }
  /**
   * 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);
  }
  /**
   * 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));
  }
  /**
   * 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);
 }
 /**
  * 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);
 }
 /**
  * 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);
    }
  }
 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);
 }