diff --git a/bundles/org.openhab.core.compat1x/src/main/java/org/openhab/model/item/binding/AbstractGenericBindingProvider.java b/bundles/org.openhab.core.compat1x/src/main/java/org/openhab/model/item/binding/AbstractGenericBindingProvider.java index 412ab4030e..dd08c43cef 100644 --- a/bundles/org.openhab.core.compat1x/src/main/java/org/openhab/model/item/binding/AbstractGenericBindingProvider.java +++ b/bundles/org.openhab.core.compat1x/src/main/java/org/openhab/model/item/binding/AbstractGenericBindingProvider.java @@ -13,7 +13,6 @@ import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; @@ -25,112 +24,132 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - *

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.

- * - *

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.

- * + *

+ * 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. + *

+ * + *

+ * 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. + *

+ * * @author Kai Kreuzer * @since 0.6.0 * */ 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 listeners = new CopyOnWriteArraySet(); + private Set listeners = new CopyOnWriteArraySet(); - /** caches binding configurations. maps itemNames to {@link BindingConfig}s */ - protected Map bindingConfigs = new ConcurrentHashMap(new WeakHashMap()); + /** caches binding configurations. maps itemNames to {@link BindingConfig}s */ + protected Map bindingConfigs = new ConcurrentHashMap(); - /** - * stores information about the context of items. The map has this content - * structure: context -> Set of Items - */ - protected Map> contextMap = new ConcurrentHashMap>(); - + /** + * stores information about the context of items. The map has this content + * structure: context -> Set of Items + */ + protected Map> contextMap = new ConcurrentHashMap>(); - public AbstractGenericBindingProvider() { - super(); - } + public AbstractGenericBindingProvider() { + super(); + } - /** - * {@inheritDoc} - */ - public void addBindingChangeListener(BindingChangeListener listener) { - listeners.add(listener); - } + /** + * {@inheritDoc} + */ + @Override + public void addBindingChangeListener(BindingChangeListener listener) { + listeners.add(listener); + } - /** - * {@inheritDoc} - */ - public void removeBindingChangeListener(BindingChangeListener listener) { - listeners.remove(listener); - } + /** + * {@inheritDoc} + */ + @Override + public void removeBindingChangeListener(BindingChangeListener listener) { + listeners.remove(listener); + } - /** - * {@inheritDoc} - */ - public void processBindingConfiguration(String context, Item item, String bindingConfig) throws BindingConfigParseException { - Set items = contextMap.get(context); - if (items==null) { - items = new HashSet(); - contextMap.put(context, items); - } - - items.add(item); - } + /** + * {@inheritDoc} + */ + @Override + public void processBindingConfiguration(String context, Item item, String bindingConfig) + throws BindingConfigParseException { + if (context == null) { + throw new BindingConfigParseException("null context is not permitted for item " + item.getName()); + } + synchronized (contextMap) { + Set items = contextMap.get(context); + if (items == null) { + items = new HashSet(); + contextMap.put(context, items); + } + items.add(item); + } + } - /** - * {@inheritDoc} - */ - public void removeConfigurations(String context) { - Set items = contextMap.get(context); - if(items!=null) { - for(Item item : items) { - // we remove all binding configurations for all items - bindingConfigs.remove(item.getName()); - notifyListeners(item); - } - contextMap.remove(context); - } - } - - protected void addBindingConfig(Item item, BindingConfig config) { - bindingConfigs.put(item.getName(), config); - notifyListeners(item); - } + /** + * {@inheritDoc} + */ + @Override + public void removeConfigurations(String context) { + Set items = null; + synchronized (contextMap) { + items = contextMap.get(context); + if (items != null) { + contextMap.remove(context); + } + } + if (items != null) { + for (Item item : items) { + // we remove all binding configurations for all items + bindingConfigs.remove(item.getName()); + notifyListeners(item); + } + } + } - private void notifyListeners(Item item) { - for (BindingChangeListener listener : listeners) { + protected void addBindingConfig(Item item, BindingConfig config) { + bindingConfigs.put(item.getName(), config); + notifyListeners(item); + } + + private void notifyListeners(Item item) { + for (BindingChangeListener listener : listeners) { try { listener.bindingChanged(this, item.getName()); } catch (Exception e) { logger.error("Binding " + listener.getClass().getName() + " threw an exception: ", e); } - } - } - - /** - * @{inheritDoc} - */ - public boolean providesBindingFor(String itemName) { - return bindingConfigs.get(itemName) != null; - } - - /** - * @{inheritDoc} - */ - public boolean providesBinding() { - return !bindingConfigs.isEmpty(); - } - - /** - * {@inheritDoc} - */ - public Collection getItemNames() { - return new ArrayList(bindingConfigs.keySet()); - } + } + } + + /** + * @{inheritDoc} + */ + @Override + public boolean providesBindingFor(String itemName) { + return bindingConfigs.get(itemName) != null; + } + + /** + * @{inheritDoc} + */ + @Override + public boolean providesBinding() { + return !bindingConfigs.isEmpty(); + } + + /** + * {@inheritDoc} + */ + @Override + public Collection getItemNames() { + return new ArrayList(bindingConfigs.keySet()); + } } \ No newline at end of file