public static FrameworkDTO newFrameworkDTO(
     BundleContext systemBundleContext, Map<String, String> configuration) {
   FrameworkDTO dto = new FrameworkDTO();
   dto.properties = asProperties(configuration);
   if (systemBundleContext == null) {
     dto.bundles = newList(0);
     dto.services = newList(0);
     return dto;
   }
   Bundle[] bundles = systemBundleContext.getBundles();
   int size = bundles == null ? 0 : bundles.length;
   List<BundleDTO> bundleDTOs = newList(size);
   for (int i = 0; i < size; i++) {
     bundleDTOs.add(newBundleDTO(bundles[i]));
   }
   dto.bundles = bundleDTOs;
   try {
     ServiceReference<?>[] references = systemBundleContext.getAllServiceReferences(null, null);
     size = references == null ? 0 : references.length;
     List<ServiceReferenceDTO> refDTOs = newList(size);
     for (int i = 0; i < size; i++) {
       ServiceReferenceDTO serviceRefDTO = getServiceReferenceDTO(references[i]);
       if (serviceRefDTO != null) {
         refDTOs.add(serviceRefDTO);
       }
     }
     dto.services = refDTOs;
   } catch (InvalidSyntaxException e) {
     dto.services = newList(0);
   }
   return dto;
 }
 @Test
 public void testResolveSingletonInSameRegions() {
   List<BundleCapability> collisionCandidates = new ArrayList<BundleCapability>();
   collisionCandidates.add(bundleCapability(BUNDLE_B));
   collisionCandidates.add(bundleCapability(BUNDLE_C));
   collisionCandidates.add(bundleCapability(BUNDLE_D));
   this.resolverHook.filterSingletonCollisions(bundleCapability(BUNDLE_A), collisionCandidates);
   assertEquals("Wrong number of collitions", 0, collisionCandidates.size());
 }
 @Test
 public void testResolveSingletonInDifferentRegions() throws BundleException {
   region(REGION_A).addBundle(bundle(BUNDLE_X));
   BundleCapability collision = bundleCapability(BUNDLE_X);
   List<BundleCapability> collisionCandidates = new ArrayList<BundleCapability>();
   collisionCandidates.add(collision);
   collisionCandidates.add(bundleCapability(BUNDLE_B));
   collisionCandidates.add(bundleCapability(BUNDLE_C));
   collisionCandidates.add(bundleCapability(BUNDLE_D));
   this.resolverHook.filterSingletonCollisions(bundleCapability(BUNDLE_A), collisionCandidates);
   assertEquals("Wrong number of collitions", 1, collisionCandidates.size());
   collisionCandidates.contains(collision);
 }
 List<Generation> getGenerations() {
   List<Generation> result = new ArrayList<Generation>();
   ModuleRevision current = getModule().getCurrentRevision();
   result.add((Generation) current.getRevisionInfo());
   ModuleWiring wiring = current.getWiring();
   if (wiring != null) {
     List<ModuleWire> hostWires = wiring.getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
     if (hostWires != null) {
       for (ModuleWire hostWire : hostWires) {
         result.add((Generation) hostWire.getRequirer().getRevisionInfo());
       }
     }
   }
   return result;
 }
Example #5
0
 /**
  * Populates the entries list with recursively found class entries.
  *
  * @param bundle The bundle to get class entries for.
  * @param entries The list to add the class entries to.
  * @param startPath The start path to look for entries.
  */
 protected void collectClassEntries(Bundle bundle, List<Class> entries, String startPath) {
   Enumeration<String> entryPathEnumeration = bundle.getEntryPaths(startPath);
   while (entryPathEnumeration.hasMoreElements()) {
     String entryPath = entryPathEnumeration.nextElement();
     if (entryPath.endsWith("/")) {
       collectClassEntries(bundle, entries, entryPath);
     } else if (entryPath.endsWith(".class")) {
       try {
         String classQName =
             entryPath.substring(0, entryPath.length() - 6).replace(File.separatorChar, '.');
         if (classQName.startsWith("WEB-INF.classes.")) {
           classQName = classQName.substring(16);
         }
         Class entryClass = bundle.loadClass(classQName);
         // If not activatorMode is true then there will be classes in this list already on the
         // first
         // call to this method. Therefore we skip duplicates.
         if (!entries.contains(entryClass)) {
           entries.add(entryClass);
         }
       } catch (ClassNotFoundException cnfe) {
         this.activatorLogger.warn("Failed to load bundle class!", cnfe);
       } catch (NoClassDefFoundError ncdfe) {
         this.activatorLogger.warn("Failed to load bundle class!", ncdfe);
       }
     }
   }
 }
