source: tmcsimulator/trunk/src/tmcsim/simulationmanager/SimulationManagerModel.java @ 445

Revision 445, 24.5 KB checked in by jdalbey, 7 years ago (diff)

Changed restart dialog in CADClientView to a non-modal one to fix #159. Shortened exception log messages in other client modules.

Line 
1package tmcsim.simulationmanager;
2
3import java.io.File;
4import java.rmi.Naming;
5import java.rmi.RemoteException;
6import java.rmi.server.UnicastRemoteObject;
7import java.util.TreeMap;
8import java.util.TreeSet;
9import java.util.Vector;
10import java.util.logging.Level;
11import java.util.logging.Logger;
12import tmcsim.cadmodels.CMSDiversion;
13import tmcsim.cadmodels.CMSInfo;
14import tmcsim.client.cadclientgui.data.Incident;
15import tmcsim.client.cadclientgui.data.IncidentEvent;
16import tmcsim.common.CADEnums.PARAMICS_STATUS;
17import tmcsim.common.CADEnums.SCRIPT_STATUS;
18import tmcsim.common.ScriptException;
19import tmcsim.common.SimulationException;
20import tmcsim.interfaces.CoordinatorInterface;
21import tmcsim.interfaces.SimulationManagerInterface;
22
23/**
24 * SimulationManagerModel is the model class for the Simulation Manager. All
25 * communication between the Coordinator and the Simulation Manager passes
26 * through this object. The view passes requests through local methods, and the
27 * Coordinator calls remote functions in this object to update the viewed
28 * simulation data.
29 * <br/>
30 * At construction, the SimulationManagerModel registers itself with the
31 * coordinator. Administrative commands for the simulation are received from the
32 * SimlationManagerView class, and then the appropriate Coordinator remote
33 * method is executed. During a simulation, the Coordinator calls remote methods
34 * contained in the SimulationManagerInterface. For a description of those
35 * methods, see the interface's documentation. After construction, this model
36 * class must have its setView() method called to set the reference to its view
37 * class.
38 *
39 * @see SimulationManagerView
40 * @see SimulationManagerInterface
41 * @author Matthew Cechini
42 * @version $Revision: 1.3 $ $Date: 2006/06/06 20:46:41 $
43 */
44@SuppressWarnings("serial")
45public class SimulationManagerModel extends UnicastRemoteObject
46        implements SimulationManagerInterface
47{
48
49    /**
50     * Error Logger.
51     */
52    private Logger simManagerLogger = Logger.getLogger("tmcsim.simulationmanager");
53    /**
54     * RMI interface for communication with the remote Coordinator.
55     */
56    private static CoordinatorInterface theCoorInt;
57    /**
58     * The SimulationManagerView object.
59     */
60    private SimulationManagerView theSimManagerView;
61
62    /**
63     * Constructor. Establishes the RMI communication with the Coordinator.
64     *
65     * @param hostname Host name of the CAD Simulator.
66     * @param portNumber Port number of the CAD Simulator RMI communication.
67     * @throws RemoteException if error in RMI communication
68     * @throws SimulationException if there is an error in registering RMI
69     * methods.
70     */
71    public SimulationManagerModel(String hostname, String portNumber)
72            throws RemoteException, SimulationException
73    {
74        super();
75
76        connect(hostname, portNumber);
77    }
78
79    /**
80     * Connect to the Coordinator's RMI object, and register this object for
81     * callback with the Coordinator.
82     *
83     * @param hostname Host name of the CAD Simulator.
84     * @param portNumber Port number of the CAD Simulator RMI communication.
85     * @throws SimulationException if there is an error creating the RMI
86     * connection.
87     */
88    protected void connect(String hostname, String portNumber)
89            throws SimulationException
90    {
91
92        String coorIntURL = "";
93
94        try
95        {
96            coorIntURL = "rmi://" + hostname + ":" + portNumber + "/coordinator";
97
98            theCoorInt = (CoordinatorInterface) Naming.lookup(coorIntURL);
99            theCoorInt.registerForCallback(this);
100
101        } catch (Exception e)
102        {
103            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
104                    "establishRMIConnection", "Unable to establish RMI "
105                    + "communication with the CAD Simulator.  URL <" + coorIntURL + ">", e);
106
107            throw new SimulationException(SimulationException.CAD_SIM_CONNECT, e);
108        }
109    }
110
111    /**
112     * This method unregisters this SimulationManager from the Coordinator and
113     * closes the RMI communication.
114     */
115    public void disconnect()
116    {
117        try
118        {
119            theCoorInt.unregisterForCallback(this);
120            theCoorInt = null;
121        } catch (Exception ex)
122        {
123            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
124                    "closeSimManager", "Exception in unregistering Simulation"
125                    + "Manager from the CAD Simulator.", ex.getMessage());
126        }
127    }
128
129    /**
130     * Set the local reference to the SimulationManagerView object. The view is
131     * updated with the current simulation time, script status, and Paramics
132     * connection status.
133     *
134     * @param newView The instance of the SimulationManagerView class.
135     * @throws SimulationException if there is an error in RMI communication to
136     * the CAD Simulator.
137     */
138    public void setView(SimulationManagerView newView) throws SimulationException
139    {
140        try
141        {
142            theSimManagerView = newView;
143
144            theSimManagerView.tick(theCoorInt.getCurrentSimulationTime());
145            theSimManagerView.setScriptStatus(theCoorInt.getScriptStatus());
146            theSimManagerView.setParamicsStatus(theCoorInt.getParamicsStatus());
147
148            initialize();
149        } catch (RemoteException re)
150        {
151            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
152                    "startSimulation", "Unable to communicate with the "
153                    + "CAD Simulator.", re);
154
155            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
156        }
157
158    }
159
160    /**
161     * This method initializes the SimulationManager with all current simulation
162     * data from the Coordinator. If the simulation is running when the
163     * Simulation Manager is initialized, all previously occured incidents,
164     * events, and current diversion must be displayed. This method first loads
165     * the list of current incidents from the coordinator, then the triggered
166     * events, followed by all CMSInfo objects. The SimulationManagerView is
167     * notified of any current diversions within the CMSInfo objects.
168     *
169     * @throws SimulationException if there is an error in RMI communication or
170     * if the SimulationManagerView reference has not been set.
171     */
172    protected void initialize() throws SimulationException
173    {
174
175        try
176        {
177
178            //Load all incidents from Coordinator
179            loadIncidents();
180
181            //Load all triggered incidents from Coordinator
182            TreeMap<Integer, Vector<IncidentEvent>> tempEvents = theCoorInt.getTriggeredEvents();
183            for (Integer key : tempEvents.keySet())
184            {
185                for (IncidentEvent ie : tempEvents.get(key))
186                {
187                    eventOccured(key, ie);
188                }
189            }
190
191            //Load all current diversions from the Coordinator
192            TreeSet<String> cmsIDs = theCoorInt.getCMSIDs();
193            CMSInfo cmsinfo = null;
194            for (String cms_id : cmsIDs)
195            {
196                cmsinfo = theCoorInt.getCMSDiversionInfo(cms_id);
197
198                for (CMSDiversion div : cmsinfo.possibleDiversions)
199                {
200                    if (div.getCurrDiv() != 0)
201                    {
202                        theSimManagerView.addDiversion(cmsinfo, div);
203                    }
204                }
205            }
206
207            //Send the list of CMS IDs to the View.
208            theSimManagerView.setCMS_IDList(cmsIDs.toArray());
209
210        } catch (Exception e)
211        {
212            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
213                    "initialize", "Unable to initialize the SimulationManager.", e);
214
215            throw new SimulationException(SimulationException.CAD_SIM_COMM, e);
216        }
217    }
218
219    public void tick(long theTime) throws RemoteException
220    {
221        if (theSimManagerView != null)
222        {
223            theSimManagerView.tick(theTime);
224        }
225    }
226
227    public void incidentAdded(Incident newIncident) throws RemoteException
228    {
229        if (theSimManagerView != null)
230        {
231            Integer logNum = new Integer(newIncident.getLogNumber());
232
233            theSimManagerView.addIncident(newIncident);
234            theSimManagerView.addIncidentTab(logNum);
235        }
236    }
237
238    public void incidentStarted(Integer logNumber) throws RemoteException
239    {
240        if (theSimManagerView != null)
241        {
242            theSimManagerView.startIncident(logNumber);
243        }
244    }
245
246    public void incidentRemoved(Integer logNumber) throws RemoteException
247    {
248        if (theSimManagerView != null)
249        {
250            theSimManagerView.removeIncident(logNumber);
251            theSimManagerView.removeIncidentTab(logNumber);
252        }
253    }
254
255    public void eventOccured(Integer logNumber, IncidentEvent theEvent) throws RemoteException
256    {
257        if (theSimManagerView != null)
258        {
259            theSimManagerView.addIncidentEvent(logNumber, theEvent);
260        }
261    }
262
263    public void setScriptStatus(SCRIPT_STATUS newStatus) throws RemoteException
264    {
265        if (theSimManagerView != null)
266        {
267            theSimManagerView.setScriptStatus(newStatus);
268        }
269    }
270
271    public void setParamicsStatus(PARAMICS_STATUS newStatus) throws RemoteException
272    {
273        if (theSimManagerView != null)
274        {
275            theSimManagerView.setParamicsStatus(newStatus);
276        }
277
278    }
279
280    /**
281     * This method passes the view's request to start the simulation on to the
282     * remote coordinator.
283     *
284     * @throws ScriptException if an error occurs in started the simulation.
285     * @throws SimulationException if there is an error in RMI communication to
286     * the CAD Simulator.
287     */
288    public void startSimulation() throws ScriptException, SimulationException
289    {
290
291        try
292        {
293            theCoorInt.startSimulation();
294        } catch (RemoteException re)
295        {
296            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
297                    "startSimulation", "Unable to communicate with the "
298                    + "CAD Simulator.", re);
299
300            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
301        }
302
303    }
304
305    /**
306     * This method passes the view's request to reset the simulation on to the
307     * remote coordinator. The View's simulation time is reset to 0. The view's
308     * incident tabs are cleared and incident list reset and initialized with
309     * the current list of incidents. The list of diversions is also reset.
310     *
311     * @throws SimulationException if there is an error in RMI communication to
312     * the CAD Simulator.
313     */
314    public void resetSimulation() throws SimulationException
315    {
316
317        try
318        {
319            theCoorInt.resetSimulation();
320
321            tick(0);
322            theSimManagerView.resetIncidentTabs();
323            theSimManagerView.resetIncidents();
324            theSimManagerView.resetDiversions();
325
326            loadIncidents();
327        } catch (RemoteException re)
328        {
329            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
330                    "resetSimulation", "Unable to communicate with the "
331                    + "CAD Simulator.", re);
332
333            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
334        }
335
336    }
337
338    /**
339     * This method passes the view's request to pause the simulation on to the
340     * remote coordinator.
341     *
342     * @throws SimulationException if there is an error in RMI communication to
343     * the CAD Simulator.
344     */
345    public void pauseSimulation() throws SimulationException
346    {
347
348        try
349        {
350            theCoorInt.pauseSimulation();
351        } catch (RemoteException re)
352        {
353            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
354                    "pauseSimulation", "Unable to communicate with the "
355                    + "CAD Simulator.", re);
356
357            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
358        }
359
360    }
361
362    /**
363     * This method passes the view's request to goto a new simulation time on to
364     * the remote coordinator.
365     *
366     * @param time Simulation time
367     * @throws SimulationException if there is an error in RMI communication to
368     * the CAD Simulator.
369     */
370    public void gotoSimulationTime(long time) throws SimulationException
371    {
372
373        try
374        {
375            theCoorInt.gotoSimulationTime(time);
376        } catch (RemoteException re)
377        {
378            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
379                    "gotoSimulationTime", "Unable to communicate with the "
380                    + "CAD Simulator.", re);
381
382            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
383        }
384    }
385
386    /**
387     * This method passes the view's request to load a script file on to the
388     * remote Coordinator. If this is successful, the View's incident tabs are
389     * cleared and incident list reset and initialized with the current list of
390     * incidents. If the load is not successful, the View's incident tabs and
391     * incident list are cleared. The list of diversions is also reset.
392     *
393     * @param scriptFile the File chosen by the user in the open file dialog.
394     * @throws ScriptException if an error occurs in reading the script file.
395     * @throws SimulationException if there is an error in RMI communication to
396     * the CAD Simulator.
397     */
398    public void loadScript(File scriptFile) throws ScriptException, SimulationException
399    {
400
401        try
402        {
403            theCoorInt.loadScriptFile(scriptFile);
404
405            tick(0);
406            theSimManagerView.resetIncidentTabs();
407            theSimManagerView.resetIncidents();
408            theSimManagerView.resetDiversions();
409
410            loadIncidents();
411        } catch (ScriptException se)
412        {
413            theSimManagerView.resetIncidentTabs();
414            theSimManagerView.resetIncidents();
415            theSimManagerView.resetDiversions();
416            throw se;
417        } catch (RemoteException re)
418        {
419            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
420                    "loadScript", "Unable to communicate with the "
421                    + "CAD Simulator.", re);
422
423            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
424        }
425    }
426
427    /**
428     * This method passes the view's request to create a connection between the
429     * CADSimulator and the Paramics Communicator on to the remote Coordinator.
430     *
431     * @throws SimulationException if there is an error in RMI communication to
432     * the CAD Simulator.
433     */
434    public void connectToParamics() throws SimulationException
435    {
436
437        try
438        {
439            theCoorInt.connectToParamics();
440        } catch (RemoteException re)
441        {
442            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
443                    "connectToParamics", "Unable to communicate with the "
444                    + "CAD Simulator.", re);
445
446            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
447        }
448    }
449
450    /**
451     * This method passes the view's request to drop the connection between the
452     * CADSimulator and the Paramics Communicator on to the remote Coordinator.
453     *
454     * @throws SimulationException if there is an error in RMI communication to
455     * the CAD Simulator.
456     */
457    public void disconnectFromParamics() throws SimulationException
458    {
459
460        try
461        {
462            theCoorInt.disconnectFromParamics();
463        } catch (RemoteException re)
464        {
465            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
466                    "disconnectFromParamics", "Unable to communicate with the "
467                    + "CAD Simulator.", re);
468
469            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
470        }
471    }
472
473    /**
474     * This method passes the view's request to load a paramics network on to
475     * the remote Coordinator.
476     *
477     * @param networkID The unique network ID that is being loaded
478     *
479     * @throws ScriptException if there is an error in loading the network
480     * @throws SimulationException if there is an error in RMI communication to
481     * the CAD Simulator.
482     */
483    public void loadParamicsNetwork(int networkID) throws ScriptException, SimulationException
484    {
485        try
486        {
487            theCoorInt.loadParamicsNetwork(networkID);
488        } catch (RemoteException re)
489        {
490            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
491                    "loadParamicsNetwork", "Unable to communicate with the "
492                    + "CAD Simulator.", re);
493
494            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
495        }
496    }
497
498    /**
499     * This method passes the view's request to get the value of the currently
500     * loaded paramics network on to the remote Coordinator.
501     *
502     * @return Value of the loaded paramics network.
503     * @throws SimulationException if there is an error in RMI communication to
504     * the CAD Simulator.
505     */
506    public int getParamicsNetworkLoaded() throws SimulationException
507    {
508        try
509        {
510            return theCoorInt.getParamicsNetworkLoaded();
511        } catch (RemoteException re)
512        {
513            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
514                    "getParamicsNetworkLoaded", "Unable to communicate with the "
515                    + "CAD Simulator.", re);
516
517            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
518        }
519    }
520
521    /**
522     * This method passes the view's request to trigger an incident on to the
523     * remote Coordinator.
524     *
525     * @throws ScriptException if an error occurs in triggering an event.
526     * @throws SimulationException if there is an error in RMI communication to
527     * the CAD Simulator.
528     */
529    public void triggerIncident(int logNumber) throws ScriptException, SimulationException
530    {
531        try
532        {
533            theCoorInt.triggerIncident(logNumber);
534
535        } catch (RemoteException re)
536        {
537            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
538                    "startIncident", "Unable to communicate with the "
539                    + "CAD Simulator.", re);
540
541            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
542        }
543    }
544
545    /**
546     * This method passes the view's request to add an incident into the
547     * simulation on to the remote Coordinator.
548     *
549     * @param newIncident Incident to add to the simulation
550     * @throws SimulationException if there is an error in RMI communication to
551     * the CAD Simulator.
552     */
553    public void addIncident(final Incident newIncident) throws SimulationException
554    {
555
556        try
557        {
558            theCoorInt.addIncident(newIncident);
559
560        } catch (RemoteException re)
561        {
562            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
563                    "addIncident", "Unable to communicate with the "
564                    + "CAD Simulator.", re);
565
566            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
567        }
568
569    }
570
571    /**
572     * This method passes the view's request to delete an incident from the
573     * simulation on to the remote Coordinator.
574     *
575     * @throws ScriptException if an error occurs in deleting an event.
576     * @throws SimulationException if there is an error in RMI communication to
577     * the CAD Simulator.
578     */
579    public void deleteIncident(int logNumber) throws ScriptException, SimulationException
580    {
581
582        try
583        {
584            theCoorInt.deleteIncident(logNumber);
585
586        } catch (RemoteException re)
587        {
588            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
589                    "deleteIncident", "Unable to communicate with the "
590                    + "CAD Simulator.", re);
591
592            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
593        }
594    }
595
596    /**
597     * This method passes the view's request to reschedule an incident on to the
598     * remote Coordinator.
599     *
600     * @param newTime New simulation time (in seconds).
601     * @throws ScriptException if the Incident has already started or the time
602     * for recheduling has already passed.
603     * @throws SimulationException if there is an error in RMI communication to
604     * the CAD Simulator.
605     */
606    public void rescheduleIncident(long newTime, int logNumber) throws ScriptException, SimulationException
607    {
608
609        try
610        {
611            theCoorInt.rescheduleIncident(logNumber, newTime);
612        } catch (RemoteException re)
613        {
614            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
615                    "rescheduleIncident", "Unable to communicate with the "
616                    + "CAD Simulator.", re);
617
618            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
619        }
620    }
621
622    /**
623     * This method passes the view's request to get the current list of
624     * Incidents loaded into the simulation on to the remote Coordinator.
625     *
626     * @return Vector The Vector of currently loaded incidents.
627     * @throws SimulationException if there is an error in RMI communication to
628     * the CAD Simulator.
629     */
630    public Vector<Incident> getIncidentList() throws SimulationException
631    {
632
633        try
634        {
635            return theCoorInt.getIncidentList();
636
637        } catch (RemoteException re)
638        {
639            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
640                    "getIncidentList", "Unable to communicate with the "
641                    + "CAD Simulator.", re);
642
643            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
644        }
645    }
646
647    /**
648     * This method passes the view's request to get the CMSInfo object that
649     * corresponds to a unique CMS ID String on to the remote Coordinator.
650     *
651     * @param cms_id Unique CMS ID String.
652     * @return CMSInfo object corresponding to the parameter CMS id.
653     * @throws SimulationException if there is an error in RMI communication to
654     * the CAD Simulator.
655     */
656    public CMSInfo getCMSDiversionInfo(String cms_id) throws SimulationException
657    {
658
659        try
660        {
661            return theCoorInt.getCMSDiversionInfo(cms_id);
662        } catch (RemoteException re)
663        {
664            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
665                    "getCMSDiversionInfo", "Unable to communicate with the "
666                    + "CAD Simulator.", re);
667
668            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
669        }
670    }
671
672    /**
673     * This method passes the view's request to update diversions for a CMS on
674     * to the remote Coordinator.
675     *
676     * @param diversion CMS diversions information to apply.
677     * @throws SimulationException if there is an error in RMI communication to
678     * the CAD Simulator.
679     */
680    public void applyDiversions(CMSInfo diversion) throws SimulationException
681    {
682
683        try
684        {
685            theCoorInt.applyDiversions(diversion);
686
687        } catch (RemoteException re)
688        {
689            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
690                    "applyDiversions", "Unable to communicate with the "
691                    + "CAD Simulator.", re);
692
693            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
694        }
695    }
696
697    /**
698     * This method loads the current list of incidents from the Coordinator into
699     * the SimulationManager. For each incident in the simulation, notify the
700     * view to add a new incident tab. If the Incident has begun in the
701     * simulation, call the incidentStarted() method to update the view
702     * accordingly.
703     *
704     * @throws SimulationException if there is an error in RMI communication to
705     * the CAD Simulator.
706     */
707    private void loadIncidents() throws SimulationException
708    {
709
710        try
711        {
712            for (Incident inc : theCoorInt.getIncidentList())
713            {
714
715                Integer logNum = new Integer(inc.getLogNumber());
716
717                theSimManagerView.addIncidentTab(logNum);
718                theSimManagerView.addIncident(inc);
719
720                if (inc.getSecondsToStart() < theCoorInt.getCurrentSimulationTime())
721                {
722                    incidentStarted(logNum);
723                }
724            }
725        } catch (RemoteException re)
726        {
727            simManagerLogger.logp(Level.SEVERE, "SimulationManagerModel",
728                    "loadIncidentListTable", "Unable to communicate with the "
729                    + "CAD Simulator.", re);
730
731            throw new SimulationException(SimulationException.CAD_SIM_COMM, re);
732        }
733
734    }
735}
Note: See TracBrowser for help on using the repository browser.