package tmcsim.cadsimulator.managers; import java.io.File; import java.io.FileInputStream; import java.util.Observable; import java.util.Observer; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JOptionPane; import javax.swing.JWindow; import javax.xml.parsers.DocumentBuilderFactory; import tmcsim.cadsimulator.db.DVDPlayerDB; import tmcsim.cadsimulator.db.StillImagesDB; import tmcsim.cadsimulator.stillimagecontrol.ImageController; import tmcsim.cadsimulator.videocontrol.DVDController; import tmcsim.cadsimulator.videocontrol.DVDStatusUpdate; import tmcsim.cadsimulator.videocontrol.DVDTitleUpdate; import tmcsim.cadsimulator.viewer.model.CADSimulatorState; import tmcsim.common.CCTVDirections; import tmcsim.common.CCTVInfo; /** * MediaManager manages the control of media associated with the speed * information received from the ParamicsCommunicator. The MediaManager * instantiates the DVDPlayerDB and StillImageDB objects, which are initialized * from XML data files to hold the information regarding which DVD titles and * Still Images are available for display. Each title or image is associated * with a specific speed range or Incident log number. The triggerIncident() * method is called to notify the MediaManager that incident media is to be * displayed. The updateCameraInfo() method is called when speed information * is received for a specific camera. In both methods, a Controller object * is found for the unique camera ID number. This Controller is updated with * the new speed data. If the update causes a change in media to be displayed, * the change is made.
*
* The MediaManager implements the Observer interface and observes the * DVDPlayerDB and StillImageDB for updates. These updates are received, action * is taken, and then the update is passed to the CADSimulatorViewer for display. * * @see tmcsim.cadsimulator.viewer.CADSimulatorViewer * @author Matthew Cechini * @version */ public class MediaManager implements Observer { /** Error Logger. */ private static Logger mediaLogger = Logger.getLogger("tmcsim.simulator"); /** * Enumeration of property names. * @author Matthew Cechini */ private static enum MEDIA_PROPERTIES { /** Filepath for xml file containing dvd control data. */ DVD_XML_FILE ("DVDPlayerXML"), /** Filepath for xml file containing still image control data. */ IMAGE_XML_FILE ("StillImagesXML"); public String name; private MEDIA_PROPERTIES(String n) { name = n; } }; /** Instance of the DVD Player Database. */ private DVDPlayerDB theDVD_DB = null; /** Instance of the Still Image Database. */ private StillImagesDB theImage_DB = null; /** Reference to the CADSimulatorModel. */ private CADSimulatorState theModel; /** Properties object for the Media portion of the CAD. */ private Properties mediaProperties; /** * Constructor. The target properties file is loaded and the DVD and Still * Image DB objects are initialized with the XML data files containing * the respective data. * * @param propertiesFile File path for target properties file. * @param theATMSManager ATMSManager object. * @param viewer CADSimulatorViewer object. */ public MediaManager(String propertiesFile, ATMSManager theATMSManager, CADSimulatorState model) { theDVD_DB = new DVDPlayerDB(); theImage_DB = new StillImagesDB(); theModel = model; try { mediaProperties = new Properties(); mediaProperties.load(new FileInputStream(new File(propertiesFile))); } catch (Exception e) { mediaLogger.logp(Level.SEVERE, "MediaManager", "Constructor", "Exception in loading properties file.", e); } // Load DVD Player Information from the XML file try { if (mediaProperties.getProperty(MEDIA_PROPERTIES.DVD_XML_FILE.name) != null) { theDVD_DB.addObserver(this); theDVD_DB.loadFromXML(DocumentBuilderFactory .newInstance().newDocumentBuilder() .parse(new File(mediaProperties.getProperty( MEDIA_PROPERTIES.DVD_XML_FILE.name)))); } } catch (Exception e) { mediaLogger.logp(Level.SEVERE, "MediaManager", "Constructor", "Exception in parsing DVDPlayer xml file.", e); JOptionPane.showMessageDialog(new JWindow(), "An error occured " + "opening and parsing the DVD xml data file: " + mediaProperties.getProperty(MEDIA_PROPERTIES.DVD_XML_FILE.name), "Initialization Error", JOptionPane.WARNING_MESSAGE); } // Load Still Image Information from the XML file try { if (mediaProperties .getProperty(MEDIA_PROPERTIES.IMAGE_XML_FILE.name) != null) { theImage_DB.addObserver(this); theImage_DB.loadFromXML(DocumentBuilderFactory .newInstance().newDocumentBuilder() .parse(new File(mediaProperties.getProperty( MEDIA_PROPERTIES.IMAGE_XML_FILE.name))), theATMSManager); } } catch (Exception e) { mediaLogger.logp(Level.SEVERE, "MediaManager", "Constructor", "Exception in parsing StillImages xml file.", e); JOptionPane.showMessageDialog(new JWindow(), "An error occured " + "opening and parsing the Image xml data file: " + mediaProperties.getProperty(MEDIA_PROPERTIES.IMAGE_XML_FILE.name), "Initialization Error", JOptionPane.WARNING_MESSAGE); } } /** * Observer method. The update objects accepted and their associated * actions are shown below.
*
* */ public void update(Observable o, Object arg) { if(arg instanceof DVDStatusUpdate) { if(((DVDStatusUpdate)arg).exception != null) { mediaLogger.logp(Level.SEVERE, "MediaManager", "update", "Exception from DVD Controller.", ((DVDStatusUpdate)arg).exception); } theModel.updateDVDStatus((DVDStatusUpdate)arg); } else if(arg instanceof DVDTitleUpdate) { theModel.updateDVDTitle((DVDTitleUpdate)arg); } } /** * This method triggers the DVD and Image Controllers for a specific camera * to display an Incident title or image for the parameter Incident log * number. * * @param info Information of the CCTV Camera to display incident images. * @param logNumber Log number of the Incident being triggered. */ public void triggerIncident(CCTVInfo info, Integer logNumber) { try { DVDController dvdCntrl = theDVD_DB.getController(info.cctv_id, info.direction); if(dvdCntrl != null) { dvdCntrl.toggleIncident(logNumber, info.toggle); } } catch (Exception e) { mediaLogger.logp(Level.SEVERE, "MediaManager", "triggerIncident", "Exception in toggling an incident on the DVD controller.", e); } try { ImageController imageCntrl = theImage_DB.getController(info.cctv_id, info.direction); if(imageCntrl != null) { imageCntrl.toggleIncident(logNumber, info.toggle); } } catch (Exception e) { mediaLogger.logp(Level.SEVERE, "MediaManager", "triggerIncident", "Exception in toggling an incident on the Image controller.", e); } } /** * This method receives updated speed information for a specific controller * and updates the DVD Title and Still Image being currently displayed for * that camera. * * @param cameraID CCTV camera ID * @param avgSpeed_NE Average speed of traffic flowing N or E * @param avgSpeed_SW Average speed of traffic flowing S or W */ public void updateCameraInfo(Integer cameraID, float avgSpeed_NE, float avgSpeed_SW) { updateDVD(cameraID, avgSpeed_NE, avgSpeed_SW); updateStillImage(cameraID, avgSpeed_NE, avgSpeed_SW); } /** * This method accepts updated speed information for a specific DVD * player. The DVDController object corresponding to the parameter camera * ID is found and updated with the new speed. If this update causes the * dvd controller to change titles, the new title is played. * * @param cameraID CCTV camera ID * @param avgSpeed_NE Average speed of traffic flowing N or E * @param avgSpeed_SW Average speed of traffic flowing S or W */ protected void updateDVD(Integer cameraID, float avgSpeed_NE, float avgSpeed_SW) { for(CCTVDirections dir : CCTVDirections.values()) { DVDController dvdCntrl = theDVD_DB.getController(cameraID, dir); //if Controller exists, update. if(dvdCntrl != null) { if( ((dir == CCTVDirections.NORTH || dir == CCTVDirections.EAST) && (dvdCntrl.updatePlayer(avgSpeed_NE))) || ((dir == CCTVDirections.SOUTH || dir == CCTVDirections.WEST) && (dvdCntrl.updatePlayer(avgSpeed_SW)))) { try { dvdCntrl.playCurrentTitle(); } catch (Exception e) { mediaLogger.logp(Level.SEVERE, "ParamicsCameraStatusReader", "updateDVD", "Exception in updating DVD player with new speed.", e); } } } } } /** * This method accepts updated speed information for a specific CCTV camera. * The ImageController object corresponding to the parameter camera ID * is found and updated with the new speed. If this update causes the image * controller to change images, the new image is shown. * * @param cameraID Unique CCTV camera ID * @param avgSpeed_NE Average speed of traffic flowing N or E * @param avgSpeed_SW Average speed of traffic flowing S or W */ protected void updateStillImage(Integer cameraID, float avgSpeed_NE, float avgSpeed_SW) { for(CCTVDirections dir : CCTVDirections.values()) { ImageController imageCntrl = theImage_DB.getController(cameraID, dir); //if Controller exists, update. if(imageCntrl != null) { if( ((dir == CCTVDirections.NORTH || dir == CCTVDirections.EAST) && (imageCntrl.updateImage(avgSpeed_NE))) || ((dir == CCTVDirections.SOUTH || dir == CCTVDirections.WEST) && (imageCntrl.updateImage(avgSpeed_SW)))) { try { imageCntrl.showCurrentImage(); } catch (Exception e) { mediaLogger.logp(Level.SEVERE, "ParamicsCameraStatusReader", "updateStillImage", "Exception in updating image controller with new speed.", e); } } } } } }