/**
* Copyright (c) 2014-2017 by the respective copyright holders.
* 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
*/
package org.eclipse.smarthome.model.item;
import java.util.ArrayList;
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 org.apache.commons.lang.StringUtils;
import org.eclipse.smarthome.core.autoupdate.AutoUpdateBindingConfigProvider;
/**
* <p>
* This class can parse information from the generic binding format and provides AutoUpdate binding information from it.
* If no binding configuration is provided <code>autoupdate</code> is evaluated to true. This means every received
* <code>Command</code> will update its corresponding <code>State</code> by default.
* </p>
* <p>
* This class registers as a {@link AutoUpdateBindingConfigProvider} service as well.
* </p>
*
* <p>
* A valid binding configuration strings looks like this:
* <ul>
* <li><code>{ autoupdate="false" }</li>
* </ul>
*
* @author Thomas.Eichstaedt-Engelen
* @author Kai Kreuzer - made it independent from parent abstract classes
*
*/
public class AutoUpdateGenericBindingConfigProvider implements AutoUpdateBindingConfigProvider, BindingConfigReader {
/** caches binding configurations. maps itemNames to {@link BindingConfig}s */
protected Map<String, AutoUpdateBindingConfig> bindingConfigs = new ConcurrentHashMap<>(
new WeakHashMap<String, AutoUpdateBindingConfig>());
/**
* stores information about the context of items. The map has this content
* structure: context -> Set of Item names
*/
protected Map<String, Set<String>> contextMap = new ConcurrentHashMap<>();
/**
* {@inheritDoc}
*/
@Override
public String getBindingType() {
return "autoupdate";
}
/**
* @{inheritDoc
*/
@Override
public void validateItemType(String itemType, String bindingConfig) throws BindingConfigParseException {
// as AutoUpdate is a default binding, each binding type is valid
}
/**
* {@inheritDoc}
*/
@Override
public void processBindingConfiguration(String context, String itemType, String itemName, String bindingConfig)
throws BindingConfigParseException {
Set<String> itemNames = contextMap.get(context);
if (itemNames == null) {
itemNames = new HashSet<String>();
contextMap.put(context, itemNames);
}
itemNames.add(itemName);
AutoUpdateBindingConfig config = new AutoUpdateBindingConfig();
parseBindingConfig(bindingConfig, config);
addBindingConfig(itemType, itemName, config);
}
protected void parseBindingConfig(String bindingConfig, AutoUpdateBindingConfig config)
throws BindingConfigParseException {
if (StringUtils.isNotBlank(bindingConfig)) {
try {
config.autoupdate = Boolean.valueOf(bindingConfig.trim());
} catch (IllegalArgumentException iae) {
throw new BindingConfigParseException("The given parameter '" + bindingConfig.trim()
+ "' has to be set to either 'true' or 'false'.");
}
}
}
/**
* {@inheritDoc}
*/
@Override
public Boolean autoUpdate(String itemName) {
AutoUpdateBindingConfig config = bindingConfigs.get(itemName);
return config != null ? config.autoupdate : null;
}
/**
* {@inheritDoc}
*/
@Override
public void startConfigurationUpdate(String context) {
Set<String> itemNames = contextMap.get(context);
if (itemNames != null) {
for (String itemName : itemNames) {
// we remove all binding configurations for all items
bindingConfigs.remove(itemName);
}
contextMap.remove(context);
}
}
@Override
public void stopConfigurationUpdate(String context) {
}
protected void addBindingConfig(String itemType, String itemName, AutoUpdateBindingConfig config) {
bindingConfigs.put(itemName, config);
}
/**
* @{inheritDoc
*/
public boolean providesBindingFor(String itemName) {
return bindingConfigs.get(itemName) != null;
}
/**
* @{inheritDoc
*/
public boolean providesBinding() {
return !bindingConfigs.isEmpty();
}
/**
* {@inheritDoc}
*/
public Collection<String> getItemNames() {
return new ArrayList<String>(bindingConfigs.keySet());
}
/**
* This is an internal data structure to store information from the binding
* config strings and use it to answer the requests to the AutoUpdate
* binding provider.
*/
static class AutoUpdateBindingConfig {
boolean autoupdate;
}
}