From 0200bf1715b98bfb35c97130c44c9ca3f582926e Mon Sep 17 00:00:00 2001 From: Obsidiam Date: Fri, 22 Sep 2017 21:42:56 +0200 Subject: [PATCH] I dont know, really... --- pom.xml | 7 +- .../com/neology/controllers/Accessable.java | 27 ++++ .../com/neology/controllers/AccessorImpl.java | 63 +++++++++ .../neology/controllers/FXMLController.java | 62 +++++++-- .../com/neology/controllers/SignalType.java | 27 ++++ .../neology/data/ConnectionDataHandler.java | 21 ++- .../exceptions/AccessDeniedException.java | 31 +++++ .../exceptions/ClosedConnectionException.java | 4 +- .../exceptions/TransportException.java | 8 +- .../com/neology/google/Authorization.java | 2 +- .../com/neology/interfaces/Connectable.java | 3 +- .../ConnectionListChangeListener.java | 28 ++++ src/main/java/com/neology/main/MainApp.java | 24 ++-- src/main/java/com/neology/net/Connection.java | 9 +- .../com/neology/net/ConnectionManager.java | 101 +++++++++++--- .../com/neology/net/ConnectionReceiver.java | 66 +++++----- src/main/java/com/neology/net/TCPThread.java | 123 ++++++++++-------- .../java/com/neology/net/states/Closed.java | 10 +- .../com/neology/net/states/Established.java | 2 +- .../com/neology/net/states/Transport.java | 17 +-- .../neology/net/states/TransportState.java | 3 +- 21 files changed, 486 insertions(+), 152 deletions(-) create mode 100644 src/main/java/com/neology/controllers/Accessable.java create mode 100644 src/main/java/com/neology/controllers/AccessorImpl.java create mode 100644 src/main/java/com/neology/controllers/SignalType.java create mode 100644 src/main/java/com/neology/exceptions/AccessDeniedException.java create mode 100644 src/main/java/com/neology/listeners/ConnectionListChangeListener.java diff --git a/pom.xml b/pom.xml index 088d5bd..8a46814 100644 --- a/pom.xml +++ b/pom.xml @@ -157,5 +157,10 @@ gson 2.8.1 - + + org.controlsfx + controlsfx + 8.40.13 + + diff --git a/src/main/java/com/neology/controllers/Accessable.java b/src/main/java/com/neology/controllers/Accessable.java new file mode 100644 index 0000000..916644b --- /dev/null +++ b/src/main/java/com/neology/controllers/Accessable.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 zsel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.neology.controllers; + +/** + * + * @author obsidiam + */ +public interface Accessable { + boolean checkViewUpdaterAccess(Thread th); + void sendNotificationSignal(SignalType s); + void commitSignalData(String msg); +} diff --git a/src/main/java/com/neology/controllers/AccessorImpl.java b/src/main/java/com/neology/controllers/AccessorImpl.java new file mode 100644 index 0000000..4389afb --- /dev/null +++ b/src/main/java/com/neology/controllers/AccessorImpl.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2017 zsel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.neology.controllers; + +import com.neology.controllers.FXMLController.ViewUpdater; +import com.neology.exceptions.AccessDeniedException; + +/** + * + * @author obsidiam + */ +final public class AccessorImpl implements Accessable{ + private ViewUpdater instance; + private boolean hasAccess = false; + private Thread th; + + AccessorImpl(ViewUpdater v){ + this.instance = v; + } + + @Override + public void sendNotificationSignal(SignalType s) { + if(hasAccess){ + instance.signal(s); + }else{ + throw new AccessDeniedException("Access is denied for "+th.getName()); + } + } + + + @Override + public boolean checkViewUpdaterAccess(Thread t) throws AccessDeniedException{ + try{ + instance.checkAccess(); + hasAccess = true; + }finally{ + if(hasAccess){ + return true; + } + } + this.th = t; + return false; + } + + @Override + public void commitSignalData(String msg) { + instance.commitSignalData(msg); + } +} diff --git a/src/main/java/com/neology/controllers/FXMLController.java b/src/main/java/com/neology/controllers/FXMLController.java index fbaeabe..8a0181d 100644 --- a/src/main/java/com/neology/controllers/FXMLController.java +++ b/src/main/java/com/neology/controllers/FXMLController.java @@ -32,6 +32,7 @@ import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.geometry.Insets; +import javafx.geometry.Pos; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Button; @@ -48,7 +49,9 @@ import javafx.scene.paint.Color; import javafx.stage.Stage; import javafx.util.Callback; +import javafx.util.Duration; import javax.xml.parsers.ParserConfigurationException; +import org.controlsfx.control.Notifications; import org.xml.sax.SAXException; public class FXMLController extends LocalEnvironment implements Initializable,Viewable { @@ -151,6 +154,7 @@ private void setUpConfiguration() throws SAXException, IOException, ParserConfig XMLController xml = new XMLController(); INIT = xml.parseInitFile(); PORT = Integer.parseInt(INIT.get(0)); + ADDR = INIT.get(1); } private void loginUser() throws ClassNotFoundException { @@ -203,6 +207,7 @@ private boolean checkFolders() { } private void initSession() { + mgr.setAccessorInstance(new AccessorImpl(v)); c.start(); tcp.start(); v.start(); @@ -216,10 +221,9 @@ private void transitToDisconnectedMode() { tcp.interrupt(); mgr.interruptThread(); CDH.getData().clear(); - CDH.getConnectionList().clear(); - + CDH.setFree(true); Platform.runLater(() ->{ VIEWER_PANEL.getItems().clear(); INFO_VIEW.getItems().clear(); @@ -235,9 +239,7 @@ private void transitToConnectedMode() { System.out.println("ConnectionManager -> "+c.getState().toString()); if(c.getState() == Service.State.CANCELLED || c.getState() == Service.State.SUCCEEDED){ Platform.runLater(() ->{ - c.restart(); - tcp.start(); - mgr.start(); + reinitSession(); }); } System.out.println("ConnectionManager -> "+c.getState().toString()); @@ -262,6 +264,12 @@ private void setInfoViewData(String line) { public void viewCustom() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } + + private void reinitSession() { + c.restart(); + tcp.start(); + mgr.start(); + } private class CallbackImpl implements Callback, ListCell> { @@ -280,9 +288,8 @@ public void updateItem(T item, boolean empty) { setText(null); setGraphic(null); } else { - String fn = Paths.get(item.toString()).getFileName().toString(); - setText(fn); - + String fn = Paths.get(item.toString().split("-")[1]).getFileName().toString(); + //setText(fn); Image out = IDH.getImagesMap().get(fn.split("\\.")[0]); if(out != null){ @@ -305,9 +312,12 @@ public void updateItem(T item, boolean empty) { } } - private class ViewUpdater extends Thread implements Runnable{ + class ViewUpdater extends Thread implements Runnable{ private Thread T = null; - + private boolean wasSignaled = false; + private SignalType type; + private String msg = null; + @Override public void start(){ if(T == null){ @@ -324,16 +334,18 @@ public void run(){ Platform.runLater(() ->{ VIEWER_PANEL.getItems().clear(); + //System.out.println(map.size()); if(map.size() > 0){ if(c.getState() == javafx.concurrent.ScheduledService.State.RUNNING){ + map.forEach((x,y) ->{ - VIEWER_PANEL.getItems().add("file://"+getLocalVar(Local.TMP)+File.separator+x+".jpg:"+x); + VIEWER_PANEL.getItems().add("file://"+getLocalVar(Local.TMP)+File.separator+x+".jpg-"+x); }); if(SELECTED > -1 && VIEWER_PANEL.getItems().size() > SELECTED){ data.forEach((x,y) ->{ VIEWER_PANEL.getSelectionModel().select(SELECTED); - Object item = VIEWER_PANEL.getItems().get(SELECTED).toString().split(":")[2]; + Object item = VIEWER_PANEL.getItems().get(SELECTED).toString().split("-")[1]; if(item != null){ if(CDH.findConnectionName(item.toString()) != null){ setInfoViewData(CDH.getData().get(CDH.findConnectionName(item.toString()))); @@ -344,6 +356,11 @@ public void run(){ } } }); + + if(wasSignaled && msg != null){ + Platform.runLater(() -> showNotification(type.toString(), msg)); + wasSignaled = false; + } try { Thread.sleep(1000); System.gc(); @@ -352,5 +369,26 @@ public void run(){ } } } + + synchronized void signal(SignalType type){ + this.type = type; + wasSignaled = true; + } + + synchronized void commitSignalData(String msg){ + this.msg = msg; + } + + private synchronized void showNotification(String title, String text) { + + Notifications notificationBuilder = Notifications.create() + .title(title) + .text(text) + .graphic(null) + .hideAfter(Duration.seconds(10)) + .darkStyle() + .position(Pos.BOTTOM_RIGHT); + notificationBuilder.show(); + } } } diff --git a/src/main/java/com/neology/controllers/SignalType.java b/src/main/java/com/neology/controllers/SignalType.java new file mode 100644 index 0000000..bbae01b --- /dev/null +++ b/src/main/java/com/neology/controllers/SignalType.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 zsel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.neology.controllers; + +/** + * + * @author obsidiam + */ +public enum SignalType { + INFO, + WARNING, + ERROR +} diff --git a/src/main/java/com/neology/data/ConnectionDataHandler.java b/src/main/java/com/neology/data/ConnectionDataHandler.java index f7b41af..43f0c22 100644 --- a/src/main/java/com/neology/data/ConnectionDataHandler.java +++ b/src/main/java/com/neology/data/ConnectionDataHandler.java @@ -6,22 +6,23 @@ package com.neology.data; import com.neology.net.Connection; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.List; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; + /** * * @author obsidiam */ -public class ConnectionDataHandler { +public final class ConnectionDataHandler{ private volatile HashMap DATA = new HashMap<>(); private volatile HashSet IPS_MAP = new HashSet<>(); private static volatile ConnectionDataHandler INSTANCE = new ConnectionDataHandler(); - private volatile List SOCKET_LIST = Collections.synchronizedList(new ArrayList<>()); + private final ObservableList SOCKET_LIST = FXCollections.synchronizedObservableList(FXCollections.observableArrayList()); private volatile HashMap CONN_USER_DATA = new HashMap<>(); + private volatile boolean isFree = true; private ConnectionDataHandler(){} @@ -55,7 +56,7 @@ public synchronized void removeFromIpMap(String ip){ IPS_MAP.remove(ip); } - public synchronized List getConnectionList(){ + public synchronized ObservableList getConnectionList(){ return SOCKET_LIST; } @@ -72,5 +73,13 @@ public synchronized void putConnectionName(String userName, String ip){ public synchronized void removeConnectionName(String userName, String ip){ CONN_USER_DATA.remove(userName, ip); + } + + public void setFree(boolean free){ + this.isFree = free; + } + + public boolean isFree(){ + return isFree; } } diff --git a/src/main/java/com/neology/exceptions/AccessDeniedException.java b/src/main/java/com/neology/exceptions/AccessDeniedException.java new file mode 100644 index 0000000..f6b4266 --- /dev/null +++ b/src/main/java/com/neology/exceptions/AccessDeniedException.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 zsel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.neology.exceptions; + +/** + * + * @author obsidiam + */ +public final class AccessDeniedException extends SecurityException{ + public AccessDeniedException(String s){ + super(s); + } + + public AccessDeniedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/neology/exceptions/ClosedConnectionException.java b/src/main/java/com/neology/exceptions/ClosedConnectionException.java index a2c164e..6ae53db 100644 --- a/src/main/java/com/neology/exceptions/ClosedConnectionException.java +++ b/src/main/java/com/neology/exceptions/ClosedConnectionException.java @@ -29,8 +29,8 @@ @SuppressWarnings("serial") public class ClosedConnectionException extends TransportException { - public ClosedConnectionException(Throwable exception) { - super(exception); + public ClosedConnectionException(String msg, Throwable exception) { + super(msg ,exception); } } diff --git a/src/main/java/com/neology/exceptions/TransportException.java b/src/main/java/com/neology/exceptions/TransportException.java index 56594bc..4e38f9f 100644 --- a/src/main/java/com/neology/exceptions/TransportException.java +++ b/src/main/java/com/neology/exceptions/TransportException.java @@ -29,11 +29,13 @@ public class TransportException extends CommonException { public TransportException(String message, Throwable exception) { super(message, exception); } + public TransportException(Throwable exception) { super(exception); } - public TransportException(String message) { - super(message); - } + + public TransportException(String message) { + super(message); + } } diff --git a/src/main/java/com/neology/google/Authorization.java b/src/main/java/com/neology/google/Authorization.java index a8c2b7f..799eae4 100644 --- a/src/main/java/com/neology/google/Authorization.java +++ b/src/main/java/com/neology/google/Authorization.java @@ -61,7 +61,7 @@ public class Authorization { DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR); } catch (IOException | GeneralSecurityException t) { t.printStackTrace(); - System.exit(1); + //System.exit(1); } } diff --git a/src/main/java/com/neology/interfaces/Connectable.java b/src/main/java/com/neology/interfaces/Connectable.java index 4f0efb4..3dfec4c 100644 --- a/src/main/java/com/neology/interfaces/Connectable.java +++ b/src/main/java/com/neology/interfaces/Connectable.java @@ -5,6 +5,7 @@ */ package com.neology.interfaces; +import com.neology.exceptions.ClosedConnectionException; import com.neology.exceptions.TransportException; import com.neology.net.states.Transport; import java.io.InputStream; @@ -18,7 +19,7 @@ */ public interface Connectable { public void openConnection(InputStream in, OutputStream out); - public void closeConnection(Transport t, Socket s); + public void closeConnection(Transport t, Socket s) throws ClosedConnectionException; public void haltConnection(Transport t, Socket s); public void sendPacket(Transport t, byte[] buffer); public void establish(Transport t); diff --git a/src/main/java/com/neology/listeners/ConnectionListChangeListener.java b/src/main/java/com/neology/listeners/ConnectionListChangeListener.java new file mode 100644 index 0000000..6f68dc0 --- /dev/null +++ b/src/main/java/com/neology/listeners/ConnectionListChangeListener.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2017 zsel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.neology.listeners; + +import com.neology.net.states.State; +import javafx.collections.ListChangeListener; + +/** + * + * @author obsidiam + */ +public interface ConnectionListChangeListener extends ListChangeListener { + void sendNotificationSignal(); +} diff --git a/src/main/java/com/neology/main/MainApp.java b/src/main/java/com/neology/main/MainApp.java index a315ab6..05c0c29 100644 --- a/src/main/java/com/neology/main/MainApp.java +++ b/src/main/java/com/neology/main/MainApp.java @@ -29,6 +29,8 @@ public class MainApp extends Application{ + private Thread tcpInst = null; + @Override public void start(Stage stage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("/fxml/Scene.fxml")); @@ -41,7 +43,7 @@ public void start(Stage stage) throws Exception { if(files != null){ for(File f : files){ - if(f.getName().endsWith(".jpg")){ + if(f.getName().endsWith(".jpg") || f.getName().endsWith(".JPG")){ try { Files.delete(f.toPath()); } catch (IOException ex) { @@ -51,14 +53,21 @@ public void start(Stage stage) throws Exception { } } - Thread[] tarray = new Thread[Thread.activeCount()]; - Thread.enumerate(tarray); - for(Thread t : tarray){ - if(t.getName().equals("TCPThread")){ + if(tcpInst == null){ + Thread[] tarray = new Thread[Thread.activeCount()]; + Thread.enumerate(tarray); + for(Thread t : tarray){ + if(t.getName().equals("TCPThread")){ + openLoginDialog(event); + } + } + }else{ + if(tcpInst.isAlive()){ + System.out.println("TCP Thread was alive..."); openLoginDialog(event); } } - System.exit(0); + //System.exit(0); }); stage.setTitle("Amelia"); @@ -117,8 +126,7 @@ private void openLoginDialog(WindowEvent evt) { if (dialogButton == loginButtonType) { return new Pair<>(username.getText(), password.getText()); }else{ - evt.consume(); - return null; + return new Pair<>("",""); } }); diff --git a/src/main/java/com/neology/net/Connection.java b/src/main/java/com/neology/net/Connection.java index 3fb346f..985fc9f 100644 --- a/src/main/java/com/neology/net/Connection.java +++ b/src/main/java/com/neology/net/Connection.java @@ -8,6 +8,7 @@ import com.neology.net.states.Transport; import com.neology.net.states.TransportState; import com.neology.data.ConnectionDataHandler; +import com.neology.exceptions.ClosedConnectionException; import com.neology.exceptions.TransportException; import com.neology.net.states.State; import java.io.IOException; @@ -19,7 +20,7 @@ * * @author obsidiam */ -public class Connection { +final public class Connection { private TransportState ACTUAL; private Transport T; @@ -45,7 +46,11 @@ public void establish(Transport t){ } public void close(){ - ACTUAL.closeConnection(T, s); + try { + ACTUAL.closeConnection(T, s); + } catch (ClosedConnectionException ex) { + Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex); + } } public void halt(){ diff --git a/src/main/java/com/neology/net/ConnectionManager.java b/src/main/java/com/neology/net/ConnectionManager.java index 7d38ac5..1bd09f8 100644 --- a/src/main/java/com/neology/net/ConnectionManager.java +++ b/src/main/java/com/neology/net/ConnectionManager.java @@ -5,21 +5,29 @@ */ package com.neology.net; +import com.neology.controllers.AccessorImpl; +import com.neology.controllers.SignalType; import com.neology.data.ConnectionDataHandler; import com.neology.data.ImageDataHandler; +import com.neology.listeners.ConnectionListChangeListener; import com.neology.net.states.Closed; +import java.util.HashSet; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; /** * * @author obsidiam */ public class ConnectionManager extends Thread implements Runnable{ - private Thread mgr; - private ConnectionDataHandler cdh = ConnectionDataHandler.getInstance(); - private ImageDataHandler idh = ImageDataHandler.getInstance(); + private volatile Thread mgr; + private final ConnectionDataHandler cdh = ConnectionDataHandler.getInstance(); + private final ImageDataHandler idh = ImageDataHandler.getInstance(); private boolean wasInterrupted; + private volatile AccessorImpl acc; @Override public void start(){ @@ -31,26 +39,71 @@ public void start(){ @Override public void run(){ - while(!mgr.isInterrupted()){ - cdh.getConnectionList().stream().map((con) -> { - return con; - }).forEachOrdered( con ->{ - if( con.getState() == com.neology.net.states.State.ESTABLISHED){ - con.establish(con.getTranportInstance()); + ObservableList cons = cdh.getConnectionList(); + cons.addListener(new ConnectionListChangeListener() { + private Connection local; + + @Override + public void onChanged(ListChangeListener.Change c) { + if(c.next()){ + if(c.wasAdded()){ + int last = c.getAddedSize(); + local = (Connection)c.getAddedSubList().get(last - 1); + } + + if(c.wasRemoved()){ + int last = c.getRemovedSize(); + local = (Connection)c.getRemoved().get(last - 1); + idh.getImagesMap().remove(local.getConnectionName()); + sendNotificationSignal(); + + } + } } - - if( con.getState() == com.neology.net.states.State.CLOSED){ - con.close(); - cdh.getConnectionList().remove(con); - idh.getImagesMap().remove(con.getConnectionName()); + + @Override + public void sendNotificationSignal() { + if(acc.checkViewUpdaterAccess(mgr)){ + acc.sendNotificationSignal(SignalType.WARNING); + acc.commitSignalData("Connection with "+local.getConnectionName()+" is "+local.getState().toString().toLowerCase()); + } } }); - + + while(!mgr.isInterrupted()){ try { - Thread.sleep(1000); + synchronized(cons){ + while(cdh.isFree()){ + System.out.println("ConnectionManager#run() -> Waiting on cdh."); + cons.wait(); + } + Set toBeRemoved = new HashSet<>(); + + if(cons.size() > 0){ + for(Connection con : cons){ + if(con != null){ + if( con.getState() == com.neology.net.states.State.CLOSED){ + con.close(); + toBeRemoved.add(con); + }else{ + + if( con.getState() == com.neology.net.states.State.ESTABLISHED){ + con.establish(con.getTranportInstance()); + } + } + } + } + cons.removeAll(toBeRemoved); + toBeRemoved.clear(); + cdh.setFree(true); + cons.notifyAll(); + } + } + //Thread.sleep(1000); } catch (InterruptedException ex) { Logger.getLogger(ConnectionManager.class.getName()).log(Level.SEVERE, null, ex); } + if(wasInterrupted){ mgr.interrupt(); } @@ -58,7 +111,7 @@ public void run(){ } public void interruptThread(){ - if(mgr.getState() != State.TIMED_WAITING){ + if(mgr.getState() != State.WAITING){ mgr.interrupt(); }else{ wasInterrupted = true; @@ -70,10 +123,18 @@ public void interruptThread(){ private void disconnectAll() { cdh.getConnectionList().forEach(con ->{ cdh.addIpToMap(con.getTranportInstance().getIp().split(":")[0]); - Closed c = new Closed(); - con.changeState(c); - con.close(); + if(con.getState() != com.neology.net.states.State.CLOSED){ + Closed c = new Closed(); + con.changeState(c); + con.close(); + } }); + cdh.getConnectionList().clear(); } + + public void setAccessorInstance(AccessorImpl a){ + this.acc = a; } +} + diff --git a/src/main/java/com/neology/net/ConnectionReceiver.java b/src/main/java/com/neology/net/ConnectionReceiver.java index 9ea0f51..121e501 100644 --- a/src/main/java/com/neology/net/ConnectionReceiver.java +++ b/src/main/java/com/neology/net/ConnectionReceiver.java @@ -7,10 +7,10 @@ import com.neology.net.states.Opened; import com.neology.data.ConnectionDataHandler; -import com.neology.data.ImageDataHandler; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; +import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javafx.concurrent.Service; @@ -23,8 +23,12 @@ public class ConnectionReceiver extends Service { private boolean IS_CONNECTED = false; private ServerSocket ss = null; - private ConnectionDataHandler CDH = ConnectionDataHandler.getInstance(); + private final ConnectionDataHandler CDH = ConnectionDataHandler.getInstance(); + final List list; + { + list = CDH.getConnectionList(); + } private Connection initConnection(Socket s) throws IOException{ Opened o = new Opened(); @@ -32,47 +36,49 @@ private Connection initConnection(Socket s) throws IOException{ c.changeState(o); c.open(s); c.setIp(s.getRemoteSocketAddress().toString()); + return c; } @Override protected Task createTask() { return new Task(){ + @Override - public Void call() throws IOException{ + public Void call() throws IOException, InterruptedException{ try { - - this.updateTitle("ConnectionManager"); - if(ss == null){ - ss = new ServerSocket(CDH.getPort(),17); - - System.out.println("ServerSocket prepared."); - } - - while(!this.isCancelled()){ - - if(ss != null){ - Socket s = ss.accept(); - if(!ss.isClosed()){ - System.out.println("Server Accepted Connection Request from "+s.getInetAddress().toString()); - Connection c; - try { - c = initConnection(s); - BaudrateMeter meter = new BaudrateMeter(); - c.getTranportInstance().setBaudrateMeter(meter); + this.updateTitle("ConnectionManager"); + if(ss == null){ + ss = new ServerSocket(CDH.getPort(),17); - CDH.getConnectionList().add(c); - } catch (IOException ex) { - Logger.getLogger(ConnectionReceiver.class.getName()).log(Level.SEVERE, null, ex); - break; + System.out.println("ServerSocket prepared."); + } + + while(!this.isCancelled()){ + if(ss != null){ + Socket s = ss.accept(); + + if(!ss.isClosed()){ + System.out.println("Server Accepted Connection Request from "+s.getInetAddress().toString()); + Connection c; + try { + c = initConnection(s); + BaudrateMeter meter = new BaudrateMeter(); + c.getTranportInstance().setBaudrateMeter(meter); + + list.add(c); + + } catch (IOException ex) { + Logger.getLogger(ConnectionReceiver.class.getName()).log(Level.SEVERE, null, ex); + break; + } } - } + } } - - } + } catch (IOException ex) { - System.out.println("ConnectionManager stopped."); + System.out.println("ConnectionReceiver stopped."); } return null; } diff --git a/src/main/java/com/neology/net/TCPThread.java b/src/main/java/com/neology/net/TCPThread.java index 639d217..1a9842c 100644 --- a/src/main/java/com/neology/net/TCPThread.java +++ b/src/main/java/com/neology/net/TCPThread.java @@ -8,7 +8,6 @@ import com.neology.net.states.Transport; import com.neology.net.states.Closed; import com.neology.net.states.Established; -import com.neology.net.states.State; import com.neology.environment.LocalEnvironment; import com.neology.data.ConnectionDataHandler; import com.neology.data.ImageDataHandler; @@ -19,9 +18,10 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import javafx.scene.image.Image; import javax.imageio.ImageIO; @@ -31,13 +31,12 @@ */ public class TCPThread extends Thread implements Runnable{ private Thread TH; - private ConnectionDataHandler cdh = ConnectionDataHandler.getInstance(); + private final ConnectionDataHandler cdh = ConnectionDataHandler.getInstance(); private String NAME; private BaudrateMeter MTR; private final ImageDataHandler IDH = ImageDataHandler.getInstance(); - private final ConnectionDataHandler CDH = ConnectionDataHandler.getInstance(); private final LocalEnvironment LOCAL = new LocalEnvironment() {}; - private String ext = "PNG"; + private String ext = "JPG"; @Override public void start(){ @@ -49,55 +48,75 @@ public void start(){ @Override public void run(){ - while(TH != null){ - if(!TH.isInterrupted()){ - List connections = cdh.getConnectionList(); - for(int i = 0; i < connections.size(); i++){ - Transport t = null; - Connection c = connections.get(i); - - MTR = c.getTranportInstance().getBaudrateMeter(); - MTR.startMeasuringCycle(); - if(c.getState() == com.neology.net.states.State.OPENED){ - Established e = new Established(); - c.changeState(e); - } + List connections = cdh.getConnectionList(); + synchronized(connections){ + while(!cdh.isFree()){ + try { + System.out.println("TCPThread#run() -> waiting on cdh monitor..."); + connections.wait(); + } catch (InterruptedException ex) { + Logger.getLogger(TCPThread.class.getName()).log(Level.SEVERE, null, ex); + } + } + + if(!TH.isInterrupted()){ + System.out.println("TCPThread#run() -> starting reading..."); + for(int i = 0; i < connections.size(); i++){ + Transport t = null; + Connection c = connections.get(i); - if(c.getState() == com.neology.net.states.State.CLOSED){ - continue; - } - t = c.getTranportInstance(); - System.out.println("TRANSPORTER_IP: "+t.getIp()); + MTR = c.getTranportInstance().getBaudrateMeter(); + MTR.startMeasuringCycle(); + + if(c.getState() == com.neology.net.states.State.OPENED){ + Established e = new Established(); + c.changeState(e); + } + + if(c.getState() == com.neology.net.states.State.CLOSED){ + continue; + } - byte[] buffer; + if(c.getState() == com.neology.net.states.State.ESTABLISHED){ + t = c.getTranportInstance(); + System.out.println("TRANSPORTER_IP: "+t.getIp()); - try { - buffer = c.read(t); - System.out.println(buffer.length); - Image im = processData(buffer); - IDH.getImagesMap().put(NAME, im); + byte[] buffer; - String data = ""; - data += "Client name: "+NAME+","; - data += "IP: "+t.getIp().substring(1)+","; - data += "Speed: "+t.getBaudrateMeter().kBPS()+"kB/s,"; - data += "Is connected: "+t.isConnected()+","; - data += "Was connected earlier: "+c.wasConnected(); - CDH.getData().put(t.getIp(), data); - if(!c.isNameSet()){ - c.setConnectionName(NAME); - } - CDH.putConnectionName(NAME, t.getIp()); - } catch (TransportException | IOException ex) { - System.err.println("LOCALIZED_ERR_MSG:"+ex.getLocalizedMessage()); - c.changeState(new Closed()); - break; - } + try { + buffer = c.read(t); + System.out.println(buffer.length); + Image im = processData(buffer); + IDH.getImagesMap().put(NAME, im); + + String data = ""; + data += "Client name: "+NAME+","; + data += "IP: "+t.getIp().substring(1)+","; + data += "Speed: "+t.getBaudrateMeter().kBPS()+"kB/s,"; + data += "Is connected: "+t.isConnected()+","; + data += "Was connected earlier: "+c.wasConnected(); + cdh.getData().put(t.getIp(), data); + if(!c.isNameSet()){ + c.setConnectionName(NAME); + + } + cdh.putConnectionName(NAME, t.getIp()); + + } catch (TransportException | IOException ex) { + System.err.println("LOCALIZED_ERR_MSG:"+ex.getLocalizedMessage()); + c.changeState(new Closed()); + + break; + } + } + } + cdh.setFree(false); + System.out.println("TCPThread#run() -> releasing cdh monitor."); + connections.notifyAll(); + }else{ + break; } - - }else{ - break; } } } @@ -105,8 +124,10 @@ public void run(){ @Override public void interrupt(){ if(TH != null){ - TH.interrupt(); - TH = null; + if(TH.getState() != State.WAITING && TH.getState() != State.TIMED_WAITING){ + TH.interrupt(); + TH = null; + } } } @@ -119,7 +140,7 @@ private Image processData(byte[] buffer) throws IOException { String name = String.valueOf(c).trim(); NAME = name; System.out.println("FILE_NAME_RECEIVED: "+name); - result = Arrays.copyOfRange(buffer,len,32768); + result = Arrays.copyOfRange(buffer,len,8192); is = new ByteArrayInputStream(result); BufferedImage bf = ImageIO.read(is); diff --git a/src/main/java/com/neology/net/states/Closed.java b/src/main/java/com/neology/net/states/Closed.java index 1cb9908..1621749 100644 --- a/src/main/java/com/neology/net/states/Closed.java +++ b/src/main/java/com/neology/net/states/Closed.java @@ -5,6 +5,7 @@ */ package com.neology.net.states; +import com.neology.exceptions.ClosedConnectionException; import java.io.IOException; import java.net.Socket; import java.util.logging.Level; @@ -18,21 +19,23 @@ public class Closed extends TransportState{ private Transport T; @Override - public void closeConnection(Transport t, Socket s) { + public void closeConnection(Transport t, Socket s) throws ClosedConnectionException{ try { System.out.println("Closed::closeConnection() -> attempting to close..."); this.T = t; if(t != null){ - if(t.isConnected()){ + if(t.isConnected() && !s.isClosed()){ t.close(); s.close(); + T = null; System.out.println("Closed::closeConnection() -> closed."); + }else{ + throw new ClosedConnectionException("Connection already closed!",new Throwable()); } } } catch (IOException ex) { Logger.getLogger(Closed.class.getName()).log(Level.SEVERE, null, ex); } - } @Override @@ -41,6 +44,7 @@ public void haltConnection(Transport t, Socket s) { this.T = t; t.close(); s.close(); + T = null; } catch (IOException ex) { Logger.getLogger(Closed.class.getName()).log(Level.SEVERE, null, ex); } diff --git a/src/main/java/com/neology/net/states/Established.java b/src/main/java/com/neology/net/states/Established.java index 6172a5c..2bef915 100644 --- a/src/main/java/com/neology/net/states/Established.java +++ b/src/main/java/com/neology/net/states/Established.java @@ -33,7 +33,7 @@ public void sendPacket(Transport t, byte[] buffer) { @Override public byte[] readPacket(Transport t) throws TransportException{ System.out.println("Established readPacket()::"+t.getIp()); - return t.readBytes(32768); + return t.readBytes(8192); } @Override diff --git a/src/main/java/com/neology/net/states/Transport.java b/src/main/java/com/neology/net/states/Transport.java index 81c0ed4..56b46e9 100644 --- a/src/main/java/com/neology/net/states/Transport.java +++ b/src/main/java/com/neology/net/states/Transport.java @@ -40,8 +40,6 @@ public class Transport { private DataOutputStream os; private InputStream origIs; private OutputStream origOs; - //Socket s; - private boolean WAS_CONNECTED = false; private BaudrateMeter baudrateMeter; private String IP; @@ -72,7 +70,6 @@ public Transport() { void release() { origIs = is = null; origOs = os = null; - WAS_CONNECTED = true; } public void close() throws IOException{ @@ -85,7 +82,7 @@ public byte readByte() throws TransportException { if (baudrateMeter != null) baudrateMeter.count(1); return is.readByte(); } catch (EOFException e) { - throw new ClosedConnectionException(e); + throw new ClosedConnectionException("Cannot read byte",e); } catch (IOException e) { throw new TransportException("Cannot read byte", e); } @@ -113,7 +110,7 @@ public short readInt16() throws TransportException { if (baudrateMeter != null) baudrateMeter.count(2); return is.readShort(); } catch (EOFException e) { - throw new ClosedConnectionException(e); + throw new ClosedConnectionException("Cannot read int16",e); } catch (IOException e) { throw new TransportException("Cannot read int16", e); } @@ -128,7 +125,7 @@ public int readInt32() throws TransportException { if (baudrateMeter != null) baudrateMeter.count(4); return is.readInt(); } catch (EOFException e) { - throw new ClosedConnectionException(e); + throw new ClosedConnectionException("Cannot read int32",e); } catch (IOException e) { throw new TransportException("Cannot read int32", e); } @@ -139,9 +136,9 @@ public long readInt64() throws TransportException { if (baudrateMeter != null) baudrateMeter.count(8); return is.readLong(); } catch (EOFException e) { - throw new ClosedConnectionException(e); + throw new ClosedConnectionException("Cannot read long",e); } catch (IOException e) { - throw new TransportException("Cannot read int32", e); + throw new TransportException("Cannot read long", e); } } @@ -209,7 +206,7 @@ public byte[] readBytes(byte[] b, int offset, int length) throws TransportExcept } return b; } catch (EOFException e) { - throw new ClosedConnectionException(e); + throw new ClosedConnectionException("Cannot read " + length + " bytes array",e); } catch (IOException e) { throw new TransportException("Cannot read " + length + " bytes array", e); } @@ -225,7 +222,7 @@ public void skip(int length) throws TransportException { baudrateMeter.count(length); } } catch (EOFException e) { - throw new ClosedConnectionException(e); + throw new ClosedConnectionException("Cannot skip " + length + " bytes",e); } catch (IOException e) { throw new TransportException("Cannot skip " + length + " bytes", e); } diff --git a/src/main/java/com/neology/net/states/TransportState.java b/src/main/java/com/neology/net/states/TransportState.java index 8a08330..767bb22 100644 --- a/src/main/java/com/neology/net/states/TransportState.java +++ b/src/main/java/com/neology/net/states/TransportState.java @@ -5,6 +5,7 @@ */ package com.neology.net.states; +import com.neology.exceptions.ClosedConnectionException; import com.neology.exceptions.TransportException; import com.neology.interfaces.Connectable; import java.io.InputStream; @@ -25,7 +26,7 @@ public void openConnection(InputStream in, OutputStream out){ T = o.getTransportInstance(); } @Override - public void closeConnection(Transport t, Socket s){ + public void closeConnection(Transport t, Socket s) throws ClosedConnectionException{ this.closeConnection(t,s); } @Override