Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Adding babel-tool for Babel network visualization

  • Loading branch information...
commit 2fa710a1edb41e4aa136fbab0ae326481f2f7925 1 parent 368418e
@Sitwon Sitwon authored
Showing with 5,150 additions and 0 deletions.
  1. +19 −0 babel-tool/LICENSE
  2. +33 −0 babel-tool/build.properties
  3. +185 −0 babel-tool/build.xml
  4. +716 −0 babel-tool/src/BabelDraw.java
  5. +31 −0 babel-tool/src/BabelEvent.java
  6. +52 −0 babel-tool/src/BabelItem.java
  7. +49 −0 babel-tool/src/BabelListener.java
  8. +470 −0 babel-tool/src/BabelReader.java
  9. +30 −0 babel-tool/src/Error.java
  10. +84 −0 babel-tool/src/InetAddressPrefix.java
  11. +39 −0 babel-tool/src/LexAction.java
  12. +30 −0 babel-tool/src/LexError.java
  13. +40 −0 babel-tool/src/LexList.java
  14. +48 −0 babel-tool/src/LexObject.java
  15. +43 −0 babel-tool/src/LexString.java
  16. +49 −0 babel-tool/src/LexUnit.java
  17. +42 −0 babel-tool/src/Lexer.java
  18. +33 −0 babel-tool/src/LineShape.java
  19. +277 −0 babel-tool/src/MainFrame.java
  20. +224 −0 babel-tool/src/MainFrame_UI.form
  21. +209 −0 babel-tool/src/MainFrame_UI.java
  22. +44 −0 babel-tool/src/NameAndColorDialog.java
  23. +390 −0 babel-tool/src/NameAndColorDialog_UI.form
  24. +310 −0 babel-tool/src/NameAndColorDialog_UI.java
  25. +43 −0 babel-tool/src/Neighbour.java
  26. +159 −0 babel-tool/src/PanelBabel.java
  27. +56 −0 babel-tool/src/PanelBabel_UI.form
  28. +57 −0 babel-tool/src/PanelBabel_UI.java
  29. +198 −0 babel-tool/src/PanelInfoRouter.java
  30. +515 −0 babel-tool/src/PanelInfoRouter_UI.form
  31. +356 −0 babel-tool/src/PanelInfoRouter_UI.java
  32. +137 −0 babel-tool/src/PanelNeigh.java
  33. +30 −0 babel-tool/src/ParseError.java
  34. +45 −0 babel-tool/src/Route.java
  35. +45 −0 babel-tool/src/Router.java
  36. +42 −0 babel-tool/src/XRoute.java
  37. +13 −0 babel-tool/tools/run_ant.bat
  38. +7 −0 babel-tool/tools/set_classpath.sh
