/**
* Copyright (c) 2010-2016 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.openhab.binding.vdr.internal;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.openhab.binding.vdr.VDRBindingProvider;
import org.openhab.binding.vdr.VDRCommandType;
import org.openhab.core.binding.BindingConfig;
import org.openhab.core.items.Item;
import org.openhab.core.library.items.NumberItem;
import org.openhab.core.library.items.StringItem;
import org.openhab.core.library.items.SwitchItem;
import org.openhab.model.item.binding.AbstractGenericBindingProvider;
import org.openhab.model.item.binding.BindingConfigParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>
* This class can parse information from the generic binding format and provides
* VDR binding information from it. It registers as a {@link VDRBindingProvider}
* service as well.
* </p>
*
* <p>
* Here are some examples for valid binding configuration strings:
* <ul>
* <li><code>{ vdr="LivingRoom:powerOff" }</code> - switch VDR off calls</li>
* <li><code>{ vdr="LivingRoom:message" }</code> - show message on OSD</li>
* <li><code>{ vdr="LivingRoom:volume" }</code> - if bound to a switch item,
* increase (true) / decrease (false) volume</li>
* <li><code>{ vdr="LivingRoom:volume" }</code> - if bound to a number item, set
* volume level (0-255)</li>
* <li><code>{ vdr="LivingRoom:channel" }</code> - if bound to a switch item,
* increase (true) / decrease (false) channel</li>
* <li><code>{ vdr="LivingRoom:channel" }</code> - if bound to a number item,
* switch to channel number</li>
* </ul>
* These binding configurations can be used on either Switch-, String- or
* DimmerItems
* </p>
*
* @author Wolfgang Willinghoefer
*
* @since 0.9.0
*/
public class VDRGenericBindingProvider extends AbstractGenericBindingProvider implements VDRBindingProvider {
static final Logger logger = LoggerFactory.getLogger(VDRGenericBindingProvider.class);
/**
* {@inheritDoc}
*/
@Override
public String getBindingType() {
return "vdr";
}
/**
* {@inheritDoc}
*/
@Override
public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException {
if (!(item instanceof SwitchItem || item instanceof NumberItem || item instanceof StringItem)) {
throw new BindingConfigParseException("item '" + item.getName() + "' is of type '"
+ item.getClass().getSimpleName()
+ "', only Switch-, String and NumberItems are allowed - please check your *.items configuration");
}
}
/**
* {@inheritDoc}
*/
@Override
public void processBindingConfiguration(String context, Item item, String bindingConfig)
throws BindingConfigParseException {
super.processBindingConfiguration(context, item, bindingConfig);
if (bindingConfig != null) {
VDRBindingConfig config = parseBindingConfig(item, bindingConfig, null);
addBindingConfig(item, config);
} else {
logger.warn("bindingConfig is NULL (item=" + item + ") -> processing bindingConfig aborted!");
}
}
/*
* (non-Javadoc)
*
* @see
* org.openhab.binding.vdr.VDRBindingProvider#getBindingItemName(java.lang
* .String, org.openhab.binding.vdr.internal.VDRCommandType)
*/
@Override
public String getBindingItemName(String vdrId, VDRCommandType vdrCommand) {
String itemName = null;
logger.debug("Searching for a binding config that matches the id '{}' and command '{}'", vdrId, vdrCommand);
for (BindingConfig config : this.bindingConfigs.values()) {
VDRBindingConfig vdrConfig = (VDRBindingConfig) config;
if (vdrConfig.vDRId.equals(vdrId) && vdrConfig.command.equals(vdrCommand.getVDRCommand())) {
itemName = vdrConfig.item.getName();
logger.debug("Match found: '{}'", itemName);
break;
} else {
logger.debug("Not a match: '{}':'{}'", vdrConfig.vDRId, vdrConfig.command);
}
}
return itemName;
}
/**
* Checks if the bindingConfig contains a valid binding type and returns an
* appropriate instance.
*
* @param item
* @param bindingConfig
*
* @throws BindingConfigParseException
* if bindingConfig is no valid binding type
*/
protected VDRBindingConfig parseBindingConfig(Item item, String bindingConfigs, VDRBindingConfig parent)
throws BindingConfigParseException {
String bindingConfig = StringUtils.substringBefore(bindingConfigs, ",");
String bindingConfigTail = StringUtils.substringAfter(bindingConfigs, ",");
String[] configParts = bindingConfig.split(":");
if (configParts.length != 2) {
throw new BindingConfigParseException(
"VDR binding configuration must consist of two parts [config=" + configParts + "]");
}
String vdrId = StringUtils.trim(configParts[0]);
String command = StringUtils.trim(configParts[1]);
if (command != null) {
if (VDRCommandType.validateBinding(command, item.getClass())) {
VDRBindingConfig vdrBindingConfig = new VDRBindingConfig(vdrId, command, item, parent);
if (StringUtils.isNotBlank(bindingConfigTail)) {
parseBindingConfig(item, bindingConfigTail, vdrBindingConfig);
}
return vdrBindingConfig;
} else {
String validItemType = VDRCommandType.getValidItemTypes(command);
if (StringUtils.isEmpty(validItemType)) {
throw new BindingConfigParseException("'" + bindingConfig + "' is no valid binding type");
} else {
throw new BindingConfigParseException("'" + bindingConfig
+ "' is not bound to a valid item type. Valid item type(s): " + validItemType);
}
}
} else {
throw new BindingConfigParseException("'" + bindingConfig + "' is no valid binding type");
}
}
/*
* (non-Javadoc)
*
* @see
* org.openhab.binding.vdr.VDRBindingProvider#getVDRId(java.lang.String)
*/
@Override
public List<String> getVDRId(String itemName) {
VDRBindingConfig config = (VDRBindingConfig) bindingConfigs.get(itemName);
List<String> ret = null;
if (config != null) {
ret = new ArrayList<String>();
ret.add(config.getVDRId());
while (config.getNext() != null) {
config = config.getNext();
ret.add(config.getVDRId());
}
}
return ret;
}
/*
* (non-Javadoc)
*
* @see
* org.openhab.binding.vdr.VDRBindingProvider#getVDRCommand(java.lang.String
* )
*/
@Override
public List<String> getVDRCommand(String itemName) {
VDRBindingConfig config = (VDRBindingConfig) bindingConfigs.get(itemName);
List<String> ret = null;
if (config != null) {
ret = new ArrayList<String>();
ret.add(config.getCommand());
while (config.getNext() != null) {
config = config.getNext();
ret.add(config.getCommand());
}
}
return ret;
}
static class VDRBindingConfig implements BindingConfig {
final private String command;
final private String vDRId;
final private Item item;
private VDRBindingConfig next = null;
public VDRBindingConfig(String pVDRId, String pCommand, Item pItem, VDRBindingConfig pParent) {
this.vDRId = pVDRId;
this.command = pCommand;
this.item = pItem;
if (pParent != null) {
pParent.next = this;
}
}
public String getVDRId() {
return vDRId;
}
public String getCommand() {
return command;
}
public VDRBindingConfig getNext() {
return next;
}
}
}