[3952] | 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 | |
---|