📄 xmlcommandhandler.java
字号:
/* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: XMLCommandHandler.java,v 1.1 2007/08/21 14:39:58 fros4943 Exp $ */package se.sics.chakana;import java.io.File;import java.io.IOException;import java.io.StringReader;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.util.Collection;import javax.swing.JFrame;import javax.swing.JInternalFrame;import org.apache.log4j.Logger;import org.jdom.Document;import org.jdom.Element;import org.jdom.JDOMException;import org.jdom.input.SAXBuilder;import se.sics.chakana.EventpointEvaluator.EventpointException;import se.sics.chakana.eventpoints.*;import se.sics.cooja.AddressMemory;import se.sics.cooja.CoreComm;import se.sics.cooja.GUI;import se.sics.cooja.Mote;import se.sics.cooja.MoteMemory;import se.sics.cooja.RadioMedium;import se.sics.cooja.Simulation;import se.sics.cooja.Mote.State;import se.sics.cooja.MoteType.MoteTypeCreationException;import se.sics.cooja.dialogs.MessageList;import se.sics.cooja.plugins.VisState;import se.sics.cooja.plugins.Visualizer2D;import se.sics.cooja.radiomediums.UDGM;/** * Handles incoming XML commands. * Each command handling call blocks during handling and returns a reply to the client. * * A command must always be of the form: * <command>...</command> * * @author Fredrik Osterlind */public class XMLCommandHandler { public static final boolean DEBUG_OUTPUT = true; private static Logger logger = Logger.getLogger(XMLCommandHandler.class); public static final String XML_OK = "<ok/>"; public static final String XML_OK_START = "<ok>"; public static final String XML_OK_END = "</ok>"; public static final String XML_INFO_START = "<info>"; public static final String XML_INFO_END = "</info>"; public static final String XML_ERROR_START = "<error>"; public static final String XML_ERROR_END = "</error>"; public static final String XML_COMMAND_NAME = "command"; public static final String XML_COMMAND_END = "</command>"; public static final String XML_EVENTPOINT_START = "<eventpoint>"; public static final String XML_EVENTPOINT_END = "</eventpoint>"; public static final String XML_ID_NAME = "id"; public static final String XML_TYPE_NAME = "type"; public static final String XML_MOTE_NAME = "mote"; public static final String XML_VARIABLE_NAME = "variable"; public static final String XML_MOTECOUNT_NAME = "motecount"; public static final String XML_VALUE_NAME = "value"; public static final String XML_TIME_NAME = "time"; public static final String XML_SIZE_NAME = "size"; public static final String XML_ADDRESS_NAME = "address"; public static final String XML_VISIBLE_NAME = "visible"; public static final String XML_TRIGGERON_NAME = "triggeron"; public static final String XML_WATCHPOINT_INT = "int"; public static final String XML_WATCHPOINT_VARIABLE = "variable"; public static final String XML_WATCHPOINT_ADDRESS = "address"; public static final String XML_TIMEPOINT_SIMULATION = "time"; public static final String XML_TIMEPOINT_REAL = "realtime"; public static final String XML_EVENTPOINT_RADIOMEDIUM = "radiomedium"; private GUI myGUI; private EventpointEvaluator myEvaluator; private ChakanaPlugin myParent; public enum Command { CREATE_SIM, CONF_SIM, CONF_PLUGINS, CONTROL_SIM, SET_GUI, ADD_EVENTPOINT, READ_MEMORY, WRITE_MEMORY, CLEAR_EVENTPOINTS, DELETE_EVENTPOINT, KILL_NODES, GET_INFO, CUSTOM_COMMAND, EXIT_COOJA; } public enum ControlSimulationCommand { RESUME; } /** * TODO Document * * @param gui * @param parent * @param evaluator */ public XMLCommandHandler(GUI gui, ChakanaPlugin parent, EventpointEvaluator evaluator) { myGUI = gui; myEvaluator = evaluator; myParent = parent; } /** * @param command * @return */ public boolean containsEntireCommand(String command) { return command.contains(XMLCommandHandler.XML_COMMAND_END); // TODO Ugly trick } /** * Handle given command (XML format). * Method blocks until given command has been handled. * * @param command * Command to handle * @return Reply to client in XML format */ public String handleCommand(String command) { try { SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(new StringReader(command)); Element root = doc.getRootElement(); if (!root.getName().equals(XML_COMMAND_NAME)) { return createErrorMessage("Malformed command: " + root.getName()); } String cmdTypeString = root.getAttributeValue("value"); Command cmdType; try { cmdType = Command.valueOf(cmdTypeString); } catch (IllegalArgumentException e) { return createErrorMessage("Unknown command: " + cmdTypeString); } Collection<Element> cmdInfo = root.getChildren(); logger.debug("Command type: " + cmdType); switch (cmdType) { case CREATE_SIM: return createSimulation(cmdInfo); case CONF_SIM: return configureSimulation(cmdInfo); case CONF_PLUGINS: return configurePlugins(cmdInfo); case CONTROL_SIM: return controlSimulation(cmdInfo); case ADD_EVENTPOINT: return addEventpoint(cmdInfo); case SET_GUI: return configureGUI(cmdInfo); case READ_MEMORY: return readMemory(cmdInfo); case WRITE_MEMORY: return writeMemory(cmdInfo); case CLEAR_EVENTPOINTS: return clearEventpoints(); case DELETE_EVENTPOINT: return deleteEventpoint(cmdInfo); case KILL_NODES: return killNodes(cmdInfo); case GET_INFO: return getInfo(cmdInfo); case CUSTOM_COMMAND: return handleCustomCommand(cmdInfo); case EXIT_COOJA: return shutdownCOOJA(cmdInfo); default: return createErrorMessage("Unknown command: " + cmdType); } } catch (JDOMException e) { logger.fatal("Command parsing exception: " + e); return createErrorMessage("Invalid command syntax: " + e.getMessage()); } catch (IOException e) { logger.fatal("Command parsing exception: " + e); return createErrorMessage("Invalid command syntax: " + e.getMessage()); } } /** * Handle create new simulation command. * * @param arguments Command arguments * @return Reply to client (XML format) */ private String createSimulation(Collection<Element> arguments) { Simulation simulation = new Simulation(myGUI); simulation.setTitle("[chakana - no title]"); simulation.setDelayTime(0); simulation.setSimulationTime(0); simulation.setTickTime(1); try { RadioMedium radioMedium = RadioMedium.generateRadioMedium(UDGM.class, simulation); simulation.setRadioMedium(radioMedium); } catch (Exception e) { return createErrorMessage("Create simulation: Could not create radio medium: " + e.getMessage()); } // Let simulation parse command arguments myGUI.setSimulation(simulation); try { boolean success = simulation.setConfigXML(arguments, false); } catch (Exception e) { logger.fatal("Error when configuring simulation: " + e); if (DEBUG_OUTPUT) { if (e instanceof MoteTypeCreationException) { MessageList compilationOutput = ((MoteTypeCreationException) e).getCompilationOutput(); if (compilationOutput != null) { logger.info("Compilation output:"); for(int i = 0; i < compilationOutput.getModel().getSize(); i++) { logger.info(compilationOutput.getModel().getElementAt(i)); } } StackTraceElement[] stackTrace = e.getStackTrace(); if (stackTrace != null) { logger.info("Stack trace:"); for(StackTraceElement element: stackTrace) { logger.info(element); } } GUI.showErrorDialog(new JFrame(""), "Set DEBUG_OUTPUT to false to disable this frame", e, false); // XXX Graphical component } } return createErrorMessage("Create simulation: Could not configure simulation: " + e.getMessage()); } return XML_OK; } /** * Handle configure simulation command. * * @param arguments Command arguments * @return Reply to client (XML format) */ private String configureSimulation(Collection<Element> arguments) { Simulation simulation = myGUI.getSimulation(); // Let simulation parse command arguments try { simulation.setConfigXML(arguments, false); } catch (Exception e) { logger.fatal("Error when configuring simulation: " + e); e.printStackTrace(); return createErrorMessage("Could not configure simulation: " + e.getMessage()); } return XML_OK; } /** * Handle configure plugins command. * * @param arguments Command arguments * @return Reply to client (XML format) */ private String configurePlugins(Collection<Element> arguments) { Simulation simulation = myGUI.getSimulation(); // Let GUI parse command arguments try { myGUI.setPluginsConfigXML(arguments, simulation, false); } catch (Exception e) { logger.fatal("Error when configuring plugins: " + e); return createErrorMessage("Could not configure plugins: " + e.getMessage()); } return XML_OK; } /** * Handle control simulation command. * * @param arguments Command arguments * @return Reply to client (XML format) */ private String controlSimulation(Collection<Element> arguments) { String reply = ""; for (Element element : arguments) { ControlSimulationCommand cmdType; try { cmdType = ControlSimulationCommand.valueOf(element.getName()); } catch (IllegalArgumentException e) { return createErrorMessage("Unknown simulation control command: " + element.getName()); } switch (cmdType) { case RESUME: // TODO Check performance degradation using try-blocks try { myEvaluator.resumeSimulation(); reply += createEventpointMessage(myEvaluator); } catch (EventpointException e) { return createErrorMessage("Exception during simulation: " + e); } break; default: return createErrorMessage("Unknown simulation control command"); } } return reply; } /** * Handle exit COOJA command. * * @param arguments Command arguments * @return Reply to client (XML format) */ private String shutdownCOOJA(Collection<Element> arguments) { myParent.performCOOJAShutdown(); logger.info("Shutdown requested"); return XML_OK; } /** * Fetch mote variable value as specified by arguments. * * @param arguments Command arguments * @return Reply to client (XML format) */ private String readMemory(Collection<Element> arguments) { Simulation simulation = myGUI.getSimulation(); String type = null; String mote = null; String variable = null; String size = null; String address = null; for (Element element : arguments) { if (element.getName().equals(XML_TYPE_NAME)) { type = element.getText(); } else if (element.getName().equals(XML_MOTE_NAME)) { mote = element.getText(); } else if (element.getName().equals(XML_VARIABLE_NAME)) { variable = element.getText();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -