/** * 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.anel.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.openhab.binding.anel.internal.AnelBinding.IInternalAnelBinding; import org.osgi.service.cm.ConfigurationException; /** * Reads the configuration and initializes connector threads for them. * * @since 1.6.0 * @author paphko */ public class AnelConfigReader { /** * Refresh rate with which the state is regularly updated. */ final static long DEFAULT_REFRESH_INTERVAL = 60000; /** * If cache period is set to a positive integer, then this specifies the * amount of minutes the switch states are cached. During that time, only * changes are reported to the event bus. E.g. when set to 60, the cache is * cleared once per hour. */ private final static long DEFAULT_CACHE_PERIOD = 0; /** Config data initialized with default values. */ private static class AnelConfig { String user = "user7"; String password = "anel"; String host = "net-control"; int sendPort = 75; int receivePort = 77; } /** Pattern for all valid device configuration keys. */ private final static Pattern CONFIG_PATTERN = Pattern .compile("^(.+?)\\.(host|user|password|udpReceivePort|udpSendPort)$", Pattern.CASE_INSENSITIVE); /** * Read configuration for the Anel binding by creating the connector threads * (they are not yet started) and returning the refresh rate and cache * period. * * @param config * The configuration passed from the core. * @param threads * A map of threads that will be filled by this call. * @param bindingFacade * The binding facade that is needed by the connector threads. * @return The refresh rate. */ static long readConfig(Dictionary<String, ?> config, Map<String, AnelConnectorThread> threads, IInternalAnelBinding bindingFacade) throws ConfigurationException { if (config == null || config.isEmpty()) { return DEFAULT_REFRESH_INTERVAL; } long cachePeriod = DEFAULT_CACHE_PERIOD; long refresh = DEFAULT_REFRESH_INTERVAL; final Map<String, AnelConfig> anelConfigs = new HashMap<String, AnelConfig>(); 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 { // refresh is global setting, get value and continue if ("refresh".equalsIgnoreCase(key)) { refresh = Long.parseLong(((String) config.get(key)).trim()); continue; } // cache period is global setting, get value and continue if ("cachePeriod".equalsIgnoreCase(key)) { cachePeriod = Integer.parseInt(((String) config.get(key)).trim()); continue; } // 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 AnelConfig anelConfig = anelConfigs.get(device); if (anelConfig == null) { anelConfig = new AnelConfig(); anelConfigs.put(device, anelConfig); } // dispatch individual properties if ("host".equalsIgnoreCase(property)) { anelConfig.host = value.trim(); } else if ("user".equalsIgnoreCase(property)) { anelConfig.user = value.trim(); } else if ("password".equalsIgnoreCase(property)) { anelConfig.password = value.trim(); } else if ("udpSendPort".equalsIgnoreCase(property)) { anelConfig.sendPort = Integer.parseInt(value.trim()); } else if ("udpReceivePort".equalsIgnoreCase(property)) { anelConfig.receivePort = Integer.parseInt(value.trim()); } } else { throw new ConfigurationException(key, "Invalid config key"); } } catch (NumberFormatException ex) { throw new ConfigurationException(key, "Invalid value: '" + value + "'"); } } // we collected all configs, now let's create the actual threads for (String device : anelConfigs.keySet()) { final AnelConfig anelConfig = anelConfigs.get(device); final AnelConnectorThread thread = new AnelConnectorThread(device, anelConfig.host, anelConfig.receivePort, anelConfig.sendPort, anelConfig.user, anelConfig.password, bindingFacade, cachePeriod); threads.put(device, thread); } return refresh; } }