org.gecko.emf.osgi.helper.ServicePropertyContextImpl Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) 2012 - 2023 Data In Motion and others.
* All rights reserved.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Data In Motion - initial API and implementation
*/
package org.gecko.emf.osgi.helper;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static java.util.Objects.requireNonNull;
import static org.gecko.emf.osgi.helper.ServicePropertiesHelper.appendToDictionary;
import static org.gecko.emf.osgi.helper.ServicePropertiesHelper.filterProperties;
import static org.gecko.emf.osgi.helper.ServicePropertiesHelper.getStringPlusValue;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.gecko.emf.osgi.constants.EMFNamespaces;
import org.osgi.framework.FrameworkUtil;
/**
* {@link ServicePropertyContext} implementation. Hold a set of property maps for Gecko EMF
* @author Mark Hoffmann
* @since 04.11.2023
*/
public class ServicePropertyContextImpl implements ServicePropertyContext {
// Map with property key as key and the map of service.id and value-set as value
final Map>> keyMapPairs = new ConcurrentHashMap<>();
// Map with service.id and corresponding sub-context instance as value
private final Map subContextMap = new ConcurrentHashMap<>();
// Set of all available properties in EMF OSGi
private static Set validKeys = new HashSet<>();
private final Map customFeatureProperties = new ConcurrentHashMap<>();
static {
validKeys.add(EMFNamespaces.EMF_CONFIGURATOR_NAME);
validKeys.add(EMFNamespaces.EMF_MODEL_NAME);
validKeys.add(EMFNamespaces.EMF_MODEL_NSURI);
validKeys.add(EMFNamespaces.EMF_MODEL_FEATURE);
validKeys.add(EMFNamespaces.EMF_MODEL_VERSION);
validKeys.add(EMFNamespaces.EMF_MODEL_CONTENT_TYPE);
validKeys.add(EMFNamespaces.EMF_MODEL_FILE_EXT);
validKeys.add(EMFNamespaces.EMF_MODEL_PROTOCOL);
}
/**
* Creates a new instance.
*/
ServicePropertyContextImpl() {
init();
}
/*
* (non-Javadoc)
* @see org.gecko.emf.osgi.helper.ServicePropertyContext#updateServiceProperties(java.util.Map)
*/
@Override
public void updateServiceProperties(Map serviceProperties) {
requireNonNull(serviceProperties);
Long serviceId = validateServiceId(serviceProperties);
updateFeatureProperties(serviceProperties);
keyMapPairs.keySet().forEach(key->updateProperties(key, serviceProperties, serviceId));
}
/*
* (non-Javadoc)
* @see org.gecko.emf.osgi.helper.ServicePropertyContext#getDictionary(boolean)
*/
@Override
public Dictionary getDictionary(boolean merged) {
Dictionary properties = new Hashtable<>();
keyMapPairs.forEach((key, map)->appendToDictionary(key, map, properties));
customFeatureProperties.forEach(properties::put);
if (!merged) {
return properties;
} else {
ServicePropertyContext[] subContexts;
synchronized (subContextMap) {
subContexts = subContextMap.values().toArray(new ServicePropertyContext[subContextMap.size()]);
}
return merge(subContexts).getDictionary(false);
}
}
/*
* (non-Javadoc)
* @see org.gecko.emf.osgi.helper.ServicePropertyContext#getProperties(boolean)
*/
@Override
public Map getProperties(boolean merged) {
return FrameworkUtil.asMap(getDictionary(merged));
}
/*
* (non-Javadoc)
* @see org.gecko.emf.osgi.helper.ServicePropertyContext#addSubContext(java.util.Map)
*/
@Override
public ServicePropertyContext addSubContext(Map subContextProperties) {
requireNonNull(subContextProperties);
return ServicePropertiesHelper.
getServiceId(subContextProperties).
map(id->addSubContext(id, subContextProperties)).
orElseThrow(()->new IllegalStateException("The sub-context properties must contains a service.id entry with a long value"));
}
/*
* (non-Javadoc)
* @see org.gecko.emf.osgi.helper.ServicePropertyContext#removeSubContext(java.util.Map)
*/
@Override
public ServicePropertyContext removeSubContext(Map subContextProperties) {
requireNonNull(subContextProperties);
validateServiceId(subContextProperties);
return ServicePropertiesHelper.
getServiceId(subContextProperties).
map(this::removeSubContext).
orElse(null);
}
/*
* (non-Javadoc)
* @see org.gecko.emf.osgi.helper.ServicePropertyContext#merge(org.gecko.emf.osgi.helper.ServicePropertyContext)
*/
@Override
public ServicePropertyContext merge(ServicePropertyContext ...toMerge) {
if (isNull(toMerge)) {
return this;
}
ServicePropertyContextImpl merged = new ServicePropertyContextImpl();
doMerge(this, merged);
for (ServicePropertyContext mergeCtx : toMerge) {
if (mergeCtx instanceof ServicePropertyContextImpl) {
doMerge((ServicePropertyContextImpl) mergeCtx, merged);
}
}
return merged;
}
/**
* Extract all properties that start with the given feature prefix
* @param serviceProperties the service properties
*/
protected void updateFeatureProperties(Map serviceProperties) {
requireNonNull(serviceProperties);
Map featureProperties = filterProperties(EMFNamespaces.EMF_MODEL_FEATURE + ".", serviceProperties);
featureProperties.forEach((key, value)->{
// append to customFeatureMap
customFeatureProperties.computeIfPresent(key, (customKey, customValue) -> {
Set
© 2015 - 2024 Weber Informatics LLC | Privacy Policy