Example #6
0
 private ConditionalPermissionInfo setConditionalPermissionInfo(
     String name, ConditionInfo[] conds, PermissionInfo[] perms, boolean firstTry) {
   ConditionalPermissionUpdate update = newConditionalPermissionUpdate();
   List rows = update.getConditionalPermissionInfos();
   ConditionalPermissionInfo newInfo =
       newConditionalPermissionInfo(name, conds, perms, ConditionalPermissionInfo.ALLOW);
   int index = -1;
   if (name != null) {
     for (int i = 0; i < rows.size() && index < 0; i++) {
       ConditionalPermissionInfo info = (ConditionalPermissionInfo) rows.get(i);
       if (name.equals(info.getName())) {
         index = i;
       }
     }
   }
   if (index < 0) {
     // must always add to the beginning (bug 303930)
     rows.add(0, newInfo);
     index = 0;
   } else {
     rows.set(index, newInfo);
   }
   synchronized (lock) {
     if (!update.commit()) {
       if (firstTry)
         // try again
         setConditionalPermissionInfo(name, conds, perms, false);
     }
     return condAdminTable.getRow(index);
   }
 }
  @Override
  public Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int signersType) {
    SignedContentFactory factory = equinoxContainer.getSignedContentFactory();
    if (factory == null) {
      return Collections.emptyMap();
    }

    try {
      SignerInfo[] infos = signerInfos;
      if (infos == null) {
        SignedContent signedContent = factory.getSignedContent(this);
        infos = signedContent.getSignerInfos();
        signerInfos = infos;
      }
      if (infos.length == 0) return Collections.emptyMap();
      Map<X509Certificate, List<X509Certificate>> results =
          new HashMap<X509Certificate, List<X509Certificate>>(infos.length);
      for (int i = 0; i < infos.length; i++) {
        if (signersType == SIGNERS_TRUSTED && !infos[i].isTrusted()) continue;
        Certificate[] certs = infos[i].getCertificateChain();
        if (certs == null || certs.length == 0) continue;
        List<X509Certificate> certChain = new ArrayList<X509Certificate>();
        for (int j = 0; j < certs.length; j++) certChain.add((X509Certificate) certs[j]);
        results.put((X509Certificate) certs[0], certChain);
      }
      return results;
    } catch (Exception e) {
      return Collections.emptyMap();
    }
  }
 @Test
 public void testResolveSingletonConnectedRegions()
     throws BundleException, InvalidSyntaxException {
   RegionFilter filter = createBundleFilter(BUNDLE_B, BUNDLE_VERSION);
   region(REGION_A).connectRegion(region(REGION_B), filter);
   region(REGION_A).addBundle(bundle(BUNDLE_X));
   BundleCapability collisionX = bundleCapability(BUNDLE_X);
   BundleCapability collisionB = bundleCapability(BUNDLE_B);
   List<BundleCapability> collisionCandidates = new ArrayList<BundleCapability>();
   collisionCandidates.add(collisionX);
   collisionCandidates.add(collisionB);
   collisionCandidates.add(bundleCapability(BUNDLE_C));
   collisionCandidates.add(bundleCapability(BUNDLE_D));
   this.resolverHook.filterSingletonCollisions(bundleCapability(BUNDLE_A), collisionCandidates);
   assertEquals("Wrong number of collitions", 2, collisionCandidates.size());
   collisionCandidates.contains(collisionX);
   collisionCandidates.contains(collisionB);
 }
 private List<WireDTO> getListBundleWireDTO(List<BundleWire> wires) {
   if (wires == null) {
     return null;
   }
   List<WireDTO> dtos = newList(wires.size());
   for (BundleWire wire : wires) {
     dtos.add(getBundleWireDTO(wire));
   }
   return dtos;
 }
