Example #1
0
  void filterServiceReferences(
      BundleContextImpl bc,
      String service,
      String filter,
      boolean allServices,
      Collection /*<ServiceReference>*/ refs) {
    ArrayList srl = fwCtx.services.get(FindHook.class.getName());
    if (srl != null) {
      RemoveOnlyCollection filtered = new RemoveOnlyCollection(refs);

      for (Iterator i = srl.iterator(); i.hasNext(); ) {
        ServiceReferenceImpl sr = ((ServiceRegistrationImpl) i.next()).reference;
        FindHook fh = (FindHook) sr.getService(fwCtx.systemBundle);
        if (fh != null) {
          try {
            fh.find(bc, service, filter, allServices, filtered);
          } catch (Exception e) {
            fwCtx.listeners.frameworkError(
                bc,
                new BundleException(
                    "Failed to call find hook  #" + sr.getProperty(Constants.SERVICE_ID), e));
          }
        }
      }
    }
  }
  /*
   * The FindHook is called when a target bundle searches the service registry
   * with the getServiceReference or getServiceReferences methods. A registered
   * FindHook service gets a chance to inspect the returned set of service
   * references and can optionally shrink the set of returned services. The order
   * in which the find hooks are called is the reverse compareTo ordering of
   * their Service References.
   */
  private List<ServiceState> processFindHooks(
      AbstractBundle bundle,
      String clazz,
      String filterStr,
      boolean checkAssignable,
      List<ServiceState> serviceStates) {
    BundleContext context = bundle.getBundleContext();
    List<ServiceState> hookRefs =
        getServiceReferencesInternal(bundle, FindHook.class.getName(), null, true);
    if (hookRefs.isEmpty()) return serviceStates;

    // Event and Find Hooks can not be used to hide the services from the framework.
    if (clazz != null && clazz.startsWith(FindHook.class.getPackage().getName()))
      return serviceStates;

    // The order in which the find hooks are called is the reverse compareTo ordering of
    // their ServiceReferences. That is, the service with the highest ranking number must be called
    // first.
    List<ServiceReference> sortedHookRefs = new ArrayList<ServiceReference>(hookRefs);
    Collections.reverse(sortedHookRefs);

    List<FindHook> hooks = new ArrayList<FindHook>();
    for (ServiceReference hookRef : sortedHookRefs)
      hooks.add((FindHook) context.getService(hookRef));

    Collection<ServiceReference> hookParam = new ArrayList<ServiceReference>();
    for (ServiceState aux : serviceStates) hookParam.add(aux.getReference());

    hookParam = new RemoveOnlyCollection<ServiceReference>(hookParam);
    for (FindHook hook : hooks) {
      try {
        hook.find(context, clazz, filterStr, !checkAssignable, hookParam);
      } catch (Exception ex) {
        log.warn("Error while calling FindHook: " + hook, ex);
      }
    }

    List<ServiceState> result = new ArrayList<ServiceState>();
    for (ServiceReference aux : hookParam) {
      ServiceState serviceState = ServiceState.assertServiceState(aux);
      result.add(serviceState);
    }

    return result;
  }