source: tmcsimulator/trunk/src/tmcsim/client/CADlogDisplay.java @ 432

Revision 432, 10.8 KB checked in by jdalbey, 7 years ago (diff)

CADlogDisplay updated. jar target added for CADlogDisplay. "Log Entries" changed to "CAD Log Entries" in Sim Mgr panel.

Line 
1package tmcsim.client;
2
3import java.awt.event.ActionEvent;
4import java.awt.event.ActionListener;
5import java.io.FileInputStream;
6import java.io.FileWriter;
7import java.io.PrintWriter;
8import java.rmi.Naming;
9import java.rmi.RemoteException;
10import java.rmi.server.UnicastRemoteObject;
11import java.util.Properties;
12import java.util.Vector;
13import java.util.concurrent.TimeUnit;
14import java.util.logging.Level;
15import java.util.logging.Logger;
16import javax.swing.JOptionPane;
17import javax.swing.JWindow;
18import javax.swing.Timer;
19import javax.swing.UIManager;
20import javax.swing.table.DefaultTableModel;
21import tmcsim.client.cadclientgui.data.Incident;
22import tmcsim.client.cadclientgui.enums.CADDataEnums.INC_TABLE;
23import tmcsim.common.SimulationException;
24import tmcsim.interfaces.CADClientInterface;
25import tmcsim.interfaces.CoordinatorInterface;
26
27/**
28 * CADlogDisplays shows the current CAD log for all incidents. It operates as a client of the
29 * CAD server, using RMI to poll the server every second for the current
30 * list of incidents and associated comments/notes table.
31 *
32 * @author jdalbey
33 */
34public class CADlogDisplay extends UnicastRemoteObject implements
35        CADClientInterface
36{
37    /**
38     * Error logger.
39     */
40    private static Logger cadClientLogger = Logger.getLogger("tmcsim.client");
41
42    private static final String CONFIG_FILE_NAME = "cad_client_config.properties";
43    private static final String LOG_FILE_NAME = "CADcomments.log";
44    private final static int TEN_SECONDS = 10000;
45
46    /**
47     * Enumeration containing properties name values. See CADClient class
48     * description for more information.
49     *
50     * @author Matthew Cechini
51     * @see CADClient
52     */
53    private static enum PROPERTIES
54    {
55        CAD_SIM_HOST("CADSimulatorHost"), CAD_SIM_PORT("CADSimulatorSocketPort"), CAD_RMI_PORT(
56        "CADRmiPort"), CLIENT_CAD_POS("CADPosition"), CLIENT_USER_ID(
57        "CADUserID"), KEYBOARD_TYPE("KeyboardType"), DISPLAY_TYPE(
58        "DisplayType");
59        public String name;
60
61        private PROPERTIES(String n)
62        {
63            name = n;
64        }
65    }
66    /**
67     * CADClientSocket Object to handle socket communication between the Client
68     * and CAD Simulator.
69     */
70    private CADClientSocket theClientSocket;
71
72    /**
73     * Properties object for the CADClient class.
74     */
75    private Properties cadClientProp;
76    /**
77     * RMI interface for communication with the remote Coordinator.
78     */
79    private static CoordinatorInterface theCoorInt;
80    /**
81     * reference to itself to be used for disconnecting from CADSimulator
82     */
83    private CADClientInterface client = this;
84    /*
85     * PrintWriter handle for sending log to a file
86     */
87    private PrintWriter writer;
88
89    /**
90     * Constructor. Initialize data from parsed properties file. Create a socket
91     * connection to the CADSimulator.
92     *
93     * @param propertiesFile File path (absolute or relative) to the properties
94     * file containing configuration data.
95     */
96    public CADlogDisplay(String propertiesFile) throws SimulationException,
97            RemoteException
98    {
99        if (!verifyProperties(propertiesFile))
100        {
101            System.exit(0);
102        }
103
104        connect(cadClientProp.getProperty(PROPERTIES.CAD_SIM_HOST.name).trim(),
105                cadClientProp.getProperty(PROPERTIES.CAD_RMI_PORT.name).trim());
106
107        // Create a timer that fetches the simulation time every second.
108        Timer timer = new Timer(TEN_SECONDS, new ActionListener()
109        {
110            public void actionPerformed(ActionEvent evt)
111            {
112                try
113                {
114                    Vector<Incident> incList = theCoorInt.getIncidentList(); 
115                    StringBuffer output = new StringBuffer();
116
117                    for (Incident incident: incList)
118                    {
119                    // DefaultTableModel noteTable = (DefaultTableModel) theCoorInt.getCadDataIncidentTable(INC_TABLE.COMMENTS_NOTES, incident.getLogNum());
120                     // Output noteTable
121                        // Retrieve the table of comments/notes the users created
122                        DefaultTableModel notesTable = incident.getCommentsNotesTable();
123                        // Retrieve the notes chronologically (Most recent is in first row)
124                        for (int row=notesTable.getRowCount()-1; row >=0; row--)
125                        {
126                            // Combine the fields into one export entry
127                            //sb.append(notesTable.getValueAt(row,1) + " "); // time
128                            String initials = (String) notesTable.getValueAt(row,2); // user initials
129                            // If there are user intials, include this item.
130                            // Zero length initials mean it's a scripted item, ignore it.
131                            if (initials.length() > 0)
132                            {//CAD Log Entry, Incident #187, Sharon: REQUEST EXTRA ANCHOVIES
133                                output.append("CAD log entry, ");
134                                output.append("Incident #" + incident.logNum + ", ");
135                                output.append(initials + ": ");
136                                output.append(notesTable.getValueAt(row,4) + "\n"); // notes
137                            }
138                        }
139                    }
140                    System.out.print(output);
141                    // Write output to a file
142                    try 
143                    {
144                        writer = new PrintWriter(new FileWriter(LOG_FILE_NAME));
145                        writer.print(output);
146                        writer.close();
147                    } catch (Exception exc) {
148                        exc.printStackTrace();
149                        } 
150       
151                    //long simtime = theCoorInt.getCurrentSimulationTime();
152                    //theView.updateTime("" + formatInterval(simtime));
153                } catch (RemoteException ex)
154                {
155                    Logger.getLogger(CADlogDisplay.class.getName()).log(Level.SEVERE, null, ex);
156                }
157            }
158        });
159        timer.start();
160
161        ensureProperShutdown();
162    }
163
164    /**
165     * Connect to the Coordinator's RMI object, and register this object for
166     * callback with the Coordinator.
167     *
168     * @param hostname Host name of the CAD Simulator.
169     * @param portNumber Port number of the CAD Simulator RMI communication.
170     * @throws SimulationException if there is an error creating the RMI
171     * connection.
172     */
173    protected void connect(String hostname, String portNumber)
174            throws SimulationException
175    {
176
177        String coorIntURL = "";
178
179        try
180        {
181            coorIntURL = "rmi://" + hostname + ":" + portNumber
182                    + "/coordinator";
183            theCoorInt = (CoordinatorInterface) Naming.lookup(coorIntURL);
184            theCoorInt.registerForCallback(this);
185        } catch (Exception e)
186        {
187            throw new SimulationException(SimulationException.CAD_SIM_CONNECT,
188                    e);
189        }
190    }
191
192    /**
193     * This method verifies that the CAD Simulator Host and Port values are not
194     * null. Also, if a CAD Position or User ID do not exist in the properties
195     * file, the user is prompted to enter values. These values are written to
196     * the properties file. If the user cancels the process of entering these
197     * values, the verification fails.
198     *
199     * @param propertiesFile File path (absolute or relative) to the properties
200     * file containing configuration data.
201     * @return True if the properties file is valid, false if not.
202     * @throws SimulationException if there is an exception in verifying the
203     * properties file, or if the user cancels input.
204     */
205    private boolean verifyProperties(String propertiesFile)
206            throws SimulationException
207    {
208
209        // Load the properties file.
210        try
211        {
212            cadClientProp = new Properties();
213            cadClientProp.load(new FileInputStream(propertiesFile));
214        } catch (Exception e)
215        {
216            cadClientLogger.logp(Level.SEVERE, "SimulationManager",
217                    "Constructor", "Exception in reading properties file.", e);
218
219            throw new SimulationException(SimulationException.INITIALIZE_ERROR,
220                    e);
221        }
222
223
224        // Ensure that the properties file does not have null values for the
225        // CAD Simulator's connection information.
226        if (cadClientProp.getProperty(PROPERTIES.CAD_SIM_HOST.name) == null
227                || cadClientProp.getProperty(PROPERTIES.CAD_SIM_PORT.name) == null)
228        {
229            cadClientLogger.logp(Level.SEVERE, "SimulationManager",
230                    "Constructor", "Null value in properties file.");
231            throw new SimulationException(SimulationException.INITIALIZE_ERROR);
232        }
233
234        return true;
235    }
236
237    /**
238     * Format a time in seconds as HH:MM:SS
239     *
240     * @param l
241     * @return
242     */
243    private String formatInterval(final long l)
244    {
245        final long hr = TimeUnit.SECONDS.toHours(l);
246        final long min = TimeUnit.SECONDS.toMinutes(l - TimeUnit.HOURS.toSeconds(hr));
247        final long sec = TimeUnit.SECONDS.toSeconds(l - TimeUnit.HOURS.toSeconds(hr) - TimeUnit.MINUTES.toSeconds(min));
248        return String.format("%02d:%02d:%02d", hr, min, sec);
249    }
250
251    public void ensureProperShutdown()
252    {
253        Runtime.getRuntime().addShutdownHook(new Thread()
254        {
255            public void run()
256            {
257                try
258                {
259                    theCoorInt.unregisterForCallback(client);
260                } catch (RemoteException e)
261                {
262                    e.printStackTrace();
263                }
264            }
265        });
266    }
267
268    @Override
269    public void refresh() throws RemoteException
270    {
271        throw new UnsupportedOperationException("Not supported yet.");
272    }
273
274    /**
275     * Construct the CADClient with the properties file path, either from the
276     * command line arguments or default.
277     *
278     * @param args Command line arguments.
279     */
280    public static void main(String[] args)
281    {
282        if (System.getProperty("CONFIG_DIR") == null)
283        {
284            System.setProperty("CONFIG_DIR", "config");
285        }
286
287        try
288        {
289            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
290            new CADlogDisplay(System.getProperty("CONFIG_DIR") + System.getProperty("file.separator") + CONFIG_FILE_NAME);
291
292        } catch (Exception e)
293        {
294            cadClientLogger.logp(Level.SEVERE, "SimulationManager", "Main",
295                    "Error initializing application.");
296
297            JOptionPane.showMessageDialog(new JWindow(), e.getMessage(),
298                    "Error - Program Exiting", JOptionPane.ERROR_MESSAGE);
299
300            System.exit(-1);
301        }
302
303    }
304}
Note: See TracBrowser for help on using the repository browser.