Example #10
0
 private static Bundle createMockBundle(String[] signers) {
   Map /* <X509Certificate, List<X509Certificate>> */ signersMap = new HashMap();
   for (int i = 0; i < signers.length; i++) {
     List chain = parseDNchain(signers[i]);
     List /* <X509Certificate> */ signersList = new ArrayList();
     Principal subject = null, issuer = null;
     X509Certificate first = null;
     for (Iterator iChain = chain.iterator(); iChain.hasNext(); ) {
       subject = issuer == null ? new MockPrincipal((String) iChain.next()) : issuer;
       issuer = iChain.hasNext() ? new MockPrincipal((String) iChain.next()) : subject;
       X509Certificate cert = new MockX509Certificate(subject, issuer);
       if (first == null) first = cert;
       signersList.add(cert);
     }
     if (subject != issuer) signersList.add(new MockX509Certificate(issuer, issuer));
     signersMap.put(first, signersList);
   }
   return new MockBundle(signersMap);
 }
 private List<RequirementRefDTO> getListRequirementRefDTO(List<BundleRequirement> reqs) {
   if (reqs == null) {
     return null;
   }
   List<RequirementRefDTO> dtos = newList(reqs.size());
   for (BundleRequirement req : reqs) {
     dtos.add(getRequirementRefDTO(req));
   }
   return dtos;
 }
 private List<CapabilityDTO> getListCapabilityDTO(List<BundleCapability> caps) {
   if (caps == null) {
     return null;
   }
   List<CapabilityDTO> dtos = newList(caps.size());
   for (BundleCapability cap : caps) {
     dtos.add(getCapabilityDTO(cap));
   }
   return dtos;
 }
 public static ServiceReferenceDTO[] newArrayServiceReferenceDTO(
     ServiceReference<?>[] references) {
   final int length = (references == null) ? 0 : references.length;
   List<ServiceReferenceDTO> refDTOs = new ArrayList<ServiceReferenceDTO>(length);
   for (int i = 0; i < length; i++) {
     ServiceReferenceDTO dto = getServiceReferenceDTO(references[i]);
     if (dto != null) {
       refDTOs.add(dto);
     }
   }
   return refDTOs.toArray(new ServiceReferenceDTO[refDTOs.size()]);
 }
