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
+234 -116

No files matched your search

@@ -5,7 +5,7 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration; import org.osgi.framework.ServiceRegistration;
import com.sap.sailing.datamining.impl.data.SailingDataMiningClassesWithFunctionsService; 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 { public class Activator implements BundleActivator {
@@ -4,7 +4,7 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import com.sap.sailing.datamining.data.HasGPSFixContext; 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 { 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 { public class TestSimpleFunctionRegistry {
private static ExpectedFunctionRegistryUtil functionRegistryUtil; private static ExpectedFunctionRegistryUtil expectedFunctionRegistryUtil;
private Set<Class<?>> internalClassesToScan; private Set<Class<?>> internalClassesToScan;
private HashSet<Class<?>> externalClassesToScan; private HashSet<Class<?>> externalClassesToScan;
@BeforeClass @BeforeClass
public static void intializeExpectedFunctions() throws NoSuchMethodException, SecurityException { public static void intializeExpectedFunctions() throws NoSuchMethodException, SecurityException {
functionRegistryUtil = new ExpectedFunctionRegistryUtil(); expectedFunctionRegistryUtil = new ExpectedFunctionRegistryUtil();
} }
@Before @Before
@@ -48,14 +48,14 @@ public class TestSimpleFunctionRegistry {
registry.registerAllWithExternalFunctionPolicy(externalClassesToScan); registry.registerAllWithExternalFunctionPolicy(externalClassesToScan);
Collection<Function<?>> expectedDimensions = new HashSet<>(); Collection<Function<?>> expectedDimensions = new HashSet<>();
expectedDimensions.addAll(functionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class)); expectedDimensions.addAll(expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class));
expectedDimensions.addAll(functionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class)); expectedDimensions.addAll(expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class));
assertThat(registry.getDimensions(), is(expectedDimensions)); 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)); 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)); assertThat(registry.getExternalFunctions(), is(expectedExternalFunctions));
} }
@@ -65,15 +65,15 @@ public class TestSimpleFunctionRegistry {
registry.registerAllWithInternalFunctionPolicy(internalClassesToScan); registry.registerAllWithInternalFunctionPolicy(internalClassesToScan);
Collection<Function<?>> expectedDimensions = new HashSet<>(); Collection<Function<?>> expectedDimensions = new HashSet<>();
expectedDimensions.addAll(functionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class)); expectedDimensions.addAll(expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class));
expectedDimensions.addAll(functionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class)); expectedDimensions.addAll(expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class));
assertThat(registry.getDimensions(), is(expectedDimensions)); assertThat(registry.getDimensions(), is(expectedDimensions));
Set<Class<?>> classesToUnregister = new HashSet<>(); Set<Class<?>> classesToUnregister = new HashSet<>();
classesToUnregister.add(Test_HasLegContext.class); classesToUnregister.add(Test_HasLegContext.class);
registry.unregisterAllFunctionsOf(classesToUnregister); registry.unregisterAllFunctionsOf(classesToUnregister);
expectedDimensions = functionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class); expectedDimensions = expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class);
assertThat(registry.getDimensions(), is(expectedDimensions)); assertThat(registry.getDimensions(), is(expectedDimensions));
registry.registerAllWithInternalFunctionPolicy(internalClassesToScan); registry.registerAllWithInternalFunctionPolicy(internalClassesToScan);
@@ -81,7 +81,7 @@ public class TestSimpleFunctionRegistry {
classesToUnregister.add(Test_HasRaceContext.class); classesToUnregister.add(Test_HasRaceContext.class);
registry.unregisterAllFunctionsOf(classesToUnregister); registry.unregisterAllFunctionsOf(classesToUnregister);
expectedDimensions = functionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class); expectedDimensions = expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasLegContext.class);
assertThat(registry.getDimensions(), is(expectedDimensions)); assertThat(registry.getDimensions(), is(expectedDimensions));
} }
@@ -1,10 +1,12 @@
package com.sap.sse.datamining.test.util; package com.sap.sse.datamining.test.util;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set;
import com.sap.sse.datamining.factories.FunctionFactory; import com.sap.sse.datamining.factories.FunctionFactory;
import com.sap.sse.datamining.functions.Function; import com.sap.sse.datamining.functions.Function;
@@ -111,15 +113,26 @@ public class ExpectedFunctionRegistryUtil {
} }
public Collection<Function<?>> getExpectedDimensionsFor(Class<?> declaringType) { 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) { 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) { 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; import java.util.Set;
@@ -1,12 +1,22 @@
package com.sap.sse.datamining.impl; 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.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext; 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.DataMiningServer;
import com.sap.sse.datamining.functions.FunctionProvider; import com.sap.sse.datamining.functions.FunctionProvider;
import com.sap.sse.datamining.functions.FunctionRegistry; 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.RegistryFunctionProvider;
import com.sap.sse.datamining.impl.functions.SimpleFunctionRegistry; 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 final int THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors(), 3);
private static BundleContext context; private static BundleContext context;
@@ -34,7 +44,7 @@ public class DataMiningActivator implements BundleActivator {
FunctionRegistry functionRegistry = new SimpleFunctionRegistry(); FunctionRegistry functionRegistry = new SimpleFunctionRegistry();
FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry); FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry);
dataMiningServer = new DataMiningServerImpl(functionRegistry, functionProvider); dataMiningServer = new DataMiningServerImpl(functionRegistry, functionProvider, this);
registerDataMiningServer(); registerDataMiningServer();
} }
@@ -58,4 +68,63 @@ public class DataMiningActivator implements BundleActivator {
return context; 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.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; 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.DataMiningServer;
import com.sap.sse.datamining.functions.ClassesWithFunctionsService;
import com.sap.sse.datamining.functions.FunctionProvider; import com.sap.sse.datamining.functions.FunctionProvider;
import com.sap.sse.datamining.functions.FunctionRegistry; import com.sap.sse.datamining.functions.FunctionRegistry;
public class DataMiningServerImpl implements DataMiningServer { public class DataMiningServerImpl implements DataMiningServer {
private static final Logger LOGGER = Logger.getLogger(DataMiningServerImpl.class.getSimpleName()); private final Set<Class<?>> registeredInternalClassesWithMarkedMethods;
private final Set<Class<?>> registeredExternalLibraryClasses;
private final BundleContext context;
private final Set<ServiceReference<ClassesWithFunctionsService>> registeredServices;
private final FunctionRegistry functionRegistry; private final FunctionRegistry functionRegistry;
private final FunctionProvider functionProvider; private final FunctionProvider functionProvider;
private ClassesWithFunctionsProvider classesWithFunctionsProvider;
public DataMiningServerImpl(FunctionRegistry functionRegistry, FunctionProvider functionProvider) { public DataMiningServerImpl(FunctionRegistry functionRegistry, FunctionProvider functionProvider, ClassesWithFunctionsProvider classesWithFunctionsProvider) {
context = DataMiningActivator.getContext(); registeredInternalClassesWithMarkedMethods = new HashSet<>();
registeredServices = new HashSet<>(); registeredExternalLibraryClasses = new HashSet<>();
this.functionRegistry = functionRegistry; this.functionRegistry = functionRegistry;
this.functionProvider = functionProvider; this.functionProvider = functionProvider;
this.classesWithFunctionsProvider = classesWithFunctionsProvider;
updateRegistryIfNecessary(); updateRegistryIfNecessary();
} }
@@ -49,97 +43,39 @@ public class DataMiningServerImpl implements DataMiningServer {
} }
private void updateRegistryIfNecessary() { private void updateRegistryIfNecessary() {
Collection<ServiceReference<ClassesWithFunctionsService>> availableServices = getAllClassesWithMarkedMethodsServices(); Collection<Class<?>> availableInternalClassesWithMarkedMethods = classesWithFunctionsProvider.getInternalClassesWithMarkedMethods();
Collection<ServiceReference<ClassesWithFunctionsService>> servicesToRegister = calculateServicesToRegister(availableServices); Collection<Class<?>> internalClassesWithMarkedMethodsToRegister = getMissingElements(/*from*/ availableInternalClassesWithMarkedMethods, /*in*/ registeredInternalClassesWithMarkedMethods);
Collection<ServiceReference<ClassesWithFunctionsService>> servicesToUnregister = calculateServicesToUnregister(availableServices); Collection<Class<?>> internalClassesWithMarkedMethodsToUnregister = getMissingElements(/*from*/ registeredInternalClassesWithMarkedMethods, /*in*/ availableInternalClassesWithMarkedMethods);
registerServices(servicesToRegister); functionRegistry.unregisterAllFunctionsOf(internalClassesWithMarkedMethodsToUnregister);
unregisterServices(servicesToUnregister); 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( private Collection<Class<?>> getMissingElements(Collection<Class<?>> from, Collection<Class<?>> in) {
Collection<ServiceReference<ClassesWithFunctionsService>> availableServices) { if (from == null) {
Collection<ServiceReference<ClassesWithFunctionsService>> servicesToRegister = new ArrayList<>();
for (ServiceReference<ClassesWithFunctionsService> availableService : availableServices) {
if (!registeredServices.contains(availableService)) {
servicesToRegister.add(availableService);
}
}
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<>(); return new ArrayList<>();
} }
private Collection<ServiceReference<ClassesWithFunctionsService>> castServiceReferences(ServiceReference<?>[] serviceReferences) { Collection<Class<?>> missingElements = new HashSet<>();
Collection<ServiceReference<ClassesWithFunctionsService>> specificServiceReferences = new ArrayList<>();
for (ServiceReference<?> serviceReference : serviceReferences) { for (Class<?> element : from) {
try { if (!in.contains(element)) {
@SuppressWarnings("unchecked") // This is necessary, because you can't use instanceof with specific generics missingElements.add(element);
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;
} }
} }