| 1 | package tmcsim.cadmodels; |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | import java.util.Observable; |
|---|
| 5 | import java.util.StringTokenizer; |
|---|
| 6 | import java.util.TreeMap; |
|---|
| 7 | |
|---|
| 8 | import org.w3c.dom.Document; |
|---|
| 9 | import org.w3c.dom.Element; |
|---|
| 10 | import org.w3c.dom.Node; |
|---|
| 11 | import org.w3c.dom.NodeList; |
|---|
| 12 | |
|---|
| 13 | import tmcsim.common.ScriptException; |
|---|
| 14 | import tmcsim.common.CADEnums.CADScreenNum; |
|---|
| 15 | import tmcsim.common.CADEnums.CADScreenType; |
|---|
| 16 | |
|---|
| 17 | /** |
|---|
| 18 | * CADScreenModel is the base model object for all CAD Screen models. The |
|---|
| 19 | * information contained within this base class includes the CAD time and date, |
|---|
| 20 | * number of routed messages, whether any messages are unread, CAD screen |
|---|
| 21 | * number, and the screen update status values. This data is used for every |
|---|
| 22 | * CAD Screen during display.<br/> |
|---|
| 23 | * <br/> |
|---|
| 24 | * This element parses and creates the following XML schema in its toXML() and |
|---|
| 25 | * fromXML() methods. The ROOT element is the parameter for those methods.<br/> |
|---|
| 26 | * <ROOT> |
|---|
| 27 | * <BASE_MODEL_INFO> |
|---|
| 28 | * <COMMAND_LINE/> |
|---|
| 29 | * <FOOTER> |
|---|
| 30 | * <CAD_TIME/> |
|---|
| 31 | * <CAD_DATE/> |
|---|
| 32 | * <ROUTED_MESSAGES/> |
|---|
| 33 | * <UNREAD_MESSAGES/> |
|---|
| 34 | * <SCREEN_NUM/> |
|---|
| 35 | * <SCREEN_UPDATES> |
|---|
| 36 | * <HAS_UPDATE Screen_Num=""/> |
|---|
| 37 | * <HAS_UPDATE Screen_Num=""/> |
|---|
| 38 | * <HAS_UPDATE Screen_Num=""/> |
|---|
| 39 | * <HAS_UPDATE Screen_Num=""/> |
|---|
| 40 | * </SCREEN_UPDATES> |
|---|
| 41 | * </FOOTER> |
|---|
| 42 | * </BASE_MODEL_INFO> |
|---|
| 43 | * </ROOT> |
|---|
| 44 | * |
|---|
| 45 | * @author Matthew Cechini |
|---|
| 46 | * @version |
|---|
| 47 | */ |
|---|
| 48 | public abstract class CADScreenModel extends Observable { |
|---|
| 49 | |
|---|
| 50 | /** |
|---|
| 51 | * Enumeration with XML tag names. |
|---|
| 52 | * @author Matthew Cechini |
|---|
| 53 | */ |
|---|
| 54 | private static enum XML_TAGS { |
|---|
| 55 | /** CAD screen mnodel. */ |
|---|
| 56 | CAD_SCREEN_MODEL ("CAD_SCREEN_MODEL"), |
|---|
| 57 | /** CAD model update. */ |
|---|
| 58 | CAD_MODEL_UPDATE ("CAD_MODEL_UPDATE"), |
|---|
| 59 | /** CAD model type. */ |
|---|
| 60 | MODEL_TYPE ("MODEL_TYPE"), |
|---|
| 61 | /** Base model information. */ |
|---|
| 62 | BASE_MODEL_INFO ("BASE_MODEL_INFO"), |
|---|
| 63 | /** Current command line. */ |
|---|
| 64 | COMMAND_LINE ("COMMAND_LINE"), |
|---|
| 65 | /** CAD screen footer. */ |
|---|
| 66 | FOOTER ("FOOTER"), |
|---|
| 67 | /** Current CAD time. */ |
|---|
| 68 | CAD_TIME ("CAD_TIME"), |
|---|
| 69 | /** Current CAD date. */ |
|---|
| 70 | CAD_DATE ("CAD_DATE"), |
|---|
| 71 | /** Screen number. */ |
|---|
| 72 | SCREEN_NUM ("SCREEN_NUM"), |
|---|
| 73 | /** Number of routed messages. */ |
|---|
| 74 | ROUTED_MESSAGES ("ROUTED_MESSAGES"), |
|---|
| 75 | /** Boolean to designate if unread messages are in the queue. */ |
|---|
| 76 | UNREAD_MESSAGES ("UNREAD_MESSAGES"), |
|---|
| 77 | /** Screen update stati. */ |
|---|
| 78 | SCREEN_UPDATES ("SCREEN_UPDATES"), |
|---|
| 79 | /** Page number attribute. */ |
|---|
| 80 | UPDATE_SCREEN_NUM ("Screen_Number"), |
|---|
| 81 | /** Screen update's stats.. */ |
|---|
| 82 | HAS_UPDATE ("HAS_UPDATE"); |
|---|
| 83 | |
|---|
| 84 | public String tag; |
|---|
| 85 | |
|---|
| 86 | private XML_TAGS(String t) { |
|---|
| 87 | tag = t; |
|---|
| 88 | } |
|---|
| 89 | |
|---|
| 90 | } |
|---|
| 91 | |
|---|
| 92 | /** Current command line. */ |
|---|
| 93 | public String commandLine; |
|---|
| 94 | |
|---|
| 95 | /** Screen type for this model. */ |
|---|
| 96 | public CADScreenType screenType; |
|---|
| 97 | |
|---|
| 98 | /** Screen number for this model. */ |
|---|
| 99 | public CADScreenNum screenNum; |
|---|
| 100 | |
|---|
| 101 | /** Number of routed messages for this CAD terminal. */ |
|---|
| 102 | public int numberRoutedMessages; |
|---|
| 103 | |
|---|
| 104 | /** Boolean flag to designate whether there are unread routed messages. */ |
|---|
| 105 | public boolean unreadMessages; |
|---|
| 106 | |
|---|
| 107 | /** Current update status for all CAD screens. */ |
|---|
| 108 | public TreeMap<CADScreenNum, Boolean> screenUpdateMap; |
|---|
| 109 | |
|---|
| 110 | /** Current CAD Date value. MMYY*/ |
|---|
| 111 | static public String theCADDate = ""; |
|---|
| 112 | |
|---|
| 113 | /** Current CAD Time value. HHMM*/ |
|---|
| 114 | static public String theCADTime = ""; |
|---|
| 115 | |
|---|
| 116 | |
|---|
| 117 | /** |
|---|
| 118 | * Constructor. Initiailze data. Set screenUpdateMap to be |
|---|
| 119 | * false for all screens. |
|---|
| 120 | * |
|---|
| 121 | * @param type CADScreenType for this model. |
|---|
| 122 | * @param num CADScreenNum for this model. |
|---|
| 123 | */ |
|---|
| 124 | public CADScreenModel(CADScreenType type, CADScreenNum num) { |
|---|
| 125 | |
|---|
| 126 | screenNum = num; |
|---|
| 127 | screenType = type; |
|---|
| 128 | commandLine = ""; |
|---|
| 129 | numberRoutedMessages = 0; |
|---|
| 130 | unreadMessages = false; |
|---|
| 131 | |
|---|
| 132 | screenUpdateMap = new TreeMap<CADScreenNum, Boolean>(); |
|---|
| 133 | |
|---|
| 134 | for(CADScreenNum screen : CADScreenNum.orderedList()) { |
|---|
| 135 | screenUpdateMap.put(screen, false); |
|---|
| 136 | } |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | public abstract void addModelObject(Object o); |
|---|
| 140 | |
|---|
| 141 | /** |
|---|
| 142 | * Creates XML tags with the model data and adds them to the parameter |
|---|
| 143 | * Element. The baseToXML() method is called to add the base |
|---|
| 144 | * XML tags for CAD model data. See clss description for XML schema. |
|---|
| 145 | * |
|---|
| 146 | * @param currElem XML Element used as a root for XML tag appending. |
|---|
| 147 | */ |
|---|
| 148 | public abstract void toXML(Element currElem); |
|---|
| 149 | |
|---|
| 150 | /** |
|---|
| 151 | * Parses model data from the parameter Node. The fromToXML() method is |
|---|
| 152 | * called to parse the base XML tags for CAD model data. See clss |
|---|
| 153 | * description for XML schema. |
|---|
| 154 | * |
|---|
| 155 | * @param modelNode XML Node containing model information. |
|---|
| 156 | * @throws ScriptException if there is an error in parsing the Node. |
|---|
| 157 | */ |
|---|
| 158 | public abstract void fromXML(Node modelNode) throws ScriptException; |
|---|
| 159 | |
|---|
| 160 | /** |
|---|
| 161 | * Writes the base model data to the XMLWriter. See the class |
|---|
| 162 | * description for the base model XML schema. |
|---|
| 163 | * |
|---|
| 164 | * @param currElem XML Element used as a root for XML tag appending. |
|---|
| 165 | */ |
|---|
| 166 | public void baseToXML(Element currElem) { |
|---|
| 167 | |
|---|
| 168 | Document theDoc = currElem.getOwnerDocument(); |
|---|
| 169 | |
|---|
| 170 | Element baseModelElem = theDoc.createElement(XML_TAGS.BASE_MODEL_INFO.tag); |
|---|
| 171 | |
|---|
| 172 | Element cmdLineElem = theDoc.createElement(XML_TAGS.COMMAND_LINE.tag); |
|---|
| 173 | cmdLineElem.appendChild(theDoc.createTextNode(commandLine)); |
|---|
| 174 | baseModelElem.appendChild(cmdLineElem); |
|---|
| 175 | |
|---|
| 176 | Element footerElem = theDoc.createElement(XML_TAGS.FOOTER.tag); |
|---|
| 177 | baseModelElem.appendChild(footerElem); |
|---|
| 178 | |
|---|
| 179 | Element timeElem = theDoc.createElement(XML_TAGS.CAD_TIME.tag); |
|---|
| 180 | timeElem.appendChild(theDoc.createTextNode(theCADTime)); |
|---|
| 181 | footerElem.appendChild(timeElem); |
|---|
| 182 | |
|---|
| 183 | Element dateElem = theDoc.createElement(XML_TAGS.CAD_DATE.tag); |
|---|
| 184 | dateElem.appendChild(theDoc.createTextNode(theCADDate)); |
|---|
| 185 | footerElem.appendChild(dateElem); |
|---|
| 186 | |
|---|
| 187 | Element routedMsgsElem = theDoc.createElement(XML_TAGS.ROUTED_MESSAGES.tag); |
|---|
| 188 | routedMsgsElem.appendChild(theDoc.createTextNode(String.valueOf(numberRoutedMessages))); |
|---|
| 189 | footerElem.appendChild(routedMsgsElem); |
|---|
| 190 | |
|---|
| 191 | Element unreadMsgsElem = theDoc.createElement(XML_TAGS.UNREAD_MESSAGES.tag); |
|---|
| 192 | unreadMsgsElem.appendChild(theDoc.createTextNode(String.valueOf(unreadMessages))); |
|---|
| 193 | footerElem.appendChild(unreadMsgsElem); |
|---|
| 194 | |
|---|
| 195 | Element screenNumElem = theDoc.createElement(XML_TAGS.SCREEN_NUM.tag); |
|---|
| 196 | screenNumElem.appendChild(theDoc.createTextNode(String.valueOf(screenNum.intNum))); |
|---|
| 197 | footerElem.appendChild(screenNumElem); |
|---|
| 198 | |
|---|
| 199 | Element screenUpdatesElem = theDoc.createElement(XML_TAGS.SCREEN_UPDATES.tag); |
|---|
| 200 | footerElem.appendChild(screenUpdatesElem); |
|---|
| 201 | |
|---|
| 202 | Element updateElem = null; |
|---|
| 203 | for(CADScreenNum screen : CADScreenNum.orderedList()) { |
|---|
| 204 | updateElem = theDoc.createElement(XML_TAGS.HAS_UPDATE.tag); |
|---|
| 205 | updateElem.appendChild(theDoc.createTextNode(String.valueOf(screenUpdateMap.get(screen)))); |
|---|
| 206 | updateElem.setAttribute(XML_TAGS.UPDATE_SCREEN_NUM.tag, String.valueOf(screen.intNum)); |
|---|
| 207 | |
|---|
| 208 | screenUpdatesElem.appendChild(updateElem); |
|---|
| 209 | } |
|---|
| 210 | |
|---|
| 211 | currElem.appendChild(baseModelElem); |
|---|
| 212 | |
|---|
| 213 | } |
|---|
| 214 | |
|---|
| 215 | /** |
|---|
| 216 | * Read in the base model data from the XML node. See the class |
|---|
| 217 | * description for the base model XML schema. |
|---|
| 218 | * |
|---|
| 219 | * @param modelNode XML Node containing model information. |
|---|
| 220 | * @throws ScriptException if there is an error in parsing the node. |
|---|
| 221 | */ |
|---|
| 222 | public void baseFromXML(Node modelNode) throws ScriptException { |
|---|
| 223 | //COMMAND_LINE node |
|---|
| 224 | Node node = modelNode.getFirstChild(); |
|---|
| 225 | commandLine = node.getTextContent(); |
|---|
| 226 | |
|---|
| 227 | //FOOTER node |
|---|
| 228 | node = node.getNextSibling(); |
|---|
| 229 | |
|---|
| 230 | //CAD_TIME node |
|---|
| 231 | node = node.getFirstChild(); |
|---|
| 232 | theCADTime = node.getTextContent(); |
|---|
| 233 | |
|---|
| 234 | //CAD_DATE node |
|---|
| 235 | node = node.getNextSibling(); |
|---|
| 236 | theCADDate = node.getTextContent(); |
|---|
| 237 | |
|---|
| 238 | //ROUTED_MESSAGES node |
|---|
| 239 | node = node.getNextSibling(); |
|---|
| 240 | numberRoutedMessages = Integer.valueOf(node.getTextContent()).intValue(); |
|---|
| 241 | |
|---|
| 242 | //UNREAD_MESSAGES node |
|---|
| 243 | node = node.getNextSibling(); |
|---|
| 244 | unreadMessages = Boolean.valueOf(node.getTextContent()).booleanValue(); |
|---|
| 245 | |
|---|
| 246 | //SCREEN_NUM node |
|---|
| 247 | node = node.getNextSibling(); |
|---|
| 248 | screenNum = CADScreenNum.fromValue(Integer.valueOf(node.getTextContent()).intValue()); |
|---|
| 249 | |
|---|
| 250 | //SCREEN_UPDATES node |
|---|
| 251 | node = node.getNextSibling(); |
|---|
| 252 | NodeList updates = node.getChildNodes(); |
|---|
| 253 | |
|---|
| 254 | screenUpdateMap.clear(); |
|---|
| 255 | Integer pageNumber = null; |
|---|
| 256 | Boolean updateStatus = null; |
|---|
| 257 | for(int i = 0; i < updates.getLength(); i++) { |
|---|
| 258 | |
|---|
| 259 | pageNumber = Integer.valueOf(updates.item(i).getAttributes(). |
|---|
| 260 | getNamedItem(XML_TAGS.UPDATE_SCREEN_NUM.tag).getTextContent()); |
|---|
| 261 | updateStatus = Boolean.valueOf(updates.item(i).getTextContent()); |
|---|
| 262 | |
|---|
| 263 | screenUpdateMap.put(CADScreenNum.fromValue(pageNumber), updateStatus); |
|---|
| 264 | } |
|---|
| 265 | } |
|---|
| 266 | |
|---|
| 267 | /** |
|---|
| 268 | * Get the CAD screen type for this model. |
|---|
| 269 | * @return Current CADScreenType object. |
|---|
| 270 | */ |
|---|
| 271 | public CADScreenType getType() { |
|---|
| 272 | return screenType; |
|---|
| 273 | } |
|---|
| 274 | |
|---|
| 275 | /** |
|---|
| 276 | * Get the CAD screen number for this model. |
|---|
| 277 | * @return Current CADScreenNum object. |
|---|
| 278 | */ |
|---|
| 279 | public CADScreenNum getScreenNum() { |
|---|
| 280 | return screenNum; |
|---|
| 281 | } |
|---|
| 282 | |
|---|
| 283 | /** |
|---|
| 284 | * This static method converts the parameter CAD screen status update |
|---|
| 285 | * map into a String representation. The resulting String is in the |
|---|
| 286 | * following format: "<#>=true,<#>=false,<#>=true,<#>=false" where <#> |
|---|
| 287 | * is the CAD screen number. |
|---|
| 288 | * |
|---|
| 289 | * @param updateMap Map containing screen update flags. |
|---|
| 290 | * @return A String concatenation of screen update information. |
|---|
| 291 | */ |
|---|
| 292 | public static String updateMapToString(TreeMap<CADScreenNum, Boolean> updateMap) { |
|---|
| 293 | |
|---|
| 294 | StringBuffer mapBuf = new StringBuffer(); |
|---|
| 295 | |
|---|
| 296 | for(CADScreenNum screen : updateMap.keySet()) { |
|---|
| 297 | mapBuf.append(screen.intNum); |
|---|
| 298 | mapBuf.append("="); |
|---|
| 299 | mapBuf.append(updateMap.get(screen).toString()); |
|---|
| 300 | mapBuf.append(","); |
|---|
| 301 | } |
|---|
| 302 | |
|---|
| 303 | mapBuf.setLength(mapBuf.length()-1); |
|---|
| 304 | |
|---|
| 305 | return mapBuf.toString(); |
|---|
| 306 | } |
|---|
| 307 | |
|---|
| 308 | /** |
|---|
| 309 | * This static method converts the parameter CAD screen status update |
|---|
| 310 | * String into an update Map. The parameter String must have the |
|---|
| 311 | * following format: "<#>=true,<#>=false,<#>=true,<#>=false" where <#> |
|---|
| 312 | * is the CAD screen number. |
|---|
| 313 | * |
|---|
| 314 | * @param updateString String containing CAD screen status update info. |
|---|
| 315 | * @return Map containing CAD Screen update info. |
|---|
| 316 | */ |
|---|
| 317 | public static TreeMap<CADScreenNum, Boolean> updateStringToMap(String updateString) { |
|---|
| 318 | |
|---|
| 319 | TreeMap<CADScreenNum, Boolean> updateMap = new TreeMap<CADScreenNum, Boolean>(); |
|---|
| 320 | |
|---|
| 321 | StringTokenizer strTok = new StringTokenizer(updateString, ","); |
|---|
| 322 | String token = null; |
|---|
| 323 | |
|---|
| 324 | CADScreenNum screen = null; |
|---|
| 325 | Boolean screenUpdate = null; |
|---|
| 326 | |
|---|
| 327 | while(strTok.hasMoreTokens()) { |
|---|
| 328 | token = strTok.nextToken(); |
|---|
| 329 | |
|---|
| 330 | screen = CADScreenNum.fromValue(Integer.parseInt( |
|---|
| 331 | token.substring(0, token.indexOf("=")))); |
|---|
| 332 | screenUpdate = Boolean.parseBoolean(token.substring( |
|---|
| 333 | token.indexOf("=")+1, token.length())); |
|---|
| 334 | |
|---|
| 335 | updateMap.put(screen, screenUpdate); |
|---|
| 336 | } |
|---|
| 337 | |
|---|
| 338 | return updateMap; |
|---|
| 339 | } |
|---|
| 340 | |
|---|
| 341 | } |
|---|