Example #14
0
 /*
  * returns true if this thread can obtain the global lock or already has the lock;
  * otherwise this loader and thread are added to the waitingList
  */
 private static synchronized boolean tryLock(Thread currentThread, Object loader) {
   if (lockThread == currentThread) {
     lockCount++;
     return true;
   }
   if (lockThread == null) {
     lockCount++;
     lockThread = currentThread;
     return true;
   }
   waitingList.add(new Object[] {currentThread, loader});
   return false;
 }
 public static BundleWiringDTO[] newArrayBundleWiringDTO(BundleRevisions revisions) {
   if (revisions == null) {
     return null;
   }
   List<BundleRevision> revs = revisions.getRevisions();
   final int size = revs.size();
   List<BundleWiringDTO> dtos = new ArrayList<BundleWiringDTO>(size);
   for (int i = 0; i < size; i++) {
     BundleWiring wiring = revs.get(i).getWiring();
     if (wiring != null) {
       dtos.add(
           new DTOBuilder().getBundleWiringDTO(wiring)); // use new DTOBuilder for each wiring dto
     }
   }
   return dtos.toArray(new BundleWiringDTO[dtos.size()]);
 }
	public void testBasic() throws BundleException, InvalidSyntaxException, InterruptedException {
		// get the system region
		Region systemRegion = digraph.getRegion(0);
		// create a disconnected test region
		Region testRegion = digraph.createRegion(getName());
		List<Bundle> bundles = new ArrayList<Bundle>();
		// Install all test bundles
		Bundle pp1, cp2, sc1;
		bundles.add(pp1 = bundleInstaller.installBundle(PP1, testRegion));
		// should be able to start pp1 because it depends on nothing
		pp1.start();
		// do a sanity check that we have no services available in the isolated region
		assertNull("Found some services.", pp1.getBundleContext().getAllServiceReferences(null, null));
		assertEquals("Found extra bundles in region", 1, pp1.getBundleContext().getBundles().length);
		pp1.stop();

		bundles.add(bundleInstaller.installBundle(SP1, testRegion));
		bundles.add(bundleInstaller.installBundle(CP1, testRegion));
		bundles.add(bundleInstaller.installBundle(PP2, testRegion));
		bundles.add(bundleInstaller.installBundle(SP2, testRegion));
		bundles.add(cp2 = bundleInstaller.installBundle(CP2, testRegion));
		bundles.add(bundleInstaller.installBundle(PC1, testRegion));
		bundles.add(bundleInstaller.installBundle(BC1, testRegion));
		bundles.add(sc1 = bundleInstaller.installBundle(SC1, testRegion));
		bundles.add(bundleInstaller.installBundle(CC1, testRegion));

		// Import the system bundle from the systemRegion
		digraph.connect(testRegion, digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_BUNDLE_NAMESPACE, "(id=0)").build(), systemRegion);
		// must import Boolean services into systemRegion to test
		digraph.connect(systemRegion, digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_SERVICE_NAMESPACE, "(objectClass=java.lang.Boolean)").build(), testRegion);

		bundleInstaller.resolveBundles(bundles.toArray(new Bundle[bundles.size()]));
		for (Bundle bundle : bundles) {
			assertEquals("Bundle did not resolve: " + bundle.getSymbolicName(), Bundle.RESOLVED, bundle.getState());
			bundle.start();
		}
		BundleContext context = getContext();
		ServiceTracker<Boolean, Boolean> cp2Tracker = new ServiceTracker<Boolean, Boolean>(context, context.createFilter("(&(objectClass=java.lang.Boolean)(bundle.id=" + cp2.getBundleId() + "))"), null);
		ServiceTracker<Boolean, Boolean> sc1Tracker = new ServiceTracker<Boolean, Boolean>(context, context.createFilter("(&(objectClass=java.lang.Boolean)(bundle.id=" + sc1.getBundleId() + "))"), null);

		cp2Tracker.open();
		sc1Tracker.open();

		assertNotNull("The cp2 bundle never found the service.", cp2Tracker.waitForService(2000));
		assertNotNull("The sc1 bundle never found the service.", sc1Tracker.waitForService(2000));
		cp2Tracker.close();
		sc1Tracker.close();
	}
 private static Object mapValue(Object v) {
   if ((v == null)
       || v instanceof Number
       || v instanceof Boolean
       || v instanceof Character
       || v instanceof String
       || v instanceof DTO) {
     return v;
   }
   if (v instanceof Map) {
     Map<?, ?> m = (Map<?, ?>) v;
     Map<Object, Object> map = newMap(m.size());
     for (Map.Entry<?, ?> e : m.entrySet()) {
       map.put(mapValue(e.getKey()), mapValue(e.getValue()));
     }
     return map;
   }
   if (v instanceof List) {
     List<?> c = (List<?>) v;
     List<Object> list = newList(c.size());
     for (Object o : c) {
       list.add(mapValue(o));
     }
     return list;
   }
   if (v instanceof Set) {
     Set<?> c = (Set<?>) v;
     Set<Object> set = newSet(c.size());
     for (Object o : c) {
       set.add(mapValue(o));
     }
     return set;
   }
   if (v.getClass().isArray()) {
     final int length = Array.getLength(v);
     final Class<?> componentType = mapComponentType(v.getClass().getComponentType());
     Object array = Array.newInstance(componentType, length);
     for (int i = 0; i < length; i++) {
       Array.set(array, i, mapValue(Array.get(v, i)));
     }
     return array;
   }
   return String.valueOf(v);
 }
