Introduced a function registry update mechanism

This commit is contained in:
Lennart Hensler committed 2014-06-06 12:27:13 +02:00
1 parent ff8b36173e
commit 69b54a2875
7 files changed
+133 -12

No files matched your search

@@ -4,9 +4,6 @@ import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sse.datamining.functions.ClassesWithFunctionsService;
public class SailingDataMiningClassesWithFunctionsService implements ClassesWithFunctionsService {
@@ -14,9 +11,13 @@ public class SailingDataMiningClassesWithFunctionsService implements ClassesWith
@Override
public Set<Class<?>> getInternalClassesWithMarkedMethods() {
Set<Class<?>> internalClasses = new HashSet<>();
internalClasses.add(HasTrackedRaceContext.class);
internalClasses.add(HasTrackedLegContext.class);
internalClasses.add(HasTrackedLegOfCompetitorContext.class);
/*
* This also contains the marked methods of
* HasTrackedRaceContext,
* HasTrackedLegContext and
* HasTrackedLegOfCompetitorContext,
* because these are the super types of HasGPSFixContext.
*/
internalClasses.add(HasGPSFixContext.class);
return internalClasses;
}
@@ -15,7 +15,7 @@ public class Activator implements BundleActivator {
public void stop(BundleContext context) throws Exception {
}
public static BundleContext getDefault() {
public static BundleContext getContext() {
return context;
}
@@ -31,7 +31,7 @@ public class DataMiningServiceImpl extends RemoteServiceServlet implements DataM
private final ServiceTracker<RacingEventService, RacingEventService> racingEventServiceTracker;
public DataMiningServiceImpl() {
context = Activator.getDefault();
context = Activator.getContext();
dataMiningServerTracker = createAndOpenDataMiningServerTracker(context);
racingEventServiceTracker = createAndOpenRacingEventServiceTracker(context);
}
@@ -25,7 +25,7 @@ public class MediaServiceImpl extends RemoteServiceServlet implements MediaServi
public MediaServiceImpl() {
super();
BundleContext context = Activator.getDefault();
BundleContext context = Activator.getContext();
racingEventServiceTracker = new ServiceTracker<RacingEventService, RacingEventService>(
context, RacingEventService.class.getName(), null);
racingEventServiceTracker.open();
@@ -384,7 +384,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
private final BundleContext context;
public SailingServiceImpl() {
context = Activator.getDefault();
context = Activator.getContext();
racingEventServiceTracker = createAndOpenRacingEventServiceTracker(context);
replicationServiceTracker = createAndOpenReplicationServiceTracker(context);
swissTimingAdapterTracker = createAndOpenSwissTimingAdapterTracker(context);
@@ -121,5 +121,9 @@ public class DataMiningActivator implements BundleActivator {
public static DataMiningStringMessages getStringMessages() {
return stringMessages;
}
public static BundleContext getContext() {
return context;
}
}
@@ -1,27 +1,143 @@
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.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.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 FunctionRegistry functionRegistry;
private FunctionProvider functionProvider;
private final BundleContext context;
private final Set<ServiceReference<ClassesWithFunctionsService>> registeredServices;
private final FunctionRegistry functionRegistry;
private final FunctionProvider functionProvider;
public DataMiningServerImpl(FunctionRegistry functionRegistry, FunctionProvider functionProvider) {
context = DataMiningActivator.getContext();
registeredServices = new HashSet<>();
this.functionRegistry = functionRegistry;
this.functionProvider = functionProvider;
}
@Override
public FunctionRegistry getFunctionRegistry() {
updateRegistryIfNecessary();
return functionRegistry;
}
@Override
public FunctionProvider getFunctionProvider() {
updateRegistryIfNecessary();
return functionProvider;
}
private void updateRegistryIfNecessary() {
Collection<ServiceReference<ClassesWithFunctionsService>> availableServices = getAllClassesWithMarkedMethodsServices();
Collection<ServiceReference<ClassesWithFunctionsService>> servicesToRegister = calculateServicesToRegister(availableServices);
Collection<ServiceReference<ClassesWithFunctionsService>> servicesToUnregister = calculateServicesToUnregister(availableServices);
registerServices(servicesToRegister);
unregisterServices(servicesToUnregister);
}
private Collection<ServiceReference<ClassesWithFunctionsService>> calculateServicesToRegister(
Collection<ServiceReference<ClassesWithFunctionsService>> availableServices) {
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<>();
}
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;
}
}