/**
* 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.ipx800.internal;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.osgi.service.cm.ConfigurationException;
/**
* Global configuration of ipx800.
*
* Configuration example :
* ipx800:myipx.host=<hostname or ip>
* ipx800:myipx.port=<port>
* ipx800:myipx.x400.[1-3]=<extension alias>
* ipx800:myipx.x880.[1-3]=<extension alias>
*
* @author Seebag
* @since 1.8.0
*
*/
public class Ipx800Config {
/** Pattern for all valid device configuration keys. */
private final static Pattern CONFIG_PATTERN = Pattern.compile("^(.+?)\\.(host|port|(x400|x880)\\.([1-3]))()$",
Pattern.CASE_INSENSITIVE);
/** Single instance of configuration */
public final static Ipx800Config INSTANCE = new Ipx800Config();
/** Map of all device configuration */
private Map<String, Ipx800DeviceConfig> devices = new HashMap<String, Ipx800Config.Ipx800DeviceConfig>();
public class Ipx800DeviceConfig {
String name;
String host;
String port = "9870";
/** Names of x400 extensions */
String[] x400extensions = new String[3];
/** Names of x880 extensions */
String[] x880extensions = new String[3];
public Ipx800DeviceConfig(String name) {
this.name = name;
}
/**
* @return the number of x400 extensions
*/
public int getX400length() {
return getExtensionSize(x400extensions);
}
/**
* @return the number of x880 extensions
*/
public int getX880length() {
return getExtensionSize(x880extensions);
}
private int getExtensionSize(String[] extension) {
int size = 0;
for (String s : extension) {
if (s != null && !s.isEmpty()) {
size++;
}
}
return size;
}
}
/**
* @return deviceConfig map with deviceName as key
*/
public Map<String, Ipx800DeviceConfig> getDevices() {
return devices;
}
/**
* Return the device identified by name, create one if it doesn't exist
*
* @param name
* @return
*/
public Ipx800DeviceConfig retrieveDevice(String name) {
if (!devices.containsKey(name)) {
devices.put(name, new Ipx800DeviceConfig(name));
}
return devices.get(name);
}
/**
* Read and parse the config creating the Ipx800Config object
*
* @param config
* @return the configuration
* @throws ConfigurationException when configuration is invalid
*/
static Ipx800Config readConfig(Dictionary<String, ?> config) throws ConfigurationException {
Ipx800Config ipx800config = Ipx800Config.INSTANCE;
if (config == null || config.isEmpty()) {
return null;
}
for (final Enumeration<String> e = config.keys(); e.hasMoreElements();) {
final String key = e.nextElement();
final String value = (String) config.get(key);
// skip empty values
if (value == null || value.trim().isEmpty()) {
continue;
}
// skip keys that we don't want to process here ...
if ("service.pid".equals(key)) {
continue;
}
try {
// check for config keys
final Matcher matcher = CONFIG_PATTERN.matcher(key);
if (matcher.matches()) {
final String device = matcher.group(1);
final String property = matcher.group(2);
// device config
Ipx800DeviceConfig deviceConfig = ipx800config.retrieveDevice(device);
// dispatch individual properties
if ("host".equalsIgnoreCase(property)) {
deviceConfig.host = value.trim();
} else if ("port".equalsIgnoreCase(property)) {
deviceConfig.port = value.trim();
} else {
final String ext = matcher.group(3);
final String number = matcher.group(4);
if ("x880".equalsIgnoreCase(ext)) {
deviceConfig.x880extensions[Integer.parseInt(number) - 1] = value.trim();
} else {
deviceConfig.x400extensions[Integer.parseInt(number) - 1] = value.trim();
}
}
} else {
throw new ConfigurationException(key, "Invalid config key");
}
} catch (NumberFormatException ex) {
throw new ConfigurationException(key, "Invalid value: '" + value + "'");
}
}
return ipx800config;
}
}