Example #18
0
  /**
   * This gets called for required services when the tracker have timed out waiting for a service to
   * become available and is about to throw an APSNoServiceAvailableException. This will unpublish
   * all published services that have a requirement on the timed out service. The service will be
   * republished later when it becomes available again by onServiceAvailable() above.
   *
   * @throws RuntimeException
   */
  @Override
  public void onTimeout() throws RuntimeException {
    this.activatorLogger.warn("A required service have gone away!");
    List<Class> uniqueClasses = new LinkedList<>();
    for (Tuple4<APSServiceTracker, Class, Boolean, List<ServiceRegistration>> requiredService :
        this.requiredServices) {
      if (!uniqueClasses.contains(requiredService.t2)) {
        uniqueClasses.add(requiredService.t2);
      }
    }

    for (Class managedClass : uniqueClasses) {
      boolean allRequiredAvailable = true;
      for (Tuple4<APSServiceTracker, Class, Boolean, List<ServiceRegistration>> requiredService :
          this.requiredServices) {
        if (requiredService.t2.equals(managedClass) && !requiredService.t1.hasTrackedService()) {
          allRequiredAvailable = false;
          break;
        }
      }

      if (!allRequiredAvailable) {
        for (Tuple4<APSServiceTracker, Class, Boolean, List<ServiceRegistration>> requiredService :
            this.requiredServices) {
          if (requiredService.t2.equals(managedClass)) {
            for (ServiceRegistration serviceRegistration : requiredService.t4) {
              try {
                serviceRegistration.unregister();
                requiredService.t3 = false;
                this.services.remove(serviceRegistration);
                this.activatorLogger.warn(
                    "Removed registration for: " + serviceRegistration.getReference());
              } catch (Exception e) {
                this.activatorLogger.error("Bundle stop problem!", e);
              }
            }
          }
        }
      }
    }
  }
Example #19
0
  /**
   * This is used to start delayed service publishing. Each tracker of a required service will be
   * calling this method on first service becoming available. When all required services are
   * available the delayed service will be published.
   *
   * @param service The received service.
   * @param serviceReference The reference to the received service.
   * @throws Exception
   */
  @Override
  public void onServiceAvailable(Object service, ServiceReference serviceReference)
      throws Exception {
    this.activatorLogger.info("Received service: " + service.getClass().getName());
    List<Class> uniqueClasses = new LinkedList<>();
    for (Tuple4<APSServiceTracker, Class, Boolean, List<ServiceRegistration>> requiredService :
        this.requiredServices) {
      if (!uniqueClasses.contains(requiredService.t2)) {
        uniqueClasses.add(requiredService.t2);
      }
    }

    for (Class managedClass : uniqueClasses) {
      boolean allRequiredAvailable = true;
      for (Tuple4<APSServiceTracker, Class, Boolean, List<ServiceRegistration>> requiredService :
          this.requiredServices) {
        if (requiredService.t2.equals(managedClass) && !requiredService.t1.hasTrackedService()) {
          allRequiredAvailable = false;
          this.activatorLogger.info(
              "Not all required services are available yet for: " + managedClass.getName());
          break;
        }
      }

      if (allRequiredAvailable) {
        this.activatorLogger.info(
            "All required services are now available for: " + managedClass.getName());
        for (Tuple4<APSServiceTracker, Class, Boolean, List<ServiceRegistration>> requiredService :
            this.requiredServices) {
          if (requiredService.t2.equals(managedClass) && requiredService.t3 == false) {
            this.activatorLogger.info("Registering services for: " + managedClass.getName());
            registerServices(requiredService.t2, this.context, requiredService.t4);
            this.services.addAll(requiredService.t4);
            requiredService.t3 = true;
          }
        }
      }
    }
  }
  /**
   * Gets the <tt>Endpoint</tt>s participating in/contributing to this <tt>Conference</tt>.
   *
   * @return the <tt>Endpoint</tt>s participating in/contributing to this <tt>Conference</tt>
   */
  public List<Endpoint> getEndpoints() {
    List<Endpoint> endpoints;
    boolean changed = false;

    synchronized (this.endpoints) {
      endpoints = new ArrayList<>(this.endpoints.size());
      for (Iterator<WeakReference<Endpoint>> i = this.endpoints.iterator(); i.hasNext(); ) {
        Endpoint endpoint = i.next().get();

        if (endpoint == null) {
          i.remove();
          changed = true;
        } else {
          endpoints.add(endpoint);
        }
      }
    }

    if (changed) firePropertyChange(ENDPOINTS_PROPERTY_NAME, null, null);

    return endpoints;
  }
