/** * Copyright (C) 2013 Colorado School of Mines * * This file is part of the Interface Software Development Kit (SDK). * * The InterfaceSDK 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. * * The InterfaceSDK 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 the InterfaceSDK. If not, see <http://www.gnu.org/licenses/>. */ package edu.mines.acmX.exhibit.input_services.hardware; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.logging.log4j.*; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * Creates a HardwareManagerMetaData object given a specified configuration * file. Throws manifest exceptions for errors related to improper tags and * attributes. * * @author Aakash Shah * @author Ryan Stauffer * * @see * {@link HardwareManager} * {@link HardwareManagerManifestException} */ public class HardwareManagerManifestLoader { private static Logger log = LogManager.getLogger(HardwareManagerManifestLoader.class.getName()); /** * Loads a manifest given a specific file. * * @param filename * @return A HardwareManagerMetaData object * @throws HardwareManagerManifestException */ public static HardwareManagerMetaData load(String filename) throws HardwareManagerManifestException { return load(HardwareManagerManifestLoader.class.getClassLoader().getResourceAsStream(filename)); } /** * Loads a manifest given a specific input stream. * * @param is The input stream * @return A HardwareManagerMetaData object * @throws HardwareManagerManifestException */ public static HardwareManagerMetaData load(InputStream is) throws HardwareManagerManifestException{ try { DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); Document manifest = docBuilder.parse(is); manifest.getDocumentElement().normalize(); return parseManifest(manifest); } catch (Exception e) { throw new HardwareManagerManifestException("Could not load manifest\n" + e.toString()); } } /** * Parses the manifest tag * * @param manifest The XML document object * @return A HardwareManagerMetaData object * @throws HardwareManagerManifestException */ private static HardwareManagerMetaData parseManifest(Document manifest) throws HardwareManagerManifestException { HardwareManagerMetaData hmmd = new HardwareManagerMetaData(); Element element = (Element) manifest.getElementsByTagName("manifest").item(0); NodeList funcTagList = element.getElementsByTagName("functionalities"); if (funcTagList.getLength() <= 0) { log.info("No functionalities tag"); throw new HardwareManagerManifestException("No functionalities tag!"); } NodeList deviceTagList = element.getElementsByTagName("devices"); if (deviceTagList.getLength() <= 0) { log.info("No devices tag"); throw new HardwareManagerManifestException("No devices tag!"); } parseFunctionalities(funcTagList, hmmd); parseDevices(deviceTagList, hmmd); return hmmd; } /** * Parses the functionalities tag. * @param funcTagList NodeList with all the functionalities tag * @param hdsmd the meta data object to store information into * @throws HardwareManagerManifestException */ private static void parseFunctionalities(NodeList funcTagList, HardwareManagerMetaData hdsmd) throws HardwareManagerManifestException { Map<String, String> supportList = new HashMap<String, String>(); for (int i = 0; i < funcTagList.getLength(); ++i) { Element funcTag = (Element) funcTagList.item(i); NodeList supportTagList = funcTag.getElementsByTagName("supports"); if (supportTagList.getLength() <= 0) { throw new HardwareManagerManifestException("No supports definition in functionalities tag"); } for (int j = 0; j < supportTagList.getLength(); ++j) { Element supportTag = (Element) supportTagList.item(j); String name = supportTag.getAttribute("name").toLowerCase(); String intrface = supportTag.getAttribute("interface"); if (name.isEmpty() || intrface.isEmpty()) { log.info("No name or interface tag"); throw new HardwareManagerManifestException("Missing attribute for support tag"); } if (supportList.containsKey(name)) { throw new HardwareManagerManifestException("Duplicate support defintions"); } supportList.put(name, intrface); } } hdsmd.setFunctionalities(supportList); } /** * Parses the devices tags * @param devicesTagList NodeList with all the devices tag * @param hmmd the meta data object to store information into * @throws HardwareManagerManifestException */ private static void parseDevices(NodeList devicesTagList, HardwareManagerMetaData hmmd) throws HardwareManagerManifestException { Map<String, String> deviceDrivers = new HashMap<String, String>(); Map<String, List<String>> deviceFunc = new HashMap<String, List<String>>(); for (int i = 0; i < devicesTagList.getLength(); ++i) { Element devicesTag = (Element) devicesTagList.item(i); NodeList deviceTagList = devicesTag.getElementsByTagName("device"); if (deviceTagList.getLength() <= 0) { throw new HardwareManagerManifestException("No device definitions in devices tag"); } for (int j = 0; j < deviceTagList.getLength(); ++j) { Element deviceTag = (Element) deviceTagList.item(j); String name = deviceTag.getAttribute("name").toLowerCase(); String driver = deviceTag.getAttribute("driver"); if (name.isEmpty() || driver.isEmpty()) { throw new HardwareManagerManifestException("Missing attribute for device tag"); } if (deviceDrivers.containsKey(name)) { throw new HardwareManagerManifestException("Duplicate driver definitions"); } NodeList provideTagList = deviceTag.getElementsByTagName("provides"); if (provideTagList.getLength() <= 0) { throw new HardwareManagerManifestException("No provides definitions in device tag"); } List<String> provideList = parseDeviceProvides(provideTagList); deviceDrivers.put(name, driver); deviceFunc.put(name, provideList); } } hmmd.setDevices(deviceDrivers); hmmd.setDeviceSupports(deviceFunc); } /** * * @param provideTagList * @return List of provided functionalities for a device * @throws HardwareManagerManifestException */ private static List<String> parseDeviceProvides(NodeList provideTagList) throws HardwareManagerManifestException{ List<String> deviceFunc = new ArrayList<String>(); for (int k = 0; k < provideTagList.getLength(); ++k) { Element provideTag = (Element) provideTagList.item(k); String name = provideTag.getAttribute("name").toLowerCase(); if (name.isEmpty()) { throw new HardwareManagerManifestException("Missing attribute for provides tag"); } deviceFunc.add(name); } return deviceFunc; } }