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:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/target
|
||||||
|
/dist
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
my file.lsa
|
||||||
|
.settings
|
186
Jenkinsfile
vendored
Normal file
186
Jenkinsfile
vendored
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
#!groovy
|
||||||
|
|
||||||
|
// Required Jenkins plugins:
|
||||||
|
// https://wiki.jenkins-ci.org/display/JENKINS/Timestamper
|
||||||
|
// https://wiki.jenkins-ci.org/display/JENKINS/Static+Code+Analysis+Plug-ins
|
||||||
|
// https://wiki.jenkins-ci.org/display/JENKINS/Checkstyle+Plugin ?
|
||||||
|
// https://wiki.jenkins-ci.org/display/JENKINS/FindBugs+Plugin
|
||||||
|
// https://wiki.jenkins-ci.org/display/JENKINS/PMD+Plugin ?
|
||||||
|
// https://wiki.jenkins-ci.org/display/JENKINS/DRY+Plugin ?
|
||||||
|
// https://wiki.jenkins-ci.org/display/JENKINS/Task+Scanner+Plugin
|
||||||
|
// https://wiki.jenkins-ci.org/display/JENKINS/Javadoc+Plugin
|
||||||
|
// https://wiki.jenkins-ci.org/display/JENKINS/JaCoCo+Plugin ?
|
||||||
|
|
||||||
|
|
||||||
|
init()
|
||||||
|
|
||||||
|
def branch_name
|
||||||
|
def branch_name_base
|
||||||
|
def build_number
|
||||||
|
def build_url
|
||||||
|
def git_commit
|
||||||
|
def job_name
|
||||||
|
def tag
|
||||||
|
def version
|
||||||
|
def build_type
|
||||||
|
def display_name
|
||||||
|
|
||||||
|
def init() {
|
||||||
|
|
||||||
|
// Keep the 5 most recent builds
|
||||||
|
properties([[$class: 'BuildDiscarderProperty', strategy: [$class: 'LogRotator', numToKeepStr: '5']]])
|
||||||
|
|
||||||
|
build_number = env.BUILD_NUMBER
|
||||||
|
build_url = env.BUILD_URL
|
||||||
|
job_name = "${env.JOB_NAME}"
|
||||||
|
branch_name = env.BRANCH_NAME
|
||||||
|
branch_name_docker = branch_name.replaceAll(/\//,'.')
|
||||||
|
persist = "/var/lib/jenkins/PERSIST/${branch_name_docker}"
|
||||||
|
|
||||||
|
// execute the branch type specific pipeline code
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (branch_name.indexOf('release/')==0) build_type='release'
|
||||||
|
if (branch_name.indexOf('feature/')==0) build_type='feature'
|
||||||
|
if (branch_name.indexOf('develop')==0) build_type='develop'
|
||||||
|
if (branch_name.indexOf('hotfix')==0) build_type='hotfix'
|
||||||
|
if (branch_name.indexOf('bugfix')==0) build_type='bugfix'
|
||||||
|
if (branch_name.indexOf('master')==0) build_type='master'
|
||||||
|
|
||||||
|
// common pipeline elements
|
||||||
|
node('master') {
|
||||||
|
Initialize()
|
||||||
|
SetVersion(build_type)
|
||||||
|
print_vars() // after SetVersion - all variables now defined
|
||||||
|
set_result('INPROGRESS')
|
||||||
|
Build() // builds database via flyway migration
|
||||||
|
}
|
||||||
|
|
||||||
|
if (branch_name.indexOf('develop')==0) {
|
||||||
|
node('master') {
|
||||||
|
Deploy();
|
||||||
|
}
|
||||||
|
} else if (branch_name.indexOf('release/')==0) {
|
||||||
|
node('master') {
|
||||||
|
Deploy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node('master') {
|
||||||
|
set_result('SUCCESS')
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
node() {
|
||||||
|
set_result('FAILURE')
|
||||||
|
}
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def Build() {
|
||||||
|
stage ('build') {
|
||||||
|
mvn "install -DskipTests=true -Dbuild.revision=${git_commit}"
|
||||||
|
step([$class: 'ArtifactArchiver', artifacts: '**/target/*.jar', fingerprint: true])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def Initialize() {
|
||||||
|
stage ('initialize') {
|
||||||
|
|
||||||
|
// get new code
|
||||||
|
checkout scm
|
||||||
|
|
||||||
|
git_commit = getSha1()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def Deploy() {
|
||||||
|
stage ('deploy') {
|
||||||
|
mvn "deploy -DskipTests=true -Dbuild.number=${build_number} -Dbuild.revision=${git_commit}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getSha1() {
|
||||||
|
sha1 = sh(script: 'git rev-parse HEAD', returnStdout: true).trim()
|
||||||
|
echo "sha1 is ${sha1}"
|
||||||
|
return sha1
|
||||||
|
}
|
||||||
|
|
||||||
|
def mvn(args) {
|
||||||
|
withMaven(
|
||||||
|
maven: 'maven-3.6.1',
|
||||||
|
globalMavenSettingsConfig: 'locusworks-settings'
|
||||||
|
) {
|
||||||
|
|
||||||
|
sh "mvn ${args}"
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def mvn_initial(args) {
|
||||||
|
mvn(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
def set_result(status) {
|
||||||
|
if ( status == 'SUCCESS' ) {
|
||||||
|
currentBuild.result = status
|
||||||
|
notify_bitbucket('SUCCESSFUL')
|
||||||
|
} else if ( status == 'FAILURE' ) {
|
||||||
|
currentBuild.result = status
|
||||||
|
notify_bitbucket('FAILED')
|
||||||
|
} else if ( status == 'INPROGRESS' ) {
|
||||||
|
notify_bitbucket('INPROGRESS')
|
||||||
|
} else {
|
||||||
|
error ("unknown status")
|
||||||
|
}
|
||||||
|
|
||||||
|
// save in persistence file for access the status page
|
||||||
|
// make sure the directory exists first
|
||||||
|
sh "mkdir -p $persist && echo $status > $persist/build.result"
|
||||||
|
}
|
||||||
|
|
||||||
|
def notify_bitbucket(state) {
|
||||||
|
}
|
||||||
|
|
||||||
|
def print_vars() {
|
||||||
|
echo "build_number = ${build_number}"
|
||||||
|
echo "build_url = ${build_url}"
|
||||||
|
echo "job_name = ${job_name}"
|
||||||
|
echo "branch_name = ${branch_name}"
|
||||||
|
echo "branch_name_base = ${branch_name_base}"
|
||||||
|
echo "build_type = ${build_type}"
|
||||||
|
echo "display_name = ${currentBuild.displayName}"
|
||||||
|
echo "version = ${version}"
|
||||||
|
echo "git_commit = ${git_commit}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
def SetVersion( v ) {
|
||||||
|
stage ('set version') {
|
||||||
|
echo "set version ${v}"
|
||||||
|
branch_name_base = (branch_name =~ /([^\/]+$)/)[0][0]
|
||||||
|
if ( v == 'release' ) {
|
||||||
|
// for release branches, where the branch is named "release/1.2.3",
|
||||||
|
// derive the version and display name derive from the numeric suffix and append the build number
|
||||||
|
// 3.2.1.100
|
||||||
|
version = branch_name_base + "." + build_number + "-RELEASE";
|
||||||
|
//version = branch_name.substring('release/'.length()) + "." + build_number
|
||||||
|
currentBuild.displayName = version
|
||||||
|
} else if (v == 'develop') {
|
||||||
|
version = branch_name_base + "." + build_number + "-SNAPSHOT";
|
||||||
|
currentBuild.displayName = version
|
||||||
|
} else {
|
||||||
|
// for all other branches the version number is 0 with an appended build number
|
||||||
|
// and for the display name use the jenkins default #n and add the branch name
|
||||||
|
// #101 - feature/user/foo
|
||||||
|
//version = '0.' + build_number
|
||||||
|
version = branch_name_base + "." + build_number
|
||||||
|
currentBuild.displayName = "#" + build_number + " - " + branch_name_base
|
||||||
|
}
|
||||||
|
display_name = currentBuild.displayName
|
||||||
|
mvn_initial "versions:set -DnewVersion=${version}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
39
pom.xml
Normal file
39
pom.xml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>net.locusworks</groupId>
|
||||||
|
<artifactId>lsproject</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>Link State Project</name>
|
||||||
|
<description>Demonstrates Dijkstra's algorithm</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- https://mvnrepository.com/artifact/junit/junit -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.13.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
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