View Javadoc

1   /*
2    * @(#) InfraFileXMLParser.java Jun 6, 2004
3    * 
4    * Copyright (c) 2003, 2004 Delft University of Technology Jaffalaan 5, 2628 BX
5    * Delft, the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
9    */
10  
11  package nl.tudelft.simulation.traffic.file;
12  
13  import java.awt.Color;
14  import java.awt.geom.Point2D;
15  import java.io.IOException;
16  import java.net.URL;
17  import java.util.ArrayList;
18  import java.util.HashMap;
19  import java.util.Iterator;
20  import java.util.List;
21  import nl.tudelft.simulation.dsol.experiment.TimeUnit;
22  import nl.tudelft.simulation.dsol.experiment.TimeUnitInterface;
23  import nl.tudelft.simulation.dsol.simulators.DEVDESSSimulatorInterface;
24  import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
25  import nl.tudelft.simulation.jstats.distributions.DistConstant;
26  import nl.tudelft.simulation.jstats.distributions.DistContinuous;
27  import nl.tudelft.simulation.jstats.distributions.DistExponential;
28  import nl.tudelft.simulation.jstats.distributions.DistNormal;
29  import nl.tudelft.simulation.jstats.distributions.DistTriangular;
30  import nl.tudelft.simulation.jstats.streams.Java2Random;
31  import nl.tudelft.simulation.jstats.streams.StreamInterface;
32  import nl.tudelft.simulation.language.d3.DirectedPoint;
33  import nl.tudelft.simulation.language.io.URLResource;
34  import nl.tudelft.simulation.logger.Logger;
35  import nl.tudelft.simulation.traffic.animation.ArcTrackAnimation;
36  import nl.tudelft.simulation.traffic.animation.StraightTrackAnimation;
37  import nl.tudelft.simulation.traffic.controlpoint.blocks.BlockTrafficLight;
38  import nl.tudelft.simulation.traffic.controlpoint.blocks.SwitchBlockTrafficLight;
39  import nl.tudelft.simulation.traffic.controlpoint.blocks.VirtualSwitchBlock;
40  import nl.tudelft.simulation.traffic.controlpoint.real.RemoveControlPoint;
41  import nl.tudelft.simulation.traffic.controlpoint.real.SpeedSign;
42  import nl.tudelft.simulation.traffic.controlpoint.real.StopSignInterface;
43  import nl.tudelft.simulation.traffic.controlpoint.real.TrafficLight;
44  import nl.tudelft.simulation.traffic.station.Station;
45  import nl.tudelft.simulation.traffic.track.ArcTrack;
46  import nl.tudelft.simulation.traffic.track.ComplexTrackLink;
47  import nl.tudelft.simulation.traffic.track.SimpleTrackLink;
48  import nl.tudelft.simulation.traffic.track.StraightTrack;
49  import nl.tudelft.simulation.traffic.track.TrackInterface;
50  import nl.tudelft.simulation.traffic.track.TrackLinkInterface;
51  import nl.tudelft.simulation.traffic.track.VirtualTrack;
52  import nl.tudelft.simulation.traffic.track.util.TrackProgression;
53  import nl.tudelft.simulation.traffic.vehicle.AccelerationProfile;
54  import nl.tudelft.simulation.traffic.vehicle.DecelerationProfile;
55  import nl.tudelft.simulation.traffic.vehicle.VehicleControl;
56  import nl.tudelft.simulation.traffic.vehicle.VehicleControlInterface;
57  import nl.tudelft.simulation.traffic.vehicle.VehiclePhysical;
58  import nl.tudelft.simulation.traffic.vehicle.VehiclePhysicalInterface;
59  import nl.tudelft.simulation.traffic.vehicle.VehicleType;
60  import nl.tudelft.simulation.xml.AbstractXMLParser;
61  import nl.tudelft.simulation.xml.language.ColorParser;
62  import nl.tudelft.simulation.xml.language.LocationParser;
63  import org.jdom.Element;
64  
65  /***
66   * <br>
67   * (c) copyright 2003-2004 <a href="http://www.simulation.tudelft.nl">Delft
68   * University of Technology </a>, the Netherlands. <br>
69   * See for project information <a href="http://www.simulation.tudelft.nl">
70   * www.simulation.tudelft.nl </a> <br>
71   * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
72   * License (GPL) </a>, no warranty <br>
73   * 
74   * @version May 31, 2004 <br>
75   * @author <a
76   * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
77   * Verbraeck </a>
78   */
79  public class InfraFileXMLParser extends AbstractXMLParser
80  {
81      /*** the default schema file */
82      public static final URL INFRAFILE_SCHEMA = URLResource
83              .getResource("/infrafile.xsd");
84  
85      /*** the map of link names to link elements */
86      private HashMap linkMap = new HashMap();
87  
88      /*** the map of track names to track elements */
89      private HashMap trackMap = new HashMap();
90  
91      /*** the map of vehicle types */
92      private HashMap vehicleTypeMap = new HashMap();
93  
94      /*** the simulator */
95      private DEVSSimulatorInterface simulator;
96  
97      /*** the width of the rails in meters */
98      private double railwidth = 1.48;
99  
100     /*** the stream to use in random values */
101     private static StreamInterface stream = new Java2Random();
102 
103     /***
104      * @param url
105      * @param schema
106      * @param schemaNamespace
107      * @param validateSchema
108      * @param simulator
109      * @throws Exception
110      */
111     public InfraFileXMLParser(final URL url, final URL schema,
112             final String schemaNamespace, final boolean validateSchema,
113             final DEVSSimulatorInterface simulator) throws Exception
114     {
115         super(url, schema, schemaNamespace, validateSchema);
116         this.simulator = simulator;
117         Element rootElement = parse();
118         parse(rootElement);
119     }
120 
121     /***
122      * @param url
123      * @param schema
124      * @param schemaNamespace
125      * @param validateSchema
126      * @param simulator
127      * @param linkMap
128      * @param trackMap
129      * @throws Exception
130      */
131     public InfraFileXMLParser(final URL url, final URL schema,
132             final String schemaNamespace, final boolean validateSchema,
133             final DEVSSimulatorInterface simulator, final HashMap linkMap,
134             final HashMap trackMap) throws Exception
135     {
136         super(url, schema, schemaNamespace, validateSchema);
137         this.simulator = simulator;
138         this.linkMap = new HashMap(linkMap);
139         this.trackMap = new HashMap(trackMap);
140         Element rootElement = parse();
141         parse(rootElement);
142     }
143 
144     /***
145      * parses an infrafile URL
146      * 
147      * @param xmlMapFileElement
148      * @throws Exception on parse exception
149      */
150     protected void parse(final Element xmlMapFileElement) throws Exception
151     {
152         try
153         {
154             // the links
155             Element links = xmlMapFileElement.getChild("links");
156             if (links == null)
157                 System.err.println("links element not found...");
158             else
159             {
160                 java.util.List linkElements = links.getChildren("link");
161                 for (Iterator iterator = linkElements.iterator(); iterator
162                         .hasNext();)
163                 {
164                     Element linkElement = (Element) iterator.next();
165                     parseLink(linkElement);
166                 }
167             }
168             // the tracks
169             Element tracks = xmlMapFileElement.getChild("tracks");
170             if (tracks == null)
171                 System.err.println("tracks element not found...");
172             else
173             {
174                 java.util.List trackElements = tracks.getChildren("track");
175                 for (Iterator iterator = trackElements.iterator(); iterator
176                         .hasNext();)
177                 {
178                     Element trackElement = (Element) iterator.next();
179                     parseTrack(trackElement).toString();
180                 }
181             }
182             // the active successors
183             Element successors = xmlMapFileElement.getChild("activeSuccessors");
184             if (successors == null)
185                 System.err.println("activeSuccessors element not found...");
186             else
187             {
188                 java.util.List successorElements = successors
189                         .getChildren("successor");
190                 for (Iterator iterator = successorElements.iterator(); iterator
191                         .hasNext();)
192                 {
193                     Element successorElement = (Element) iterator.next();
194                     parseSuccessor(successorElement);
195                 }
196             }
197             //stations
198             Element stations = xmlMapFileElement.getChild("stations");
199             if (stations != null)
200             {
201                 java.util.List stationElements = stations
202                         .getChildren("station");
203                 for (Iterator iterator = stationElements.iterator(); iterator
204                         .hasNext();)
205                 {
206                     Element stationElement = (Element) iterator.next();
207                     parseStation(stationElement);
208                 }
209             }
210             // the signals
211             Element signals = xmlMapFileElement.getChild("signals");
212             if (signals != null)
213             {
214                 java.util.List speedSignElements = signals
215                         .getChildren("speedSign");
216                 for (Iterator iterator = speedSignElements.iterator(); iterator
217                         .hasNext();)
218                 {
219                     Element speedSignElement = (Element) iterator.next();
220                     parseSpeedSign(speedSignElement);
221                 }
222                 java.util.List trafficLightRandomElements = signals
223                         .getChildren("trafficLightRandom");
224                 for (Iterator iterator = trafficLightRandomElements.iterator(); iterator
225                         .hasNext();)
226                 {
227                     Element trafficLightRandomElement = (Element) iterator
228                             .next();
229                     parseTrafficLightRandom(trafficLightRandomElement);
230                 }
231                 java.util.List blockTrafficLightElements = signals
232                         .getChildren("blockTrafficLight");
233                 for (Iterator iterator = blockTrafficLightElements.iterator(); iterator
234                         .hasNext();)
235                 {
236                     Element blockTrafficLightElement = (Element) iterator
237                             .next();
238                     parseBlockTrafficLight(blockTrafficLightElement);
239                 }
240                 java.util.List switchBlockElements = signals
241                         .getChildren("switchBlock");
242                 for (Iterator iterator = switchBlockElements.iterator(); iterator
243                         .hasNext();)
244                 {
245                     Element switchBlockElement = (Element) iterator.next();
246                     parseSwitchBlock(switchBlockElement);
247                 }
248             }
249             // the vehicle types
250             Element vehicleTypes = xmlMapFileElement.getChild("vehicleTypes");
251             if (vehicleTypes == null)
252                 System.err.println("vehicleTypes element not found...");
253             else
254             {
255                 java.util.List vehicleTypesElements = vehicleTypes
256                         .getChildren("vehicleType");
257                 for (Iterator iterator = vehicleTypesElements.iterator(); iterator
258                         .hasNext();)
259                 {
260                     Element vehicleTypeElement = (Element) iterator.next();
261                     parseVehicleType(vehicleTypeElement);
262                 }
263             }
264             // the vehicles
265             /********************************************************************
266              * Element vehicles = xmlMapFileElement.getChild("vehicles"); if
267              * (vehicles == null) System.err.println("vehicles element not
268              * found..."); else { java.util.List vehiclesElements = vehicles
269              * .getChildren("vehicle"); for (Iterator iterator =
270              * vehiclesElements.iterator(); iterator .hasNext();) { Element
271              * vehicleElement = (Element) iterator.next();
272              * parseVehicle(vehicleElement); } }
273              ******************************************************************/
274             // the generated vehicles
275             Element genVehicles = xmlMapFileElement.getChild("genVehicles");
276             if (genVehicles == null)
277                 System.out.println("genVehicles element not found...");
278             else
279             {
280                 java.util.List genVehiclesElements = genVehicles
281                         .getChildren("genVehicle");
282                 for (Iterator iterator = genVehiclesElements.iterator(); iterator
283                         .hasNext();)
284                 {
285                     Element genVehicleElement = (Element) iterator.next();
286                     parseGenVehicle(genVehicleElement);
287                 }
288                 java.util.List delVehiclesElements = genVehicles
289                         .getChildren("delVehicle");
290                 for (Iterator iterator = delVehiclesElements.iterator(); iterator
291                         .hasNext();)
292                 {
293                     Element delVehicleElement = (Element) iterator.next();
294                     parseDelVehicle(delVehicleElement);
295                 }
296             }
297         } catch (Exception exception)
298         {
299             throw exception;
300         }
301     }
302 
303     /***
304      * parses a xml-element representing a (dx, dy) animation offset
305      * 
306      * @param element The j-dom element
307      * @return Point2D
308      * @throws IOException
309      */
310     private Point2D parseAnimationOffset(final Element element)
311             throws IOException
312     {
313         try
314         {
315             double dx = new Double(element.getChildText("dx")).doubleValue();
316             double dy = new Double(element.getChildText("dy")).doubleValue();
317             return new Point2D.Double(dx, dy);
318         } catch (Exception exception)
319         {
320             throw new IOException(exception.getMessage());
321         }
322     }
323 
324     /***
325      * parses a xml-element representing a time value with a time unit
326      * 
327      * @param element The j-dom element
328      * @return the units on the simulator
329      * @throws IOException
330      */
331     private double parseTimeUnit(final Element element) throws IOException
332     {
333         try
334         {
335             double value = new Double(element.getChildText("value"))
336                     .doubleValue();
337             String unit = element.getChildText("unit");
338             if ("second".equals(unit))
339                 return TimeUnit.convert(value, TimeUnitInterface.SECOND,
340                         this.simulator);
341             else if ("minute".equals(unit))
342                 return TimeUnit.convert(value, TimeUnitInterface.MINUTE,
343                         this.simulator);
344             else if ("hour".equals(unit))
345                 return TimeUnit.convert(value, TimeUnitInterface.HOUR,
346                         this.simulator);
347             else
348                 throw new Exception("Unknown time unit " + unit);
349         } catch (Exception exception)
350         {
351             throw new IOException(exception.getMessage());
352         }
353     }
354 
355     /***
356      * parses a xml-element representing a time value with a speed unit
357      * 
358      * @param element The j-dom element
359      * @return the units on the simulator
360      * @throws IOException
361      */
362     private double parseSpeedUnit(final Element element) throws IOException
363     {
364         try
365         {
366             double value = new Double(element.getChildText("value"))
367                     .doubleValue();
368             String unit = element.getChildText("unit");
369             if ("mps".equals(unit))
370                 return value
371                         / TimeUnit.convert(1, TimeUnitInterface.SECOND,
372                                 this.simulator);
373             else if ("kmph".equals(unit))
374                 return 1000.0
375                         * value
376                         / TimeUnit.convert(1, TimeUnitInterface.HOUR,
377                                 this.simulator);
378             else
379                 throw new Exception("Unknown speed unit " + unit);
380         } catch (Exception exception)
381         {
382             throw new IOException(exception.getMessage());
383         }
384     }
385 
386     /***
387      * parses a xml-element representing a distribution function for a time
388      * value
389      * 
390      * @param element The j-dom element
391      * @return the units on the simulator
392      * @throws IOException
393      */
394     private DistContinuous parseContinuousTimeDistribution(final Element element)
395             throws IOException
396     {
397         try
398         {
399             String streamId = element.getChildText("stream");
400             StreamInterface stream = this.simulator.getReplication().getStream(
401                     streamId);
402             if (stream == null)
403                 stream = new Java2Random();
404             if (element.getChild("triangular") != null)
405             {
406                 Element distribution = element.getChild("triangular");
407                 double a = new Double(parseTimeUnit(distribution.getChild("a")))
408                         .doubleValue();
409                 double b = new Double(parseTimeUnit(distribution.getChild("b")))
410                         .doubleValue();
411                 double c = new Double(parseTimeUnit(distribution.getChild("c")))
412                         .doubleValue();
413                 return new DistTriangular(stream, a, b, c);
414             } else if (element.getChild("normal") != null)
415             {
416                 Element distribution = element.getChild("normal");
417                 double mean = new Double(parseTimeUnit(distribution
418                         .getChild("mean"))).doubleValue();
419                 double stdev = new Double(parseTimeUnit(distribution
420                         .getChild("stdev"))).doubleValue();
421                 return new DistNormal(stream, mean, stdev);
422             } else if (element.getChild("exponential") != null)
423             {
424                 Element distribution = element.getChild("exponential");
425                 double lambda = new Double(parseTimeUnit(distribution
426                         .getChild("lambda"))).doubleValue();
427                 return new DistExponential(stream, lambda);
428             } else if (element.getChild("constant") != null)
429             {
430                 Element distribution = element.getChild("constant");
431                 double c = new Double(parseTimeUnit(distribution.getChild("c")))
432                         .doubleValue();
433                 return new DistConstant(stream, c);
434             } else
435                 throw new Exception("Unknown distribution in "
436                         + element.getName());
437         } catch (Exception exception)
438         {
439             throw new IOException(exception.getMessage());
440         }
441     }
442 
443     /***
444      * parses a xml-element representing a Link
445      * 
446      * @param element The j-dom element
447      * @return the Link
448      * @throws IOException
449      */
450     private TrackLinkInterface parseLink(final Element element)
451             throws IOException
452     {
453         DirectedPoint location = new DirectedPoint();
454         String name = "";
455         try
456         {
457             name = element.getChildText("name");
458             location = LocationParser.parseLocation(element
459                     .getChild("location"));
460             boolean simple = "simple".equals(element.getChildText("type"));
461             TrackLinkInterface link;
462             if (simple)
463                 link = new SimpleTrackLink(name, location);
464             else
465                 link = new ComplexTrackLink(name, location);
466             this.linkMap.put(name, link);
467             Logger.finer(this, "parseLink", link.toString());
468             return link;
469         } catch (Exception exception)
470         {
471             exception.printStackTrace();
472             throw new IOException(exception.getMessage());
473         }
474     }
475 
476     /***
477      * parses a xml-element representing a Track
478      * 
479      * @param element The j-dom element
480      * @return Track of element
481      * @throws IOException
482      */
483     private TrackInterface parseTrack(final Element element) throws IOException
484     {
485         try
486         {
487             String name = element.getChildText("name");
488             String startLinkString = element.getChildText("startLink");
489             TrackLinkInterface startLink = (TrackLinkInterface) this.linkMap
490                     .get(startLinkString);
491             if (startLink == null)
492             {
493                 throw new Exception("Track " + name + ": start link "
494                         + startLinkString + " not defined");
495             }
496             String endLinkString = element.getChildText("endLink");
497             TrackLinkInterface endLink = (TrackLinkInterface) this.linkMap
498                     .get(endLinkString);
499             if (endLink == null)
500             {
501                 throw new Exception("Track " + name + ": end link "
502                         + endLinkString + " not defined");
503             }
504             String type = element.getChildText("type");
505             if ("straight".equals(type))
506             {
507                 TrackInterface track = new StraightTrack(name, startLink,
508                         endLink);
509                 new StraightTrackAnimation(track, this.simulator,
510                         this.railwidth);
511                 this.trackMap.put(name, track);
512                 Logger.finer(this, "parseTrack[straight]", track.toString());
513                 return track;
514             } else if ("arc".equals(type))
515             {
516                 double radius = new Double(element.getChildText("radius"))
517                         .doubleValue();
518                 ArcTrack track = new ArcTrack(name, startLink, endLink, radius);
519                 new ArcTrackAnimation(track, this.simulator, this.railwidth);
520                 this.trackMap.put(name, track);
521                 Logger.finer(this, "parseTrack[arc]", track.toString());
522                 return track;
523             } else if ("virtual".equals(type))
524             {
525                 TrackInterface track = new VirtualTrack(name, startLink,
526                         endLink);
527                 this.trackMap.put(name, track);
528                 Logger.finer(this, "parseTrack[virtual]", track.toString());
529                 return track;
530             } else
531             {
532                 throw new Exception("Track " + name + ": type " + type
533                         + " not supported yet");
534             }
535         } catch (Exception exception)
536         {
537             exception.printStackTrace();
538             throw new IOException(exception.getMessage());
539         }
540     }
541 
542     /***
543      * parses a xml-element representing a Successor
544      * 
545      * @param element The j-dom element
546      * @throws IOException
547      */
548     private void parseSuccessor(final Element element) throws IOException
549     {
550         try
551         {
552             String linkString = element.getChildText("link");
553             TrackLinkInterface link = (TrackLinkInterface) this.linkMap
554                     .get(linkString);
555             if (link == null)
556             {
557                 throw new Exception("Successor: link " + link + " not defined");
558             }
559             String startTrackString = element.getChildText("startTrack");
560             TrackInterface startTrack = (TrackInterface) this.trackMap
561                     .get(startTrackString);
562             if (startTrack == null)
563             {
564                 throw new Exception("Successor: start track "
565                         + startTrackString + " not defined");
566             }
567             if (!link.equals(startTrack.getEndLink()))
568             {
569                 throw new Exception("Successor: link " + link
570                         + " not the end link of track " + startTrackString);
571             }
572             String nextTrackString = element.getChildText("nextTrack");
573             TrackInterface nextTrack = (TrackInterface) this.trackMap
574                     .get(nextTrackString);
575             if (nextTrack == null)
576             {
577                 throw new Exception("Successor: next track " + nextTrackString
578                         + " not defined");
579             }
580             if (!link.equals(nextTrack.getStartLink()))
581             {
582                 throw new Exception("Successor: link " + link
583                         + " not the start link of track " + nextTrackString);
584             }
585             boolean active = Boolean.valueOf(element.getChildText("active"))
586                     .booleanValue();
587             startTrack.getEndLink().setActiveSuccessor(startTrack, nextTrack);
588             Logger.finer(this, "parseSuccessor", startTrack.toString() + "-"
589                     + nextTrack.toString());
590             if (active)
591             {
592                 link.setActiveSuccessor(startTrack, nextTrack);
593             }
594         } catch (Exception exception)
595         {
596             exception.printStackTrace();
597             throw new IOException(exception.getMessage());
598         }
599     }
600 
601     /***
602      * @param track
603      * @param progression
604      * @return the TrackProgression
605      */
606     private TrackProgression correctedTrackProgression(
607             final TrackInterface track, final double progression)
608     {
609         List tpl = track.calculateTrackProgressionListAll(progression);
610         if (tpl.size() == 1)
611         {
612             return (TrackProgression) tpl.get(0);
613         }
614         Logger.severe(this, "correctedTrackProgression",
615                 "not one corrected location for track " + track
616                         + ", progression " + progression);
617         System.out.println();
618         return new TrackProgression(track, progression);
619     }
620 
621     /***
622      * @param element
623      * @throws IOException
624      */
625     private void parseStation(final Element element) throws IOException
626     {
627         try
628         {
629             String stationName = element.getChildText("stationName");
630             String stationCode = element.getChildText("stationCode");
631             String stationCompanyCode = element
632                     .getChildText("stationCompanyCode");
633             String startTrackString = element.getChildText("startTrack");
634             TrackInterface startTrack = (TrackInterface) this.trackMap
635                     .get(startTrackString);
636             if (startTrack == null)
637             {
638                 throw new Exception("Station: start track " + startTrackString
639                         + "not defined");
640             }
641             double stationProgression = new Double(element
642                     .getChildText("progression")).doubleValue();
643             TrackProgression tp = correctedTrackProgression(startTrack,
644                     stationProgression);
645             double requestDistance = new Double(element
646                     .getChildText("requestDistance")).doubleValue();
647             double stationLength = new Double(element
648                     .getChildText("stationLength")).doubleValue();
649             double stoppingPlaceLength = new Double(element
650                     .getChildText("stoppingPlaceLength")).doubleValue();
651             double haltingTime = new Double(element.getChildText("haltingTime"))
652                     .doubleValue();
653             String platformSide = element.getChildText("platformSide");
654             new Station(stationName, stationCode, stationCompanyCode, tp
655                     .getTrack(), tp.getProgression(), requestDistance,
656                     stationLength, stoppingPlaceLength, TimeUnit.convert(
657                             haltingTime, TimeUnitInterface.SECOND,
658                             this.simulator), platformSide, this.simulator);
659         } catch (Exception exception)
660         {
661             exception.printStackTrace();
662             throw new IOException(exception.getMessage());
663         }
664     }
665 
666     /***
667      * parses a xml-element representing a SpeedSign
668      * 
669      * @param element The j-dom element
670      * @throws IOException
671      */
672     private void parseSpeedSign(final Element element) throws IOException
673     {
674         try
675         {
676             String name = element.getChildText("name");
677             String trackString = element.getChildText("track");
678             TrackInterface track = (TrackInterface) this.trackMap
679                     .get(trackString);
680             if (track == null)
681             {
682                 throw new Exception("parseSpeedSign : track " + trackString
683                         + " not defined");
684             }
685             double progression = new Double(element.getChildText("progression"))
686                     .doubleValue();
687             TrackProgression tp = correctedTrackProgression(track, progression);
688             double visibleDistance = new Double(element
689                     .getChildText("visibleDistance")).doubleValue();
690             Element speedLimit = element.getChild("speedLimit");
691             double speedLimitValue = parseSpeedUnit(speedLimit);
692             String speedLimitText = speedLimit.getChildText("text");
693             Point2D animationOffset = parseAnimationOffset(element
694                     .getChild("animationOffset"));
695             Color backgroundColor = ColorParser.parseColor(element
696                     .getChild("backgroundColor"));
697             Color textColor = ColorParser.parseColor(element
698                     .getChild("textColor"));
699             Color lineColor = ColorParser.parseColor(element
700                     .getChild("lineColor"));
701             new SpeedSign(name, tp.getTrack(), tp.getProgression(),
702                     visibleDistance, speedLimitValue, this.simulator,
703                     animationOffset.getX(), animationOffset.getY(),
704                     speedLimitText, backgroundColor, textColor, lineColor);
705             Logger.finer(this, "parseSpeedSign", track.toString() + ":" + name);
706         } catch (Exception exception)
707         {
708             exception.printStackTrace();
709             throw new IOException(exception.getMessage());
710         }
711     }
712 
713     /***
714      * parses a xml-element representing a TrafficLightRandom
715      * 
716      * @param element The j-dom element
717      * @throws IOException
718      */
719     private void parseTrafficLightRandom(final Element element)
720             throws IOException
721     {
722         try
723         {
724             String name = element.getChildText("name");
725             String trackString = element.getChildText("track");
726             TrackInterface track = (TrackInterface) this.trackMap
727                     .get(trackString);
728             if (track == null)
729             {
730                 throw new Exception("parseTrafficLightRandom : track "
731                         + trackString + " not defined");
732             }
733             double progression = new Double(element.getChildText("progression"))
734                     .doubleValue();
735             TrackProgression tp = correctedTrackProgression(track, progression);
736             double visibleDistance = new Double(element
737                     .getChildText("visibleDistance")).doubleValue();
738             double timeGreen = new Double(element.getChildText("timeGreen"))
739                     .doubleValue();
740             double timeRed = new Double(element.getChildText("timeRed"))
741                     .doubleValue();
742             boolean initialGreen = Boolean.valueOf(
743                     element.getChildText("initialGreen")).booleanValue();
744             String status;
745             if (initialGreen)
746                 status = StopSignInterface.CONTINUE;
747             else
748                 status = StopSignInterface.STOP;
749             Point2D animationOffset = parseAnimationOffset(element
750                     .getChild("animationOffset"));
751             new TrafficLight(name, tp.getProgression(), visibleDistance, tp
752                     .getTrack(), new DistExponential(stream, timeGreen),
753                     new DistExponential(stream, timeRed), status,
754                     this.simulator, animationOffset.getX(), animationOffset
755                             .getY());
756             Logger.finer(this, "parseTrafficLightRandom", track.toString()
757                     + ":" + name);
758         } catch (Exception exception)
759         {
760             exception.printStackTrace();
761             throw new IOException(exception.getMessage());
762         }
763     }
764 
765     /***
766      * parses a xml-element representing a AbsoluteBlockTrafficLight
767      * 
768      * @param element The j-dom element
769      * @throws IOException
770      */
771     private void parseBlockTrafficLight(final Element element)
772             throws IOException
773     {
774         try
775         {
776             String name = element.getChildText("name");
777             String trackString = element.getChildText("track");
778             TrackInterface track = (TrackInterface) this.trackMap
779                     .get(trackString);
780             if (track == null)
781             {
782                 throw new Exception("parseBlockTrafficLight : track "
783                         + trackString + " not defined");
784             }
785             double progression = new Double(element.getChildText("progression"))
786                     .doubleValue();
787             TrackProgression tp = correctedTrackProgression(track, progression);
788             double visibleDistance = new Double(element
789                     .getChildText("visibleDistance")).doubleValue();
790             double distanceRed = new Double(element.getChildText("distanceRed"))
791                     .doubleValue();
792             double distanceYellow = new Double(element
793                     .getChildText("distanceYellow")).doubleValue();
794             double distanceGreen = new Double(element
795                     .getChildText("distanceGreen")).doubleValue();
796             Point2D animationOffset = parseAnimationOffset(element
797                     .getChild("animationOffset"));
798             new BlockTrafficLight(name, tp.getTrack(), tp.getProgression(),
799                     visibleDistance, distanceRed, distanceYellow,
800                     distanceGreen, this.simulator, animationOffset.getX(),
801                     animationOffset.getY());
802             Logger.finer(this, "parseBlockTrafficLight", track.toString() + ":"
803                     + name);
804         } catch (Exception exception)
805         {
806             exception.printStackTrace();
807             throw new IOException(exception.getMessage());
808         }
809     }
810 
811     /***
812      * parses a xml-element representing a VirtualSwitchBlock with
813      * SwitchBlockTrafficLights
814      * 
815      * @param element The j-dom element
816      * @throws IOException
817      */
818     private void parseSwitchBlock(final Element element) throws IOException
819     {
820         try
821         {
822             String name = element.getChildText("name");
823             DistContinuous switchTime = parseContinuousTimeDistribution(element
824                     .getChild("switchTime"));
825             System.out.println("switchBlock = " + name + " switchTime = "
826                     + switchTime);
827             VirtualSwitchBlock switchBlock = new VirtualSwitchBlock(name,
828                     this.simulator, switchTime);
829             java.util.List switchBlockTrafficLightElements = element
830                     .getChildren("switchBlockTrafficLight");
831             for (Iterator iterator = switchBlockTrafficLightElements.iterator(); iterator
832                     .hasNext();)
833             {
834                 Element switchBlockTrafficLightElement = (Element) iterator
835                         .next();
836                 parseSwitchBlockTrafficLight(switchBlock,
837                         switchBlockTrafficLightElement);
838             }
839         } catch (Exception exception)
840         {
841             exception.printStackTrace();
842             throw new IOException(exception.getMessage());
843         }
844     }
845 
846     /***
847      * parses a xml-element representing a AbsoluteBlockTrafficLight
848      * 
849      * @param switchBlock
850      * @param element The j-dom element
851      * @throws IOException
852      */
853     private void parseSwitchBlockTrafficLight(
854             final VirtualSwitchBlock switchBlock, final Element element)
855             throws IOException
856     {
857         try
858         {
859             String name = element.getChildText("name");
860             String trackString = element.getChildText("track");
861             TrackInterface track = (TrackInterface) this.trackMap
862                     .get(trackString);
863             if (track == null)
864             {
865                 throw new Exception("parseSwitchBlockTrafficLight : track "
866                         + trackString + " not defined");
867             }
868             double progression = new Double(element.getChildText("progression"))
869                     .doubleValue();
870             TrackProgression tp = correctedTrackProgression(track, progression);
871             double visibleDistance = new Double(element
872                     .getChildText("visibleDistance")).doubleValue();
873             double distanceRequest = new Double(element
874                     .getChildText("distanceRequest")).doubleValue();
875             double distanceRed = new Double(element.getChildText("distanceRed"))
876                     .doubleValue();
877             Point2D animationOffset = parseAnimationOffset(element
878                     .getChild("animationOffset"));
879             SwitchBlockTrafficLight sbtl = new SwitchBlockTrafficLight(name, tp
880                     .getTrack(), tp.getProgression(), switchBlock,
881                     visibleDistance, distanceRequest, distanceRed,
882                     this.simulator, animationOffset.getX(), animationOffset
883                             .getY());
884             // get the switch settings - if needed
885             Element switchSettings = element.getChild("switchSettings");
886             java.util.List switchSettingsElements = switchSettings
887                     .getChildren("switchSetting");
888             if (switchSettingsElements != null)
889             {
890                 for (Iterator iterator = switchSettingsElements.iterator(); iterator
891                         .hasNext();)
892                 {
893                     Element switchSettingElement = (Element) iterator.next();
894                     parseSwitchSetting(sbtl, switchSettingElement);
895                 }
896             }
897             Logger.finer(this, "parseSwitchBlockTrafficLight", track.toString()
898                     + ":" + name);
899         } catch (Exception exception)
900         {
901             exception.printStackTrace();
902             throw new IOException(exception.getMessage());
903         }
904     }
905 
906     /***
907      * parses a xml-element representing a SwitchSetting within a
908      * AbsoluteBlockTrafficLight
909      * 
910      * @param sbtl the AbsoluteBlockTrafficLight
911      * @param element The j-dom element
912      * @throws IOException
913      */
914     private void parseSwitchSetting(final SwitchBlockTrafficLight sbtl,
915             final Element element) throws IOException
916     {
917         try
918         {
919             Element linesElement = element.getChild("lines");
920             List lineElementList = linesElement.getChildren("line");
921             List lineList = new ArrayList();
922             if (lineElementList != null)
923             {
924                 for (Iterator iterator = lineElementList.iterator(); iterator
925                         .hasNext();)
926                 {
927                     String lineText = ((Element) iterator.next()).getText();
928                     System.out.println("parser line: " + lineText);
929                     lineList.add(lineText);
930                 }
931             }
932             Element successor = element.getChild("successor");
933             String fromTrackStr = successor.getChildText("fromTrack");
934             TrackInterface fromTrack = (TrackInterface) this.trackMap
935                     .get(fromTrackStr);
936             if (fromTrack == null)
937             {
938                 throw new Exception("parseSwitchSetting: fromTrack "
939                         + fromTrackStr + " not defined");
940             }
941             TrackLinkInterface link = fromTrack.getEndLink();
942             String toTrackStr = successor.getChildText("toTrack");
943             TrackInterface toTrack = (TrackInterface) this.trackMap
944                     .get(toTrackStr);
945             if (toTrack == null)
946             {
947                 throw new Exception("parseSwitchSetting: toTrack " + toTrackStr
948                         + " not defined");
949             }
950             if (!link.equals(toTrack.getStartLink()))
951             {
952                 throw new Exception("parseSwitchSetting: link " + link
953                         + " not the start link of track " + toTrackStr);
954             }
955             double distanceRelease = new Double(element
956                     .getChildText("distanceRelease")).doubleValue();
957             System.out.println("parser distanceRelease: " + distanceRelease);
958             ((VirtualSwitchBlock) sbtl.getVirtualBlock()).addSwitchDirection(
959                     sbtl, lineList, distanceRelease, fromTrack, toTrack);
960         } catch (Exception exception)
961         {
962             exception.printStackTrace();
963             throw new IOException(exception.getMessage());
964         }
965     }
966 
967     /***
968      * parses a xml-element representing a VehicleType
969      * 
970      * @param element The j-dom element
971      * @return Layer of element
972      * @throws IOException
973      */
974     private VehicleType parseVehicleType(final Element element)
975             throws IOException
976     {
977         String name = "";
978         try
979         {
980             VehicleType vehicleType = new VehicleType();
981             name = element.getChildText("name");
982             vehicleType.setName(name);
983             vehicleType.setLength(new Double(element.getChildText("length"))
984                     .doubleValue());
985             vehicleType.setWidth(new Double(element.getChildText("width"))
986                     .doubleValue());
987             double maxSpeed = new Double(element.getChildText("maxSpeed"))
988                     .doubleValue();
989             vehicleType.setVehicleMaximumSpeed(maxSpeed);
990             // the acceleration profile
991             AccelerationProfile accProfile = new AccelerationProfile(maxSpeed);
992             java.util.List accElements = element.getChildren("acceleration");
993             for (Iterator iterator = accElements.iterator(); iterator.hasNext();)
994             {
995                 Element accElement = (Element) iterator.next();
996                 double speed = new Double(accElement.getChildText("speed"))
997                         .doubleValue();
998                 double acc = new Double(accElement.getChildText("acc"))
999                         .doubleValue();
1000                 accProfile.setAccelerationFromSpeed(speed, acc);
1001             }
1002             vehicleType.setAccelerationProfile(accProfile);
1003             // the deceleration profile
1004             DecelerationProfile decProfile = new DecelerationProfile(maxSpeed);
1005             java.util.List decElements = element.getChildren("deceleration");
1006             for (Iterator iterator = decElements.iterator(); iterator.hasNext();)
1007             {
1008                 Element decElement = (Element) iterator.next();
1009                 double speed = new Double(decElement.getChildText("speed"))
1010                         .doubleValue();
1011                 double dec = new Double(decElement.getChildText("dec"))
1012                         .doubleValue();
1013                 decProfile.setDecelerationFromSpeed(speed, dec);
1014             }
1015             vehicleType.setDecelerationProfile(decProfile);
1016             //
1017             vehicleType.setColor(ColorParser.parseColor(element
1018                     .getChild("color")));
1019             // the segments -- if present
1020             Element segments = element.getChild("segments");
1021             if (segments != null)
1022             {
1023                 java.util.List segmentsElements = segments
1024                         .getChildren("segment");
1025                 for (Iterator iterator = segmentsElements.iterator(); iterator
1026                         .hasNext();)
1027                 {
1028                     Element segmentElement = (Element) iterator.next();
1029                     double front = new Double(segmentElement
1030                             .getChildText("front")).doubleValue();
1031                     double axle1 = new Double(segmentElement
1032                             .getChildText("axle1")).doubleValue();
1033                     double axle2 = new Double(segmentElement
1034                             .getChildText("axle2")).doubleValue();
1035                     double length = new Double(segmentElement
1036                             .getChildText("length")).doubleValue();
1037                     vehicleType.addSegment(front, axle1, axle2, length);
1038                 }
1039             }
1040             this.vehicleTypeMap.put(name, vehicleType);
1041             Logger.finer(this, "parseVehicleType", vehicleType.getName());
1042             System.out.println("parseVehicleType " + vehicleType.getName());
1043             return vehicleType;
1044         } catch (Exception exception)
1045         {
1046             exception.printStackTrace();
1047             throw new IOException(exception.getMessage());
1048         }
1049     }
1050 
1051     /***
1052      * parses a xml-element representing a Vehicle instance
1053      * 
1054      * @param element The j-dom element
1055      * @return Vehicle instance
1056      * @throws IOException
1057      */
1058     private VehicleControlInterface parseVehicle(final Element element)
1059             throws IOException
1060     {
1061         try
1062         {
1063             String type = element.getChildText("type");
1064             VehicleType vehicleType = (VehicleType) this.vehicleTypeMap
1065                     .get(type);
1066             if (vehicleType == null)
1067             {
1068                 throw new Exception("parseVehicle : vehicleType " + type
1069                         + " not defined");
1070             }
1071             String trackString = element.getChildText("track");
1072             TrackInterface track = (TrackInterface) this.trackMap
1073                     .get(trackString);
1074             if (track == null)
1075             {
1076                 throw new Exception("parseVehicle : track " + trackString
1077                         + " not defined");
1078             }
1079             double progression = new Double(element.getChildText("progression"))
1080                     .doubleValue();
1081             TrackProgression tp = correctedTrackProgression(track, progression);
1082             String line = element.getChildText("line");
1083             double maxSpeedStart = new Double(element
1084                     .getChildText("maxSpeedStart")).doubleValue();
1085             Logger.finer(this, "parseVehicle", vehicleType.getName()
1086                     + " track " + track);
1087             System.out.println("parseVehicle" + vehicleType.getName()
1088                     + " track " + track);
1089             VehicleControlInterface vehicleControl = new VehicleControl(line);
1090             VehiclePhysicalInterface vehiclePhysical = new VehiclePhysical(
1091                     vehicleType, vehicleControl, tp.getTrack(), tp
1092                             .getProgression(), maxSpeedStart,
1093                     (DEVDESSSimulatorInterface) this.simulator);
1094             vehiclePhysical.setVehicleControl(vehicleControl);
1095             vehicleControl.setVehiclePhysical(vehiclePhysical);
1096             // schedule driving at t=0
1097             this.simulator.scheduleEvent(0.0, this, vehicleControl,
1098                     "startDriving", new Object[]{});
1099             return vehicleControl;
1100         } catch (Exception exception)
1101         {
1102             exception.printStackTrace();
1103             throw new IOException(exception.getMessage());
1104         }
1105     }
1106 
1107     /***
1108      * parses a xml-element representing a Vehicle generator
1109      * 
1110      * @param element The j-dom element
1111      * @throws IOException
1112      */
1113     private void parseGenVehicle(final Element element) throws IOException
1114     {
1115         try
1116         {
1117             String type = element.getChildText("type");
1118             VehicleType vehicleType = (VehicleType) this.vehicleTypeMap
1119                     .get(type);
1120             if (vehicleType == null)
1121             {
1122                 throw new Exception("parseGenVehicle : vehicleType " + type
1123                         + " not defined");
1124             }
1125             String trackString = element.getChildText("track");
1126             TrackInterface track = (TrackInterface) this.trackMap
1127                     .get(trackString);
1128             if (track == null)
1129             {
1130                 throw new Exception("parseGenVehicle : track " + trackString
1131                         + " not defined");
1132             }
1133             double progression = new Double(element.getChildText("progression"))
1134                     .doubleValue();
1135             TrackProgression tp = correctedTrackProgression(track, progression);
1136             double firstGen = parseTimeUnit(element.getChild("firstGen"));
1137             double interval = parseTimeUnit(element.getChild("interval"));
1138             String line = element.getChildText("line");
1139             double maxSpeedStart = new Double(element
1140                     .getChildText("maxSpeedStart")).doubleValue();
1141             Logger.finer(this, "parseGenVehicle", vehicleType.getName()
1142                     + " track " + tp);
1143             System.out.println("parseGenVehicle" + vehicleType.getName()
1144                     + " track " + tp);
1145             Object[] args = new Object[]{tp.getTrack(),
1146                     new Double(tp.getProgression()), new Double(maxSpeedStart),
1147                     vehicleType, new Double(interval), line};
1148             this.simulator.scheduleEvent(firstGen, this, this, "genVehicle",
1149                     args);
1150         } catch (Exception exception)
1151         {
1152             exception.printStackTrace();
1153             throw new IOException(exception.getMessage());
1154         }
1155     }
1156 
1157     /***
1158      * @param track
1159      * @param progression
1160      * @param maxSpeedStart
1161      * @param vehicleType
1162      * @param interval
1163      * @param line
1164      * @throws Exception
1165      */
1166     protected void genVehicle(final TrackInterface track,
1167             final double progression, final double maxSpeedStart,
1168             final VehicleType vehicleType, double interval, String line)
1169             throws Exception
1170     {
1171         try
1172         {
1173             VehicleControlInterface vehicleControl = new VehicleControl(line);
1174             VehiclePhysicalInterface vehiclePhysical = new VehiclePhysical(
1175                     vehicleType, vehicleControl, track, progression,
1176                     maxSpeedStart, (DEVDESSSimulatorInterface) this.simulator);
1177             vehicleControl.setVehiclePhysical(vehiclePhysical);
1178             vehicleControl.startDriving();
1179             Object[] args = new Object[]{track, new Double(progression),
1180                     new Double(maxSpeedStart), vehicleType,
1181                     new Double(interval), line};
1182             this.simulator.scheduleEvent(interval, this, this, "genVehicle",
1183                     args);
1184         } catch (Exception exception)
1185         {
1186             exception.printStackTrace();
1187             throw new Exception(exception.getMessage());
1188         }
1189     }
1190 
1191     /***
1192      * parses a xml-element representing a Vehicle destroyer
1193      * 
1194      * @param element The j-dom element
1195      * @throws IOException
1196      */
1197     private void parseDelVehicle(final Element element) throws IOException
1198     {
1199         try
1200         {
1201             String trackString = element.getChildText("track");
1202             TrackInterface track = (TrackInterface) this.trackMap
1203                     .get(trackString);
1204             if (track == null)
1205             {
1206                 throw new Exception("parseDelVehicle : track " + trackString
1207                         + " not defined");
1208             }
1209             double progression = new Double(element.getChildText("progression"))
1210                     .doubleValue();
1211             TrackProgression tp = correctedTrackProgression(track, progression);
1212             new RemoveControlPoint(tp.getTrack(), tp.getProgression(),
1213                     this.simulator);
1214         } catch (Exception exception)
1215         {
1216             exception.printStackTrace();
1217             throw new IOException(exception.getMessage());
1218         }
1219     }
1220 }