diff --git a/.gitignore b/.gitignore
index a1e37f0..b9fce6c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,145 @@
-/nbproject/
-/build/
\ No newline at end of file
+# Created by https://www.gitignore.io/api/linux,macos,maven,windows,intellij
+
+### Intellij ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff:
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/dictionaries
+.idea/vcs.xml
+
+## Sensitive or high-churn files:
+#.idea/**/dataSources/
+#.idea/**/dataSources.ids
+#.idea/**/dataSources.xml
+#.idea/**/dataSources.local.xml
+#.idea/**/sqlDataSources.xml
+#.idea/**/dynamic.xml
+#.idea/**/uiDesigner.xml
+
+## Gradle:
+#.idea/**/gradle.xml
+#.idea/**/libraries
+
+# CMake
+cmake-build-debug/
+
+## Mongo Explorer plugin:
+#.idea/**/mongoSettings.xml
+
+## File-based project format:
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+### Intellij Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+.idea/sonarlint
+
+### Linux ###
+*~
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### macOS ###
+*.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### Maven ###
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+
+# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
+!/.mvn/wrapper/maven-wrapper.jar
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+\.idea/
+
+gabriel\.iml
diff --git a/.idea/artifacts/gabriel_jar.xml b/.idea/artifacts/gabriel_jar.xml
new file mode 100644
index 0000000..d7edc38
--- /dev/null
+++ b/.idea/artifacts/gabriel_jar.xml
@@ -0,0 +1,11 @@
+
+
+ $PROJECT_DIR$/out/artifacts/gabriel_jar
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
new file mode 100644
index 0000000..c4c9543
--- /dev/null
+++ b/.idea/codeStyleSettings.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..fa799c6
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..b26911b
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000..1c24f9a
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..fd7ac46
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/Gabriel.userlibraries b/Gabriel.userlibraries
new file mode 100644
index 0000000..5aec3f5
--- /dev/null
+++ b/Gabriel.userlibraries
@@ -0,0 +1,3 @@
+
+
+
diff --git a/README.md b/README.md
index 6ccf689..4ef8439 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,4 @@
# Gabriel
-Repository for organic node communication and resource transportation
+
+Organic node communication and resource transmission.
+
diff --git a/Screenshot000.jpg b/Screenshot000.jpg
new file mode 100644
index 0000000..4056d0e
Binary files /dev/null and b/Screenshot000.jpg differ
diff --git a/build.xml b/build.xml
deleted file mode 100644
index d07ad84..0000000
--- a/build.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- Builds, tests, and runs the project Gabriel.
-
-
-
diff --git a/manifest.mf b/manifest.mf
deleted file mode 100644
index 1574df4..0000000
--- a/manifest.mf
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-X-COMMENT: Main-Class will be added automatically by build
-
diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml
deleted file mode 100644
index 9caacb8..0000000
--- a/nbproject/build-impl.xml
+++ /dev/null
@@ -1,1420 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must set src.dir
- Must set test.src.dir
- Must set build.dir
- Must set dist.dir
- Must set build.classes.dir
- Must set dist.javadoc.dir
- Must set build.test.classes.dir
- Must set build.test.results.dir
- Must set build.classes.excludes
- Must set dist.jar
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must set javac.includes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- No tests executed.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must set JVM to use for profiling in profiler.info.jvm
- Must set profiler agent JVM arguments in profiler.info.jvmargs.agent
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select some files in the IDE or set javac.includes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- To run this application from the command line without Ant, try:
-
- java -jar "${dist.jar.resolved}"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set run.class
-
-
-
- Must select one file in the IDE or set run.class
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set debug.class
-
-
-
-
- Must select one file in the IDE or set debug.class
-
-
-
-
- Must set fix.includes
-
-
-
-
-
-
-
-
-
- This target only works when run from inside the NetBeans IDE.
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set profile.class
- This target only works when run from inside the NetBeans IDE.
-
-
-
-
-
-
-
-
- This target only works when run from inside the NetBeans IDE.
-
-
-
-
-
-
-
-
-
-
-
-
- This target only works when run from inside the NetBeans IDE.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set run.class
-
-
-
-
-
- Must select some files in the IDE or set test.includes
-
-
-
-
- Must select one file in the IDE or set run.class
-
-
-
-
- Must select one file in the IDE or set applet.url
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select some files in the IDE or set javac.includes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Some tests failed; see details above.
-
-
-
-
-
-
-
-
- Must select some files in the IDE or set test.includes
-
-
-
- Some tests failed; see details above.
-
-
-
- Must select some files in the IDE or set test.class
- Must select some method in the IDE or set test.method
-
-
-
- Some tests failed; see details above.
-
-
-
-
- Must select one file in the IDE or set test.class
-
-
-
- Must select one file in the IDE or set test.class
- Must select some method in the IDE or set test.method
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set applet.url
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set applet.url
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties
deleted file mode 100644
index 7cb5466..0000000
--- a/nbproject/genfiles.properties
+++ /dev/null
@@ -1,8 +0,0 @@
-build.xml.data.CRC32=bcbc5910
-build.xml.script.CRC32=fc3107a1
-build.xml.stylesheet.CRC32=8064a381@1.80.1.48
-# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
-# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=bcbc5910
-nbproject/build-impl.xml.script.CRC32=71363201
-nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48
diff --git a/nbproject/project.properties b/nbproject/project.properties
deleted file mode 100644
index 19d8340..0000000
--- a/nbproject/project.properties
+++ /dev/null
@@ -1,74 +0,0 @@
-annotation.processing.enabled=true
-annotation.processing.enabled.in.editor=false
-annotation.processing.processor.options=
-annotation.processing.processors.list=
-annotation.processing.run.all.processors=true
-annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
-build.classes.dir=${build.dir}/classes
-build.classes.excludes=**/*.java,**/*.form
-# This directory is removed when the project is cleaned:
-build.dir=build
-build.generated.dir=${build.dir}/generated
-build.generated.sources.dir=${build.dir}/generated-sources
-# Only compile against the classpath explicitly listed here:
-build.sysclasspath=ignore
-build.test.classes.dir=${build.dir}/test/classes
-build.test.results.dir=${build.dir}/test/results
-# Uncomment to specify the preferred debugger connection transport:
-#debug.transport=dt_socket
-debug.classpath=\
- ${run.classpath}
-debug.test.classpath=\
- ${run.test.classpath}
-# Files in build.classes.dir which should be excluded from distribution jar
-dist.archive.excludes=
-# This directory is removed when the project is cleaned:
-dist.dir=dist
-dist.jar=${dist.dir}/Gabriel.jar
-dist.javadoc.dir=${dist.dir}/javadoc
-excludes=
-includes=**
-jar.compress=false
-javac.classpath=
-# Space-separated list of extra javac options
-javac.compilerargs=
-javac.deprecation=false
-javac.external.vm=true
-javac.processorpath=\
- ${javac.classpath}
-javac.source=1.8
-javac.target=1.8
-javac.test.classpath=\
- ${javac.classpath}:\
- ${build.classes.dir}
-javac.test.processorpath=\
- ${javac.test.classpath}
-javadoc.additionalparam=
-javadoc.author=false
-javadoc.encoding=${source.encoding}
-javadoc.noindex=false
-javadoc.nonavbar=false
-javadoc.notree=false
-javadoc.private=false
-javadoc.splitindex=true
-javadoc.use=true
-javadoc.version=false
-javadoc.windowtitle=
-main.class=gabriel.MainScreen
-manifest.file=manifest.mf
-meta.inf.dir=${src.dir}/META-INF
-mkdist.disabled=false
-platform.active=default_platform
-run.classpath=\
- ${javac.classpath}:\
- ${build.classes.dir}
-# Space-separated list of JVM arguments used when running the project.
-# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
-# To set system properties for unit tests define test-sys-prop.name=value:
-run.jvmargs=
-run.test.classpath=\
- ${javac.test.classpath}:\
- ${build.test.classes.dir}
-source.encoding=UTF-8
-src.dir=src
-test.src.dir=test
diff --git a/nbproject/project.xml b/nbproject/project.xml
deleted file mode 100644
index 3de93d4..0000000
--- a/nbproject/project.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- org.netbeans.modules.java.j2seproject
-
-
- Gabriel
-
-
-
-
-
-
-
-
-
diff --git a/pom.xml b/pom.xml
index f89deb6..6454c4a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,13 +1,16 @@
-
- 4.0.0
- org.organet.commons
- Gabriel
- 1.0-SNAPSHOT
- jar
-
- UTF-8
- 1.8
- 1.8
-
-
\ No newline at end of file
+
+ 4.0.0
+
+ org.organet.commons
+ gabriel
+ 1.0-SNAPSHOT
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
diff --git a/src/gabriel/ConnectionManager.java b/src/gabriel/ConnectionManager.java
deleted file mode 100644
index 24f27db..0000000
--- a/src/gabriel/ConnectionManager.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel;
-
-import gabriel.models.Connection;
-import gabriel.models.Index;
-import gabriel.models.SharedFileHeader;
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author TheDoctor
- */
-public class ConnectionManager {
-
- private ArrayList connections = new ArrayList<>();
- private final Integer PORT_NO = 5000;
-
- Index myIndex = new Index();
- Index networkIndex = new Index();
-
- public Integer getPORT_NO() {
- return PORT_NO;
- }
-
- public ConnectionManager() {
-
- }
-
- public void addConnection(Connection conn) {
- this.connections.add(conn);
- }
-
- Boolean startConnection(Connection newConnection) {
- try {
- newConnection.setConnectionSocket(new Socket(newConnection.getConnectionIp(), PORT_NO));
-
- sendData(newConnection, myIndex);
- addConnection(newConnection);
- return true;
- } catch (IOException ex) {
- Logger.getLogger(ConnectionManager.class.getName()).log(Level.SEVERE, null, ex);
- return false;
- }
- }
-
- public void sendData(Connection connection, Index myIndex) {
- try {
- try (OutputStream os = connection.getConnectionSocket().getOutputStream()) {
- ObjectOutputStream objectOS = new ObjectOutputStream(os);
- objectOS.writeObject(myIndex);
- }
- } catch (IOException ex) {
- Logger.getLogger(ConnectionManager.class.getName()).log(Level.SEVERE, null, ex);
- }
-
- }
-
- public Index getMyIndex() {
- return myIndex;
- }
-
- public void setMyIndex(Index myIndex) {
- this.myIndex = myIndex;
- }
-
- public Index getNetworkIndex() {
- return networkIndex;
- }
-
- public void setNetworkIndex(Index networkIndex) {
- this.networkIndex = networkIndex;
- }
-
- void addToNetworkIndex(Index incomingIndex) {
- this.networkIndex.getFileHeaders().addAll(incomingIndex.getFileHeaders());
- }
-
- Index getIndex(Socket connectionSocket) {
- Index incomingIndex = null;
- try {
- //Getting the ObjectInputStream to retrive file index
- ObjectInputStream incomingStream = new ObjectInputStream(new BufferedInputStream(connectionSocket.getInputStream()));
-
- incomingIndex = (Index) incomingStream.readObject();
- } catch (IOException | ClassNotFoundException ex) {
- Logger.getLogger(ConnectionManager.class.getName()).log(Level.SEVERE, null, ex);
- }
- return incomingIndex;
- }
-
-}
diff --git a/src/gabriel/Controller/Hasher.java b/src/gabriel/Controller/Hasher.java
deleted file mode 100644
index 3efa387..0000000
--- a/src/gabriel/Controller/Hasher.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package gabriel.Controller;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-public class Hasher {
-
- public static String calculateFileHash(String path) throws IOException, NoSuchAlgorithmException {
-
-
-
- return null;
- }
-}
diff --git a/src/gabriel/Controller/HostChecker.java b/src/gabriel/Controller/HostChecker.java
deleted file mode 100644
index a1ab50c..0000000
--- a/src/gabriel/Controller/HostChecker.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel.Controller;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author TheDoctor
- */
-public class HostChecker extends Thread {
- String hostName = null;
- Boolean isValid = false;
- public HostChecker(String hostName) {
- this.hostName = hostName;
- }
- @Override
- public void run() {
- int timeout = 2000;
- try {
- if (InetAddress.getByName(hostName).isReachable(timeout)) {
- System.out.println(hostName + " is reachable ");
- isValid = true;
- }else
- isValid=false;
- } catch (IOException ex) {
- Logger.getLogger(Introducer.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-}
diff --git a/src/gabriel/Controller/HostCheckerAll.java b/src/gabriel/Controller/HostCheckerAll.java
deleted file mode 100644
index af3a75c..0000000
--- a/src/gabriel/Controller/HostCheckerAll.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel.Controller;
-
-import java.util.ArrayList;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- *
- * @author TheDoctor
- */
-public class HostCheckerAll{
-
- ArrayList hostIps = new ArrayList<>();
- String subnet;
- Integer possibleHostCount;
-
- public HostCheckerAll(String subnet, Integer possibleHostCount) {
- this.subnet = subnet;
- this.possibleHostCount = possibleHostCount;
- }
-
- public void run() {
-
- HostChecker[] hostCheckers = new HostChecker[possibleHostCount];
-
- String[] addresses = new String[possibleHostCount];
- for (int i = 0; i < possibleHostCount; i++) {
- addresses[i] = subnet + "." + i;
- }
- hostIps.clear();
- ExecutorService executor = Executors.newFixedThreadPool(possibleHostCount);
- for (int i = 0; i < possibleHostCount; i++) {
- hostCheckers[i] = new HostChecker(addresses[i]);
- executor.execute(hostCheckers[i]);
- }
- executor.shutdown();
- while (!executor.isTerminated()) {
- }
- for (int i = 0; i < possibleHostCount; i++) {
- if (hostCheckers[i].isValid && !hostIps.contains(hostCheckers[i].hostName)) {
- hostIps.add(hostCheckers[i].hostName);
- System.out.println("Host Ip: " + hostCheckers[i].hostName + " added");
-
- }
- }
- }
-
- public ArrayList getHostIps() {
- //Collections.sort(hostIps);
- return hostIps;
- }
-
- public void setHostIps(ArrayList hostIps) {
- this.hostIps = hostIps;
- }
-
- public String getSubnet() {
- return subnet;
- }
-
- public void setSubnet(String subnet) {
- this.subnet = subnet;
- }
-
- public Integer getHostCount() {
- return possibleHostCount;
- }
-
- public void setHostCount(Integer hostCount) {
- this.possibleHostCount = hostCount;
- }
-}
diff --git a/src/gabriel/Controller/Introducer.java b/src/gabriel/Controller/Introducer.java
deleted file mode 100644
index 436d347..0000000
--- a/src/gabriel/Controller/Introducer.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel.Controller;
-
-import gabriel.models.Connection;
-import gabriel.models.Node;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author EmreDan This class is to Introduce new node to the current node. It
- * creates a Connection object and listens for new connection.
- */
-public class Introducer implements Runnable {
-
- ArrayList nodes = new ArrayList<>();
- HostCheckerAll hostCheckerAll;
-
- public Introducer(ArrayList connections) {
- this.nodes = connections;
- }
-
- @Override
- public void run() {
- // When new connection comes add it to connections
-// while (true) {
-// //TODO: Search for why we should use logger.
-// System.out.println("Node " + connectionSocket.getInetAddress()
-// + ":" + connectionSocket.getPort() + " is connected.");
-// }
- }
-
- public void checkHostsBruteForce(String subnet) {
- try {
- hostCheckerAll = new HostCheckerAll(subnet, 255);
- hostCheckerAll.run();
-
- hostCheckerAll.getHostIps().forEach((hostIp) -> {
- try {
- Inet4Address ipAddress = (Inet4Address) Inet4Address.getByName(hostIp);
- this.nodes.add(new Node(ipAddress));
- } catch (UnknownHostException ex) {
- System.out.println("Error on Introducer.getConnections()!");
- }
- });
-
- System.out.println(hostCheckerAll.getHostIps());
- } catch (Exception ex) {
- Logger.getLogger(Introducer.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- public ArrayList getNodes() {
- return nodes;
- }
-
- public void setNodes(ArrayList nodes) {
- this.nodes = nodes;
- }
-
- public HostCheckerAll getHostCheckerAll() {
- return hostCheckerAll;
- }
-
- public void setHostCheckerAll(HostCheckerAll hostCheckerAll) {
- this.hostCheckerAll = hostCheckerAll;
- }
-
-}
diff --git a/src/gabriel/Controller/Receiver.java b/src/gabriel/Controller/Receiver.java
deleted file mode 100644
index d4c8c0f..0000000
--- a/src/gabriel/Controller/Receiver.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel.Controller;
-
-/**
- *
- * @author EmreDan
- * This class is to Receive Messages and Resources from other Connections
- */
-public class Receiver implements Runnable{
-
-
- @Override
- public void run() {
-
-
-
- }
-
-}
diff --git a/src/gabriel/Controller/Sender.java b/src/gabriel/Controller/Sender.java
deleted file mode 100644
index dcd5617..0000000
--- a/src/gabriel/Controller/Sender.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel.Controller;
-
-/**
- *
- * @author EmreDan
- * This class is to send Messages and Resources
- */
-public class Sender implements Runnable {
-
- @Override
- public void run() {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
-}
diff --git a/src/gabriel/Gabriel.java b/src/gabriel/Gabriel.java
deleted file mode 100644
index 6dba633..0000000
--- a/src/gabriel/Gabriel.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel;
-
-import gabriel.Controller.Sender;
-import gabriel.Controller.Receiver;
-import gabriel.Controller.Introducer;
-import gabriel.models.Node;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author TheDoctor This class is to: Listen for connection, send & receive
- * messages from & to nodes, update locale & remote index tables
- *
- */
-public class Gabriel {
-
- final static int RANDOM_PORT = 5000;
- String subnet = "192.168.1";
-
- private ArrayList nodeList;
- private Introducer mainIntroducer;
- private Receiver receiver;
- private Sender sender;
- private ConnectionManager connectionManager;
-
- public ArrayList getNodeList() {
- return nodeList;
- }
-
- public void setNodeList(ArrayList nodeList) {
- this.nodeList = nodeList;
- }
-
- public ConnectionManager getConnectionManager() {
- return connectionManager;
- }
-
- public void setConnectionManager(ConnectionManager connectionManager) {
- this.connectionManager = connectionManager;
- }
-
- public Gabriel() {
- nodeList = new ArrayList<>();
- sender = new Sender();
- receiver = new Receiver();
- mainIntroducer = new Introducer(nodeList);
- connectionManager = new ConnectionManager();
- }
-
- public Node getNode(String ipAddress) {
- for (Node node : nodeList) {
- if (node.getConnectionIp().toString().equals(ipAddress)) {
- return node;
- }
- }
- try {
- System.out.println("gelen ip `" + ipAddress + "`");
- return new Node((Inet4Address) InetAddress.getByName(ipAddress));
- } catch (UnknownHostException ex) {
- Logger.getLogger(Gabriel.class.getName()).log(Level.SEVERE, null, ex);
- return null;
- }
- }
-
- public ArrayList getNodes() {
- return nodeList;
- }
-
- public void setNodes(ArrayList nodeList) {
- this.nodeList = nodeList;
- }
-
- public Introducer getMainIntroducer() {
- return mainIntroducer;
- }
-
- public void setMainIntroducer(Introducer mainIntroducer) {
- this.mainIntroducer = mainIntroducer;
- }
-
- public Receiver getReceiver() {
- return receiver;
- }
-
- public void setReceiver(Receiver receiver) {
- this.receiver = receiver;
- }
-
- public Sender getSender() {
- return sender;
- }
-
- public void setSender(Sender sender) {
- this.sender = sender;
- }
-
- public String getSubnet() {
- return subnet;
- }
-
- public void setSubnet(String subnet) {
- this.subnet = subnet;
- }
-}
diff --git a/src/gabriel/MainScreen.form b/src/gabriel/MainScreen.form
deleted file mode 100644
index df0e6b5..0000000
--- a/src/gabriel/MainScreen.form
+++ /dev/null
@@ -1,198 +0,0 @@
-
-
-
diff --git a/src/gabriel/MainScreen.java b/src/gabriel/MainScreen.java
deleted file mode 100644
index 63f104d..0000000
--- a/src/gabriel/MainScreen.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel;
-
-import gabriel.Controller.Introducer;
-import gabriel.models.Connection;
-import gabriel.models.Index;
-import gabriel.models.Node;
-import java.awt.HeadlessException;
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.net.Inet4Address;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.concurrent.Executors;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.swing.JOptionPane;
-
-/**
- *
- * @author TheDoctor
- */
-public class MainScreen extends javax.swing.JFrame {
-
- /**
- * Creates new form MainScreen
- */
- Gabriel gabriel;
- Introducer mainIntroducer;
- ConnectionManager connectionManager;
-
- public MainScreen() {
- initComponents();
- gabriel = new Gabriel();
- connectionManager = gabriel.getConnectionManager();
- mainIntroducer = gabriel.getMainIntroducer();
- mainIntroducer.checkHostsBruteForce(gabriel.getSubnet());
- mainIntroducer.getHostCheckerAll().getHostIps().forEach((node) -> {
- IpListBox.add(node);
- });
-
- }
-
- /**
- * This method is called from within the constructor to initialize the form.
- * WARNING: Do NOT modify this code. The content of this method is always
- * regenerated by the Form Editor.
- */
- @SuppressWarnings("unchecked")
- // //GEN-BEGIN:initComponents
- private void initComponents() {
-
- ScanNetworkButton = new javax.swing.JButton();
- ConnectButton = new javax.swing.JButton();
- jLabel1 = new javax.swing.JLabel();
- jLabel2 = new javax.swing.JLabel();
- ConnectionListBox = new java.awt.List();
- jLabel3 = new javax.swing.JLabel();
- IpListBox = new java.awt.List();
- jLabel4 = new javax.swing.JLabel();
- filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0));
- listenConnection = new javax.swing.JButton();
- jLabel5 = new javax.swing.JLabel();
- NetworkIndexListBox = new java.awt.List();
- LocalIndexListBox = new java.awt.List();
-
- setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
-
- ScanNetworkButton.setText("Refresh Network List");
- ScanNetworkButton.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- ScanNetworkButtonActionPerformed(evt);
- }
- });
-
- ConnectButton.setText("Connect");
- ConnectButton.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- ConnectButtonActionPerformed(evt);
- }
- });
-
- jLabel1.setFont(new java.awt.Font("Sitka Text", 1, 14)); // NOI18N
- jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
- jLabel1.setText("Nodes in your AdHoc Network");
-
- jLabel2.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
- jLabel2.setText("Welcome to Organic AdHoc Networks!");
-
- jLabel3.setFont(new java.awt.Font("Sitka Text", 1, 14)); // NOI18N
- jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
- jLabel3.setText("Active Connections");
- jLabel3.setToolTipText("");
-
- IpListBox.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- IpListBoxActionPerformed(evt);
- }
- });
-
- jLabel4.setText("Your File Index Table");
-
- listenConnection.setText("Get Index");
- listenConnection.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- listenConnectionActionPerformed(evt);
- }
- });
-
- jLabel5.setText("Neighbour Index Table");
-
- javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
- getContentPane().setLayout(layout);
- layout.setHorizontalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGap(10, 10, 10)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGap(174, 174, 174)
- .addComponent(ConnectButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(0, 0, Short.MAX_VALUE))
- .addGroup(layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addGap(0, 18, Short.MAX_VALUE)
- .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 279, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGroup(layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
- .addComponent(IpListBox, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 269, Short.MAX_VALUE)
- .addComponent(jLabel4, javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(ScanNetworkButton, javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(LocalIndexListBox, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addGap(0, 0, Short.MAX_VALUE)))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(layout.createSequentialGroup()
- .addGap(24, 24, 24)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jLabel5)
- .addComponent(ConnectionListBox, javax.swing.GroupLayout.PREFERRED_SIZE, 276, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(NetworkIndexListBox, javax.swing.GroupLayout.PREFERRED_SIZE, 267, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(listenConnection))
- .addGap(0, 60, Short.MAX_VALUE))))
- .addGroup(layout.createSequentialGroup()
- .addGap(189, 189, 189)
- .addComponent(jLabel2)
- .addGap(0, 0, Short.MAX_VALUE)))
- .addContainerGap())
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addGap(0, 0, Short.MAX_VALUE)
- .addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(81, 81, 81))
- );
- layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addContainerGap()
- .addComponent(jLabel2)
- .addGap(31, 31, 31)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(jLabel1)
- .addComponent(jLabel3))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(ConnectionListBox, javax.swing.GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE)
- .addComponent(IpListBox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(ScanNetworkButton)
- .addComponent(ConnectButton)
- .addComponent(listenConnection))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 32, Short.MAX_VALUE)
- .addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(jLabel4)
- .addComponent(jLabel5))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(LocalIndexListBox, javax.swing.GroupLayout.DEFAULT_SIZE, 195, Short.MAX_VALUE)
- .addComponent(NetworkIndexListBox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addGap(44, 44, 44))
- );
-
- pack();
- }// //GEN-END:initComponents
-
- private void ScanNetworkButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ScanNetworkButtonActionPerformed
- Executors.newSingleThreadExecutor().execute(new Runnable() {
- @Override
- public void run() {
- try {
- IpListBox.removeAll();
- //FIXME: Up Iplerin gelmesi uzun suruyor. Ve sonradan gelenler oluyor ??!
- mainIntroducer = gabriel.getMainIntroducer();
- mainIntroducer.setNodes(new ArrayList<>());
- mainIntroducer.checkHostsBruteForce(gabriel.getSubnet());
- Thread.sleep(1);
- mainIntroducer.getHostCheckerAll().getHostIps().forEach((node) -> {
- IpListBox.add(node);
- });
- } catch (InterruptedException ex) {
- Logger.getLogger(MainScreen.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- });
-
- }//GEN-LAST:event_ScanNetworkButtonActionPerformed
-
- private void ConnectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ConnectButtonActionPerformed
- String selectedIp = IpListBox.getSelectedItem();
- if (selectedIp == null) {
- JOptionPane.showMessageDialog(null, "Please choose 1 IP to connect to.");
- } else {
- try {
- String ip = selectedIp.split(" -")[0].replaceAll("/", "");
- Node selectedNode = gabriel.getNode(ip);
- Connection newConnection = new Connection((Inet4Address) selectedNode.getConnectionIp());
-
- connectionManager.addConnection(newConnection);
- if (connectionManager.startConnection(newConnection)) {
- ConnectionListBox.add(newConnection.getConnectionIp().toString());
- } else {
- System.out.println("Sorry, could not connect to: " + newConnection.getConnectionIp().toString());
- }
- } catch (HeadlessException ex) {
- Logger.getLogger(MainScreen.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }//GEN-LAST:event_ConnectButtonActionPerformed
-
- private void IpListBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_IpListBoxActionPerformed
- // TODO add your handling code here:
- }//GEN-LAST:event_IpListBoxActionPerformed
-
- private void listenConnectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_listenConnectionActionPerformed
-
- try {
- //Listening for a connection to be made
- ServerSocket serverSocket = new ServerSocket(connectionManager.getPORT_NO());
- System.out.println("TCPServer Waiting for client on port 5000\n");
- Socket connectionSocket = serverSocket.accept();
-
- Connection newIncomingConnection = new Connection((Inet4Address) connectionSocket.getInetAddress());
- connectionManager.addConnection(newIncomingConnection);
- Index nodeIndex =connectionManager.getIndex(connectionSocket);
-
- connectionManager.addToNetworkIndex(nodeIndex);
-
-// connectionManager.networkIndex.getFileHeaders().addAll(incomingData.getFileHeaders());
- System.out.println(nodeIndex.getFileHeaders().get(0).getName());
-
-
- ConnectionListBox.add(newIncomingConnection.getConnectionIp().toString());
-
- } catch (IOException ex) {
- System.out.println("Input Output Exception on Listen Connection Action Performed");
- Logger.getLogger(MainScreen.class.getName()).log(Level.SEVERE, null, ex);
- }
- }//GEN-LAST:event_listenConnectionActionPerformed
-
- /**
- * @param args the command line arguments
- */
- public static void main(String args[]) throws InterruptedException {
- /* Set the Nimbus look and feel */
- //
- /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
- * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
- */
- try {
- for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
- if ("Nimbus".equals(info.getName())) {
- javax.swing.UIManager.setLookAndFeel(info.getClassName());
- break;
- }
- }
- } catch (ClassNotFoundException ex) {
- java.util.logging.Logger.getLogger(MainScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
- } catch (InstantiationException ex) {
- java.util.logging.Logger.getLogger(MainScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
- } catch (IllegalAccessException ex) {
- java.util.logging.Logger.getLogger(MainScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
- } catch (javax.swing.UnsupportedLookAndFeelException ex) {
- java.util.logging.Logger.getLogger(MainScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
- }
- //
-
- /* Create and display the form */
- java.awt.EventQueue.invokeLater(new Runnable() {
- public void run() {
- new MainScreen().setVisible(true);
- }
- });
-
- }
-
-
- // Variables declaration - do not modify//GEN-BEGIN:variables
- private javax.swing.JButton ConnectButton;
- private java.awt.List ConnectionListBox;
- private java.awt.List IpListBox;
- private java.awt.List LocalIndexListBox;
- private java.awt.List NetworkIndexListBox;
- private javax.swing.JButton ScanNetworkButton;
- private javax.swing.Box.Filler filler1;
- private javax.swing.JLabel jLabel1;
- private javax.swing.JLabel jLabel2;
- private javax.swing.JLabel jLabel3;
- private javax.swing.JLabel jLabel4;
- private javax.swing.JLabel jLabel5;
- private javax.swing.JButton listenConnection;
- // End of variables declaration//GEN-END:variables
-}
diff --git a/src/gabriel/models/Connection.java b/src/gabriel/models/Connection.java
deleted file mode 100644
index 2cebcc7..0000000
--- a/src/gabriel/models/Connection.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel.models;
-
-import java.net.Inet4Address;
-import java.net.Socket;
-
-/**
- * @author TheDoctor
- */
-public class Connection {
-
- Inet4Address connectionIp;
- Socket connectionSocket;
-
- public Connection(Inet4Address connectionIp) {
- this.connectionIp = connectionIp;
- }
-
- public Inet4Address getConnectionIp() {
- return connectionIp;
- }
-
- public void setConnectionIp(Inet4Address connectionIp) {
- this.connectionIp = connectionIp;
- }
-
- public Socket getConnectionSocket() {
- return connectionSocket;
- }
-
- public void setConnectionSocket(Socket connectionSocket) {
- this.connectionSocket = connectionSocket;
- }
-
-
- @Override
- public String toString() {
- return "Connection{" + "connectionIp=" + connectionIp + '}';
- }
-
-}
diff --git a/src/gabriel/models/Host.java b/src/gabriel/models/Host.java
deleted file mode 100644
index f0c8f38..0000000
--- a/src/gabriel/models/Host.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel.models;
-
-/**
- *
- * @author TheDoctor
- */
-public class Host {
-
- String hostIp;
-
- public Host(String hostIp) {
- this.hostIp = hostIp;
- }
-
- public String getHostIp() {
- return hostIp;
- }
-
- public void setHostIp(String hostIp) {
- this.hostIp = hostIp;
- }
-
-}
diff --git a/src/gabriel/models/Index.java b/src/gabriel/models/Index.java
deleted file mode 100644
index 7fb8104..0000000
--- a/src/gabriel/models/Index.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel.models;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-
-/**
- *
- * @author TheDoctor
- */
-public class Index implements Serializable {
-
- ArrayList fileHeaders;
-
- public Index(ArrayList fileHeaders) {
- this.fileHeaders = fileHeaders;
- }
-
- public Index() {
- this.fileHeaders = new ArrayList<>();
-
- //falsely filled
- SharedFileHeader fakeSharedFile = new SharedFileHeader();
- fakeSharedFile.setName("ilk file header");
- this.fileHeaders.add(fakeSharedFile);
- //false
-
- }
-
- public ArrayList getFileHeaders() {
- return fileHeaders;
- }
-
- public void setFileHeaders(ArrayList fileHeaders) {
- this.fileHeaders = fileHeaders;
- }
-
-}
diff --git a/src/gabriel/models/Node.java b/src/gabriel/models/Node.java
deleted file mode 100644
index 69642fd..0000000
--- a/src/gabriel/models/Node.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel.models;
-
-import java.net.Inet4Address;
-
-/**
- *
- * @author EmreDan
- * This class is to manage existing connections between nodes
- */
-public class Node {
-
- Inet4Address connectionIp;
-
- public Node(Inet4Address connectionIp) {
- this.connectionIp = connectionIp;
- }
-
- public Inet4Address getConnectionIp() {
- return connectionIp;
- }
-
- public void setConnectionIp(Inet4Address connectionIp) {
- this.connectionIp = connectionIp;
- }
-}
diff --git a/src/gabriel/models/SharedFileHeader.java b/src/gabriel/models/SharedFileHeader.java
deleted file mode 100644
index 8764e36..0000000
--- a/src/gabriel/models/SharedFileHeader.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package gabriel.models;
-
-import gabriel.Controller.Hasher;
-import java.io.File;
-import java.io.IOException;
-import java.io.Serializable;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Objects;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author TheDoctor
- */
-public class SharedFileHeader implements Serializable{
-
- private String name = "";
- private String path = null;
- private String mimeType = null;
- private String hash = null;
- private Long size = null;
- private Long lastModified = null;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
-
-
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- public String getMimeType() {
- return mimeType;
- }
-
- public void setMimeType(String mimeType) {
- this.mimeType = mimeType;
- }
-
- public String getHash() {
- return hash;
- }
-
- public void setHash(String hash) {
- this.hash = hash;
- }
-
- public Long getSize() {
- return size;
- }
-
- public void setSize(Long size) {
- this.size = size;
- }
-
- public Long getLastModified() {
- return lastModified;
- }
-
- public void setLastModified(Long lastModified) {
- this.lastModified = lastModified;
- }
-
- public String getHashValue(){
- try {
- hash = Hasher.calculateFileHash(this.getPath());
- return hash;
- } catch (IOException ex) {
- Logger.getLogger(SharedFileHeader.class.getName()).log(Level.SEVERE, null, ex);
- } catch (NoSuchAlgorithmException ex) {
- Logger.getLogger(SharedFileHeader.class.getName()).log(Level.SEVERE, null, ex);
- }
- return hash;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final SharedFileHeader other = (SharedFileHeader) obj;
- if (!Objects.equals(this.path, other.path)) {
- return false;
- }
- if (!Objects.equals(this.mimeType, other.mimeType)) {
- return false;
- }
- if (!Objects.equals(this.hash, other.hash)) {
- return false;
- }
- if (!Objects.equals(this.size, other.size)) {
- return false;
- }
- if (!Objects.equals(this.lastModified, other.lastModified)) {
- return false;
- }
- return true;
- }
-
-
-
-}
diff --git a/src/gabriel/organic-network.jpg b/src/gabriel/organic-network.jpg
deleted file mode 100644
index 5298487..0000000
Binary files a/src/gabriel/organic-network.jpg and /dev/null differ
diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..2521462
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: org.organet.commons.gabriel.App
+
diff --git a/src/main/java/org/organet/commons/gabriel/App.java b/src/main/java/org/organet/commons/gabriel/App.java
new file mode 100644
index 0000000..9898a94
--- /dev/null
+++ b/src/main/java/org/organet/commons/gabriel/App.java
@@ -0,0 +1,175 @@
+package org.organet.commons.gabriel;
+
+import org.organet.commons.gabriel.Controller.Introducer;
+import org.organet.commons.gabriel.Model.Node;
+import org.organet.commons.inofy.Index;
+import org.organet.commons.inofy.Model.SharedFileHeader;
+import org.organet.commons.inofy.Watcher;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.*;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Stream;
+
+public class App {
+ final static String SUBNET = "192.168.1"; // 10.253.74
+ static String sharedDirPath;
+ public static Index localIndex = null;
+ public static String localIp;
+ private static ArrayList nodeList;
+ private static Introducer introducer;
+ private static ConnectionManager connectionManager; // TODO
+ private static int possibleHostsCount;
+
+ public static MainForm mainForm;
+
+ public static SharedFileHeader chosenSharedFileHeader;
+
+ public static void main(String args[]) {
+ if (args.length < 2) {
+ System.out.println("Shared directory path and/or IP address is missing, first argument must be a valid path.");
+
+ return;
+ }
+ calculatePossibleHostsCount();
+ nodeList = new ArrayList<>();
+ introducer = new Introducer(nodeList);
+ connectionManager = new ConnectionManager();
+
+ mainForm = new MainForm();
+ mainForm.setVisible(true);
+
+ localIp = args[0];
+ mainForm.IPLabel.setText("Your Ip Address is: "+ localIp + " and server is listening on port: "+ connectionManager.getPORT_NO());
+
+ sharedDirPath = args[1];
+ if (!sharedDirPath.endsWith(File.separator)) {
+ sharedDirPath += File.separator;
+ }
+ File sharedDir = new File(sharedDirPath);
+ localIndex = new Index(true);
+
+ // Watch the shared directory directory recursively for changes
+
+ App.startWatcherExecutor( sharedDir);
+
+ App.startServerExecutor();
+
+ // Walk shared directory for initial indexing
+ try(Stream paths = Files.walk(Paths.get(sharedDirPath))) {
+ paths.forEach(filePath -> {
+ if (Files.isRegularFile(filePath)) {
+ // FIXME Implement this behaviour in another way (i.e. anywhere else)
+ App.mainForm.LocalIndexListModel.addElement(filePath.toFile().getName());
+ SharedFileHeader sh = SharedFileHeader.fromFile(filePath.toFile());
+ localIndex.add(sh);
+ }
+ });
+ } catch (IOException e) {
+ e.printStackTrace();
+
+ return;
+ }
+
+ }
+
+ private static void startWatcherExecutor(File sharedDir){
+ ExecutorService executorService = Executors.newFixedThreadPool(1);
+ Watcher w = null;
+ try {
+ w= new Watcher(sharedDir.getPath());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ executorService.submit(w::run);
+ executorService.shutdown();
+ }
+
+ private static void startServerExecutor() {
+ ExecutorService executorService = Executors.newFixedThreadPool(1);
+ executorService.submit(ConnectionManager::startServer);
+ executorService.shutdown();
+ }
+
+ private static void calculatePossibleHostsCount() {
+ String[] splittedSUBNET = SUBNET.split("\\.");
+
+ possibleHostsCount = (int) Math.pow(255, (4 - splittedSUBNET.length));
+ }
+
+ static Introducer getIntroducer() {
+ return introducer;
+ }
+
+ static Node getNode(String ipAddress) {
+ for (Node node : nodeList) {
+ if (node.getConnectionIp().toString().equals(ipAddress)) {
+ return node;
+ }
+ }
+
+ try {
+ return new Node((Inet4Address) InetAddress.getByName(ipAddress));
+ } catch (UnknownHostException ex) {
+ Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
+
+ return null;
+ }
+ }
+
+ public static int getPossibleHostsCount() {
+ return possibleHostsCount;
+ }
+
+ private static String calculateDeviceID() {
+ // Start with MAC address of the ad-hoc network interface
+ String idBase = Helper.getMACAddress();
+
+ // Remove dashes
+ idBase = idBase.replace("-", "");
+
+ // Arbitrarily shuffle the ID
+ int idBaseLen = idBase.length();
+ char[] characters = idBase.toCharArray();
+
+ // Generate and fill the `charactersOrder` with random numbers
+ // NOTE Hard-coded order guarantees that every time same device identifier \
+ // is going to be calculated for the same MAC address.
+ List charactersOrder = new ArrayList<>(Arrays.asList(10, 1, 5, 8, 0, 2, 6, 4, 7, 11, 3, 9));
+
+ // Finally construct the device identifier by appending it with characters
+ StringBuilder idBuilder = new StringBuilder(idBaseLen);
+ for (int i = 0; i < idBaseLen; i++) {
+ // Try to convert odd numbers to characters in ASCII table if adding 5 (53 in ASCII)
+ // will not make them greater than 'f' so this way the device identifier might look
+ // more like a random hexadecimal number rather than MAC address-based number.
+ if (i % 2 != 0 || ((int) (characters[charactersOrder.get(i)]) - 48) > 5) {
+ idBuilder.append(characters[charactersOrder.get(i)]);
+ } else {
+ idBuilder.append((char) (((int) (characters[charactersOrder.get(i)]) - 48) + 'a'));
+ }
+ }
+
+ return idBuilder.toString();
+ }
+
+ public static String getSharedDirPath() {
+ return sharedDirPath;
+ }
+
+ public static void setSharedDirPath(String sharedDirPath) {
+ App.sharedDirPath = sharedDirPath;
+ }
+}
diff --git a/src/main/java/org/organet/commons/gabriel/ConnectionManager.java b/src/main/java/org/organet/commons/gabriel/ConnectionManager.java
new file mode 100644
index 0000000..54bf6c4
--- /dev/null
+++ b/src/main/java/org/organet/commons/gabriel/ConnectionManager.java
@@ -0,0 +1,208 @@
+package org.organet.commons.gabriel;
+
+import org.organet.commons.gabriel.Model.Connection;
+import org.organet.commons.inofy.Index;
+import org.organet.commons.inofy.Model.SharedFileHeader;
+
+import java.io.*;
+import java.net.Inet4Address;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class ConnectionManager {
+ private static ArrayList connections = new ArrayList<>();
+ private final static Integer PORT_NO = 5001;
+ private static String localIp;
+
+ static Index networkIndex = new Index(false);
+
+ public static void startServer() {
+ try {
+ //Listening for a connection to be made
+ System.out.println("server started");
+ ServerSocket serverSocket = new ServerSocket(PORT_NO);
+ System.out.println("TCPServer Waiting for client on port " + PORT_NO);
+ while (true) {
+ Socket neighbourConnectionSocket = serverSocket.accept();
+ Connection newIncomingConnection = new Connection(neighbourConnectionSocket);
+
+ sendIndex(newIncomingConnection);
+ getRemoteIndex(newIncomingConnection);
+
+ connections.add(newIncomingConnection);
+
+ App.mainForm.getConnectionListModel().addElement(newIncomingConnection.getConnectionIp().toString());
+
+ new Thread(newIncomingConnection.getListenCommands()).start();
+
+ System.out.println("started listening");
+
+ }
+ } catch (IOException ex) {
+ System.out.println("Input Output Exception on Listen Connection Action Performed");
+ Logger.getLogger(MainForm.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ public static void sendIndex(Connection connection) {
+ Index myIndex = App.localIndex;
+ for (SharedFileHeader sh :
+ ConnectionManager.networkIndex.getSharedFileHeaders()) {
+ if(!connection.getConnectionIp().toString().contains(sh.getIp())) {
+ sh.setIp(App.localIp);
+ myIndex.add(sh);
+ }
+ }
+
+ ObjectOutputStream objectOS = null;
+ try {
+ objectOS = new ObjectOutputStream(new BufferedOutputStream(connection.getConnectionSocket().getOutputStream()));
+ objectOS.writeObject(myIndex);
+ objectOS.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void getRemoteIndex(Connection conn) {
+ try {
+ ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(conn.getConnectionSocket().getInputStream()));
+ Index remoteIndex = new Index(false);
+ boolean flag = true;
+ while (flag) {
+ try {
+ remoteIndex = (Index) in.readObject();
+ flag = false;
+ } catch (EOFException ex) {
+ flag = true;
+ }
+ }
+ System.out.println("Index read successfully: " + remoteIndex.toString());
+ networkIndex.addAllSharedFiles(remoteIndex);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ public static Connection createConnection(Inet4Address connectionIp) {
+ try {
+
+ final Connection newConnection = new Connection(new Socket(connectionIp.getHostAddress(), PORT_NO));
+
+ getRemoteIndex(newConnection);
+ sendIndex(newConnection);
+
+ connections.add(newConnection);
+ App.mainForm.getConnectionListModel().addElement(newConnection.getConnectionIp().toString());
+
+ new Thread(newConnection.getListenCommands()).start();
+
+ System.out.println("started listening");
+
+ return newConnection;
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.out.println("Couldn't create connection");
+ return null;
+ }
+ }
+
+ public static void downloadFile() {
+ String selectedString = App.mainForm.getNetworkIndexListBox().getSelectedValue();
+ String []data = selectedString.split(" - ");
+ String selectedFileName = data[1];
+
+ System.out.println("chosen file to download: "+ selectedFileName);
+ if (selectedFileName == null) {
+ System.out.println("Error file not specified");
+ return;
+ }
+ getConnection(data[2]).requestFile(selectedFileName); //first find IP to decide who to ask.
+ }
+
+ public static void sendNewSharedFiletoNetwork(SharedFileHeader sh) {
+
+ // Create a shared file and add to the local index
+ for (Connection c : getConnections()) {
+ System.out.println("Comparing *" +c.getConnectionIp().toString() + "* ?= *" + sh.getIp()+"*");
+ if(c.getConnectionIp().toString().equals("/"+sh.getIp())){
+ continue;
+ }
+
+ String command = "NEW";
+ OutputStreamWriter os = null;
+ try {
+ //Sending command "NEW" to inform peers that a new file is added.
+ os = new OutputStreamWriter(c.getConnectionSocket().getOutputStream());
+ System.out.println("Sending " + c.getConnectionIp() + " the command: " + command);
+ os.write(command);
+ os.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ try {
+ Thread.sleep(300);
+ System.out.println("Sending to " + c.getConnectionIp() + " the Shared File Object: " + sh.getFileName());
+
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(c.getConnectionSocket().getOutputStream() ));
+
+ objectOutputStream.writeObject(sh);
+ objectOutputStream.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static Connection getConnection(String sourceIp) {
+ for(Connection c : getConnections()){
+ if(c.getConnectionIp().toString().equals(sourceIp));
+ return c;
+ }
+ return null;
+ }
+
+ public static Integer getPortNo() {
+ return PORT_NO;
+ }
+
+ public static String getLocalIp() {
+ return localIp;
+ }
+
+ public static void setLocalIp(String localIp) {
+ ConnectionManager.localIp = localIp;
+ }
+
+ public static ArrayList getConnections() {
+ return connections;
+ }
+
+ public static void setConnections(ArrayList connections) {
+ ConnectionManager.connections = connections;
+ }
+
+ public Integer getPORT_NO() {
+ return PORT_NO;
+ }
+
+ public static Index getNetworkIndex() {
+ return networkIndex;
+ }
+
+ public void setNetworkIndex(Index networkIndex) {
+ this.networkIndex = networkIndex;
+ }
+
+}
diff --git a/src/main/java/org/organet/commons/gabriel/Controller/HostChecker.java b/src/main/java/org/organet/commons/gabriel/Controller/HostChecker.java
new file mode 100644
index 0000000..aee4fc1
--- /dev/null
+++ b/src/main/java/org/organet/commons/gabriel/Controller/HostChecker.java
@@ -0,0 +1,30 @@
+package org.organet.commons.gabriel.Controller;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class HostChecker extends Thread {
+ String hostName = null;
+ Boolean isValid = false;
+ final int timeout = 1200;
+
+ public HostChecker(String hostName) {
+ this.hostName = hostName;
+ }
+ @Override
+ public void run() {
+ try {
+ if (InetAddress.getByName(hostName).isReachable(timeout)) {
+ System.out.println(hostName + " is reachable ");
+ this.isValid = true;
+ } else {
+ this.isValid = false;
+ }
+ } catch (IOException ex) {
+ Logger.getLogger(Introducer.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+}
diff --git a/src/main/java/org/organet/commons/gabriel/Controller/HostCheckerAll.java b/src/main/java/org/organet/commons/gabriel/Controller/HostCheckerAll.java
new file mode 100644
index 0000000..5f7835e
--- /dev/null
+++ b/src/main/java/org/organet/commons/gabriel/Controller/HostCheckerAll.java
@@ -0,0 +1,66 @@
+package org.organet.commons.gabriel.Controller;
+
+import java.util.ArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class HostCheckerAll {
+ ArrayList hostIps = new ArrayList<>();
+ String subnet;
+ Integer possibleHostCount;
+
+ public HostCheckerAll(String subnet, Integer possibleHostCount) {
+ this.subnet = subnet;
+ this.possibleHostCount = possibleHostCount;
+ }
+
+ public void run() {
+ HostChecker[] hostCheckers = new HostChecker[possibleHostCount];
+
+ String[] addresses = new String[possibleHostCount];
+ for (int i = 0; i < possibleHostCount; i++) {
+ addresses[i] = subnet + "." + i;
+ }
+ hostIps.clear();
+ ExecutorService executor = Executors.newFixedThreadPool(possibleHostCount);
+ for (int i = 0; i < possibleHostCount; i++) {
+ hostCheckers[i] = new HostChecker(addresses[i]);
+ executor.execute(hostCheckers[i]);
+ }
+ executor.shutdown();
+ while (!executor.isTerminated()) {
+ }
+ for (int i = 0; i < possibleHostCount; i++) {
+ if (hostCheckers[i].isValid && !hostIps.contains(hostCheckers[i].hostName)) {
+ hostIps.add(hostCheckers[i].hostName);
+ System.out.println("Host Ip: " + hostCheckers[i].hostName + " added");
+
+ }
+ }
+ }
+
+ public ArrayList getHostIps() {
+ //Collections.sort(hostIps);
+ return hostIps;
+ }
+
+ public void setHostIps(ArrayList hostIps) {
+ this.hostIps = hostIps;
+ }
+
+ public String getSubnet() {
+ return subnet;
+ }
+
+ public void setSubnet(String subnet) {
+ this.subnet = subnet;
+ }
+
+ public Integer getHostCount() {
+ return possibleHostCount;
+ }
+
+ public void setHostCount(Integer hostCount) {
+ this.possibleHostCount = hostCount;
+ }
+}
diff --git a/src/main/java/org/organet/commons/gabriel/Controller/Introducer.java b/src/main/java/org/organet/commons/gabriel/Controller/Introducer.java
new file mode 100644
index 0000000..0992bec
--- /dev/null
+++ b/src/main/java/org/organet/commons/gabriel/Controller/Introducer.java
@@ -0,0 +1,63 @@
+package org.organet.commons.gabriel.Controller;
+
+import org.organet.commons.gabriel.App;
+import org.organet.commons.gabriel.Model.Node;
+
+import java.net.Inet4Address;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class is to Introduce new node to the current node. It
+ * creates a Connection object and listens for new socket.
+ */
+public class Introducer implements Runnable {
+ private ArrayList nodes = new ArrayList<>();
+ private HostCheckerAll hostCheckerAll;
+
+ public Introducer(ArrayList connections) {
+ this.nodes = connections;
+ }
+
+ @Override
+ public void run() {
+ throw new UnsupportedOperationException("Not supported yet."); // FIXME
+ }
+
+ public void checkHostsBruteForce(String subnet) {
+ try {
+ hostCheckerAll = new HostCheckerAll(subnet, App.getPossibleHostsCount());
+ hostCheckerAll.run();
+
+ hostCheckerAll.getHostIps().forEach((hostIp) -> {
+ try {
+ Inet4Address ipAddress = (Inet4Address) Inet4Address.getByName(hostIp);
+ this.nodes.add(new Node(ipAddress));
+ } catch (UnknownHostException ex) {
+ System.out.println("Error on Introducer.getConnections()!");
+ }
+ });
+ System.out.println(hostCheckerAll.getHostIps());
+ } catch (Exception ex) {
+ Logger.getLogger(Introducer.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ public ArrayList getNodes() {
+ return nodes;
+ }
+
+ public void setNodes(ArrayList nodes) {
+ this.nodes = nodes;
+ }
+
+ public HostCheckerAll getHostCheckerAll() {
+ return hostCheckerAll;
+ }
+
+ public void setHostCheckerAll(HostCheckerAll hostCheckerAll) {
+ this.hostCheckerAll = hostCheckerAll;
+ }
+}
diff --git a/src/main/java/org/organet/commons/gabriel/Controller/ListenCommands.java b/src/main/java/org/organet/commons/gabriel/Controller/ListenCommands.java
new file mode 100644
index 0000000..3c04e43
--- /dev/null
+++ b/src/main/java/org/organet/commons/gabriel/Controller/ListenCommands.java
@@ -0,0 +1,192 @@
+package org.organet.commons.gabriel.Controller;
+
+import org.organet.commons.gabriel.App;
+import org.organet.commons.gabriel.ConnectionManager;
+import org.organet.commons.gabriel.Helper;
+import org.organet.commons.gabriel.Model.Connection;
+import org.organet.commons.inofy.Model.SharedFileHeader;
+
+import javax.swing.*;
+import java.io.*;
+import java.net.InetAddress;
+import java.net.Socket;
+
+/**
+ * Created by TheDoctor on 10-May-17.
+ */
+public class ListenCommands extends Thread {
+
+ Socket socket;
+
+ public ListenCommands(Socket socket) {
+ this.socket = socket;
+ }
+
+ @Override
+ public synchronized void start() {
+ super.start();
+ run();
+ }
+
+ @Override
+ public void run() {
+ try {
+
+ Thread.sleep(1300);
+ BufferedReader bufferedInputStreamReader =new BufferedReader( new InputStreamReader(socket.getInputStream()));
+
+ OutputStreamWriter outputStreamWriter = new OutputStreamWriter(socket.getOutputStream());
+
+ String commandOrFileFirstLine;
+ while(true) {
+ System.out.println("waiting to Listen command");
+ char[] buff = new char[3];
+ int output = bufferedInputStreamReader.read(buff,0,3);
+ commandOrFileFirstLine = new String(buff);
+ System.out.println("command received " + commandOrFileFirstLine);
+
+ if (commandOrFileFirstLine.equals("\0\0\0")) {
+ System.out.format("Connection lost (%s)\n", socket.getInetAddress());
+ break;
+ }
+
+ if (commandOrFileFirstLine.startsWith("GET")) {
+ //Send File
+ sendFile(bufferedInputStreamReader, outputStreamWriter);
+ } else if(commandOrFileFirstLine.startsWith("SEN")){
+ //Receiving file from other node.
+ receiveNewFile(bufferedInputStreamReader);
+ }
+ else if(commandOrFileFirstLine.startsWith("NEW")){
+ recieveNewSharedFileHeader();
+ }
+ }
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void sendFile(BufferedReader bufferedInputStreamReader, OutputStreamWriter outputStreamWriter) throws IOException, InterruptedException {
+ String commandOrFileFirstLine;
+ commandOrFileFirstLine = "GET" + bufferedInputStreamReader.readLine();
+ System.out.print("command listened: " + commandOrFileFirstLine);
+ String fileName = commandOrFileFirstLine.split(" - ")[1];
+
+ outputStreamWriter.write("SEN");
+ outputStreamWriter.flush();
+ Thread.sleep(300);
+
+ //check requested file locally.
+ SharedFileHeader sharedFileHeader = App.localIndex.findIndex(fileName);
+ if(sharedFileHeader!=null){ //file found locally.
+ // retrieve from file.
+ BufferedInputStream bufferedFileInputStream = new BufferedInputStream(new FileInputStream(sharedFileHeader.getAbsoluteFile()),1024);
+
+ int c;
+ int x =0;
+ while ((c = bufferedFileInputStream.read()) != -1) {
+ outputStreamWriter.write(c);
+ x++;
+ }
+ System.out.println("bytes sent : "+x);
+ outputStreamWriter.flush();
+ bufferedFileInputStream.close();
+ }else{
+ //if file is not local, check network Index.
+ sharedFileHeader = ConnectionManager.getNetworkIndex().findIndex(fileName);
+ //if file still not found. show error and exit.
+ if(sharedFileHeader == null){
+ JOptionPane.showMessageDialog(null, "Requested file not found.");
+ return;
+ }
+ String sourceIp= sharedFileHeader.getIp();
+ Connection sourceConnection = ConnectionManager.getConnection(sourceIp); /// find file source and receive from there and send to requested node.
+ sourceConnection.requestFile(sharedFileHeader.fileName);
+ redirectFile(sharedFileHeader, sourceConnection.getConnectionSocket(), socket);
+ }
+ }
+
+ private void redirectFile(SharedFileHeader sh, Socket sourceSocket, Socket destinationSocket) {
+ try {
+ System.out.println("\nredirecting file :"+sh+" from " + sourceSocket.getInetAddress() + " to " + destinationSocket.getInetAddress());
+ //Thread.sleep(1000);
+ char[] buff = new char[3];
+ BufferedReader bufferedInputStreamReader = new BufferedReader( new InputStreamReader(sourceSocket.getInputStream()));
+ int output = bufferedInputStreamReader.read(buff,0,3);
+ System.out.println(new String (buff) + " command to send file is received. Sending file now.");
+ OutputStreamWriter outputStreamWriter = new OutputStreamWriter(destinationSocket.getOutputStream());
+
+ int c;
+ int x=0;
+ do {
+ c = bufferedInputStreamReader.read();
+ outputStreamWriter.write(c);
+ x++;
+ }while(x < sh.getSize());
+ outputStreamWriter.flush();
+ System.out.println(x + " bytes redirected");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void receiveNewFile(BufferedReader bufferedInputStreamReader) throws IOException {
+ String chosenName = App.mainForm.getNetworkIndexListBox().getSelectedValue();
+ //create the file
+ String [] text=chosenName.split(" - ");
+ File file = new File(App.getSharedDirPath()+text[1]);
+ SharedFileHeader sharedFileHeader = ConnectionManager.getNetworkIndex().findIndex(text[1]);
+ //start receiving.
+ BufferedOutputStream bufferedFileOutputStream = new BufferedOutputStream(new FileOutputStream(file),1024) ;
+ int c;
+ int x=0;
+ do {
+ c = bufferedInputStreamReader.read();
+ bufferedFileOutputStream.write(c);
+ x++;
+ }while(x < sharedFileHeader.getSize());
+
+ System.out.println("bytes read : "+x);
+ bufferedFileOutputStream.flush();
+ bufferedFileOutputStream.close();
+ }
+
+ private void recieveNewSharedFileHeader() throws IOException {
+ //new object is created on neighbour. And updating this node.
+ try {
+ ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
+ SharedFileHeader sh;
+ boolean flag = true;
+ while (flag) {
+ try {
+ sh = (SharedFileHeader) objectInputStream.readObject();
+ if(!App.localIndex.isContainsHash(sh.getHash())) { //to prevent flooding, if exists, dont Add
+
+ System.out.println("NEW SharedFileHeader added to index successfully: " + sh.toString());
+ sh.setNDNid(ConnectionManager.getNetworkIndex().getNDNcount());
+ String ipd = socket.getInetAddress().toString();
+ if (ipd.startsWith("/")) ipd = ipd.substring(1);
+
+ sh.setIp(ipd); //Set Ip to received node.
+
+ ConnectionManager.getNetworkIndex().add(sh);
+ App.mainForm.getNetworkIndexListModel().addElement(sh.getScreenName());
+
+ ConnectionManager.sendNewSharedFiletoNetwork(sh);
+
+ }else{
+ System.out.println("NEW SharedFileHeader already exists: " + sh.toString());
+ }
+ flag = false;
+ } catch (EOFException ex) {
+ flag = true;
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/org/organet/commons/gabriel/Helper.java b/src/main/java/org/organet/commons/gabriel/Helper.java
new file mode 100644
index 0000000..733c171
--- /dev/null
+++ b/src/main/java/org/organet/commons/gabriel/Helper.java
@@ -0,0 +1,205 @@
+package org.organet.commons.gabriel;
+
+import java.net.*;
+import java.util.*;
+
+public class Helper {
+ public static final int ELECTION_SCORE_THRESHOLD = 5;
+
+ private static final NetworkInterface adhocInterface;
+ private static final byte[] rawMACAddress; // The MAC address of the ad-hoc network interface card
+ private static final Inet4Address rawIPAddress; // The IP address of this very node on the ad-hoc network
+ private static final InetAddress rawBroadcastAddress;
+ private static final String macAddress;
+ private static final String ipAddress;
+ private static final String broadcastAddress;
+
+ static {
+ adhocInterface = obtainAdhocInterface();
+ rawMACAddress = obtainMACAddress();
+ rawIPAddress = obtainIPAddress();
+ rawBroadcastAddress = obtainBroadcastAddress();
+
+ macAddress = convertMACAddress(rawMACAddress);
+ ipAddress = stringifyInetAddress(rawIPAddress);
+ broadcastAddress = stringifyInetAddress(rawBroadcastAddress);
+ }
+
+ private static NetworkInterface obtainAdhocInterface() {
+ Enumeration interfaces;
+ List adhocInterfaceCandidates = new ArrayList<>();
+
+ try {
+ interfaces = NetworkInterface.getNetworkInterfaces();
+ } catch (SocketException e) {
+ System.exit(1);
+ return null;
+ }
+
+ int interfacesCount = 0;
+
+ while (interfaces.hasMoreElements()) {
+ NetworkInterface theInterface = interfaces.nextElement();
+
+ interfacesCount += 1;
+
+ // The interface MUST NOT be loopback
+ try {
+ if (theInterface.isLoopback()) {
+ continue; // Continue with the next interface since this one is loopback
+ }
+ } catch (SocketException e) {
+ continue; // Continue with the next interface since this interface is erroneous
+ }
+
+ // The interface MUST be a physical one
+ if (theInterface.isVirtual()) {
+ continue;
+ }
+
+ adhocInterfaceCandidates.add(theInterface);
+ }
+
+ if (adhocInterfaceCandidates.isEmpty()) {
+ System.exit(2);
+ return null;
+ }
+
+ return electAdhocInterface(adhocInterfaceCandidates);
+ }
+
+ private static NetworkInterface electAdhocInterface(List candidateInterfaces) {
+ SortedMap interfacesAndScores = new TreeMap<>();
+
+ for (NetworkInterface candidate : candidateInterfaces) {
+ int score = 0;
+
+ char[] candidateNameCharacters = candidate.getName().toCharArray();
+ if (candidateNameCharacters[0] == 'w') {
+ score += 1;
+ }
+ if (candidateNameCharacters[1] == 'l') {
+ score += 1;
+ }
+ if (candidateNameCharacters[2] == 'a' || candidateNameCharacters[2] == 'p') {
+ score += 1;
+ }
+ if (candidateNameCharacters[2] == 'n') {
+ score += 1;
+ }
+
+ if (candidateNameCharacters[candidateNameCharacters.length - 1] >= '0' &&
+ candidateNameCharacters[candidateNameCharacters.length - 1] <= '9') {
+ score += 1;
+ }
+
+ if (candidate.getInterfaceAddresses().size() > 0) {
+ score += 1;
+ }
+
+ // Check if the interface has IPv4 address bound
+ Enumeration addresses = candidate.getInetAddresses();
+
+ while (addresses.hasMoreElements()) {
+ InetAddress theAddress = addresses.nextElement();
+
+ if (theAddress instanceof Inet4Address) {
+ score += 1;
+
+ // TODO Check if the address starts with "192.168"
+ String[] theAddressOctets = stringifyInetAddress(theAddress).split("\\.");
+
+ if (theAddressOctets[0].equals("192")) {
+ score += 1;
+ }
+ if (theAddressOctets[0].equals("168")) {
+ score += 1;
+ }
+ }
+ }
+
+ interfacesAndScores.put(score, candidate);
+ }
+
+ if (((Integer) ((TreeMap) interfacesAndScores).lastEntry().getKey()) <= ELECTION_SCORE_THRESHOLD) {
+
+ System.exit(5);
+ }
+
+ NetworkInterface electedInterface = (NetworkInterface) ((TreeMap) interfacesAndScores).lastEntry().getValue();
+
+ // Last entry has the highest score
+ return (electedInterface);
+ }
+
+ private static byte[] obtainMACAddress() {
+ try {
+ return adhocInterface.getHardwareAddress();
+ } catch (SocketException e) {
+ System.exit(3);
+ return null;
+ }
+ }
+
+ private static Inet4Address obtainIPAddress() {
+ Enumeration addresses = adhocInterface.getInetAddresses();
+
+ while (addresses.hasMoreElements()) {
+ InetAddress theAddress = addresses.nextElement();
+
+ if (theAddress instanceof Inet4Address) {
+ // TODO Do more checks on the addresses if necessary
+
+ return (Inet4Address) theAddress;
+ }
+ }
+
+ return null;
+ }
+
+ private static InetAddress obtainBroadcastAddress() {
+ List addresses = adhocInterface.getInterfaceAddresses();
+
+ for (InterfaceAddress theAddress : addresses) {
+ if (theAddress.getAddress().equals(rawIPAddress)) {
+ return theAddress.getBroadcast();
+ }
+ }
+
+ return null;
+ }
+
+ private static String convertMACAddress(byte[] macAddress) {
+ StringBuilder sb = new StringBuilder();
+
+ for (int i = 0, len = macAddress.length; i < len; i++) {
+ sb.append(String.format("%02X%s", macAddress[i], (i < len - 1) ? "-" : ""));
+ }
+
+ return sb.toString();
+ }
+
+ private static String stringifyInetAddress(InetAddress ipAddress) {
+ if (ipAddress == null) {
+ return null;
+ }
+
+ if (ipAddress instanceof Inet6Address) {
+ return ipAddress.getHostAddress();
+ } else {
+ return ipAddress.toString().replaceAll("^/+", "");
+ }
+ }
+
+ public static String getMACAddress() {
+ return macAddress;
+ }
+
+ public static String getIPAddress() {
+ return ipAddress;
+ }
+
+ public static String getBroadcastAddress() {
+ return broadcastAddress;
+ }
+}
diff --git a/src/main/java/org/organet/commons/gabriel/MainForm.form b/src/main/java/org/organet/commons/gabriel/MainForm.form
new file mode 100644
index 0000000..92b77a6
--- /dev/null
+++ b/src/main/java/org/organet/commons/gabriel/MainForm.form
@@ -0,0 +1,374 @@
+
+
diff --git a/src/main/java/org/organet/commons/gabriel/MainForm.java b/src/main/java/org/organet/commons/gabriel/MainForm.java
new file mode 100644
index 0000000..a234d9f
--- /dev/null
+++ b/src/main/java/org/organet/commons/gabriel/MainForm.java
@@ -0,0 +1,248 @@
+package org.organet.commons.gabriel;
+
+import org.organet.commons.gabriel.Controller.Introducer;
+import org.organet.commons.gabriel.Model.Connection;
+import org.organet.commons.gabriel.Model.Node;
+import org.organet.commons.inofy.Index;
+import org.organet.commons.inofy.Model.SharedFileHeader;
+import sun.security.provider.SHA;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionListener;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+@SuppressWarnings("unused")
+public class MainForm extends JFrame {
+ private JList IpListBox;
+ private JButton ScanNetworkButton;
+ private JButton ConnectButton;
+ private JList ConnectionListBox;
+ private JButton listenConnection;
+ private JList LocalIndexListBox;
+
+ public JList getNetworkIndexListBox() {
+ return NetworkIndexListBox;
+ }
+
+ public void setNetworkIndexListBox(JList networkIndexListBox) {
+ NetworkIndexListBox = networkIndexListBox;
+ }
+
+ private JList NetworkIndexListBox;
+ private JPanel panelMain;
+ private JButton downloadButton;
+ private JList keywords;
+ private JButton delete;
+ private JButton addKeyword;
+ private JTextField keywordsTextField;
+ private JButton deleteKeyword;
+ private JTextArea fileHeaderInfo;
+ private JTextField searchText;
+ private JButton clearFilterButton;
+ private JButton filterButton;
+ public JLabel IPLabel;
+
+ private DefaultListModel IpListModel = new DefaultListModel<>();
+ private DefaultListModel ConnectionListModel = new DefaultListModel<>();
+ public DefaultListModel LocalIndexListModel = new DefaultListModel<>();
+ private DefaultListModel NetworkIndexListModel = new DefaultListModel<>();
+ public DefaultListModel KeywordsModel = new DefaultListModel<>();
+
+ public DefaultListModel getConnectionListModel() {
+ return ConnectionListModel;
+ }
+
+ public void setConnectionListModel(DefaultListModel connectionListModel) {
+ ConnectionListModel = connectionListModel;
+ }
+
+ public DefaultListModel getNetworkIndexListModel() {
+ return NetworkIndexListModel;
+ }
+
+ // TODO Move these to App
+ private Introducer introducer;
+
+ MainForm() {
+ IpListModel.setSize(10);
+ IpListBox.setModel(IpListModel);
+ IpListBox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ IpListBox.setPreferredSize(new Dimension(10,700));
+ IpListBox.setLayoutOrientation(JList.HORIZONTAL_WRAP);
+ IpListBox.setVisibleRowCount(10);
+ IpListBox.revalidate();
+ IpListBox.repaint();
+
+ ConnectionListBox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ ConnectionListBox.setLayoutOrientation(JList.VERTICAL);
+ ConnectionListBox.setModel(ConnectionListModel);
+
+ LocalIndexListBox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ LocalIndexListBox.setLayoutOrientation(JList.VERTICAL);
+ LocalIndexListBox.setModel(LocalIndexListModel);
+
+ NetworkIndexListBox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ NetworkIndexListBox.setLayoutOrientation(JList.VERTICAL);
+ NetworkIndexListBox.setModel(NetworkIndexListModel);
+
+ fileHeaderInfo.setText("");
+
+ ScanNetworkButton.addActionListener(this::ScanNetworkButtonActionPerformed);
+ ConnectButton.addActionListener(this::ConnectButtonActionPerformed);
+ downloadButton.addActionListener(this::downloadButtonActionPerformed);
+
+ introducer = App.getIntroducer();
+
+ panelMain.setPreferredSize(new Dimension(900, 650));
+ panelMain.repaint();
+ revalidate();
+
+ keywords.setModel(KeywordsModel);
+ keywords.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ super.mouseClicked(e);
+ String a = (String) keywords.getSelectedValue();
+ System.out.println("keyword " + a+ " clicked");
+
+ //delete keyword
+ }
+ });
+ LocalIndexListBox.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ super.mouseClicked(e);
+ KeywordsModel.removeAllElements();
+ String name = LocalIndexListBox.getSelectedValue();
+ System.out.println("Shared File " + name + " clicked ");
+ SharedFileHeader sfh = App.localIndex.findIndex(name);
+ App.chosenSharedFileHeader = sfh;
+ sfh.getKeywords().forEach(p-> KeywordsModel.addElement(p.toString()));
+ setKeywordFieldsState(true);
+ fillFileHeader(sfh);
+ }
+ });
+ deleteKeyword.addActionListener(e -> {
+ String keyword = ( String) keywords.getSelectedValue();
+ if(keyword==null) {
+ JOptionPane.showMessageDialog(null, "Please choose 1 keyword to delete.");
+ return;
+ }
+ App.chosenSharedFileHeader.getKeywords().remove(keyword);
+ KeywordsModel.removeElement(keyword);
+ });
+ addKeyword.addActionListener(e -> {
+ if(App.chosenSharedFileHeader == null){
+ JOptionPane.showMessageDialog(null, "Please choose 1 File to add keyword.");
+ return;
+ }
+ if(keywordsTextField == null || keywordsTextField.getText().length()==0 ){
+ JOptionPane.showMessageDialog(null, "Please write keyword to add.");
+ return;
+ }
+ App.chosenSharedFileHeader.getKeywords().add(keywordsTextField.getText());
+ KeywordsModel.addElement(keywordsTextField.getText());
+ keywordsTextField.setText("");
+ fillFileHeader(App.chosenSharedFileHeader );
+ });
+
+ filterButton.addActionListener(e -> {
+ ArrayList found = (ArrayList) ConnectionManager.networkIndex.search(searchText.getText());
+ NetworkIndexListModel.removeAllElements();
+ found.forEach(p->NetworkIndexListModel.addElement(p.getScreenName()));
+ });
+ clearFilterButton.addActionListener(e -> {
+ NetworkIndexListModel.removeAllElements();
+ ConnectionManager.networkIndex.getSharedFileHeaders().forEach(P->NetworkIndexListModel.addElement(P.getScreenName()));
+ searchText.setText("");
+ });
+ NetworkIndexListBox.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ super.mouseClicked(e);
+ String name = getNetworkIndexListBox().getSelectedValue();
+ name = name.split(" - ")[1];
+ System.out.println("Shared File " + name + " clicked ");
+ SharedFileHeader sfh = ConnectionManager.getNetworkIndex().findIndex(name);
+ App.chosenSharedFileHeader = sfh;
+ setKeywordFieldsState(false);
+ fillFileHeader(App.chosenSharedFileHeader );
+ }
+ });
+
+ getAndListHosts();
+ setContentPane(panelMain);
+ setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+ pack();
+ }
+
+ private void setKeywordFieldsState(boolean state){
+ keywordsTextField.setEnabled(state);
+ addKeyword.setEnabled(state);
+ deleteKeyword.setEnabled(state);
+ keywords.setEnabled(state);
+ if(!state){
+ keywords.removeAll();
+ KeywordsModel.removeAllElements();
+ }
+ }
+
+ private void fillFileHeader(SharedFileHeader sfh) {
+ fileHeaderInfo.setText(sfh.getName() + "\nKeywords:\n" );
+ sfh.getKeywords().forEach(p->fileHeaderInfo.append("["+p+"]\n"));
+ fileHeaderInfo.append("\nIP: " + sfh.getIp());
+ }
+ private void downloadButtonActionPerformed(ActionEvent evt) {
+ ConnectionManager.downloadFile();
+ }
+
+ private void ScanNetworkButtonActionPerformed(ActionEvent evt) {
+ clearScreen();
+
+ getAndListHosts();
+ }
+
+ private void clearScreen() {
+
+ searchText.setText("");
+ keywordsTextField.setText("");
+ keywords.removeAll();
+ }
+
+ private void getAndListHosts() {
+ IpListModel.removeAllElements();
+ introducer.checkHostsBruteForce(App.SUBNET);
+ introducer.getHostCheckerAll().getHostIps().forEach((node) -> IpListModel.addElement(node));
+ }
+
+ private void ConnectButtonActionPerformed(ActionEvent evt) {
+ String selectedIp = IpListModel.getElementAt(IpListBox.getSelectedIndex());
+
+ // TODO If there is no selection then disable the button before here
+ if (selectedIp == null) {
+ JOptionPane.showMessageDialog(null, "Please choose 1 IP to connect to.");
+ } else {
+ try {
+ String ip = selectedIp.split(" -")[0].replaceAll("/", "");
+ Node selectedNode = App.getNode(ip);
+ Connection newConnection = ConnectionManager.createConnection(selectedNode.getConnectionIp());
+
+ } catch (HeadlessException ex) {
+ Logger.getLogger(MainForm.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ private void createUIComponents() {
+ // TODO: place custom component creation code here
+ }
+}
diff --git a/src/main/java/org/organet/commons/gabriel/Model/Connection.java b/src/main/java/org/organet/commons/gabriel/Model/Connection.java
new file mode 100644
index 0000000..264f389
--- /dev/null
+++ b/src/main/java/org/organet/commons/gabriel/Model/Connection.java
@@ -0,0 +1,92 @@
+package org.organet.commons.gabriel.Model;
+
+import org.organet.commons.gabriel.App;
+import org.organet.commons.gabriel.ConnectionManager;
+import org.organet.commons.gabriel.Controller.ListenCommands;
+import org.organet.commons.inofy.Index;
+import org.organet.commons.inofy.Model.SharedFileHeader;
+
+import javax.swing.*;
+import java.io.*;
+import java.net.Inet4Address;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class Connection {
+ Inet4Address connectionIp;
+
+ Socket connectionSocket;
+
+ OutputStream os;
+ InputStream is;
+ ListenCommands listenCommands;
+
+ public Connection(Socket connectionSocket) {
+ this.connectionSocket = connectionSocket;
+ this.connectionIp = (Inet4Address) connectionSocket.getInetAddress();
+ try {
+ this.os = connectionSocket.getOutputStream();
+ this.is = connectionSocket.getInputStream();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ listenCommands = new ListenCommands(connectionSocket);
+
+ }
+
+ public Inet4Address getConnectionIp() {
+ return connectionIp;
+ }
+
+ public void setConnectionIp(Inet4Address connectionIp) {
+ this.connectionIp = connectionIp;
+ }
+
+ public Socket getConnectionSocket() {
+ return connectionSocket;
+ }
+
+ public void setConnectionSocket(Socket connectionSocket) {
+ this.connectionSocket = connectionSocket;
+ }
+
+ @Override
+ public String toString() {
+ return "Connection{" + "connectionIp=" + connectionIp + '}';
+ }
+
+ public void requestFile(String fileName) {
+ try {
+ SharedFileHeader sh = ConnectionManager.getNetworkIndex().findIndex(fileName);
+ if(App.localIndex.isContainsHash(sh.getHash())){
+ JOptionPane.showMessageDialog(null, "This file already exist in Local Index");
+ return;
+ }
+
+ System.out.println(connectionSocket);
+ OutputStreamWriter os = new OutputStreamWriter(connectionSocket.getOutputStream());
+ System.out.println("Sending " + connectionSocket.getInetAddress() + " the command: GET NDNID:" + fileName);
+ os.write(("GET - " + fileName+"\n"));
+ os.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public OutputStream getOutputStream() {
+ return os;
+ }
+ public InputStream getInputStream() {
+ return is;
+ }
+
+
+ public ListenCommands getListenCommands() {
+ return listenCommands;
+ }
+
+ public void setListenCommands(ListenCommands listenCommands) {
+ this.listenCommands = listenCommands;
+ }
+
+}
diff --git a/src/main/java/org/organet/commons/gabriel/Model/Node.java b/src/main/java/org/organet/commons/gabriel/Model/Node.java
new file mode 100644
index 0000000..96f5669
--- /dev/null
+++ b/src/main/java/org/organet/commons/gabriel/Model/Node.java
@@ -0,0 +1,22 @@
+package org.organet.commons.gabriel.Model;
+
+import java.net.Inet4Address;
+
+/**
+ * This class is to manage existing connections between nodes
+ */
+public class Node {
+ Inet4Address connectionIp;
+
+ public Node(Inet4Address connectionIp) {
+ this.connectionIp = connectionIp;
+ }
+
+ public Inet4Address getConnectionIp() {
+ return connectionIp;
+ }
+
+ public void setConnectionIp(Inet4Address connectionIp) {
+ this.connectionIp = connectionIp;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/organet/commons/inofy/FileTypes.java b/src/main/java/org/organet/commons/inofy/FileTypes.java
new file mode 100644
index 0000000..f5331d5
--- /dev/null
+++ b/src/main/java/org/organet/commons/inofy/FileTypes.java
@@ -0,0 +1,50 @@
+package org.organet.commons.inofy;
+
+import java.util.*;
+
+public class FileTypes {
+ private static Map extensions = new HashMap<>();
+
+ static {
+ extensions.put("aac", "Audio");
+ extensions.put("flac", "Audio");
+ extensions.put("m4a", "Audio");
+ extensions.put("mp3", "Audio");
+ extensions.put("ogg", "Audio");
+ extensions.put("wav", "Audio");
+
+ extensions.put("doc", "Document");
+ extensions.put("docx", "Document");
+ extensions.put("odt", "Document");
+ extensions.put("pdf", "Document");
+ extensions.put("rtf", "Document");
+ extensions.put("tex", "Document");
+ extensions.put("txt", "Document");
+ extensions.put("xps", "Document");
+
+ extensions.put("bmp", "Image");
+ extensions.put("gif", "Image");
+ extensions.put("ico", "Image");
+ extensions.put("jpeg", "Image");
+ extensions.put("jpg", "Image");
+ extensions.put("png", "Image");
+ extensions.put("tga", "Image");
+ extensions.put("tiff", "Image");
+ extensions.put("webp", "Image");
+
+ extensions.put("3gp", "Video");
+ extensions.put("avi", "Video");
+ extensions.put("flv", "Video");
+ extensions.put("mkv", "Video");
+ extensions.put("mov", "Video");
+ extensions.put("mp4", "Video");
+ extensions.put("mpeg", "Video");
+ extensions.put("mpg", "Video");
+ extensions.put("webm", "Video");
+ extensions.put("wmv", "Video");
+ }
+
+ public static String getFileType(String extension) {
+ return extensions.getOrDefault(extension, "Other");
+ }
+}
diff --git a/src/main/java/org/organet/commons/inofy/Hasher.java b/src/main/java/org/organet/commons/inofy/Hasher.java
new file mode 100644
index 0000000..54a30b0
--- /dev/null
+++ b/src/main/java/org/organet/commons/inofy/Hasher.java
@@ -0,0 +1,36 @@
+package org.organet.commons.inofy;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class Hasher {
+ public static String calculateFileHash(String path) throws NoSuchAlgorithmException, IOException {
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
+ FileInputStream fis = new FileInputStream(path);
+
+ long startTime = System.nanoTime();
+
+ byte[] dataBytes = new byte[1024];
+
+ int nread = 0;
+ while ((nread = fis.read(dataBytes)) != -1) {
+ md.update(dataBytes, 0, nread);
+ }
+ byte[] mdbytes = md.digest();
+
+ //convert the byte to hex format method 1
+ StringBuffer sb = new StringBuffer();
+ for (byte mdbyte : mdbytes) {
+ sb.append(Integer.toString((mdbyte & 0xff) + 0x100, 16).substring(1));
+ }
+ String hash = sb.toString();
+
+ long endTime = System.nanoTime();
+
+ System.out.format("%fms - %s\n", (endTime - startTime) / 1e6, hash); // FIXME Remove console print
+
+ return hash;
+ }
+}
diff --git a/src/main/java/org/organet/commons/inofy/Index.java b/src/main/java/org/organet/commons/inofy/Index.java
new file mode 100644
index 0000000..af0396a
--- /dev/null
+++ b/src/main/java/org/organet/commons/inofy/Index.java
@@ -0,0 +1,207 @@
+package org.organet.commons.inofy;
+
+import org.organet.commons.gabriel.App;
+import org.organet.commons.inofy.Model.SharedFileHeader;
+
+import java.io.Serializable;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+// TODO `implements Serializable` or `.serialize()`
+public class Index implements Serializable {
+ private ArrayList sharedFileHeaders;
+ private boolean isLocal;
+ Integer ndncount = 0;
+ public Index(boolean isLocal) {
+ sharedFileHeaders = new ArrayList<>();
+ this.isLocal = isLocal;
+ }
+
+ public ArrayList getSharedFileHeaders() {
+ return sharedFileHeaders;
+ }
+
+ public int size() {
+ return sharedFileHeaders.size();
+ }
+
+ // Performance O(N)
+ public boolean contains(String ndnid) {
+ for (SharedFileHeader sharedFileHeader : sharedFileHeaders) {
+ if (sharedFileHeader.getNDNID().equals(ndnid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean containsName(String fileName) {
+ for (SharedFileHeader sharedFileHeader : sharedFileHeaders) {
+ if (sharedFileHeader.getFileName().equals(fileName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isContainsHash(String fileHash) {
+ for (SharedFileHeader sharedFileHeader : sharedFileHeaders) {
+ if (sharedFileHeader.getHash().equals(fileHash)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean add(SharedFileHeader sharedFileHeader) {
+ return sharedFileHeaders.add(sharedFileHeader);
+ }
+
+ public boolean remove(SharedFileHeader sharedFileHeader) {
+ return sharedFileHeaders.remove(sharedFileHeader);
+ // TODO Invoke the necessary method to propagate the updated index (if the index is local)
+ // TODO TR Future work'e yaz: Sadece değişiklikler propagate edilebilir
+ }
+
+ public void clear() {
+ sharedFileHeaders.clear();
+ // TODO Invoke the necessary method to propagate the updated index (if the index is local)
+ // TODO TR Future work'e yaz: Sadece değişiklikler propagate edilebilir
+ }
+
+ public SharedFileHeader get(int index) {
+ return sharedFileHeaders.get(index);
+ }
+
+ public SharedFileHeader get(String ndnid) {
+ for (SharedFileHeader sharedFileHeader : sharedFileHeaders) {
+ if (sharedFileHeader.getNDNID().equals(ndnid)) {
+ return sharedFileHeader;
+ }
+ }
+
+ return null;
+ }
+
+ public SharedFileHeader remove(String ndnid) {
+ SharedFileHeader itemToBeRemoved = null;
+
+ for (int i = 0, len = sharedFileHeaders.size(); i < len; i++) {
+ if (sharedFileHeaders.get(i).getNDNID().equals(ndnid)) {
+ itemToBeRemoved = sharedFileHeaders.get(i);
+ sharedFileHeaders.remove(i);
+
+ break;
+ }
+ }
+
+ return itemToBeRemoved;
+ // TODO Invoke the necessary method to propagate the updated index (if the index is local)
+ // TODO TR Future work'e yaz: Sadece değişiklikler propagate edilebilir
+ }
+
+ public SharedFileHeader remove(Path filename) {
+ SharedFileHeader itemToBeRemoved = null;
+
+ for (int i = 0, len = sharedFileHeaders.size(); i < len; i++) {
+ if (sharedFileHeaders.get(i).getPath().equals(filename)) {
+ itemToBeRemoved = sharedFileHeaders.get(i);
+ sharedFileHeaders.remove(i);
+
+ break;
+ }
+ }
+
+ return itemToBeRemoved;
+ // TODO Invoke the necessary method to propagate the updated index (if the index is local)
+ // TODO TR Future work'e yaz: Sadece değişiklikler propagate edilebilir
+ }
+
+ public int indexOf(String ndnid) {
+ for (int i = 0, len = sharedFileHeaders.size(); i < len; i++) {
+ if (sharedFileHeaders.get(i).getNDNID().equals(ndnid)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ // NOTE This method can be considered `.set(int, element)` of List interface
+ public boolean update(String ndnid, SharedFileHeader sharedFileHeader) {
+ int index = indexOf(ndnid);
+
+ if (index > -1) {
+ // exists - replace with the given one
+ return (sharedFileHeaders.set(index, sharedFileHeader).getNDNID().equals(ndnid));
+ } else {
+ // doesn't exist - add the given shared file
+ return add(sharedFileHeader);
+ }
+ }
+
+ public List search(String keyword) {
+ List foundSharedFileHeaders = new ArrayList<>();
+ keyword=keyword.toLowerCase();
+
+ for (SharedFileHeader sharedFileHeader : sharedFileHeaders) {
+ for (String key : sharedFileHeader.getKeywords()) {
+ if(key.toLowerCase().contains(keyword)) {
+ foundSharedFileHeaders.add(sharedFileHeader);
+ break;
+ }
+ }
+ }
+ return foundSharedFileHeaders;
+ }
+
+ @Override
+ public String toString() {
+ return "Index{" +
+ "sharedFileHeaders=" + sharedFileHeaders +
+ '}';
+ }
+
+ public void addAllSharedFiles(Index newIndex){
+ for (int i=0;i extends ArrayList {
+ @Override
+ public boolean contains(Object o) {
+ String searchKeyword = (String) o;
+
+ for (String keyword : this) {
+ if (keyword.matches(searchKeyword)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/src/main/java/org/organet/commons/inofy/Model/SharedFileHeader.java b/src/main/java/org/organet/commons/inofy/Model/SharedFileHeader.java
new file mode 100644
index 0000000..8a36e3b
--- /dev/null
+++ b/src/main/java/org/organet/commons/inofy/Model/SharedFileHeader.java
@@ -0,0 +1,171 @@
+package org.organet.commons.inofy.Model;
+
+import org.organet.commons.gabriel.App;
+import org.organet.commons.inofy.FileTypes;
+import org.organet.commons.inofy.Hasher;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.NoSuchAlgorithmException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class SharedFileHeader extends File implements Serializable {
+ private Integer ndnid = null; // Named Data Network Identifier
+ private String ndntype = null; // Named Data Network File Type
+ private transient String localPath = null; // Absolute path of the file
+ private transient long lastModified = -1;
+ private String hash = null;
+ private Long size;
+ public String fileName;
+ private String ip;
+ private ArrayList keywords = new ArrayList<>();
+
+
+ private void initialize() {
+ ndntype = FileTypes.getFileType(getExtension());
+ keywords.add(getName());
+ keywords.add(ndntype);
+ fileName = getName();
+// try {
+ String ipd = App.localIp;
+// String ipd = InetAddress.getLocalHost().getHostAddress().toString();
+ if(ipd.startsWith("\\"))
+ ip =ipd.substring(1) ;
+ else ip = ipd;
+// } catch (UnknownHostException e) {
+// e.printStackTrace();
+// }
+ hash = getHash();
+ size = length();
+ }
+
+ public SharedFileHeader(String pathname) {
+ super(pathname);
+ localPath = pathname;
+ initialize();
+ }
+
+ public SharedFileHeader(String parent, String child) {
+ super(parent, child);
+ initialize();
+ }
+
+ public SharedFileHeader(File parent, String child) {
+ super(parent, child);
+
+ initialize();
+ }
+
+ public SharedFileHeader(URI uri) {
+ super(uri);
+
+ initialize();
+ }
+
+ public static SharedFileHeader fromFile(File file) {
+ return new SharedFileHeader(file.getPath());
+ }
+
+ public Integer getNDNID() {
+ return ndnid;
+ }
+
+ String getExtension() {
+ String name = getName();
+
+ try {
+ return name.substring(name.lastIndexOf(".") + 1).toLowerCase();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ String getNDNType() {
+ return ndntype;
+ }
+
+ String getLocalPath() {
+ return localPath;
+ }
+
+ String getHash(boolean force) {
+ if ((hash != null && hash.length() > 0) && !force) {
+ return hash;
+ }
+
+ try {
+ hash = Hasher.calculateFileHash(localPath);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+
+ return hash;
+ }
+
+ public String getHash() {
+ return getHash(false);
+ }
+
+ long getLastModified() {
+ return lastModified();
+ }
+
+ boolean isRemoteFile() {
+ return (getPath() == null && lastModified == -1);
+ }
+
+ public boolean hasKeyword(String keyword) {
+ return keywords.contains(keyword);
+ }
+
+ public String getScreenName(){
+ return ndnid +" - "+getName() +" - "+ ip;
+ }
+
+ public List getKeywords() {
+ return keywords;
+ }
+
+ @Override
+ public String toString() {
+ return "SharedFileHeader{" +
+ "fileName='"+ fileName +"\'"+
+ ", ip='" +ip+"\'"+
+ ", ndnid='" + ndnid + '\'' +
+ ", ndntype='" + ndntype + '\'' +
+ ", keywords=" + keywords +
+ ", localPath='" + localPath + '\'' +
+ ", lastModified=" + lastModified +
+ ", hash='" + getHash() + '\'' +
+ ", size=" + getSize() +
+ '}';
+ }
+
+ public void setNDNid(Integer NDNid) {
+ this.ndnid = NDNid;
+ }
+
+ public String getIp() {
+ return ip;
+ }
+
+ public long getSize() {
+ return size;
+ }
+
+ public void setIp(String ip) {
+ this.ip = ip;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+}
diff --git a/src/main/java/org/organet/commons/inofy/Watcher.java b/src/main/java/org/organet/commons/inofy/Watcher.java
new file mode 100644
index 0000000..d263dcc
--- /dev/null
+++ b/src/main/java/org/organet/commons/inofy/Watcher.java
@@ -0,0 +1,193 @@
+package org.organet.commons.inofy;
+
+import org.organet.commons.gabriel.App;
+import org.organet.commons.gabriel.ConnectionManager;
+import org.organet.commons.gabriel.Model.Connection;
+import org.organet.commons.inofy.Model.SharedFileHeader;
+
+import java.io.*;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
+import static java.nio.file.StandardWatchEventKinds.*;
+
+public class Watcher implements Runnable {
+ private final WatchService watcher;
+ private final Map keys;
+
+ @SuppressWarnings("unchecked")
+ static WatchEvent cast(WatchEvent> event) {
+ return (WatchEvent)event;
+ }
+
+ /**
+ * Creates a WatchService and registers the given directory
+ */
+ Watcher(Path dir) throws IOException {
+ watcher = FileSystems.getDefault().newWatchService();
+ keys = new HashMap<>();
+
+ registerAll(dir);
+ }
+
+ public Watcher(String path) throws IOException {
+ this(Paths.get(path));
+ }
+
+ /**
+ * Register the given directory with the WatchService
+ */
+ private void register(Path dir) throws IOException {
+ WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
+
+ Path prev = keys.get(key);
+ if (prev == null) {
+ // TODO Continue formatting printed text
+ System.out.format("register: %s\n", dir);
+ } else {
+ if (!dir.equals(prev)) {
+ System.out.format("update: %s -> %s\n", prev, dir);
+ }
+ }
+
+ keys.put(key, dir);
+ }
+
+ /**
+ * Register the given directory, and all its sub-directories, with the
+ * WatchService.
+ */
+ private void registerAll(final Path start) throws IOException {
+ // register directory and sub-directories
+ Files.walkFileTree(start, new SimpleFileVisitor() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+ register(dir);
+
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+
+ /**
+ * Process all events for keys queued to the watcher
+ */
+ @Override
+ public void run() {
+ int i=0;
+ for (;;) {
+ // wait for key to be signalled
+ WatchKey key;
+ try {
+ // Returns a queued key. If no queued key is available, this method waits.
+ key = watcher.take();
+ } catch (InterruptedException x) {
+ return;
+ }
+
+ Path dir = keys.get(key);
+ if (dir == null) {
+ System.err.println("WatchKey not recognized!!");
+ continue;
+ }
+
+ // Process the pending events for the key.
+ for (WatchEvent> event: key.pollEvents()) {
+ WatchEvent.Kind kind = event.kind();
+
+ // TBD - provide example of how OVERFLOW event is handled
+ if (kind == OVERFLOW) {
+ continue;
+ }
+
+ // Context for directory entry event is the file fileName of entry
+ WatchEvent ev = cast(event);
+ Path filename = ev.context();
+ Path child = dir.resolve(filename);
+
+ boolean isDirectory = Files.isDirectory(child, NOFOLLOW_LINKS);
+ if (isDirectory) {
+ // if directory is created, and watching recursively, then
+ // register it and its sub-directories
+ if (kind == ENTRY_CREATE) {
+ try {
+ if (Files.isDirectory(child, NOFOLLOW_LINKS)) {
+ registerAll(child);
+ }
+ //
+ } catch (IOException x) {
+ // ignore to keep sample readable
+ }
+ }
+ } else {
+ // Check if file is hidden - if so omit the file
+ if (filename.toFile().isHidden()) {
+ continue;
+ }
+
+ // TODO Decide file type (DOCUMENT, IMAGE, VIDEO, AUDIO etc.) \
+ // File types are implementation specific
+
+ if (kind == ENTRY_CREATE) {
+ isCompletelyWritten(child.toFile());
+
+ SharedFileHeader sh = new SharedFileHeader(child.toString());
+ ConnectionManager.sendNewSharedFiletoNetwork(sh);
+ System.out.println("new Shared File: " + sh.toString());
+ App.localIndex.add(sh);
+ App.mainForm.LocalIndexListModel.addElement(sh.getFileName());
+
+ } else if (kind == ENTRY_MODIFY) {
+ // TODO Re-calculate the hash and update the local index
+ } else if (kind == ENTRY_DELETE) {
+ // Remove file from the local index
+ App.localIndex.remove(child);
+
+ // FIXME Implement this behaviour in another way (i.e. anywhere else) \
+ // filename MUST stay as it is, it is not the problem here
+ App.mainForm.LocalIndexListModel.removeElement(filename.toString());
+ }
+ }
+ }
+
+ // reset key and remove from set if directory no longer accessible
+ boolean valid = key.reset();
+ if (!valid) {
+ keys.remove(key);
+
+ // all directories are inaccessible
+ if (keys.isEmpty()) {
+ break;
+ }
+ }
+ }
+ }
+
+ private boolean isCompletelyWritten(File file) {
+ while(true){
+
+ RandomAccessFile stream = null;
+ try {
+ Thread.sleep(1000);
+ stream = new RandomAccessFile(file, "rw");
+ Thread.sleep(1000);
+ return true;
+ } catch (Exception e) {
+ System.out.println("Skipping file " + file.getName() + " for this iteration due it's not completely written");
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ System.out.println("Exception during closing file " + file.getName());
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/main.iml b/src/main/main.iml
new file mode 100644
index 0000000..908ad4f
--- /dev/null
+++ b/src/main/main.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file