Warning: Can't use blame annotator:
svn blame failed on trunk/src/tmcsim/client/CADClient.java: ("Can't find a temporary directory: Internal error", 20014)

source: tmcsimulator/trunk/src/tmcsim/client/CADClient.java @ 2

Revision 2, 19.4 KB checked in by jdalbey, 10 years ago (diff)

Initial Import of project files

RevLine 
1package tmcsim.client;
2
3import java.awt.event.WindowEvent;
4import java.awt.event.WindowListener;
5import java.io.FileInputStream;
6import java.io.FileOutputStream;
7import java.io.IOException;
8import java.rmi.Naming;
9import java.rmi.RemoteException;
10import java.rmi.server.UnicastRemoteObject;
11import java.util.Properties;
12import java.util.Vector;
13import java.util.logging.Level;
14import java.util.logging.Logger;
15
16import javax.swing.JFrame;
17import javax.swing.JOptionPane;
18import javax.swing.JWindow;
19import javax.swing.UIManager;
20
21import tmcsim.client.cadclientgui.CADClientGUI;
22import tmcsim.client.cadclientgui.CardfileReader;
23import tmcsim.client.cadclientgui.GUIScriptReader;
24import tmcsim.client.cadclientgui.data.CADData;
25import tmcsim.client.cadclientgui.screens.Login;
26import tmcsim.client.cadclientgui.screens.ScreenManager;
27import tmcsim.common.CADEnums;
28import tmcsim.common.SimulationException;
29import tmcsim.interfaces.CADClientInterface;
30import tmcsim.interfaces.CoordinatorInterface;
31
32/**
33 * CADClient is the main class for the CAD Client application. The main method
34 * instantiates an instance of the CADClient object with the default properties
35 * file "..\config\CADClient.properties" or the first argument fom the command
36 * line invocation. Properties data values are used to bind socket communication
37 * between the CAD Client and the CAD Simulator. The CADClientModel object is
38 * instantiated and the CAD Client registers itself with the CAD Simulator.
39 * Finally, the CADClientView is initialized, the model-view and observer
40 * relationships are established, and the view is shown.<br>
41 * <br>
42 * The properties file contains the following data: <br>
43 * <code>
44 * -----------------------------------------------------------------------------<br>
45 * Host Name     The host name where the CAD Simulator is located.<br>
46 * Port Number   The port number that the CAD Simulator is bound on.<br>
47 * CAD Position  The integer (>= 0) position for this CAD Client.<br>
48 * CAD User ID   The unique user id for this CAD Client.<br>
49 * Error File    Filename of error logging file.<br>
50 * -----------------------------------------------------------------------------<br>
51 * Example File: <br>
52 * CADSimulatorHost       = localhost<br>
53 * CADSimulatorSocketPort = 4444<br>
54 * CADPosition = 1 <br>
55 * CADUserID   = A12345<br>
56 * ErrorFile   = cad_client_err.txt<br>
57 * </code>
58 *
59 * @author Matthew Cechini (mcechini@calpoly.edu)
60 * @version $Date: 2009/04/17 16:27:47 $ $Revision: 1.8 $
61 */
62/*Hai :3  yeeeee*/
63public class CADClient extends UnicastRemoteObject implements
64        CADClientInterface {
65
66    /** Error logger. */
67    private static Logger cadClientLogger = Logger.getLogger("tmcsim.client");
68
69    /**
70     * Enumeration containing properties name values. See CADClient class
71     * description for more information.
72     *
73     * @author Matthew Cechini
74     * @see CADClient
75     */
76    private static enum PROPERTIES {
77        CAD_SIM_HOST("CADSimulatorHost"), CAD_SIM_PORT("CADSimulatorSocketPort"), CAD_RMI_PORT(
78                "CADRmiPort"), CLIENT_CAD_POS("CADPosition"), CLIENT_USER_ID(
79                "CADUserID"), KEYBOARD_TYPE("KeyboardType"), DISPLAY_TYPE(
80                "DisplayType");
81
82        public String name;
83
84        private PROPERTIES(String n) {
85            name = n;
86        }
87    }
88
89    /**
90     * CADClientSocket Object to handle socket communication between the Client
91     * and CAD Simulator.
92     */
93    private CADClientSocket theClientSocket;
94
95    /** Instance of the CADClientModel. */
96    private CADClientModel theClientScreenModel;
97
98    /** Instance of the CADClientView. */
99    private CADClientView theClientScreenView;
100
101    /**
102     * Instance of the CADCLientGUI Replaces CADClientView
103     */
104    private CADClientGUI theClientGUI;
105
106    /** Properties object for the CADClient class. */
107    private Properties cadClientProp;
108
109    /** RMI interface for communication with the remote Coordinator. */
110    private static CoordinatorInterface theCoorInt;
111
112    /** reference to itself to be used for disconnecting from CADSimulator */
113    private CADClientInterface client = this;
114
115    /**
116     * Constructor. Initialize data from parsed properties file. Create a socket
117     * connection to the CADSimulator. The ClientScreenModel is initialized with
118     * the input and output I/O streams for socket communication. The
119     * ClientScreenModel registers with the CAD Simulator, using CAD position
120     * and userID read in from the properties file. The ClientScreenView is then
121     * created and initialized and set as an observer of the model.
122     *
123     * A thread is created with the runnable ClientScreenModel and is started.
124     * When this thread is no longer alive, or the ClientScrenView and
125     * CADClientSocket are closed. The program then exits.
126     *
127     * @param propertiesFile
128     *            File path (absolute or relative) to the properties file
129     *            containing configuration data.
130     */
131    public CADClient(String propertiesFile) throws SimulationException,
132            RemoteException {
133        if (!verifyProperties(propertiesFile))
134            System.exit(0);
135
136        connect(cadClientProp.getProperty(PROPERTIES.CAD_SIM_HOST.name).trim(),
137                cadClientProp.getProperty(PROPERTIES.CAD_RMI_PORT.name).trim());
138
139        // Instantiate the Socket and Model Objects.
140        theClientSocket = new CADClientSocket(cadClientProp.getProperty(
141                PROPERTIES.CAD_SIM_HOST.name).trim(),
142                Integer.parseInt(cadClientProp.getProperty(
143                        PROPERTIES.CAD_SIM_PORT.name).trim()));
144        theClientScreenModel = new CADClientModel();
145        theClientScreenModel.initializeScreen(theClientSocket.getInputStream(),
146                theClientSocket.getOutputStream());
147
148        // Register this CAD Client with the Simulation Manager
149        theClientScreenModel.register(Integer.parseInt(cadClientProp
150                .getProperty(PROPERTIES.CLIENT_CAD_POS.name)), cadClientProp
151                .getProperty(PROPERTIES.CLIENT_USER_ID.name));
152
153        // Instantiate the CADScreenView and set up the model-view observer
154        // relationship.
155        theClientScreenView = new CADClientView(theClientScreenModel);
156        theClientScreenView.setVisible(false);
157
158        // TODO: set up model-view relationship similar to ClientView and
159        // ScreenView
160        // Can repurpose the old model, but may be better to copy over and
161        // modify in parallel
162        // This is required to perform powerline commands on the data
163        theClientGUI = new CADClientGUI();
164
165        // Each screen of the UI should have a reference to either it's parent
166        // object or the main client
167        // This ensures they all have access to each other and the data model
168        theClientGUI.screen = new ScreenManager(theCoorInt);
169        theClientGUI.login = new Login();
170        theClientGUI.client = this;
171
172        // setup keyboard settings for CAD Client
173        if (cadClientProp.getProperty(PROPERTIES.KEYBOARD_TYPE.name).trim()
174                .equals("CAD")) {
175            CADEnums.CAD_KEYS.setupCADKeyboard();
176        }
177        // STD
178        else {
179            CADEnums.CAD_KEYS.setupStandardKeyboard();
180        }
181
182        theClientScreenModel.addObserver(theClientScreenView);
183
184        // Initialize the display
185        if (cadClientProp.getProperty(PROPERTIES.DISPLAY_TYPE.name).equals(
186                "FULL_SCREEN")) {
187
188            theClientScreenView.addWindowListener(new WindowListener() {
189                public void windowClosed(WindowEvent e) {
190                }
191
192                public void windowOpened(WindowEvent e) {
193                }
194
195                public void windowIconified(WindowEvent e) {
196                }
197
198                public void windowDeiconified(WindowEvent e) {
199                }
200
201                public void windowActivated(WindowEvent e) {
202                }
203
204                public void windowDeactivated(WindowEvent e) {
205                }
206
207                public void windowClosing(WindowEvent e) {
208
209                    try {
210                        theClientSocket.closeSocket();
211                    } catch (SimulationException se) {
212                    }
213
214                    System.exit(0);
215                }
216            });
217
218            theClientScreenView.initWindow();
219            theClientScreenView.setVisible(false);
220        } else {
221            JFrame cadFrame = new JFrame("CAD Client");
222            cadFrame.add(theClientScreenView.initBox());
223            cadFrame.setSize(800, 600);
224
225            cadFrame.addWindowListener(new WindowListener() {
226                public void windowClosed(WindowEvent e) {
227                }
228
229                public void windowOpened(WindowEvent e) {
230                }
231
232                public void windowIconified(WindowEvent e) {
233                }
234
235                public void windowDeiconified(WindowEvent e) {
236                }
237
238                public void windowActivated(WindowEvent e) {
239                }
240
241                public void windowDeactivated(WindowEvent e) {
242                }
243
244                public void windowClosing(WindowEvent e) {
245
246                    try {
247                        theClientSocket.closeSocket();
248                    } catch (SimulationException se) {
249                    }
250
251                    System.exit(0);
252                }
253            });
254
255            cadFrame.setVisible(true);
256        }
257
258        // Create the CAD Client thread to run the CADClientModel Object.
259        Thread clientThread = new Thread(theClientScreenModel);
260        clientThread.start();
261
262        ensureProperShutdown();
263    }
264
265    /**
266     * Connect to the Coordinator's RMI object, and register this object for
267     * callback with the Coordinator.
268     *
269     * @param hostname
270     *            Host name of the CAD Simulator.
271     * @param portNumber
272     *            Port number of the CAD Simulator RMI communication.
273     * @throws SimulationException
274     *             if there is an error creating the RMI connection.
275     */
276    protected void connect(String hostname, String portNumber)
277            throws SimulationException {
278
279        String coorIntURL = "";
280
281        try {
282            coorIntURL = "rmi://" + hostname + ":" + portNumber
283                    + "/coordinator";
284            theCoorInt = (CoordinatorInterface) Naming.lookup(coorIntURL);
285            theCoorInt.registerForCallback(this);
286        } catch (Exception e) {
287            throw new SimulationException(SimulationException.CAD_SIM_CONNECT,
288                    e);
289        }
290    }
291
292    /**
293     * This method verifies that the CAD Simulator Host and Port values are not
294     * null. Also, if a CAD Position or User ID do not exist in the properties
295     * file, the user is prompted to enter values. These values are written to
296     * the properties file. If the user cancels the process of entering these
297     * values, the verification fails.
298     *
299     * @param propertiesFile
300     *            File path (absolute or relative) to the properties file
301     *            containing configuration data.
302     * @return True if the properties file is valid, false if not.
303     * @throws SimulationException
304     *             if there is an exception in verifying the properties file, or
305     *             if the user cancels input.
306     */
307    private boolean verifyProperties(String propertiesFile)
308            throws SimulationException {
309
310        // Load the properties file.
311        try {
312            cadClientProp = new Properties();
313            cadClientProp.load(new FileInputStream(propertiesFile));
314        } catch (Exception e) {
315            cadClientLogger.logp(Level.SEVERE, "SimulationManager",
316                    "Constructor", "Exception in reading properties file.", e);
317
318            throw new SimulationException(SimulationException.INITIALIZE_ERROR,
319                    e);
320        }
321
322        // Ensure that the properties file does not have null values for the
323        // CAD Simulator's connection information.
324        if (cadClientProp.getProperty(PROPERTIES.CAD_SIM_HOST.name) == null
325                || cadClientProp.getProperty(PROPERTIES.CAD_SIM_PORT.name) == null) {
326            cadClientLogger.logp(Level.SEVERE, "SimulationManager",
327                    "Constructor", "Null value in properties file.");
328            throw new SimulationException(SimulationException.INITIALIZE_ERROR);
329        }
330
331        try {
332            // If the properties file does not specify a CAD position, prompt
333            // the
334            // user to select one. If the user selects a position, write the
335            // new properties values to the file. If the user cancels, else
336            // throw an exception.
337            if (cadClientProp.getProperty(PROPERTIES.CLIENT_CAD_POS.name) == null) {
338                if (getCADPosition())
339                    cadClientProp.store(new FileOutputStream(propertiesFile),
340                            "");
341                else
342                    throw new SimulationException(
343                            SimulationException.INITIALIZE_ERROR);
344            }
345
346            // If the properties file does not specifiy a CAD User ID, prompt
347            // the
348            // user to enter a value. If the user enters a valid ID, write the
349            // new properties values to the file. If the user cancels, else
350            // throw an exception.
351            if (cadClientProp.getProperty(PROPERTIES.CLIENT_USER_ID.name) == null) {
352                if (getUserID())
353                    cadClientProp.store(new FileOutputStream(propertiesFile),
354                            "");
355                else
356                    throw new SimulationException(
357                            SimulationException.INITIALIZE_ERROR);
358            }
359        } catch (IOException ioe) {
360            cadClientLogger.logp(Level.SEVERE, "SimulationManager",
361                    "Constructor",
362                    "Exception in writing to the properties file.");
363            throw new SimulationException(SimulationException.INITIALIZE_ERROR);
364        }
365
366        // Ensure that the properties file has a valid display type
367        if (cadClientProp.getProperty(PROPERTIES.DISPLAY_TYPE.name) == null
368                || (!cadClientProp.getProperty(PROPERTIES.DISPLAY_TYPE.name)
369                        .equals("FULL_SCREEN") && !cadClientProp.getProperty(
370                        PROPERTIES.DISPLAY_TYPE.name).equals("FRAME"))) {
371            cadClientLogger.logp(Level.SEVERE, "SimulationManager",
372                    "Constructor", "Invalid display type.");
373            throw new SimulationException(SimulationException.INITIALIZE_ERROR);
374        }
375
376        return true;
377    }
378
379    /**
380     * This method prompts the user to select a value for the CAD position. If
381     * the user cancels the method returns false, else the Properties object is
382     * updated and true is returned.
383     *
384     * @return True if the user successfully selected a CAD position, false if
385     *         not.
386     */
387    private boolean getCADPosition() {
388
389        Vector<Integer> positions = new Vector<Integer>();
390        for (int i = 0; i < 10; i++)
391            positions.add(i);
392
393        Object cadPos = null;
394
395        while (true) {
396            cadPos = JOptionPane.showInputDialog(null,
397                    "Please assign this workstation a CAD position number.",
398                    "CAD Position Asignment", JOptionPane.QUESTION_MESSAGE,
399                    null, positions.toArray(), positions.get(0));
400
401            // If the user pressed cancel, confirm the exit and return false.
402            if (cadPos == null) {
403                if (JOptionPane
404                        .showConfirmDialog(
405                                null,
406                                "CAD Client cannot load until a valid CAD "
407                                        + "position has been selected.  Do you wish to "
408                                        + "cancel loading the CAD Client?",
409                                "Confirm Exit", JOptionPane.YES_NO_OPTION,
410                                JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION)
411                    return false;
412            }
413            // Else the user selected a CAD position, exit the loop.
414            else {
415                break;
416            }
417        }
418
419        cadClientProp.setProperty(PROPERTIES.CLIENT_CAD_POS.name,
420                cadPos.toString());
421        return true;
422    }
423
424    /**
425     * This method prompts the user to enter a 5-character User ID. If the user
426     * cancels the method returns false, else the Properties object is updated
427     * and true is returned.
428     *
429     * @return True if the user successfully selected a CAD position, false if
430     *         not.
431     */
432    private boolean getUserID() {
433        String cadUID = null;
434
435        while (true) {
436            cadUID = JOptionPane.showInputDialog(null,
437                    "Please assign this workstation a 6-character CAD "
438                            + "User ID.", "CAD User ID Asignment",
439                    JOptionPane.QUESTION_MESSAGE);
440
441            // /If the user pressed cancel, confirm the exit and return false.
442            if (cadUID == null) {
443                if (JOptionPane.showConfirmDialog(null,
444                        "CAD Client cannot load until a valid User ID "
445                                + "has been entered.  Do you wish to "
446                                + "cancel loading the CAD Client?",
447                        "Confirm Exit", JOptionPane.YES_NO_OPTION,
448                        JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION)
449                    return false;
450            }
451            // If the user does not enter a valid User ID, notify and reprompt.
452            else if (cadUID.length() != 6) {
453                JOptionPane.showMessageDialog(null,
454                        "The User ID must be 6 characters.", "Invalid User ID",
455                        JOptionPane.WARNING_MESSAGE);
456            }
457            // Else the user entered a valid value, exit the loop.
458            else {
459                break;
460            }
461        }
462
463        cadClientProp.setProperty(PROPERTIES.CLIENT_USER_ID.name, cadUID);
464        return true;
465    }
466
467    /**
468     * Construct the CADClient with the properties file path, either from the
469     * command line arguments or default.
470     *
471     * @param args
472     *            Command line arguments.
473     */
474    public static void main(String[] args) {
475        System.setProperty("CAD_CLIENT_PROPERTIES",
476                "config/cad_client_config.properties");
477
478        try {
479            if (System.getProperty("CAD_CLIENT_PROPERTIES") != null) {
480                UIManager.setLookAndFeel(UIManager
481                        .getSystemLookAndFeelClassName());
482
483                new CADClient(System.getProperty("CAD_CLIENT_PROPERTIES"));
484            } else {
485                throw new Exception(
486                        "CAD_CLIENT_PROPERTIES system property not defined.");
487            }
488        } catch (Exception e) {
489            cadClientLogger.logp(Level.SEVERE, "SimulationManager", "Main",
490                    "Error initializing application.");
491
492            JOptionPane.showMessageDialog(new JWindow(), e.getMessage(),
493                    "Error - Program Exiting", JOptionPane.ERROR_MESSAGE);
494
495            System.exit(-1);
496        }
497
498    }
499
500    public void refresh() {
501        theClientGUI.screen.refreshScreens();
502    }
503
504    public void ensureProperShutdown() {
505        Runtime.getRuntime().addShutdownHook(new Thread() {
506            public void run() {
507                try {
508                    theCoorInt.unregisterForCallback(client);
509                } catch (RemoteException e) {
510                    e.printStackTrace();
511                }
512            }
513        });
514    }
515
516}
Note: See TracBrowser for help on using the repository browser.