package tmcsim.paramicslog; import java.io.FileInputStream; import java.io.IOException; import java.rmi.Naming; import java.util.Properties; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; import javax.swing.JOptionPane; import tmcsim.common.SimulationException; import tmcsim.interfaces.CoordinatorInterface; /** * Logs communication from ParamicsCommunicator to ParamicsSimulator. * * The system property "PARAMICS_LOG_CONFIG" should be set to the path where the * properties file for this class is located.

* The data for the properties file follows.
* * -----------------------------------------------------------------
* Log File The file to write the communication to. CAD Simulator Host The host * that runs the CAD Simulator. CAD Simulator RMI Port The port on the host that * runs the CAD Simulator where the RMI Coordinator object is registered to. * -----------------------------------------------------------------
* Example File:
* LogFile=c:\\log.txt CADSimulatorHost=localhost CADSimulatorRMIPort=4445 * -----------------------------------------------------------------
*
* * @author Nathaniel Lehrer * @version */ public class ParamicsLogFileHandler extends java.util.logging.FileHandler { /** * Enmeration containing property names. * * @author Nathaniel Lehrer */ private enum PROPERTIES { LOG_FILE("LogFile"), CAD_SIM_HOST("CADSimulatorHost"), CAD_SIM_PORT("CADSimulatorRMIPort"); public String name; private PROPERTIES(String n) { name = n; } } /** * Error logger. */ private static Logger paramLogger = Logger.getLogger("tmcsim.paramicslog"); /** * Static instance. */ private static ParamicsLogFileHandler instance; private static String propertiesFile; /** * Properties object. */ private static Properties paramicsLogProp; /** * File log entries are written to */ // private static String logFile; /** * Stores the log entries. This contains the same information logFile. */ private StringBuilder log; /** * Remote reference to the simulation */ private CoordinatorInterface theCoorInt; /** * Object for synchronizing IO */ Object lock; /** * Creates the singleton instance of this class. */ public static ParamicsLogFileHandler getInstance() throws IOException { System.setProperty("PARAMICS_LOG_PROPERTIES", "config/paramics_communicator_logging.properties"); // Has an instance been created yet? if (instance == null) { try { if (System.getProperty("PARAMICS_LOG_PROPERTIES") != null) { propertiesFile = System.getProperty("PARAMICS_LOG_PROPERTIES"); paramicsLogProp = new Properties(); paramicsLogProp.load(new FileInputStream(propertiesFile)); if ((paramicsLogProp.getProperty(PROPERTIES.LOG_FILE.name)) == null) { throw new Exception("Properties file missing log file location."); } String logFile = paramicsLogProp.getProperty(PROPERTIES.LOG_FILE.name); instance = new ParamicsLogFileHandler(logFile); } else { throw new Exception("PARAMICS_LOG_PROPERTIES system property not defined."); } } catch (Exception e) { instance = new ParamicsLogFileHandler(); paramLogger.logp(Level.WARNING, "ParamicsLog", "static initializer", "Error occured initializing application", e); JOptionPane.showMessageDialog(null, e.getMessage(), "Error - ParamicsLog will not save log to file.", JOptionPane.ERROR_MESSAGE); } } return instance; } /** * Creates an instance of ParamicsLog that does not write to a file when * writeToLog is called. */ private ParamicsLogFileHandler() throws IOException { lock = new Object(); log = new StringBuilder(""); } /** * Creates an instance of ParamicsLog that writes to a file when writeToLog * is called. * * @param propertiesFile */ private ParamicsLogFileHandler(String logFile) throws IOException { super(logFile); lock = new Object(); log = new StringBuilder(""); //String logFile = null; String CADSIMHost = null; String CADSIMPort = null; try { paramicsLogProp = new Properties(); paramicsLogProp.load(new FileInputStream(propertiesFile)); if ((CADSIMHost = paramicsLogProp.getProperty(PROPERTIES.CAD_SIM_HOST.name)) == null) { throw new Exception("Properties file missing CAD Simulator host."); } else if ((CADSIMPort = paramicsLogProp.getProperty(PROPERTIES.CAD_SIM_PORT.name)) == null) { throw new Exception("Properties file missing CAD Simulator RMI port."); } try { connect(CADSIMHost, CADSIMPort); } catch (Exception e) { JOptionPane.showMessageDialog(null, "ParamicsLog: Could not connect to remote Coordinator object.", "Network Error", JOptionPane.ERROR_MESSAGE); } // try // { // createLogFile(logFile); // } catch (Exception e) // { // JOptionPane.showMessageDialog(null, // "ParamicsLog: Could not create new log file.", // "File Error", JOptionPane.ERROR_MESSAGE); // } } catch (Exception e) { paramLogger.logp(Level.WARNING, "ParamicsLog", "ParamicsLog constructor", "Properties file incorrect or missing.", e); JOptionPane.showMessageDialog(null, "ParamicsLog: Properties file invalid.", "Invalid Configuration", JOptionPane.ERROR_MESSAGE); } } /** * Connect to the Coordinator's RMI object. * * @param hostname Host name of the CAD Simulator. * @param portNumber Port number of the CAD Simulator RMI communication. * @throws SimulationException if there is an error creating the RMI * connection. */ private void connect(String hostname, String portNumber) throws SimulationException { String coorIntURL = ""; try { coorIntURL = "rmi://" + hostname + ":" + portNumber + "/coordinator"; theCoorInt = (CoordinatorInterface) Naming.lookup(coorIntURL); } catch (Exception e) { paramLogger.logp(Level.WARNING, "ParamicsLog", "establishRMIConnection", "Unable to establish RMI " + "communication with the CAD Simulator. URL <" + coorIntURL + ">", e); } } /** * Accessor to the entries in the log. No file IO is used. * * @return The entries in the log. */ public String getLog() { return log.toString(); } /** * Writes an entry to the log. The simulator time when the message was sent * is prepended to the entry. Entries are padded by a blank line before and * after them. TODO: Ensure output is written in order of request. * * @param entry */ public void publish(LogRecord rec) { String time = "?"; String formattedEntry; String entry = rec.getMessage(); if (theCoorInt != null) { try { time = formatTime(theCoorInt.getCurrentSimulationTime()); } catch (Exception e) { paramLogger.logp(Level.WARNING, "ParamicsLog", "RMICommunication", "Unable to communicate with RMI object", e); } } formattedEntry = "\n" + "\n" + entry + "\n"; log.append(formattedEntry); rec.setMessage(formattedEntry); super.publish(rec); //ParamicsLogGUI.getInstance().update(this, entry); } /** * Formats the time given in seconds to hh:mm:ss format. * * @param time The time in seconds. */ public String formatTime(long time) { long seconds = time % 60; long minutes = (time - seconds) / 60; long hours = (time - seconds - minutes * 60) / 60; return padr(hours) + ":" + padr(minutes) + ":" + padr(seconds); } private String padr(long n) { if (n < 10) { return "0" + n; } { return "" + n; } } /** * Accessor for static instance of this class. * * @return The instance of this class. */ // public static ParamicsLogFileHandler getInstance() // { // // return instance; // } }