1 | /* |
---|
2 | * Jeti, a Java Jabber client, Copyright (C) 2003 E.S. de Boer |
---|
3 | * |
---|
4 | * This program is free software; you can redistribute it and/or modify |
---|
5 | * it under the terms of the GNU General Public License as published by |
---|
6 | * the Free Software Foundation; either version 2 of the License, or |
---|
7 | * (at your option) any later version. |
---|
8 | * |
---|
9 | * This program is distributed in the hope that it will be useful, |
---|
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | * GNU General Public License for more details. |
---|
13 | * |
---|
14 | * You should have received a copy of the GNU General Public License |
---|
15 | * along with this program; if not, write to the Free Software |
---|
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
17 | * |
---|
18 | * For questions, comments etc, |
---|
19 | * use the website at http://jeti.jabberstudio.org |
---|
20 | * or mail me at jeti@jabber.org |
---|
21 | */ |
---|
22 | |
---|
23 | package nu.fw.jeti.backend; |
---|
24 | |
---|
25 | import java.text.MessageFormat; |
---|
26 | import java.util.Iterator; |
---|
27 | |
---|
28 | import javax.swing.JOptionPane; |
---|
29 | |
---|
30 | import nu.fw.jeti.events.IQResultListener; |
---|
31 | import nu.fw.jeti.events.MessageEventListener; |
---|
32 | import nu.fw.jeti.events.MessageListener; |
---|
33 | import nu.fw.jeti.events.PresenceListener; |
---|
34 | import nu.fw.jeti.jabber.Backend; |
---|
35 | import nu.fw.jeti.jabber.JID; |
---|
36 | import nu.fw.jeti.jabber.JIDStatus; |
---|
37 | import nu.fw.jeti.jabber.elements.*; |
---|
38 | import nu.fw.jeti.util.I18N; |
---|
39 | import nu.fw.jeti.util.Log; |
---|
40 | import nu.fw.jeti.util.Popups; |
---|
41 | import nu.fw.jeti.util.ServerExpresso; |
---|
42 | |
---|
43 | |
---|
44 | /** |
---|
45 | * distributes the xml packets received from the server |
---|
46 | * @author E.S. de Boer |
---|
47 | */ |
---|
48 | |
---|
49 | public class Jabber implements PacketReceiver |
---|
50 | { |
---|
51 | private Backend backend; |
---|
52 | private Discovery discovery; |
---|
53 | private IQTimerQueue iqTimerQueue; |
---|
54 | private OwnCapabilities capabilities; |
---|
55 | public String NameContact; |
---|
56 | public String NameOrganization; |
---|
57 | |
---|
58 | public Jabber(Backend backend,OwnCapabilities capabilities, Discovery browse, IQTimerQueue timerQueue) |
---|
59 | { |
---|
60 | iqTimerQueue = timerQueue; |
---|
61 | this.backend = backend; |
---|
62 | this.discovery = browse; |
---|
63 | this.capabilities = capabilities; |
---|
64 | } |
---|
65 | |
---|
66 | public void receivePackets(Packet packet) |
---|
67 | { |
---|
68 | if (packet instanceof StreamError) backend.streamError((StreamError)packet); |
---|
69 | if (packet instanceof InfoQuery) infoQuery((InfoQuery) packet); |
---|
70 | else if (packet instanceof Message) message((Message) packet); |
---|
71 | else if (packet instanceof Presence) presence((Presence) packet); |
---|
72 | } |
---|
73 | |
---|
74 | /*------------------------------InfoQuery------------------------*/ |
---|
75 | private void infoQuery(InfoQuery infoQuery) |
---|
76 | { |
---|
77 | IQResultListener iqrListener = iqTimerQueue.getInfoQueryListener(infoQuery.getID()); |
---|
78 | if(iqrListener!=null) |
---|
79 | { |
---|
80 | iqrListener.iqResult(infoQuery); |
---|
81 | } |
---|
82 | else |
---|
83 | { |
---|
84 | if (infoQuery.hasExtensions()) |
---|
85 | { |
---|
86 | IQExtension extension = infoQuery.getIQExtension(); |
---|
87 | if (extension instanceof IQDiscoInfo) |
---|
88 | {//move to execute |
---|
89 | if (infoQuery.getType().equals("result")) |
---|
90 | { |
---|
91 | discovery.discoveryInfoResult(infoQuery.getFrom(), infoQuery.getID(), (IQDiscoInfo) extension); |
---|
92 | } |
---|
93 | else if (infoQuery.getType().equals("get")) |
---|
94 | { |
---|
95 | capabilities.answerInfoRequest(infoQuery,(IQDiscoInfo) extension); |
---|
96 | } |
---|
97 | else if (infoQuery.getType().equals("error")) |
---|
98 | { |
---|
99 | Log.xmlReceivedError("Disco error " + infoQuery.getErrorCode() + " " + infoQuery.getErrorDescription() + " from " + infoQuery.getFrom()); |
---|
100 | discovery.discoError(infoQuery.getID(), infoQuery.getFrom()); |
---|
101 | } |
---|
102 | } |
---|
103 | else if (extension instanceof IQDiscoItems) |
---|
104 | {//move to execute |
---|
105 | if (infoQuery.getType().equals("result")) |
---|
106 | { |
---|
107 | discovery.discoveryItemResult(infoQuery.getFrom(), infoQuery.getID(), (IQDiscoItems) extension); |
---|
108 | } |
---|
109 | else if (infoQuery.getType().equals("error")) |
---|
110 | { |
---|
111 | Log.xmlReceivedError("Disco error " + infoQuery.getErrorCode() + " " + infoQuery.getErrorDescription() + " from " + infoQuery.getFrom()); |
---|
112 | discovery.discoError(infoQuery.getID(), infoQuery.getFrom()); |
---|
113 | } |
---|
114 | } |
---|
115 | else if (extension instanceof IQBrowse) |
---|
116 | { |
---|
117 | /*if (infoQuery.getType().equals("result")) |
---|
118 | { |
---|
119 | browse.browseResult(infoQuery.getFrom(), infoQuery.getID(), (IQBrowse) extension); |
---|
120 | } |
---|
121 | else if (infoQuery.getType().equals("error")) |
---|
122 | { |
---|
123 | Log.xmlReceivedError("Browse error " + infoQuery.getErrorCode() + " " + infoQuery.getErrorDescription() + " from " + infoQuery.getFrom()); |
---|
124 | browse.browseError(infoQuery.getID(), infoQuery.getFrom()); |
---|
125 | }*/ |
---|
126 | } |
---|
127 | else extension.execute(infoQuery, backend); |
---|
128 | } else if (infoQuery.getType().equals("set")) { |
---|
129 | XMPPError err = new XMPPError("cancel", 501); |
---|
130 | err.addError(new XMPPErrorTag("feature-not-implemented")); |
---|
131 | backend.send(new InfoQuery(infoQuery.getFrom(), |
---|
132 | infoQuery.getID(), err)); |
---|
133 | } |
---|
134 | //TODO change Jingle code to register iq listeners instead of this |
---|
135 | else if(infoQuery.getType().equals("result") && infoQuery.getID().indexOf("jj") == 0 ){ |
---|
136 | for(Iterator i = backend.getListeners(IQResultListener.class); i.hasNext();){ |
---|
137 | ((IQResultListener)i.next()).iqResult(infoQuery); |
---|
138 | } |
---|
139 | } |
---|
140 | } |
---|
141 | } |
---|
142 | |
---|
143 | /*-------------------------------Message-------------------------*/ |
---|
144 | private void message(Message message) |
---|
145 | { |
---|
146 | MessageListener messageListener = backend.getMessageListener(message.getFrom()); |
---|
147 | if(messageListener != null) |
---|
148 | { |
---|
149 | messageListener.message(message); |
---|
150 | return; |
---|
151 | } |
---|
152 | |
---|
153 | if (message.getBody() != null || message.getType().equals("groupchat")) |
---|
154 | { |
---|
155 | for (Iterator j = backend.getListeners(MessageListener.class); j.hasNext();) |
---|
156 | { |
---|
157 | ((MessageListener) j.next()).message(message); |
---|
158 | } |
---|
159 | } |
---|
160 | if (message.hasExtensions()) |
---|
161 | { |
---|
162 | for (Iterator i = message.getExtensions(); i.hasNext();) |
---|
163 | { |
---|
164 | Extension extension = (Extension) i.next(); |
---|
165 | if (extension instanceof XExecutableExtension) |
---|
166 | { |
---|
167 | ((XExecutableExtension)extension).execute(message, backend); |
---|
168 | } |
---|
169 | |
---|
170 | else if (extension instanceof XMessageEvent) |
---|
171 | {//make executable? |
---|
172 | //goes wrong with groupchat |
---|
173 | //System.out.println( "exts" + extension); |
---|
174 | if (message.getBody() == null) |
---|
175 | { |
---|
176 | //no body so composing event |
---|
177 | for (Iterator j = backend.getListeners(MessageEventListener.class); j.hasNext();) |
---|
178 | { |
---|
179 | ((MessageEventListener) j.next()).onComposing(message.getFrom(), message.getThread(), (XMessageEvent) extension); |
---|
180 | } |
---|
181 | } |
---|
182 | else |
---|
183 | { |
---|
184 | //body so request to sent events //goes wrong with groupchat |
---|
185 | for (Iterator j = backend.getListeners(MessageEventListener.class); j.hasNext();) |
---|
186 | { |
---|
187 | ((MessageEventListener) j.next()).requestComposing(message.getFrom(), message.getID(), message.getThread()); |
---|
188 | } |
---|
189 | } |
---|
190 | } |
---|
191 | } |
---|
192 | } |
---|
193 | } |
---|
194 | |
---|
195 | //----------------------------------Presence----------------------------------------------------\\ |
---|
196 | private void presence(Presence presence) |
---|
197 | { |
---|
198 | //presence for groupchat eg |
---|
199 | PresenceListener presenceListener = backend.getPresenceListener(presence.getFrom()); |
---|
200 | if(presenceListener != null) |
---|
201 | { |
---|
202 | presenceListener.presenceChanged(presence); |
---|
203 | return; |
---|
204 | } |
---|
205 | |
---|
206 | String type = presence.getType(); |
---|
207 | if(!"error".equals(type)) |
---|
208 | { |
---|
209 | if(presence.hasExtensions()) |
---|
210 | { |
---|
211 | for(Iterator i = presence.getExtensions();i.hasNext();) |
---|
212 | { |
---|
213 | Object o = i.next(); |
---|
214 | if(o instanceof IQXCaps) |
---|
215 | { |
---|
216 | backend.setCapability(presence.getFrom(),(IQXCaps)o); |
---|
217 | break; |
---|
218 | } |
---|
219 | } |
---|
220 | } |
---|
221 | } |
---|
222 | |
---|
223 | if (type.equals("available") || type.equals("unavailable")) |
---|
224 | { |
---|
225 | for (Iterator j = backend.getListeners(PresenceListener.class); j.hasNext();) |
---|
226 | { |
---|
227 | ((PresenceListener) j.next()).presenceChanged(presence); |
---|
228 | } |
---|
229 | } |
---|
230 | else if ("subscribe".equals(type)) |
---|
231 | { |
---|
232 | JID from = presence.getFrom(); |
---|
233 | if (from.getUser() == null) |
---|
234 | { |
---|
235 | //server |
---|
236 | sendSubscribed(from, "subscribed", presence.getID()); |
---|
237 | if (backend.getJIDStatus(presence.getFrom()) == null) |
---|
238 | { |
---|
239 | backend.send(new Presence(from, "subscribe")); |
---|
240 | IQXRoster roster = new IQXRoster(new RosterItem(from, null, null, "subscribe", null)); |
---|
241 | backend.send(new InfoQuery("set", roster)); |
---|
242 | } |
---|
243 | } else { |
---|
244 | fireOnSubscriptionRequestEvent(from, presence.getID()); |
---|
245 | } |
---|
246 | } |
---|
247 | else if ("unsubscribed".equals(type)) |
---|
248 | { |
---|
249 | |
---|
250 | /** |
---|
251 | * @DATE : 14/10/2008 |
---|
252 | * @author : Alexandre Correia - alexandrecorreia@im.pr.gov.br |
---|
253 | * @Description : Trecho Comentado : |
---|
254 | * Este trecho faz com que se receba uma notificacao quando o seu |
---|
255 | * convite nao foi aceito/rejeitado. |
---|
256 | */ |
---|
257 | //Popups.messagePopup(presence.getFrom() + "unsuscribed you from his presence", "Unsubscribed"); |
---|
258 | |
---|
259 | } |
---|
260 | else if ("error".equals(type)) |
---|
261 | { |
---|
262 | Log.xmlReceivedError("Presence error " |
---|
263 | + presence.getErrorCode() + " " |
---|
264 | + presence.getErrorDescription() |
---|
265 | + " from " + presence.getFrom()); |
---|
266 | } |
---|
267 | } |
---|
268 | |
---|
269 | private void fireOnSubscriptionRequestEvent(final JID from, final String id) |
---|
270 | { |
---|
271 | /** |
---|
272 | * @Author : Alexandre Correia - alexandrecorreia@celepar.pr.gov.br |
---|
273 | * @Date : 13/10/2008 |
---|
274 | * @Description : Passa para o Servidor Expresso o uid para retornar |
---|
275 | * o cn e a organizacao do requerente, informacao que sera |
---|
276 | * mostrada, pedindo autorizacao. |
---|
277 | */ |
---|
278 | |
---|
279 | JIDStatus jidStatus = backend.getJIDStatus(from); |
---|
280 | String cName = new String(); |
---|
281 | cName = from.toString(); |
---|
282 | ServerExpresso JidName = new ServerExpresso(); |
---|
283 | String ReturnComplete = JidName.NameCN(cName); |
---|
284 | |
---|
285 | NameContact = ReturnComplete.substring(0, ReturnComplete.indexOf(";")); |
---|
286 | NameOrganization = ReturnComplete.substring(ReturnComplete.indexOf(";") + 1 ,ReturnComplete.length()); |
---|
287 | |
---|
288 | if (jidStatus != null) |
---|
289 | { |
---|
290 | Popups.OptionChoosed choose = new Popups.OptionChoosed() |
---|
291 | { |
---|
292 | public void optionChoosed(int option) |
---|
293 | { |
---|
294 | String type = "subscribed"; |
---|
295 | if (option == javax.swing.JOptionPane.YES_OPTION) |
---|
296 | type = "unsubscribed"; |
---|
297 | sendSubscribed(from, type, id); |
---|
298 | } |
---|
299 | }; |
---|
300 | |
---|
301 | Object[] options = { I18N.gettext("main.popup.Deny_subscription"), I18N.gettext("OK") }; |
---|
302 | Popups.showOptionDialog( |
---|
303 | //MessageFormat.format(I18N.gettext("main.popup.{0}_wants_to_subscribe_to_your_presence"),new Object[]{jidStatus.getNick()}), |
---|
304 | MessageFormat.format(I18N.gettext("main.popup.{0}_wants_to_subscribe_to_your_presence"),new Object[]{NameContact + "\n" + NameOrganization + " , "}), |
---|
305 | I18N.gettext("main.popup.Subscription_request"), |
---|
306 | javax.swing.JOptionPane.YES_NO_OPTION, |
---|
307 | javax.swing.JOptionPane.QUESTION_MESSAGE, |
---|
308 | null, |
---|
309 | options, |
---|
310 | options[1], |
---|
311 | choose); |
---|
312 | } |
---|
313 | else |
---|
314 | { |
---|
315 | Popups.OptionChoosed choose = new Popups.OptionChoosed() |
---|
316 | { |
---|
317 | public void optionChoosed(int option) |
---|
318 | { |
---|
319 | String type = "subscribed"; |
---|
320 | if ( option == javax.swing.JOptionPane.NO_OPTION ) |
---|
321 | { |
---|
322 | /** |
---|
323 | * @Author : Alexandre Correia - alexandrecorreia@celepar.pr.gov.br |
---|
324 | * @Date : 17/10/2008 |
---|
325 | * @Description : Passa para a janela o Nome do Contato consultado no Ldap Expresso. |
---|
326 | */ |
---|
327 | //add to roster //frame to addcontact ipv null?? |
---|
328 | //new nu.fw.jeti.ui.AddContact(from, null, backend).setVisible(true); |
---|
329 | new nu.fw.jeti.ui.AddContact(from, null, backend, NameContact, NameOrganization).setVisible(true); |
---|
330 | } |
---|
331 | else |
---|
332 | type = "unsubscribed"; |
---|
333 | sendSubscribed(from, type, id); |
---|
334 | |
---|
335 | // no more no filed (distracts users) |
---|
336 | // else if (option == javax.swing.JOptionPane.CANCEL_OPTION || option == javax.swing.JOptionPane.CLOSED_OPTION) |
---|
337 | // {//add to not filed make different |
---|
338 | // //subscribe(from,null,"Friends"); |
---|
339 | // IQXRoster roster = new IQXRoster(new RosterItem(from,null,null,null,null)); |
---|
340 | // backend.send(new InfoQuery("set",roster)); |
---|
341 | // } |
---|
342 | } |
---|
343 | }; |
---|
344 | Object[] options = { I18N.gettext("main.popup.Deny_subscription"), I18N.gettext("main.popup.Add_to_roster") }; |
---|
345 | Popups.showOptionDialog( |
---|
346 | //MessageFormat.format(I18N.gettext("main.popup.{0}_wants_to_subscribe_to_your_presence"),new Object[]{from}), |
---|
347 | MessageFormat.format(I18N.gettext("main.popup.{0}_wants_to_subscribe_to_your_presence"), new Object[]{NameContact + "\n" + NameOrganization + " , "}), |
---|
348 | I18N.gettext("main.popup.Subscription_request"), |
---|
349 | javax.swing.JOptionPane.YES_NO_OPTION, |
---|
350 | javax.swing.JOptionPane.QUESTION_MESSAGE, |
---|
351 | null, |
---|
352 | options, |
---|
353 | options[1], |
---|
354 | choose); |
---|
355 | } |
---|
356 | } |
---|
357 | |
---|
358 | private void sendSubscribed(JID from, String type, String id) |
---|
359 | { |
---|
360 | //id so need builder |
---|
361 | try |
---|
362 | { |
---|
363 | PresenceBuilder pb = new PresenceBuilder(); |
---|
364 | pb.type = type; |
---|
365 | pb.setId(id); |
---|
366 | pb.setTo(from); |
---|
367 | backend.send(pb.build()); |
---|
368 | } |
---|
369 | catch (InstantiationException e) |
---|
370 | { |
---|
371 | e.printStackTrace(); |
---|
372 | } |
---|
373 | } |
---|
374 | |
---|
375 | } |
---|
376 | |
---|
377 | /* |
---|
378 | * Overrides for emacs |
---|
379 | * Local variables: |
---|
380 | * tab-width: 4 |
---|
381 | * End: |
---|
382 | */ |
---|
383 | |
---|