package atmsdriver.model; import atmsdriver.NetworkLoader; import atmsdriver.model.Station.DIRECTION; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.net.Socket; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Observable; import java.util.Observer; import java.util.Scanner; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * * @author John A. Torres */ public class Highways implements Observer { final private ArrayList lines; final private String FEPHostName; final private int FEPPortNum; final private ArrayList highways; private Map> HiwayMap = new HashMap>(); // NEED FINISH final private ArrayList highways; public Highways(String ldsFileName, String loopsFileName, String highwayMetaFileName, String FEPHostName, int FEPPortNum) { /* lines = loadLines(highwayMetaFileName); System.out.println("SIZE: " + toXML().toCharArray().length); */ NetworkLoader ldr = new NetworkLoader(new File(ldsFileName), new File(loopsFileName)); this.lines = (ArrayList) ldr.getFEPLines(); this.FEPHostName = FEPHostName; this.FEPPortNum = FEPPortNum; this.highways = loadHighways(); //writeHighwaysMeta("hard.txt"); } public ArrayList getHighways() { return this.highways; } private ArrayList loadHighways() { System.out.println("Loading highways..."); // The list of highways to return ArrayList highways = new ArrayList(); Hashtable, ArrayList> highwayTable = new Hashtable<>(); for (FEPLine line : lines) { ArrayList lineStations = (ArrayList) line.getStations(); for(Station station : lineStations) { Integer hwyNum = station.getHighwayNumber(); DIRECTION dir = station.getDirection(); Hashtable check = new Hashtable<>(); check.put(hwyNum, dir); if(highwayTable.get(check) == null) { ArrayList stnList = new ArrayList<>(); stnList.add(station); Hashtable, ArrayList> newEntry = new Hashtable(); newEntry.put(check, stnList); highwayTable.putAll(newEntry); } else { highwayTable.get(check).add(station); } } } Set> hwyKeys = highwayTable.keySet(); for(Hashtable hwyKey : hwyKeys) { Enumeration hwyNumEnum = hwyKey.keys(); Integer hwyNum = hwyNumEnum.nextElement(); ArrayList hwyStations = highwayTable.get(hwyKey); DIRECTION hwyDir = hwyKey.get(hwyNum); Collections.sort(highwayTable.get(hwyKey)); System.out.println("Adding highway: " + hwyNum + " " + hwyDir.toString().charAt(0)); highways.add(new Highway(hwyNum, hwyStations)); } return highways; } /* private ArrayList loadLines(String highwayMetaFileName) { ArrayList lines = new ArrayList<>(); try { Scanner sc = new Scanner(new File(highwayMetaFileName)); String firstLine = sc.nextLine(); Scanner linesc = new Scanner(firstLine); int numLines = linesc.nextInt(); linesc.close(); for (int i = 0; i < numLines; i++) { System.out.println("CURR: " + i); lines.add(loadLine(sc)); } sc.close(); } catch (FileNotFoundException ex) { Logger.getLogger(Highways.class.getName()).log(Level.SEVERE, null, ex); } return lines; } private FEPLine loadLine(Scanner sc) { String line = sc.nextLine(); System.out.println(line); Scanner scline = new Scanner(line); int lineNum = scline.nextInt(); int count = scline.nextInt(); int numStations = scline.nextInt(); ArrayList stations = new ArrayList<>(); for (int i = 0; i < numStations; i++) { stations.add(loadStation(sc, lineNum)); } return new FEPLine(lineNum, stations, count); } private Station loadStation(Scanner sc, int lineNum) { String line = sc.nextLine(); System.out.println(line); Scanner scline = new Scanner(line); int ldsID = scline.nextInt(); int drop = scline.nextInt(); int fwy = scline.nextInt(); DIRECTION dir = DIRECTION.getEnum(scline.next()); double postmile = scline.nextDouble(); int numLoops = scline.nextInt(); String location = getStationLoc(line); ArrayList loops = new ArrayList<>(); for (int i = 0; i < numLoops; i++) { loops.add(loadLoop(sc)); } return new Station(lineNum, ldsID, drop, location, loops, fwy, dir, postmile); } private LoopDetector loadLoop(Scanner sc) { String line = sc.nextLine(); Scanner scline = new Scanner(line); int loopID = scline.nextInt(); int laneNum = scline.nextInt(); String loopLoc = getLoopLoc(line); // NEED GET LOOPLOC scline.close(); return new LoopDetector(loopID, loopLoc, laneNum); } private String getLoopLoc(String line) { Scanner sc = new Scanner(line); sc.nextInt(); sc.nextInt(); // GRABS FROM CURRENT TO END OF LINE sc.useDelimiter("\\z"); String loc = sc.next().trim(); sc.close(); return loc; } // Returns the loction given the whole line from the lookup file private String getStationLoc(String line) { Scanner scline = new Scanner(line); scline.nextInt(); scline.nextInt(); scline.nextInt(); scline.next(); scline.nextDouble(); scline.nextInt(); // GRABS FROM CURRENT TO END OF LINE scline.useDelimiter("\\z"); String loc = scline.next().trim(); scline.close(); return loc; } */ public void writeToFEP() { System.out.println(this.toXML().toCharArray().length); try { Socket sock = new Socket(FEPHostName, FEPPortNum); PrintWriter out = new PrintWriter(sock.getOutputStream(), true); out.println(this.toXML()); sock.close(); } catch (IOException ex) { Logger.getLogger(Highways.class.getName()).log(Level.SEVERE, null, ex); } } // CHECK: DO WE EVEN NEED TO DO THIS? private void updateSequences() { for (FEPLine line : lines) { line.updateSequences(); } } /** * Returns the network metadata in condensed form. This is just a quick * script function to make a proper highway metadata configuration file, so * that we can read the network faster. * * @return Network metadata */ public void writeHighwaysMeta(String fileName) { try { FileWriter fw = new FileWriter(new File(fileName)); StringBuilder build = new StringBuilder(); build.append(lines.size()); build.append("\n"); System.out.println(lines.size()); fw.write(build.toString()); int count = 1; for (FEPLine line : lines) { System.out.println("Writing num: " + count); count++; fw.write(line.getLineMeta()); } } catch (IOException ex) { Logger.getLogger(Highways.class.getName()).log(Level.SEVERE, null, ex); } } public String toXML() { String xml = null; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document theDoc = builder.newDocument(); Element networkElement = theDoc.createElement(XML_TAGS.NETWORK.tag); theDoc.appendChild(networkElement); for (FEPLine line : lines) { line.toXML(networkElement); } Transformer tf = TransformerFactory.newInstance().newTransformer(); tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); tf.setOutputProperty(OutputKeys.INDENT, "yes"); tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); Writer out = new StringWriter(); tf.transform(new DOMSource(theDoc), new StreamResult(out)); xml = out.toString(); out.close(); } catch (Exception ex) { Logger.getLogger(Highways.class.getName()).log(Level.SEVERE, null, ex); } return xml; } @Override public void update(Observable o, Object arg) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } private static enum XML_TAGS { NETWORK("Network"); String tag; private XML_TAGS(String n) { tag = n; } } }