00001
00002 package riverrat;
00003
00004 import java.util.Vector;
00005 import org.xml.sax.Locator;
00006 import org.xml.sax.ContentHandler;
00007 import org.xml.sax.Attributes;
00008 import org.xml.sax.SAXException;
00009
00015 public class Race implements ContentHandler {
00021 public static final int MODE_FINISHED = 3;
00022
00028 public static final int MODE_LIVE = 2;
00029
00035 public static final int MODE_SETUP = 1;
00036
00042 public static final int MODE_NONE = 0;
00043
00048 RiverRatListener rrlistener;
00049
00056 Thread listenthread;
00057
00059 Vector boatlist;
00060
00062 Vector marklist;
00063
00065 long starttime;
00066
00071 int mode;
00072
00077 String name;
00078
00082 int racenum;
00083
00088 int raceid;
00089
00093 public Race() {
00094
00095 boatlist = new Vector();
00096 marklist = new Vector();
00097 starttime = (long)-1;
00098 }
00099
00107 public Race(String host, int port) {
00108 this();
00109 rrlistener = new RiverRatListener(this, host, port);
00110 listenthread = new Thread(rrlistener);
00111 listenthread.start();
00112 }
00113
00119 public synchronized int numBoats() {
00120 return boatlist.size();
00121 }
00122
00128 public synchronized int numMarks() {
00129 return marklist.size();
00130 }
00131
00137 public synchronized void addBoat(Boat newboat) {
00138 boatlist.addElement(newboat);
00139 }
00140
00146 public synchronized void addMark(Mark newmark) {
00147 marklist.addElement(newmark);
00148 }
00149
00155 public synchronized void addRaceObject(RaceObject newobject) {
00156 if (newobject instanceof Mark) addMark((Mark) newobject);
00157 else if (newobject instanceof Boat) addBoat((Boat) newobject);
00158 }
00159
00166 public synchronized Boat getBoat(int id) throws NoSuchObjectException {
00167 for(int i = 0; i < boatlist.size(); i++) {
00168 if(((Boat) boatlist.elementAt(i)).getID() == id) {
00169 return (Boat) boatlist.elementAt(i);
00170 }
00171 }
00172 throw new NoSuchObjectException();
00173 }
00174
00181 public synchronized Mark getMark(int id) throws NoSuchObjectException {
00182 for(int i = 0; i < marklist.size(); i++) {
00183 if(((Mark) marklist.elementAt(i)).getID() == id) {
00184 return (Mark) marklist.elementAt(i);
00185 }
00186 }
00187 throw new NoSuchObjectException();
00188 }
00189
00195 public synchronized long getStartTime() {
00196 return starttime;
00197 }
00198
00205 public synchronized int getMode() {
00206 return mode;
00207 }
00208
00214 public synchronized String getName() {
00215 return name;
00216 }
00217
00223 public synchronized int getNum() {
00224 return racenum;
00225 }
00226
00232 public synchronized int getID() {
00233 return raceid;
00234 }
00235
00241 public void startDocument() throws SAXException {
00242
00243 }
00244
00249 public void startElement(String uri, String localpart, String rawname, Attributes attrs) throws SAXException {
00250
00251 String attrname;
00252 int length = attrs != null ? attrs.getLength() : 0;
00253 if(rawname == "race") {
00254
00255 for(int i = 0; i < length; i++) {
00256 attrname = attrs.getQName(i);
00257 if(attrname == "id") {
00258 raceid = Integer.decode(attrs.getValue(i)).intValue();
00259 } else if(attrname == "race") {
00260 racenum = Integer.decode(attrs.getValue(i)).intValue();
00261 } else if(attrname == "regatta") {
00262 name = attrs.getValue(i);
00263 }
00264 }
00265 } else if(rawname == "setup") {
00266 mode = MODE_SETUP;
00267 } else if(rawname == "live") {
00268 mode = MODE_LIVE;
00269 } else if(rawname == "starttime") {
00270
00271 for(int i = 0; i < length; i++) {
00272 attrname = attrs.getQName(i);
00273 if(attrname == "data") {
00274
00275 } else if(attrname == "time") {
00276
00277 starttime = Long.decode(attrs.getValue(i)).longValue();
00278 }
00279 }
00280 } else if((rawname == "boat") || (rawname == "mark")) {
00281 int newobjid = -1, newobjsn = -1;
00282 long newobjtime = (long) -1;
00283 float newobjlat = 0.0f, newobjlon = 0.0f, newobjhdg = -1.0f, newobjvel = -1.0f, newobjheel = 0.0f;
00284 for(int i = 0; i < length; i++) {
00285 attrname = attrs.getQName(i);
00286 if(attrname == "id") {
00287 newobjid = Integer.decode(attrs.getValue(i)).intValue();
00288 } else if(attrname == "sn") {
00289 newobjsn = Integer.decode(attrs.getValue(i)).intValue();
00290 } else if(attrname == "time") {
00291 newobjtime = Long.decode(attrs.getValue(i)).longValue();
00292 } else if(attrname == "lat") {
00293 newobjlat = Float.parseFloat(attrs.getValue(i));
00294 } else if(attrname == "lon") {
00295 newobjlon = Float.parseFloat(attrs.getValue(i));
00296 } else if(attrname == "hdg") {
00297 newobjhdg = Float.parseFloat(attrs.getValue(i));
00298 } else if(attrname == "vel") {
00299 newobjvel = Float.parseFloat(attrs.getValue(i));
00300 } else if(attrname == "heel") {
00301 newobjheel = Float.parseFloat(attrs.getValue(i));
00302 }
00303 }
00304
00305 if(mode == MODE_SETUP) {
00306
00307 if(rawname == "boat") {
00308 try {
00309
00310 getBoat(newobjid).setSN(newobjsn);
00311 } catch(NoSuchObjectException ex) {
00312
00313 addBoat(new Boat(newobjid));
00314 getBoat(newobjid).setSN(newobjsn);
00315 }
00316 }
00317 if(rawname == "mark") {
00318 try {
00319
00320 getMark(newobjid).setSN(newobjsn);
00321 } catch(NoSuchObjectException ex) {
00322
00323 addMark(new Mark(newobjid));
00324 getMark(newobjid).setSN(newobjsn);
00325 }
00326 }
00327 } else if(mode == MODE_LIVE) {
00328
00329 if(rawname == "boat") {
00330 try {
00331
00332 getBoat(newobjid).update(new Fix(newobjlat, newobjlon, newobjtime, newobjvel, newobjhdg, newobjheel));
00333 } catch(NoSuchObjectException ex) {
00334
00335 }
00336 } else if(rawname == "mark") {
00337 try {
00338
00339 getMark(newobjid).update(new Fix(newobjlat, newobjlon, newobjtime, newobjvel, newobjhdg, newobjheel));
00340 } catch(NoSuchObjectException ex) {
00341
00342 }
00343 }
00344 }
00345 }
00346 }
00347
00353 public void endDocument() throws SAXException {
00354
00355 }
00356
00361 public void endElement(String uri, String localpart, String rawname) throws SAXException {
00362
00363 if((rawname == "setup") || (rawname == "live")) {
00364 mode = MODE_NONE;
00365 }
00366 if(rawname == "race") {
00367 mode = MODE_FINISHED;
00368 }
00369 }
00370
00372 public void characters(char[] ch, int start, int length) throws SAXException {}
00373
00375 public void endPrefixMapping(String prefix) throws SAXException {}
00376
00378 public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {}
00379
00381 public void processingInstruction(String target, String data) throws SAXException {}
00382
00384 public void setDocumentLocator(Locator locator) {}
00385
00387 public void skippedEntity(String name) throws SAXException {}
00388
00390 public void startPrefixMapping(String prefix, String uri) throws SAXException {}
00391
00393 public static void main(String args[]) {
00394 System.out.println("Starting Race class test case...");
00395 Race testrace = new Race("localhost", 8080);
00396 while(true) {
00397 System.out.println("Race now has "+testrace.numBoats()+" boats.");
00398 System.out.println("Race is in mode "+testrace.getMode());
00399 if(testrace.getMode() == MODE_FINISHED) {
00400 System.out.println("Race finished.");
00401 System.exit(0);
00402 }
00403 for(int boatid = 0; boatid < testrace.numBoats(); boatid++) {
00404 System.out.println(" - "+testrace.getBoat(boatid).boatToString());
00405 }
00406 try {
00407 Thread.sleep(100);
00408 } catch(InterruptedException ex) {
00409 System.err.println("Interrupted.");
00410 }
00411 }
00412 }
00413 }