src/main/java/de/unixwork/im/Xmpp.java

changeset 0
f3095cda599e
child 1
42d0d099492b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/de/unixwork/im/Xmpp.java	Wed Dec 25 21:49:48 2024 +0100
@@ -0,0 +1,144 @@
+
+package de.unixwork.im;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.jivesoftware.smack.ConnectionConfiguration;
+import org.jivesoftware.smack.SmackException;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.MessageWithBodiesFilter;
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.packet.MessageBuilder;
+import org.jivesoftware.smack.roster.Roster;
+import org.jivesoftware.smack.roster.RosterEntry;
+import org.jivesoftware.smack.tcp.XMPPTCPConnection;
+import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
+import org.jxmpp.stringprep.XmppStringprepException;
+
+public class Xmpp extends Thread {
+    private final XMPPTCPConnectionConfiguration config;
+    
+    private XMPPTCPConnection connection = null;
+    
+    // BlockingQueue for event-driven communication
+    private final BlockingQueue<XmppEvent> eventQueue = new LinkedBlockingQueue<>();
+    
+    public Xmpp(XMPPTCPConnectionConfiguration xmppConfig) {
+        config = xmppConfig;
+    }
+    
+    // Method to send a message (this will be called from another thread)
+    public void sendMessage(String to, String message, boolean encrypted) {
+        try {
+            XmppMessage event = new XmppMessage(to, message, encrypted);
+            eventQueue.put(event);  // Block if the queue is full
+        } catch (InterruptedException e) {
+            Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, "Error adding event to queue", e);
+        }
+    }
+    
+    private void connect() throws SmackException, IOException, XMPPException, InterruptedException {
+        connection = new XMPPTCPConnection(config);
+        connection.setUseStreamManagement(false);
+        connection.connect();
+        connection.login();
+        
+    }
+    
+    public List<RosterEntry> getRosterItems() throws SmackException.NotLoggedInException, SmackException.NotConnectedException, InterruptedException {
+        try {
+            // Ensure we are connected
+            if (connection != null && connection.isConnected()) {
+                // Get the roster instance
+                Roster roster = Roster.getInstanceFor(connection);
+                
+                // Fetch all roster entries (contacts)
+                roster.reload();
+                
+                // Add all roster entries to the list
+                ArrayList<RosterEntry> rosterList = new ArrayList<>(16);
+                roster.getEntries().forEach(entry -> rosterList.add(entry));
+
+                // Optionally, print the list to verify
+                System.out.println("Roster List: ");
+                for (RosterEntry entry : rosterList) {
+                    System.out.println("Contact: " + entry.getUser());
+                }
+                
+                return rosterList;
+            } else {
+                System.out.println("Not connected to XMPP server.");
+            }
+        } catch (SmackException e) {
+            Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, "Error getting roster items", e);
+        }
+        
+        return null;
+    }
+    
+    @Override
+    public void run() {
+        try {
+            connect();
+            connection.addAsyncStanzaListener((stanza -> {
+                        var jid = stanza.getFrom();
+                        if(jid != null) {
+                            String body = ((Message)stanza).getBody();
+                            App.getInstance().dispatchMessage(jid, body, true);
+                        }
+                    }), MessageWithBodiesFilter.INSTANCE);            
+            List<RosterEntry> roster = getRosterItems();
+            if(roster != null) {
+                App.getInstance().setContacts(roster);
+            }
+            
+            while (true) {
+                // Wait for an event (message to send)
+                XmppEvent event = eventQueue.take();  // This will block until an event is available
+                event.exec(this, connection);
+            }
+        } catch (SmackException ex) {
+            Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, null, ex);
+        } catch (IOException ex) {
+            Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, null, ex);
+        } catch (XMPPException ex) {
+            Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, null, ex);
+        } catch (InterruptedException ex) {
+            Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+}
+
+class XmppMessage implements XmppEvent {
+    String to;
+    String message;
+    boolean encrypted;
+    
+    XmppMessage(String to, String message, boolean encrypted) {
+        this.to = to;
+        this.message = message;
+        this.encrypted = encrypted;
+    }
+    
+    public void exec(Xmpp xmpp, XMPPTCPConnection conn) {
+        final Message msg;
+        try {
+            msg = MessageBuilder.buildMessage()
+                    .to(to)
+                    .setBody(message)
+                    .build();
+            conn.sendStanza(msg);
+        } catch (XmppStringprepException ex) {
+            Logger.getLogger(XmppMessage.class.getName()).log(Level.SEVERE, null, ex);
+        } catch (SmackException.NotConnectedException ex) {
+            Logger.getLogger(XmppMessage.class.getName()).log(Level.SEVERE, null, ex);
+        } catch (InterruptedException ex) {
+            Logger.getLogger(XmppMessage.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+}
\ No newline at end of file

mercurial