package caida.mapnet; import caida.image.WorldProducer; import java.awt.*; import java.awt.image.FilteredImageSource; import java.io.*; import java.applet.*; import java.net.*; import java.util.Date; /********************************************************************** * MapNet written 08/11/97 * by Bradley Huffaker modified 11/09/97 * Cooperative Association for Internet Data Analysis (CAIDA) * version 1.1 * * This should read in from a file some of the * major ISP and display them based on the topolgy * of there major backbones. ************************************************************************ ************************************************************************ By accessing this software, MAPNET, you are duly informed of and agree to be bound by the conditions described below in this notice: This software product, MAPNET, is developed by Bradley Huffaker, and copyrighted(C) 1998 by the University of California, San Diego (UCSD), with all rights reserved. UCSD administers the NSF grant to CAIDA, number NCR-9711092, under which this code was developed. There is no charge for MAPNET software. You can redistribute it and/or modify it under the terms of the GNU General Public License, v. 2 dated June 1991 which is incorporated by reference herein. MAPNET is distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE or that the use of it will not infringe on any third party's intellectual property rights. You should have received a copy of the GNU GPL along with the MAPNET program. Copies can also be obtained from http://www.gnu.org/copyleft/gpl.html or by writing to University of California, San Diego SDSC/CAIDA 9500 Gilman Dr., MS-0505 La Jolla, CA 92093 - 0505 USA Or contact INFO@CAIDA.ORG ***********************************************************************/ public class MapNet extends Applet { GridBagLayout gridbag = new GridBagLayout(); MyList pipes; MyList nodes; MyList clouds; MyList isps; MyList fed_isps; MyList inc_isps; MyList both_isps; MyList all_isps; MyList peers; final int LIST_SIZE = 10; List status; List isp_list; boolean [] isp_selected; ISP[] isp_index; Color[] isp_color; int isp_num; IOHandler ioHandler; boolean loaded; // Flag set by Loader set when all the stuff is loaded final int DATA_ADD = 0; final int INC_ADD = 1; final int FED_ADD = 2; final String FED_STR = "R&E Backbones"; final String INC_STR = "Commercial Backbones"; final String BOTH_STR = "Both Backbones"; int which_address; String data_address; final String SHOW_MAP = "Show Map"; final String HIDE_MAP = "Hide Map"; Map map; Logo logo; Image img; Button Show_Map; Button Show_Off_Links; Button Set_Mode; Button Reload; Button Clear_ISP; Choice ViewPort; final String VIEW_WORLD = "View World"; final String VIEW_USA = "View USA"; final String VIEW_EUROPE = "View Europe"; final String VIEW_ASIA = "View Asia"; Choice Zoom_Mode; final String SELECT_MODE = "Select Mode"; final String MOVE_MODE = "Move Mode"; final String ZOOM_IN_MODE = "ZoomIn Mode"; final String ZOOM_OUT_MODE = "ZoomOut Mode"; Choice Mode; int MAX_SIZE = 10; Choice Size; Choice Which_isp; final String ISP_MODE = "Color by ISP"; final String BAND_MODE = "Color by bandwidth"; int waiting; public void init() { setBackground(Color.white); setForeground(Color.black); isp_list = new List(LIST_SIZE,true); String temp = " "; for (int i=0; i < 15; i++) { isp_list.addItem(temp); temp = temp + " "; } waiting = 1; peers = new MyList(); nodes = new MyList(); clouds = new MyList(); isps = new MyList(); inc_isps = new MyList(); fed_isps = new MyList(); both_isps = new MyList(); all_isps = new MyList(); status = new List(LIST_SIZE,false); this.setLayout(gridbag); // --------------------- Map Stuff --------------------------- float top_lat = Float.valueOf(this.getParameter("Upper_Left_Lat")) .floatValue(); float top_lon = Float.valueOf(this.getParameter("Upper_Left_Lon")) .floatValue(); float bot_lat = Float.valueOf(this.getParameter("Lower_Right_Lat")) .floatValue(); float bot_lon = Float.valueOf(this.getParameter("Lower_Right_Lon")) .floatValue(); int width = Integer.parseInt(this.getParameter("Image_Width")); int height = Integer.parseInt(this.getParameter("Image_Height")); int logo_width = Integer.parseInt(this.getParameter("Logo_Width")); int logo_height = Integer.parseInt(this.getParameter("Logo_Height")); String base = this.getCodeBase().toString(); try { String image_address = base + this.getParameter("image_address"); // String address = "http://www.caida.org/MapNet/Backbones/pics/usa.gif"; String logo_address = base + this.getParameter("logo_address"); // logo_address = "http://www.caida.org/MapNet/Backbones/pics/map_net.gif"; /* if (!image_address.equals(address)) { image_address = address; } */ URL url = new URL(image_address); Image image = this.getImage(new URL(image_address)); img = image; //width = image.getWidth(this); //height = image.getHeight(this); map = new Map(image,top_lat,top_lon,bot_lat,bot_lon,width ,height,this); map.resize(width,height); image = this.getImage(new URL(logo_address)); logo = new Logo(logo_width,logo_height,image); } catch (MalformedURLException e0) { Error(""+e0.toString()); } catch (IOException e1) { Error(""+e1.toString()); } // ----------------- IOHandler Stuff ------------------------- which_address = DATA_ADD; data_address = base + this.getParameter("data_address"); loaded = false; try { ioHandler = new IOHandler(this); ioHandler.Load(data_address); } catch (VerifyError e) { Error( e.toString() ); } // ---------------- Button Stuff ----------------------- Show_Map = new Button("Show/Hide Map"); Show_Off_Links = new Button ("Show/Hide OffScreen Links"); Reload = new Button("Reload the data"); Clear_ISP = new Button("Clear the map"); Size = new Choice(); for (int size=1;size <= MAX_SIZE; size++) Size.addItem(String.valueOf(size)); ViewPort = new Choice(); ViewPort.addItem(VIEW_ASIA); ViewPort.addItem(VIEW_EUROPE); ViewPort.addItem(VIEW_USA); ViewPort.addItem(VIEW_WORLD); ViewPort.select(VIEW_WORLD); Which_isp = new Choice(); Which_isp.addItem(FED_STR); Which_isp.addItem(INC_STR); Which_isp.addItem(BOTH_STR); Mode = new Choice(); Mode.addItem(ISP_MODE); Mode.addItem(BAND_MODE); Zoom_Mode = new Choice(); Zoom_Mode.addItem(SELECT_MODE); Zoom_Mode.addItem(MOVE_MODE); Zoom_Mode.addItem(ZOOM_IN_MODE); Zoom_Mode.addItem(ZOOM_OUT_MODE); Zoom_Mode.select(SELECT_MODE); //#################### Set up the layout #################### //-------------------List panel Panel lists_panel = new Panel(); lists_panel.setLayout(gridbag); constrain(lists_panel,isp_list,0,0,1,1, GridBagConstraints.BOTH, GridBagConstraints.CENTER,0.3, 0.0, 0, 0, 0, 0); constrain(lists_panel,status,1,0,1,1, GridBagConstraints.BOTH, GridBagConstraints.CENTER,0.3, 0.0, 0, 0, 0, 0); //------------------Button panel Panel size_panel = new Panel(); size_panel.setLayout(new BorderLayout()); size_panel.add("West", new Label("Line Size:")); size_panel.add("Center",Size); Panel buttons_panel = new Panel(); buttons_panel.setLayout(gridbag); constrain(buttons_panel, Show_Map, 0, 0); constrain(buttons_panel, Show_Off_Links, 1, 0); constrain(buttons_panel, ViewPort, 2, 0); constrain(buttons_panel, Clear_ISP, 3, 0); constrain(buttons_panel, size_panel, 0, 1); constrain(buttons_panel, Mode, 1, 1); constrain(buttons_panel, Zoom_Mode, 2, 1); constrain(buttons_panel, Which_isp, 3, 1); //------------------Bring it all together constrain(this,buttons_panel,0,0,1,1, GridBagConstraints.BOTH, GridBagConstraints.CENTER,0.3, 0.0, 0, 0, 0, 0); constrain(this,map,0,1,1,1, GridBagConstraints.BOTH, GridBagConstraints.CENTER,0.3, 0.0, 0, 0, 0, 0); constrain(this,lists_panel,0,2,1,1, GridBagConstraints.BOTH, GridBagConstraints.CENTER,0.3, 0.0, 0, 0, 0, 0); } public void write(String msg) { status.addItem(msg); } public void writeNode(Node node, MyList ispslist) { status.addItem(""); status.addItem("City: " + node.name); repaint(); status.addItem("Lat:" + String.valueOf(node.lat) + " Long: " + String.valueOf(node.lon)); Pad[] pad = new Pad[3]; FontMetrics fm = status.getFontMetrics(status.getFont()); pad[0] = new Pad(fm); pad[1] = new Pad(fm); pad[2] = new Pad(fm); MyList pipes = node.pipes; pipes.reset(); status.addItem("----------"); while(!pipes.end()) { Pipe pipe = (Pipe) pipes.next(); Node other; if (pipe.to != node) other = pipe.to; else other = pipe.from; if (ispslist.exists(pipe.isp)) { pad[0].add(String.valueOf(pipe.bandwidth)); pad[1].add(other.name); pad[2].add(pipe.isp.name); } } MyList links = node.links; links.reset(); while(!links.end()) { Link link = (Link) links.next(); if (ispslist.exists(link.isp)) { pad[0].add(String.valueOf(link.bandwidth)); pad[1].add(link.cloud.name+"(Cloud)"); pad[2].add(link.isp.name); } } pad[0].reset(); pad[1].reset(); pad[2].reset(); while (!pad[0].end()) { String[] strings = new String[3]; strings[0] = pad[0].next(); strings[1] = pad[1].next(); strings[2] = pad[2].next(); status.addItem(" " + strings[0] + "-> " + strings[1] + " | " + strings[2]); } MyList peers = node.peers; peers.reset(); if (!peers.end()) { status.addItem(" Peers"); status.addItem("----------"); } while(!peers.end()) { Peer peer = (Peer) peers.next(); if (ispslist.exists(peer.isps[0]) || ispslist.exists(peer.isps[1])) status.addItem( peer.isps[0].name + "<->" + peer.isps[1].name ); } /* isps.reset(); status.addItem(" ISPs"); status.addItem("----------"); while(!isps.end()) { status.addItem( ((ISP) isps.next()).name ); } */ } public void writePipe(Pipe pipe) { status.addItem(pipe.isp.name); status.addItem(" " + pipe.to.name + "<->" + pipe.from.name + " " + pipe.bandwidth); } public void Error(String msg) { msg = "ERROR::" + msg; status.addItem(msg); } void ShowLists() { System.out.println("Enter ShowList"); pipes.reset(); /* while(!pipes.end()) { Pipe pipe = (Pipe) pipes.next(); System.out.println("Pipe: " + pipe.from.name + "->" + pipe.to.name +" " + pipe.bandwidth + " ISP: " + pipe.isp.name); } */ nodes.reset(); while(!nodes.end()) { Node node = (Node) nodes.next(); System.out.println("Node: " + node.name + " lat:" + node.lat +" lon:" + node.lon); /* node.pipes.reset(); while (!node.pipes.end()) { Pipe pipe = (Pipe) node.pipes.next(); System.out.println(" Pipe:" + pipe.from.name+ " -> " +" " + pipe.bandwidth + " ISP: " + pipe.isp.name); } node.isps.reset(); while (!node.isps.end()) { ISP isp = (ISP) node.isps.next(); System.out.println(" ISP:" + isp.name); } node.peers.reset(); while (!node.peers.end()) { Peer peer = (Peer) node.peers.next(); System.out.println(" Peer:" + peer.isps[0].name + " <-> " + peer.isps[1].name); } */ } ShowISP(); } public void ShowISP() { System.out.println("Showing ISP list"); isps.reset(); while(!isps.end()) { ISP isp = (ISP) isps.next(); System.out.println("ISP: " + isp.name); isp.pipes.reset(); while(!isp.pipes.end()) { Pipe pipe = (Pipe) isp.pipes.next(); System.out.println(" Pipe:" + pipe.from.name + "->" + pipe.to.name +" " + pipe.bandwidth + " ISP: " + pipe.isp.name); } /* isp.nodes.reset(); while(!isp.nodes.end()) { Node node = (Node) isp.nodes.next(); System.out.println(" Node:" + node.name); } isp.peers.reset(); while (!isp.peers.end()) { Peer peer = (Peer) isp.peers.next(); System.out.println(" Peer:" + peer.isps[0].name + " <-> " + peer.isps[1].name); } */ } /* peers.reset(); while (!peers.end()) { Peer peer = (Peer) peers.next(); System.out.println("Peer: " + peer.node.name +" " + peer.isps[0].name + "<->" + peer.isps[1].name); } */ } Node GetNode(String name) { Index i_nodes = new Index(nodes); while (!i_nodes.end()) { Node node = (Node) i_nodes.next(); if (node.name.equals(name)) return node; } return null; } Cloud GetCloud(String name) { clouds.reset(); Cloud cloud; while(!clouds.end()) { cloud = (Cloud) clouds.next(); if (cloud.name.equals(name)) return cloud; } cloud = new Cloud(name); clouds.enqueue(cloud); return cloud; } ISP GetISP(String name) { ISP answer = null; Index i_isps = new Index(isps); while (!i_isps.end()) { ISP isp = (ISP) i_isps.next(); if (isp.name.equals(name)) answer = isp; } i_isps = new Index(both_isps); while (!i_isps.end()) { ISP isp = (ISP) i_isps.next(); if (isp.name.equals(name)) answer = isp; } all_isps.reset(); while(!all_isps.end()) { ISP isp = (ISP) all_isps.next(); if (isp.name.equals(name)) answer = isp; } if (answer == null) answer = new ISP(name); if (!all_isps.exists(answer)) all_isps.push(answer); return answer; } public boolean handleEvent(Event e) { switch (e.id) { case Event.ACTION_EVENT: { if (e.target == Show_Map) { map.Swap_Map(); return true; } else if (e.target == ViewPort) { ViewPort((String) e.arg); return true; } else if (e.target == Show_Off_Links) { map.Swap_Off_Links(); return true; } else if (e.target == Size) { map.SetSize(Integer.parseInt( (String) e.arg)); return true; } else if (e.target == Which_isp) { SwapISPs((String)e.arg); return true; } else if (e.target == Mode) { if ((String) e.arg == BAND_MODE) map.SetMode(map.BAND_MODE); else map.SetMode(map.ISP_MODE); return true; } else if (e.target == Reload) { pipes = new MyList(); nodes = new MyList(); isps = new MyList(); map.Clear_ISP(); /* ioHandler = new IOHandler(this); ioHandler.Load(data_address); */ return true; } else if (e.target == Clear_ISP) { map.Clear_ISP(); return true; } } case Event.LIST_SELECT: { for (int index=0;index < isp_num; index++) { if (isp_selected[index] != isp_list.isSelected(index)) { map.AddISP(isp_index[index]); isp_list.replaceItem( map.GetColorName(isp_index[index]) + " - " + isp_index[index].name,index ); isp_color[index] = map.GetColor(isp_index[index]); isp_list.select(index); isp_selected[index] = !isp_selected[index]; } } map.repaint(); return true; } case Event.LIST_DESELECT: { for (int index=0;index < isp_num; index++) { if (isp_selected[index] != isp_list.isSelected(index)) { map.DropISP(isp_index[index]); isp_selected[index] = !isp_selected[index]; SetISPList(); } } map.repaint(); return true; } } return super.handleEvent(e); } public void DeselectAllISP() { for (int index=0;index < isp_num; index++) { if (isp_selected[index] || isp_list.isSelected(index)) { isp_selected[index] = false; isp_list.deselect(index); map.DropISP(isp_index[index]); } } SetISPList(); map.repaint(); } protected void SetISPList() { boolean selected; if (isp_color == null || isp_list == null || isp_index == null || map == null) return; for (int index=0; index < isp_num; index++) { Color color = map.GetColor(isp_index[index]); if (isp_color[index] != color) { String color_name = map.GetColorName(isp_index[index]); if (isp_list.isSelected(index)) selected = true; else selected = false; if (color_name != null) isp_list.replaceItem( color_name + " - " + isp_index[index].name, index); else isp_list.replaceItem(isp_index[index].name, index); if (selected) isp_list.select(index); isp_color[index] = color; } } } public void SwapISPs(String name) { if (name.equals(INC_STR)) isps = inc_isps; else if (name.equals(FED_STR)) isps = fed_isps; else isps = both_isps; int count = isp_list.countItems(); isp_num = isps.count(); isp_selected = new boolean[isp_num]; isp_index = new ISP[isp_num]; isp_color = new Color[isp_num]; isps.reset(); int index = 0; while(!isps.end()) { isp_selected[index] = false; ISP isp = (ISP) isps.next(); isp_index[index] = isp; if (index < count) isp_list.replaceItem(isp.name,index); else isp_list.addItem(isp.name); index++; } for (index=index; index < count;index++) isp_list.replaceItem("",index); map.Clear_ISP(); } public void ViewPort(String choice) { if (choice.equals(VIEW_ASIA)) map.Zoom( 37.89, 87.5, 191, 18.75); else if (choice.equals(VIEW_EUROPE)) map.Zoom( -20, 70, 50, 33.13); else if (choice.equals(VIEW_USA)) map.Zoom( -131.37, 53.13, -63.79, 22.5); else if (choice.equals(VIEW_WORLD)) map.ZoomWorld(); } public void Wait() { if (waiting < 0) waiting = 0; waiting += 1; //this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); } public void Free() { waiting -= 1; if (waiting < 0) waiting = 0; //if (waiting == 0) // this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } public void SetBandwidths(MyList floats) { map.SetBandwidths(floats); } public void constrain(Container container, Component component, int grid_x, int grid_y, int grid_width, int grid_height, int fill, int anchor, double weight_x, double weight_y, int top, int left, int bottom, int right) { GridBagConstraints c = new GridBagConstraints(); c.gridx = grid_x; c.gridy = grid_y; c.gridwidth = grid_width; c.gridheight = grid_height; c.fill = fill; c.anchor = anchor; c.weightx = weight_x; c.weighty = weight_y; if (top+bottom+left+right >0) c.insets = new Insets(top, left, bottom, right); ((GridBagLayout)container.getLayout()).setConstraints(component, c); container.add(component); } public void constrain(Container container, Component componet, int x, int y) { constrain(container , componet,x,y,1,1, GridBagConstraints.BOTH, GridBagConstraints.CENTER,0.3, 0.0, 0, 0, 0, 0); } } class Pad { FontMetrics fm; MyList strings; String pad; int pad_len; int max; public Pad(FontMetrics fm_input) { this(fm_input," "); } public Pad(FontMetrics fm_input, String pad_input) { fm = fm_input; pad = pad_input; pad_len = fm.stringWidth(pad); strings= new MyList(); } public void add(String string) { strings.enqueue(string); } public void reset() { GetMax(); strings.reset(); } public String next() { return AddPad( (String) strings.next() ); } public boolean end() { return strings.end(); } protected void GetMax() { strings.reset(); max = 0; while(!strings.end()) { String a = (String) strings.next(); int len = fm.stringWidth(a); if (len > max) max = len; } } protected String AddPad(String a) { int len = fm.stringWidth(a); while (len < max) { a = a + pad; len += pad_len; } return a; } } class Logo extends Canvas { Image image; int width; int height; public Logo(int input_width,int input_height, Image input) { width = input_width; height = input_height; image = input; resize(width,height); } public void paint(Graphics g) { if (image != null) { g.drawImage(image,0,0,this); } } } class Pipe extends Object { public Node from; public Node to; public float bandwidth; public ISP isp; public Pipe(Node f, Node t, float b, ISP i) { from = f; to = t; bandwidth = b; isp = i; } } class Node extends Object { public String name; public float lat; public float lon; public MyList peers; public MyList pipes; public MyList isps; public MyList links; public MyList clouds; public Node() { name = "None"; peers = new MyList(); pipes = new MyList(); isps = new MyList(); links = new MyList(); clouds = new MyList(); } public Node(String n, float lt, float ln) { name = n; lat = lt; lon = ln; peers = new MyList(); pipes = new MyList(); isps = new MyList(); links = new MyList(); clouds = new MyList(); } public boolean IsPeerFor(ISP isp) { peers.reset(); while(!peers.end()) { Peer peer = (Peer) peers.next(); if (peer.isps[0] == isp) return true; if (peer.isps[1] == isp) return true; } return false; } public boolean IsCloudFor(ISP isp) { links.reset(); while(!links.end()) { Link link = (Link) links.next(); if (link.isp == isp) return true; } return false; } } class Link extends Object { float bandwidth; ISP isp; Node node; Cloud cloud; public Link (ISP isp_input, Node node_input, Cloud cloud_input,float bandwidth_input) { isp = isp_input; node = node_input; cloud = cloud_input; bandwidth = bandwidth_input; } } class Cloud extends Object { public String name; public MyList links; public MyList nodes; public MyList isps; public Cloud(String name_input) { name = name_input; links = new MyList(); nodes = new MyList(); isps = new MyList(); } } class ISP extends Object { public String name; public MyList pipes; public MyList nodes; public MyList peers; public MyList clouds; public MyList links; public ISP(String n) { name = n; pipes = new MyList(); nodes = new MyList(); peers = new MyList(); clouds = new MyList(); links = new MyList(); } public static MyList Sort(MyList isps) { MyList sorted = new MyList(); isps.reset(); while (!isps.end()) { ISP isp = (ISP) isps.next(); sorted.reset(); ISP where = (ISP) sorted.top(); if (where == null) sorted.push(isp); else { while(where != null && (compare(isp.name,where.name) > 0) && !sorted.end()) { sorted.next(); where = (ISP) sorted.where(); } sorted.insert(isp); } } return sorted; } public static int compare(String left, String right) { left = left.toLowerCase(); right = right.toLowerCase(); char[] l_c = left.toCharArray(); char[] r_c = right.toCharArray(); int shortest; if (left.length() > right.length()) shortest = right.length(); else shortest = left.length(); for (int index=0; index < shortest; index++) { if (l_c[index] < r_c[index]) return -1; if (l_c[index] > r_c[index]) return 1; } if (left.length() == right.length()) return 0; if (left.length() == shortest) return -2; return 2; } } class Peer extends Object { Node node; ISP[] isps; public Peer(Node n, ISP[] i) { node = n; isps = i; } } class My_Pipe extends Object { public String from; public String to; public float bandwidth; public My_Pipe(String f, String t, float b) { from = f; to = t; bandwidth = b; } } class My_Link extends Object { public String cloud; public String node; public float bandwidth; public My_Link(String c, String n, float b) { cloud = c; node = n; bandwidth = b; } } class My_Node extends Object { public String name; public float lat; public float lon; public My_Node(String n, float lt, float ln) { name = n; lat = lt; lon = ln; } } class My_Peer extends Object { public String isp_a; public String isp_b; public String node; public My_Peer(String n, String a, String b) { node = n; isp_a = a; isp_b = b; } } class My_ISP extends Object { String name; MyList pipes; MyList links; static final int FED = 0; static final int INC = 1; int type; public My_ISP(String n,int type_input) { name = n; type = type_input; pipes = new MyList(); links = new MyList(); } } class IOHandler extends Thread { // The type of formats final char TOTAL_NODES = 'T'; final char TOTAL_CLOUDS= 't'; final char TOTAL_ISPS= 'R'; final char NODE = 'C'; final char CLOUD = 'c'; final char ISP = 'I'; final char ISP_DATA = 'i'; final char END_ISP = 'E'; final char ISP_RES = 'R'; final char ISP_INC = 'I'; final char LINK = 'L'; final char PIPE = 'P'; final char PEER = 'p'; // The nodes,links, and the main list MyList pipes = new MyList(); MyList links = new MyList(); MyList peers = new MyList(); MyList bandwidths = new MyList(); ISP current_isp; MyList fed_isps = new MyList(); MyList inc_isps = new MyList(); MyList both_isps = new MyList(); Node[] nodes; ISP[] isps; Cloud[] clouds; // MapNet MapNet mapnet; String address; int linenum; // Checks to see if it is still loading boolean loading = false; boolean saving = false; // Used to select from the list of possible local files //FileDailog dialogbox = new FileDialog(this, "Select File"); // Used by Parse String and it's Helper Methoids // The reason that I choice to do it this way dispite // my better judgement was because. Prase of Int and floats // happen on more then one time. therefor there should // be a single methoid for doing it. But to make a methoid // work it need to be able to change state. boolean parse_error; char[] buffer; int index; int length; public IOHandler(MapNet mapnet_input) { mapnet= mapnet_input; } public void Load(String address_input) { if (address_input == null) { Error("IOHandler.Load()", "The pasted address is null"); return; } address = address_input; start(); } public void run() { if (mapnet.status.countItems() > 0) mapnet.status.clear(); mapnet.write("Loading..(This could take a few minutes)"); mapnet.Wait(); // Reseting mapping for a new file try { linenum = 1; StartLoading(); } catch (IOException e1) { Error("IOHandler.run()",e1.toString()); stop(); } // ---- Set up mapnet variable int num_isps = isps.length; mapnet.isp_num = num_isps; mapnet.isp_selected = new boolean[num_isps]; mapnet.isp_index = new ISP[num_isps]; mapnet.isp_color = new Color[num_isps]; for (int i=0;i< num_isps;i++) mapnet.isp_selected[index] = false; // --- Load in the Nodes MyList nodes_list = new MyList(); for(int i=0; i < nodes.length;i++) if (nodes[i] != null) nodes_list.enqueue(nodes[i]); mapnet.nodes = nodes_list; // --- Load in the Clouds MyList clouds_list = new MyList(); for(int i=0; i < clouds.length;i++) if (clouds[i] != null) clouds_list.enqueue(clouds[i]); mapnet.clouds = clouds_list; // ---- Loading over the ISPs ISP junk = new ISP("junk"); mapnet.fed_isps = junk.Sort(fed_isps); mapnet.inc_isps = junk.Sort(inc_isps); mapnet.both_isps = junk.Sort(both_isps); // ---- Loading over the links mapnet.pipes = pipes; mapnet.peers = peers; loading = false; mapnet.repaint(); mapnet.loaded = true; mapnet.isps.reset(); mapnet.write("Load complete"); mapnet.SetBandwidths(bandwidths); mapnet.SwapISPs(mapnet.FED_STR); mapnet.Free(); } public void StartLoading() throws IOException { // The buffer that holds the tokens string buffer = new char[256]; // control flag that ends the loop boolean working = true; // the curent length of the string in buffer length = 0; // The number of byte read into byte_buffer int byte_length; byte[] byte_buffer = new byte[256]; // the input Stream InputStream is = getInputStream(); // A comment charater has been reached and the rest of the // the line should be ignored. boolean is_comment = false; if (is == null) { Error("IOHandler.StartLoading()","InputStream is null"); stop(); } do { byte_length = is.read(byte_buffer); if (byte_length < 0) { byte_length = 0; byte_buffer[byte_length++] = '\n'; working = false; } for (int offset=0; offset < byte_length; offset++) { if (length == buffer.length) { char[] temp = new char[(int)(buffer.length*1.1)]; for (int i=0; i< buffer.length; i++) temp[i] = buffer[i]; buffer = temp; } buffer[length] = (char) byte_buffer[offset]; if (buffer[length] == '\n') { ParseString(); length= 0; linenum++; is_comment = false; } else if (buffer[length] == '#') is_comment = true; else if (!is_comment) length++; } } while (working); } public InputStream getInputStream() { InputStream is = null; try { URL url = new URL(address); is = url.openStream(); } catch (MalformedURLException e0) { Error("IOHandler.getInputSteam()",e0.toString()); } catch (IOException e1) { Error("IOHandler.getInputSteam()",e1.toString()); } return is; } // Breaks the string into tokens and then create objects public void ParseString() { //System.err.println("ParesString["+address+"]"+new String(buffer,0,length)); // checks for empty strings if (length <= 0) return; // Skip the first char it should be format index = 2; parse_error = false; char format = buffer[0]; // Value holders int total; int node_index; int cloud_index; int isp_index; int from_index; int to_index; int isp_from; int isp_to; float bandwidth; Node node; Cloud cloud; ISP isp; Link link; String name; switch (format) { case TOTAL_NODES: total = GetIndex(); if (parse_error) return; if (nodes == null) nodes = new Node[total]; else { Error("IOHandler.ParsesString", "Duplicate 'T' lines found"); return; } break; case TOTAL_CLOUDS: total = GetIndex(); if (parse_error) return; if (clouds == null) clouds = new Cloud[total]; else { Error("IOHandler.ParsesString", "Duplicate 't' lines found"); return; } break; case TOTAL_ISPS: total = GetIndex(); if (parse_error) return; if (isps == null) isps = new ISP[total]; else { Error("IOHandler.ParsesString", "Duplicate 't' lines found"); return; } break; case NODE: node_index = GetIndex(); if (parse_error) return; //System.err.println(linenum +":" + node_index +" < "+ nodes.length); if (node_index >= nodes.length || node_index < 0) { Error("IOHandler.ParseString()", "Node index is out of array" + node_index); return; } if (nodes[node_index] != null) { Error("IOHandler.ParseString()", "Node already exists at " + node_index); return; } float lat = GetFloat(); if (parse_error) return; float lon = GetFloat(); if (parse_error) return; String city = new String(buffer,index,length-index); nodes[node_index] = new Node(city,lat,lon); break; case CLOUD: cloud_index = GetIndex(); if (parse_error) return; if (clouds[cloud_index] != null) { Error("IOHandler.ParseString()", "Cloud already exists at " + cloud_index); return; } name = new String(buffer,index,length-index); clouds[cloud_index] = new Cloud(name); break; case ISP: case ISP_DATA: isp_index = GetIndex(); if (parse_error) return; char isp_type = buffer[index]; if (format == ISP) index += 2; name = new String(buffer,index,length-index); current_isp = new ISP(name); if (isps.length <= isp_index) { Error("IOHandler.ParseString()", "ISP index out of range [0-"+(isps.length-1) + "] index:" + isp_index); return; } if (isps[isp_index] != null) { Error("IOHandler.ParseString()", "ISP already exists at " + isp_index); return; } isps[isp_index] = current_isp; if (format == ISP) { if (isp_type == ISP_RES) fed_isps.push(current_isp); else if (isp_type == ISP_INC) inc_isps.push(current_isp); else { Error("IOHandler.ParseString()", "Unknown ISP type"); return; } both_isps.push(current_isp); } break; case END_ISP: name = new String(buffer,index,length-index); if (current_isp == null) { Error("IOHandler.ParseString", "type E found with out a I"); return; } if (!name.equals(current_isp.name)) { Error("IOHandler.ParseString()", "Current ISP does not equal end ISP"); return; } current_isp = null; break; case PIPE: if (current_isp == null) { Error("IOHandler.ParseString()", "Pipe found outsite of an ISP"); return; } from_index = GetIndex(); to_index = GetIndex(); bandwidth = GetFloat(); if (parse_error) return; AddBandwidth(bandwidth); if (to_index >= nodes.length || to_index < 0 || from_index >= nodes.length || from_index < 0) { Error("IOHandler.ParseString()", "One of the node_index is out of range"); return; } Node from = nodes[from_index]; Node to = nodes[to_index]; if (to == null || from == null) { Error("IOHandler.ParseString()", "Unable to find one of the nodes"); return; } Pipe pipe = new Pipe(from,to,bandwidth,current_isp); to.pipes.enqueue(pipe); from.pipes.enqueue(pipe); if (!from.isps.exists(current_isp)) from.isps.enqueue(current_isp); if (!to.isps.exists(current_isp)) to.isps.enqueue(current_isp); if (!current_isp.nodes.exists(to)) current_isp.nodes.enqueue(to); if (!current_isp.nodes.exists(from)) current_isp.nodes.enqueue(from); current_isp.pipes.enqueue(pipe); pipes.enqueue(pipe); break; case LINK: cloud_index = GetIndex(); node_index = GetIndex(); bandwidth = GetFloat(); if (parse_error) return; AddBandwidth(bandwidth); if (cloud_index >= clouds.length|| cloud_index < 0 || node_index >= nodes.length || node_index < 0) { Error("IOHandler.ParseString()", "One of the indexs is out of range"); return; } cloud = clouds[cloud_index]; node = nodes[node_index]; if (cloud == null || node == null) { Error("IOHandler.ParseString()", "One object has not been defined"); return; } link = new Link(current_isp,node,cloud,bandwidth); current_isp.links.enqueue(link); node.links.enqueue(link); cloud.links.enqueue(link); if (!cloud.nodes.exists(node)) cloud.nodes.enqueue(node); if (!current_isp.clouds.exists(cloud)) current_isp.clouds.enqueue(cloud); links.push(link); break; case PEER: node_index = GetIndex(); isp_from = GetIndex(); isp_to = GetIndex(); if (parse_error) return; if (node_index > nodes.length || node_index < 0 || isp_from > isps.length || isp_from < 0 || isp_to > nodes.length || isp_to < 0) { Error("IOHandler.ParseString()" ,"One of the index is out of range"); return; } node = nodes[node_index]; ISP[] isp_array = new ISP[2]; if (isps.length <= isp_from || isps.length <= isp_to) { Error("IOHandler.ParseString()", "One or both objects indexs are greater then" + (isps.length-1) + " peer: " + isp_from +"<->" + isp_to ); return; } isp_array[0] = isps[isp_from]; isp_array[1] = isps[isp_to]; if (node == null || isp_array[0] == null || isp_array[1] == null) { Error("IOHandler.ParseString()", "One of the objects doesn't exists"); return; } Peer peer = new Peer(node,isp_array); peers.push(peer); node.peers.push(peer); isp_array[0].peers.push(peer); isp_array[1].peers.push(peer); break; default: Error("IOHandler.ParseString()", "Unknown Format '" + format +"'"); } } protected int GetIndex() { int offset = index; while (index < length && buffer[index] >= '0' && buffer[index] <= '9') index++; if (index == offset) { parse_error = true; Error("IOHandler.ParseString()", "index not int"); return -1; } int answer = Integer.parseInt(new String(buffer ,offset,index-offset)); index++; return answer; } protected float GetFloat() { int offset = index; while (index < length && ((buffer[index] >= '0' && buffer[index] <= '9') || buffer[index] == '.' || buffer[index] == '-')) index++; //System.err.println("GetFloat index:"+index+" offset:"+offset+" buffer:"+buffer[index]+" string:"+(new String(buffer,index,index-offset))); if (index == offset) { parse_error = true; Error("IOHandler.GetDouble()", "excpected float"); return -1; } try { float answer = Float.valueOf( new String(buffer,offset,index-offset)) .floatValue(); index++; return answer; } catch (NumberFormatException e) { Error("IOHandler.GetDouble()", e.toString()); parse_error = true; } return 0; } public void Error(String where, String msg) { System.err.println("FILE ERROR<"+where+"> [" + linenum +"]" + address + "\n --->" + msg); mapnet.write("FILE ERROR ["+linenum +"]" + address + "::" +msg); } protected void AddBandwidth(float input) { bandwidths.reset(); while(!bandwidths.end()) { Float value = (Float) bandwidths.next(); if (value.floatValue() == input) return; } bandwidths.push(new Float(input)); } } class MapNode extends Object { int x; int y; Color my_color; MyList nodes; MyList isp_peered; MyList links; public MapNode(int X, int Y, Node n,Color default_color) { x = X; y = Y; my_color = default_color; nodes = new MyList(); isp_peered = new MyList(); links = new MyList(); AddNode(n); } public void AddNode(Node n) { MyList peers = n.peers; peers.reset(); while (!peers.end()) { Peer peer = (Peer) peers.next(); for (int index = 0; index < 2; index++) { ISP isp = peer.isps[index]; if (!isp_peered.exists(isp)) isp_peered.enqueue(isp); } } nodes.enqueue(n); } public void AddLink(Link link) { if (!links.exists(link)) links.push(link); } public boolean peered(ISP isp) { return (isp_peered.exists(isp)); } public String getString() { return ("MapNode.getString() I don't want to write it now."); } } class MapPipe extends Object { Color my_color; MapNode to; MapNode from; MyList pipes; public MapPipe(MapNode t, MapNode f, Pipe pipe) { to = t; from = f; pipes = new MyList(); pipes.push(pipe); } public String getString() { return ("MapPipe.getString() I don't want to write it now."); } } class Map extends Canvas { MapNet applet; Image image; Image source_image; boolean Show_Map; boolean Show_Off_Links; int color_mode; final int MODE_WIEGHT = 0; final int ISP_MODE = 1; final int BAND_MODE = 2; final int level_num = 4; final Color[] level_colors = {Color.lightGray, Color.yellow, Color.red, Color.white}; int level_split; final int COLOR_NUM = 11; final String[] COLORS_NAMES = { "green", "cyan", "orange", "blue", "yellow", "magenta", "red", "pink", "light gray", "gray", "dark gray", }; final Color[] COLORS = { Color.green, Color.cyan, Color.orange, Color.blue, Color.yellow, Color.magenta, Color.red, Color.pink, Color.lightGray, Color.gray, Color.darkGray, }; int num_bandwidths; float [] band_to_color; Color [] band_colors; final int BAND_SPACING = 2; final Color BAND_BACK = Color.black; final Color BAND_WORDS = Color.white; Object selected; int what_selected; final int NONE = -1; final int NODE = 0; final int PIPE = 1; final Color COLOR_SELECT = Color.white; protected MyList[] isp_to_color; protected MyList[] cloud_to_color; final Color BGCOLOR = Color.black; final Color NODE_COLOR = Color.green; final Color PEER_COLOR = Color.orange; final int FROM = 0; final int TO = 1; final int NODE_WIDTH = 2; final int NODE_HEIGHT = 2; MyList isps; MyList mappipes; MyList mapnodes; int width,height; float top_lat,top_lon; float bot_lat,bot_lon; float source_top_lat,source_top_lon; float source_bot_lat,source_bot_lon; int MaxPipeCount; int size; float ZoomFactor = 2; final double MAX_ZOOM = .003; WorldProducer worldProducer; public Map(Image img,float t_lat,float t_lon, float b_lat,float b_lon, int width_input, int height_input, MapNet app) { source_image = img; source_top_lat = top_lat = t_lat; source_top_lon = top_lon = t_lon; source_bot_lat = bot_lat = b_lat; source_bot_lon = bot_lon = b_lon; width = width_input; height = height_input; worldProducer = new WorldProducer(source_image,source_top_lon ,source_top_lat ,source_bot_lon ,source_bot_lat ,width,height); image = createImage (worldProducer); applet = app; mappipes = new MyList(); mapnodes = new MyList(); isps = new MyList(); isp_to_color = new MyList[COLOR_NUM]; cloud_to_color = new MyList[COLOR_NUM]; for (int index=0; index < COLOR_NUM; index++) { isp_to_color[index] = new MyList(); cloud_to_color[index] = new MyList(); } Show_Map = true; Show_Off_Links = true; color_mode = ISP_MODE; size = 1; //super.resize(width,height); what_selected = NONE; selected = null; } public void ShowList() { applet.write("----- ISP -------"); isps.reset(); while (!isps.end()) { ISP isp = (ISP) isps.next(); applet.write(isp.name); } applet.write("----- Links -------"); mappipes.reset(); while(!mappipes.end()) { MapPipe m_pipe = (MapPipe) mappipes.next(); applet.write(m_pipe.getString()); } applet.write("----- Nodes -------"); mapnodes.reset(); while(!mapnodes.end()) { MapNode mapnode = (MapNode) mapnodes.next(); applet.write(mapnode.getString()); } } public boolean AddISP(ISP isp) { if (!isps.exists(isp)) { isps.push(isp); Update(); return true; } return false; } public boolean DropISP(ISP isp) { if(isps.drop(isp)) { RemoveColor(isp); Update(); return true; } return isps.drop(isp); } public void Swap_Off_Links() { selected = null; Show_Off_Links = !Show_Off_Links; repaint(); } public void Swap_Map() { Show_Map = !Show_Map; repaint(); } public void Show_Map(boolean flag) { Show_Map = flag; repaint(); } public void Swap_Mode() { if (color_mode == MODE_WIEGHT) color_mode = ISP_MODE; else color_mode = MODE_WIEGHT; Update(); repaint(); } public void SetMode(int mode) { color_mode = mode; Update(); repaint(); } public void SetSize(int Size) { size = Size; Update(); repaint(); } public void paint(Graphics g) { if (image != null && Show_Map) { g.drawImage(image,0,0,this); } else { g.setColor(BGCOLOR); g.fillRect(0,0,width,height); } if (color_mode == BAND_MODE) DrawBands(g); mappipes.reset(); while (!mappipes.end()) { MapPipe mappipe = (MapPipe) mappipes.next(); if (Show_Off_Links || (OnScreen(mappipe.to) && OnScreen(mappipe.from))) DrawLines(g,mappipe); } mapnodes.reset(); while(!mapnodes.end()) { MapNode node = (MapNode) mapnodes.next(); DrawNode(g,node); } } public boolean OnScreen(MapNode node) { return ((node.x >= 0) && (node.x <= width) && (node.y >= 0) && (node.y <= height)); } public void DrawLinks(Graphics g, MapNode node) { if (node.links == null) System.err.println("Error: nodes.links is null\n\n"); MyList links = node.links; links.reset(); int shift = size/2; int my_size; if (shift <= 0) { shift = 1; my_size= (shift+1)*links.count(); } else my_size= (shift+1)*links.count()+1; while(!links.end()) { Link link = (Link) links.next(); if (node == selected) g.setColor(COLOR_SELECT); else if (color_mode == BAND_MODE) g.setColor(GetBandColor(link.bandwidth)); else g.setColor(SetColor(link.cloud)); g.fillRect(node.x-(NODE_WIDTH+my_size) ,node.y-(NODE_WIDTH+my_size) ,(NODE_WIDTH+my_size)*2 ,(NODE_HEIGHT+my_size)*2); if (!links.end()) { my_size -= shift; g.setColor(Color.black); g.drawRect(node.x-(NODE_WIDTH+my_size) ,node.y-(NODE_WIDTH+my_size) ,(NODE_WIDTH+my_size)*2 ,(NODE_HEIGHT+my_size)*2); my_size -= 1; } } } public void DrawClear(Graphics g) { Dimension dim = size(); g.setColor(BGCOLOR); g.drawRect(0,0,dim.width,dim.height); } public void DrawNode(Graphics g, MapNode node) { DrawLinks(g,node); int my_size = size/2; my_size++; g.setColor(Color.black); g.drawOval(node.x-(NODE_WIDTH+my_size) ,node.y-(NODE_WIDTH+my_size) ,(NODE_WIDTH+my_size)*2 ,(NODE_HEIGHT+my_size)*2); if (node == selected) g.setColor(COLOR_SELECT); else g.setColor(node.my_color); my_size--; g.fillOval(node.x-(NODE_WIDTH+my_size) ,node.y-(NODE_WIDTH+my_size) ,(NODE_WIDTH+my_size)*2 ,(NODE_HEIGHT+my_size)*2); } public void DrawLine(Graphics g,int x1, int y1, int x2,int y2) { int x_diff = x1-x2; x_diff *= x_diff; int y_diff = y1-y2; y_diff *= y_diff; int x_shift = 0; int y_shift = 0; if (x_diff > y_diff) { x_shift = 0; y_shift = 1; } else { y_shift = 0; x_shift = 1; } int shift = 0; for (int index=0; index < size; index++) { g.drawLine(x1-x_shift*shift,y1-y_shift*shift ,x2-x_shift*shift ,y2-y_shift*shift); shift *= -1; if (index == 1) shift = 1; else if (shift>0) shift += 1; } } public void DrawLines(Graphics g,MapPipe mappipe) { mappipe.pipes.reset(); int sign = 1; int index = 0; int boundary = 0; int x_shift = 0; int y_shift = 0; int x_diff = mappipe.from.x - mappipe.to.x; x_diff *= x_diff; int y_diff = mappipe.from.y - mappipe.to.y; y_diff *= y_diff; if (x_diff > y_diff) { x_shift = 0; y_shift = 1; } else { y_shift = 0; x_shift = 1; } int shift = 0; while(!mappipe.pipes.end()) { sign *= -1; Pipe pipe = (Pipe) mappipe.pipes.next(); if (mappipe != selected) { if (color_mode == BAND_MODE) g.setColor(GetBandColor(pipe.bandwidth)); else g.setColor(GetColor(pipe.isp)); } else g.setColor(COLOR_SELECT); DrawLine(g, mappipe.from.x + x_shift*shift, mappipe.from.y + y_shift*shift, mappipe.to.x + x_shift*shift, mappipe.to.y + y_shift*shift); index++; shift *= -1; if (index == 1) shift = size+1; else if (shift>0) shift += size+1; } } public void DrawBands(Graphics g) { FontMetrics fm = g.getFontMetrics(g.getFont()); int height = (3*fm.getHeight())/4; int rec_width = 2*fm.charWidth(' '); int space = height + BAND_SPACING; int shift_x = 0; int shift_y = this.height; int longest = 0; for (int index=0;index < num_bandwidths; index++) { String string = String.valueOf(band_to_color[index]); int width = 2*rec_width +fm.stringWidth(string); g.setColor(BAND_BACK); g.fillRect(BAND_SPACING+shift_x,shift_y-height,width ,height); g.setColor(GetBandColor(band_to_color[index])); g.fillRect(BAND_SPACING+shift_x,shift_y-height,rec_width ,height); g.setColor(BAND_WORDS); g.drawString(String.valueOf(band_to_color[index]), BAND_SPACING+2*rec_width-2+shift_x,shift_y); if (width > longest) longest = width; shift_y -= space; if (shift_y-space< 0) { shift_y = this.height; shift_x += longest; longest = width; } } } public void Update() { mapnodes = new MyList(); mappipes = new MyList(); if (applet.status.countItems() > 0) applet.status.clear(); selected = null; what_selected = NONE; isps.reset(); while(!isps.end()) { ISP isp = (ISP) isps.next(); isp.pipes.reset(); Color isp_color = Color.white; isp_color = SetColor(isp); while(!isp.pipes.end()) { Pipe pipe = (Pipe) isp.pipes.next(); UpdatePipe(pipe,isp,isp_color); } isp.peers.reset(); while(!isp.peers.end()) { Peer peer = (Peer) isp.peers.next(); UpdateNode(peer.node,isp); } } if (color_mode == MODE_WIEGHT) { MaxPipeCount = 0; mappipes.reset(); while(!mappipes.end()) { int count = ((MapPipe) mappipes.next()).pipes.count(); if (count > MaxPipeCount) MaxPipeCount = count; } int level_split = MaxPipeCount/level_num; mappipes.reset(); while(!mappipes.end()) { MapPipe mappipe = (MapPipe) mappipes.next(); int count = mappipe.pipes.count(); int total = MaxPipeCount - level_split; int index = level_num -1; while (index > 0 && total > count) { total -= level_split; index--; } mappipe.my_color = level_colors[index]; } } } public void ShowBandwidths() { for (int index = 0; index < num_bandwidths;index++) applet.write(String.valueOf(band_to_color[index]) + " " + COLORS_NAMES[index]); } public void SetBandwidths(MyList floats) { num_bandwidths = floats.count(); band_to_color = new float[num_bandwidths]; int index = 0; floats.reset(); while (index < num_bandwidths && !floats.end()) { Float d = (Float) floats.next(); band_to_color[index] = d.floatValue(); int next = index; while ((next > 0) && (band_to_color[next-1] < band_to_color[next])) { float temp = band_to_color[next]; band_to_color[next] = band_to_color[next-1]; band_to_color[next-1] = temp; next--; } index++; } band_colors = new Color[num_bandwidths]; for (index=0;index < num_bandwidths;index++) { float value = 240*(1 - (float)(num_bandwidths - index)/(float)num_bandwidths); band_colors[index] = HueColor(value); } } protected Color HueColor(float input) { input = input / 60; while (input >= 6) input -= 6; while (input < 0) input += 6; int i = (int) input; float v = 1; float f = input - i; float p = 0; float q = 1-f; float red=1,green=1,blue=1; switch (i) { case 0: red=v; green=f; blue=p; break; case 1: red=q; green=v; blue=p; break; case 2: red=p; green=v; blue=f; break; case 3: red=f; green=q; blue=v; break; case 4: red=f; green=p; blue=v; break; case 5: red=v; green=p; blue=q; break; } return new Color(red,green,blue); } public Color GetBandColor(float bandwidth) { for (int index=0 ; index < num_bandwidths; index++) if (band_to_color[index] == bandwidth) return band_colors[index]; return Color.green; } public String GetBandColorName(float bandwidth) { for (int index=0 ; index < COLOR_NUM; index++) if (band_to_color[index] == bandwidth) return COLORS_NAMES[index]; return COLORS_NAMES[num_bandwidths-1]; } protected void ShowColorList() { for (int index=0 ; index < COLOR_NUM; index++) { applet.write("List " + String.valueOf(index)); isp_to_color[index].reset(); while(!isp_to_color[index].end()) { ISP isp = (ISP) isp_to_color[index].next(); applet.write(" " + isp.name); } } } protected Color SetColor(Cloud cloud) { int few = 0; for (int index=0; index < COLOR_NUM; index++) { if (cloud_to_color[index].exists(cloud)) return COLORS[index]; if (cloud_to_color[index].count() < cloud_to_color[few].count()) few = index; } cloud_to_color[few].push(cloud); return COLORS[few]; } protected Color SetColor(ISP isp) { int few = 0; for (int index=0 ; index < COLOR_NUM; index++) { if (isp_to_color[index].exists(isp)) return COLORS[index]; if (isp_to_color[index].count() < isp_to_color[few].count()) few = index; } isp_to_color[few].push(isp); return COLORS[few]; } protected boolean RemoveColor(ISP isp) { int many = 0; int few = 0; boolean found = false; for (int index=0 ; index < COLOR_NUM; index++) { if (isp_to_color[index].drop(isp)) found = true; if (isp_to_color[index].count() > isp_to_color[many].count()) many = index; if (isp_to_color[index].count() < isp_to_color[few].count()) few = index; } if ((isp_to_color[many].count() > 1) && (isp_to_color[many].count() > isp_to_color[few].count())) isp_to_color[few].push(isp_to_color[many].pop()); return true; } public Color GetColor(ISP isp) { for (int index=0 ; index < COLOR_NUM; index++) if (isp_to_color[index].exists(isp)) return COLORS[index]; return Color.black; } public String GetColorName(ISP isp) { for (int index=0 ; index < COLOR_NUM; index++) if (isp_to_color[index].exists(isp)) return COLORS_NAMES[index]; return null; } public void UpdatePipe(Pipe pipe, ISP isp,Color isp_color) { MapNode to = UpdateNode(pipe.to,isp); MapNode from = UpdateNode(pipe.from,isp); if (!OnScreen(to) && !OnScreen(from)) return; mappipes.reset(); MapPipe mappipe; mappipes.reset(); while(!mappipes.end()) { mappipe = (MapPipe) mappipes.next(); if (((mappipe.to == to) && (mappipe.from == from)) || ((mappipe.to == from) && (mappipe.from == to))) { mappipe.pipes.push(pipe); return; } } mappipe = new MapPipe(to,from,pipe); mappipe.my_color = isp_color; mappipes.push(mappipe); return ; } public MapNode UpdateNode(Node node,ISP isp) { float shift = 0; float middle = (bot_lon + top_lon) /2; while (node.lon +shift > middle + 180) shift -= 360; while (node.lon + shift < middle -180) shift += 360; mapnodes.reset(); int[] xy = ToMap(node.lat,node.lon + shift); mapnodes.reset(); MapNode mapnode = null; while(!mapnodes.end() && mapnode == null) { mapnode = (MapNode) mapnodes.next(); if ((mapnode.x == xy[0]) && (mapnode.y == xy[1])) { if (!mapnode.nodes.exists(node)) mapnode.AddNode(node); if (mapnode.my_color == NODE_COLOR) if (mapnode.peered(isp)) mapnode.my_color = PEER_COLOR; } else mapnode = null; } if (mapnode == null) { mapnode = new MapNode(xy[0],xy[1],node,NODE_COLOR); if (mapnode.peered(isp)) mapnode.my_color = PEER_COLOR; mapnodes.push(mapnode); } MyList links = node.links; links.reset(); while(!links.end()) { Link link = (Link) links.next(); if (isps.exists(link.isp)) { mapnode.AddLink(link); SetColor(link.cloud); } } return mapnode; } public int[] ToMap(float lat,float lon) { int[] xy = new int[2]; xy[0] = (int) ( ((lon-top_lon) * width) / (bot_lon-top_lon)); xy[1] = (int) ( ((top_lat-lat) * height) / (top_lat - bot_lat)); return xy; } public float[] FromMap(int x, int y) { float[] lat_long = new float[2]; lat_long[0] = top_lat - ((float) y*(top_lat - bot_lat) / (float) height); lat_long[1] = top_lon + ((float) x*(bot_lon - top_lon) / (float) width); if (lat_long[1] < -180) lat_long[1] += 360; return lat_long; } public boolean mouseMove(Event e, int x, int y) { int SIZE = (NODE_WIDTH+(size/2))*(NODE_WIDTH+(size/2)); double smallest = SIZE; Object pick = null; int type = -1; mapnodes.reset(); while(!mapnodes.end()) { MapNode mapnode = (MapNode) mapnodes.next(); if ( OnScreen(mapnode)) { int X = mapnode.x - x; int Y = mapnode.y - y; int Z = X*X + Y*Y; if (Z <= smallest) { pick = mapnode; smallest = Z; type = NODE; } } } if (pick == null) { mappipes.reset(); while(!mappipes.end()) { MapPipe mappipe = (MapPipe) mappipes.next(); if ( Show_Off_Links || (OnScreen(mappipe.to) && OnScreen(mappipe.from))) { int low_x = mappipe.from.x; int high_x = mappipe.to.x; int low_y = mappipe.from.y; int high_y = mappipe.to.y; if (mappipe.to.x < mappipe.from.x) { low_x = mappipe.to.x; high_x = mappipe.from.x; } if (mappipe.to.y < mappipe.from.y) { low_y = mappipe.to.y; high_y = mappipe.from.y; } if (low_x <= x && high_x >= x && low_y <= y && high_y >= y) { double Xn = mappipe.to.y - mappipe.from.y; double Yn = mappipe.from.x - mappipe.to.x; double Z = (y*Yn + x*Xn - mappipe.to.y*Yn - mappipe.to.x*Xn); Z = Z * Z / ( Xn*Xn + Yn*Yn); if (Z <= smallest) { pick = mappipe; smallest = Z; type = PIPE; } } } } } if ((pick != null) && (pick != selected)) { Graphics g = this.getGraphics(); Object old = selected; selected = pick; if (what_selected == NODE) DrawNode(g,(MapNode) old); else if (what_selected == PIPE) DrawLines(g,(MapPipe) old); what_selected = type; if (applet.status.countItems() > 0) applet.status.clear(); if (type == NODE) { MapNode mapnode = (MapNode) pick; MyList nodes = mapnode.nodes; nodes.reset(); while(!nodes.end()) { Node node = (Node) nodes.next(); applet.writeNode(node,isps); } DrawNode(g,mapnode); } else { applet.write(""); applet.write(" Pipes "); applet.write("----------"); MapPipe mappipe = (MapPipe) pick; MyList pipes = mappipe.pipes; pipes.reset(); while(!pipes.end()) { Pipe pipe = (Pipe) pipes.next(); applet.write(pipe.bandwidth + " " + pipe.isp.name); applet.write(" " + pipe.to.name + "<->" + pipe.from.name); } DrawLines(g,mappipe); } //repaint(); } return true; } public boolean mouseDown(Event e, int x, int y) { if (applet.Zoom_Mode.getSelectedItem().equals(applet.MOVE_MODE)) Zoom(x,y,1); if (applet.Zoom_Mode.getSelectedItem().equals(applet.ZOOM_IN_MODE)) Zoom(x,y,1/ZoomFactor); if (applet.Zoom_Mode.getSelectedItem().equals(applet.ZOOM_OUT_MODE)) Zoom(x,y,ZoomFactor); return super.mouseDown(e,x,y); } public void ZoomWorld() { float lon = (top_lon + bot_lon) /2; float lat = (top_lat + bot_lat) /2; float zoom = 360/(bot_lon - top_lon); Zoom(lon,lat,zoom); } public void Zoom(float t_lon, float t_lat, float b_lon, float b_lat) { while (t_lon >= b_lon) b_lon += 360; float lon = (t_lon + b_lon)/2; float lat = (t_lat + b_lat)/2; float zoom = (b_lon - t_lon)/(bot_lon - top_lon); Zoom(lon,lat,zoom); } public void Zoom(double t_lon, double t_lat, double b_lon, double b_lat) { Zoom((float) t_lon, (float) t_lat, (float) b_lon, (float) b_lat); } public void Zoom (int x, int y, float zoom) { float latlong[] = FromMap(x,y); Zoom(latlong[1],latlong[0],zoom); } public void Zoom (float lon, float lat, float zoom) { float lat_size,lon_size; if (top_lat < bot_lat) lat_size = (bot_lat - top_lat) * zoom; else lat_size = (top_lat - bot_lat) * zoom; if (top_lon < bot_lon) lon_size = (bot_lon - top_lon) * zoom; else lon_size = (top_lon - bot_lon) * zoom; if (lon_size/360 < MAX_ZOOM) return; if (lat_size > 180) { lon_size = lon_size*180/lat_size; lat_size = 180; } if (lon_size > 360) { lat_size = lat_size *360/lon_size; lon_size = 360; } /* System.err.println("lat_size:" + lat_size + " lon_size:" + lon_size + " zoom:" + zoom); System.err.println(" latlon[0]:" + latlong[0] + " latlong[1]:" + latlong[1]); */ float t_lat = lat + lat_size/2; float t_lon = lon - lon_size/2; float b_lat = lat - lat_size/2; float b_lon = lon + lon_size/2; while (t_lon < -180) { t_lon += 360; b_lon += 360; } while (t_lon > 180) { t_lon -= 360; b_lon -= 360; } if (t_lat > 90) { b_lat -= t_lat - 90; t_lat = 90; } else if (b_lat < -90) { t_lat -= b_lat + 90; b_lat = -90; } top_lon = t_lon; top_lat = t_lat; bot_lon = b_lon; bot_lat = b_lat; if (worldProducer != null) worldProducer.abort(); worldProducer.setBox(top_lon,top_lat,bot_lon,bot_lat); image = createImage (worldProducer); Update(); DrawClear(getGraphics()); repaint(); } public void Clear_ISP() { isps = new MyList(); for (int color =0; color < COLOR_NUM; color++) isp_to_color[color] = new MyList(); mappipes = new MyList(); mapnodes = new MyList(); applet.DeselectAllISP(); repaint(); } } class MyNode extends Object { public Object value; public MyNode next; public MyNode(Object val) { value = val; next = null; } } class MyList extends Object { MyNode first; MyNode tail; MyNode before; MyNode where; public MyList() { where=tail = first = null; } public MyList(MyList list) { if (list.first == null) { tail = first = null; return; } tail = first =new MyNode(list.first.value); tail.next = null; MyNode his = list.first.next; tail = first; while (his != null) { tail.next = new MyNode(his.value); tail = tail.next; his = his.next; } reset(); } public void push(Object value) { MyNode temp = new MyNode(value); if (first == null) { tail = first = temp; first.next = null; return; } temp.next = first; first = temp; temp = null; } public void enqueue(Object value) { MyNode temp = new MyNode(value); if (first == null) { tail = first = temp; first.next = null; return; } tail.next = temp; tail = tail.next; tail.next = null; } public Object top () { if (first != null) return first.value; else return null; } public Object pop () { if (first == null) return null; if (first == where) where = first.next; Object value = first.value; first = first.next; return value; } public boolean empty() { return (first == null); } public boolean exists(Object value) { MyNode current = first; while (current != null) { if (current.value == value) return true; current = current.next; } return false; } public boolean drop(Object value) { MyNode previous = first; MyNode current = first; while (current != null) { if (current.value == value) { if (current == first) { previous = first = first.next; } else previous.next = current.next; if (before == current) before = previous; else if (where == current) where = current.next; if (current == tail) tail = previous; return true; } previous = current; current = current.next; } return false; } public int count() { int count = 0; MyNode current = first; while(current != null) { count++; current = current.next; } return count; } public Object where() { if (where != null) return where.value; else return null; } public Object next() { if (where == null) return null; Object temp = where.value; before = where; where = where.next; return temp; } public Object remove() { if (where == null) return null; if (before == null) first = first.next; MyNode temp = where; before.next = where.next; where = where.next; return temp.value; } public void insert(Object value) { MyNode node = new MyNode (value); if (before == null) { node.next = first; first = node; } else { node.next = before.next; before.next = node; } where = node; } public void reset() { before = null; where = first; } public boolean end() { return (where == null); } } class Index extends MyList { MyList list; MyNode before; MyNode current; public Index (MyList l) { list = l; before = null; current = list.first; } public Object where() { return current.value; } public Object next() { if (current == null) return null; Object temp = current.value; before = current; current = current.next; return temp; } public Object remove() { if (current == null) return null; if (before == null) list.first = list.first.next; MyNode temp = current; before.next = current.next; current = current.next; return temp.value; } public void reset() { current = list.first; } public boolean end() { return (current == null); } }