| 1 | package tmcsim.cadsimulator.db; |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | import java.io.IOException; |
|---|
| 5 | import java.util.Observable; |
|---|
| 6 | import java.util.Observer; |
|---|
| 7 | import java.util.TreeMap; |
|---|
| 8 | import java.util.logging.Level; |
|---|
| 9 | import java.util.logging.Logger; |
|---|
| 10 | |
|---|
| 11 | import org.w3c.dom.Document; |
|---|
| 12 | import org.w3c.dom.Element; |
|---|
| 13 | import org.w3c.dom.NodeList; |
|---|
| 14 | |
|---|
| 15 | import tmcsim.cadsimulator.videocontrol.DVDController; |
|---|
| 16 | import tmcsim.cadsimulator.videocontrol.DVDIncident; |
|---|
| 17 | import tmcsim.cadsimulator.videocontrol.DVDRange; |
|---|
| 18 | import tmcsim.common.CCTVDirections; |
|---|
| 19 | import tmcsim.common.ScriptException; |
|---|
| 20 | |
|---|
| 21 | /** |
|---|
| 22 | * DVDPlayerDB acts as a database containing the information |
|---|
| 23 | * for each dvd player and the cameras whose playback is found on that |
|---|
| 24 | * player. The "Database" of dvd players and information is created by |
|---|
| 25 | * calling the loadFromXML() method with a valid XML document. DVD players |
|---|
| 26 | * are "queried" according to the corresponding CCTV camera ID and direction |
|---|
| 27 | * whose video is represented on that DVD. |
|---|
| 28 | * |
|---|
| 29 | * @author Matthew Cechini (mcechini@calpoly.edu) |
|---|
| 30 | * @version $Date: 2006/06/06 22:33:20 $ $Revision: 1.4 $ |
|---|
| 31 | */ |
|---|
| 32 | public class DVDPlayerDB extends Observable implements Observer { |
|---|
| 33 | |
|---|
| 34 | /** Error Logger. */ |
|---|
| 35 | private static Logger dvdLogger = Logger.getLogger("tmcsim.cadsimulator.db"); |
|---|
| 36 | |
|---|
| 37 | /** |
|---|
| 38 | * Enumeration containing XML tag names used to parse the XML |
|---|
| 39 | * document containing information about DVD Title control. |
|---|
| 40 | * @author Matthew Cechini |
|---|
| 41 | */ |
|---|
| 42 | private static enum DVD_TAGS { |
|---|
| 43 | /** Top level tag. */ |
|---|
| 44 | DVD_PLAYERS ("DVD_PLAYERS"), |
|---|
| 45 | /** DVD player info. */ |
|---|
| 46 | DVD_PLAYER ("DVD_PLAYER"), |
|---|
| 47 | /** DVD player type. */ |
|---|
| 48 | TYPE ("type"), |
|---|
| 49 | /** DVD player address. */ |
|---|
| 50 | HOST ("host"), |
|---|
| 51 | /** DVD player port. */ |
|---|
| 52 | PORT ("port"), |
|---|
| 53 | /** CCTV camera info. */ |
|---|
| 54 | CCTV ("CCTV"), |
|---|
| 55 | /** CCTV camera id. */ |
|---|
| 56 | ID ("id"), |
|---|
| 57 | /** CCTV camera direction. */ |
|---|
| 58 | DIRECTION ("dir"), |
|---|
| 59 | /** Incident title info. */ |
|---|
| 60 | INCIDENT ("INCIDENT"), |
|---|
| 61 | /** Log number of an incident title. */ |
|---|
| 62 | LOG_NUM ("log_num"), |
|---|
| 63 | /** Speed range mapping to a title number. */ |
|---|
| 64 | RANGE ("RANGE"), |
|---|
| 65 | /** Minimum speed in a range. */ |
|---|
| 66 | MIN_SPEED ("min_speed"), |
|---|
| 67 | /** Maximum speed in a range. */ |
|---|
| 68 | MAX_SPEED ("max_speed"), |
|---|
| 69 | /** Title name. */ |
|---|
| 70 | TITLE ("title"); |
|---|
| 71 | |
|---|
| 72 | /** XML Tag Name */ |
|---|
| 73 | public String tag; |
|---|
| 74 | |
|---|
| 75 | private DVD_TAGS(String t) { |
|---|
| 76 | tag = t; |
|---|
| 77 | } |
|---|
| 78 | } |
|---|
| 79 | |
|---|
| 80 | |
|---|
| 81 | /** |
|---|
| 82 | * The map containing all current CCTV Camera IDs(key) and the corresponding |
|---|
| 83 | * DVD Controller(value) that have been registered with the system. |
|---|
| 84 | */ |
|---|
| 85 | private TreeMap<CCTVInfo, DVDController> dvdPlayerMap = null; |
|---|
| 86 | |
|---|
| 87 | /** |
|---|
| 88 | * Constructor. Initialize the DVD Controller map. |
|---|
| 89 | */ |
|---|
| 90 | public DVDPlayerDB() { |
|---|
| 91 | dvdPlayerMap = new TreeMap<CCTVInfo, DVDController>(); |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | /** |
|---|
| 95 | * Implementation of the Observer update() method. All received update |
|---|
| 96 | * objects are sent to Observers of this DB. |
|---|
| 97 | */ |
|---|
| 98 | public void update(Observable o, Object arg) { |
|---|
| 99 | setChanged(); |
|---|
| 100 | notifyObservers(arg); |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | /** |
|---|
| 104 | * Load the DVD map from an xml document, adhering to the |
|---|
| 105 | * following schema. When parsing has finished, the map of |
|---|
| 106 | * DVDController and CCTVInfo objects will contain objects |
|---|
| 107 | * representing all control objects specified in the XML. |
|---|
| 108 | * A connection to each DVD controller will be automatically |
|---|
| 109 | * started after parsing has completed.<br> |
|---|
| 110 | * |
|---|
| 111 | * <DVD_PLAYERS> <br> |
|---|
| 112 | * <DVD_PLAYER type="" host="" port=""> |
|---|
| 113 | * <CCTV id="" dir=""/> |
|---|
| 114 | * <INCIDENT log_num="" title="" duration=""/> |
|---|
| 115 | * <RANGE min_speed="" max_speed="" title="" duration=""/> |
|---|
| 116 | ( </DVD_PLAYER> |
|---|
| 117 | *</DVD_PLAYERS> <br> |
|---|
| 118 | * |
|---|
| 119 | * @param newDoc The XML document containing the DVD player |
|---|
| 120 | * registration information. |
|---|
| 121 | * @throws ScriptException if there is an error in parsing the node. |
|---|
| 122 | */ |
|---|
| 123 | public void loadFromXML(Document newDoc) throws ScriptException { |
|---|
| 124 | |
|---|
| 125 | //temporary variables |
|---|
| 126 | Element rootElement = newDoc.getDocumentElement(); |
|---|
| 127 | Element playerElement = null; |
|---|
| 128 | Element cctvElement = null; |
|---|
| 129 | Element rangeElement = null; |
|---|
| 130 | Element incidentElement = null; |
|---|
| 131 | |
|---|
| 132 | Integer cctvID = null; |
|---|
| 133 | CCTVDirections cctvDirection = null; |
|---|
| 134 | DVDController theController = null; |
|---|
| 135 | |
|---|
| 136 | NodeList players = rootElement.getElementsByTagName(DVD_TAGS.DVD_PLAYER.tag); |
|---|
| 137 | NodeList ranges = null; |
|---|
| 138 | NodeList incidents = null; |
|---|
| 139 | |
|---|
| 140 | |
|---|
| 141 | for(int i = 0; i < players.getLength(); i++) { |
|---|
| 142 | |
|---|
| 143 | playerElement = (Element)players.item(i); |
|---|
| 144 | |
|---|
| 145 | try { |
|---|
| 146 | theController = (DVDController)Class.forName( |
|---|
| 147 | "tmcsim.cadsimulator.videocontrol." + playerElement.getAttribute( |
|---|
| 148 | DVD_TAGS.TYPE.tag)).newInstance(); |
|---|
| 149 | theController.addObserver(this); |
|---|
| 150 | } |
|---|
| 151 | catch (Exception e) { |
|---|
| 152 | dvdLogger.logp(Level.SEVERE, "DVDPlayerDB", "loadFromXML", |
|---|
| 153 | "Error in instantiating DVD Controller", e); |
|---|
| 154 | continue; |
|---|
| 155 | } |
|---|
| 156 | |
|---|
| 157 | theController.setConnectionInfo(playerElement.getAttribute( |
|---|
| 158 | DVD_TAGS.HOST.tag), |
|---|
| 159 | Integer.parseInt(playerElement.getAttribute( |
|---|
| 160 | DVD_TAGS.PORT.tag))); |
|---|
| 161 | |
|---|
| 162 | cctvElement = (Element)playerElement.getElementsByTagName( |
|---|
| 163 | DVD_TAGS.CCTV.tag).item(0); |
|---|
| 164 | cctvID = Integer.parseInt(cctvElement.getAttribute( |
|---|
| 165 | DVD_TAGS.ID.tag)); |
|---|
| 166 | cctvDirection = CCTVDirections.fromChar(cctvElement.getAttribute( |
|---|
| 167 | DVD_TAGS.DIRECTION.tag).charAt(0)); |
|---|
| 168 | |
|---|
| 169 | ranges = playerElement.getElementsByTagName(DVD_TAGS.RANGE.tag); |
|---|
| 170 | incidents = playerElement.getElementsByTagName(DVD_TAGS.INCIDENT.tag); |
|---|
| 171 | |
|---|
| 172 | for(int j = 0; j < ranges.getLength(); j++) { |
|---|
| 173 | rangeElement = (Element)ranges.item(j); |
|---|
| 174 | |
|---|
| 175 | theController.addRange(new DVDRange( |
|---|
| 176 | Float.parseFloat(rangeElement.getAttribute( |
|---|
| 177 | DVD_TAGS.MIN_SPEED.tag)), |
|---|
| 178 | Float.parseFloat(rangeElement.getAttribute( |
|---|
| 179 | DVD_TAGS.MAX_SPEED.tag)), |
|---|
| 180 | Integer.parseInt(rangeElement.getAttribute( |
|---|
| 181 | DVD_TAGS.TITLE.tag)))); |
|---|
| 182 | } |
|---|
| 183 | |
|---|
| 184 | for(int j = 0; j < incidents.getLength(); j++) { |
|---|
| 185 | incidentElement = (Element)incidents.item(j); |
|---|
| 186 | |
|---|
| 187 | theController.addIncident(new DVDIncident( |
|---|
| 188 | Integer.parseInt(incidentElement.getAttribute( |
|---|
| 189 | DVD_TAGS.LOG_NUM.tag)), |
|---|
| 190 | Integer.parseInt(incidentElement.getAttribute( |
|---|
| 191 | DVD_TAGS.TITLE.tag)))); |
|---|
| 192 | } |
|---|
| 193 | |
|---|
| 194 | dvdPlayerMap.put(new CCTVInfo(cctvID, cctvDirection), theController); |
|---|
| 195 | |
|---|
| 196 | } |
|---|
| 197 | |
|---|
| 198 | //Thread the connection of DVD controllers so that initialization does not hang. |
|---|
| 199 | Runnable connect = new Runnable() { |
|---|
| 200 | |
|---|
| 201 | public void run() { |
|---|
| 202 | for(DVDController controller : dvdPlayerMap.values()) { |
|---|
| 203 | try { |
|---|
| 204 | controller.connect(); |
|---|
| 205 | } |
|---|
| 206 | catch (IOException ioe) { |
|---|
| 207 | dvdLogger.logp(Level.SEVERE, "DVDPlayerDB", "loadFromXML:runnable", |
|---|
| 208 | "IOException in connecting DVD " + |
|---|
| 209 | controller.getConnectionInfo(), ioe); |
|---|
| 210 | } |
|---|
| 211 | } |
|---|
| 212 | } |
|---|
| 213 | }; |
|---|
| 214 | |
|---|
| 215 | Thread connectThread = new Thread(connect); |
|---|
| 216 | connectThread.start(); |
|---|
| 217 | } |
|---|
| 218 | |
|---|
| 219 | /** |
|---|
| 220 | * Gets the DVDController for a registered camera. DVDControllers |
|---|
| 221 | * are referenced by the Camera ID and direction. |
|---|
| 222 | * |
|---|
| 223 | * @param cctv_id CCTV camera id |
|---|
| 224 | * @param dir CCTV camera direction |
|---|
| 225 | * |
|---|
| 226 | * @return Returns the DVDController object corresponding with the parameter |
|---|
| 227 | * camera values. Returns null if no corresponding DVD Controller is found. |
|---|
| 228 | */ |
|---|
| 229 | public DVDController getController(Integer cctv_id, CCTVDirections dir) { |
|---|
| 230 | return dvdPlayerMap.get(new CCTVInfo(cctv_id, dir)); |
|---|
| 231 | } |
|---|
| 232 | |
|---|
| 233 | |
|---|
| 234 | } |
|---|