Added old project initial commit
All checks were successful
Locusworks Team/lsproject/pipeline/head This commit looks good
All checks were successful
Locusworks Team/lsproject/pipeline/head This commit looks good
This commit is contained in:
56
src/main/java/net/locusworks/lsproject/driver/Program.java
Normal file
56
src/main/java/net/locusworks/lsproject/driver/Program.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package net.locusworks.lsproject.driver;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import net.locusworks.lsproject.gui.DebugConsole;
|
||||
import net.locusworks.lsproject.gui.StartupWindow;
|
||||
|
||||
/**
|
||||
* Contains the main (start-up) function.
|
||||
*/
|
||||
public class Program {
|
||||
private static DebugConsole console;
|
||||
|
||||
/**
|
||||
* Entry point of the program.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
console = new DebugConsole();
|
||||
|
||||
setupStreams();
|
||||
|
||||
new StartupWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the typical output streams to a window. This means that output sent through System.out
|
||||
* and System.err are sent instead to a designated console window.
|
||||
*/
|
||||
public static void setupStreams() {
|
||||
PrintStream errorStream = new PrintStream(new OutputStream() {
|
||||
@Override
|
||||
public void write(int c) throws IOException {
|
||||
write(new byte[] { Byte.parseByte(Integer.toString(c)) });
|
||||
}
|
||||
|
||||
public void write(byte[] b) {
|
||||
console.writeError(new String(b));
|
||||
}
|
||||
});
|
||||
|
||||
PrintStream outputStream = new PrintStream(new OutputStream() {
|
||||
@Override
|
||||
public void write(int c) throws IOException {
|
||||
write(new byte[] { Byte.parseByte(Integer.toString(c)) });
|
||||
}
|
||||
|
||||
public void write(byte[] b) {
|
||||
console.writeString(new String(b));;
|
||||
}
|
||||
});
|
||||
|
||||
//System.setErr(errorStream);
|
||||
System.setOut(outputStream);
|
||||
}
|
||||
}
|
||||
118
src/main/java/net/locusworks/lsproject/gui/CostViewerWindow.java
Normal file
118
src/main/java/net/locusworks/lsproject/gui/CostViewerWindow.java
Normal file
@@ -0,0 +1,118 @@
|
||||
package net.locusworks.lsproject.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.event.TableModelListener;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
import net.locusworks.lsproject.driver.Program;
|
||||
import net.locusworks.lsproject.object.Network;
|
||||
import net.locusworks.lsproject.object.Router;
|
||||
|
||||
|
||||
public class CostViewerWindow extends JPanel implements TableModelListener{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 8571350255455457432L;
|
||||
private boolean DEBUG = false;
|
||||
private Router router = null;
|
||||
|
||||
|
||||
public CostViewerWindow(Router _router){
|
||||
super(new BorderLayout());
|
||||
|
||||
router = _router;
|
||||
|
||||
String[] columnNames = {"Connection",
|
||||
"Cost"};
|
||||
|
||||
int numberOfConnections = router.getConnections().size();
|
||||
|
||||
Object data[][]= new Object[numberOfConnections][2];
|
||||
|
||||
for (int i = 0; i < numberOfConnections; i++){
|
||||
|
||||
String tempFirstParticipant = router.getConnections()
|
||||
.get(i).getFirstParticipantAddress();
|
||||
|
||||
String tempSecondParticipant = router.getConnections()
|
||||
.get(i).getSecondParticipantAddress();
|
||||
|
||||
if(tempFirstParticipant.equals(router.getIpAddress())){
|
||||
data[i][0] = tempSecondParticipant;
|
||||
}
|
||||
else{
|
||||
data[i][0] = tempFirstParticipant;
|
||||
}
|
||||
data[i][1] = router.getConnections().get(i).getCost();
|
||||
}
|
||||
|
||||
final JTable table = new JTable(data, columnNames);
|
||||
table.setPreferredScrollableViewportSize(new Dimension(300, 70));
|
||||
table.setFillsViewportHeight(true);
|
||||
table.getModel().addTableModelListener(this);
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
add(scrollPane);
|
||||
|
||||
}
|
||||
|
||||
public void createGUI(){
|
||||
|
||||
JFrame frame = new JFrame("Cost Viewer For Router " + router.getIpAddress());
|
||||
CostViewerWindow newContentPane = new CostViewerWindow(router);
|
||||
newContentPane.setOpaque(true);
|
||||
frame.setContentPane(newContentPane);
|
||||
frame.pack();
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tableChanged(TableModelEvent e) {
|
||||
if (e.getColumn() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int row = e.getFirstRow();
|
||||
int column = e.getColumn();
|
||||
TableModel model = (TableModel)e.getSource();
|
||||
Object data = model.getValueAt(row, column);
|
||||
|
||||
final String otherRouterIp = model.getValueAt(row, 0).toString();
|
||||
|
||||
final int oldCost = router.getConnectionByParticipant(router.getIpAddress(), otherRouterIp).getCost();
|
||||
int newCost = oldCost;
|
||||
try {
|
||||
newCost = Integer.parseInt(data.toString());
|
||||
|
||||
if (newCost < 1 || newCost > 10){
|
||||
System.out.println("Cost Has To Be Between 0 - 10");
|
||||
|
||||
newCost = oldCost;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
router.getConnectionByParticipant(
|
||||
router.getIpAddress(), otherRouterIp).setCost(newCost);
|
||||
Router otherRouter = Network.getInstance().getRouterByIp(otherRouterIp);
|
||||
otherRouter.getConnectionByParticipant(
|
||||
router.getIpAddress(), otherRouterIp).setCost(newCost);
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
System.out.println("Invalid cost.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
53
src/main/java/net/locusworks/lsproject/gui/DebugConsole.java
Normal file
53
src/main/java/net/locusworks/lsproject/gui/DebugConsole.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package net.locusworks.lsproject.gui;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
import net.locusworks.lsproject.gui.helper.ImageHelper;
|
||||
|
||||
/**
|
||||
* The DebugConsole displays normal debug messages from stdout.
|
||||
*/
|
||||
public class DebugConsole extends JFrame {
|
||||
private static final long serialVersionUID = -4430646440883436819L;
|
||||
private JTextArea textArea;
|
||||
|
||||
public DebugConsole() {
|
||||
super("Debug Console");
|
||||
|
||||
textArea = new JTextArea();
|
||||
setSize(400, 300);
|
||||
textArea.setSize(400, 300);
|
||||
textArea.setEditable(false);
|
||||
textArea.setLineWrap(true);
|
||||
|
||||
JScrollPane pane = new JScrollPane(textArea);
|
||||
pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
|
||||
pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
|
||||
setIconImage(ImageHelper.getImageFromResource("assets/router_ico.png"));
|
||||
|
||||
add(pane);
|
||||
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a normal string to the console.
|
||||
* @param s String to write.
|
||||
*/
|
||||
public void writeString(String s) {
|
||||
textArea.append(s);
|
||||
textArea.setCaretPosition(textArea.getText().length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an error string to the console.
|
||||
* @param s String to write.
|
||||
*/
|
||||
public void writeError(String s) {
|
||||
textArea.append(s);
|
||||
textArea.setCaretPosition(textArea.getText().length());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,411 @@
|
||||
package net.locusworks.lsproject.gui;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Random;
|
||||
import javax.swing.*;
|
||||
|
||||
import net.locusworks.lsproject.gui.helper.ImageHelper;
|
||||
import net.locusworks.lsproject.gui.helper.RouterPath;
|
||||
import net.locusworks.lsproject.object.Connection;
|
||||
import net.locusworks.lsproject.object.Router;
|
||||
import net.locusworks.lsproject.object.Network;
|
||||
import net.locusworks.lsproject.util.Utility;
|
||||
|
||||
|
||||
/**
|
||||
* Display a network.
|
||||
*/
|
||||
public class RouterViewerWindow extends JFrame implements MouseListener,
|
||||
MouseMotionListener,
|
||||
KeyListener {
|
||||
// Makes compiler happy.
|
||||
private static final long serialVersionUID = 5141131466102432149L;
|
||||
|
||||
private JPanel surface;
|
||||
private Image routerImage;
|
||||
private int imageWidth;
|
||||
private int imageHeight;
|
||||
|
||||
private String highlightedRouter;
|
||||
|
||||
private Image offscreenImage;
|
||||
private Graphics buffer;
|
||||
|
||||
private boolean[] keys;
|
||||
|
||||
private Hashtable<String, RoutingTableWindow> routingTables = new Hashtable<String, RoutingTableWindow>();
|
||||
|
||||
// This is a hack for a weird java-related bug where it does not draw pictures on the first paint.
|
||||
private boolean firstPaint = true;
|
||||
|
||||
/**
|
||||
* Construct a new RouterViewerWindow object.
|
||||
*/
|
||||
public RouterViewerWindow() {
|
||||
super("Network Viewer - " + Network.getInstance().getName());
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the GUI components of this class.
|
||||
*/
|
||||
private void initialize() {
|
||||
routerImage = ImageHelper.getImageFromResource("assets/router.png");
|
||||
imageWidth = 129;
|
||||
imageHeight = 71;
|
||||
|
||||
setIconImage(ImageHelper.getImageFromResource("assets/router_ico.png"));
|
||||
|
||||
surface = new JPanel(true);
|
||||
surface.setSize(800, 600);
|
||||
surface.setBackground(Color.GRAY);
|
||||
|
||||
setContentPane(surface);
|
||||
|
||||
addMouseListener(this);
|
||||
addMouseMotionListener(this);
|
||||
addKeyListener(this);
|
||||
|
||||
setSize(800, 600);
|
||||
|
||||
setResizable(false);
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setLocationRelativeTo(null);
|
||||
setVisible(true);
|
||||
|
||||
// Track key states. Initialize all to false (not pressed).
|
||||
keys = new boolean[525];
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
keys[i] = false;
|
||||
}
|
||||
|
||||
// Create the buffer.
|
||||
offscreenImage = surface.createImage(getWidth(), getHeight());
|
||||
buffer = offscreenImage.getGraphics();
|
||||
|
||||
// Repaint the window every once in a while.
|
||||
new Thread() {
|
||||
public void run() {
|
||||
while (isVisible()) {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint the routers to the screen.
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
buffer.setColor(Color.GRAY);
|
||||
buffer.fillRect(0, 0, getWidth(), getHeight());
|
||||
|
||||
buffer.setColor(Color.BLACK);
|
||||
|
||||
// Draw connections.
|
||||
for (Router r : Network.getInstance().getRouters()) {
|
||||
for (Connection connection : r.getConnections()) {
|
||||
Router r1 = Network.getInstance().getRouterByIp(connection.getFirstParticipantAddress());
|
||||
Router r2 = Network.getInstance().getRouterByIp(connection.getSecondParticipantAddress());
|
||||
|
||||
buffer.drawLine(r1.getPosition().x, r1.getPosition().y,
|
||||
r2.getPosition().x, r2.getPosition().y);
|
||||
|
||||
buffer.drawString(Integer.toString(connection.getCost()),
|
||||
(r1.getPosition().x + r2.getPosition().x) / 2,
|
||||
(r1.getPosition().y + r2.getPosition().y - 10) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
for (Router r : Network.getInstance().getRouters()) {
|
||||
Point position = r.getPosition();
|
||||
|
||||
buffer.setColor(Color.BLACK);
|
||||
|
||||
// Draw router IP addresses.
|
||||
buffer.drawString(r.getIpAddress(), position.x - (imageWidth / 2) + 5,
|
||||
position.y - (imageHeight / 2) - 10);
|
||||
|
||||
buffer.drawImage(routerImage, position.x - (imageWidth / 2),
|
||||
position.y - (imageHeight / 2), imageWidth, imageHeight, null);
|
||||
|
||||
// Highlight a different color if shift is pressed down.
|
||||
if (keys[KeyEvent.VK_SHIFT]) {
|
||||
buffer.setColor(Color.RED);
|
||||
}
|
||||
|
||||
if (highlightedRouter != null && !highlightedRouter.equals("")) {
|
||||
if (r.getIpAddress().equals(highlightedRouter)) {
|
||||
buffer.drawRect(position.x - (imageWidth / 2), position.y - (imageHeight / 2),
|
||||
imageWidth, imageHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
illuminatePath(buffer);
|
||||
|
||||
// Draw the buffer image to the screen.
|
||||
g.drawImage(offscreenImage, 0, 0, getWidth(), getHeight(), Color.GRAY, null);
|
||||
|
||||
// Hack to attempt to get the first image to draw.
|
||||
if (firstPaint) {
|
||||
firstPaint = false;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight the path between a start and end router, if necessary.
|
||||
* @param g Graphics device.
|
||||
*/
|
||||
public void illuminatePath(Graphics g) {
|
||||
// Draw highlighted router boxes.
|
||||
if (RouterPath.firstRouter != null) {
|
||||
final Point position = RouterPath.firstRouter.getPosition();
|
||||
buffer.setColor(new Color(0, 255, 255));
|
||||
buffer.drawRect(position.x - (imageWidth / 2), position.y - (imageHeight / 2),
|
||||
imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
if (RouterPath.secondRouter != null) {
|
||||
final Point position = RouterPath.secondRouter.getPosition();
|
||||
buffer.setColor(new Color(0, 255, 255));
|
||||
buffer.drawRect(position.x - (imageWidth / 2), position.y - (imageHeight / 2),
|
||||
imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
if (RouterPath.highlightedPath != null) {
|
||||
Router lastRouter = RouterPath.firstRouter;
|
||||
while (RouterPath.highlightedPath.hasNext()) {
|
||||
final Router next = RouterPath.highlightedPath.getNext();
|
||||
|
||||
final Point start = lastRouter.getPosition();
|
||||
final Point end = next.getPosition();
|
||||
buffer.drawLine(start.x, start.y, end.x, end.y);
|
||||
|
||||
lastRouter = next;
|
||||
}
|
||||
|
||||
RouterPath.highlightedPath.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to prevent the frame from erasing the background.
|
||||
*/
|
||||
@Override public void update(Graphics g) {
|
||||
paint(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn a new routing table window.
|
||||
* @param r Router to display.
|
||||
*/
|
||||
public void spawnRoutingTable(Router r) {
|
||||
if (routingTables.contains(r.getIpAddress())) {
|
||||
RoutingTableWindow window = routingTables.get(r.getIpAddress());
|
||||
window.dispose();
|
||||
routingTables.remove(r.getIpAddress());
|
||||
}
|
||||
|
||||
routingTables.put(r.getIpAddress(), new RoutingTableWindow(r));
|
||||
}
|
||||
|
||||
public void spawnCostViwerWindow(Router r){
|
||||
CostViewerWindow window = new CostViewerWindow(r);
|
||||
window.createGUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Force each router to perform the algorithm.
|
||||
*/
|
||||
public void updateAllRouters() {
|
||||
for (Router router : Network.getInstance().getRouters()) {
|
||||
router.getRoutingTable().execute(router, null);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Event handlers.
|
||||
*/
|
||||
/**
|
||||
* Check if the mouse is over a router on the screen.
|
||||
*/
|
||||
private Router mouseIsOverRouter(MouseEvent e) {
|
||||
for (Router r : Network.getInstance().getRouters()) {
|
||||
if (Math.abs(r.getPosition().x - e.getPoint().x) < imageWidth / 2 &&
|
||||
Math.abs(r.getPosition().y - e.getPoint().y) < imageHeight / 2) {
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public void mouseClicked(MouseEvent e) {}
|
||||
@Override public void mouseEntered(MouseEvent e) {}
|
||||
@Override public void mouseExited(MouseEvent e) {}
|
||||
@Override public void mouseReleased(MouseEvent e) {}
|
||||
|
||||
/**
|
||||
* Check if the mouse was pressed down. This will highlight or unhighlight routers.
|
||||
*/
|
||||
@Override public void mousePressed(MouseEvent e) {
|
||||
// Collision detection.
|
||||
Router r = null;
|
||||
if ((r = mouseIsOverRouter(e)) != null) {
|
||||
// The mouse is over a router.
|
||||
if (highlightedRouter != null && !highlightedRouter.equals(r.getIpAddress())) {
|
||||
// The selected router is not currently highlighted.
|
||||
if (keys[KeyEvent.VK_SHIFT]) {
|
||||
// Shift is pressed down. User is trying to make a connection.
|
||||
Random rand = new Random();
|
||||
Connection connection = new Connection(
|
||||
highlightedRouter, r.getIpAddress(), rand.nextInt(5) + 1);
|
||||
|
||||
if (r.getConnectionByParticipant(highlightedRouter, r.getIpAddress()) != null) {
|
||||
// Connection exists.
|
||||
return;
|
||||
}
|
||||
|
||||
r.addConnection(connection);
|
||||
Network.getInstance().getRouterByIp(highlightedRouter).addConnection(connection);
|
||||
|
||||
System.out.println("Added connection between " + highlightedRouter + " and " +
|
||||
r.getIpAddress() + ". Cost: " + connection.getCost() + ".");
|
||||
|
||||
repaint();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (keys[KeyEvent.VK_CONTROL]) {
|
||||
// CTRL is pressed down -- select routers for highlighting.
|
||||
RouterPath.highlightOne(r);
|
||||
|
||||
repaint();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
highlightedRouter = r.getIpAddress();
|
||||
|
||||
repaint();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (keys[KeyEvent.VK_SHIFT] || keys[KeyEvent.VK_CONTROL]) {
|
||||
// Do not create a router if shift or control are held down.
|
||||
e.consume();
|
||||
return;
|
||||
}
|
||||
|
||||
// If the program reaches this point, it will create a new router.
|
||||
|
||||
int routerId = Network.getInstance().getRouters().size();
|
||||
String routerName = new String(new char[] { (char)(routerId + 65) });
|
||||
while (Network.getInstance().getRouterByIp(routerName) != null) {
|
||||
routerId++;
|
||||
}
|
||||
|
||||
Network.getInstance().addRouter(new Router(routerName, e.getPoint()));
|
||||
highlightedRouter = routerName;
|
||||
|
||||
System.out.println("Added new router: " + routerName);
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an event when the mouse is dragged.
|
||||
*/
|
||||
@Override public void mouseDragged(MouseEvent e) {
|
||||
// Check if a mouse is trying to drag a router across the screen.
|
||||
if (highlightedRouter != null && !highlightedRouter.equals("")
|
||||
&& !keys[KeyEvent.VK_SHIFT] && !keys[KeyEvent.VK_CONTROL]) {
|
||||
Router r = Network.getInstance().getRouterByIp(highlightedRouter);
|
||||
if (r == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Point offset = new Point();
|
||||
offset.x = r.getPosition().x + (e.getPoint().x - r.getPosition().x);
|
||||
offset.y = r.getPosition().y + (e.getPoint().y - r.getPosition().y);
|
||||
|
||||
r.setPosition(offset);
|
||||
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void mouseMoved(MouseEvent e) {}
|
||||
@Override public void keyTyped(KeyEvent e) {}
|
||||
|
||||
@Override public void keyPressed(KeyEvent e) {
|
||||
keys[e.getKeyCode()] = true;
|
||||
|
||||
if (highlightedRouter != null &&
|
||||
!highlightedRouter.equals("") &&
|
||||
keys[KeyEvent.VK_DELETE]) {
|
||||
Network.getInstance().removeRouterByIp(highlightedRouter);
|
||||
|
||||
try {
|
||||
highlightedRouter = Network.getInstance().getRouters().get(0).toString();
|
||||
}
|
||||
catch (Exception ex) {}
|
||||
|
||||
RouterPath.clear();
|
||||
|
||||
updateAllRouters();
|
||||
}
|
||||
|
||||
else if (keys[KeyEvent.VK_S] && ((e.getModifiers() & KeyEvent.VK_CONTROL) == 0)) {
|
||||
try {
|
||||
Utility.saveNetwork();
|
||||
|
||||
System.out.println("Network saved to " + Network.getInstance().getName() + Utility.FILE_EXTENSION);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
System.err.println("Couldn't save network. Details:");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn routing table.
|
||||
else if (e.getKeyCode() == KeyEvent.VK_R) {
|
||||
spawnRoutingTable(Network.getInstance().getRouterByIp(highlightedRouter));
|
||||
}
|
||||
|
||||
if (e.getKeyCode() == KeyEvent.VK_C){
|
||||
SwingUtilities.invokeLater(new Runnable(){
|
||||
public void run(){
|
||||
spawnCostViwerWindow(Network.getInstance().getRouterByIp(highlightedRouter));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override public void keyReleased(KeyEvent e) {
|
||||
keys[e.getKeyCode()] = false;
|
||||
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
package net.locusworks.lsproject.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import net.locusworks.lsproject.driver.Program;
|
||||
import net.locusworks.lsproject.object.Network;
|
||||
import net.locusworks.lsproject.object.Router;
|
||||
import net.locusworks.lsproject.object.helper.DijkstraCallback;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class RoutingTableWindow extends JFrame implements WindowListener {
|
||||
private static final long serialVersionUID = 1768859322938299953L;
|
||||
|
||||
private Router router = null;
|
||||
private JTable table = null;
|
||||
private RoutingTableModel tableModel = new RoutingTableModel();
|
||||
private String set = "";
|
||||
|
||||
/**
|
||||
* Display a new routing table window.
|
||||
* @param _router
|
||||
*/
|
||||
public RoutingTableWindow(Router _router) {
|
||||
super("Routing table - " + _router.getIpAddress());
|
||||
|
||||
router = _router;
|
||||
|
||||
initializeComponents();
|
||||
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the GUI components used by this window.
|
||||
*/
|
||||
private void initializeComponents() {
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
table = new JTable(tableModel);
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
|
||||
add(table.getTableHeader(), BorderLayout.PAGE_START);
|
||||
add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
setSize(425, 200);
|
||||
|
||||
router.getRoutingTable().registerCallback(tableModel);
|
||||
|
||||
router.getRoutingTable().execute(router, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow access to which router this window is displaying.
|
||||
* @return Router object.
|
||||
*/
|
||||
public Router getRouter() {
|
||||
return router;
|
||||
}
|
||||
|
||||
/**
|
||||
* Model used for displaying the routing table.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
private class RoutingTableModel extends AbstractTableModel implements DijkstraCallback {
|
||||
private ArrayList<String> columnNames = new ArrayList<String>();
|
||||
private Object[][] data;
|
||||
private int currentRow = 0;
|
||||
|
||||
public RoutingTableModel() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle callback.
|
||||
*/
|
||||
|
||||
@Override public void reset() {
|
||||
set = router.getIpAddress();
|
||||
columnNames.clear();
|
||||
currentRow = 0;
|
||||
|
||||
columnNames.add("N'");
|
||||
columnNames.add(router.toString());
|
||||
for (Router r : Network.getInstance().getRouters()) {
|
||||
if (r != router) {
|
||||
columnNames.add(r.getIpAddress());
|
||||
}
|
||||
}
|
||||
|
||||
fireTableStructureChanged();
|
||||
|
||||
data = new Object[Network.getInstance().getRouters().size()][columnNames.size()];
|
||||
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
for (int j =0; j < data[i].length; j++) {
|
||||
data[i][j] = "";
|
||||
fireTableCellUpdated(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
setValueAt(set, 0, 0);
|
||||
|
||||
fireTableDataChanged();
|
||||
|
||||
System.out.println("Routing table " + router + " reset.");
|
||||
}
|
||||
|
||||
@Override public void predecessorAdded(Router key, Router value) {
|
||||
if (key == router) return;
|
||||
final int columnIndex = getColumnByName(value.getIpAddress());
|
||||
|
||||
setValueAt(key.getIpAddress() + "," + getValueAt(currentRow, columnIndex), currentRow, columnIndex);
|
||||
}
|
||||
|
||||
@Override public void settledRouterAdded(Router r) {
|
||||
if (set.contains(r.getIpAddress())) return;
|
||||
|
||||
currentRow++;
|
||||
|
||||
set += (set.length() > 0 ? "," : "") + r.getIpAddress();
|
||||
|
||||
final int rowIndex = set.split("\\,").length - 1;
|
||||
|
||||
setValueAt(set, rowIndex, 0);
|
||||
}
|
||||
|
||||
@Override public void shortestDistanceUpdated(Router router, int cost) {
|
||||
final int column = getColumnByName(router.getIpAddress());
|
||||
|
||||
setValueAt(cost, currentRow, column);
|
||||
}
|
||||
|
||||
/*
|
||||
* Override AbstractTableModel functions.
|
||||
*/
|
||||
|
||||
@Override public String getColumnName(int columnNumber) {
|
||||
return columnNames.get(columnNumber);
|
||||
}
|
||||
|
||||
public int getColumnByName(String columnName) {
|
||||
for (int i = 0; i < columnNames.size(); i++) {
|
||||
if (columnNames.get(i).equals(columnName)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getRowByFirstCellName(String cellName) {
|
||||
for (int i = 1; i < getRowCount(); i++) {
|
||||
if (columnNames.get(i).endsWith(cellName)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override public int getColumnCount() {
|
||||
return columnNames.size();
|
||||
}
|
||||
|
||||
@Override public int getRowCount() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
return data[rowIndex][columnIndex];
|
||||
}
|
||||
|
||||
@Override public void setValueAt(Object value, int rowIndex, int columnIndex) {
|
||||
data[rowIndex][columnIndex] = value;
|
||||
|
||||
super.fireTableCellUpdated(rowIndex, columnIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void windowClosing(WindowEvent e) {
|
||||
router.getRoutingTable().unregisterCallback(tableModel);
|
||||
}
|
||||
|
||||
@Override public void windowActivated(WindowEvent arg0) {}
|
||||
@Override public void windowClosed(WindowEvent arg0) {}
|
||||
@Override public void windowDeactivated(WindowEvent arg0) {}
|
||||
@Override public void windowDeiconified(WindowEvent arg0) {}
|
||||
@Override public void windowIconified(WindowEvent arg0) {}
|
||||
@Override public void windowOpened(WindowEvent arg0) {}
|
||||
}
|
||||
182
src/main/java/net/locusworks/lsproject/gui/StartupWindow.java
Normal file
182
src/main/java/net/locusworks/lsproject/gui/StartupWindow.java
Normal file
@@ -0,0 +1,182 @@
|
||||
package net.locusworks.lsproject.gui;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
import net.locusworks.lsproject.driver.Program;
|
||||
import net.locusworks.lsproject.gui.helper.ImageHelper;
|
||||
import net.locusworks.lsproject.object.Network;
|
||||
import net.locusworks.lsproject.util.Utility;
|
||||
|
||||
|
||||
/**
|
||||
* The first window that the user will see. Prompts user to create a new network, load a network, or exit.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class StartupWindow extends JFrame {
|
||||
// Declare class members.
|
||||
private JButton newNetworkButton;
|
||||
private JButton loadNetworkButton;
|
||||
private JButton exitButton;
|
||||
|
||||
/**
|
||||
* Construct a new startup window.
|
||||
*/
|
||||
public StartupWindow() {
|
||||
super("LS Network Project");
|
||||
|
||||
initializeGui();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the GUI for this window.
|
||||
*/
|
||||
private void initializeGui() {
|
||||
// Initialize class members (GUI objects)
|
||||
newNetworkButton = new JButton("New Network");
|
||||
loadNetworkButton = new JButton("Load Network");
|
||||
exitButton = new JButton("Exit");
|
||||
|
||||
// Layout setup.
|
||||
setLayout(new GridBagLayout());
|
||||
|
||||
// Component layout setup.
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
|
||||
c.gridx = 0;
|
||||
c.gridy = 0;
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.insets = new Insets(10, 20, 5, 20);
|
||||
add(newNetworkButton, c);
|
||||
|
||||
c.gridy = 1;
|
||||
c.insets = new Insets(5, 20, 5, 20);
|
||||
add(loadNetworkButton, c);
|
||||
|
||||
c.gridy = 2;
|
||||
c.insets = new Insets(5, 20, 10, 20);
|
||||
add(exitButton, c);
|
||||
|
||||
// Event handler setup.
|
||||
newNetworkButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
newNetworkButton_onClick();
|
||||
}
|
||||
});
|
||||
|
||||
loadNetworkButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
loadNetworkButton_onClick();
|
||||
}
|
||||
});
|
||||
|
||||
exitButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
exitButton_onClick();
|
||||
}
|
||||
});
|
||||
|
||||
// Load window icon.
|
||||
setIconImage(ImageHelper.getImageFromResource("assets/router_ico.png"));
|
||||
|
||||
// Typical window setup.
|
||||
pack();
|
||||
|
||||
setLocationRelativeTo(null);
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle event when the newNetworkButton is clicked.
|
||||
* Opens a new RouterViewerWindow GUI and closes this window.
|
||||
*/
|
||||
private void newNetworkButton_onClick() {
|
||||
setVisible(false);
|
||||
|
||||
dispose();
|
||||
|
||||
String networkName = "";
|
||||
while (networkName.equals("")) {
|
||||
networkName = JOptionPane.showInputDialog("Please enter your network's name:");
|
||||
if (networkName == null) {
|
||||
// Canceled.
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
Network.createInstance(networkName);
|
||||
|
||||
new RouterViewerWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle event when the loadNetworkButton is clicked.
|
||||
* Opens a file dialog, loads a network, opens a new RouterViewerWindow GUI and closes this window.
|
||||
*/
|
||||
private void loadNetworkButton_onClick() {
|
||||
JFileChooser fileChooser = new JFileChooser(".");
|
||||
fileChooser.addChoosableFileFilter(new FileFilter() {
|
||||
@Override public boolean accept(File f) {
|
||||
if (f.isDirectory())
|
||||
return true;
|
||||
|
||||
final String ext = Utility.getExtension(f);
|
||||
if (ext == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !ext.equalsIgnoreCase(Utility.FILE_EXTENSION);
|
||||
}
|
||||
|
||||
@Override public String getDescription() {
|
||||
return "*" + Utility.FILE_EXTENSION + " - Serialized network object file.";
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
final int userAction = fileChooser.showOpenDialog(this);
|
||||
if (userAction == JFileChooser.CANCEL_OPTION) {
|
||||
// Canceled.
|
||||
return;
|
||||
}
|
||||
|
||||
File f = fileChooser.getSelectedFile();
|
||||
|
||||
try {
|
||||
Utility.loadNetwork(f);
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
JOptionPane.showMessageDialog(this,
|
||||
"An error occured while trying to load the network file:\n" + e.getMessage(),
|
||||
"Error loading file!",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setVisible(false);
|
||||
|
||||
dispose();
|
||||
|
||||
new RouterViewerWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle event when exitButton is clicked.
|
||||
* Closes the program.
|
||||
*/
|
||||
private void exitButton_onClick() {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package net.locusworks.lsproject.gui.helper;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
|
||||
public class ImageHelper {
|
||||
|
||||
public static Image getImageFromResource(String imageName) {
|
||||
try(ByteArrayOutputStream baos = new ByteArrayOutputStream(); InputStream is = ImageHelper.class.getClassLoader().getResourceAsStream(imageName)) {
|
||||
byte[] buff = new byte[1024];
|
||||
int read = 0;
|
||||
while((read = is.read(buff)) > -1) {
|
||||
baos.write(buff, 0, read);
|
||||
}
|
||||
// Load window icon.
|
||||
return Toolkit.getDefaultToolkit().createImage(baos.toByteArray());
|
||||
} catch (IOException ex) {
|
||||
JOptionPane.showMessageDialog(null,
|
||||
"An error occured while trying to load the assets file:\n" + ex.getMessage(),
|
||||
"Error loading file!",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package net.locusworks.lsproject.gui.helper;
|
||||
|
||||
import net.locusworks.lsproject.object.DijkstraEngine;
|
||||
import net.locusworks.lsproject.object.Path;
|
||||
import net.locusworks.lsproject.object.Router;
|
||||
|
||||
/**
|
||||
* The RouterPath class's job is to keep track of two separate routers for the purpose of
|
||||
* showing the quickest path from the source (firstRouter) to the destination (secondRouter).
|
||||
*/
|
||||
public class RouterPath {
|
||||
public static Router firstRouter = null;
|
||||
public static Router secondRouter = null;
|
||||
|
||||
public static Path highlightedPath = null;
|
||||
|
||||
/**
|
||||
* Null out the routers.
|
||||
*/
|
||||
public static void clear() {
|
||||
firstRouter = null;
|
||||
secondRouter = null;
|
||||
highlightedPath = null;
|
||||
|
||||
System.out.println("Cleared highlights.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights a router. If one is highlighted, it highlights the other one.
|
||||
* If both are highlighted, it nulls the second and highlights the first.
|
||||
* @param r Router to highlight.
|
||||
*/
|
||||
public static void highlightOne(Router r) {
|
||||
if (firstRouter == null) {
|
||||
firstRouter = r;
|
||||
System.out.println("Highlighted source router: " + r.getIpAddress());
|
||||
}
|
||||
else if (secondRouter == null) {
|
||||
secondRouter = r;
|
||||
System.out.println("Highlighted destination router: " + r.getIpAddress());
|
||||
|
||||
highlightedPath = findShortestPath(firstRouter, secondRouter);
|
||||
if (highlightedPath == null) {
|
||||
System.out.println("No connection from " +
|
||||
firstRouter.getIpAddress() + " to " + secondRouter.getIpAddress());
|
||||
|
||||
clear();
|
||||
}
|
||||
else {
|
||||
System.out.println("Path: total cost: " + highlightedPath.getTotalCost());
|
||||
}
|
||||
}
|
||||
else {
|
||||
clear();
|
||||
}
|
||||
|
||||
if (firstRouter == secondRouter && firstRouter != null) {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the shortest path from the first router (A) to the target router (B).
|
||||
* @see DijkstraEngine.findShortestPath
|
||||
* @param _firstRouter Starting router.
|
||||
* @param _secondRouter Target router.
|
||||
* @return Sequence from the source router to the destination router.
|
||||
*/
|
||||
public static Path findShortestPath(Router _firstRouter, Router _secondRouter) {
|
||||
return new DijkstraEngine().findShortestPath(_firstRouter, _secondRouter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package net.locusworks.lsproject.object;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A Connection represents a single wire (i.e. the connection between two routers).
|
||||
*/
|
||||
public class Connection implements Serializable {
|
||||
private static final long serialVersionUID = -1883775251010127340L;
|
||||
|
||||
private int cost;
|
||||
private String ipAddress1;
|
||||
private String ipAddress2;
|
||||
|
||||
/**
|
||||
* Construct a Connection object.
|
||||
* @param _ipAddress1 Address of one router on the connection.
|
||||
* @param _ipAddress2 Address of the other router on the connection.
|
||||
* @param _cost Cost of the wire.
|
||||
*/
|
||||
public Connection(String _ipAddress1, String _ipAddress2, int _cost) {
|
||||
ipAddress1 = _ipAddress1;
|
||||
ipAddress2 = _ipAddress2;
|
||||
cost = _cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronized (thread-safe) method for obtaining the cost of this connection.
|
||||
* @return Cost (type integer) of the wire.
|
||||
*/
|
||||
public synchronized int getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronized (thread-safe) method for setting a new cost for this connection.
|
||||
* @param _cost Cost (type integer) of the wire.
|
||||
*/
|
||||
public synchronized void setCost(int _cost) {
|
||||
cost = _cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* A single connection has at most two participants. This retrieves IP Address 1
|
||||
* (not ordered in any way; this is simply the first parameter of the Connection constructor).
|
||||
* @return IP address of participant #1 of this connection.
|
||||
*/
|
||||
public String getFirstParticipantAddress() {
|
||||
return ipAddress1;
|
||||
}
|
||||
|
||||
/**
|
||||
* A single connection has at most two participants. This retrieves IP Address 2
|
||||
* (not ordered in any way; this is simply the second parameter of the Connection constructor).
|
||||
* @return IP address of participant #2 of this connection.
|
||||
*/
|
||||
public String getSecondParticipantAddress() {
|
||||
return ipAddress2;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the participants of this connections ever need to be modified, they can be done so through
|
||||
* this method.
|
||||
* @param _ipAddress1 IP Address of the first participant.
|
||||
* @param _ipAddress2 IP Address of the second participant.
|
||||
*/
|
||||
public void setParticipants(String _ipAddress1, String _ipAddress2) {
|
||||
ipAddress1 = _ipAddress1;
|
||||
ipAddress2 = _ipAddress2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
package net.locusworks.lsproject.object;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
|
||||
import net.locusworks.lsproject.object.helper.DijkstraCallback;
|
||||
|
||||
|
||||
/**
|
||||
* Keeper and executor of the Dijkstra algorithm.
|
||||
*/
|
||||
public class DijkstraEngine {
|
||||
public static final int infinity = 100000;
|
||||
|
||||
private ArrayList<Router> routers = new ArrayList<Router>();
|
||||
private ArrayList<DijkstraCallback> callbacks = new ArrayList<DijkstraCallback>();
|
||||
|
||||
/**
|
||||
* Create a comparator to sort which routers take priority.
|
||||
*/
|
||||
private final Comparator<Router> shortertDistanceComparator = new Comparator<Router>(){
|
||||
public int compare(Router firstRouter, Router secondRouter){
|
||||
|
||||
int results = getShortestDistance(firstRouter) - getShortestDistance(secondRouter);
|
||||
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
||||
private final PriorityQueue<Router> unsettledNodes = new PriorityQueue<Router>(
|
||||
1, shortertDistanceComparator);
|
||||
|
||||
private final Set<Router> settledNodes = new HashSet<Router>();
|
||||
private final Map<Router, Integer> shortestDistances = new HashMap<Router, Integer>();
|
||||
private final Map<Router, Router> predecessors = new HashMap<Router, Router>();
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public DijkstraEngine() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a callback that will be called when an event happens.
|
||||
* @param dc Callback class to call.
|
||||
*/
|
||||
public void registerCallback(DijkstraCallback dc) {
|
||||
if (!callbacks.contains(dc)) {
|
||||
callbacks.add(dc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a callback from the list.
|
||||
* @param dc Callback to remove.
|
||||
*/
|
||||
public void unregisterCallback(DijkstraCallback dc) {
|
||||
callbacks.remove(dc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nodes that have their paths determined.
|
||||
* @return Set of settled nodes.
|
||||
*/
|
||||
public Set<Router> getSettledNodes() {
|
||||
return settledNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of routers which have values associated to them telling what the
|
||||
* shortest distances are from the start router to the key router.
|
||||
* @return Map of router->integers.
|
||||
*/
|
||||
public Map<Router, Integer> getShortestDistances() {
|
||||
return shortestDistances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of predecessors.
|
||||
* @return Router->Router mapping.
|
||||
*/
|
||||
public Map<Router, Router> getPredecessors() {
|
||||
return predecessors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method which adds a router and the shortest possible distance from
|
||||
* the start router to the given router.
|
||||
* @param _router Router to add.
|
||||
* @param cost Cost to get to that router.
|
||||
*/
|
||||
private void setShortestDistance(Router _router, int cost) {
|
||||
for (DijkstraCallback dc : callbacks) {
|
||||
dc.shortestDistanceUpdated(_router, cost);
|
||||
}
|
||||
|
||||
unsettledNodes.remove(_router);
|
||||
shortestDistances.put(_router, cost);
|
||||
unsettledNodes.add(_router);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param _startRouter
|
||||
*/
|
||||
private void initialize(Router _startRouter){
|
||||
for (DijkstraCallback dc : callbacks) {
|
||||
dc.reset();
|
||||
}
|
||||
|
||||
settledNodes.clear();
|
||||
unsettledNodes.clear();
|
||||
|
||||
shortestDistances.clear();
|
||||
predecessors.clear();
|
||||
|
||||
setShortestDistance(_startRouter, 0);
|
||||
unsettledNodes.add(_startRouter);
|
||||
}
|
||||
|
||||
private boolean isSettled(Router _router){
|
||||
return settledNodes.contains(_router);
|
||||
}
|
||||
|
||||
private void relaxNeighbors(Router _router){
|
||||
for (Router r : Network.getInstance().getNeighboringRouters(_router)){
|
||||
if (isSettled(r)) continue;
|
||||
if (r == null) continue;
|
||||
|
||||
Connection tempConnection = _router.getConnectionByParticipant(_router.getIpAddress(), r.getIpAddress());
|
||||
if (tempConnection == null) continue;
|
||||
|
||||
int shortDistance = getShortestDistance(_router) + tempConnection.getCost();
|
||||
|
||||
if (shortDistance < getShortestDistance(r)){
|
||||
setShortestDistance(r, shortDistance);
|
||||
setPredecessor(_router, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setPredecessor(Router a, Router b){
|
||||
for (DijkstraCallback dc : callbacks) {
|
||||
dc.predecessorAdded(a, b);
|
||||
}
|
||||
|
||||
predecessors.put(a, b);
|
||||
}
|
||||
|
||||
public int getShortestDistance(Router _router){
|
||||
Integer d = shortestDistances.get(_router);
|
||||
return (d == null) ? infinity : d;
|
||||
}
|
||||
|
||||
public Router getPredecessor(Router r){
|
||||
return predecessors.get(r);
|
||||
}
|
||||
|
||||
public void execute(Router startRouter, Router endRouter) {
|
||||
initialize(startRouter);
|
||||
|
||||
Router r = null;
|
||||
|
||||
while ((r = unsettledNodes.poll()) != null){
|
||||
if (r == endRouter) break;
|
||||
|
||||
settledNodes.add(r);
|
||||
for (DijkstraCallback dc : callbacks) {
|
||||
dc.settledRouterAdded(r);
|
||||
}
|
||||
|
||||
relaxNeighbors(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the shortest path between one router and another, returning the path that one must
|
||||
* take to get from the start to the end.
|
||||
*
|
||||
* Note that this function must run the algorithm multiple times to find how it gets from start to end.
|
||||
* Therefore, in a very large network, this may take a while to execute. On modern computers, this is
|
||||
* not much of a concern. Still, a more efficient algorithm should be used to find start->end along the
|
||||
* quickest path in a more serious system.
|
||||
* @param startRouter Router to start from.
|
||||
* @param endRouter Router to end at.
|
||||
* @return The path (Path object) from the start to the end. If start is not connected to end,
|
||||
* this will return null.
|
||||
*/
|
||||
public Path findShortestPath(Router startRouter, Router endRouter){
|
||||
// Get the array of network routers.
|
||||
routers.clear();
|
||||
|
||||
// Run the algorithm once to get the shortest path from start to end..
|
||||
execute(startRouter, endRouter);
|
||||
|
||||
if (shortestDistances.get(endRouter) == null) {
|
||||
// In this situation, startRouter is not connected to endRouter.
|
||||
return null;
|
||||
}
|
||||
|
||||
// We now know how much it will cost to get from start to end.
|
||||
final int totalCost = shortestDistances.get(endRouter);
|
||||
|
||||
// Leading cost will track how much it costs each step from start to end (additively).
|
||||
int leadingCost = 0;
|
||||
|
||||
Router currentRouter = startRouter;
|
||||
Router lastRouter = currentRouter;
|
||||
|
||||
// Loop until we reach the last router.
|
||||
while (!currentRouter.getIpAddress().equals(endRouter.getIpAddress())) {
|
||||
final ArrayList<Router> neighbors = (ArrayList<Router>)Network.getInstance().getNeighboringRouters(currentRouter);
|
||||
// No need to check last router.
|
||||
neighbors.remove(lastRouter);
|
||||
|
||||
// Search through the current router's neighbors, attempting to find the shortest path from A to B.
|
||||
for (Router r : neighbors) {
|
||||
execute(r, endRouter);
|
||||
|
||||
final Connection c = currentRouter.getConnectionByParticipant(
|
||||
currentRouter.getIpAddress(), r.getIpAddress());
|
||||
|
||||
// Obtain cost from the current router to the target router.
|
||||
final int newCost = shortestDistances.get(endRouter);
|
||||
|
||||
// Test if this router's jump cost is the same as the total cost, taking into
|
||||
// consideration how much it cost to get from previous connections to the current router.
|
||||
if ((totalCost - newCost - leadingCost) == c.getCost()) {
|
||||
// We've found our router -- add it to the path.
|
||||
routers.add(Network.getInstance().getRouterByIp(r.getIpAddress()));
|
||||
|
||||
leadingCost += c.getCost();
|
||||
|
||||
currentRouter = r;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lastRouter = currentRouter;
|
||||
}
|
||||
|
||||
if (!routers.contains(endRouter))
|
||||
routers.add(endRouter);
|
||||
|
||||
// Convert the array list to a raw array of routers.
|
||||
Router[] list = new Router[routers.size()];
|
||||
for (int i = 0; i < routers.size(); i++) {
|
||||
list[i] = routers.get(i);
|
||||
}
|
||||
|
||||
return new Path(list, totalCost);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
129
src/main/java/net/locusworks/lsproject/object/Network.java
Normal file
129
src/main/java/net/locusworks/lsproject/object/Network.java
Normal file
@@ -0,0 +1,129 @@
|
||||
package net.locusworks.lsproject.object;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Network class is capable of performing LS calculations and has the router information
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class Network implements Serializable {
|
||||
// Makes compiler happy.
|
||||
private static final long serialVersionUID = -3073110726594813517L;
|
||||
|
||||
private String name = null;
|
||||
private ArrayList<Router> routers = new ArrayList<Router>();
|
||||
|
||||
private static Network instance;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Network.
|
||||
* @param _name Name of the network.
|
||||
*/
|
||||
private Network(String _name) {
|
||||
setName(_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the network's name.
|
||||
* @return String containing the network's name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new name for the network, which is used as the file name for the network.
|
||||
* @param _name Name of the network.
|
||||
*/
|
||||
public void setName(String _name) {
|
||||
name = _name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a router to the network.
|
||||
* @param r Router to add.
|
||||
*/
|
||||
public synchronized void addRouter(Router r) {
|
||||
routers.add(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the routers in this network.
|
||||
* @return Array list of routers.
|
||||
*/
|
||||
public synchronized ArrayList<Router> getRouters() {
|
||||
return routers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a router by it's IP address.
|
||||
* @param ip IP address to search for.
|
||||
* @return The router that is being searched for. Returns null if the router doesn't exist.
|
||||
*/
|
||||
public synchronized Router getRouterByIp(String ip) {
|
||||
for (Router r : routers) {
|
||||
if (r.getIpAddress().equals(ip)) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized List<Router> getNeighboringRouters(Router _router){
|
||||
List<Router> neighboringRouters = new ArrayList<Router>(_router.getConnections().size());
|
||||
|
||||
final String sourceAddr = _router.getIpAddress();
|
||||
for (Connection connection : _router.getConnections()){
|
||||
if (!connection.getFirstParticipantAddress().equals(sourceAddr)){
|
||||
neighboringRouters.add(getRouterByIp(connection.getFirstParticipantAddress()));
|
||||
}
|
||||
else{
|
||||
neighboringRouters.add(getRouterByIp(connection.getSecondParticipantAddress()));
|
||||
}
|
||||
}
|
||||
|
||||
return neighboringRouters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a router from the network.
|
||||
* @param ip IP address of the router.
|
||||
*/
|
||||
public synchronized void removeRouterByIp(String ip) {
|
||||
for (int i = 0; i < routers.size(); i++) {
|
||||
if (routers.get(i).getIpAddress().equals(ip)) {
|
||||
for (Connection c : routers.get(i).getConnections()) {
|
||||
final String otherRouterAddr = (!c.getFirstParticipantAddress().equals(ip) ?
|
||||
c.getFirstParticipantAddress() : c.getSecondParticipantAddress());
|
||||
|
||||
Router r = getRouterByIp(otherRouterAddr);
|
||||
r.removeConnectionByParticipant(ip, otherRouterAddr);
|
||||
}
|
||||
|
||||
routers.remove(i);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void createInstance(String networkName) {
|
||||
instance = new Network(networkName);
|
||||
}
|
||||
|
||||
public static Network getInstance() {
|
||||
if (instance == null) instance = new Network("network");
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void createInstance(Network readObject) {
|
||||
instance = readObject;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
42
src/main/java/net/locusworks/lsproject/object/Path.java
Normal file
42
src/main/java/net/locusworks/lsproject/object/Path.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package net.locusworks.lsproject.object;
|
||||
|
||||
|
||||
public class Path{
|
||||
|
||||
private Router[] routers;
|
||||
private int totalCost;
|
||||
private int element = 0;
|
||||
|
||||
public Path(Router[] _routers, int cost){
|
||||
|
||||
totalCost = cost;
|
||||
routers = _routers;
|
||||
}
|
||||
|
||||
public int getTotalCost(){
|
||||
return totalCost;
|
||||
}
|
||||
|
||||
public boolean hasNext(){
|
||||
return (element < routers.length);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
element = 0;
|
||||
}
|
||||
|
||||
public Router getNext(){
|
||||
if (! hasNext())
|
||||
return null;
|
||||
|
||||
Router r = routers[element];
|
||||
element++;
|
||||
return r;
|
||||
}
|
||||
|
||||
public Router getDestinationRouter(){
|
||||
return routers[routers.length - 1];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
149
src/main/java/net/locusworks/lsproject/object/Router.java
Normal file
149
src/main/java/net/locusworks/lsproject/object/Router.java
Normal file
@@ -0,0 +1,149 @@
|
||||
package net.locusworks.lsproject.object;
|
||||
import java.awt.Point;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A Router is a single entity within the network that is capable of holding one or more connections
|
||||
* with various routers across the network. A router is uniquely identified on the network by it's
|
||||
* IP address.
|
||||
*/
|
||||
public class Router implements Serializable {
|
||||
private static final long serialVersionUID = 8998728841964957750L;
|
||||
|
||||
private ArrayList<Connection> connections;
|
||||
private String ipAddress;
|
||||
private Point position;
|
||||
|
||||
private RoutingTable routingTable;
|
||||
|
||||
/**
|
||||
* Create a new router.
|
||||
* @param _ipAddress IP address (should be unique) of the router.
|
||||
* @param _position Position of the router on the Network.
|
||||
*/
|
||||
public Router(String _ipAddress, Point _position) {
|
||||
ipAddress = _ipAddress;
|
||||
position = _position;
|
||||
connections = new ArrayList<Connection>();
|
||||
routingTable = new RoutingTable(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the routing table that this router calcultes.
|
||||
* @return
|
||||
*/
|
||||
public RoutingTable getRoutingTable() {
|
||||
return routingTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IP address of this router.
|
||||
* @return String containing the IP address of the router.
|
||||
*/
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new IP address for this router.
|
||||
* @param _ipAddress New address for the router.
|
||||
*/
|
||||
public void setIpAddress(String _ipAddress) {
|
||||
ipAddress = _ipAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the position of the router.
|
||||
* @return Position of the router in a Point object.
|
||||
*/
|
||||
public Point getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new position for the router.
|
||||
* @param _position Position to set.
|
||||
*/
|
||||
public void setPosition(Point _position) {
|
||||
position = _position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronized (thread-safe) method for adding a connection to this router.
|
||||
* @param _newConnection Add a new connection to this router's list of connections.
|
||||
*/
|
||||
public synchronized void addConnection(Connection _newConnection) {
|
||||
connections.add(_newConnection);
|
||||
|
||||
// Re-calculate connections.
|
||||
routingTable.execute(this, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search through the list of connections and obtain a connection based on the participants.<br>
|
||||
* NOTE: The order does not matter! It will return true regardless of which is the "first" or "second"
|
||||
* participant, assuming such a connection exists.
|
||||
* @param _ipAddress1 One participant's address.
|
||||
* @param _ipAddress2 Another participant's address.
|
||||
* @return Connection object if found, or null if not found.
|
||||
*/
|
||||
public synchronized Connection getConnectionByParticipant(String _ipAddress1, String _ipAddress2) {
|
||||
for (Connection connection : connections) {
|
||||
if ((connection .getFirstParticipantAddress() .equals(_ipAddress1) &&
|
||||
connection .getSecondParticipantAddress().equals(_ipAddress2)) ||
|
||||
(connection .getSecondParticipantAddress().equals(_ipAddress1) &&
|
||||
connection .getFirstParticipantAddress() .equals(_ipAddress2))) {
|
||||
// Connection found.
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string-form of Router, which is it's IP address.
|
||||
*/
|
||||
@Override public String toString() {
|
||||
return getIpAddress();
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a connection from the list of connections.
|
||||
* @param _ipAddress1 First participant.
|
||||
* @param _ipAddress2 Second participant.
|
||||
*/
|
||||
public synchronized void removeConnectionByParticipant(String _ipAddress1, String _ipAddress2) {
|
||||
connections.remove(getConnectionByParticipant(_ipAddress1, _ipAddress2));
|
||||
|
||||
routingTable.execute(this, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Router's list of connections. Useful if the router is deleted and connections
|
||||
* need to be severed.
|
||||
* @return Array list of Connection objects.
|
||||
*/
|
||||
public synchronized ArrayList<Connection> getConnections() {
|
||||
return connections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the Router's list of connections.
|
||||
*/
|
||||
public synchronized void clearConnections(){
|
||||
connections.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple method for adding connection.
|
||||
* @param router1
|
||||
* @param router2
|
||||
* @param connection
|
||||
*/
|
||||
public static void addConnection(Router router1, Router router2, Connection connection) {
|
||||
router1.addConnection(connection);
|
||||
router2.addConnection(connection);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.locusworks.lsproject.object;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class RoutingTable extends DijkstraEngine implements Serializable {
|
||||
private static final long serialVersionUID = 848488383828283L;
|
||||
private Router parentRouter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param _parentRouter
|
||||
*/
|
||||
public RoutingTable(Router _parentRouter){
|
||||
parentRouter = _parentRouter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide access to this table's parent router.
|
||||
* @return Parent router which this routing table is for.
|
||||
*/
|
||||
public Router getRouter() {
|
||||
return parentRouter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform Dijkstra's algorithm. Should be called every time the router is changed.
|
||||
*/
|
||||
public void recalculate() {
|
||||
execute(parentRouter, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.locusworks.lsproject.object.helper;
|
||||
|
||||
import net.locusworks.lsproject.object.Router;
|
||||
|
||||
/**
|
||||
* A callback can be set to the DijkstraEngine if one needs live updates to
|
||||
* the algorithm.
|
||||
*/
|
||||
public interface DijkstraCallback {
|
||||
public void reset();
|
||||
public void settledRouterAdded(Router router);
|
||||
public void predecessorAdded(Router key, Router value);
|
||||
public void shortestDistanceUpdated(Router router, int cost);
|
||||
}
|
||||
72
src/main/java/net/locusworks/lsproject/util/Utility.java
Normal file
72
src/main/java/net/locusworks/lsproject/util/Utility.java
Normal file
@@ -0,0 +1,72 @@
|
||||
package net.locusworks.lsproject.util;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import net.locusworks.lsproject.object.Network;
|
||||
|
||||
|
||||
public final class Utility {
|
||||
public static final String FILE_EXTENSION = ".lsa";
|
||||
|
||||
/**
|
||||
* Save a network to disk. It uses it's name + the file extension FILE_EXTENSION.
|
||||
* @param network Network to save.
|
||||
* @throws IOException Thrown if an IO error occurs during write.
|
||||
*/
|
||||
public static void saveNetwork() throws IOException {
|
||||
FileOutputStream out = new FileOutputStream(Network.getInstance().getName() + FILE_EXTENSION);
|
||||
ObjectOutputStream objectOut = new ObjectOutputStream(out);
|
||||
|
||||
objectOut.writeObject(Network.getInstance());
|
||||
|
||||
objectOut.flush();
|
||||
objectOut.close();
|
||||
out.close();
|
||||
|
||||
System.out.println("Wrote network " + Network.getInstance().getName() + " to file.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an existing network object file from disk.
|
||||
* @param networkFile File to load.
|
||||
* @return Network object.
|
||||
* @throws IOException Thrown if an IO error occurs during read.
|
||||
*/
|
||||
public static void loadNetwork(File networkFile) throws IOException {
|
||||
if (!networkFile.getName().endsWith(FILE_EXTENSION)) {
|
||||
throw new IOException("Invalid network object file.");
|
||||
}
|
||||
|
||||
FileInputStream in = new FileInputStream(networkFile);
|
||||
ObjectInputStream objectIn = new ObjectInputStream(in);
|
||||
|
||||
try {
|
||||
Network.createInstance((Network)objectIn.readObject());
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new IOException("Target file is corrupted.");
|
||||
}
|
||||
finally {
|
||||
objectIn.close();
|
||||
in.close();
|
||||
}
|
||||
|
||||
System.out.println("Loaded network " + Network.getInstance().getName() + ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function for getting a file's extension.
|
||||
* @param f File to look at.
|
||||
* @return Extension of the file.
|
||||
*/
|
||||
public static String getExtension(File f) {
|
||||
String ext = null;
|
||||
String s = f.getName();
|
||||
int i = s.lastIndexOf('.');
|
||||
|
||||
if (i > 0 && i < s.length() - 1) {
|
||||
ext = s.substring(i+1).toLowerCase();
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
}
|
||||
BIN
src/main/resources/assets/router.png
Normal file
BIN
src/main/resources/assets/router.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.8 KiB |
BIN
src/main/resources/assets/router_ico.png
Normal file
BIN
src/main/resources/assets/router_ico.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
49
src/test/java/object/ConnectionTest.java
Normal file
49
src/test/java/object/ConnectionTest.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package object;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import net.locusworks.lsproject.object.Connection;
|
||||
|
||||
public class ConnectionTest {
|
||||
|
||||
private Connection testConnection;
|
||||
|
||||
@Before
|
||||
public void setUpBeforeTest(){
|
||||
|
||||
testConnection = new Connection("1", "2", 4);
|
||||
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testGetCost() {
|
||||
assertEquals(4, testConnection.getCost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetCost() {
|
||||
testConnection.setCost(21);
|
||||
assertEquals(21, testConnection.getCost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFirstParticipantAddress() {
|
||||
assertEquals("1", testConnection.getFirstParticipantAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSecondParticipantAddress() {
|
||||
assertEquals("2", testConnection.getSecondParticipantAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetParticipants() {
|
||||
testConnection.setParticipants("100", "200");
|
||||
assertEquals("100", testConnection.getFirstParticipantAddress());
|
||||
assertEquals("200", testConnection.getSecondParticipantAddress());
|
||||
}
|
||||
|
||||
}
|
||||
90
src/test/java/object/NetworkTest.java
Normal file
90
src/test/java/object/NetworkTest.java
Normal file
@@ -0,0 +1,90 @@
|
||||
package object;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import net.locusworks.lsproject.driver.Program;
|
||||
import net.locusworks.lsproject.object.Connection;
|
||||
import net.locusworks.lsproject.object.DijkstraEngine;
|
||||
import net.locusworks.lsproject.object.Network;
|
||||
import net.locusworks.lsproject.object.Path;
|
||||
import net.locusworks.lsproject.object.Router;
|
||||
|
||||
public class NetworkTest {
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() {
|
||||
Network.createInstance("Johnny");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUpBeforeTest(){
|
||||
Router router1 = new Router("192.168.1.0", new Point(0,1));
|
||||
Router router2 = new Router("192.168.1.1", new Point(0,2));
|
||||
Router router3 = new Router("192.168.1.2", new Point(0,3));
|
||||
Router router4 = new Router("192.168.1.3", new Point(0,4));
|
||||
Router router5 = new Router("192.168.1.4", new Point(0,5));
|
||||
|
||||
|
||||
Connection connection1 = new Connection(router1.getIpAddress(),
|
||||
router2.getIpAddress(), 1);
|
||||
|
||||
Connection connection2 = new Connection(router1.getIpAddress(),
|
||||
router3.getIpAddress(), 3);
|
||||
|
||||
Connection connection3 = new Connection(router1.getIpAddress(),
|
||||
router4.getIpAddress(), 6);
|
||||
|
||||
Connection connection4 = new Connection(router2.getIpAddress(),
|
||||
router3.getIpAddress(), 5);
|
||||
|
||||
Connection connection5 = new Connection(router2.getIpAddress(),
|
||||
router4.getIpAddress(), 2);
|
||||
|
||||
Connection connection6 = new Connection(router3.getIpAddress(),
|
||||
router5.getIpAddress(), 2);
|
||||
|
||||
Connection connection7 = new Connection(router4.getIpAddress(),
|
||||
router5.getIpAddress(), 1);
|
||||
|
||||
Router.addConnection(router1, router2, connection1);
|
||||
Router.addConnection(router1, router3, connection2);
|
||||
Router.addConnection(router1, router4, connection3);
|
||||
Router.addConnection(router2, router3, connection4);
|
||||
Router.addConnection(router2, router4, connection5);
|
||||
Router.addConnection(router3, router5, connection6);
|
||||
Router.addConnection(router4, router5, connection7);
|
||||
|
||||
Network.getInstance().addRouter(router1);
|
||||
Network.getInstance().addRouter(router2);
|
||||
Network.getInstance().addRouter(router3);
|
||||
Network.getInstance().addRouter(router4);
|
||||
Network.getInstance().addRouter(router5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testFindShortestPath(){
|
||||
DijkstraEngine engine = new DijkstraEngine();
|
||||
|
||||
System.out.println(Network.getInstance().getRouters().size());
|
||||
|
||||
Path path = engine.findShortestPath(Network.getInstance().getRouterByIp("192.168.1.0"),
|
||||
Network.getInstance().getRouterByIp("192.168.1.4"));
|
||||
|
||||
int i = 1;
|
||||
ArrayList<Router> routerz = new ArrayList<Router>();
|
||||
while (path.hasNext()) {
|
||||
Router r = path.getNext();
|
||||
routerz.add(r);
|
||||
System.out.println("Step " + i++ + ": " + r.getIpAddress());
|
||||
}
|
||||
System.out.println("Total cost: " + path.getTotalCost());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
73
src/test/java/object/PathTest.java
Normal file
73
src/test/java/object/PathTest.java
Normal file
@@ -0,0 +1,73 @@
|
||||
package object;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import java.awt.Point;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.locusworks.lsproject.object.Connection;
|
||||
import net.locusworks.lsproject.object.Path;
|
||||
import net.locusworks.lsproject.object.Router;
|
||||
|
||||
public class PathTest {
|
||||
private Path path;
|
||||
private Path path2;
|
||||
private final int expectedTotalCost = 9;
|
||||
|
||||
@Before
|
||||
public void setUpBeforeClass(){
|
||||
Router[] routers = new Router[10];
|
||||
|
||||
for(int i = 0; i < 10; i++){
|
||||
Router router = new Router("192.168.1."+ i, new Point(0, 0));
|
||||
routers[i] = router;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 9; i++){
|
||||
Connection connection = new Connection("192.168.1."+i, "192.168.1."+(i+1),
|
||||
1);
|
||||
routers[i].addConnection(connection);
|
||||
routers[i+1].addConnection(connection);
|
||||
}
|
||||
|
||||
path = new Path(routers, expectedTotalCost);
|
||||
path2 = new Path(routers, expectedTotalCost);
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testPath() {
|
||||
|
||||
for(int i = 0; i < 8; i++){
|
||||
if(path.hasNext() == false|| path2.hasNext() == false){
|
||||
fail("Has Next failed at " + i + ". Should Never be False but was False");
|
||||
}
|
||||
assertEquals(path.getNext(), path2.getNext());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetTotalCost() {
|
||||
assertEquals(expectedTotalCost, path.getTotalCost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNext(){
|
||||
for(int i = 0; i < 9; i++){
|
||||
if(path.getNext() == null){
|
||||
fail("getNext reached null. Should never reach it");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasNext(){
|
||||
for (int i = 0; i < 9; i++){
|
||||
path.getNext();
|
||||
if(path.hasNext() == false){
|
||||
fail("hasNext reached the end of the elements");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
78
src/test/java/object/RouterTest.java
Normal file
78
src/test/java/object/RouterTest.java
Normal file
@@ -0,0 +1,78 @@
|
||||
package object;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import net.locusworks.lsproject.object.Connection;
|
||||
import net.locusworks.lsproject.object.Router;
|
||||
|
||||
public class RouterTest {
|
||||
private Router router = null;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUpBeforeTest(){
|
||||
|
||||
router = new Router("192.168.1.0", new Point(0, 0));
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIpAddress() {
|
||||
if (! router.getIpAddress().equals("192.168.1.0")){
|
||||
fail("ip Address does not match");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetIpAddress() {
|
||||
router.setIpAddress("192.168.1.2");
|
||||
if(! router.getIpAddress().equals("192.168.1.2")){
|
||||
fail("Ip address did not set correctly");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddConnection() {
|
||||
Connection testConnection = new Connection("192.168.1.3", "192.168.1.4", 3);
|
||||
router.addConnection(testConnection);
|
||||
|
||||
String connection1 = router.getConnections().get(0).getFirstParticipantAddress();
|
||||
String connection2 = router.getConnections().get(0).getSecondParticipantAddress();
|
||||
|
||||
assertEquals("192.168.1.3", connection1);
|
||||
assertEquals("192.168.1.4", connection2);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConnectionByParticipant() {
|
||||
|
||||
for(int i = 0; i < 10; i++){
|
||||
router.addConnection(new Connection(Integer.toString(i), Integer.toString(i+1), 1));
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < 10; i++){
|
||||
Connection testConnection = router.getConnectionByParticipant(
|
||||
Integer.toString(i), Integer.toString(i+1));
|
||||
assertEquals(Integer.toString(i), testConnection.getFirstParticipantAddress());
|
||||
assertEquals(Integer.toString(i+1), testConnection.getSecondParticipantAddress());
|
||||
}
|
||||
|
||||
Connection testCase = new Connection ("a", "A", 1);
|
||||
|
||||
router.clearConnections();
|
||||
|
||||
router.addConnection(testCase);
|
||||
assertNull(router.getConnectionByParticipant("a", "a"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user