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

Revision 103, 12.5 KB checked in by jtorres, 9 years ago (diff)

trunk/src/atmsdriver/ConsoleDriver.java: Created console driver for ATMSDriver, completed and very nice. Still need to apply correct vol/occ values to actually change the colors. Still need to write a JUnit test for it. trunk/src/atmsdriver/ATMSDriver.java: Refactored to run the console driver. ATMSDriver runs in thread, console driver runs, and they share the highways instance. Renamed NetworkLoader?.java to FEPLineLoader.java. trunk/src/atmsdriver/model/Highways.java: refactored loadHighways() method to conform to new undirected highway abstraction. trunk/src/atmsdriver/model/Station.java: added updateByDirection(DIRECTION dir) method and supporting utility methods. trunk/test/atmsdriver/model/LoadHighwaysTest.java: Conformed LoadHighways? test to new undirected highway abstraction. trunk/test/atmsdriver/model/StationTest.java: Conformed StationTest?.java to new changes - very minor stuff. Went through all model classes and changed any final privates with a getter method to final public, for good OOP practice and simplicity. Went through ALL FILES and commented everything very well. minor application custom configuration changes. Removed all .class or .o.d files from svn repository

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