blob: f057f5dfa4f1868ac94457ac7f48aa4eba18aa36 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011-2015 EclipseSource Muenchen GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eugen Neufeld - initial API and implementation
******************************************************************************/
package org.eclipse.emfforms.internal.core.services.scoped;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.eclipse.emfforms.common.Optional;
import org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext;
import org.eclipse.emfforms.spi.core.services.view.EMFFormsViewServiceFactory;
import org.eclipse.emfforms.spi.core.services.view.EMFFormsViewServiceManager;
import org.eclipse.emfforms.spi.core.services.view.EMFFormsViewServicePolicy;
import org.eclipse.emfforms.spi.core.services.view.EMFFormsViewServiceScope;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
/**
* The implementation of the EMFFormsScopedServicesFactory.
*
* @author Eugen Neufeld
*
*/
@Component
public class EMFFormsViewServiceManagerImpl implements EMFFormsViewServiceManager {
private final Map<Class<?>, EMFFormsViewServiceFactory<?>> localImmediateMap = new LinkedHashMap<Class<?>, EMFFormsViewServiceFactory<?>>();
private final Map<Class<?>, EMFFormsViewServiceFactory<?>> localLazyMap = new LinkedHashMap<Class<?>, EMFFormsViewServiceFactory<?>>();
private final Map<Class<?>, EMFFormsViewServiceFactory<?>> globalImmediateMap = new LinkedHashMap<Class<?>, EMFFormsViewServiceFactory<?>>();
private final Map<Class<?>, EMFFormsViewServiceFactory<?>> globalLazyMap = new LinkedHashMap<Class<?>, EMFFormsViewServiceFactory<?>>();
/**
* Called by OSGi whenever a new provider is available.
*
* @param provider The newly available provider
*/
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
protected void addEMFFormsScopedServiceProvider(EMFFormsViewServiceFactory<?> provider) {
final Map<Class<?>, EMFFormsViewServiceFactory<?>> serviceProviderMap = getServiceProviderMap(provider);
double currentPrio = Double.NEGATIVE_INFINITY;
if (serviceProviderMap.containsKey(provider.getType())) {
currentPrio = serviceProviderMap.get(provider.getType()).getPriority();
}
if (currentPrio < provider.getPriority()) {
serviceProviderMap.put(provider.getType(), provider);
}
}
/**
* Called by OSGi whenever a provider is removed.
*
* @param provider The removed provider
*/
protected void removeEMFFormsScopedServiceProvider(EMFFormsViewServiceFactory<?> provider) {
getServiceProviderMap(provider).remove(provider.getType());
}
private Map<Class<?>, EMFFormsViewServiceFactory<?>> getServiceProviderMap(
EMFFormsViewServiceFactory<?> provider) {
if (provider.getPolicy() == EMFFormsViewServicePolicy.IMMEDIATE
&& provider.getScope() == EMFFormsViewServiceScope.GLOBAL) {
return globalImmediateMap;
} else if (provider.getPolicy() == EMFFormsViewServicePolicy.LAZY
&& provider.getScope() == EMFFormsViewServiceScope.GLOBAL) {
return globalLazyMap;
} else if (provider.getPolicy() == EMFFormsViewServicePolicy.IMMEDIATE
&& provider.getScope() == EMFFormsViewServiceScope.LOCAL) {
return localImmediateMap;
} else if (provider.getPolicy() == EMFFormsViewServicePolicy.LAZY
&& provider.getScope() == EMFFormsViewServiceScope.LOCAL) {
return localLazyMap;
}
throw new IllegalStateException(
"This should never be reached as we check for all possible cases before.s Only when there is one more combination of policy and scope that we missed this can happen!"); //$NON-NLS-1$
}
@SuppressWarnings("unchecked")
private <T> Optional<T> getServiceOptional(Class<T> type,
Map<Class<?>, EMFFormsViewServiceFactory<?>> classFactoryMap, EMFFormsViewContext emfFormsViewContext) {
final EMFFormsViewServiceFactory<?> serviceProvider = classFactoryMap.get(type);
if (serviceProvider != null) {
return (Optional<T>) Optional.of(serviceProvider.createService(emfFormsViewContext));
}
return Optional.empty();
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emfforms.spi.core.services.view.EMFFormsViewServiceManager#createLocalImmediateService(java.lang.Class,EMFFormsViewContext)
*/
@Override
public <T> Optional<T> createLocalImmediateService(Class<T> type, EMFFormsViewContext emfFormsViewContext) {
return getServiceOptional(type, localImmediateMap, emfFormsViewContext);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emfforms.spi.core.services.view.EMFFormsViewServiceManager#createLocalLazyService(java.lang.Class,EMFFormsViewContext)
*/
@Override
public <T> Optional<T> createLocalLazyService(Class<T> type, EMFFormsViewContext emfFormsViewContext) {
return getServiceOptional(type, localLazyMap, emfFormsViewContext);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emfforms.spi.core.services.view.EMFFormsViewServiceManager#createGlobalImmediateService(java.lang.Class,EMFFormsViewContext)
*/
@Override
public <T> Optional<T> createGlobalImmediateService(Class<T> type, EMFFormsViewContext emfFormsViewContext) {
return getServiceOptional(type, globalImmediateMap, emfFormsViewContext);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emfforms.spi.core.services.view.EMFFormsViewServiceManager#createGlobalLazyService(java.lang.Class,EMFFormsViewContext)
*/
@Override
public <T> Optional<T> createGlobalLazyService(Class<T> type, EMFFormsViewContext emfFormsViewContext) {
return getServiceOptional(type, globalLazyMap, emfFormsViewContext);
}
private Set<Class<?>> getAllTypes(Collection<EMFFormsViewServiceFactory<?>> factorySet) {
final SortedSet<EMFFormsViewServiceFactory<?>> sortedFactories = new TreeSet<EMFFormsViewServiceFactory<?>>(
new Comparator<EMFFormsViewServiceFactory<?>>() {
@Override
public int compare(EMFFormsViewServiceFactory<?> factory0, EMFFormsViewServiceFactory<?> factory1) {
final int result = Double.compare(factory0.getPriority(), factory1.getPriority());
if (result == 0) {
return 1;
}
return result;
}
});
for (final EMFFormsViewServiceFactory<?> factory : factorySet) {
sortedFactories.add(factory);
}
final Set<Class<?>> result = new LinkedHashSet<Class<?>>();
for (final EMFFormsViewServiceFactory<?> factory : sortedFactories) {
result.add(factory.getType());
}
return result;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emfforms.spi.core.services.view.EMFFormsViewServiceManager#getAllGlobalImmediateServiceTypes()
*/
@Override
public Set<Class<?>> getAllGlobalImmediateServiceTypes() {
// return globalImmediateMap.keySet();
return getAllTypes(globalImmediateMap.values());
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emfforms.spi.core.services.view.EMFFormsViewServiceManager#getAllLocalImmediateServiceTypes()
*/
@Override
public Set<Class<?>> getAllLocalImmediateServiceTypes() {
// return localImmediateMap.keySet();
return getAllTypes(localImmediateMap.values());
}
}