Warning: Can't use blame annotator:
svn blame failed on trunk/src/atmsdriver/ConsoleDriver.java: ("Can't find a temporary directory: Internal error", 20014)

source: tmcsimulator/trunk/src/atmsdriver/ConsoleDriver.java @ 127

Revision 127, 15.2 KB checked in by jdalbey, 9 years ago (diff)

Station.java Enhance DOTCOLOR enum to have volume and occupancy fields. Minor changes to error messages in other files.

RevLine 
1package atmsdriver;
2
3import atmsdriver.model.Highways;
4import atmsdriver.model.Station.DIRECTION;
5import atmsdriver.model.Highway;
6import atmsdriver.model.Station;
7import java.io.FileInputStream;
8import java.util.ArrayList;
9import java.util.Arrays;
10import java.util.List;
11import java.util.Properties;
12import java.util.Scanner;
13import java.util.logging.Level;
14import java.util.logging.Logger;
15
16/**
17 * A console application to drive the ATMS Server.
18 *
19 * @author jdalbey, John A. Torres
20 * @version 10/11/2017
21 */
22public final class ConsoleDriver {
23    // highways model
24    private final Highways highways;
25   
26    // lists used for user input validation
27    private final List<Integer> routeNumInputList;
28    private final List<String> dotColorInputList;
29    /**
30     * Properties for the ConsoleDriver
31     */
32    private static Properties ConsoleDriverProperties;
33
34    /** Entry point for the application.
35     *
36     * @param args unused
37     */
38    public static void main(String[] args) {
39        try {
40            if (System.getProperty("ATMSDRIVER_PROPERTIES") != null) 
41            {
42                // Load properties of runtime parameters
43                if (!loadProperties()) 
44                {
45                    System.exit(0);
46                }       
47                // Create the Highway Model
48                Highways highways = new Highways(
49                    "config/vds_data/lds.txt",
50                    "config/vds_data/loop.txt",
51                    "config/vds_data/highwaysMeta.txt",
52                    ConsoleDriverProperties.getProperty(
53                        "FEPWriterHost"),
54                    Integer.parseInt(ConsoleDriverProperties.getProperty(
55                        "FEPWriterPort")));
56
57                // Construct the console driver using the highways model
58                ConsoleDriver driver = new ConsoleDriver(highways);
59                driver.runConsole();   
60            } else {
61                throw new Exception("ATMSDRIVER_PROPERTIES system property not defined.");
62            }
63        } catch (Exception e) {
64            Logger.getLogger("ConsoleDriver").logp(Level.SEVERE, "ConsoleDriver", "Main",
65                    "Error occured initializing application", e);
66            System.exit(-1);
67        }
68    }   
69    /**
70     * Load the properties file containing values for runtime parameters.
71     *
72     * @param propertiesFile
73     * @return
74     */
75    private static boolean loadProperties() 
76    {
77        // Load the properties file.
78        try {
79            ConsoleDriverProperties = new Properties();
80            ConsoleDriverProperties.load(new FileInputStream(System.getProperty("ATMSDRIVER_PROPERTIES")));
81        } catch (Exception e) {
82            Logger.getLogger("CosoleDriver").logp(Level.SEVERE, "ConsoleDriver",
83                    "Constructor", "Exception in reading properties file.", e);
84        }
85
86        return true;
87    }
88    /**
89     * Constructor. Sets the highways model and generates the input validation
90     * lists, and then runs the console driver application.
91     * @param highways
92     */
93    public ConsoleDriver(Highways highways) {
94        // set highways model
95        this.highways = highways;
96       
97        // set input validation lists
98        routeNumInputList = generateRouteNumInputList();
99        dotColorInputList = new ArrayList<>(Arrays.asList("R", "Y", "G"));       
100    }
101   
102    /**
103     * Generates the route number list, used for user input validation.
104     * @return list of route numbers.
105     */
106    private ArrayList<Integer> generateRouteNumInputList()
107    {
108        ArrayList<Integer> routeNums = new ArrayList<>();
109        // add the route number for each highway to the list
110        for(Highway hwy : highways.highways)
111        {
112            routeNums.add(hwy.routeNumber);
113        }
114        return routeNums;
115    }
116
117    /**
118     * Runs the console driver application.
119     */
120    public void runConsole() {
121        Scanner sc = new Scanner(System.in);
122        // Run continuously
123        while (true) {
124            // Get necessary values for colorization of highways
125            Integer routeNumber = getRouteNumber(sc);
126            DIRECTION direction = getDirection(sc, routeNumber);
127            Double postmile = getPostmile(sc, routeNumber, direction);
128            Integer range = getRange(sc, postmile);
129            DOTCOLOR dotcolor = getDotColor(sc);
130           
131            // apply colorization to highways
132            applyColorToHighwayStretch(routeNumber, direction, postmile, range, dotcolor);
133        }
134    }
135   
136    /**
137     * Applies specified color to the specified highway stretch. Route number and
138     * direction specify the highway. Postmile and range specify the stretch of
139     * specified highway. Dot color is the color to be applied to the stretch.
140     *
141     * @param routeNumber highway route number
142     * @param direction highway direction
143     * @param postmile origin postmile value
144     * @param range range from origin postmile
145     * @param dotColor the color to be applied to specified highway stretch
146     */
147    public void applyColorToHighwayStretch(Integer routeNumber, DIRECTION direction, 
148            Double postmile, Integer range, DOTCOLOR dotColor) {
149        System.out.println("Applying " + dotColor.name() + " dots to highway " 
150                + routeNumber + " " + direction.name() + " at postmile " 
151                + postmile + " with a range of " + range + " miles...");
152       
153        // Get the highway by route number
154        Highway highway = highways.getHighwayByRouteNumber(routeNumber);
155       
156        // start value for highway section, and end value for highway section
157        // by postmile
158        Double startPost;
159        Double endPost;
160       
161        // postmiles increase from s to n and w to e
162       
163        // if the direction is south or west
164        if(direction.equals(DIRECTION.SOUTH) || direction.equals(DIRECTION.WEST))
165        {
166            // add range value to startPost to get
167            // the end postmile value of the highway section
168            startPost = postmile;
169            endPost = postmile + range;
170           
171            // iterate through the stations, if within the specified highway
172            // stretch, update the station by direction and apply dot color
173            for(Station station : highway.stations)
174            {
175                if(station.postmile > startPost && station.postmile < endPost)
176                {
177                    station.updateByDirection(direction, dotColor);
178                }
179            }
180        }
181        // if the direction is north or east
182        else
183        {
184            //subtract range value from startPost
185            // to get the end postmile value of the highway section
186            startPost = postmile;
187            endPost = postmile - range;
188           
189            // iterate through the stations, if within the specified highway
190            // section, update the station by direction and apply dot color
191            for(Station station : highway.stations)
192            {
193                if(station.postmile < startPost && station.postmile > endPost)
194                {
195                    station.updateByDirection(direction, dotColor);
196                }
197            }
198        }
199        System.out.println("");
200        highways.writeToFEP();
201    }
202   
203    /**
204     * Gets the highway route number from user and validates the input.
205     *
206     * @param sc stdIn scanner
207     * @return highway route number
208     */
209    private Integer getRouteNumber(Scanner sc) {
210        Integer routeNum = null;
211        Boolean verified = false;
212       
213        // validation loop
214        while(!verified)
215        {
216            // Prints out available route numbers to user to select from
217            System.out.print("Available route numbers: [");
218            for(Integer rtNum : routeNumInputList)
219            {
220                System.out.print(rtNum.toString() + ", ");
221            }
222            System.out.print("]");
223            System.out.println("");
224           
225            // Prompt user to input a route number
226            System.out.println("Enter a route number: ");
227            routeNum = sc.nextInt();
228            System.out.println("");
229           
230            // validate the user's input
231            if(routeNumInputList.contains(routeNum))
232            {
233                verified = true;
234            }
235            else
236            {
237                System.out.println("Invalid route number, please re-enter: ");
238            }
239        }
240       
241        return routeNum;
242    }
243   
244    /**
245     * Gets the highway direction from the user and validates the input.
246     *
247     * @param sc stdIn scanner
248     * @return highway direction
249     */
250    private DIRECTION getDirection(Scanner sc, Integer routeNum) {
251        DIRECTION direction;
252        String directionInput = null;
253        Boolean verified = false;
254       
255        // validation loop
256        while(!verified)
257        {
258            // Get available directions for route
259            ArrayList<DIRECTION> availDirs = new ArrayList<>();
260            for(Station stn : highways.getHighwayByRouteNumber(routeNum).stations)
261            {
262                if(!availDirs.contains(stn.direction))
263                {
264                    availDirs.add(stn.direction);
265                }
266            }
267           
268            // prompt user for input
269            System.out.print("Available directions for highway " + routeNum + ": [");
270            for(DIRECTION dir : availDirs)
271            {
272                System.out.print(dir.getLetter() + ", ");
273            }
274            System.out.print("]");
275            System.out.println("");
276            System.out.println("Enter a direction:");
277            directionInput = sc.next().toUpperCase();
278            System.out.println("");
279           
280            // validate the user's input
281            if(availDirs.contains(DIRECTION.toDirection(directionInput)))
282            {
283                verified = true;
284            }
285            else
286            {
287                System.out.println("Invalid direction, please re-enter: ");
288            }
289        }
290       
291        return DIRECTION.toDirection(directionInput);
292    }
293   
294    /**
295     * Gets the starting/origin postmile value for the highway section from the
296     * user and validates the input.
297     *
298     * @param sc stdIn scanner
299     * @param routeNumber highway route number
300     * @param dir highway direction
301     * @return highway section start/origin postmile value
302     */
303    private Double getPostmile(Scanner sc, Integer routeNumber, DIRECTION dir) {
304        Double postmile = null;
305        Boolean verified = false;
306       
307        // validation loop
308        while(!verified)
309        {
310            // Get highway, and grab the floor and ceiling for postmile values
311            // from the highway stations to present to the user
312            Highway hwy = highways.getHighwayByRouteNumber(routeNumber);
313            Double floorPostmile = hwy.stations.get(0).postmile;
314            Double ceilPostmile = hwy.stations
315                    .get(hwy.stations.size() - 1).postmile;
316           
317            // present user with range of postmiles for given highway
318            System.out.println("Route " + hwy.routeNumber + " " + dir
319                    + " postmile range: [" + floorPostmile + ", " 
320                    + ceilPostmile + "]");
321           
322            // prompt user for postmile value
323            System.out.println("Enter a postmile value (Integer/Double): ");
324            postmile = sc.nextDouble();
325            System.out.println("");
326           
327            // validate user's input, ensures that the postmile is within given
328            // postmile range (floorPostmile, ceilPostmile)
329            if(postmile >= floorPostmile && postmile <= ceilPostmile)
330            {
331                verified = true;
332            }
333            else
334            {
335                System.out.println("Postmile must be within postmile range: [" + floorPostmile + ", " 
336                    + ceilPostmile + "] please re-enter: ");
337            }
338        }
339       
340        return postmile;
341    }
342   
343    /**
344     * Gets the range to extend the highway stretch from the start/origin postmile
345     * value from the user and validates the input.
346     *
347     * @param sc stdIn scanner
348     * @param postmile origin/start postmile value for highway stretch
349     * @return range value
350     */
351    private Integer getRange(Scanner sc, Double postmile) {
352        Integer range = null;
353        Boolean verified = false;
354       
355        // validation loop
356        while(!verified)
357        {
358            // prompt user for range value
359            System.out.println("Enter a range value (Integer):");
360            range = sc.nextInt();
361            System.out.println("");
362           
363            // range must be greater than or equal to 0
364            if(range >= 0)
365            {
366                verified = true;
367            }
368            else
369            {
370                System.out.println("Range must be >= 0");
371            }
372        }
373       
374        return range;
375    }
376
377    /**
378     * Gets the dot color from the user, to be applied to specified highway
379     * stretch and validates the user's input.
380     *
381     * @param sc stdIn scanner
382     * @return dot color to be applied to highway stretch
383     */
384    private DOTCOLOR getDotColor(Scanner sc) {
385        DOTCOLOR dotColor;
386        String dotColorInput = null;
387        Boolean verified = false;
388       
389        // validationloop
390        while(!verified)
391        {
392            // prompt user for color
393            System.out.println("Enter a dot color (G/Y/R):");
394            dotColorInput = sc.next();
395            System.out.println("");
396            // validate user's input
397            if(dotColorInputList.contains(dotColorInput))
398            {
399                verified = true;
400            }
401            else
402            {
403                System.out.println("Invalid dot color, please re-enter: ");
404            }
405        }
406       
407        return DOTCOLOR.toDotColor(dotColorInput);
408    }
409   
410    /**
411     * Enum for highway status dot colors. Each color has associated volume
412     * and occupancy constants.
413     *
414     * @author John A. Torres, jdalbey
415     * @version 10/11/2017
416     */
417    public static enum DOTCOLOR {
418
419        RED(10,10),
420        YELLOW(5,5),
421        GREEN(0,0);
422       
423        // All the first letters of the values, in order.
424        private static String allLetters = "RYG";
425       
426        private int vol;  /* volume */
427        private int occ;  /* occupancy */     
428       
429        private DOTCOLOR(int v, int o)
430        {
431            vol = v;
432            occ = o;
433        }
434        /**
435         * Return the first letter of this enum.
436         *
437         * @return String first letter of this enum.
438         */
439        public String getLetter() {
440            return this.toString().substring(0, 1);
441        }
442
443        public int volume()
444        {
445            return vol;
446        }
447        public int occupancy()
448        {
449            return occ;
450        }
451        /**
452         * Returns a dot color given its first character.
453         *
454         * @param letter the first character of a dot color
455         * @return dot color corresponding to letter
456         * @pre letter must be one of allLetters
457         */
458        public static DOTCOLOR toDotColor(String letter) {
459            return values()[allLetters.indexOf(letter.charAt(0))];
460        }
461    } 
462}
Note: See TracBrowser for help on using the repository browser.