Example #21
0
  /**
   * Returns a managed instance of a class.
   *
   * @param managedClass The managed class to get instance for.
   * @param size The number of instances.
   */
  protected List<Object> getManagedInstances(Class managedClass, int size) {
    List<Object> managedInstances = this.managedInstances.get(managedClass);
    if (managedInstances == null) {
      managedInstances = new LinkedList<>();
    }

    if (managedInstances.isEmpty()) {
      if (size == -1) throw new IllegalStateException("Expected instances are not available!");
      try {
        for (int i = 0; i < size; i++) {
          Object managedInstance = managedClass.newInstance();
          managedInstances.add(managedInstance);
          this.managedInstances.put(managedClass, managedInstances);
          this.activatorLogger.info(
              "Instantiated '" + managedClass.getName() + "': " + managedInstance);
        }
      } catch (InstantiationException | IllegalAccessException e) {
        throw new APSActivatorException("Failed to instantiate activator managed class!", e);
      }
    }

    return managedInstances;
  }
  /**
   * Gets a <tt>Content</tt> of this <tt>Conference</tt> which has a specific name. If a
   * <tt>Content</tt> of this <tt>Conference</tt> with the specified <tt>name</tt> does not exist at
   * the time the method is invoked, the method initializes a new <tt>Content</tt> instance with the
   * specified <tt>name</tt> and adds it to the list of <tt>Content</tt>s of this
   * <tt>Conference</tt>.
   *
   * @param name the name of the <tt>Content</tt> which is to be returned
   * @return a <tt>Content</tt> of this <tt>Conference</tt> which has the specified <tt>name</tt>
   */
  public Content getOrCreateContent(String name) {
    Content content;

    synchronized (contents) {
      for (Content aContent : contents) {
        if (aContent.getName().equals(name)) {
          aContent.touch(); // It seems the content is still active.
          return aContent;
        }
      }

      content = new Content(this, name);
      if (isRecording()) {
        content.setRecording(true, getRecordingPath());
      }
      contents.add(content);
    }

    if (logger.isInfoEnabled()) {
      /*
       * The method Videobridge.getChannelCount() should better be
       * executed outside synchronized blocks in order to reduce the risks
       * of causing deadlocks.
       */
      Videobridge videobridge = getVideobridge();

      logger.info(
          "Created content "
              + name
              + " of conference "
              + getID()
              + ". "
              + videobridge.getConferenceCountString());
    }

    return content;
  }
Example #23
0
 /**
  * Adds an instance to manage.
  *
  * @param instance The instance to add.
  */
 public void addManagedInstance(Object instance) {
   List<Object> instances = new LinkedList<>();
   instances.add(instance);
   this.managedInstances.put(instance.getClass(), instances);
 }
Example #24
0
 /**
  * Adds a specific <tt>UserCapsNodeListener</tt> to the list of <tt>UserCapsNodeListener</tt>s
  * interested in events notifying about changes in the list of user caps nodes of this
  * <tt>EntityCapsManager</tt>.
  *
  * @param listener the <tt>UserCapsNodeListener</tt> which is interested in events notifying about
  *     changes in the list of user caps nodes of this <tt>EntityCapsManager</tt>
  */
 public void addUserCapsNodeListener(UserCapsNodeListener listener) {
   if (listener == null) throw new NullPointerException("listener");
   synchronized (userCapsNodeListeners) {
     if (!userCapsNodeListeners.contains(listener)) userCapsNodeListeners.add(listener);
   }
 }
