package paramsim.paramicssimulator; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Observable; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JOptionPane; import paramsim.paramicssimulator.ParamicsSimulatorLogMessage.PARAMICS_SIMULATOR_LOG; import paramsim.paramicssimulator.gui.ParamicsSimulatorGUI; /** * ParamicsSimulator is the main class for this module. The ParamicsSimulator * can be used to simulate the Paramics device.

* The properties file for the ParamicsCommunicator class contains the following data.
* * -----------------------------------------------------------------------------
* WorkingDirectory The working directory of the Paramics Communicator
* ParamicsStatusLog The Paramics status log file
* CameraStatusLog The camera status log file
* ExchangeLog The exchange log file
* CameraControlConfig The camera control file which maps the camera information
* DVDPlayersConfig The DVD Players XML file which contains camera information
* -----------------------------------------------------------------------------
* Example File:
* WorkingDirectory = c:/paramics/out
* ParamicsStatusLog = paramics_status.log
* CameraStatusLog = camera_status.log
* IncidentLog = exchange.log
* CameraControlConfig = camera_control.txt * DVDPlayersConfig = dvdplayers.xml * -----------------------------------------------------------------------------
*
* * @author Greg Eddington (geddingt@calpoly.edu) */ public class ParamicsSimulator extends Observable implements Runnable { /** Error Log **/ private static Logger paramLogger = Logger.getLogger("paramsim.paramicssimulator"); /** Incident file **/ private static final String INCIDENT_FILE = "exchange.xml"; /** Paramics Status file **/ private static final String PARAM_STATUS_FILE = "paramics_status.xml"; /** Camera Status file **/ private static final String CAMERA_STATUS_FILE = "camera_status.xml"; /** Sleep Time (10 seconds) **/ private static final int SLEEP_TIME = 10000; /** * Enumeration containing property names. * @author Greg Eddington */ private static enum PROPERTIES { /** The working directory for Paramics **/ WORKING_DIR ("WorkingDirectory"), /** The Paramics log **/ PARAM_STATUS_LOG ("ParamicsStatusLog"), /** The camera status log **/ CAMERA_STATUS_LOG ("CameraStatusLog"), /** The exchange log **/ INCIDENT_LOG ("IncidentLog"), /** The camera control file **/ CAMERA_CONTROL ("CameraControlConfig"), /** The still images XML file **/ DVD_PLAYERS ("DVDPlayersConfig"); public String name; private PROPERTIES(String n) { name = n; } } /** * Enumeration of network statuses. * @author Greg Eddington **/ public static enum NETWORK_STATUS { LOADING ("LOADING"), WARMING ("WARMING"), LOADED ("LOADED"), UNKNOWN ("UNKNOWN"); public String message; private NETWORK_STATUS(String n) { message = n; } } /** Properties object. */ private Properties paramicsSimProp = null; /** Working Directory **/ private String workingDirectory = null; /** Incidents File **/ private String incidentFile = null; /** Paramics Status File **/ private String paramStatusFile = null; /** Camera Status File **/ private String cameraStatusFile = null; /** Incidents Log **/ private String incidentLog = null; /** Paramics Status Log **/ private String paramStatusLog = null; /** Camera Status Log **/ private String cameraStatusLog = null; /** Incident Reader **/ private ParamicsIncidentReader incidentReader = null; /** The paramics simulator GUI **/ private ParamicsSimulatorGUI theGUI; /** The network ID **/ private int networkId = 1; /** Simulation Cameras **/ private List cameras; /** * Creates a ParamicsSimulator object with properties defined in the propertiesFile * parameter. It will initialize all file locations. */ public ParamicsSimulator(String propertiesFile) { try { paramicsSimProp = new Properties(); paramicsSimProp.load(new FileInputStream(propertiesFile)); /** Check property file **/ for (PROPERTIES property : PROPERTIES.values()) { if (paramicsSimProp.getProperty(property.name) == null || paramicsSimProp.getProperty(property.name).length() == 0) { System.err.println("Invalid Configuration: Properties file missing " + property.name + " property."); System.exit(0); } } // Directory workingDirectory = paramicsSimProp.getProperty(PROPERTIES.WORKING_DIR.name).trim(); boolean endsWithSlash = workingDirectory.charAt(workingDirectory.length()-1) == '/' || workingDirectory.charAt(workingDirectory.length()-1) == '\\'; // Files paramStatusFile = workingDirectory + (endsWithSlash ? "" : "/") + PARAM_STATUS_FILE; cameraStatusFile = workingDirectory + (endsWithSlash ? "" : "/") + CAMERA_STATUS_FILE; incidentFile = workingDirectory + (endsWithSlash ? "" : "/") + INCIDENT_FILE; // Logs incidentLog = paramicsSimProp.getProperty(PROPERTIES.INCIDENT_LOG.name).trim(); paramStatusLog = paramicsSimProp.getProperty(PROPERTIES.PARAM_STATUS_LOG.name).trim(); cameraStatusLog = paramicsSimProp.getProperty(PROPERTIES.CAMERA_STATUS_LOG.name).trim(); // Delete any old logs File ilFile = new File(incidentLog); File pslFile = new File(paramStatusLog); File cslFile = new File(cameraStatusLog); ilFile.delete(); pslFile.delete(); cslFile.delete(); // Cameras String cameraConfig = paramicsSimProp.getProperty(PROPERTIES.CAMERA_CONTROL.name).trim(); String stillImages = paramicsSimProp.getProperty(PROPERTIES.DVD_PLAYERS.name).trim(); try { // Load the cameras cameras = CameraParser.loadCameras(stillImages, cameraConfig); } catch (IOException e) { // Create an empty camera array cameras = new ArrayList(); // Log Error paramLogger.logp(Level.SEVERE, "ParamicsSimulator", "Constructor", "Error loading camera config from files \"" + stillImages + "\" and \"" + cameraConfig + "\".", e); } // Initialize GUI theGUI = new ParamicsSimulatorGUI(this); addObserver(theGUI); theGUI.addWindowListener ( new WindowListener() { public void windowActivated(WindowEvent arg0) {}; public void windowClosed(WindowEvent arg0) {}; public void windowClosing(WindowEvent arg0) { System.exit(0); }; public void windowDeactivated(WindowEvent arg0) {}; public void windowDeiconified(WindowEvent arg0) {}; public void windowIconified(WindowEvent arg0) {}; public void windowOpened(WindowEvent arg0) {}; } ); // Write an initial packets writeParamicsStatus(NETWORK_STATUS.LOADING); writeCameraStatus(cameras); } catch (Exception e) { paramLogger.logp(Level.SEVERE, "ParamicsSimulator", "Constructor", "Exception in reading properties file.", e); } incidentReader = new ParamicsIncidentReader(); } /** * Appends a message to a log file. * @param logName The name of the log file. * @param message The message to append. */ private void writeToLog(String logName, String message) { try { FileWriter w = new FileWriter(logName, true); w.write(message + "\n\n"); w.close(); } catch (IOException e) { paramLogger.logp(Level.WARNING, "ParamicsSimulator", "writeToLog", "Error writing to file " + logName + ".", e); } } /** * Runs the Paramics simulator thread. */ public void run() { // Check for packets and update the simulator for(;;) { // Flush the input file ParamicsSimulationInfo psi = incidentReader.parse(incidentFile); // Update the network ID if a packet is received if (psi != null) { networkId = psi.networkId; writeToLog(incidentLog, psi.xmlMessage); setChanged(); notifyObservers(new ParamicsSimulatorLogMessage(PARAMICS_SIMULATOR_LOG.EXCHANGE, psi.xmlMessage)); } // Write camera status writeCameraStatus(cameras); // Sleep try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException ie) {} } } /** * Writes the camera status to the camera status XML file read by the Paramics Communicator, * as well as to the camera status log file. All observers are notified with the new status, * so they can also log it. * * @param id Camera ID * @param route Route * @param direction The direction of traffic * @param postmile The postmile * @param averageSpeedNE The average speed North or East * @param averageSpeedSW The average speed South or West */ public void writeCameraStatus(List cameras) { StringBuilder message = new StringBuilder("\n"); for (SimulationCamera camera : cameras) { message.append ( " \n" + " " + camera.id + "\n" + " " + camera.route + "\n" + " " + camera.direction.xml + "\n" + " " + camera.postmile + "\n" + " " + camera.averageSpeedNE + "\n" + " " + camera.averageSpeedSW + "\n" + " \n" ); } message.append(""); try { FileWriter w = new FileWriter(cameraStatusFile); w.write(message.toString()); w.close(); } catch (IOException e) { paramLogger.logp(Level.SEVERE, "ParamicsSimulator", "writeCameraStatus", "Error writing to file " + cameraStatusFile + ".", e); } writeToLog(cameraStatusLog, message.toString()); setChanged(); notifyObservers(new ParamicsSimulatorLogMessage(PARAMICS_SIMULATOR_LOG.CAMERA_STATUS, message.toString())); } /** * Writes the Paramics status to the camera status XML file read by the Paramics Communicator, * as well as to the Paramics status log file. All observers are notified with the new status, * so they can also log it. * * @param status The current Paramics status */ public void writeParamicsStatus(NETWORK_STATUS status) { String message = "\n " + status.message + "\n " + networkId + "\n"; try { FileWriter w = new FileWriter(paramStatusFile); w.write(message); w.close(); } catch (IOException e) { paramLogger.logp(Level.SEVERE, "TrafficSimulator", "writeParamicsStatus", "Error writing to file " + paramStatusFile + ".", e); } writeToLog(paramStatusLog, message); setChanged(); notifyObservers(new ParamicsSimulatorLogMessage(PARAMICS_SIMULATOR_LOG.PARAMICS_STATUS, message)); } /** * Runs the Paramics simulator. */ public static void main(String[] args) { try { if(System.getProperty("PARAMICS_SIM_PROPERTIES") != null) { new Thread(new ParamicsSimulator(System.getProperty( "PARAMICS_SIM_PROPERTIES"))).start(); } else { throw new Exception ("PARAMICS_SIM_PROPERTIES system property not defined."); } } catch (Exception e) { paramLogger.logp(Level.SEVERE, "ParamicsSimulator", "Main", "Error occured initializing application", e); JOptionPane.showMessageDialog(null, e.getMessage(), "Error - Program Exiting", JOptionPane.ERROR_MESSAGE); System.exit(-1); } } /** * Gets the simulation cameras being used by the Paramics Simulator. * @return A list of Simulation Cameras. */ public List getCameras() { return cameras; } }