// RoadNetwork.java import java.io.File; import java.io.FileNotFoundException; import java.util.LinkedList; import java.util.Scanner; // Utility classes class Errors { static void fatal( String message ) { System.err.println( "Fatal error: " + message ); System.exit( 1 ); } static void warning( String message ) { System.err.println( "Error: " + message ); } } // Simulation classes /** Roads are one-way streets linking intersections * @see Intersection */ class Road { private float travelTime; // measured in seconds private Intersection destination;// where road goes private Intersection source; // where road comes from // name of road is source-destination // initializer public Road( Scanner sc, LinkedList inters ) { // scan and process one road String sourceName = sc.next(); String dstName = sc.next(); // Bug: What if at end of file? What does sc.next do? source = RoadNetwork.findIntersection( sourceName ); destination = RoadNetwork.findIntersection( dstName ); if (source == null) { Errors.warning( "In road " + sourceName + " " + dstName + ", Intersection " + sourceName + " undefined" ); // note, object is created with a null source } if (destination == null) { Errors.warning( "In road " + sourceName + " " + dstName + ", Intersection " + dstName + " undefined" ); // note, object is created with a null destination } if (sc.hasNextFloat()) { travelTime = sc.nextFloat(); // Bug: What if it's negative } else { Errors.warning( "In road " + sourceName + " " + dstName + ", travel time not given" ); travelTime = 99.99; } String skip = sc.nextLine(); // Bug: What if more junk at end of line (skip not empty) } // other methods public String toString() { return ( "Road " + ( source != null ? source.name : "---" ) + " " + ( destination != null ? destination.name : "---" ) + " " + travelTime ); } } /** Intersections join roads * @see Road */ class Intersection { final String name; private LinkedList outgoing = new LinkedList (); private LinkedList incoming = new LinkedList (); // Bug: multiple types of intersections -- stoplight, 4-way etc // Bug: do I ever need to know about incoming roads? // initializer public Intersection( Scanner sc, LinkedList inters ) { // scan and process one intersection name = sc.next(); if (RoadNetwork.findIntersection( name ) != null) { Errors.warning( "Intersection " + name + " redefined." ); // Bug: Should we prevent creation of this object? } String skip = sc.nextLine(); // Bug: What if more junk at end of line (skip not empty) } // other methods public String toString() { return ( "Intersection " + name ); } } /** RoadNetwork is the main class that builds the whole model * @see Road * @see Intersection */ public class RoadNetwork { // the sets of all roads and all intersections static LinkedList roads = new LinkedList (); static LinkedList inters = new LinkedList (); /** Look up s in inters, find that Intersection if it exists * return null if not. */ public static Intersection findIntersection( String s ) { for (Intersection i: RoadNetwork.inters) { if (i.name.equals(s)) { return i; } } return null; } /** Initialize the road network by scanning its description */ static void initializeNetwork( Scanner sc ) { while (sc.hasNext()) { String command = sc.next(); if (("intersection".equals( command )) || ("i".equals( command ))) { inters.add( new Intersection( sc, inters ) ); } else if (("road".equals( command )) || ("r".equals( command ))) { roads.add( new Road( sc, inters ) ); } else { Errors.warning( "unknown command" ); // Bug: should we allow comments? } } } /** Print out the road network from the data structure */ static void printNetwork() { for (Intersection i:inters) { System.out.println( i.toString() ); } for (Road r:roads) { System.out.println( r.toString() ); } } /** Main program * @see initializeNetwork */ public static void main(String[] args) { try { if (args.length < 1) { Errors.fatal( "missing file name" ); } if (args.length > 1) { Errors.fatal( "too many arguments" ); } initializeNetwork( new Scanner(new File(args[0])) ); } catch (FileNotFoundException e) { Errors.fatal( "file not found: " + args[0] ); } printNetwork(); } }