예제 #1
0
  /**
   * Tracks and injects APSServiceTracker directly or as wrapped service instance using the tracker
   * to call the service depending on the field type.
   *
   * @param field The field to inject.
   * @param managedClass Used to lookup or create an instance of this class to inject into.
   * @param context The bundle context.
   */
  protected void handleServiceInjections(Field field, Class managedClass, BundleContext context) {
    OSGiService service = field.getAnnotation(OSGiService.class);
    if (service != null) {
      String trackerKey = field.getType().getName() + service.additionalSearchCriteria();
      APSServiceTracker tracker = this.trackers.get(trackerKey);

      if (tracker == null) {
        tracker =
            new APSServiceTracker<>(
                context, field.getType(), service.additionalSearchCriteria(), service.timeout());
        this.trackers.put(trackerKey, tracker);
      }
      tracker.start();

      List<Object> managedInstances = getManagedInstances(managedClass);
      for (Object managedInstance : managedInstances) {
        if (field.getType().equals(APSServiceTracker.class)) {
          injectObject(managedInstance, tracker, field);
        } else {
          injectObject(managedInstance, tracker.getWrappedService(), field);
        }
      }

      if (service.required() && this.supportsRequired) {
        Tuple4<APSServiceTracker, Class, Boolean, List<ServiceRegistration>> requiredService =
            new Tuple4<>(
                tracker,
                managedClass,
                false,
                (List<ServiceRegistration>) new LinkedList<ServiceRegistration>());
        this.requiredServices.add(requiredService);
      }

      this.activatorLogger.info(
          "Injected tracked service '"
              + field.getType().getName()
              + (service.additionalSearchCriteria().length() > 0
                  ? " " + service.additionalSearchCriteria()
                  : "")
              + "' "
              + "into '"
              + managedClass.getName()
              + "."
              + field.getName()
              + "' for bundle: "
              + context.getBundle().getSymbolicName()
              + " for "
              + managedInstances.size()
              + " instance(s)!");
    }
  }
예제 #2
0
  /**
   * Called when this bundle is stopped so the Framework can perform the bundle-specific activities
   * necessary to stop the bundle. In general, this method should undo the work that the
   * `BundleActivator.start()` method started. There should be no active threads that were started
   * by this bundle when this bundle returns. A stopped bundle must not call any Framework objects.
   *
   * <p>This method must complete and return to its caller in a timely manner.
   *
   * @param context The execution context of the bundle being stopped.
   * @throws Exception If this method throws an exception, the bundle is still marked as stopped,
   *     and the Framework will remove the bundle's listeners, unregister all services registered by
   *     the bundle, and release all services used by the bundle.
   */
  @Override
  public void stop(BundleContext context) throws Exception {
    if (this.services == null) {
      System.err.println("ERROR: Stopping non started instance of APSActivator!");
      return; // Not started!
    }

    Exception failure = null;

    this.activatorLogger.info(
        "Stopping APSActivator for bundle '"
            + context.getBundle().getSymbolicName()
            + "' with activatorMode: "
            + this.activatorMode);

    for (ListenerWrapper listenerWrapper : this.listeners) {
      listenerWrapper.stop(context);
    }
    this.listeners = null;

    for (Tuple2<Method, Object> shutdownMethod : this.shutdownMethods) {
      try {
        shutdownMethod.t1.invoke(shutdownMethod.t2, null);

        this.activatorLogger.info(
            "Called bundle shutdown method '"
                + shutdownMethod.t2.getClass()
                + "."
                + shutdownMethod.t1.getName()
                + "() for bundle: "
                + context.getBundle().getSymbolicName()
                + "!");
      } catch (Exception e) {
        this.activatorLogger.error("Bundle stop problem!", e);
        failure = e;
      }
    }
    this.shutdownMethods = null;

    for (ServiceRegistration serviceRegistration : this.services) {
      try {
        serviceRegistration.unregister();
      } catch (Exception e) {
        this.activatorLogger.error("Bundle stop problem!", e);
        failure = e;
      }
    }
    this.services = null;

    for (String trackerKey : this.trackers.keySet()) {
      APSServiceTracker tracker = this.trackers.get(trackerKey);
      try {
        tracker.stop(context);
      } catch (Exception e) {
        this.activatorLogger.error("Bundle stop problem!", e);
        failure = e;
      }
    }
    this.trackers = null;

    for (String namedInstanceKey : this.namedInstances.keySet()) {
      Object namedInstance = this.namedInstances.get(namedInstanceKey);
      if (namedInstance instanceof APSLogger) {
        try {
          ((APSLogger) namedInstance).stop(context);
        } catch (Exception e) {
          this.activatorLogger.error("Bundle stop problem!", e);
          failure = e;
        }
      }
    }
    this.namedInstances = null;

    this.activatorLogger.stop(context);
    this.activatorLogger = null;

    if (failure != null) {
      throw new APSActivatorException("Bundle stop not entirely successful!", failure);
    }
  }