Example #25
0
  /**
   * Registers/publishes services annotated with @OSGiServiceProvider.
   *
   * @param managedClass The managed class to instantiate and register as an OSGi service.
   * @param context The bundle context.
   * @param serviceRegs The list to save all service registrations to for later unregistration.
   * @throws Exception
   */
  protected void registerServices(
      Class managedClass, BundleContext context, List<ServiceRegistration> serviceRegs)
      throws Exception {
    OSGiServiceProvider serviceProvider =
        (OSGiServiceProvider) managedClass.getAnnotation(OSGiServiceProvider.class);
    if (serviceProvider != null) {
      List<Tuple3<Properties, Object, List<String>>> serviceInstData = new LinkedList<>();

      if (serviceProvider.properties().length > 0) {
        Tuple3<Properties, Object, List<String>> sd = new Tuple3<>();
        sd.t1 = osgiPropertiesToProperties(serviceProvider.properties());
        serviceInstData.add(sd);
      } else if (serviceProvider.instances().length > 0) {
        for (OSGiServiceInstance serviceInst : serviceProvider.instances()) {
          Tuple3<Properties, Object, List<String>> sd = new Tuple3<>();
          sd.t1 = osgiPropertiesToProperties(serviceInst.properties());
          serviceInstData.add(sd);
        }
      } else if (!serviceProvider.instanceFactoryClass().equals(InstanceFactory.class)) {
        InstanceFactory instanceFactory =
            (InstanceFactory) getManagedInstance(serviceProvider.instanceFactoryClass());
        if (instanceFactory == null) {
          instanceFactory = serviceProvider.instanceFactoryClass().newInstance();
        }
        for (Properties props : instanceFactory.getPropertiesPerInstance()) {
          Tuple3<Properties, Object, List<String>> sd = new Tuple3<>();
          sd.t1 = props;
          serviceInstData.add(sd);
        }
      } else {
        Tuple3<Properties, Object, List<String>> sd = new Tuple3<>();
        sd.t1 = new Properties();
        serviceInstData.add(sd);
      }

      // The number of managedInstances and serviceInstData will always be the same. They both
      // originate
      // from the same information.
      List<Object> managedInstances = getManagedInstances(managedClass);
      for (int i = 0; i < serviceInstData.size(); i++) {

        List<String> serviceAPIs = new LinkedList<>();

        if (serviceProvider.serviceAPIs().length > 0) {
          for (Class svcAPI : serviceProvider.serviceAPIs()) {
            serviceAPIs.add(svcAPI.getName());
          }
        } else if (serviceProvider.instances().length > 0) {
          OSGiServiceInstance svsInstAnn = serviceProvider.instances()[i];
          for (Class svcAPI : svsInstAnn.serviceAPIs()) {
            serviceAPIs.add(svcAPI.getName());
          }
        } else if (!serviceProvider.instanceFactoryClass().equals(InstanceFactory.class)) {
          String svcAPIList =
              serviceInstData.get(i).t1.getProperty(InstanceFactory.SERVICE_API_CLASSES_PROPERTY);
          if (svcAPIList != null) {
            for (String svcAPI : svcAPIList.split(":")) {
              serviceAPIs.add(svcAPI);
            }
          } else {
            Class[] interfaces = managedClass.getInterfaces();
            if (interfaces != null && interfaces.length > 0) {
              serviceAPIs.add(interfaces[0].getName());
            }
          }
        } else {
          Class[] interfaces = managedClass.getInterfaces();
          if (interfaces != null && interfaces.length > 0) {
            serviceAPIs.add(interfaces[0].getName());
          }
        }

        Tuple3<Properties, Object, List<String>> sd = serviceInstData.get(i);
        sd.t3 = serviceAPIs;
        sd.t2 = managedInstances.get(i);
      }

      for (Tuple3<Properties, Object, List<String>> sd : serviceInstData) {
        sd.t1.put(Constants.SERVICE_PID, managedClass.getName());
        if (!sd.t3.isEmpty()) {
          injectInstanceProps(sd.t2, sd.t1);
          for (String svcAPI : sd.t3) {
            ServiceRegistration serviceReg = context.registerService(svcAPI, sd.t2, sd.t1);

            serviceRegs.add(serviceReg);
            this.activatorLogger.info(
                "Registered '"
                    + managedClass.getName()
                    + "' as a service provider of '"
                    + svcAPI
                    + "' for bundle: "
                    + context.getBundle().getSymbolicName()
                    + "!");
          }
        } else {
          throw new IllegalArgumentException(
              "The @OSGiServiceProvider annotated service of class '"
                  + managedClass.getName()
                  + "' does not implement a service interface!");
        }
      }
    }
  }