/* * Copyright 2011-16 Fraunhofer ISE * * This file is part of OpenMUC. * For more information visit http://www.openmuc.org * * OpenMUC is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenMUC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenMUC. If not, see <http://www.gnu.org/licenses/>. * */ package org.openmuc.framework.core.datamanager; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import org.openmuc.framework.config.DeviceConfig; import org.openmuc.framework.config.DriverConfig; import org.openmuc.framework.config.IdCollisionException; import org.openmuc.framework.config.ParseException; import org.openmuc.framework.config.RootConfig; import org.openmuc.framework.driver.spi.DriverService; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public final class DriverConfigImpl implements DriverConfig { String id; Integer samplingTimeout = null; Integer connectRetryInterval = null; Boolean disabled = null; final HashMap<String, DeviceConfigImpl> deviceConfigsById = new LinkedHashMap<>(); RootConfigImpl rootConfigParent; DriverService activeDriver = null; DriverConfigImpl(String id, RootConfigImpl rootConfigParent) { this.id = id; this.rootConfigParent = rootConfigParent; } @Override public String getId() { return id; } @Override public void setId(String id) throws IdCollisionException { if (id == null) { throw new IllegalArgumentException("The driver ID may not be null"); } ChannelConfigImpl.checkIdSyntax(id); if (rootConfigParent.driverConfigsById.containsKey(id)) { throw new IdCollisionException("Collision with the driver ID:" + id); } rootConfigParent.driverConfigsById.put(id, rootConfigParent.driverConfigsById.remove(this.id)); this.id = id; } @Override public Integer getSamplingTimeout() { return samplingTimeout; } @Override public void setSamplingTimeout(Integer timeout) { if (timeout != null && timeout < 0) { throw new IllegalArgumentException("A negative sampling timeout is not allowed"); } samplingTimeout = timeout; } @Override public Integer getConnectRetryInterval() { return connectRetryInterval; } @Override public void setConnectRetryInterval(Integer interval) { if (interval != null && interval < 0) { throw new IllegalArgumentException("A negative connect retry interval is not allowed"); } connectRetryInterval = interval; } @Override public Boolean isDisabled() { return disabled; } @Override public void setDisabled(Boolean disabled) { this.disabled = disabled; } @Override public DeviceConfig addDevice(String deviceId) throws IdCollisionException { if (deviceId == null) { throw new IllegalArgumentException("The device ID may not be null"); } ChannelConfigImpl.checkIdSyntax(deviceId); if (rootConfigParent.deviceConfigsById.containsKey(deviceId)) { throw new IdCollisionException("Collision with device ID: " + deviceId); } DeviceConfigImpl newDevice = new DeviceConfigImpl(deviceId, this); rootConfigParent.deviceConfigsById.put(deviceId, newDevice); deviceConfigsById.put(deviceId, newDevice); return newDevice; } @Override public DeviceConfig getDevice(String deviceId) { return deviceConfigsById.get(deviceId); } @SuppressWarnings("unchecked") @Override public Collection<DeviceConfig> getDevices() { return (Collection<DeviceConfig>) (Collection<?>) Collections .unmodifiableCollection(deviceConfigsById.values()); } @Override public void delete() { rootConfigParent.driverConfigsById.remove(id); for (DeviceConfigImpl deviceConfig : deviceConfigsById.values()) { deviceConfig.clear(); } deviceConfigsById.clear(); rootConfigParent = null; } static void addDriverFromDomNode(Node driverConfigNode, RootConfig parentConfig) throws ParseException { String id = ChannelConfigImpl.getAttributeValue(driverConfigNode, "id"); if (id == null) { throw new ParseException("driver has no id attribute"); } DriverConfigImpl config; try { config = (DriverConfigImpl) parentConfig.addDriver(id); } catch (Exception e) { throw new ParseException(e); } NodeList driverChildren = driverConfigNode.getChildNodes(); try { for (int j = 0; j < driverChildren.getLength(); j++) { Node childNode = driverChildren.item(j); String childName = childNode.getNodeName(); if (childName.equals("#text")) { continue; } else if (childName.equals("device")) { DeviceConfigImpl.addDeviceFromDomNode(childNode, config); } else if (childName.equals("samplingTimeout")) { config.setSamplingTimeout(ChannelConfigImpl.timeStringToMillis(childNode.getTextContent())); } else if (childName.equals("connectRetryInterval")) { config.setConnectRetryInterval(ChannelConfigImpl.timeStringToMillis(childNode.getTextContent())); } else if (childName.equals("disabled")) { String disabledString = childNode.getTextContent().toLowerCase(); if (disabledString.equals("true")) { config.disabled = true; } else if (disabledString.equals("false")) { config.disabled = false; } else { throw new ParseException("\"disabled\" tag contains neither \"true\" nor \"false\""); } } else { throw new ParseException("found unknown tag:" + childName); } } } catch (IllegalArgumentException e) { throw new ParseException(e); } } Element getDomElement(Document document) { Element parentElement = document.createElement("driver"); parentElement.setAttribute("id", id); Element childElement; if (samplingTimeout != null) { childElement = document.createElement("samplingTimeout"); childElement.setTextContent(ChannelConfigImpl.millisToTimeString(samplingTimeout)); parentElement.appendChild(childElement); } if (connectRetryInterval != null) { childElement = document.createElement("connectRetryInterval"); childElement.setTextContent(ChannelConfigImpl.millisToTimeString(connectRetryInterval)); parentElement.appendChild(childElement); } if (disabled != null) { childElement = document.createElement("disabled"); if (disabled) { childElement.setTextContent("true"); } else { childElement.setTextContent("false"); } parentElement.appendChild(childElement); } for (DeviceConfigImpl deviceConfig : deviceConfigsById.values()) { parentElement.appendChild(deviceConfig.getDomElement(document)); } return parentElement; } DriverConfigImpl clone(RootConfigImpl clonedParentConfig) { DriverConfigImpl configClone = new DriverConfigImpl(id, clonedParentConfig); configClone.samplingTimeout = samplingTimeout; configClone.connectRetryInterval = connectRetryInterval; configClone.disabled = disabled; for (DeviceConfigImpl deviceConfig : deviceConfigsById.values()) { configClone.deviceConfigsById.put(deviceConfig.id, deviceConfig.clone(configClone)); } return configClone; } DriverConfigImpl cloneWithDefaults(RootConfigImpl clonedParentConfig) { DriverConfigImpl configClone = new DriverConfigImpl(id, clonedParentConfig); if (samplingTimeout == null) { configClone.samplingTimeout = SAMPLING_TIMEOUT_DEFAULT; } else { configClone.samplingTimeout = samplingTimeout; } if (connectRetryInterval == null) { configClone.connectRetryInterval = CONNECT_RETRY_INTERVAL_DEFAULT; } else { configClone.connectRetryInterval = connectRetryInterval; } if (disabled == null) { configClone.disabled = DISABLED_DEFAULT; } else { configClone.disabled = disabled; } for (DeviceConfigImpl deviceConfig : deviceConfigsById.values()) { configClone.deviceConfigsById.put(deviceConfig.id, deviceConfig.cloneWithDefaults(configClone)); } return configClone; } }