source: tmcsimulator/trunk/src/tmcsim/paramicslog/ParamicsLog.java @ 33

Revision 33, 10.0 KB checked in by bokumura, 10 years ago (diff)

Directory Restructure: All system properties have been deprecated and replaced by the system property: "CONFIG_DIR". If CONFIG_DIR is not specified at run time, it will default to the "config/" directory.

Line 
1package tmcsim.paramicslog;
2
3import java.io.File;
4import java.io.FileInputStream;
5import java.io.FileWriter;
6import java.io.IOException;
7import java.rmi.Naming;
8import java.util.Observable;
9import java.util.Properties;
10import java.util.logging.Level;
11import java.util.logging.Logger;
12
13import javax.swing.JOptionPane;
14
15import org.w3c.dom.Element;
16
17import tmcsim.common.SimulationException;
18import tmcsim.interfaces.CoordinatorInterface;
19import tmcsim.paramicslog.gui.ParamicsLogGUI;
20
21/**
22 * Logs communication from ParamicsCommunicator to ParamicsSimulator.
23 *
24 * The system property "PARAMICS_LOG_CONFIG" should be set to the path
25 * where the properties file for this class is located. <br><br>
26 * The data for the properties file follows. <br>
27 * <code>
28 * -----------------------------------------------------------------<br>
29 * Log File                The file to write the communication to.
30 * CAD Simulator Host      The host that runs the CAD Simulator.
31 * CAD Simulator RMI Port  The port on the host that runs the CAD
32 *                         Simulator where the RMI Coordinator
33 *                         object is registered to.
34 * -----------------------------------------------------------------<br>
35 * Example File: <br>
36 * LogFile=c:\\log.txt
37 * CADSimulatorHost=localhost
38 * CADSimulatorRMIPort=4445
39 * -----------------------------------------------------------------<br>
40 * </code>
41 *
42 * @author Nathaniel Lehrer
43 * @version
44 */
45public class ParamicsLog extends Observable
46{   
47    /**
48     * Enmeration containing property names.
49     * @author Nathaniel Lehrer
50     */
51    private enum PROPERTIES
52    {
53        LOG_FILE      ("LogFile"),
54        CAD_SIM_HOST  ("CADSimulatorHost"),
55        CAD_SIM_PORT  ("CADSimulatorRMIPort");
56       
57        public String name;
58       
59        private PROPERTIES(String n)
60        {
61            name = n;
62        }
63    }
64
65        private static final String CONFIG_FILE_NAME = "paramics_communicator_logging.properties";
66   
67    /** Error logger. */
68    private static Logger paramLogger = Logger.getLogger("tmcsim.paramicslog");
69   
70    /** Static instance. */
71    private static ParamicsLog instance;
72   
73    /** Properties object. */
74    private Properties paramicsLogProp;
75   
76    /** File log entries are written to */
77    private File logFile;
78   
79    /** Stores the log entries. This contains the same information logFile. */
80    private StringBuilder log;
81
82    /** Remote reference to the simulation */
83    private CoordinatorInterface theCoorInt;
84   
85    /** Object for synchronizing IO */
86    Object lock;
87   
88    /**
89     * Creates the singleton instance of this class.
90     */
91    static {
92        try {
93                if(System.getProperty("CONFIG_DIR") == null){
94                System.setProperty("CONFIG_DIR", "config");
95            }
96               
97                instance = new ParamicsLog(System.getProperty("CONFIG_DIR") + System.getProperty("file.separator") + CONFIG_FILE_NAME);
98        } 
99        catch (Exception e) 
100        {
101            instance = new ParamicsLog();
102           
103            paramLogger.logp(Level.WARNING, "ParamicsLog", "static initializer", 
104                    "Error occured initializing application", e);
105
106            JOptionPane.showMessageDialog(null, e.getMessage(), 
107                    "Error - ParamicsLog will not save log to file.", 
108                    JOptionPane.ERROR_MESSAGE); 
109        }
110       
111        instance.addObserver(ParamicsLogGUI.getInstance());
112    }
113   
114    /**
115     * Creates an instance of ParamicsLog that does not write to a file when
116     * writeToLog is called.
117     */
118    private ParamicsLog() {
119       
120        lock = new Object();
121        log = new StringBuilder("");
122    }
123   
124    /**
125     * Creates an instance of ParamicsLog that writes to a file when writeToLog is called.
126     * @param propertiesFile
127     */
128    private ParamicsLog(String propertiesFile) {
129        this();
130       
131        String logFile = null;
132        String CADSIMHost = null;
133        String CADSIMPort = null;
134       
135        try {
136            paramicsLogProp = new Properties();
137            paramicsLogProp.load(new FileInputStream(propertiesFile));
138           
139            if ((logFile = paramicsLogProp.getProperty(PROPERTIES.LOG_FILE.name)) == null)
140            {
141                throw new Exception("Properties file missing log file location.");
142            }
143            else if ((CADSIMHost = paramicsLogProp.getProperty(PROPERTIES.CAD_SIM_HOST.name)) == null)
144            {   
145                throw new Exception("Properties file missing CAD Simulator host.");
146            }
147            else if ((CADSIMPort = paramicsLogProp.getProperty(PROPERTIES.CAD_SIM_PORT.name)) == null)
148            {
149                throw new Exception("Properties file missing CAD Simulator RMI port.");
150            }
151           
152            try
153            {
154                connect(CADSIMHost, CADSIMPort);
155            }
156            catch (Exception e)
157            {
158                JOptionPane.showMessageDialog(null, 
159                        "ParamicsLog: Could not connect to remote Coordinator object.", 
160                        "Network Error", JOptionPane.ERROR_MESSAGE);               
161            }
162           
163            try 
164            {
165                createLogFile(logFile);
166            }
167            catch (Exception e)
168            {
169                JOptionPane.showMessageDialog(null, 
170                        "ParamicsLog: Could not create new log file.", 
171                        "File Error", JOptionPane.ERROR_MESSAGE);
172            }
173           
174        } catch (Exception e) {
175           
176            paramLogger.logp(Level.WARNING, "ParamicsLog", "ParamicsLog constructor", 
177                    "Properties file incorrect or missing.", e);
178           
179            JOptionPane.showMessageDialog(null, 
180                    "ParamicsLog: Properties file invalid.", 
181                    "Invalid Configuration", JOptionPane.ERROR_MESSAGE);
182        }
183    }
184   
185    /**
186     * Creates the log file.
187     * @param filePath The path to the file including the file name.
188     * @throws IOException If the log file could not be created.
189     */
190    private void createLogFile(String filePath) throws IOException
191    {
192        try {
193            logFile = new File(filePath);
194           
195            if (logFile.exists()) {
196                logFile.delete();
197            }
198           
199            logFile.createNewFile();
200           
201        } catch (Exception e) {
202           
203            logFile = null;
204           
205            paramLogger.logp(Level.WARNING, "ParamicsLog", "ParamicsLog constructor", 
206                    "Could not create new log file.", e);
207           
208            throw new IOException("Could not create log file.");
209        }               
210    }
211   
212    /**
213     * Connect to the Coordinator's RMI object.
214     * @param hostname Host name of the CAD Simulator.   
215     * @param portNumber Port number of the CAD Simulator RMI communication.
216     * @throws SimulationException if there is an error creating the RMI connection.
217     */ 
218    private void connect(String hostname, String portNumber) 
219        throws SimulationException {
220       
221        String coorIntURL = "";
222       
223        try { 
224            coorIntURL = "rmi://" + hostname + ":" + portNumber + "/coordinator"; 
225           
226            theCoorInt = (CoordinatorInterface)Naming.lookup(coorIntURL);           
227        }
228        catch (Exception e) 
229        {
230            paramLogger.logp(Level.WARNING, "ParamicsLog", 
231                    "establishRMIConnection", "Unable to establish RMI " +
232                    "communication with the CAD Simulator.  URL <" + coorIntURL + ">", e);
233        }   
234    }
235   
236    /**
237     * Accessor to the entries in the log. No file IO is used.
238     * @return The entries in the log.
239     */
240    public String getLog() {
241       
242        return log.toString();
243    }
244   
245    /**
246     * Writes an entry to the log.
247     * The simulator time when the message was sent is prepended to the entry.
248     * Entries are padded by a blank line before and after them.
249     * TODO: Ensure output is written in order of request.
250     * @param entry
251     */
252    public void writeToLog(String entry) {
253       
254        String time = "?";
255        String formattedEntry;
256       
257        if (theCoorInt != null)
258        {
259            try
260            {
261                time = formatTime(theCoorInt.getCurrentSimulationTime());
262            }
263            catch (Exception e)
264            {
265                paramLogger.logp(Level.WARNING, "ParamicsLog", 
266                        "RMICommunication", "Unable to communicate with RMI object", e);
267            }
268        }
269       
270        formattedEntry = "\n" + "<!-- Time written to file: " + time + " -->\n" + entry + "\n";
271        log.append(formattedEntry);
272       
273        if (logFile != null)
274        {
275            try 
276            {
277                synchronized(lock)
278                {
279                    FileWriter writer = new FileWriter(logFile, true);
280                    writer.append(formattedEntry);
281                    writer.flush();
282                    writer.close();
283                }
284            } 
285            catch (IOException e) 
286            {
287                paramLogger.logp(Level.WARNING, "ParamicsLog", "writeToLog", 
288                        "Could not write to log file.", e);
289            }
290        }
291       
292        setChanged();
293        notifyObservers(entry);
294    }
295   
296    /**
297     * Formats the time given in seconds to hh:mm:ss format.
298     * @param time The time in seconds.
299     */
300    private String formatTime(long time)
301    {
302        long seconds = time % 60;
303        long minutes = (time - seconds) / 60;
304        long hours = (time - seconds - minutes * 60) / 60;
305
306        return padr(hours) + ":" + padr(minutes) + ":" + padr(seconds);
307    }
308   
309    private String padr(long n)
310    {
311        if (n < 10)
312        {
313            return "0" + n;
314        }
315        {
316            return "" + n;
317        }
318    }
319   
320    /**
321     * Accessor for static instance of this class.
322     * @return The instance of this class.
323     */
324    public static ParamicsLog getInstance() {
325       
326        return instance;
327    }
328}
Note: See TracBrowser for help on using the repository browser.