/** * Copyright (C) 2010-14 diirt developers. See COPYRIGHT.TXT * All rights reserved. Use is subject to license terms. See LICENSE.TXT */ package org.diirt.service.exec; import java.io.IOException; import java.io.InputStream; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.diirt.service.Service; import org.diirt.vtype.VNumber; import org.diirt.vtype.VString; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * Utility class to create ExecServices. * * @author carcassi */ public class ExecServices { private ExecServices() { // Prevent instantiation } /** * Creates a service with exec arguments based on the description of an XML * file. * * @param input a stream with an xml file; can't be null * @return the new service for exec commands */ public static Service createFromXml(InputStream input) { if (input == null){ throw new IllegalArgumentException("Input must not be null"); } try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(input); XPathFactory xpathFactory = XPathFactory.newInstance(); XPath xPath = xpathFactory.newXPath(); String ver = xPath.evaluate("/execService/@ver", document); String serviceName = xPath.evaluate("/execService/@name", document); String serviceDesecription = xPath.evaluate("/execService/@description", document); if (!ver.equals("1")) { throw new IllegalArgumentException("Unsupported version " + ver); } ExecServiceDescription service = new ExecServiceDescription(serviceName, serviceDesecription); service.executorService(GenericExecService.defaultExecutor); NodeList methods = (NodeList) xPath.evaluate("/execService/methods/method", document, XPathConstants.NODESET); for (int i = 0; i < methods.getLength(); i++) { Node method = methods.item(i); String methodName = xPath.evaluate("@name", method); String methodDescription = xPath.evaluate("@description", method); String command = xPath.evaluate("command", method); String resultName = xPath.evaluate("result/@name", method); String resultDescription = xPath.evaluate("result/@description", method); ExecServiceMethodDescription execMethod = new ExecServiceMethodDescription(methodName, methodDescription); execMethod.command(command); if (!resultName.trim().isEmpty()) { execMethod.queryResult(resultName, resultDescription); } NodeList arguments = (NodeList) xPath.evaluate("argument", method, XPathConstants.NODESET); for (int nArg = 0; nArg < arguments.getLength(); nArg++) { Node argument = arguments.item(nArg); String argName = xPath.evaluate("@name", argument); String argDescription = xPath.evaluate("@description", argument); String argType = xPath.evaluate("@type", argument); Class<?> argClass = null; switch(argType) { case "VNumber": argClass = VNumber.class; break; case "VString": argClass = VString.class; break; default: throw new IllegalArgumentException("Type " + argType + " not supported."); } if (!argName.trim().isEmpty()) { execMethod.addArgument(argName, argDescription, argClass); } } service.addServiceMethod(execMethod); } return service.createService(); } catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException ex) { Logger.getLogger(ExecServices.class.getName()).log(Level.FINEST, "Couldn't create service", ex); throw new IllegalArgumentException("Couldn't create service", ex); } } }