Decoupled the DataMiningServerImpl from the BundleContext

This allowed me to write a test for the function registry update
mechanism.
This commit is contained in:
Lennart Hensler committed 2014-06-09 23:19:43 +02:00
1 parent a95e89fa0e
commit affe1e2990
9 files changed
+235 -117

No files matched your search

@@ -5,7 +5,7 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import com.sap.sailing.datamining.impl.data.SailingDataMiningClassesWithFunctionsService;
import com.sap.sse.datamining.functions.ClassesWithFunctionsService;
import com.sap.sse.datamining.ClassesWithFunctionsService;
public class Activator implements BundleActivator {
@@ -4,7 +4,7 @@ import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sse.datamining.functions.ClassesWithFunctionsService;
import com.sap.sse.datamining.ClassesWithFunctionsService;
public class SailingDataMiningClassesWithFunctionsService implements ClassesWithFunctionsService {
@@ -0,0 +1,90 @@
package com.sap.sse.datamining.impl;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.junit.BeforeClass;
import org.junit.Test;
import com.sap.sse.datamining.ClassesWithFunctionsProvider;
import com.sap.sse.datamining.DataMiningServer;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.FunctionProvider;
import com.sap.sse.datamining.functions.FunctionRegistry;
import com.sap.sse.datamining.impl.functions.RegistryFunctionProvider;
import com.sap.sse.datamining.impl.functions.SimpleFunctionRegistry;
import com.sap.sse.datamining.test.functions.registry.test_contexts.Test_HasLegContext;
import com.sap.sse.datamining.test.functions.registry.test_contexts.Test_HasRaceContext;
import com.sap.sse.datamining.test.util.ExpectedFunctionRegistryUtil;
public class TestDataMiningServer {
private static ExpectedFunctionRegistryUtil expectedFunctionRegistryUtil;
@BeforeClass
public static void intializeExpectedFunctions() throws NoSuchMethodException, SecurityException {
expectedFunctionRegistryUtil = new ExpectedFunctionRegistryUtil();
}
@Test
public void testThatTheFunctionRegistryIsAllwaysUpToDate() {
FunctionRegistry registry = new SimpleFunctionRegistry();
FunctionProvider provider = new RegistryFunctionProvider(registry);
OpenClassesWithFunctionsProvider classesWithFunctionsProvider = new OpenClassesWithFunctionsProvider();
DataMiningServer server = new DataMiningServerImpl(registry, provider, classesWithFunctionsProvider);
assertThat("The function registry should be empty.",
server.getFunctionRegistry().getAllFunctions().isEmpty(),
is(true));
classesWithFunctionsProvider.internalClassesWithMarkedMethods.add(Test_HasLegContext.class);
Collection<Function<?>> expectedFunctions = new HashSet<>();
expectedFunctions.addAll(expectedFunctionRegistryUtil.getExpectedFunctionsFor(Test_HasLegContext.class));
expectedFunctions.addAll(expectedFunctionRegistryUtil.getExpectedFunctionsFor(Test_HasRaceContext.class));
assertThat(server.getFunctionRegistry().getAllFunctions(), is(expectedFunctions));
classesWithFunctionsProvider.internalClassesWithMarkedMethods.remove(Test_HasLegContext.class);
classesWithFunctionsProvider.internalClassesWithMarkedMethods.add(Test_HasRaceContext.class);
expectedFunctions = expectedFunctionRegistryUtil.getExpectedFunctionsFor(Test_HasRaceContext.class);
assertThat(server.getFunctionRegistry().getAllFunctions(), is(expectedFunctions));
}
@Test
public void testThatTheRegistryUpdateWorksWithNullCollections() {
FunctionRegistry registry = new SimpleFunctionRegistry();
FunctionProvider provider = new RegistryFunctionProvider(registry);
OpenClassesWithFunctionsProvider classesWithFunctionsProvider = new OpenClassesWithFunctionsProvider();
DataMiningServer server = new DataMiningServerImpl(registry, provider, classesWithFunctionsProvider);
classesWithFunctionsProvider.internalClassesWithMarkedMethods = null;
classesWithFunctionsProvider.externalLibraryClasses = null;
server.getFunctionRegistry();
}
private class OpenClassesWithFunctionsProvider implements ClassesWithFunctionsProvider {
public Set<Class<?>> internalClassesWithMarkedMethods;
public Set<Class<?>> externalLibraryClasses;
public OpenClassesWithFunctionsProvider() {
internalClassesWithMarkedMethods = new HashSet<>();
externalLibraryClasses = new HashSet<>();
}
@Override
public Set<Class<?>> getInternalClassesWithMarkedMethods() {
return internalClassesWithMarkedMethods;
}
@Override
public Set<Class<?>> getExternalLibraryClasses() {
return externalLibraryClasses;
}
}
}
@@ -21,14 +21,14 @@ import com.sap.sse.datamining.test.util.ExpectedFunctionRegistryUtil;
public class TestSimpleFunctionRegistry {
private static ExpectedFunctionRegistryUtil functionRegistryUtil;
private static ExpectedFunctionRegistryUtil expectedFunctionRegistryUtil;
private Set<Class<?>> internalClassesToScan;
private HashSet<Class<?>> externalClassesToScan;
@BeforeClass
public static void intializeExpectedFunctions() throws NoSuchMethodException, SecurityException {
functionRegistryUtil = new ExpectedFunctionRegistryUtil();
expectedFunctionRegistryUtil = new ExpectedFunctionRegistryUtil();
}
@Before
@@ -48,14 +48,14 @@ public class TestSimpleFunctionRegistry {
registry.registerAllWithExternalFunctionPolicy(externalClassesToScan);
Collection<Function<?>> expectedDimensions = new HashSet<>();
expectedDimensions.addAll(functionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class));
expectedDimensions.addAll(functionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class));
expectedDimensions.addAll(expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class));
expectedDimensions.addAll(expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class));
assertThat(registry.getDimensions(), is(expectedDimensions));
Collection<Function<?>> expectedStatistics = functionRegistryUtil.getExpectedStatisticsFor(Test_HasLegContext.class);
Collection<Function<?>> expectedStatistics = expectedFunctionRegistryUtil.getExpectedStatisticsFor(Test_HasLegContext.class);
assertThat(registry.getStatistics(), is(expectedStatistics));
Collection<Function<?>> expectedExternalFunctions = functionRegistryUtil.getExpectedExternalFunctionsFor(Test_ExternalLibraryClass.class);
Collection<Function<?>> expectedExternalFunctions = expectedFunctionRegistryUtil.getExpectedExternalFunctionsFor(Test_ExternalLibraryClass.class);
assertThat(registry.getExternalFunctions(), is(expectedExternalFunctions));
}
@@ -65,15 +65,15 @@ public class TestSimpleFunctionRegistry {
registry.registerAllWithInternalFunctionPolicy(internalClassesToScan);
Collection<Function<?>> expectedDimensions = new HashSet<>();
expectedDimensions.addAll(functionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class));
expectedDimensions.addAll(functionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class));
expectedDimensions.addAll(expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class));
expectedDimensions.addAll(expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class));
assertThat(registry.getDimensions(), is(expectedDimensions));
Set<Class<?>> classesToUnregister = new HashSet<>();
classesToUnregister.add(Test_HasLegContext.class);
registry.unregisterAllFunctionsOf(classesToUnregister);
expectedDimensions = functionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class);
expectedDimensions = expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class);
assertThat(registry.getDimensions(), is(expectedDimensions));
registry.registerAllWithInternalFunctionPolicy(internalClassesToScan);
@@ -81,7 +81,7 @@ public class TestSimpleFunctionRegistry {
classesToUnregister.add(Test_HasRaceContext.class);
registry.unregisterAllFunctionsOf(classesToUnregister);
expectedDimensions = functionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class);
expectedDimensions = expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class);
assertThat(registry.getDimensions(), is(expectedDimensions));
}
@@ -1,10 +1,12 @@
package com.sap.sse.datamining.test.util;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import com.sap.sse.datamining.factories.FunctionFactory;
import com.sap.sse.datamining.functions.Function;
@@ -111,15 +113,26 @@ public class ExpectedFunctionRegistryUtil {
}
public Collection<Function<?>> getExpectedDimensionsFor(Class<?> declaringType) {
return expectedDimensions.get(declaringType);
Collection<Function<?>> expectedDimensions = this.expectedDimensions.get(declaringType);
return expectedDimensions != null ? expectedDimensions : new ArrayList<Function<?>>();
}
public Collection<Function<?>> getExpectedStatisticsFor(Class<?> declaringType) {
return expectedStatistics.get(declaringType);
Collection<Function<?>> expectedStatistics = this.expectedStatistics.get(declaringType);
return expectedStatistics != null ? expectedStatistics : new ArrayList<Function<?>>();
}
public Collection<Function<?>> getExpectedExternalFunctionsFor(Class<?> declaringType) {
return expectedExternalFunctions.get(declaringType);
Collection<Function<?>> expectedExternalFunctions = this.expectedExternalFunctions.get(declaringType);
return expectedExternalFunctions != null ? expectedExternalFunctions : new ArrayList<Function<?>>();
}
public Set<Function<?>> getExpectedFunctionsFor(Class<?> declaringType) {
Set<Function<?>> expectedFunctions = new HashSet<>();
expectedFunctions.addAll(getExpectedDimensionsFor(declaringType));
expectedFunctions.addAll(getExpectedStatisticsFor(declaringType));
expectedFunctions.addAll(getExpectedExternalFunctionsFor(declaringType));
return expectedFunctions;
}
}
@@ -0,0 +1,10 @@
package com.sap.sse.datamining;
import java.util.Set;
public interface ClassesWithFunctionsProvider {
public Set<Class<?>> getInternalClassesWithMarkedMethods();
public Set<Class<?>> getExternalLibraryClasses();
}
@@ -1,4 +1,4 @@
package com.sap.sse.datamining.functions;
package com.sap.sse.datamining;
import java.util.Set;
@@ -1,12 +1,22 @@
package com.sap.sse.datamining.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import com.sap.sse.datamining.ClassesWithFunctionsProvider;
import com.sap.sse.datamining.ClassesWithFunctionsService;
import com.sap.sse.datamining.DataMiningServer;
import com.sap.sse.datamining.functions.FunctionProvider;
import com.sap.sse.datamining.functions.FunctionRegistry;
@@ -14,9 +24,9 @@ import com.sap.sse.datamining.i18n.DataMiningStringMessages;
import com.sap.sse.datamining.impl.functions.RegistryFunctionProvider;
import com.sap.sse.datamining.impl.functions.SimpleFunctionRegistry;
public class DataMiningActivator implements BundleActivator {
public class DataMiningActivator implements BundleActivator, ClassesWithFunctionsProvider {
// private static final Logger LOGGER = Logger.getLogger(DataMiningActivator.class.getName());
private static final Logger LOGGER = Logger.getLogger(DataMiningActivator.class.getName());
private static final int THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors(), 3);
private static BundleContext context;
@@ -34,7 +44,7 @@ public class DataMiningActivator implements BundleActivator {
FunctionRegistry functionRegistry = new SimpleFunctionRegistry();
FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry);
dataMiningServer = new DataMiningServerImpl(functionRegistry, functionProvider);
dataMiningServer = new DataMiningServerImpl(functionRegistry, functionProvider, this);
registerDataMiningServer();
}
@@ -58,4 +68,63 @@ public class DataMiningActivator implements BundleActivator {
return context;
}
@Override
public Set<Class<?>> getInternalClassesWithMarkedMethods() {
Set<Class<?>> internalClassesWithMarkedMethods = new HashSet<>();
for (ServiceReference<ClassesWithFunctionsService> serviceReference : getAllClassesWithMarkedMethodsServices()) {
internalClassesWithMarkedMethods.addAll(getInternalClassesWithMarkedMethodsFromService(serviceReference));
}
return internalClassesWithMarkedMethods;
}
@Override
public Set<Class<?>> getExternalLibraryClasses() {
Set<Class<?>> externalLibraryClasses = new HashSet<>();
for (ServiceReference<ClassesWithFunctionsService> serviceReference : getAllClassesWithMarkedMethodsServices()) {
externalLibraryClasses.addAll(getExternalLibraryClassesFromService(serviceReference));
}
return externalLibraryClasses;
}
private Collection<ServiceReference<ClassesWithFunctionsService>> getAllClassesWithMarkedMethodsServices() {
try {
ServiceReference<?>[] serviceReferences = context.getServiceReferences(ClassesWithFunctionsService.class.getName(), null);
if (serviceReferences != null) {
return castServiceReferences(serviceReferences);
}
} catch (InvalidSyntaxException e) {
LOGGER.log(Level.SEVERE, "Error getting the service references. Data mining won't work.", e);
}
LOGGER.log(Level.SEVERE, "There were no " + ClassesWithFunctionsService.class.getName() + "-Services registered. Data mining won't work.");
return new ArrayList<>();
}
private Collection<ServiceReference<ClassesWithFunctionsService>> castServiceReferences(ServiceReference<?>[] serviceReferences) {
Collection<ServiceReference<ClassesWithFunctionsService>> specificServiceReferences = new ArrayList<>();
for (ServiceReference<?> serviceReference : serviceReferences) {
try {
@SuppressWarnings("unchecked") // This is necessary, because you can't use instanceof with specific generics
ServiceReference<ClassesWithFunctionsService> specificServiceReference = (ServiceReference<ClassesWithFunctionsService>) serviceReference;
specificServiceReferences.add(specificServiceReference);
} catch (ClassCastException exception) {
String serviceName = context.getService(serviceReference).getClass().getName();
LOGGER.log(Level.WARNING, "Couldn't register the service '" + serviceName + "' to the function registry."
+ " Data mining functionalities will be restricted.", exception);
}
}
return specificServiceReferences;
}
private Collection<Class<?>> getInternalClassesWithMarkedMethodsFromService(ServiceReference<ClassesWithFunctionsService> serviceReference) {
Collection<Class<?>> internalClassesWithMarkedMethods = context.getService(serviceReference).getInternalClassesWithMarkedMethods();
return internalClassesWithMarkedMethods != null ? internalClassesWithMarkedMethods : new ArrayList<Class<?>>();
}
private Collection<Class<?>> getExternalLibraryClassesFromService(ServiceReference<ClassesWithFunctionsService> serviceReference) {
Collection<Class<?>> externalLibraryClasses = context.getService(serviceReference).getExternalLibraryClasses();
return externalLibraryClasses != null ? externalLibraryClasses : new ArrayList<Class<?>>();
}
}
@@ -4,34 +4,28 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import com.sap.sse.datamining.ClassesWithFunctionsProvider;
import com.sap.sse.datamining.DataMiningServer;
import com.sap.sse.datamining.functions.ClassesWithFunctionsService;
import com.sap.sse.datamining.functions.FunctionProvider;
import com.sap.sse.datamining.functions.FunctionRegistry;
public class DataMiningServerImpl implements DataMiningServer {
private static final Logger LOGGER = Logger.getLogger(DataMiningServerImpl.class.getSimpleName());
private final BundleContext context;
private final Set<ServiceReference<ClassesWithFunctionsService>> registeredServices;
private final Set<Class<?>> registeredInternalClassesWithMarkedMethods;
private final Set<Class<?>> registeredExternalLibraryClasses;
private final FunctionRegistry functionRegistry;
private final FunctionProvider functionProvider;
private ClassesWithFunctionsProvider classesWithFunctionsProvider;
public DataMiningServerImpl(FunctionRegistry functionRegistry, FunctionProvider functionProvider) {
context = DataMiningActivator.getContext();
registeredServices = new HashSet<>();
public DataMiningServerImpl(FunctionRegistry functionRegistry, FunctionProvider functionProvider, ClassesWithFunctionsProvider classesWithFunctionsProvider) {
registeredInternalClassesWithMarkedMethods = new HashSet<>();
registeredExternalLibraryClasses = new HashSet<>();
this.functionRegistry = functionRegistry;
this.functionProvider = functionProvider;
this.classesWithFunctionsProvider = classesWithFunctionsProvider;
updateRegistryIfNecessary();
}
@@ -49,97 +43,39 @@ public class DataMiningServerImpl implements DataMiningServer {
}
private void updateRegistryIfNecessary() {
Collection<ServiceReference<ClassesWithFunctionsService>> availableServices = getAllClassesWithMarkedMethodsServices();
Collection<ServiceReference<ClassesWithFunctionsService>> servicesToRegister = calculateServicesToRegister(availableServices);
Collection<ServiceReference<ClassesWithFunctionsService>> servicesToUnregister = calculateServicesToUnregister(availableServices);
Collection<Class<?>> availableInternalClassesWithMarkedMethods = classesWithFunctionsProvider.getInternalClassesWithMarkedMethods();
Collection<Class<?>> internalClassesWithMarkedMethodsToRegister = getMissingElements(/*from*/ availableInternalClassesWithMarkedMethods, /*in*/ registeredInternalClassesWithMarkedMethods);
Collection<Class<?>> internalClassesWithMarkedMethodsToUnregister = getMissingElements(/*from*/ registeredInternalClassesWithMarkedMethods, /*in*/ availableInternalClassesWithMarkedMethods);
registerServices(servicesToRegister);
unregisterServices(servicesToUnregister);
functionRegistry.unregisterAllFunctionsOf(internalClassesWithMarkedMethodsToUnregister);
registeredInternalClassesWithMarkedMethods.removeAll(internalClassesWithMarkedMethodsToUnregister);
functionRegistry.registerAllWithInternalFunctionPolicy(internalClassesWithMarkedMethodsToRegister);
registeredInternalClassesWithMarkedMethods.addAll(internalClassesWithMarkedMethodsToRegister);
Collection<Class<?>> availableExternalLibraryClasses = classesWithFunctionsProvider.getExternalLibraryClasses();
Collection<Class<?>> externalLibraryClassesToRegister = getMissingElements(/*from*/ availableExternalLibraryClasses, /*in*/ registeredExternalLibraryClasses);
Collection<Class<?>> externalLibraryClassesToUnregister = getMissingElements(/*from*/ registeredExternalLibraryClasses, /*in*/ availableExternalLibraryClasses);
functionRegistry.unregisterAllFunctionsOf(externalLibraryClassesToUnregister);
registeredExternalLibraryClasses.retainAll(externalLibraryClassesToUnregister);
functionRegistry.registerAllWithExternalFunctionPolicy(externalLibraryClassesToRegister);
registeredExternalLibraryClasses.addAll(externalLibraryClassesToRegister);
}
private Collection<ServiceReference<ClassesWithFunctionsService>> calculateServicesToRegister(
Collection<ServiceReference<ClassesWithFunctionsService>> availableServices) {
Collection<ServiceReference<ClassesWithFunctionsService>> servicesToRegister = new ArrayList<>();
private Collection<Class<?>> getMissingElements(Collection<Class<?>> from, Collection<Class<?>> in) {
if (from == null) {
return new ArrayList<>();
}
for (ServiceReference<ClassesWithFunctionsService> availableService : availableServices) {
if (!registeredServices.contains(availableService)) {
servicesToRegister.add(availableService);
Collection<Class<?>> missingElements = new HashSet<>();
for (Class<?> element : from) {
if (!in.contains(element)) {
missingElements.add(element);
}
}
return servicesToRegister;
}
private Collection<ServiceReference<ClassesWithFunctionsService>> calculateServicesToUnregister(
Collection<ServiceReference<ClassesWithFunctionsService>> availableServices) {
Collection<ServiceReference<ClassesWithFunctionsService>> servicesToUnregister = new ArrayList<>();
for (ServiceReference<ClassesWithFunctionsService> registeredService : registeredServices) {
if (!availableServices.contains(registeredService)) {
servicesToUnregister.add(registeredService);
}
}
return servicesToUnregister;
}
private void registerServices(Collection<ServiceReference<ClassesWithFunctionsService>> servicesToRegister) {
Set<Class<?>> internalClassesWithMarkedMethods = new HashSet<>();
Set<Class<?>> externalLibraryClasses = new HashSet<>();
for (ServiceReference<ClassesWithFunctionsService> serviceReference : servicesToRegister) {
internalClassesWithMarkedMethods.addAll(getInternalClassesWithMarkedMethodsFromService(serviceReference));
externalLibraryClasses.addAll(getExternalLibraryClassesFromService(serviceReference));
}
functionRegistry.registerAllWithInternalFunctionPolicy(internalClassesWithMarkedMethods);
functionRegistry.registerAllWithExternalFunctionPolicy(externalLibraryClasses);
}
private void unregisterServices(Collection<ServiceReference<ClassesWithFunctionsService>> servicesToUnregister) {
Set<Class<?>> classesToUnregister = new HashSet<>();
for (ServiceReference<ClassesWithFunctionsService> serviceReference : servicesToUnregister) {
classesToUnregister.addAll(getInternalClassesWithMarkedMethodsFromService(serviceReference));
classesToUnregister.addAll(getExternalLibraryClassesFromService(serviceReference));
}
functionRegistry.unregisterAllFunctionsOf(classesToUnregister);
}
private Collection<Class<?>> getInternalClassesWithMarkedMethodsFromService(ServiceReference<ClassesWithFunctionsService> serviceReference) {
Collection<Class<?>> internalClassesWithMarkedMethods = context.getService(serviceReference).getInternalClassesWithMarkedMethods();
return internalClassesWithMarkedMethods != null ? internalClassesWithMarkedMethods : new ArrayList<Class<?>>();
}
private Collection<Class<?>> getExternalLibraryClassesFromService(ServiceReference<ClassesWithFunctionsService> serviceReference) {
Collection<Class<?>> externalLibraryClasses = context.getService(serviceReference).getExternalLibraryClasses();
return externalLibraryClasses != null ? externalLibraryClasses : new ArrayList<Class<?>>();
}
private Collection<ServiceReference<ClassesWithFunctionsService>> getAllClassesWithMarkedMethodsServices() {
try {
ServiceReference<?>[] serviceReferences = context.getServiceReferences(ClassesWithFunctionsService.class.getName(), null);
if (serviceReferences != null) {
return castServiceReferences(serviceReferences);
}
} catch (InvalidSyntaxException e) {
LOGGER.log(Level.SEVERE, "Error getting the service references. Data mining won't work.", e);
}
LOGGER.log(Level.SEVERE, "There were no " + ClassesWithFunctionsService.class.getName() + "-Services registered. Data mining won't work.");
return new ArrayList<>();
}
private Collection<ServiceReference<ClassesWithFunctionsService>> castServiceReferences(ServiceReference<?>[] serviceReferences) {
Collection<ServiceReference<ClassesWithFunctionsService>> specificServiceReferences = new ArrayList<>();
for (ServiceReference<?> serviceReference : serviceReferences) {
try {
@SuppressWarnings("unchecked") // This is necessary, because you can't use instanceof with specific generics
ServiceReference<ClassesWithFunctionsService> specificServiceReference = (ServiceReference<ClassesWithFunctionsService>) serviceReference;
specificServiceReferences.add(specificServiceReference);
} catch (ClassCastException exception) {
String serviceName = context.getService(serviceReference).getClass().getName();
LOGGER.log(Level.WARNING, "Couldn't register the service '" + serviceName + "' to the function registry."
+ " Data mining functionalities will be restricted.", exception);
}
}
return specificServiceReferences;
return missingElements;
}
}