diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..9821ca9 --- /dev/null +++ b/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..9caddaa --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + Projet_POO + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/Projet_POO/src/bdd/GestionnaireHistorique.java b/Projet_POO/src/bdd/GestionnaireHistorique.java index d187645..ad81be5 100644 --- a/Projet_POO/src/bdd/GestionnaireHistorique.java +++ b/Projet_POO/src/bdd/GestionnaireHistorique.java @@ -1,17 +1,11 @@ package bdd; -import java.net.InetAddress; import java.sql.Connection; -import java.sql.PreparedStatement; import java.sql.Statement; import java.sql.ResultSet; import java.sql.SQLException; -import javax.swing.JOptionPane; - -import clavardage.gestionnaireClavardage; import nom.GestionnaireNom; -import ui.NomUI; public class GestionnaireHistorique { diff --git a/Projet_POO/src/clavardage/EnvoiMessageDistance.java b/Projet_POO/src/clavardage/EnvoiMessageDistance.java new file mode 100644 index 0000000..d707be8 --- /dev/null +++ b/Projet_POO/src/clavardage/EnvoiMessageDistance.java @@ -0,0 +1,119 @@ +package clavardage; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import data.ServletResponse; +import defaut.Constantes; +import data.Message; + +public class EnvoiMessageDistance { + + + + public static void main(String[] args) throws IOException { + + //Test 1 + System.out.println("Test 1"); + System.out.println(EnvoiMessageDistance.envoiMessage("command", "World", "", "initialize")); + System.out.println(EnvoiMessageDistance.envoiMessage("message", "Me", "World", "Hello World !")); + System.out.println(EnvoiMessageDistance.envoiMessage("message", "Me", "World", "Hello again !")); + System.out.println(EnvoiMessageDistance.envoiMessage("command", "World", "", "getMessages")); + + //Test 2 (Longue liste de messages en attente) + System.out.println(""); + System.out.println("Test 2"); + System.out.println(EnvoiMessageDistance.envoiMessage("command", "Destinataire", "", "initialize")); + for (int i = 0; i<100; i++) { + System.out.println(EnvoiMessageDistance.envoiMessage("message", "Personne " + i, "Destinataire", "Message numéro " + i)); + } + System.out.println(EnvoiMessageDistance.envoiMessage("command", "Destinataire", "", "getMessages")); + + //Test 3 (Pas de messages en attente) + System.out.println(""); + System.out.println("Test 3"); + System.out.println(EnvoiMessageDistance.envoiMessage("command", "Me", "", "initialize")); + System.out.println(EnvoiMessageDistance.envoiMessage("command", "Me", "", "getMessages")); + + + //Test4 commande invalide + System.out.println(""); + System.out.println("Test 4"); + System.out.println(EnvoiMessageDistance.envoiMessage("command", "World", "", "getMessage")); + + //Test5 type invalide + System.out.println(""); + System.out.println("Test 5"); + System.out.println(EnvoiMessageDistance.envoiMessage("autre", "User1", "User2", "Le type de ce message est invalide")); + + + + /* + Reader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); + + for (int c; (c = in.read()) >= 0;) + System.out.print((char)c); + */ + + + } + + public static ServletResponse envoiMessage(String Type, String Sender, String Recipient, String Body) throws IOException { + + //Préparation du message + Message msg = new Message(); + msg.setType(Type); + msg.setSender(Sender); + msg.setRecipient(Recipient); + msg.setBody(Body); + + //On transforme le Message en ByteArray + ByteArrayOutputStream baostream = new ByteArrayOutputStream (); + ObjectOutputStream oostream = new ObjectOutputStream (baostream); + oostream.writeObject(msg); + oostream.flush(); + byte[] postDataBytes = baostream.toByteArray(); + + + //URL url = new URL("http://localhost:8080/Servlet_MBP/messageServlet"); + URL url = new URL(Constantes.URL_SERVLET_MESSAGES); + HttpURLConnection conn = (HttpURLConnection)url.openConnection(); + + //On configure la requête POST + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "multipart/form-data"); + conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); + + //On envoie la donnée + conn.setDoOutput(true); + conn.getOutputStream().write(postDataBytes); + + //Si la commande avait pour but de récupérer les messages d'un utilisateur + if (msg.getType().equals("command") && msg.getBody().equals("getMessages")) { + ArrayList msgList = null; + try { + msgList = (ArrayList ) new ObjectInputStream (conn.getInputStream()).readObject(); + } catch (ClassNotFoundException | IOException e) { + e.printStackTrace(); + } + + return new ServletResponse(200, msgList); + + } + + + //Sinon, on récupère le status code pour vérifier que tout c'est bien passé + else { + return new ServletResponse(conn.getResponseCode(),null); + } + + + } + + + +} diff --git a/Projet_POO/src/clavardage/GestionnaireMessagesDistants.java b/Projet_POO/src/clavardage/GestionnaireMessagesDistants.java new file mode 100644 index 0000000..7eb43d6 --- /dev/null +++ b/Projet_POO/src/clavardage/GestionnaireMessagesDistants.java @@ -0,0 +1,96 @@ +package clavardage; + +import java.io.IOException; +import data.Message; +import data.ServletResponse; +import nom.GestionnaireNom; + +public class GestionnaireMessagesDistants implements Runnable{ + + private static GestionnaireMessagesDistants uniqueInstance = null; + private Thread thread; + + public static GestionnaireMessagesDistants instance() { + if (uniqueInstance == null) { + uniqueInstance = new GestionnaireMessagesDistants(); + } + return GestionnaireMessagesDistants.uniqueInstance; + } + + public GestionnaireMessagesDistants () { + this.thread = new Thread(this); + this.thread.start(); + } + + public void run() { + + //On indique au servlet que l'on est disponible pour recevoire des messages + try { + EnvoiMessageDistance.envoiMessage("command", GestionnaireNom.instance().getId(), "", "initialize"); + } catch (IOException e) { + e.printStackTrace(); + } + + while (true) { + + //On attend 1 seconde + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //On essai de récupérer les nouveaux messages qui nous sont destinés sur le serveur, si il y en a. + ServletResponse res = new ServletResponse(0, null); + + try { + res = EnvoiMessageDistance.envoiMessage("command", GestionnaireNom.instance().getId(), "", "getMessages"); + } catch (IOException e) { + e.printStackTrace(); + } + + if (res.getMessageList() != null) { + //On transmet les messages au bon endroit/effectue les ouertures de session + for (Message msg : res.getMessageList()) { + if (msg.getType().equals("message")){ + String sender = msg.getSender(); + SessionClavardageDistante session = GestionnaireSessionsDistantes.instance().getSessions().get(sender); + if (session != null) { + //La sesion est ouverte, on transmet le message + session.addMessage(msg); + } + + } + else if (msg.getType().equals("command")) { + switch (msg.getBody()) { + + case "startSession": + try { + GestionnaireSessionsDistantes.instance().createSession(GestionnaireNom.instance().nomFromId(msg.getSender()), false); + } catch (IOException e) { + //Cette erreur ne peut pas se produire lorsque notifyRemoteClient vaut false, comme au dessus + e.printStackTrace(); + } + break; + case "stopSession": + String sender = msg.getSender(); + SessionClavardageDistante session = GestionnaireSessionsDistantes.instance().getSessions().get(sender); + if (session != null) { + //La session est ouverte, on transmet le message. + session.addMessage(msg); + } + default: + //Commande inconnue. On l'ignore. + } + } + + else { + //Type de message inconnu. On l'ignore. + } + } + } + + } + } + +} diff --git a/Projet_POO/src/clavardage/GestionnaireSessionsDistantes.java b/Projet_POO/src/clavardage/GestionnaireSessionsDistantes.java new file mode 100644 index 0000000..525d23a --- /dev/null +++ b/Projet_POO/src/clavardage/GestionnaireSessionsDistantes.java @@ -0,0 +1,70 @@ +package clavardage; +import java.awt.EventQueue; +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; + +import nom.GestionnaireNom; +import ui.DiscussionUI; + +public class GestionnaireSessionsDistantes { + private static GestionnaireSessionsDistantes uniqueInstance = null; + private ConcurrentHashMap sessions = new ConcurrentHashMap (); + //private Thread thread; + + public static GestionnaireSessionsDistantes instance() { + if (uniqueInstance == null) { + uniqueInstance = new GestionnaireSessionsDistantes(); + } + return GestionnaireSessionsDistantes.uniqueInstance; + } + + + private GestionnaireSessionsDistantes() { + //this.thread = new Thread(this); + //this.thread.start(); + } + + //notifyRemoteClient vaut true si la fonction doit notifier le client distant de la création de la session, false sinon. + public void createSession(String name, boolean notifyRemoteClient) throws IOException { + GestionnaireNom gn = GestionnaireNom.instance(); + SessionClavardageDistante session = new SessionClavardageDistante(gn.getId(), gn.idFromNom(name)); + this.sessions.put(gn.idFromNom(name), session); + if (notifyRemoteClient) { + EnvoiMessageDistance.envoiMessage("command", gn.getId(), gn.idFromNom(name), "startSession"); + } + //Lancement de la fenêtre de session + EventQueue.invokeLater(new Runnable() { + public void run() { + try { + DiscussionUI frame = new DiscussionUI(session); + frame.setVisible(true); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + public void deleteSession(SessionClavardageDistante session) { + session.stop(); + this.sessions.remove(session.getIdDestination()); + } + + public ConcurrentHashMap getSessions() { + return this.sessions; + } + + public void fermerSessions() throws IOException { + for (SessionClavardageDistante s : this.sessions.values()) { + s.stop(); + } + } + + public void printSessions() { + for (SessionClavardageDistante s : this.sessions.values()) { + System.out.print(s); + } + } + + +} diff --git a/Projet_POO/src/clavardage/gestionnaireClavardage.java b/Projet_POO/src/clavardage/GestionnaireSessionsLocales.java similarity index 69% rename from Projet_POO/src/clavardage/gestionnaireClavardage.java rename to Projet_POO/src/clavardage/GestionnaireSessionsLocales.java index 3044150..f3d7153 100644 --- a/Projet_POO/src/clavardage/gestionnaireClavardage.java +++ b/Projet_POO/src/clavardage/GestionnaireSessionsLocales.java @@ -1,34 +1,30 @@ package clavardage; import java.awt.EventQueue; import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.ServerSocket; import java.net.Socket; -import java.net.SocketAddress; -import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; import nom.GestionnaireNom; import reseau.*; import ui.DiscussionUI; -public class gestionnaireClavardage implements Runnable{ +public class GestionnaireSessionsLocales implements Runnable{ public static final int PORT_REQUETE_NOUVELLE_SESSION = 19999; public static final int BACKLOG = 10; - private static gestionnaireClavardage uniqueInstance = null; - private ArrayList sessions = new ArrayList(); + private static GestionnaireSessionsLocales uniqueInstance = null; + private ConcurrentHashMap sessions = new ConcurrentHashMap (); private TCPServer requestServer; private Thread thread; - public static gestionnaireClavardage instance() { + public static GestionnaireSessionsLocales instance() { if (uniqueInstance == null) { - uniqueInstance = new gestionnaireClavardage(BACKLOG); + uniqueInstance = new GestionnaireSessionsLocales(BACKLOG); } - return gestionnaireClavardage.uniqueInstance; + return GestionnaireSessionsLocales.uniqueInstance; } - //Ajouter la supppression des sessions de la liste après déconnexion - //Remplacer par un singleton - private gestionnaireClavardage(int backlog) { + //TODO Ajouter la suppression des sessions de la liste après déconnexion + private GestionnaireSessionsLocales(int backlog) { GestionnaireNom gn = GestionnaireNom.instance(); System.out.print(gn.getIp()); this.requestServer = new TCPServer(gn.getIp(), backlog, PORT_REQUETE_NOUVELLE_SESSION + Integer.parseInt(gn.getId())); @@ -39,8 +35,8 @@ public class gestionnaireClavardage implements Runnable{ public void createSession(String name) { GestionnaireNom gn = GestionnaireNom.instance(); TCPClient client = new TCPClient(gn.ipFromNom(name), PORT_REQUETE_NOUVELLE_SESSION + Integer.parseInt(gn.idFromNom(name))) ; - SessionClavardage session = new SessionClavardage(gn.getId(), gn.idFromNom(name), client, null); - this.sessions.add(session); + SessionClavardageLocale session = new SessionClavardageLocale(gn.getId(), gn.idFromNom(name), client, null); + this.sessions.put(gn.idFromNom(name), session); client.send(gn.getId()+"\n"); System.out.print("Paramètres de session envoyée à " + gn.idFromNom(name) + "\n"); @@ -59,21 +55,21 @@ public class gestionnaireClavardage implements Runnable{ public void deleteSession(SessionClavardage session) { session.stop(); - this.sessions.remove(session); + this.sessions.remove(session.getIdDestination()); } - public ArrayList getSessions() { + public ConcurrentHashMap getSessions() { return this.sessions; } public void fermerSessions() { - for (SessionClavardage s : this.sessions) { + for (SessionClavardageLocale s : this.sessions.values()) { s.stop(); } } public void printSessions() { - for (SessionClavardage s : sessions) { + for (SessionClavardageLocale s : this.sessions.values()) { System.out.print(s); } } @@ -85,7 +81,7 @@ public class gestionnaireClavardage implements Runnable{ Socket ssocket = this.requestServer.accept(); System.out.print("Données reçues sur le serveur de " + gn.getId() + "\n"); - for (SessionClavardage s : this.sessions) System.out.print(s); + for (SessionClavardageLocale s : this.sessions.values()) System.out.print(s); TCPServerThread client = new TCPServerThread(ssocket,false); String idClient = null; @@ -98,17 +94,14 @@ public class gestionnaireClavardage implements Runnable{ Thread t = new Thread(client); t.start(); - int i = 0; - while (idClient != null && i= this.sessions.size()) { + else if (this.sessions.get(idClient) == null) { //Il n'existe pas encore de session entre les deux utilisateurs System.out.print("Nouvelle session sur le serveur de " + gn.getId() + "\n"); TCPClient clientEnvoi = new TCPClient(client.getAdresseCible(), PORT_REQUETE_NOUVELLE_SESSION + Integer.parseInt(idClient)); - SessionClavardage session = new SessionClavardage(gn.getId(), idClient, clientEnvoi, client); - this.sessions.add(session); + SessionClavardageLocale session = new SessionClavardageLocale(gn.getId(), idClient, clientEnvoi, client); + this.sessions.put(idClient, session); clientEnvoi.send(gn.getId()+"\n"); System.out.print("Fin de la configuration de " + gn.getId() + "\n"); System.out.println("Il y a actuellement " + sessions.size() + " session(s) ouverte(s)."); @@ -125,10 +118,10 @@ public class gestionnaireClavardage implements Runnable{ } }); } - else if (this.sessions.get(i).getClientReception() == null) { + else if (this.sessions.get(idClient).getClientReception() == null) { System.out.print("Suite de la configuration sur le serveur de " + gn.getId() + "\n"); //il existe une session entre les deux utilisateurs, mais la phase de configuration n'est pas terminée - this.sessions.get(i).setClientReception(client); + this.sessions.get(idClient).setClientReception(client); System.out.print("Fin de la configuration de " + gn.getId() + "\n"); System.out.println("Il y a actuellement " + sessions.size() + " session(s) ouverte(s)."); } diff --git a/Projet_POO/src/clavardage/SessionClavardage.java b/Projet_POO/src/clavardage/SessionClavardage.java index fd07769..f833c33 100644 --- a/Projet_POO/src/clavardage/SessionClavardage.java +++ b/Projet_POO/src/clavardage/SessionClavardage.java @@ -1,38 +1,32 @@ package clavardage; -import reseau.*; +import java.beans.PropertyChangeListener; +import java.io.IOException; +import java.util.ArrayList; -public class SessionClavardage { +import data.Message; + +public abstract class SessionClavardage { private String idSource = null; private String idDestination = null; - private TCPClient clientEmission = null; - private TCPClient clientReception = null; - - public SessionClavardage(String idSource, String idDestination, TCPClient clientEmission, TCPClient clientReception) { + private boolean remote = false; + + public SessionClavardage(String idSource, String idDestination) { this.idSource = idSource; this.idDestination = idDestination; - this.clientEmission = clientEmission; - this.clientReception = clientReception; } - public SessionClavardage(String idSource, String idDestination, TCPClient clientReception) { - this.idSource = idSource; - this.idDestination = idDestination; - this.clientReception = clientReception; - } + public abstract ArrayList getNewMessages (); - public void send(String message) { - this.clientEmission.send(message); - } + public abstract void sendObject(Message message) throws IOException; - public void stop() { - if (this.clientEmission != null) this.clientEmission.stop(); - if (this.clientReception != null) this.clientReception.stop(); - } + public abstract void stop(); + + public abstract void addPropertyChangeListener(PropertyChangeListener p); + public abstract void removePropertyChangeListener(PropertyChangeListener p); public String toString() { - return "Session entre " + this.idSource + " à l'adresse " + this.clientEmission.getAdresseSource() - + ", et " + this.idDestination + " à l'adresse " + this.clientEmission.getAdresseCible() + "\n"; + return "Session entre " + "this.idSource" + " et " + this.idDestination + "\n"; } public String getIdSource() { @@ -43,15 +37,8 @@ public class SessionClavardage { return this.idDestination; } - public TCPClient getClientReception() { - return this.clientReception; + public boolean isRemote() { + return this.remote; } - - public void setClientReception(TCPClient client) { - this.clientReception = client; - } - - //public void run() { - //} } diff --git a/Projet_POO/src/clavardage/SessionClavardageDistante.java b/Projet_POO/src/clavardage/SessionClavardageDistante.java new file mode 100644 index 0000000..cba7adf --- /dev/null +++ b/Projet_POO/src/clavardage/SessionClavardageDistante.java @@ -0,0 +1,69 @@ +package clavardage; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.IOException; +import java.util.ArrayList; +import java.util.concurrent.ConcurrentLinkedQueue; + +import data.Message; + +public class SessionClavardageDistante extends SessionClavardage{ + private Message lastMessage = null; + private ConcurrentLinkedQueue messageQueue = new ConcurrentLinkedQueue (); + protected PropertyChangeSupport support; + + + public SessionClavardageDistante(String idSource, String idDestination) { + super(idSource, idDestination); + this.support = new PropertyChangeSupport(this); + } + + public void addPropertyChangeListener(PropertyChangeListener pcl) { + support.addPropertyChangeListener(pcl); + } + + public void removePropertyChangeListener(PropertyChangeListener pcl) { + support.removePropertyChangeListener(pcl); + } + + //TODO qui n'a rien a faire ici, faire en sorte que la mise en bdd qui a lieu lors de l'envoie se fasse sur un autre thread + + public void send(String message) throws IOException { + EnvoiMessageDistance.envoiMessage("message", this.getIdSource(), this.getIdDestination(), message); + } + + public void sendObject(Message message) throws IOException { + EnvoiMessageDistance.envoiMessage(message.getType(), message.getSender(), message.getRecipient(), message.getBody()); + } + + public void stop() { + try { + EnvoiMessageDistance.envoiMessage("command", this.getIdSource(), this.getIdDestination(), "stopSession"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public synchronized void addMessage(Message msg) { + this.messageQueue.add(msg); + this.support.firePropertyChange("lastMessage", this.lastMessage, msg); + this.lastMessage = msg; + } + + public synchronized ArrayList getNewMessages() { + + ArrayList msgList = new ArrayList (); + while (!this.messageQueue.isEmpty()) { + msgList.add(messageQueue.poll()); + } + + return msgList; + } + + public String toString() { + return "Session à distance entre " + this.getIdSource() + " et " + this.getIdDestination() + "\n"; + } + + + +} diff --git a/Projet_POO/src/clavardage/SessionClavardageLocale.java b/Projet_POO/src/clavardage/SessionClavardageLocale.java new file mode 100644 index 0000000..249782e --- /dev/null +++ b/Projet_POO/src/clavardage/SessionClavardageLocale.java @@ -0,0 +1,71 @@ +package clavardage; +import java.beans.PropertyChangeListener; +import java.io.IOException; +import java.util.ArrayList; + +import data.Message; +import reseau.*; + +public class SessionClavardageLocale extends SessionClavardage{ + private String idSource = null; + private String idDestination = null; + private TCPClient clientEmission = null; + private TCPClient clientReception = null; + + public SessionClavardageLocale(String idSource, String idDestination, TCPClient clientEmission, TCPClient clientReception) { + super(idSource, idDestination); + this.clientEmission = clientEmission; + this.clientReception = clientReception; + } + + public SessionClavardageLocale(String idSource, String idDestination, TCPClient clientReception) { + super(idSource, idDestination); + this.clientReception = clientReception; + } + + public void send(String message) { + this.clientEmission.send(message); + } + + public void stop() { + if (this.clientEmission != null) this.clientEmission.stop(); + if (this.clientReception != null) this.clientReception.stop(); + } + + @Override + public String toString() { + return "Session locale entre " + this.idSource + " à l'adresse " + this.clientEmission.getAdresseSource() + + ", et " + this.idDestination + " à l'adresse " + this.clientEmission.getAdresseCible() + "\n"; + } + + public TCPClient getClientReception() { + return this.clientReception; + } + + public ArrayList getNewMessages () { + TCPServerThread source = (TCPServerThread) this.clientReception; + return source.getNewMessages(); + } + + public void setClientReception(TCPClient client) { + this.clientReception = client; + } + + public void sendObject(Message message) throws IOException { + this.clientEmission.sendObject(message); + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener p) { + while (this.getClientReception() == null); //On attends que le client soit configuré + this.getClientReception().addPropertyChangeListener(p);; + + } + + public void removePropertyChangeListener(PropertyChangeListener p) { + if (this.getClientReception() != null) { + this.getClientReception().removePropertyChangeListener(p); + } + } + +} diff --git a/Projet_POO/src/clavardage/test.java b/Projet_POO/src/clavardage/test.java index 6c267c9..e543b36 100644 --- a/Projet_POO/src/clavardage/test.java +++ b/Projet_POO/src/clavardage/test.java @@ -1,6 +1,11 @@ package clavardage; import java.awt.EventQueue; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import liste.GestionnaireListeUtilisateur; @@ -15,10 +20,10 @@ public class test { } /* public static void main2(String[] args) { - ArrayList l = new ArrayList(); + ArrayList l = new ArrayList(); int i; for (i = 0; i < 15; i++) { - gestionnaireClavardage gc = new gestionnaireClavardage(i * 10 + 4, 5, "localhost"); + GestionnaireSessionsLocales gc = new GestionnaireSessionsLocales(i * 10 + 4, 5, "localhost"); l.add(gc); if (i>=1) gc.createSession(4); } @@ -48,7 +53,7 @@ public class test { } */ - public static void main(String[] args) { + /*public static void main(String[] args) { GestionnaireListeUtilisateur glu = GestionnaireListeUtilisateur.instance(); ArrayList list = new ArrayList(); list.add(new TypeListeUtilisateur("10", "User1", "localhost", "online")); @@ -58,10 +63,12 @@ public class test { gn.setId("11"); gn.setIp("localhost"); gn.setNom("User2"); - gestionnaireClavardage gc = gestionnaireClavardage.instance(); + GestionnaireSessionsLocales gc = GestionnaireSessionsLocales.instance(); gc.createSession("User1"); - } + }*/ + + } diff --git a/Projet_POO/src/data/AbstractData.java b/Projet_POO/src/data/AbstractData.java new file mode 100644 index 0000000..3ffea0b --- /dev/null +++ b/Projet_POO/src/data/AbstractData.java @@ -0,0 +1,23 @@ +package data; +import java.time.*; + +import javax.swing.JLabel; + +public abstract class AbstractData {//TODO Etendre Abstractdata à imagedata et filedata et utiliser ces objets au lieu des strings lors des échanges en local, comme pour le servlet + private Instant dateEnvoi; + private String expediteur; + private String data; + + public AbstractData(Instant dateEnvoi, String expediteur, String data) { + this.dateEnvoi = dateEnvoi; + this.expediteur = expediteur; + this.data = data; + } + + public String getData() { + return this.data; + } + + public abstract JLabel afficher(); + +} diff --git a/Projet_POO/src/data/Message.java b/Projet_POO/src/data/Message.java new file mode 100644 index 0000000..8344a4d --- /dev/null +++ b/Projet_POO/src/data/Message.java @@ -0,0 +1,71 @@ +package data; + +import java.io.Serializable; +import java.time.Instant; + +@SuppressWarnings("serial") +public class Message implements Serializable{ + private String type; + private String sender; + private String recipient; + private String body; + private Instant date; + + public Message() { + date = Instant.now(); + } + + + public void setType(String sender) { + this.type = sender; + } + + public void setSender(String sender) { + this.sender = sender; + } + + public void setRecipient(String recipient) { + this.recipient = recipient; + } + + public void setDate(Instant date) { + this.date = date; + } + + public void setBody(String body) { + this.body = body; + } + + public String getType() { + return this.type; + } + + public String getSender() { + return this.sender; + } + + public String getRecipient() { + return this.recipient; + } + + public String getBody() { + return this.body; + } + + public Instant getDate() { + return this.date; + } + + public String toString() { + if (this.type.equals("message")) { + return "Message from " + this.sender + " to "+ this.recipient + ": " + body; + } + else if (this.type.equals("command")) { + return "Command from " + this.sender + ": " + this.body; + } + else { + return this.type + " from " + this.sender + ": " + this.body; + } + + } +} diff --git a/Projet_POO/src/data/ServletResponse.java b/Projet_POO/src/data/ServletResponse.java new file mode 100644 index 0000000..5e2db65 --- /dev/null +++ b/Projet_POO/src/data/ServletResponse.java @@ -0,0 +1,33 @@ +package data; + +import java.util.ArrayList; + +public class ServletResponse { + + private int statusCode = 0; + private ArrayList messageList = null; + + public ServletResponse(int statusCode, ArrayList messageList) { + this.statusCode = statusCode; + this.messageList = messageList; + + } + + public int getStatusCode () { + return this.statusCode; + } + + public ArrayList getMessageList () { + return this.messageList; + } + + public String toString (){ + if (this.messageList != null) { + return "Status code: " + this.statusCode +", " + this.messageList.size() + " messages reçus."; + } + else { + return "Status code: " + this.statusCode; + } + } + +} diff --git a/Projet_POO/src/data/StringData.java b/Projet_POO/src/data/StringData.java new file mode 100644 index 0000000..2289baa --- /dev/null +++ b/Projet_POO/src/data/StringData.java @@ -0,0 +1,17 @@ +package data; + +import java.time.Instant; + +import javax.swing.JLabel; + +public class StringData extends AbstractData { + + public StringData(Instant dateEnvoi, String expediteur, String string) { + super(dateEnvoi, expediteur, string); + } + + public JLabel afficher() { + return new JLabel(this.getData()); + } + +} diff --git a/Projet_POO/src/defaut/Constantes.java b/Projet_POO/src/defaut/Constantes.java new file mode 100644 index 0000000..f8f55bb --- /dev/null +++ b/Projet_POO/src/defaut/Constantes.java @@ -0,0 +1,10 @@ +package defaut; + +public class Constantes { + + public static final String URL_SERVLET_MESSAGES = "https://srv-gei-tomcat.insa-toulouse.fr/Servlet_MBP/messageServlet"; + public static final String URL_SERVLET_PRESENCE = "https://srv-gei-tomcat.insa-toulouse.fr/Servlet_MBP/Servlet"; + + //Intervalle, en seconde, entre les requêtes envoyés périodiquement par chaque client au servlet + public static final float POLL_FREQUENCY = 1; +} diff --git a/Projet_POO/src/defaut/Main.java b/Projet_POO/src/defaut/Main.java index 1b0bcd9..bde5333 100644 --- a/Projet_POO/src/defaut/Main.java +++ b/Projet_POO/src/defaut/Main.java @@ -2,7 +2,6 @@ package defaut; import java.io.IOException; -import bdd.GestionnaireHistorique; import liste.GestionnaireListeUtilisateur; import ui.Login_RegisterUI; import servlet.Get; diff --git a/Projet_POO/src/reseau/TCPClient.java b/Projet_POO/src/reseau/TCPClient.java index 6a7ba58..8f45049 100644 --- a/Projet_POO/src/reseau/TCPClient.java +++ b/Projet_POO/src/reseau/TCPClient.java @@ -1,5 +1,8 @@ package reseau; import java.net.*; + +import data.Message; + import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.io.*; @@ -13,21 +16,22 @@ public class TCPClient { InetAddress adresseSource = null; int port = 0; Socket socket = null; - BufferedReader input = null; - PrintWriter output = null; + BufferedReader textInput = null; + PrintWriter textOutput = null; protected PropertyChangeSupport support; public TCPClient() { this.port = 0; this.socket = null; - this.input = null; - this.output = null; - support = new PropertyChangeSupport(this); + this.textInput = null; + this.textOutput = null; + this.support = new PropertyChangeSupport(this); } public TCPClient(String host, int port) { this.port = port; + try { this.socket = new Socket(host, port); } @@ -39,21 +43,23 @@ public class TCPClient { System.out.print("port= "+port+" host= "+host+"\n"); System.out.print("Could not create socket\n"); } + + this.adresseCible = socket.getInetAddress(); this.adresseSource = socket.getLocalAddress(); try { - this.input = new BufferedReader(new InputStreamReader(socket.getInputStream())); + this.textInput = new BufferedReader(new InputStreamReader(socket.getInputStream())); } catch (IOException e) { - System.out.print("Error while reading input stream\n"); + System.out.print("Error while reading textInput stream\n"); } try { - this.output = new PrintWriter(socket.getOutputStream(),true); + this.textOutput = new PrintWriter(socket.getOutputStream(),true); } catch (IOException e) { - System.out.print("Error while reading output stream\n"); + System.out.print("Error while reading textOutput stream\n"); } - support = new PropertyChangeSupport(this); + this.support = new PropertyChangeSupport(this); } @@ -63,29 +69,43 @@ public class TCPClient { this.adresseCible = socket.getInetAddress(); this.adresseSource = socket.getLocalAddress(); try { - this.input = new BufferedReader(new InputStreamReader(socket.getInputStream())); + this.textInput = new BufferedReader(new InputStreamReader(socket.getInputStream())); } catch (IOException e) { - System.out.print("Error while reading input stream"); + System.out.print("Error while reading textInput stream"); } try { - this.output = new PrintWriter(socket.getOutputStream(),true); + this.textOutput = new PrintWriter(socket.getOutputStream(),true); } catch (IOException e) { - System.out.print("Error while reading output stream"); + System.out.print("Error while reading textOutput stream"); } support = new PropertyChangeSupport(this); } public void send(String message) { //Le message doit se terminer par \n ? - this.output.print(message); - this.output.flush(); + this.textOutput.print(message); + this.textOutput.flush(); } public String receive() throws IOException{ String message = null; - message = input.readLine(); + message = textInput.readLine(); + + return message; + } + + public void sendObject(Message message) throws IOException { + ObjectOutputStream ooutput = new ObjectOutputStream(socket.getOutputStream()); + ooutput.writeObject(message); + this.textOutput.flush(); + } + + + public Message receiveObject() throws IOException, ClassNotFoundException{ + Message message = null; + message = (Message) new ObjectInputStream (socket.getInputStream()).readObject(); return message; } @@ -133,7 +153,8 @@ public class TCPClient { } public static void main(String[] args) throws IOException{ - TCPClient client = new TCPClient("localhost", 1999); + //TCPClient client = new TCPClient("LAPTOP-944OJJB9", 19999); + TCPClient client = new TCPClient("srv-gei-tomcat.insa-toulouse.fr", 19999); String message = "Bonjour.\n"; System.out.printf("Message envoyé: %s", message); client.send(message); diff --git a/Projet_POO/src/reseau/TCPServerThread.java b/Projet_POO/src/reseau/TCPServerThread.java index 9a256c1..a448976 100644 --- a/Projet_POO/src/reseau/TCPServerThread.java +++ b/Projet_POO/src/reseau/TCPServerThread.java @@ -1,25 +1,24 @@ package reseau; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.io.BufferedReader; +import java.io.EOFException; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; import java.net.Socket; -import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.List; +import java.util.LinkedList; +import data.Message; +import nom.GestionnaireNom; public class TCPServerThread extends TCPClient implements Runnable{ Thread thread; boolean terminé = false; - List messages = new ArrayList(); + private Message lastMessage = null; + private LinkedList messageQueue = new LinkedList (); public TCPServerThread(Socket socket, boolean start) { super(socket); + if (start) { thread = new Thread(this); thread.start(); @@ -34,6 +33,7 @@ public class TCPServerThread extends TCPClient implements Runnable{ } } + public void stop() { this.terminé = true; try { @@ -44,28 +44,45 @@ public class TCPServerThread extends TCPClient implements Runnable{ } } + + public synchronized void addMessage(Message msg) { + this.messageQueue.add(msg); + this.support.firePropertyChange("lastMessage", this.lastMessage, msg); + this.lastMessage = msg; + } + + public synchronized ArrayList getNewMessages() { + + ArrayList msgList = new ArrayList (); + while (!this.messageQueue.isEmpty()) { + msgList.add(messageQueue.poll()); + } + + return msgList; + } - public void setMessages(String message) { - List newMessages = new ArrayList(this.messages); - newMessages.add(message); - this.support.firePropertyChange("messages", this.messages, newMessages); - this.messages = newMessages; - } public void run() { while (!terminé) { try { - String message = this.receive(); - setMessages(message); - if (message != null) { - System.out.print("Status : " + terminé + ", message reçu : " + message + "\n"); - } - else { - //La connexion a été interrompue - this.terminé = true; - } + Message message = this.receiveObject(); + addMessage(message); + System.out.print("Terminé : " + terminé + ", message reçu : " + message + "\n"); } + + catch(EOFException e) { + //La connexion a été interrompue par l'autre client + this.terminé = true; + System.out.println("L'interruption de la connection a eu lieu"); + Message messageStop = new Message(); + messageStop.setType("command"); + messageStop.setBody("stopSession"); + messageStop.setSender(GestionnaireNom.instance().getId()); + addMessage(messageStop); + } + catch (IOException e) { + //La connexion est interrompue par notre client/une erreur this.terminé = true; System.out.print("Connection sur le port " + this.port + " vers " + this.adresseCible +" interrompue.\n"); } diff --git a/Projet_POO/src/servlet/Get.java b/Projet_POO/src/servlet/Get.java index 74e84fb..837246b 100644 --- a/Projet_POO/src/servlet/Get.java +++ b/Projet_POO/src/servlet/Get.java @@ -8,7 +8,7 @@ public class Get { //private static final String USER_AGENT = "Mozilla/5.0"; - private static final String GET_URL = liste.Constante.URL_SERVLET; + private static final String GET_URL = defaut.Constantes.URL_SERVLET_PRESENCE; diff --git a/Projet_POO/src/servlet/Post.java b/Projet_POO/src/servlet/Post.java index f9a390d..3f2c270 100644 --- a/Projet_POO/src/servlet/Post.java +++ b/Projet_POO/src/servlet/Post.java @@ -7,7 +7,7 @@ import java.net.URL; public class Post { - private static final String POST_URL = liste.Constante.URL_SERVLET; + private static final String POST_URL = defaut.Constantes.URL_SERVLET_PRESENCE; public static void sendPOST(String msg) throws IOException { // Publish cmd : change$$$id$$$nom$$$ip$$$dedans$$$statut URL obj = new URL(POST_URL); diff --git a/Projet_POO/src/ui/DiscussionUI.java b/Projet_POO/src/ui/DiscussionUI.java index 884bdec..4389ba0 100644 --- a/Projet_POO/src/ui/DiscussionUI.java +++ b/Projet_POO/src/ui/DiscussionUI.java @@ -1,10 +1,6 @@ package ui; -import java.awt.BorderLayout; -import java.awt.EventQueue; - import javax.swing.JFrame; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; @@ -17,10 +13,11 @@ import javax.swing.JButton; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.util.List; +import java.io.IOException; +import java.util.ArrayList; import java.awt.event.ActionEvent; -import javax.swing.JScrollBar; import clavardage.*; +import data.Message; import nom.GestionnaireNom; public class DiscussionUI extends JFrame implements PropertyChangeListener{ @@ -30,6 +27,7 @@ public class DiscussionUI extends JFrame implements PropertyChangeListener{ private JTextArea historicField; private SessionClavardage session; + /** * Launch the application. */ @@ -48,36 +46,51 @@ public class DiscussionUI extends JFrame implements PropertyChangeListener{ */ - public void setSession(SessionClavardage session) { + public void setSession(SessionClavardageLocale session) { this.session = session; } public void propertyChange(PropertyChangeEvent evt) { - List list = ((List) evt.getNewValue()); - String message = list.get(list.size()-1); - if (message != null) { - historicField.setText(historicField.getText() + message + "\n"); - } - else - { - historicField.setText(historicField.getText() + GestionnaireNom.instance().nomFromId(session.getIdDestination()) + " s'est déconnecté(e).\n"); - this.finDeSession(); + ArrayList list = session.getNewMessages(); + for (Message msg : list) { + if (msg.getType().equals("command") && msg.getBody().equals("stopSession")) { + historicField.setText(historicField.getText() + GestionnaireNom.instance().nomFromId(session.getIdDestination()) + " s'est déconnecté(e).\n"); + this.finDeSession(); + } + else + { + System.out.print(msg); + String message = GestionnaireNom.instance().nomFromId(msg.getSender()) + ": " + msg.getBody(); + historicField.setText(historicField.getText() + message + "\n"); + + } } } public void finDeSession() { - gestionnaireClavardage.instance().deleteSession(session); + this.session.removePropertyChangeListener(this); //On arrête d'écouter les messages provenant du client en face + GestionnaireSessionsLocales.instance().deleteSession(session); this.setSession(null); System.out.println(this.session); } private void sendMessage() { - String message = textField.getText(); - if (!message.isEmpty() && this.session != null) { + Message message = new Message(); + message.setType("message"); + message.setBody(textField.getText()); + if (!message.getBody().isEmpty() && this.session != null) { + + message.setSender(this.session.getIdSource()); + message.setRecipient(this.session.getIdDestination()); textField.setText(""); - historicField.append(GestionnaireNom.instance().nomFromId(session.getIdSource()) +": " + message + "\n"); - session.send(GestionnaireNom.instance().nomFromId(session.getIdSource()) + ": " + message+"\n"); - GestionnaireHistorique.instance().ajouter(this.session.getIdSource(), this.session.getIdDestination(), this.session.getIdSource(), message); + historicField.append(GestionnaireNom.instance().nomFromId(message.getSender()) +": " + message.getBody() + "\n"); + //session.send(GestionnaireNom.instance().nomFromId(session.getIdSource()) + ": " + message+"\n"); + try { + session.sendObject(message); + } catch (IOException e) { + System.out.println("Echec lors de l'envoi de l'objet message."); + } + GestionnaireHistorique.instance().ajouter(this.session.getIdSource(), this.session.getIdDestination(), this.session.getIdSource(), message.getBody()); } } @@ -89,10 +102,8 @@ public class DiscussionUI extends JFrame implements PropertyChangeListener{ */ public DiscussionUI(SessionClavardage session) { this.session = session; - - while (this.session.getClientReception() == null); //On attends que le client soit configuré - this.session.getClientReception().addPropertyChangeListener(this);; - + this.session.addPropertyChangeListener(this); + setTitle("Discussion"); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); diff --git a/Projet_POO/src/ui/ListUI.java b/Projet_POO/src/ui/ListUI.java index eacdb7e..fb41e7f 100644 --- a/Projet_POO/src/ui/ListUI.java +++ b/Projet_POO/src/ui/ListUI.java @@ -1,10 +1,7 @@ package ui; -import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; -import java.awt.EventQueue; - import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; @@ -23,7 +20,8 @@ import java.awt.event.ActionEvent; import java.util.ArrayList; -import clavardage.gestionnaireClavardage; +import clavardage.GestionnaireSessionsDistantes; +import clavardage.GestionnaireSessionsLocales; import liste.GestionnaireListeUtilisateur; import nom.GestionnaireNom; import servlet.Post; @@ -252,16 +250,32 @@ public class ListUI extends JFrame implements Runnable{ try{ if (list.getSelectedValue() != null) { if(!list.getSelectedValue().statut.equals("invisible")) { + //TODO Que faire si le nom change entre temps ? String nom = list.getSelectedValue().nom; - gestionnaireClavardage gc = gestionnaireClavardage.instance(); - gc.createSession(nom); + String statut = null; + ArrayList listeUtilisateur = GestionnaireListeUtilisateur.instance().getListeUtilisateur(); + for (TypeListeUtilisateur user : listeUtilisateur) { + if (user.nom.equals(nom)) { + statut = user.statut; + } + } + + if (GestionnaireNom.instance().getDansReseau() && statut.equals("true")) { + GestionnaireSessionsLocales gc = GestionnaireSessionsLocales.instance(); + gc.createSession(nom); + } + else { + GestionnaireSessionsDistantes gc = GestionnaireSessionsDistantes.instance(); + gc.createSession(nom, true); + } } } - }catch (Exception e) { - System.out.println("Erreur : connect ListUI"); - e.printStackTrace(); - } + } + catch (Exception e) { + System.out.println("Erreur : connect ListUI"); + e.printStackTrace(); + } } diff --git a/Projet_POO/src/ui/Login_RegisterUI.java b/Projet_POO/src/ui/Login_RegisterUI.java index 52693f1..853dd44 100644 --- a/Projet_POO/src/ui/Login_RegisterUI.java +++ b/Projet_POO/src/ui/Login_RegisterUI.java @@ -1,8 +1,6 @@ package ui; import java.awt.Color; -import java.awt.EventQueue; - import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JPasswordField; @@ -29,7 +27,9 @@ import java.sql.Connection; import java.sql.PreparedStatement; import bdd.Liaison; -import clavardage.gestionnaireClavardage; +import clavardage.GestionnaireMessagesDistants; +import clavardage.GestionnaireSessionsDistantes; +import clavardage.GestionnaireSessionsLocales; import nom.GestionnaireNom; import javax.swing.JCheckBox; @@ -232,7 +232,7 @@ public class Login_RegisterUI extends JFrame implements Runnable{ if( pwd.equals("admin") || id.equals("0") ) { //remplaver || par && -> facilite debug //TODO ( à remplacer par BDD après ) GestionnaireNom.instance().setId(id); - gestionnaireClavardage.instance(); //Init(gestionnaireClavardage) + GestionnaireSessionsLocales.instance(); //Init(GestionnaireSessionsLocales) dispose(); @@ -275,7 +275,11 @@ public class Login_RegisterUI extends JFrame implements Runnable{ if(rs.next()) { System.out.println("BDD SUCCESS"); GestionnaireNom.instance().setId(id); - gestionnaireClavardage.instance(); //Init(gestionnaireClavardage) + + //Instantiation des gestionnaires + GestionnaireSessionsLocales.instance(); + GestionnaireSessionsDistantes.instance(); + GestionnaireMessagesDistants.instance(); dispose(); diff --git a/Projet_POO/src/ui/NomUI.java b/Projet_POO/src/ui/NomUI.java index fd748b7..017dd03 100644 --- a/Projet_POO/src/ui/NomUI.java +++ b/Projet_POO/src/ui/NomUI.java @@ -1,7 +1,5 @@ package ui; -import java.awt.BorderLayout; -import java.awt.EventQueue; import java.awt.Toolkit; import java.awt.Dimension; @@ -69,7 +67,7 @@ public class NomUI extends JFrame implements Runnable{ //Operation par defaut setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - //dimennsion + //dimension setBounds(100, 100, 450, 300); setAlwaysOnTop(true);