/** * 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.zwave.internal.config; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Collections; import java.util.List; import org.osgi.framework.FrameworkUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamImplicit; import com.thoughtworks.xstream.io.xml.StaxDriver; /** * Implements the top level functions for the XML product database This class * includes helper functions to manipulate the database and facilitate access to * the database. * * @author Chris Jackson * @since 1.4.0 * */ public class ZWaveProductDatabase { private static final Logger logger = LoggerFactory.getLogger(ZWaveProductDatabase.class); ZWaveDbRoot database = null; Languages language = Languages.ENGLISH; ZWaveDbManufacturer selManufacturer = null; ZWaveDbProduct selProduct = null; ZWaveDbProductFile productFile = null; String productVersion; public ZWaveProductDatabase() { loadDatabase(); } /** * Constructor for the product database * * @param Language * defines the language in which all labels will be returned */ public ZWaveProductDatabase(Languages Language) { language = Language; loadDatabase(); } /** * Constructor for the product database * * @param Language * defines the language in which all labels will be returned */ public ZWaveProductDatabase(String Language) { language = Languages.fromString(Language); loadDatabase(); } private void loadDatabase() { URL entry = FrameworkUtil.getBundle(ZWaveProductDatabase.class).getEntry("database/products.xml"); if (entry == null) { database = null; logger.error("Unable to load ZWave product database!"); return; } XStream xstream = new XStream(new StaxDriver()); xstream.alias("Manufacturers", ZWaveDbRoot.class); xstream.alias("Manufacturer", ZWaveDbManufacturer.class); xstream.alias("Product", ZWaveDbProduct.class); xstream.alias("Reference", ZWaveDbProductReference.class); xstream.processAnnotations(ZWaveDbRoot.class); try { // this.Manufacturer = (ZWaveDbManufacturer) InputStream x = entry.openStream(); database = (ZWaveDbRoot) xstream.fromXML(x); if (database == null) { return; } } catch (IOException e) { e.printStackTrace(); } } /** * Loads the product file relating to the requested version. * * @param version the required device version * @return filename of the product file */ private ZWaveDbProductFile LoadProductFile() { // If the file is already loaded, then just return the class if (productFile != null) { return productFile; } // Have we selected a product? if (selProduct == null) { return null; } String cfgFile = selProduct.getConfigFile(productVersion); if (cfgFile == null || cfgFile.isEmpty()) { return null; } URL entry = FrameworkUtil.getBundle(ZWaveProductDatabase.class).getEntry("database/" + cfgFile); if (entry == null) { database = null; logger.error("Unable to load ZWave product file: '{}'", cfgFile); return null; } XStream xstream = new XStream(new StaxDriver()); xstream.alias("Product", ZWaveDbProductFile.class); xstream.alias("Configuration", ZWaveDbProductFile.ZWaveDbConfiguration.class); xstream.alias("Parameter", ZWaveDbConfigurationParameter.class); xstream.alias("Item", ZWaveDbConfigurationListItem.class); xstream.alias("Associations", ZWaveDbProductFile.ZWaveDbAssociation.class); xstream.alias("Group", ZWaveDbAssociationGroup.class); xstream.alias("CommandClass", ZWaveDbProductFile.ZWaveDbCommandClassList.class); xstream.alias("Class", ZWaveDbCommandClass.class); xstream.processAnnotations(ZWaveDbProductFile.class); try { // this.Manufacturer = (ZWaveDbManufacturer) InputStream x = entry.openStream(); productFile = (ZWaveDbProductFile) xstream.fromXML(x); } catch (IOException e) { logger.error("Unable to load ZWave product file '{}' : {}", cfgFile, e.toString()); } return productFile; } public List<ZWaveDbManufacturer> GetManufacturers() { if (database == null || database.Manufacturer == null) { return Collections.emptyList(); } return database.Manufacturer; } public List<ZWaveDbProduct> GetProducts() { if (selManufacturer == null) { return Collections.emptyList(); } return selManufacturer.Product; } /** * Finds the manufacturer in the database. * * @param manufacturerId * @return true if the manufacturer was found */ public boolean FindManufacturer(int manufacturerId) { if (database == null || database.Manufacturer == null) { return false; } selManufacturer = null; selProduct = null; productFile = null; for (ZWaveDbManufacturer manufacturer : database.Manufacturer) { if (manufacturer.Id == manufacturerId) { selManufacturer = manufacturer; return true; } } return false; } /** * Finds a product in the database * * @param manufacturerId * The manufacturer ID * @param productType * The product type * @param productId * The product ID * @return true if the product was found */ public boolean FindProduct(int manufacturerId, int productType, int productId, String version) { if (FindManufacturer(manufacturerId) == false) { return false; } return FindProduct(productType, productId, version); } /** * Finds a product in the database. FindManufacturer must be called before * this function. * * @param productType * The product type * @param productId * The product ID * @return true if the product was found */ public boolean FindProduct(int productType, int productId, String version) { if (selManufacturer == null) { return false; } productVersion = version; for (ZWaveDbProduct product : selManufacturer.Product) { for (ZWaveDbProductReference reference : product.Reference) { if (reference.Type == productType && reference.Id == productId) { selProduct = product; return true; } } } return false; } /** * Returns the manufacturer name. FindManufacturer or FindProduct must be * called before this method. * * @return String with the manufacturer name, or null if not found. */ public String getManufacturerName() { if (selManufacturer == null) { return ""; } else { return selManufacturer.Name; } } /** * Returns the manufacturer ID. FindManufacturer or FindProduct must be * called before this method. * * @return Integer with the manufacturer ID, or null if not found. */ public Integer getManufacturerId() { if (selManufacturer == null) { return null; } else { return selManufacturer.Id; } } /** * Returns the product name. FindProduct must be called before this method. * * @return String with the product name, or null if not found. */ public String getProductName() { if (selProduct == null) { return ""; } else { return selProduct.Model + " " + getLabel(selProduct.Label); } } /** * Returns the product model. FindProduct must be called before this method. * * @return String with the product model, or null if not found. */ public String getProductModel() { if (selProduct == null) { return null; } return selProduct.Model; } /** * Returns the number of endpoints from the database. FindProduct must be * called before this method. * * @return number of endpoints */ public Integer getProductEndpoints() { if (selProduct == null) { return null; } return 0; } /** * Checks if a specific command class is implemented by the device. * FindProduct must be called before this method. * * @param classNumber * the class number to check * @return true if the class is supported */ public boolean doesProductImplementCommandClass(Integer classNumber) { if (LoadProductFile() == null) { return false; } if (productFile.CommandClasses == null || productFile.CommandClasses.Class == null) { return false; } for (ZWaveDbCommandClass iClass : productFile.CommandClasses.Class) { if (iClass.Id.equals(classNumber)) { return true; } } return false; } /** * Returns the command classes implemented by the device. * FindProduct must be called before this method. * * @return true if the class is supported */ public List<ZWaveDbCommandClass> getProductCommandClasses() { if (LoadProductFile() == null) { return null; } if (productFile.CommandClasses == null) { return null; } return productFile.CommandClasses.Class; } /** * Returns the configuration parameters list. FindProduct must be called * before this method. * * @return List of configuration parameters */ public List<ZWaveDbConfigurationParameter> getProductConfigParameters() { if (LoadProductFile() == null) { return Collections.emptyList(); } return productFile.getConfiguration(); } /** * Returns the associations list. FindProduct must be called before this * method. * * @return List of association groups */ public List<ZWaveDbAssociationGroup> getProductAssociationGroups() { if (LoadProductFile() == null) { return null; } return productFile.getAssociations(); } private class ZWaveDbRoot { @XStreamImplicit List<ZWaveDbManufacturer> Manufacturer; } /** * Helper function to find the label associated with the specified database * language If no language is defined, or if the label cant be found in the * specified language the english label will be returned. * * @param labelList * A List defining the label * @return String of the respective language */ public String getLabel(List<ZWaveDbLabel> labelList) { if (labelList == null) { return null; } for (ZWaveDbLabel label : labelList) { if (label.Language == null) { return label.Label; } if (label.Language.equals(language.toString())) { return label.Label; } } return null; } /** * enum defining the languages used for the multilingual labels in the * product database * */ public enum Languages { ENGLISH("en"), GERMAN("de"); private String value; private Languages(String value) { this.value = value; } public static Languages fromString(String text) { if (text != null) { for (Languages c : Languages.values()) { if (text.equalsIgnoreCase(c.value)) { return c; } } } return ENGLISH; } @Override public String toString() { return this.value; } } }