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