mirror of
https://github.com/danieldemus/openhab-core.git
synced 2025-01-26 20:21:33 +01:00
Merge pull request #20 from kaikreuzer/agbp
Introduced concurrency fixes as done in https://github.com/openhab/op…
This commit is contained in:
commit
49ef22b90c
@ -13,7 +13,6 @@ import java.util.Collection;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.WeakHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
@ -25,112 +24,132 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>This abstract class serves as a basis for implementations of binding providers that retrieve binding
|
* <p>
|
||||||
* information from the items configuration file(s), i.e. they register as {@link BindingConfigReader}s.</p>
|
* This abstract class serves as a basis for implementations of binding providers that retrieve binding
|
||||||
*
|
* information from the items configuration file(s), i.e. they register as {@link BindingConfigReader}s.
|
||||||
* <p>This class takes care of tracking all changes in the binding config strings and makes sure that all
|
* </p>
|
||||||
* listeners are correctly notified of any change.<p>
|
*
|
||||||
*
|
* <p>
|
||||||
|
* This class takes care of tracking all changes in the binding config strings and makes sure that all
|
||||||
|
* listeners are correctly notified of any change.
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
* @author Kai Kreuzer
|
* @author Kai Kreuzer
|
||||||
* @since 0.6.0
|
* @since 0.6.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractGenericBindingProvider implements BindingConfigReader, BindingProvider {
|
public abstract class AbstractGenericBindingProvider implements BindingConfigReader, BindingProvider {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(AbstractGenericBindingProvider.class);
|
private static final Logger logger = LoggerFactory.getLogger(AbstractGenericBindingProvider.class);
|
||||||
|
|
||||||
private Set<BindingChangeListener> listeners = new CopyOnWriteArraySet<BindingChangeListener>();
|
private Set<BindingChangeListener> listeners = new CopyOnWriteArraySet<BindingChangeListener>();
|
||||||
|
|
||||||
/** caches binding configurations. maps itemNames to {@link BindingConfig}s */
|
/** caches binding configurations. maps itemNames to {@link BindingConfig}s */
|
||||||
protected Map<String, BindingConfig> bindingConfigs = new ConcurrentHashMap<String, BindingConfig>(new WeakHashMap<String, BindingConfig>());
|
protected Map<String, BindingConfig> bindingConfigs = new ConcurrentHashMap<String, BindingConfig>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stores information about the context of items. The map has this content
|
* stores information about the context of items. The map has this content
|
||||||
* structure: context -> Set of Items
|
* structure: context -> Set of Items
|
||||||
*/
|
*/
|
||||||
protected Map<String, Set<Item>> contextMap = new ConcurrentHashMap<String, Set<Item>>();
|
protected Map<String, Set<Item>> contextMap = new ConcurrentHashMap<String, Set<Item>>();
|
||||||
|
|
||||||
|
|
||||||
public AbstractGenericBindingProvider() {
|
public AbstractGenericBindingProvider() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void addBindingChangeListener(BindingChangeListener listener) {
|
@Override
|
||||||
listeners.add(listener);
|
public void addBindingChangeListener(BindingChangeListener listener) {
|
||||||
}
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void removeBindingChangeListener(BindingChangeListener listener) {
|
@Override
|
||||||
listeners.remove(listener);
|
public void removeBindingChangeListener(BindingChangeListener listener) {
|
||||||
}
|
listeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void processBindingConfiguration(String context, Item item, String bindingConfig) throws BindingConfigParseException {
|
@Override
|
||||||
Set<Item> items = contextMap.get(context);
|
public void processBindingConfiguration(String context, Item item, String bindingConfig)
|
||||||
if (items==null) {
|
throws BindingConfigParseException {
|
||||||
items = new HashSet<Item>();
|
if (context == null) {
|
||||||
contextMap.put(context, items);
|
throw new BindingConfigParseException("null context is not permitted for item " + item.getName());
|
||||||
}
|
}
|
||||||
|
synchronized (contextMap) {
|
||||||
items.add(item);
|
Set<Item> items = contextMap.get(context);
|
||||||
}
|
if (items == null) {
|
||||||
|
items = new HashSet<Item>();
|
||||||
|
contextMap.put(context, items);
|
||||||
|
}
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void removeConfigurations(String context) {
|
@Override
|
||||||
Set<Item> items = contextMap.get(context);
|
public void removeConfigurations(String context) {
|
||||||
if(items!=null) {
|
Set<Item> items = null;
|
||||||
for(Item item : items) {
|
synchronized (contextMap) {
|
||||||
// we remove all binding configurations for all items
|
items = contextMap.get(context);
|
||||||
bindingConfigs.remove(item.getName());
|
if (items != null) {
|
||||||
notifyListeners(item);
|
contextMap.remove(context);
|
||||||
}
|
}
|
||||||
contextMap.remove(context);
|
}
|
||||||
}
|
if (items != null) {
|
||||||
}
|
for (Item item : items) {
|
||||||
|
// we remove all binding configurations for all items
|
||||||
protected void addBindingConfig(Item item, BindingConfig config) {
|
bindingConfigs.remove(item.getName());
|
||||||
bindingConfigs.put(item.getName(), config);
|
notifyListeners(item);
|
||||||
notifyListeners(item);
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void notifyListeners(Item item) {
|
protected void addBindingConfig(Item item, BindingConfig config) {
|
||||||
for (BindingChangeListener listener : listeners) {
|
bindingConfigs.put(item.getName(), config);
|
||||||
|
notifyListeners(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyListeners(Item item) {
|
||||||
|
for (BindingChangeListener listener : listeners) {
|
||||||
try {
|
try {
|
||||||
listener.bindingChanged(this, item.getName());
|
listener.bindingChanged(this, item.getName());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Binding " + listener.getClass().getName() + " threw an exception: ", e);
|
logger.error("Binding " + listener.getClass().getName() + " threw an exception: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @{inheritDoc}
|
* @{inheritDoc}
|
||||||
*/
|
*/
|
||||||
public boolean providesBindingFor(String itemName) {
|
@Override
|
||||||
return bindingConfigs.get(itemName) != null;
|
public boolean providesBindingFor(String itemName) {
|
||||||
}
|
return bindingConfigs.get(itemName) != null;
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @{inheritDoc}
|
/**
|
||||||
*/
|
* @{inheritDoc}
|
||||||
public boolean providesBinding() {
|
*/
|
||||||
return !bindingConfigs.isEmpty();
|
@Override
|
||||||
}
|
public boolean providesBinding() {
|
||||||
|
return !bindingConfigs.isEmpty();
|
||||||
/**
|
}
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
/**
|
||||||
public Collection<String> getItemNames() {
|
* {@inheritDoc}
|
||||||
return new ArrayList<String>(bindingConfigs.keySet());
|
*/
|
||||||
}
|
@Override
|
||||||
|
public Collection<String> getItemNames() {
|
||||||
|
return new ArrayList<String>(bindingConfigs.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user