View
19 babel-tool/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
View
33 babel-tool/build.properties
@@ -0,0 +1,33 @@
+# Override the ant.project.name property
+ant.project.name=BabelTool
+
+# The Main class for the project
+main=BabelDraw
+
+# Options for the 'run' target
+run.args=
+run.dir=
+
+# Additional libraries (those not in ${lib})
+# colon-delimited list
+libs=
+
+# Additions to the Classpath (those not in ${lib})
+# space-delimited list
+classpath=
+
+# Debugging options
+debug=true
+debuglevel=lines,vars,source
+
+# Common directory paths
+src=src
+test=src
+lib=lib
+build=build
+dist=dist
+javadoc=${dist}/javadoc
+
+# Uncomment this line to enable JUnit testing.
+# It only requires a value if JUnit is not in the classpath.
+#junit.path=
View
185 babel-tool/build.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- A valid XML document requires a declaration as the first line. -->
+<!-- The @encoding attribute is optional, but if specified it should be correct. -->
+
+<!-- The root element of an Ant build file.
+Valid attributes are @name, @default, and @basedir.
+
+@name = This sets the ant.project.name property. (Optional)
+We are skipping it here to set it later in the properties file.
+
+@default = The default target. The name of the target to run if none are specified
+on the command-line. (Optional)
+We are using the meta-target 'all' for configurability.
+
+@basedir = The base directory for all relative paths. (Optional)
+-->
+<project default="all" basedir=".">
+ <!-- Load the properties file containing the project-specific configuration. -->
+ <loadproperties srcFile="build.properties"/>
+
+ <property name="x-jarfile" location="${dist}/${ant.project.name}.jar"/>
+
+ <!-- Initialization target. -->
+ <target name="init">
+ <!-- Initialize the timestamp properties. -->
+ <tstamp/>
+
+ <!-- Make sure the src and lib directories exist. -->
+ <mkdir dir="${src}"/>
+ <mkdir dir="${test}"/>
+ <mkdir dir="${lib}"/>
+
+ <!-- Create the build directory. -->
+ <mkdir dir="${build}"/>
+ </target>
+
+ <!-- Meta-target. Just specifies the default target(s) when none is specified on the command-line. -->
+ <target name="all" depends="jar, test"/>
+
+ <!-- Distribute target. Here we prepare for distribution to a customer. -->
+ <target name="dist" depends="clean, jar, javadoc" />
+
+ <!-- Compile target. Here we compile the .java files to .class files. -->
+ <target name="compile" depends="init">
+ <!-- Call javac.
+ Compile the files in @srcdir and place the classes in @destdir.
+ @includeantruntime = Don't want Ant run-time libraries in the classpath.
+ @debug = Include debugging information in the .class files.
+ @debuglevel = Include line numbers, variable names, and lines of source.
+ -->
+ <javac srcdir="${src}"
+ destdir="${build}"
+ includeantruntime="false"
+ debug="${debug}"
+ debuglevel="${debuglevel}">
+ <!-- Include these libraries in the classpath. -->
+ <classpath>
+ <pathelement path="${libs}"/>
+ <fileset dir="${lib}">
+ <include name="**/*.jar"/>
+ </fileset>
+ </classpath>
+ </javac>
+ </target>
+
+ <!-- Compile the unit tests. -->
+ <target name="compile-tests" depends="compile">
+ <javac srcdir="${test}"
+ destdir="${build}"
+ includeantruntime="false"
+ debug="${debug}"
+ debuglevel="${debuglevel}">
+ <classpath>
+ <pathelement path="${build}"/>
+ <pathelement path="${junit.path}"/>
+ <pathelement path="${libs}"/>
+ <fileset dir="${lib}">
+ <include name="**/*.jar"/>
+ </fileset>
+ </classpath>
+ </javac>
+ </target>
+
+ <!-- Test target. Make sure all the unit tests pass. -->
+ <target name="test" depends="compile, compile-tests" if="junit.path">
+ <junit fork="yes" haltonfailure="yes">
+ <classpath>
+ <pathelement path="${build}"/>
+ <pathelement path="${junit.path}"/>
+ <pathelement path="${libs}"/>
+ <fileset dir="${lib}">
+ <include name="**/*.jar"/>
+ </fileset>
+ </classpath>
+
+ <!-- Format and report the test results to the console. -->
+ <formatter type="plain" usefile="no"/>
+
+ <!-- Consider all classes named Test* to be unit tests and run them. -->
+ <batchtest>
+ <fileset dir="${test}">
+ <include name="**/Test*.java"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <!-- Make-jar target. Here we make the Jar file that will be distributed. -->
+ <target name="jar" depends="compile">
+ <!-- Create the distributable directory. -->
+ <mkdir dir="${dist}"/>
+
+ <!-- Create the lib sub directory for the third-party libraries we depend on. -->
+ <mkdir dir="${dist}/lib"/> <!-- this should be conditional on whether or not we have any libs -->
+
+ <!-- Copy the dependent libs to the lib folder.
+ @overwrite = Overwrite exiting (potentially older) versions.
+ @flatten = Don't create subdirectories in the @todir.
+ -->
+ <copy todir="${dist}/lib" overwrite="true" flatten="true">
+ <fileset dir="${lib}"/>
+ </copy>
+
+ <!-- Create a normalized Classpath to point to our libs -->
+ <pathconvert pathsep=" " property="x.classpath">
+ <fileset dir="${lib}"/>
+ <chainedmapper>
+ <flattenmapper/>
+ <globmapper from="*" to="lib/*"/>
+ </chainedmapper>
+ </pathconvert>
+
+ <!-- Create the Jar file for our project in the distributable directory. -->
+ <jar jarfile="${x-jarfile}">
+ <!-- Include compiled classes -->
+ <fileset dir="${build}"/>
+
+ <!-- Include source code, but exclude temporary editor files -->
+ <fileset dir="${src}" excludes="**/.*.swp **/*~"/>
+
+ <manifest>
+ <!-- Set's the Main class.
+ This is the class who's main() method will be called by default.
+ -->
+ <attribute name="Main-Class" value="${main}"/>
+
+ <!-- Set the Classpath to use when the Main-Class is executed. -->
+ <attribute name="Class-Path" value="${x.classpath} ${classpath}"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <!-- Javadoc target. Generate the Javadoc for the project. -->
+ <target name="javadoc" depends="init">
+ <!-- Create the directory for the project's documentation. -->
+ <mkdir dir="${javadoc}"/>
+
+ <!-- Generate the Javadoc -->
+ <javadoc destdir="${javadoc}">
+ <fileset dir="${src}" excludes="**/.*.swp **/*~"/>
+ <classpath>
+ <pathelement path="${libs}"/>
+ <fileset dir="${lib}">
+ <include name="**/*.jar"/>
+ </fileset>
+ </classpath>
+ </javadoc>
+ </target>
+
+ <!-- Run target. Run the finished product. -->
+ <target name="run" depends="jar">
+ <!-- Run the compiled Jar file using the arguments and directory specified in the properties. -->
+ <java jar="${x-jarfile}" fork="true" dir="${run.dir}">
+ <arg line="${run.args}"/>
+ </java>
+ </target>
+
+ <!-- Clean target. Clean up all the generated files and directories. -->
+ <target name="clean">
+ <delete dir="${javadoc}"/>
+ <delete dir="${dist}"/>
+ <delete dir="${build}"/>
+ </target>
+</project>
+
View
716 babel-tool/src/BabelDraw.java
@@ -0,0 +1,716 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.geom.Ellipse2D;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Vector;
+import java.util.prefs.Preferences;
+import javax.swing.JPanel;
+import javax.swing.Timer;
+
+/*
+ * This is the JPanel where the drawings are done. It's initialized with a list of routes
+ * created from babel's route table. paintComponent() figures where to draw peers and routes
+ * and add all shapes to the list shapeList which is finally "converted" into an array.
+ * This array is used in the listeners (mouseMotion and mouse listeners) and recreated each time BabelDraw
+is updated (several times per second).
+ */
+
+public class BabelDraw extends JPanel {
+
+ boolean isDrawn = false;
+ double scale = 1, tx, ty, angel = -1.;
+ List<Route> route;
+ List<Router> finale;
+ List<Shape> shapeList = new LinkedList<Shape>();
+ Shape[] shapes;
+ MainFrame parent;
+ List<Route> neighbour;
+
+ public BabelDraw(String name, MainFrame mf) {
+ super();
+ setName(name);
+ route =(List<Route>) mf.panelRoute.rows;
+ parent = mf;
+ this.isDrawn = false;
+ setFocusable(true);
+
+
+ this.neighbour = setRouter();
+ new Timer(100, new ActionListener() {
+
+ public void actionPerformed(ActionEvent arg0) {
+ parent.updateLists();
+ if (parent.isLinear) {
+ updateSprings();
+ } else {
+ updateSpringsWithAccelerator();
+ }
+
+ BabelDraw.this.updateUI();
+ }
+ }).start();
+
+ setBackground(Color.BLACK);
+ ActionListener zoom = new ActionListener() {
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == parent.zoomIn) {
+ scale += 0.2;
+ }
+
+ if (e.getSource() == parent.zoomOut) {
+ scale -= 0.2;
+ }
+
+ if (scale < 0) {
+ scale = 0;
+ }
+
+ shapeList.clear();
+ updateUI();
+ }
+ };
+
+ parent.zoomIn.addActionListener(zoom);
+ parent.zoomOut.addActionListener(zoom);
+
+ addMouseWheelListener(new MouseWheelListener() {
+
+ public void mouseWheelMoved(MouseWheelEvent mwe) {
+ int clics = mwe.getWheelRotation();
+ if (clics == 0) {
+ return;
+ }
+
+ if (clics < 0) {
+ clics *= -1;
+ scale += 0.1 * clics;
+
+ } else {
+ scale -= 0.1 * clics;
+ }
+
+ if (scale < 0) {
+ scale = 0;
+ }
+ }
+ });
+
+ addMouseListener(new MouseAdapter() {
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+
+ if (!hasFocus()) {
+ requestFocus();
+ }
+
+ if (e.getClickCount() == 2) {
+
+ e.translatePoint((int) -getWidth() / 2, (int) -getHeight() / 2);
+ e.translatePoint((int) -tx, (int) -ty);
+
+ for (int i = 0; i < shapes.length; i++) {
+
+ Shape s = shapes[i];
+
+ if (s instanceof Router && s.contains(e.getPoint())) {
+
+ Router ps = (Router) s;
+ NameAndColorDialog d = new NameAndColorDialog(parent, isDrawn,
+ "Change Name and Color",
+ (String) Preferences.userRoot().get(ps.id, ps.id),
+ ps.oldC,
+ "ME");
+
+ d.setVisible(true);
+ String newName = d.newName;
+ ps.oldC = d.color;
+ ps.c = d.color;
+ d = null;
+ Preferences.userRoot().put(ps.id, newName);
+ repaint();
+ break;
+
+ }
+
+ }
+ }
+ }
+ });
+
+ addMouseMotionListener(new MouseMotionAdapter() {
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ if (!hasFocus()) {
+ requestFocus();
+ }
+
+ Dimension d = BabelDraw.this.getSize();
+ Graphics2D gg = (Graphics2D) getGraphics();
+ gg.translate((int) getWidth() / 2, (int) getHeight() / 2);
+ e.translatePoint((int) -getWidth() / 2, (int) -getHeight() / 2);
+ e.translatePoint((int) -tx, (int) -ty);
+ gg.translate(tx, ty);
+
+
+ // The mouse event translation is a bit weird but its an adjustment due to the translation
+ // for the shapes (the center of panel is (0,0), not (getWidth()/2, getHeight()/2)
+ for (Shape s : shapes) {
+ if (s instanceof Router) {
+ Router r = (Router) s;
+
+ if (s.contains(e.getPoint())) {
+ if (r.c != Color.YELLOW) {
+ r.oldC = r.c;
+ }
+ r.c = Color.YELLOW;
+ gg.setColor(r.c);
+ gg.fill(s);
+
+ parent.infoRouter.setRouter(((Router) s).id);
+
+ }
+
+ if (!s.contains(e.getPoint())) {
+
+ r.c = r.oldC;
+ gg.setColor(r.c);
+ gg.fill(s);
+
+ }
+ }
+
+ }
+
+ }
+ });
+
+
+ addKeyListener(new KeyAdapter() {
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_UP) {
+ ty += 15.0;
+ } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
+ ty += -15.0;
+ } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
+ tx += -15.0;
+ } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
+ tx += 15.0;
+ } else if (e.getKeyCode() == KeyEvent.VK_PAGE_DOWN) {
+ scale -= 0.2;
+ } else if (e.getKeyCode() == KeyEvent.VK_PAGE_UP) {
+ scale += 0.2;
+ } else {
+
+ }
+
+ if (scale < 0) {
+ scale = 0;
+ }
+
+ updateUI();
+ }
+ });
+
+ parent.randomize.addActionListener(new ActionListener() {
+
+ public void actionPerformed(ActionEvent arg0) {
+ if (finale != null) {
+ synchronized (finale) {
+ for (Router r : finale) {
+ r.angle = Math.random() * 2 * Math.PI;
+ r.velocity = 0.0;
+ }
+ }
+ }
+ }
+ });
+
+ parent.jRadioButton1.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ if (finale != null) {
+ synchronized (finale) {
+ for (Router r : finale) {
+ r.angle = Math.random() * 2 * Math.PI;
+ r.velocity = 0.0;
+ }
+ }
+ }
+ }
+ });
+
+ parent.jRadioButton2.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ if (finale != null) {
+ synchronized (finale) {
+ for (Router r : finale) {
+ r.angle = Math.random() * 2 * Math.PI;
+ r.velocity = 0.0;
+ }
+ }
+ }
+ }
+ });
+ }
+
+ public boolean isNeighbour(String id) {
+ for (Route r : route) {
+ if (r.otherValues.get("id").equals(id)) {
+ if (r.otherValues.get("refmetric").equals("0")) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean isMyNeighbour(Route rt, Route neigh) {
+ for (Route r : this.route) {
+ if (((String) r.otherValues.get("via")).equals(rt.otherValues.get("via"))) {
+ if (r.otherValues.get("id").equals(neigh.otherValues.get("id"))) {
+ return true;
+ }
+ }
+
+ }
+ return false;
+ }
+
+ public List<Route> setRouter() {
+ List<Route> result = new Vector<Route>();
+ for (Route r : this.route) {
+ if (r.otherValues.get("refmetric").equals("0")) {
+ result.add(r);
+ }
+ }
+ return result;
+ }
+
+ public double alkashi(double a, double b, double c, String id) {
+ //Return the angle formed with lines of length b and c
+ double calcule = (-1 * c * c + a * a + b * b) / (2 * a * b);
+ if (calcule > 1 || calcule < -1) {
+ return 0;
+ }
+
+ return Math.acos(calcule);
+
+ }
+
+ public boolean isIpv6Gateway(String id) {
+
+ for (Route r : route) {
+
+
+ if (r.otherValues.get("prefix").equals("::/0")) {
+ if (r.otherValues.get("installed").equals("yes")) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean isIpv4Gateway(String id) {
+ for (Route r : route) {
+ if (r.otherValues.get("prefix").equals("0.0.0.0/0")) {
+ if (r.otherValues.get("installed").equals("yes")) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void paintComponent(Graphics g) {
+ boolean drawPeers, drawCircles, drawRoutes, drawNames;
+ drawCircles = parent.circlesChkBx.isSelected();
+ drawPeers = parent.peersChkBx.isSelected();
+ drawRoutes = parent.routesChkBx.isSelected();
+ drawNames = parent.namesChkBx.isSelected();
+ super.paintComponent(g);
+ Graphics2D gg = (Graphics2D) g;
+ gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ gg.setColor(Color.WHITE);
+ Dimension d = getSize();
+
+ gg.translate(d.width / 2, d.height / 2);// Panel's center is 0,0
+ gg.translate(tx, ty);// Apply the current translation
+
+ Point center = new Point(0, 0);
+
+ Collections.sort(route, new Comparator<Route>() {
+
+ public int compare(Route a, Route b) {
+ int res = ((String) a.otherValues.get("id")).compareTo((String) b.otherValues.get("id"));
+ if (res == 0) {
+ return Integer.parseInt((String) a.otherValues.get("metric")) - Integer.parseInt((String) b.otherValues.get("metric"));
+ }
+ return res;
+ }
+ });
+ if (!this.isDrawn) {
+ shapeList.clear();
+ }
+ List<Router> lastFinal = new LinkedList<Router>();
+ if (this.isDrawn) {
+ lastFinal = this.finale;
+ }
+ List<Router> temp = new LinkedList<Router>();
+ double theta = (Math.random() * 1000) % Math.PI;
+ int radius = -1;
+ for (Route r : route) {
+ theta = (Math.random() * 1000) % Math.PI;
+ radius = Integer.parseInt((String) r.otherValues.get("metric"));
+ if (radius >= 65534) {
+ continue;
+ }
+ temp.add(new Router((int) (scale * radius * Math.cos(theta)), (int) (scale * radius * Math.sin(theta)), r, theta));
+ }
+
+ String lastId = null;
+ this.finale = new LinkedList<Router>();
+ for (Router r : temp) {
+ r.x = scale * r.x - Router.radius;
+ r.y = scale * r.y - Router.radius;
+ if (!r.id.equals(lastId)) {
+ finale.add(r);
+ }
+
+ lastId = r.id;
+ }
+ if (this.isDrawn == false) {
+ finale.add(new Router((int) (scale * center.x), (int) (scale * center.y), new Route("Me", new Hashtable()), 0));
+ }
+ if (this.isDrawn) {
+ int cmpt = 0;
+ for (int i = 0; i < this.finale.size(); i++) {
+
+ int res = this.finale.get(i).id.compareTo(lastFinal.get(cmpt).id);
+ radius = 0;
+ if (res == 0) {
+ radius = Integer.parseInt((String) this.finale.get(i).route.otherValues.get("metric"));
+ int lastRadius = Integer.parseInt((String) lastFinal.get(cmpt).route.otherValues.get("metric"));
+ if (radius == lastRadius) {
+ this.finale.remove(i);
+ this.finale.add(i, lastFinal.get(cmpt));
+ } else {
+ this.finale.get(i).angle = lastFinal.get(cmpt).angle;
+ this.finale.get(i).x = (int) (scale * radius * Math.cos(this.finale.get(i).angle));
+ this.finale.get(i).y = (int) (scale * radius * Math.sin(this.finale.get(i).angle));
+ }
+ }
+ if (res < 0) {
+ continue;
+ }
+ if (res > 0) {
+ i--;
+ }
+ cmpt++;
+ }
+
+ finale.add(lastFinal.get(lastFinal.size() - 1));
+ shapeList.clear();
+ }
+ List<Router> neigh = new LinkedList<Router>();
+ for (Router r : this.finale) {
+ if (r.id.equals("Me")) {
+ continue;
+ }
+ if (r.route.otherValues.get("refmetric") == null) {
+ continue;
+ }
+ if (r.route.otherValues.get("refmetric").equals("0")) {
+ neigh.add(r);
+ }
+ }
+
+ for (Router r : neigh) {
+ for (Router rt : this.finale) {
+ if (r.id.equals("Me") || rt.id.equals("Me")) {
+ continue;
+ }
+ if (rt.route.otherValues.get("refmetric").equals("0")) {
+ continue;
+ }
+ if (isNeighbour(r.id) && !this.isDrawn) {
+ shapeList.add(new LineShape((String) rt.route.otherValues.get("id"), r.x + Router.radius, r.y + Router.radius, rt.x + Router.radius, rt.y + Router.radius));
+ }
+ if (isMyNeighbour(r.route, rt.route) && this.isDrawn) {
+ shapeList.add(new LineShape((String) rt.route.otherValues.get("id"), r.x + Router.radius, r.y + Router.radius, rt.x + Router.radius, rt.y + Router.radius));
+ }
+ }
+ }
+
+ for (Router r : finale) {
+ if (r.id.equals("Me")) {
+ if (drawPeers && this.isDrawn) {
+ shapeList.add(r);
+
+ }
+ continue;
+ }
+ radius = Integer.parseInt((String) r.route.otherValues.get("metric"));
+ r.x = (int) (scale * (radius * Math.cos(r.angle)) - Router.radius);
+ r.y = (int) (scale * (radius * Math.sin(r.angle)) - Router.radius);
+ if (drawCircles) {
+ shapeList.add(new Ellipse2D.Double(center.x - scale * radius, center.y - scale * radius, scale * radius * 2, scale * radius * 2));
+ }
+
+ if (drawRoutes) {
+ if (r.route.otherValues.get("refmetric").equals("0")) {
+ shapeList.add(new LineShape((String) r.route.otherValues.get("id"), center.x, center.y, r.x + Router.radius, r.y + Router.radius));
+ }
+ }
+ if (drawPeers) {
+ shapeList.add(r);
+ }
+
+ }
+
+
+ shapes = shapeList.toArray(new Shape[0]); // Stores all shapes in an array
+ //(faster than anything else)
+ gg.setColor(Color.WHITE);
+ for (Shape s : shapes) {
+
+ if (s instanceof Router) {
+ if (drawPeers) {
+ gg.setColor(((Router) s).c);
+ gg.fill(s);
+ gg.setColor(Color.WHITE);
+ }
+
+ Preferences pref = Preferences.userRoot();
+ Router pshap = (Router) s;
+ if (drawNames) {
+
+ gg.setColor(Color.CYAN);
+
+ gg.drawString((String) pref.get(pshap.id, pshap.id), (float) pshap.getX(), (float) pshap.getY() + 30);
+ gg.setColor(Color.WHITE);
+
+ }
+
+ } else if (s instanceof LineShape) {
+ if (isIpv6Gateway(((LineShape) s).id)) {
+ gg.setColor(Color.YELLOW);
+ }
+
+ if (isIpv4Gateway(((LineShape) s).id)) {
+ gg.setColor(Color.BLUE);
+ }
+
+ if (isIpv6Gateway(((LineShape) s).id) && isIpv4Gateway(((LineShape) s).id)) {
+ gg.setColor(Color.GREEN);
+ }
+
+ gg.draw(s);
+ gg.setColor(Color.WHITE);
+
+ } else {
+ gg.draw(s);
+
+ }
+
+ }
+ this.isDrawn = true;
+ }
+
+ public int findRefMetric(String id, Route neigh) {
+ int res = -1, tmp;
+ for (int i = 0; i < route.size(); i++) {
+ if (route.get(i) instanceof Route) {
+ Route a = (Route) route.get(i);
+ if (a.otherValues.get("id").equals(id) && isMyNeighbour(a, neigh)) {
+ tmp = Integer.parseInt((String) a.otherValues.get("refmetric"));
+ if (res == -1 || res < tmp) {
+ res = tmp;
+ }
+ }
+ }
+ }
+
+ return res;
+ }
+
+ public static double angleDiff(double a, double b) {
+ double d = b - a;
+ if (d <= -Math.PI) {
+ return d + 2 * Math.PI;
+ } else if (d > Math.PI) {
+ return d - 2 * Math.PI;
+ } else {
+ return d;
+ }
+ }
+
+ public void updateSprings() {
+ if (finale == null) {
+ return;
+ }
+ for (Shape s1 : finale) {
+ Router pshap1 = (Router) s1;
+ if (!isNeighbour(pshap1.id)) {
+ continue;
+ }
+ for (Shape s2 : finale) {
+ if (s1 == s2) {
+ continue;
+ }
+ Router pshap2 = (Router) s2;
+ if (pshap2.id.equals("Me")) {
+ continue;
+ }
+
+ double drawAngle = angleDiff(pshap1.angle, pshap2.angle + Math.random() / 20);
+ double a, b;
+ a = Integer.parseInt((String) pshap1.route.otherValues.get("metric"));
+ b = Integer.parseInt((String) pshap2.route.otherValues.get("metric"));
+ int c1 = findRefMetric(pshap1.id, pshap2.route), c2 = findRefMetric(pshap2.id, pshap1.route);
+
+ int c = 0;
+
+ if (c1 == 0 && c2 == 0) {
+ return;
+ } else if (c1 * c2 < 0) {
+ c = -1 * c1 * c2;
+ } else if (c1 * c2 == 0) {
+ c = c1 == 0 ? c2 : c1;
+ } else {
+ c = (c1 + c2) / 2;
+ }
+ double realAngle = alkashi(a, b, c, pshap2.id);
+ if (realAngle == 0) {
+ continue;
+ }
+ double diff = angleDiff(drawAngle, realAngle);
+ pshap1.angle += diff / 800;
+ pshap2.angle -= diff / 800;
+
+ }
+ }
+
+
+ }
+
+ public void updateSpringsWithAccelerator() {
+ if (finale == null) {
+ return;
+ }
+ for (Shape s1 : finale) {
+ Router pshap1 = (Router) s1;
+ if (!isNeighbour(pshap1.id)) {
+ continue;
+ }
+ for (Shape s2 : finale) {
+ if (s1 == s2) {
+ continue;
+ }
+ Router pshap2 = (Router) s2;
+ if (pshap2.id.equals("Me")) {
+ continue;
+ }
+
+ double drawAngle = angleDiff(pshap1.angle, pshap2.angle + Math.random() / 20);
+ double a, b;
+ a = Integer.parseInt((String) pshap1.route.otherValues.get("metric"));
+ b = Integer.parseInt((String) pshap2.route.otherValues.get("metric"));
+ int c1 = findRefMetric(pshap1.id, pshap2.route), c2 = findRefMetric(pshap2.id, pshap1.route);
+
+ int c = 0;
+
+ if (c1 <= 0 && c2 <= 0) {
+ c = 96;
+ } else if (c1 * c2 < 0) {
+ c = -1 * c1 * c2;
+ } else if (c1 * c2 == 0) {
+ c = c1 == 0 ? c2 : c1;
+ } else {
+ c = (c1 + c2) / 2;
+ }
+ double realAngle = alkashi(a, b, c, pshap2.id);
+ if (realAngle == 0) {
+ continue;
+ }
+ double diff = angleDiff(drawAngle, realAngle);
+ pshap1.velocity *= 0.8; pshap1.velocity += diff / 500;
+ pshap2.velocity *= 0.8; pshap2.velocity -= diff / 500;
+ pshap1.angle += pshap1.velocity;
+ pshap2.angle += pshap2.velocity;
+ }
+ }
+ }
+
+ public static void main(final String[] args) {
+
+ new Thread(new Runnable() {
+
+ public void run() {
+ int port = 33123;
+ int cmpt = 0;
+ for (String s : args) {
+ if (s.equals("-p")) {
+ try {
+ port = Integer.parseInt(args[cmpt + 1]);
+ } catch (Exception e) {
+ port = 33123;
+ }
+ }
+ cmpt++;
+ }
+ MainFrame mf = new MainFrame("BabelTool", port);
+ mf.pack();
+ mf.setSize(800, 800);
+ mf.setLocationRelativeTo(null);
+
+ mf.setVisible(true);
+ }
+ }).start();
+ }
+}
View
31 babel-tool/src/BabelEvent.java
@@ -0,0 +1,31 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+import java.util.EventObject;
+
+
+public class BabelEvent extends EventObject{
+ BabelItem item;
+ public BabelEvent(BabelReader BR, BabelItem item){
+ super(BR);
+ this.item=item;
+ }
+}
View
52 babel-tool/src/BabelItem.java
@@ -0,0 +1,52 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+import java.util.Hashtable;
+
+
+public abstract class BabelItem {
+
+ public String id;
+ public Hashtable otherValues;
+ public int position=-1;
+ public BabelItem(String s, Hashtable otherValues) {
+ this.id = s;
+ this.otherValues = otherValues;
+ }
+
+
+ public String getId(){
+ return id;
+ }
+ @Override
+ public boolean equals(Object o) {
+ BabelItem item = (BabelItem) o;
+ return this.id.equals(item.id);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 83 * hash + (this.id != null ? this.id.hashCode() : 0);
+ return hash;
+ }
+}
View
49 babel-tool/src/BabelListener.java
@@ -0,0 +1,49 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+import java.util.EventListener;
+
+
+public interface BabelListener extends EventListener{
+
+ public void addRoute(BabelEvent e);
+
+ public void addXRoute(BabelEvent e);
+
+ public void addNeigh(BabelEvent e);
+
+ public void changeRoute(BabelEvent e);
+
+ public void changeXRoute(BabelEvent e);
+
+ public void changeNeigh(BabelEvent e);
+
+ public void flushRoute(BabelEvent e);
+
+ public void flushXRoute(BabelEvent e);
+
+ public void flushNeigh(BabelEvent e);
+
+ public void somethingHappening(BabelEvent e);
+ //Invoked for all kinds of changes, just before add/change/flush call
+
+}
View
470 babel-tool/src/BabelReader.java
@@ -0,0 +1,470 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+ */
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.net.Socket;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+
+import javax.swing.JOptionPane;
+import javax.swing.Timer;
+
+
+public class BabelReader extends Thread {
+
+ List<Route> route;
+ List<XRoute> xroute;
+ List<Neighbour> neighbour;
+ List<BabelListener> listeners = Collections.synchronizedList(new LinkedList<BabelListener>());
+ MainFrame mf;
+ static Socket sock;
+ Timer tea;
+ static int port = 33123;
+ String host = "::1";
+ public static boolean updateNeigh = false;
+ public static boolean updateRoute = false;
+ public static boolean updateXRoute = false;
+
+ public BabelReader(int port,MainFrame mf) {
+ setName("BabelReader");
+ BabelReader.port = port;
+ this.mf=mf;
+ this.route = Collections.synchronizedList(new LinkedList<Route>());
+ this.xroute = Collections.synchronizedList(new LinkedList<XRoute>());
+ this.neighbour = Collections.synchronizedList(new LinkedList<Neighbour>());
+ tea = new Timer(500, new ActionListener() {
+
+ public void actionPerformed(ActionEvent arg0) {
+ if (sock == null) {
+ return;
+ }
+ if (sock.isClosed()) {
+
+ JOptionPane.showMessageDialog(null, "Connection error : babel is unreachable.", "Can't connect to " + host + " " + BabelReader.this.port, JOptionPane.ERROR_MESSAGE);
+
+ tea.stop();
+ }
+
+ }
+ });
+ tea.start();
+ }
+
+ public void addBabelListener(BabelListener bl) {
+ listeners.add(bl);
+ }
+
+ public BabelListener removeBabelListener(BabelListener bl) {
+ if (listeners.contains(bl)) {
+ listeners.remove(bl);
+ return bl;
+ }
+ return null;
+ }
+
+ private void notifyListenersAddRoute(Route r) {
+ synchronized (listeners) {
+ BabelEvent be = new BabelEvent(this, r);
+ for (BabelListener bl : listeners) {
+ bl.somethingHappening(be);
+ bl.addRoute(be);
+ }
+ BabelReader.updateRoute = true;
+ }
+ }
+
+ private void notifyListenersChangeRoute(Route r) {
+ synchronized (listeners) {
+ BabelEvent be = new BabelEvent(this, r);
+ for (BabelListener bl : listeners) {
+ bl.somethingHappening(be);
+ bl.changeRoute(be);
+ }
+ }
+ }
+
+ private void notifyListenersFlushRoute(Route r) {
+ synchronized (listeners) {
+ BabelEvent be = new BabelEvent(this, r);
+ for (BabelListener bl : listeners) {
+ bl.somethingHappening(be);
+ bl.flushRoute(be);
+ }
+ BabelReader.updateRoute = true;
+ }
+ }
+
+ private void notifyListenersAddXRoute(XRoute xr) {
+ synchronized (listeners) {
+ BabelEvent be = new BabelEvent(this, xr);
+ for (BabelListener bl : listeners) {
+ bl.somethingHappening(be);
+ bl.addXRoute(be);
+ }
+ BabelReader.updateXRoute = true;
+ }
+ }
+
+ private void notifyListenersChangeXRoute(XRoute xr) {
+ synchronized (listeners) {
+ BabelEvent be = new BabelEvent(this, xr);
+ for (BabelListener bl : listeners) {
+ bl.somethingHappening(be);
+ bl.changeXRoute(be);
+ }
+ }
+ }
+
+ private void notifyListenersFlushXRoute(XRoute xr) {
+ synchronized (listeners) {
+ BabelEvent be = new BabelEvent(this, xr);
+ for (BabelListener bl : listeners) {
+ bl.somethingHappening(be);
+ bl.flushXRoute(be);
+ }
+ BabelReader.updateXRoute = true;
+ }
+ }
+
+ private void notifyListenersAddNeigh(Neighbour n) {
+ synchronized (listeners) {
+ BabelEvent be = new BabelEvent(this, n);
+ for (BabelListener bl : listeners) {
+ bl.somethingHappening(be);
+ bl.addNeigh(be);
+ }
+ BabelReader.updateNeigh = true;
+ }
+ }
+
+ private void notifyListenersChangeNeigh(Neighbour n) {
+ synchronized (listeners) {
+ BabelEvent be = new BabelEvent(this, n);
+ for (BabelListener bl : listeners) {
+ bl.somethingHappening(be);
+ bl.changeNeigh(be);
+ }
+ }
+ }
+
+ private void notifyListenersFlushNeigh(Neighbour n) {
+ synchronized (listeners) {
+ BabelEvent be = new BabelEvent(this, n);
+ for (BabelListener bl : listeners) {
+ bl.somethingHappening(be);
+ bl.flushNeigh(be);
+ }
+ BabelReader.updateNeigh = true;
+ }
+ }
+
+ public Route getRoute(String id) {
+ synchronized (route) {
+ int i = route.indexOf(new Route(id,null));
+ if (i == -1) {
+ return null;
+ } else {
+ return route.get(i);
+ }
+ }
+ }
+
+ public XRoute getXRoute(String id) {
+ synchronized (xroute) {
+ int i = xroute.indexOf(new XRoute(id, null));
+ if (i == -1) {
+ return null;
+ } else {
+ return xroute.get(i);
+ }
+ }
+
+ }
+
+ public Neighbour getNeigh(String id) {
+ synchronized (neighbour) {
+ int i = neighbour.indexOf(new Neighbour(id,null));
+ if (i == -1) {
+ return null;
+ } else {
+ return neighbour.get(i);
+ }
+ }
+
+
+ }
+
+ private void addRoute(LexUnit l) throws ParseError {
+ HashMap<String, String> map = l.list.map;
+ Hashtable more = new Hashtable();
+
+
+ Set<Map.Entry<String, String>> s = map.entrySet();
+ String key = null, value = null;
+ for (Map.Entry<String, String> entry : s) {
+ key = entry.getKey();
+
+ value = entry.getValue();
+ more.put(key, value);
+ }
+
+ Route r = new Route(l.id, more);
+ this.route.add(r);
+ notifyListenersAddRoute(r);
+ }
+
+ private void changeRoute(LexUnit l) throws ParseError {
+ Route r;
+ HashMap<String, String> map = l.list.map;
+ if ((r = getRoute(l.id)) == null) {
+ throw new ParseError("Id not found in route table : "+l.id);
+ }
+
+ Hashtable more = r.otherValues;
+
+ Set<Map.Entry<String, String>> s = map.entrySet();
+ String key = null, value = null;
+ for (Map.Entry<String, String> entry : s) {
+ key = entry.getKey();
+
+ value = entry.getValue();
+ if (more.contains(key)) {
+ more.remove(key);
+ }
+ more.put(key, value);
+
+ }
+ notifyListenersChangeRoute(r);
+ }
+
+ private void flushRoute(LexUnit l) throws ParseError {
+ Route r = getRoute(l.id);
+ if (r == null) {
+ throw new ParseError("Id not found in route table : "+l.id);
+ }
+ r.position=route.indexOf(r);
+ notifyListenersFlushRoute(r);
+ this.route.remove(r);
+ }
+
+ private void addXRoute(LexUnit l) throws ParseError {
+ HashMap<String, String> map = l.list.map;
+
+
+ String id = l.id;
+ Hashtable more = new Hashtable();
+
+ Set<Map.Entry<String, String>> s = map.entrySet();
+ String key = null, value = null;
+ for (Map.Entry<String, String> entry : s) {
+ key = entry.getKey();
+
+ value = entry.getValue();
+ more.put(key, value);
+ }
+
+
+ XRoute xr = new XRoute(id, more);
+ this.xroute.add(xr);
+ notifyListenersAddXRoute(xr);
+
+ }
+
+ private void changeXRoute(LexUnit l) throws ParseError {
+ XRoute xr;
+ HashMap<String, String> map = l.list.map;
+ if ((xr = getXRoute(l.id)) == null) {
+ throw new ParseError("Id not found in xroute table : "+l.id);
+ }
+
+
+ Hashtable more = xr.otherValues;
+
+ Set<Map.Entry<String, String>> s = map.entrySet();
+ String key = null, value = null;
+ for (Map.Entry<String, String> entry : s) {
+ key = entry.getKey();
+
+ value = entry.getValue();
+ if (more.contains(key)) {
+ more.remove(key);
+ }
+ more.put(key, value);
+
+ }
+ notifyListenersChangeXRoute(xr);
+ }
+
+ private void flushXRoute(LexUnit l) throws ParseError {
+ XRoute xr = getXRoute(l.id);
+ if (xr == null) {
+ throw new ParseError("Id not found in xroute table : "+l.id);
+ }
+ xr.position=xroute.indexOf(xr);
+ notifyListenersFlushXRoute(xr);
+ this.xroute.remove(xr);
+ }
+
+ private void addNeighbour(LexUnit l) throws ParseError {
+ HashMap<String, String> map = l.list.map;
+
+ Hashtable more = new Hashtable();
+
+ Set<Map.Entry<String, String>> s = map.entrySet();
+ String key = null, value = null;
+ for (Map.Entry<String, String> entry : s) {
+ key = entry.getKey();
+
+ value = entry.getValue();
+
+
+ more.put(key, value);
+
+ }
+ Neighbour n = new Neighbour(l.id, more);
+ this.neighbour.add(n);
+ notifyListenersAddNeigh(n);
+ }
+
+ private void changeNeighbour(LexUnit l) throws ParseError {
+ Neighbour n;
+ HashMap<String, String> map = l.list.map;
+ if ((n = getNeigh(l.id)) == null) {
+ throw new ParseError("Id not found in neigh table : "+l.id);
+ }
+
+
+ Hashtable more = n.otherValues;
+
+ Set<Map.Entry<String, String>> s = map.entrySet();
+ String key = null, value = null;
+ for (Map.Entry<String, String> entry : s) {
+ key = entry.getKey();
+
+ value = entry.getValue();
+ if (more.contains(key)) {
+ more.remove(key);
+ }
+ more.put(key, value);
+
+ }
+ notifyListenersChangeNeigh(n);
+ }
+
+ private void flushNeighbour(LexUnit l) throws ParseError {
+ Neighbour n = getNeigh(l.id);
+ if (n == null) {
+ throw new ParseError("Id not found in neigh table : "+l.id);
+ }
+ n.position=neighbour.indexOf(n);
+ notifyListenersFlushNeigh(n);
+ this.neighbour.remove(n);
+ }
+
+ public void parsing(String s) {
+ try {
+ String[] t = s.split(" ");
+ if (t.length <= 4) {
+ if (t[0].equals("BABEL")) {
+ if (t[1].charAt(0) != '0' && t[1].charAt(1) != '.') {
+ throw new LexError("List is even (and should be odd)");
+ } else {
+ return;
+ }
+ } else {
+ throw new LexError("Lexing Error problem:" + t[0]);
+ }
+ } else if ((t.length % 2) == 0) {
+ throw new LexError("List is even (and should be odd)");
+ }
+ LexUnit res = new LexUnit(t);
+ if (res.action.action.equals("add")) {
+ if (res.object.object.equals("route")) {
+ this.addRoute(res);
+ } else if (res.object.object.equals("xroute")) {
+ this.addXRoute(res);
+ } else if (res.object.object.equals("neighbour")) {
+ this.addNeighbour(res);
+ }
+ } else if (res.action.action.equals("change")) {
+ if (res.object.object.equals("route")) {
+ this.changeRoute(res);
+ } else if (res.object.object.equals("xroute")) {
+ this.changeXRoute(res);
+ }/* else if (res.object.object.equals("neighbour")) {
+ this.changeNeighbour(res);
+ }*/
+ } else if (res.action.action.equals("flush")) {
+ if (res.object.object.equals("route")) {
+ this.flushRoute(res);
+ } else if (res.object.object.equals("xroute")) {
+ this.flushXRoute(res);
+ } /*else if (res.object.object.equals("neighbour")) {
+ this.flushNeighbour(res);
+ }*/
+ }
+
+ } catch (Error e) {
+ e.printStackTrace();
+ System.err.println("Error when parsing : "+s);
+ }
+ }
+
+ @Override
+ public void run() {
+ Socket s = null;
+ try {
+ s = new Socket(host, port);
+ sock = s;
+ Scanner sc = new Scanner(s.getInputStream());
+
+
+ while (sc.hasNextLine()) {
+ String line = sc.nextLine();
+ this.parsing(line);
+ }
+ } catch (IOException e) {
+ JOptionPane.showMessageDialog(null, "Connection error : babel is unreachable.", "Can't connect to " + host + " " + port, JOptionPane.ERROR_MESSAGE);
+ } catch (Exception e) {
+ System.err.println(e);
+ e.printStackTrace();
+
+ } finally {
+ try {
+ if (s == null) {
+ return;
+ }
+ s.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
View
30 babel-tool/src/Error.java
@@ -0,0 +1,30 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+public class Error extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public Error(String s) {
+ super(s);
+ }
+}
View
84 babel-tool/src/InetAddressPrefix.java
@@ -0,0 +1,84 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+/**
+ *
+ * @author momotte
+ */
+public class InetAddressPrefix {
+
+ private String ip;
+ private int prefix;
+
+ public InetAddressPrefix(String ip_pref) throws LexError {
+ String[] t = ip_pref.split("/");
+ if (t.length != 2) {
+ throw new LexError("LexError : IP in InetAddressPrefix " + "-> " + ip_pref);
+ }
+ prefix = Integer.parseInt(t[1]);
+ ip = t[0];
+ }
+
+ public boolean isIPv4() {
+ try {
+ InetAddress ina = InetAddress.getByName(ip);
+ return (ina instanceof Inet4Address);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public boolean isIPv6() {
+ try {
+ InetAddress ina = InetAddress.getByName(ip);
+ return (ina instanceof Inet6Address);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public boolean isRange() {
+ if (isIPv4()) {
+ return prefix == 32;
+ } else {
+ return prefix == 128;
+ }
+ }
+
+ public long range() {
+ if (isIPv4()) {
+ return (long) Math.pow(2, 32 - prefix);
+ } else {
+ return (long) Math.pow(2, 128 - prefix);
+ }
+ }
+}
View
39 babel-tool/src/LexAction.java
@@ -0,0 +1,39 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+public class LexAction {
+
+ String action;
+
+ public LexAction(String s) throws LexError {
+ if (s.equals("flush") || s.equals("add") || s.equals("change")) {
+ action = s;
+ } else {
+ throw new LexError("Action unknown");
+ }
+
+ }
+
+ public String toString() {
+ return action;
+ }
+}
View
30 babel-tool/src/LexError.java
@@ -0,0 +1,30 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+public class LexError extends Error {
+
+ private static final long serialVersionUID = 1L;
+
+ public LexError(String s) {
+ super(s);
+ }
+}
View
40 babel-tool/src/LexList.java
@@ -0,0 +1,40 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+import java.util.HashMap;
+
+
+public class LexList {
+
+ HashMap<String, String> map = new HashMap<String, String>(2);
+
+ public LexList(String[] t) {
+
+ for (int i = 3; i < t.length - 1; i += 2) {
+ map.put(t[i], t[i + 1]);
+ }
+ }
+
+ public String toString() {
+ return map.toString();
+ }
+}
View
48 babel-tool/src/LexObject.java
@@ -0,0 +1,48 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+public class LexObject {
+
+ static String[] values = {"self", "neighbour", "route", "xroute"};
+ String object;
+
+ public LexObject(String s) throws LexError {
+ if (checkValue(s)) {
+ object = s;
+ } else {
+ throw new LexError("Unknown object " + s);
+ }
+ }
+
+ public static boolean checkValue(String val) {
+ for (int i = 0; i < values.length; i++) {
+ if (val.equals(values[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String toString() {
+ return object;
+ }
+}
View
43 babel-tool/src/LexString.java
@@ -0,0 +1,43 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+public class LexString {
+
+ private String firstKey;
+ private String secondKey;
+
+ public String getFirstKey() {
+ return firstKey;
+ }
+
+ public void setFirstKey(String firstKey) {
+ this.firstKey = firstKey;
+ }
+
+ public String getSecondKey() {
+ return secondKey;
+ }
+
+ public void setSecondKey(String secondKey) {
+ this.secondKey = secondKey;
+ }
+}
View
49 babel-tool/src/LexUnit.java
@@ -0,0 +1,49 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+public class LexUnit {
+
+ LexAction action;
+ LexObject object;
+ String id;
+ LexList list;
+
+ public LexUnit(String[] t) throws LexError {
+ action = new LexAction(t[0]);
+ object = new LexObject(t[1]);
+ id = t[2];
+ list = new LexList(t);
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("Action : " + action + " | ");
+ sb.append("Object : " + object + " | ");
+ sb.append("ID : " + id);
+ sb.append("\n");
+ sb.append("List : " + list);
+ sb.append("\n\n");
+
+ return sb.toString();
+ }
+}
View
42 babel-tool/src/Lexer.java
@@ -0,0 +1,42 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+public class Lexer {
+
+ public static String[] lexing(String s) throws LexError {
+ String[] tmp = s.split(" ");
+ if (tmp.length < 3) {
+ if (tmp[0].equals("Trying") || tmp[0].equals("Connected")) {
+ ;
+ } else if (tmp[0].equals("BABEL")) {
+ if (tmp[1].charAt(0) == '0' && tmp[1].charAt(1) == '.') {
+ ;
+ } else {
+ System.err.println("Wrong protocole number");
+ }
+ } else {
+ throw new LexError("Lexing Error problem:" + tmp[0]);
+ }
+ }
+ return tmp;
+ }
+}
View
33 babel-tool/src/LineShape.java
@@ -0,0 +1,33 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+import java.awt.geom.Line2D;
+
+public class LineShape extends Line2D.Double {
+
+ String id;
+
+ public LineShape(String id, double x1, double y1, double x2, double y2) {
+ super(x1, y1, x2, y2);
+ this.id = id;
+ }
+}
View
277 babel-tool/src/MainFrame.java
@@ -0,0 +1,277 @@
+/*
+Copyright (c) 2008 by Pejman Attar and Alexis Rosovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+ */
+
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+
+import javax.swing.event.TableModelEvent;
+import javax.swing.table.AbstractTableModel;
+
+public class MainFrame extends MainFrame_UI {
+
+ PanelBabel<Neighbour> panelNeigh;
+ PanelBabel<Route> panelRoute;
+ PanelBabel<XRoute> panelXroute;
+ BabelDraw babelDraw = null;
+ JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+ PanelInfoRouter infoRouter;
+ BabelReader babelReader;
+
+ public MainFrame(String name, int port) {
+ super();
+ babelReader = new BabelReader(port, this);
+ babelReader.start();
+ setTitle(name);
+
+ panelNeigh = new PanelBabel<Neighbour>("Neighbours");
+ panelRoute = new PanelBabel<Route>("Routes");
+ panelXroute = new PanelBabel<XRoute>("XRoutes");
+
+ tabbedPane.add(panelNeigh);
+ tabbedPane.add(panelRoute);
+ tabbedPane.add(panelXroute);
+
+ initGui();
+
+ EventQueue.invokeLater(new Runnable() {
+
+ public void run() {
+ setBabel();
+ drawNeighbours();
+ }
+ });
+ }
+
+ public void initGui() {
+ ActionListener redraw = new ActionListener() {
+
+ public void actionPerformed(ActionEvent arg0) {
+ try {
+ babelDraw.updateUI();
+ if (arg0.getSource() == peersChkBx && !peersChkBx.isSelected()) {
+ namesChkBx.setSelected(false);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ };
+ peersChkBx.addActionListener(redraw);
+ circlesChkBx.addActionListener(redraw);
+ routesChkBx.addActionListener(redraw);
+ namesChkBx.addActionListener(redraw);
+
+ }
+
+ public void drawNeighbours() {
+ if (babelDraw == null) {
+ babelDraw = new BabelDraw("Babel Draw", this);
+ split.setLeftComponent(babelDraw);
+ Dimension min = new Dimension(0, 0);
+ babelDraw.setMinimumSize(min);
+ infoRouter = new PanelInfoRouter(this);
+ split.setRightComponent(infoRouter);
+ infoRouter.setMinimumSize(min);
+
+ tabbedPane.addTab("BabelDraw", split);
+ split.setResizeWeight(0.7);
+ } else {
+ babelDraw.shapeList.clear();
+ babelDraw.updateUI();
+ }
+ }
+
+ public void setBabel() {
+ List<Neighbour> copyNeigh;
+ List<Route> copyRoute;
+ List<XRoute> copyXroute;
+ synchronized (babelReader.neighbour) {
+ copyNeigh = new LinkedList();
+ copyNeigh.addAll(babelReader.neighbour);
+ }
+ synchronized (babelReader.route) {
+ copyRoute = new LinkedList<Route>();
+ copyRoute.addAll(babelReader.route);
+ }
+ synchronized (babelReader.xroute) {
+ copyXroute = new LinkedList<XRoute>();
+ copyXroute.addAll(babelReader.xroute);
+ }
+
+ panelNeigh.setTable(copyNeigh);
+ panelRoute.setTable(copyRoute);
+ panelXroute.setTable(copyXroute);
+
+ JTable routeTable, XrouteTable, neighTable;
+ routeTable = panelRoute.table;
+ XrouteTable = panelXroute.table;
+ neighTable = panelNeigh.table;
+ new Thread(new Runnable() {
+
+ public void run() {
+ //Sometimes, the number of columns isn't properly computed. This happends under particular (and random) conditions.
+ //I figure how many columns are needed by analysing one element of the table (Route, Neighbour or XRoute)
+ //If setTable is invoked with an empty list, there is no element i can look into, so the column number is set to one.
+ //Until columns are computed again, the column number wont change.
+
+ //The following thread will run only once, 3 seconds after the initial call of setTable and will recompute the columns.
+ //Three seconds is much more time than the BabelReader needs to fill its lists, but it's a simple way
+ //to be sure that its lists aren't empty :)
+ //Note that if columns are already all there it'll change nothing and that
+ //any update of any table which has only one column will trigger a new column computation.
+ try {
+ Thread.sleep(3000);
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ JTable routeTable, XrouteTable, neighTable;
+ routeTable = panelRoute.table;
+ XrouteTable = panelXroute.table;
+ neighTable = panelNeigh.table;
+ ((AbstractTableModel) routeTable.getModel()).fireTableStructureChanged();
+ ((AbstractTableModel) XrouteTable.getModel()).fireTableStructureChanged();
+ ((AbstractTableModel) neighTable.getModel()).fireTableStructureChanged();
+
+ }
+
+ }
+ }).start();
+ babelReader.addBabelListener(new BabelListener() {
+
+ public void somethingHappening(BabelEvent e) {
+ JTable table = null;
+ PanelBabel panel = null;
+ if (e.item instanceof Route) {
+ table = panelRoute.table;
+ panel = panelRoute;
+ } else if (e.item instanceof XRoute) {
+ table = panelXroute.table;
+ panel = panelXroute;
+ } else if (e.item instanceof Neighbour) {
+ table = panelNeigh.table;
+ panel = panelNeigh;
+ }
+ if (panel.rows != null && table.getColumnCount() == 1 && panel.rows.size() != 0) {
+ ((AbstractTableModel) table.getModel()).fireTableChanged(new TableModelEvent(table.getModel(), TableModelEvent.HEADER_ROW));
+ }
+
+ }
+
+ public void addRoute(BabelEvent e) {
+ synchronized (panelRoute.rows) {
+ int i = panelRoute.rows.indexOf(e.item);
+ ((AbstractTableModel) panelRoute.table.getModel()).fireTableRowsInserted(i, i);
+ }
+ }
+
+ public void addXRoute(BabelEvent e) {
+ synchronized (panelXroute.rows) {
+ int i = panelXroute.rows.indexOf(e.item);
+ ((AbstractTableModel) panelXroute.table.getModel()).fireTableRowsInserted(i, i);
+ }
+ }
+
+ public void addNeigh(BabelEvent e) {
+ synchronized (panelNeigh.rows) {
+ int i = panelNeigh.rows.indexOf(e.item);
+ ((AbstractTableModel) panelNeigh.table.getModel()).fireTableRowsInserted(i, i);
+ }
+ }
+
+ public void changeRoute(BabelEvent e) {
+ synchronized (panelRoute.rows) {
+ int i = panelRoute.rows.indexOf(e.item);
+ int j = ((AbstractTableModel) panelRoute.table.getModel()).getRowCount();
+ if (i < j) {
+ try {
+ ((AbstractTableModel) panelRoute.table.getModel()).fireTableRowsUpdated(i, i);
+ }catch(Exception exn){
+ /* DefaultRowSorter.rowsUpdated() regularly and
+ mysteriously triggers IndexOutOfBoundsException here.
+ I don't know how to fix it, so I ignore it.
+ */
+ }
+ }
+ }
+ }
+
+ public void changeXRoute(BabelEvent e) {
+ synchronized (panelXroute.rows) {
+ int i = panelXroute.rows.indexOf(e.item);
+ ((AbstractTableModel) panelXroute.table.getModel()).fireTableRowsUpdated(i, i);
+ }
+ }
+
+ public void changeNeigh(BabelEvent e) {
+ synchronized (panelNeigh.rows) {
+ int i = panelNeigh.rows.indexOf(e.item);
+ ((AbstractTableModel) panelNeigh.table.getModel()).fireTableRowsUpdated(i, i);
+ }
+ }
+
+ public void flushRoute(BabelEvent e) {
+ synchronized (panelRoute.rows) {
+ int i = e.item.position;
+ ((AbstractTableModel) panelRoute.table.getModel()).fireTableDataChanged();
+ }
+ }
+
+ public void flushXRoute(BabelEvent e) {
+ synchronized (panelXroute.rows) {
+ int i = e.item.position;
+ ((AbstractTableModel) panelXroute.table.getModel()).fireTableDataChanged();
+ }
+ }
+
+ public void flushNeigh(BabelEvent e) {
+ synchronized (panelNeigh.rows) {
+ int i = e.item.position;
+ ((AbstractTableModel) panelNeigh.table.getModel()).fireTableDataChanged();
+ }
+ }
+ });
+ }
+
+ public void updateLists() {
+ if (BabelReader.updateNeigh) {
+ this.panelNeigh.updateRows(babelReader.neighbour);
+ }
+
+ if (BabelReader.updateRoute) {
+ this.panelRoute.updateRows(babelReader.route);
+ }
+
+ if (BabelReader.updateXRoute) {
+ this.panelXroute.updateRows(babelReader.xroute);
+ }
+
+ }
+}