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

changeset 0
f3095cda599e
child 1
42d0d099492b
equal deleted inserted replaced
-1:000000000000 0:f3095cda599e
1
2 package de.unixwork.im;
3
4 import java.io.IOException;
5 import java.util.ArrayList;
6 import java.util.List;
7 import java.util.concurrent.BlockingQueue;
8 import java.util.concurrent.LinkedBlockingQueue;
9 import java.util.logging.Level;
10 import java.util.logging.Logger;
11 import org.jivesoftware.smack.ConnectionConfiguration;
12 import org.jivesoftware.smack.SmackException;
13 import org.jivesoftware.smack.XMPPException;
14 import org.jivesoftware.smack.filter.MessageWithBodiesFilter;
15 import org.jivesoftware.smack.packet.Message;
16 import org.jivesoftware.smack.packet.MessageBuilder;
17 import org.jivesoftware.smack.roster.Roster;
18 import org.jivesoftware.smack.roster.RosterEntry;
19 import org.jivesoftware.smack.tcp.XMPPTCPConnection;
20 import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
21 import org.jxmpp.stringprep.XmppStringprepException;
22
23 public class Xmpp extends Thread {
24 private final XMPPTCPConnectionConfiguration config;
25
26 private XMPPTCPConnection connection = null;
27
28 // BlockingQueue for event-driven communication
29 private final BlockingQueue<XmppEvent> eventQueue = new LinkedBlockingQueue<>();
30
31 public Xmpp(XMPPTCPConnectionConfiguration xmppConfig) {
32 config = xmppConfig;
33 }
34
35 // Method to send a message (this will be called from another thread)
36 public void sendMessage(String to, String message, boolean encrypted) {
37 try {
38 XmppMessage event = new XmppMessage(to, message, encrypted);
39 eventQueue.put(event); // Block if the queue is full
40 } catch (InterruptedException e) {
41 Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, "Error adding event to queue", e);
42 }
43 }
44
45 private void connect() throws SmackException, IOException, XMPPException, InterruptedException {
46 connection = new XMPPTCPConnection(config);
47 connection.setUseStreamManagement(false);
48 connection.connect();
49 connection.login();
50
51 }
52
53 public List<RosterEntry> getRosterItems() throws SmackException.NotLoggedInException, SmackException.NotConnectedException, InterruptedException {
54 try {
55 // Ensure we are connected
56 if (connection != null && connection.isConnected()) {
57 // Get the roster instance
58 Roster roster = Roster.getInstanceFor(connection);
59
60 // Fetch all roster entries (contacts)
61 roster.reload();
62
63 // Add all roster entries to the list
64 ArrayList<RosterEntry> rosterList = new ArrayList<>(16);
65 roster.getEntries().forEach(entry -> rosterList.add(entry));
66
67 // Optionally, print the list to verify
68 System.out.println("Roster List: ");
69 for (RosterEntry entry : rosterList) {
70 System.out.println("Contact: " + entry.getUser());
71 }
72
73 return rosterList;
74 } else {
75 System.out.println("Not connected to XMPP server.");
76 }
77 } catch (SmackException e) {
78 Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, "Error getting roster items", e);
79 }
80
81 return null;
82 }
83
84 @Override
85 public void run() {
86 try {
87 connect();
88 connection.addAsyncStanzaListener((stanza -> {
89 var jid = stanza.getFrom();
90 if(jid != null) {
91 String body = ((Message)stanza).getBody();
92 App.getInstance().dispatchMessage(jid, body, true);
93 }
94 }), MessageWithBodiesFilter.INSTANCE);
95 List<RosterEntry> roster = getRosterItems();
96 if(roster != null) {
97 App.getInstance().setContacts(roster);
98 }
99
100 while (true) {
101 // Wait for an event (message to send)
102 XmppEvent event = eventQueue.take(); // This will block until an event is available
103 event.exec(this, connection);
104 }
105 } catch (SmackException ex) {
106 Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, null, ex);
107 } catch (IOException ex) {
108 Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, null, ex);
109 } catch (XMPPException ex) {
110 Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, null, ex);
111 } catch (InterruptedException ex) {
112 Logger.getLogger(Xmpp.class.getName()).log(Level.SEVERE, null, ex);
113 }
114 }
115 }
116
117 class XmppMessage implements XmppEvent {
118 String to;
119 String message;
120 boolean encrypted;
121
122 XmppMessage(String to, String message, boolean encrypted) {
123 this.to = to;
124 this.message = message;
125 this.encrypted = encrypted;
126 }
127
128 public void exec(Xmpp xmpp, XMPPTCPConnection conn) {
129 final Message msg;
130 try {
131 msg = MessageBuilder.buildMessage()
132 .to(to)
133 .setBody(message)
134 .build();
135 conn.sendStanza(msg);
136 } catch (XmppStringprepException ex) {
137 Logger.getLogger(XmppMessage.class.getName()).log(Level.SEVERE, null, ex);
138 } catch (SmackException.NotConnectedException ex) {
139 Logger.getLogger(XmppMessage.class.getName()).log(Level.SEVERE, null, ex);
140 } catch (InterruptedException ex) {
141 Logger.getLogger(XmppMessage.class.getName()).log(Level.SEVERE, null, ex);
142 }
143 }
144 }

mercurial