diff --git a/pitiupi.mpChat/.idea/.gitignore b/pitiupi.mpChat/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/pitiupi.mpChat/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/pitiupi.mpChat/.idea/misc.xml b/pitiupi.mpChat/.idea/misc.xml new file mode 100644 index 0000000..8547fc5 --- /dev/null +++ b/pitiupi.mpChat/.idea/misc.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/pitiupi.mpChat/.idea/modules.xml b/pitiupi.mpChat/.idea/modules.xml new file mode 100644 index 0000000..93aa0d1 --- /dev/null +++ b/pitiupi.mpChat/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/pitiupi.mpChat/.idea/vcs.xml b/pitiupi.mpChat/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/pitiupi.mpChat/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pitiupi.mpChat/out/GUI/ChatMenu.class b/pitiupi.mpChat/out/GUI/ChatMenu.class deleted file mode 100644 index c0ab65b..0000000 Binary files a/pitiupi.mpChat/out/GUI/ChatMenu.class and /dev/null differ diff --git a/pitiupi.mpChat/out/GUI/ChatWindow.class b/pitiupi.mpChat/out/GUI/ChatWindow.class deleted file mode 100644 index 0a97f82..0000000 Binary files a/pitiupi.mpChat/out/GUI/ChatWindow.class and /dev/null differ diff --git a/pitiupi.mpChat/out/GUI/PrivateChatWindow.class b/pitiupi.mpChat/out/GUI/PrivateChatWindow.class deleted file mode 100644 index 0d7a074..0000000 Binary files a/pitiupi.mpChat/out/GUI/PrivateChatWindow.class and /dev/null differ diff --git a/pitiupi.mpChat/out/GUI/PublicChatWindow.class b/pitiupi.mpChat/out/GUI/PublicChatWindow.class deleted file mode 100644 index b8f8c03..0000000 Binary files a/pitiupi.mpChat/out/GUI/PublicChatWindow.class and /dev/null differ diff --git a/pitiupi.mpChat/out/GUI/SocketTestMenu.class b/pitiupi.mpChat/out/GUI/SocketTestMenu.class deleted file mode 100644 index 724eae7..0000000 Binary files a/pitiupi.mpChat/out/GUI/SocketTestMenu.class and /dev/null differ diff --git a/pitiupi.mpChat/out/GUI/SocketTestWindow.class b/pitiupi.mpChat/out/GUI/SocketTestWindow.class deleted file mode 100644 index b782ecd..0000000 Binary files a/pitiupi.mpChat/out/GUI/SocketTestWindow.class and /dev/null differ diff --git a/pitiupi.mpChat/out/META-INF/services/pitiupi.plugin.Plugin b/pitiupi.mpChat/out/META-INF/services/pitiupi.models.Plugin similarity index 100% rename from pitiupi.mpChat/out/META-INF/services/pitiupi.plugin.Plugin rename to pitiupi.mpChat/out/META-INF/services/pitiupi.models.Plugin diff --git a/pitiupi.mpChat/out/control/ChatController.class b/pitiupi.mpChat/out/control/ChatController.class deleted file mode 100644 index 864a1bb..0000000 Binary files a/pitiupi.mpChat/out/control/ChatController.class and /dev/null differ diff --git a/pitiupi.mpChat/out/net/MpChatMessage.class b/pitiupi.mpChat/out/net/MpChatMessage.class deleted file mode 100644 index 78047ae..0000000 Binary files a/pitiupi.mpChat/out/net/MpChatMessage.class and /dev/null differ diff --git a/pitiupi.mpChat/out/net/TestChatMessage.class b/pitiupi.mpChat/out/net/TestChatMessage.class deleted file mode 100644 index 02c09f3..0000000 Binary files a/pitiupi.mpChat/out/net/TestChatMessage.class and /dev/null differ diff --git a/pitiupi.mpChat/out/net/TestMessage.class b/pitiupi.mpChat/out/net/TestMessage.class deleted file mode 100644 index d472376..0000000 Binary files a/pitiupi.mpChat/out/net/TestMessage.class and /dev/null differ diff --git a/pitiupi.mpChat/out/plugin/MultiProtocolChat.class b/pitiupi.mpChat/out/plugin/MultiProtocolChat.class deleted file mode 100644 index 7ecd755..0000000 Binary files a/pitiupi.mpChat/out/plugin/MultiProtocolChat.class and /dev/null differ diff --git a/pitiupi.mpChat/out/plugin/SocketTest.class b/pitiupi.mpChat/out/plugin/SocketTest.class deleted file mode 100644 index 549bbe9..0000000 Binary files a/pitiupi.mpChat/out/plugin/SocketTest.class and /dev/null differ diff --git a/pitiupi.mpChat/out/plugin/TestChat.class b/pitiupi.mpChat/out/plugin/TestChat.class deleted file mode 100644 index 29ca5c3..0000000 Binary files a/pitiupi.mpChat/out/plugin/TestChat.class and /dev/null differ diff --git a/pitiupi.mpChat/src/GUI/ChatMenu.java b/pitiupi.mpChat/src/GUI/ChatMenu.java deleted file mode 100644 index 1881c6e..0000000 --- a/pitiupi.mpChat/src/GUI/ChatMenu.java +++ /dev/null @@ -1,40 +0,0 @@ -package GUI; - -import pitiupi.models.Menus.MenuCategory; -import pitiupi.models.Menus.MulticastMenus.MulticastSubMenu; -import plugin.MultiProtocolChat; - -import javax.swing.*; -import java.awt.*; - -public class ChatMenu extends MulticastSubMenu { - private final MultiProtocolChat multiProtocolChat; - - public ChatMenu(MultiProtocolChat multiProtocolChat) { - this.multiProtocolChat = multiProtocolChat; - this.setText("MP-Chat"); - - JMenuItem startPrivateChat = new JMenuItem("start Private Chat"); - startPrivateChat.addActionListener(e -> showPrivateChatDialog()); - this.add(startPrivateChat); - } - - public void newMenuItem(JMenuItem newMenuItem, ChatWindow chatWindow) { - newMenuItem.addActionListener(e -> chatWindow.setVisible(true)); - - this.add(newMenuItem); - } - - public void removeMenuItem(JMenuItem removeMenuItem) { - this.remove(removeMenuItem); - } - - private void showPrivateChatDialog() { - - } - - @Override - public String getText() { - return "MP-Chat"; - } -} diff --git a/pitiupi.mpChat/src/GUI/ChatWindow.java b/pitiupi.mpChat/src/GUI/ChatWindow.java deleted file mode 100644 index bca8e1c..0000000 --- a/pitiupi.mpChat/src/GUI/ChatWindow.java +++ /dev/null @@ -1,94 +0,0 @@ -package GUI; - -import net.MpChatMessage; -import pitiupi.control.ConnectionManager; - -import javax.swing.*; -import java.awt.*; -import java.net.InetAddress; -import java.net.UnknownHostException; - -public abstract class ChatWindow extends JFrame { - - protected final ConnectionManager connectionManager; - - private JTextArea receivedMessagesArea; - protected JTextField messageField; - - public ChatWindow(ConnectionManager connectionManager) { - this.connectionManager = connectionManager; - initComponents(); - } - - private void initComponents() { - setTitle("Socket Test"); - setSize(700, 500); - setLocationRelativeTo(null); - setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); - - JPanel mainPanel = new JPanel(new BorderLayout(10, 10)); - - mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - - initReceivedMessagesPanel(mainPanel); - initBottomPanel(mainPanel); - - setContentPane(mainPanel); - } - - private void initReceivedMessagesPanel(JPanel mainPanel) { - receivedMessagesArea = new JTextArea(); - receivedMessagesArea.setEditable(false); - receivedMessagesArea.setLineWrap(true); - receivedMessagesArea.setWrapStyleWord(true); - - JScrollPane messagesScrollPane = new JScrollPane(receivedMessagesArea); - - messagesScrollPane.setBorder(BorderFactory.createTitledBorder("Mensagens recebidas")); - - mainPanel.add(messagesScrollPane, BorderLayout.CENTER); - } - - private void initBottomPanel(JPanel mainPanel) { - messageField = new JTextField(); - - JPanel bottomPanel = new JPanel(new BorderLayout(10, 10)); - - bottomPanel.add(messageField, BorderLayout.CENTER); - - initButtons(bottomPanel); - - mainPanel.add(bottomPanel, BorderLayout.SOUTH); - } - - protected abstract void initButtons(JPanel bottomPanel); - - protected MpChatMessage createMessage(String tipoMensagem) { - try { - String nome = connectionManager.getUserName(); - String ip = InetAddress.getLocalHost().getHostAddress(); - String message = messageField.getText(); - - return new MpChatMessage(nome, ip, tipoMensagem, message); - - } catch (UnknownHostException e) { - throw new RuntimeException(e); - } - } - - public void receiveMessage(MpChatMessage msg) { - SwingUtilities.invokeLater(() -> { - String mensagem = String.format( - "[%s] %s (%s): %s%n", - msg.getTipoMensagem(), - msg.getNome(), - msg.getIp(), - msg.getMessage() - ); - - receivedMessagesArea.append(mensagem); - - receivedMessagesArea.setCaretPosition(receivedMessagesArea.getDocument().getLength()); - }); - } -} \ No newline at end of file diff --git a/pitiupi.mpChat/src/GUI/PublicChatMenu.java b/pitiupi.mpChat/src/GUI/MulticastMpChatMenu.java similarity index 66% rename from pitiupi.mpChat/src/GUI/PublicChatMenu.java rename to pitiupi.mpChat/src/GUI/MulticastMpChatMenu.java index aa1b18a..a068b1d 100644 --- a/pitiupi.mpChat/src/GUI/PublicChatMenu.java +++ b/pitiupi.mpChat/src/GUI/MulticastMpChatMenu.java @@ -2,10 +2,10 @@ package GUI; import pitiupi.models.Menus.MulticastMenus.MulticastActionMenu; -public class PublicChatMenu extends MulticastActionMenu { +public class MulticastMpChatMenu extends MulticastActionMenu { PublicChatWindow publicChatWindow; - PublicChatMenu(PublicChatWindow publicChatWindow) { + public MulticastMpChatMenu(PublicChatWindow publicChatWindow) { this.publicChatWindow = publicChatWindow; } @@ -14,8 +14,9 @@ public class PublicChatMenu extends MulticastActionMenu { publicChatWindow.setVisible(true); } + @Override public String getText() { - return ""; + return "MP-Chat"; } } diff --git a/pitiupi.mpChat/src/GUI/PrivateChatMenu.java b/pitiupi.mpChat/src/GUI/PrivateChatMenu.java deleted file mode 100644 index e57bc2f..0000000 --- a/pitiupi.mpChat/src/GUI/PrivateChatMenu.java +++ /dev/null @@ -1,38 +0,0 @@ -package GUI; - -import control.ChatController; -import pitiupi.models.Menus.UnicastMenus.UnicastActionMenu; -import pitiupi.models.User; -import plugin.MultiProtocolChat; - -import javax.swing.*; -import java.awt.*; -import java.net.InetAddress; - -public class PrivateChatMenu extends UnicastActionMenu { - PrivateChatWindow privateChatWindow; - private final MultiProtocolChat multiProtocolChat; - private final ChatController chatController; - - public PrivateChatMenu(PrivateChatWindow PrivateChatWindow, MultiProtocolChat multiProtocolChat, ChatController chatController) { - this.privateChatWindow = PrivateChatWindow; - this.multiProtocolChat = multiProtocolChat; - this.chatController = chatController; - } - - @Override - public void onClick(User user) { - if (multiProtocolChat.openConnection(user.getAddress()) - else errorLabel.setVisible(true); - - dialog.setContentPane(contentPanel); - dialog.pack(); - dialog.setLocationRelativeTo(SwingUtilities.getWindowAncestor(privateChatWindow)); - dialog.setVisible(true); - } - - @Override - public String getText() { - return "start Private Chat"; - } -} diff --git a/pitiupi.mpChat/src/GUI/PrivateChatWindow.java b/pitiupi.mpChat/src/GUI/PrivateChatWindow.java index ad60dc4..ff4e3d3 100644 --- a/pitiupi.mpChat/src/GUI/PrivateChatWindow.java +++ b/pitiupi.mpChat/src/GUI/PrivateChatWindow.java @@ -1,43 +1,122 @@ package GUI; import net.MpChatMessage; -import pitiupi.control.ConnectionManager; import pitiupi.net.tcp.TcpConnection; +import pitiupi.plugin.Pitiupi; import javax.swing.*; import java.awt.*; +import java.net.InetAddress; import java.util.logging.Level; import java.util.logging.Logger; -public class PrivateChatWindow extends ChatWindow { +public class PrivateChatWindow extends JFrame { + private final Pitiupi pitiupi; private final TcpConnection connection; - public PrivateChatWindow(ConnectionManager ConnectionManager, TcpConnection connection) { - super(ConnectionManager); - this.connection = connection; - } + private final JTextArea receivedMessagesArea; + private final JTextField messageField; + + public PrivateChatWindow( + Pitiupi pitiupi, + TcpConnection connection + ) { + this.pitiupi = pitiupi; + this.connection = connection; + + setTitle("Chat privado"); + setSize(700, 500); + setLocationRelativeTo(null); + setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + + JPanel mainPanel = new JPanel(new BorderLayout(10, 10)); + mainPanel.setBorder( + BorderFactory.createEmptyBorder(10, 10, 10, 10) + ); + + receivedMessagesArea = new JTextArea(); + receivedMessagesArea.setEditable(false); + receivedMessagesArea.setLineWrap(true); + receivedMessagesArea.setWrapStyleWord(true); + + JScrollPane messagesScrollPane = + new JScrollPane(receivedMessagesArea); + + messagesScrollPane.setBorder( + BorderFactory.createTitledBorder("Mensagens") + ); + + mainPanel.add( + messagesScrollPane, + BorderLayout.CENTER + ); + + JPanel bottomPanel = new JPanel( + new BorderLayout(10, 10) + ); + + messageField = new JTextField(); - @Override - protected void initButtons(JPanel bottomPanel) { JButton tcpButton = new JButton("TCP"); - tcpButton.addActionListener(e -> sendTCP()); - JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0)); + bottomPanel.add( + messageField, + BorderLayout.CENTER + ); - buttonsPanel.add(tcpButton); + bottomPanel.add( + tcpButton, + BorderLayout.EAST + ); - bottomPanel.add(buttonsPanel, BorderLayout.EAST); + mainPanel.add( + bottomPanel, + BorderLayout.SOUTH + ); + + setContentPane(mainPanel); } private void sendTCP() { try { - MpChatMessage msg = createMessage("TCP Private"); - connection.send(msg.toByteArray()); + String nome = pitiupi.getUserName(); + + MpChatMessage message = new MpChatMessage( + nome, + InetAddress.getLocalHost().getHostAddress(), + "TCP Private", + messageField.getText() + ); + + connection.send(message.toByteArray()); + receiveMessage(message); + + messageField.setText(""); } catch (Exception ex) { - Logger.getLogger(PrivateChatWindow.class.getName()).log(Level.SEVERE, null, ex); + Logger.getLogger( + PrivateChatWindow.class.getName() + ).log(Level.SEVERE, null, ex); } } -} + + public void receiveMessage(MpChatMessage message) { + SwingUtilities.invokeLater(() -> { + String texto = String.format( + "[%s] %s (%s): %s%n", + message.getTipoMensagem(), + message.getNome(), + message.getIp(), + message.getMessage() + ); + + receivedMessagesArea.append(texto); + + receivedMessagesArea.setCaretPosition( + receivedMessagesArea.getDocument().getLength() + ); + }); + } +} \ No newline at end of file diff --git a/pitiupi.mpChat/src/GUI/PublicChatWindow.java b/pitiupi.mpChat/src/GUI/PublicChatWindow.java index ff6967e..67cbafa 100644 --- a/pitiupi.mpChat/src/GUI/PublicChatWindow.java +++ b/pitiupi.mpChat/src/GUI/PublicChatWindow.java @@ -2,36 +2,95 @@ package GUI; import net.MpChatMessage; import pitiupi.control.ConnectionManager; +import pitiupi.plugin.Pitiupi; import javax.swing.*; +import javax.swing.text.BadLocationException; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; import java.awt.*; import java.net.InetAddress; import java.util.logging.Level; import java.util.logging.Logger; -public class PublicChatWindow extends ChatWindow { +public class PublicChatWindow extends JFrame { + private final Pitiupi pitiupi; + private JTextPane receivedMessagesArea; + private JTextField messageField; private JTextField ipField; - public PublicChatWindow(ConnectionManager connectionManager) { - super(connectionManager); + public PublicChatWindow(Pitiupi pitiupi) { + this.pitiupi = pitiupi; + + initComponents(); } - @Override - protected void initButtons(JPanel bottomPanel) { + private void initComponents() { + setTitle("Public Chat"); + setSize(700, 500); + setLocationRelativeTo(null); + setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + + JPanel mainPanel = new JPanel(new BorderLayout(10, 10)); + + mainPanel.setBorder( + BorderFactory.createEmptyBorder(10, 10, 10, 10) + ); + + initReceivedMessagesPanel(mainPanel); + initBottomPanel(mainPanel); + + setContentPane(mainPanel); + } + + private void initReceivedMessagesPanel(JPanel mainPanel) { + receivedMessagesArea = new JTextPane(); + + receivedMessagesArea.setEditable(false); + + JScrollPane messagesScrollPane = new JScrollPane(receivedMessagesArea); + + messagesScrollPane.setBorder( + BorderFactory.createTitledBorder("Mensagens recebidas") + ); + + mainPanel.add(messagesScrollPane, BorderLayout.CENTER); + } + + private void initBottomPanel(JPanel mainPanel) { + messageField = new JTextField(); + + JPanel bottomPanel = new JPanel( + new BorderLayout(10, 10) + ); + + bottomPanel.add(messageField, BorderLayout.CENTER); + initIpField(bottomPanel); initCommunicationButtons(bottomPanel); + + mainPanel.add(bottomPanel, BorderLayout.SOUTH); } private void initIpField(JPanel bottomPanel) { ipField = new JTextField(); ipField.setPreferredSize(new Dimension(130, 30)); - JPanel ipPanel = new JPanel(new BorderLayout(5, 5)); + JPanel ipPanel = new JPanel( + new BorderLayout(5, 5) + ); - ipPanel.add(new JLabel("IP destino:"), BorderLayout.WEST); + ipPanel.add( + new JLabel("IP destino:"), + BorderLayout.WEST + ); - ipPanel.add(ipField, BorderLayout.CENTER); + ipPanel.add( + ipField, + BorderLayout.CENTER + ); bottomPanel.add(ipPanel, BorderLayout.WEST); } @@ -45,13 +104,71 @@ public class PublicChatWindow extends ChatWindow { udpButton.addActionListener(e -> sendUDP()); multicastButton.addActionListener(e -> sendMulticast()); - JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0)); + JPanel buttonsPanel = new JPanel( + new FlowLayout(FlowLayout.RIGHT, 5, 0) + ); buttonsPanel.add(tcpButton); buttonsPanel.add(udpButton); buttonsPanel.add(multicastButton); - bottomPanel.add(buttonsPanel, BorderLayout.EAST); + bottomPanel.add( + buttonsPanel, + BorderLayout.EAST + ); + } + + private MpChatMessage createMessage(String tipoMensagem) { + try { + String nome = pitiupi.getUserName(); + String ip = InetAddress.getLocalHost().getHostAddress(); + String message = messageField.getText(); + + return new MpChatMessage( + nome, + ip, + tipoMensagem, + message + ); + + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + public void receiveMessage(MpChatMessage msg) { + SwingUtilities.invokeLater(() -> { + String mensagem = String.format( + "[%s] %s (%s): %s%n", + msg.getTipoMensagem(), + msg.getNome(), + msg.getIp(), + msg.getMessage() + ); + + StyledDocument document = receivedMessagesArea.getStyledDocument(); + + SimpleAttributeSet attributes = new SimpleAttributeSet(); + + if (msg.getTipoMensagem().equals("TCP Unicast") || msg.getTipoMensagem().equals("UDP Unicast")) { + StyleConstants.setForeground(attributes, new Color(128, 0, 128)); + } + + try { + document.insertString( + document.getLength(), + mensagem, + attributes + ); + + receivedMessagesArea.setCaretPosition( + document.getLength() + ); + + } catch (BadLocationException ex) { + Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex); + } + }); } private void sendTCP() { @@ -60,10 +177,13 @@ public class PublicChatWindow extends ChatWindow { InetAddress ip = InetAddress.getByName(ipField.getText()); - connectionManager.sendTcp(msg, ip); + pitiupi.sendTcp(msg, ip); + receiveMessage(msg); } catch (Exception ex) { - Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex); + Logger.getLogger( + PublicChatWindow.class.getName() + ).log(Level.SEVERE, null, ex); } } @@ -73,10 +193,13 @@ public class PublicChatWindow extends ChatWindow { InetAddress ip = InetAddress.getByName(ipField.getText()); - connectionManager.sendUdpUnicast(msg, ip); + pitiupi.sendUdpUnicast(msg, ip); + receiveMessage(msg); } catch (Exception ex) { - Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex); + Logger.getLogger( + PublicChatWindow.class.getName() + ).log(Level.SEVERE, null, ex); } } @@ -84,10 +207,12 @@ public class PublicChatWindow extends ChatWindow { try { MpChatMessage msg = createMessage("UDP Multicast"); - connectionManager.sendUdpMulticast(msg); + pitiupi.sendUdpMulticast(msg); } catch (Exception ex) { - Logger.getLogger(PublicChatWindow.class.getName()).log(Level.SEVERE, null, ex); + Logger.getLogger( + PublicChatWindow.class.getName() + ).log(Level.SEVERE, null, ex); } } } \ No newline at end of file diff --git a/pitiupi.mpChat/src/GUI/UnicastMpChatMenu.java b/pitiupi.mpChat/src/GUI/UnicastMpChatMenu.java new file mode 100644 index 0000000..e848440 --- /dev/null +++ b/pitiupi.mpChat/src/GUI/UnicastMpChatMenu.java @@ -0,0 +1,26 @@ +package GUI; + +import control.PrivateChatController; +import pitiupi.models.Menus.UnicastMenus.UnicastActionMenu; +import pitiupi.models.User; + +public class UnicastMpChatMenu extends UnicastActionMenu { + + private final PrivateChatController controller; + + public UnicastMpChatMenu( + PrivateChatController controller + ) { + this.controller = controller; + } + + @Override + public void onClick(User user) { + controller.openChat(user); + } + + @Override + public String getText() { + return "Start Private Chat"; + } +} \ No newline at end of file diff --git a/pitiupi.mpChat/src/control/PrivateChatController.java b/pitiupi.mpChat/src/control/PrivateChatController.java new file mode 100644 index 0000000..aad138a --- /dev/null +++ b/pitiupi.mpChat/src/control/PrivateChatController.java @@ -0,0 +1,116 @@ +package control; + +import GUI.PrivateChatWindow; +import net.MpChatMessage; +import pitiupi.models.User; +import pitiupi.net.tcp.TcpConnection; +import pitiupi.plugin.Pitiupi; +import plugin.MultiProtocolChat; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class PrivateChatController { + + private final Pitiupi pitiupi; + private final MultiProtocolChat multiProtocolChat; + + /* + * Relaciona o endereço do usuário à janela de chat. + */ + private final Map windows; + + /* + * Endereços para os quais uma conexão já foi solicitada, + * mas ainda não chegou. + */ + private final Set pendingConnections; + + public PrivateChatController( + Pitiupi pitiupi, + MultiProtocolChat multiProtocolChat + ) { + this.pitiupi = pitiupi; + this.multiProtocolChat = multiProtocolChat; + + this.windows = new HashMap<>(); + this.pendingConnections = new HashSet<>(); + } + + public void openChat(User user) { + String address = user.getAddress().getHostAddress(); + + PrivateChatWindow window = windows.get(address); + + /* + * Já existe uma janela para esse usuário. + */ + if (window != null) { + window.setVisible(true); + window.toFront(); + window.requestFocus(); + return; + } + + /* + * Já estamos esperando uma conexão para esse usuário. + */ + if (pendingConnections.contains(address)) { + return; + } + + /* + * Ainda não existe conexão. + */ + pendingConnections.add(address); + + multiProtocolChat.openConnection(address); + } + + public void receiveMessage(TcpConnection connection, MpChatMessage message) { + String address = connection.getAddress().toString(); + + PrivateChatWindow window = windows.get(address); + + if (window == null) { + return; + } + + window.receiveMessage(message); + } + + /** + * Deve ser chamado quando uma nova conexão privada chegar. + */ + public void connectionReceived(TcpConnection connection) { + String address = connection.getAddress().toString(); + + pendingConnections.remove(address); + + PrivateChatWindow window = new PrivateChatWindow( + pitiupi, + connection + ); + + windows.put(address, window); + + window.setVisible(true); + window.toFront(); + window.requestFocus(); + } + + /** + * Fecha a janela e remove o relacionamento. + */ + public void closeChat(TcpConnection connection) { + String address = connection.getAddress().toString(); + + PrivateChatWindow window = windows.remove(address); + + if (window != null) { + window.dispose(); + } + } +} \ No newline at end of file diff --git a/pitiupi.mpChat/src/plugin/MultiProtocolChat.java b/pitiupi.mpChat/src/plugin/MultiProtocolChat.java index a9999bd..bab8d2a 100644 --- a/pitiupi.mpChat/src/plugin/MultiProtocolChat.java +++ b/pitiupi.mpChat/src/plugin/MultiProtocolChat.java @@ -1,24 +1,29 @@ package plugin; -import GUI.ChatMenu; -import control.ChatController; +import GUI.MulticastMpChatMenu; +import GUI.PrivateChatWindow; +import GUI.PublicChatWindow; +import GUI.UnicastMpChatMenu; +import control.PrivateChatController; import net.MpChatMessage; -import pitiupi.control.ConnectionManager; -import pitiupi.control.GuiManager; +import pitiupi.models.Menus.MenuCategory; import pitiupi.models.Messages.Message; import pitiupi.net.tcp.TcpConnection; import pitiupi.models.Plugin; +import pitiupi.plugin.Pitiupi; import javax.swing.*; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.net.InetAddress; +import java.util.List; public class MultiProtocolChat extends Plugin { - ChatController chatController; - ConnectionManager connectionManager; - GuiManager guiManager; + Pitiupi pitiupi; + + PrivateChatController privateChatController; + PublicChatWindow publicChatWindow; @Override public String getName() { @@ -41,30 +46,37 @@ public class MultiProtocolChat extends Plugin { } @Override - public void createPlugin(ConnectionManager connectionManager, GuiManager guiManager) { - this.connectionManager = connectionManager; - this.guiManager = guiManager; + public void createPlugin(Pitiupi pitiupi) { + this.pitiupi = pitiupi; - ChatMenu chatMenu = new ChatMenu(this); - chatController = new ChatController(connectionManager, chatMenu); - guiManager.addMulticastMenu(chatMenu); + privateChatController = new PrivateChatController(pitiupi, this); + + publicChatWindow = new PublicChatWindow(pitiupi); + + MulticastMpChatMenu multicastMpChatMenu = new MulticastMpChatMenu(publicChatWindow); + UnicastMpChatMenu unicastMpChatMenu = new UnicastMpChatMenu(privateChatController); + + pitiupi.createMenu(MenuCategory.Social, multicastMpChatMenu); + pitiupi.createMenu(MenuCategory.Social, unicastMpChatMenu); } @Override - public Message getMessage() { - return new MpChatMessage(); + public List> getMessages() { + return List.of(MpChatMessage.class); } @Override - public void receiveMessage(byte[] message) { - MpChatMessage mpChatMessage = parseMessage(message); - chatController.receivePublic(mpChatMessage); + public void receiveMessage(Message message) { + if (message instanceof MpChatMessage mpChatMessage) { + publicChatWindow.receiveMessage(mpChatMessage); + } } + @Override public boolean receivePrivateConnection(TcpConnection connection) { SwingUtilities.invokeLater(() -> { - chatController.addChatWindow(connection); + privateChatController.connectionReceived(connection); }); return true; } @@ -72,25 +84,29 @@ public class MultiProtocolChat extends Plugin { @Override public boolean receiveBytes(TcpConnection connection, byte[] bytes) { MpChatMessage mpChatMessage = parseMessage(bytes); - chatController.receivePrivate(connection, mpChatMessage); + if (mpChatMessage == null) { + System.out.println("Invalid message received"); + return true; + } + else System.out.println(mpChatMessage.getMessage()); + + privateChatController.receiveMessage(connection, mpChatMessage); return true; } @Override public boolean onSocketClosed(TcpConnection connection) { - chatController.removeChatWindow(connection); + privateChatController.closeChat(connection); return true; } - public boolean openConnection(String ip) { + public void openConnection(String ip) { try { - connectionManager.connectPluginTcp(InetAddress.getByName(ip), getIdentifier(), getIdentifier()); - return true; + pitiupi.connectTcp(InetAddress.getByName(ip), getIdentifier(), getIdentifier()); } catch (Exception e) { System.out.println("Error opening connection: " + e.getMessage()); } - return false; } private MpChatMessage parseMessage(byte[] bytes) { diff --git a/pitiupi.screenCast/.idea/pitiupi.screenCast.iml b/pitiupi.screenCast/.idea/pitiupi.screenCast.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/pitiupi.screenCast/.idea/pitiupi.screenCast.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/pitiupi.screenCast/src/META-INF/services/pitiupi.plugin.Plugin b/pitiupi.screenCast/src/META-INF/services/pitiupi.models.Plugin similarity index 100% rename from pitiupi.screenCast/src/META-INF/services/pitiupi.plugin.Plugin rename to pitiupi.screenCast/src/META-INF/services/pitiupi.models.Plugin diff --git a/pitiupi/src/pitiupi/GUI/MenuBar.java b/pitiupi/src/pitiupi/GUI/MenuBar.java index c6c67c8..846dd10 100644 --- a/pitiupi/src/pitiupi/GUI/MenuBar.java +++ b/pitiupi/src/pitiupi/GUI/MenuBar.java @@ -111,7 +111,6 @@ public class MenuBar extends JMenuBar { } public void addPluginMenu(MenuCategory category, JMenuItem menu){ - System.out.println("addPluginMenu"); categories.get(category).add(menu); } } diff --git a/pitiupi/src/pitiupi/control/plugins/PluginManager.java b/pitiupi/src/pitiupi/control/plugins/PluginManager.java index ada270d..94cabf3 100644 --- a/pitiupi/src/pitiupi/control/plugins/PluginManager.java +++ b/pitiupi/src/pitiupi/control/plugins/PluginManager.java @@ -60,8 +60,9 @@ public class PluginManager { private Plugin getPlugin(String pluginId) { for (LoadedPlugin loadedPlugin : loadedPlugins) { - if (loadedPlugin.getPlugin().getIdentifier().equals(pluginId)) + if (loadedPlugin.getPlugin().getIdentifier().equals(pluginId)) { return loadedPlugin.getPlugin(); + } } return null; } @@ -79,7 +80,7 @@ public class PluginManager { plugin.receivePrivateConnection(connection); - return false; + return true; } public void handleDisconnection(TcpConnection connection, String receiverId) { @@ -115,7 +116,6 @@ public class PluginManager { ServiceLoader serviceLoader = ServiceLoader.load(Plugin.class, classLoader); for (Plugin plugin : serviceLoader) { - System.out.println("Loading: " + plugin.getName()); LoadedPlugin loadedPlugin = new LoadedPlugin(plugin, classLoader); plugin.createPlugin(connectionManager, guiManager); diff --git a/pitiupi/src/pitiupi/net/tcp/SocketTCP.java b/pitiupi/src/pitiupi/net/tcp/SocketTCP.java index 688f638..09c7d46 100644 --- a/pitiupi/src/pitiupi/net/tcp/SocketTCP.java +++ b/pitiupi/src/pitiupi/net/tcp/SocketTCP.java @@ -271,8 +271,9 @@ public class SocketTCP extends Thread { return; } - if (pluginManager.handleConnection(connection, connection.getReceiver())) + if (pluginManager.handleConnection(connection, connection.getReceiver())) { privateConnectionReceiver(connection); + } else { InfoMessage.sendSystemInfo( connection, @@ -336,7 +337,7 @@ public class SocketTCP extends Thread { * ao plugin destinatário. * *

Dados que não representam mensagens de controle são entregues - * diretamente ao {@link PrivateConnectionPlugin}. Mensagens de controle + * diretamente ao {@link pitiupi.models.Plugin}. Mensagens de controle * relacionadas ao encerramento ou a erros internos provocam a notificação * do plugin e o fechamento da conexão.

* diff --git a/pitiupi/src/pitiupi/net/tcp/TcpConnection.java b/pitiupi/src/pitiupi/net/tcp/TcpConnection.java index be7c0e4..d6cfb9d 100644 --- a/pitiupi/src/pitiupi/net/tcp/TcpConnection.java +++ b/pitiupi/src/pitiupi/net/tcp/TcpConnection.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.SocketException; +import java.util.Arrays; /** * Representa uma conexão TCP ativa com um peer remoto. @@ -77,6 +78,7 @@ public class TcpConnection { byte[] message = input.readNBytes(length); + if (message.length != length) { throw new IOException("Connection closed before receiving the complete message."); }