1 11 12 package org.jivesoftware.messenger.handler; 13 14 import org.jivesoftware.messenger.*; 15 import org.jivesoftware.messenger.auth.UnauthorizedException; 16 import org.jivesoftware.messenger.container.BasicModule; 17 import org.jivesoftware.messenger.roster.Roster; 18 import org.jivesoftware.messenger.roster.RosterItem; 19 import org.jivesoftware.messenger.roster.RosterManager; 20 import org.jivesoftware.messenger.user.UserNotFoundException; 21 import org.jivesoftware.util.ConcurrentHashSet; 22 import org.jivesoftware.util.LocaleUtils; 23 import org.jivesoftware.util.Log; 24 import org.xmpp.packet.*; 25 26 import java.util.*; 27 import java.util.concurrent.ConcurrentHashMap ; 28 29 67 public class PresenceUpdateHandler extends BasicModule implements ChannelHandler { 68 69 private Map <String , WeakHashMap<ChannelHandler, Set<String >>> directedPresences; 70 71 private RosterManager rosterManager; 72 private XMPPServer localServer; 73 private PresenceManager presenceManager; 74 private PacketDeliverer deliverer; 75 private OfflineMessageStore messageStore; 76 private SessionManager sessionManager; 77 78 public PresenceUpdateHandler() { 79 super("Presence update handler"); 80 directedPresences = new ConcurrentHashMap <String , WeakHashMap<ChannelHandler, Set<String >>>(); 81 } 82 83 public void process(Packet xmppPacket) throws UnauthorizedException, PacketException { 84 Presence presence = (Presence)xmppPacket; 85 try { 86 ClientSession session = sessionManager.getSession(presence.getFrom()); 87 Presence.Type type = presence.getType(); 88 if (type == null) { 90 broadcastUpdate(presence.createCopy()); 91 if (session != null) { 92 session.setPresence(presence); 93 if (!session.isInitialized()) { 94 initSession(session); 95 session.setInitialized(true); 96 } 97 } 98 presenceManager.userAvailable(presence); 101 } 102 else if (Presence.Type.unavailable == type) { 103 broadcastUpdate(presence.createCopy()); 104 broadcastUnavailableForDirectedPresences(presence); 105 if (session != null) { 106 session.setPresence(presence); 107 } 108 presenceManager.userUnavailable(presence); 112 } 113 else { 114 presence = presence.createCopy(); 115 if (session != null) { 116 presence.setFrom(new JID(null, session.getServerName(), null)); 117 presence.setTo(session.getAddress()); 118 } 119 else { 120 JID sender = presence.getFrom(); 121 presence.setFrom(presence.getTo()); 122 presence.setTo(sender); 123 } 124 presence.setError(PacketError.Condition.bad_request); 125 deliverer.deliver(presence); 126 } 127 128 } 129 catch (Exception e) { 130 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 131 } 132 } 133 134 139 public void process(Presence presence) throws PacketException { 140 try { 141 process((Packet)presence); 142 } 143 catch (UnauthorizedException e) { 144 try { 145 Session session = sessionManager.getSession(presence.getFrom()); 146 presence = presence.createCopy(); 147 if (session != null) { 148 presence.setFrom(new JID(null, session.getServerName(), null)); 149 presence.setTo(session.getAddress()); 150 } 151 else { 152 JID sender = presence.getFrom(); 153 presence.setFrom(presence.getTo()); 154 presence.setTo(sender); 155 } 156 presence.setError(PacketError.Condition.not_authorized); 157 deliverer.deliver(presence); 158 } 159 catch (Exception err) { 160 Log.error(LocaleUtils.getLocalizedString("admin.error"), err); 161 } 162 } 163 } 164 165 176 private void initSession(ClientSession session) throws UserNotFoundException { 177 178 if (session.getAddress().getNode() != null && !"".equals(session.getAddress().getNode())) { 180 String username = session.getAddress().getNode(); 181 Roster roster = rosterManager.getRoster(username); 182 for (RosterItem item : roster.getRosterItems()) { 183 if (item.getRecvStatus() == RosterItem.RECV_SUBSCRIBE) { 184 session.process(createSubscribePresence(item.getJid(), true)); 185 } 186 else if (item.getRecvStatus() == RosterItem.RECV_UNSUBSCRIBE) { 187 session.process(createSubscribePresence(item.getJid(), false)); 188 } 189 if (item.getSubStatus() == RosterItem.SUB_TO 190 || item.getSubStatus() == RosterItem.SUB_BOTH) { 191 presenceManager.probePresence(session.getAddress(), item.getJid()); 192 } 193 } 194 if (session.canFloodOfflineMessages()) { 195 Collection<OfflineMessage> messages = messageStore.getMessages(username, true); 197 for (Message message : messages) { 198 session.process(message); 199 } 200 } 201 } 202 } 203 204 public Presence createSubscribePresence(JID senderAddress, boolean isSubscribe) { 205 Presence presence = new Presence(); 206 presence.setFrom(senderAddress); 207 if (isSubscribe) { 208 presence.setType(Presence.Type.subscribe); 209 } 210 else { 211 presence.setType(Presence.Type.unsubscribe); 212 } 213 return presence; 214 } 215 216 228 private void broadcastUpdate(Presence update) throws PacketException { 229 if (update.getFrom() == null) { 230 return; 231 } 232 if (localServer.isLocal(update.getFrom())) { 233 String name = update.getFrom().getNode(); 235 try { 236 if (name != null && !"".equals(name)) { 237 name = name.toLowerCase(); 238 Roster roster = rosterManager.getRoster(name); 239 roster.broadcastPresence(update); 240 } 241 } 242 catch (UserNotFoundException e) { 243 Log.warn("Presence being sent from unknown user " + name, e); 244 } 245 catch (PacketException e) { 246 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 247 } 248 } 249 else { 250 Log.warn("Presence requested from server " 253 + localServer.getServerInfo().getName() 254 + " by unknown user: " + update.getFrom()); 255 282 } 283 } 284 285 295 public void directedPresenceSent(Presence update, ChannelHandler handler, String jid) { 296 if (update.getFrom() == null) { 297 return; 298 } 299 if (localServer.isLocal(update.getFrom())) { 300 boolean keepTrack = false; 301 WeakHashMap<ChannelHandler, Set<String >> map; 302 String name = update.getFrom().getNode(); 303 if (name != null && !"".equals(name)) { 304 name = name.toLowerCase(); 305 try { 306 Roster roster = rosterManager.getRoster(name); 307 if (!roster.isRosterItem(update.getTo())) { 311 keepTrack = true; 312 } 313 } 314 catch (UserNotFoundException e) { 315 Log.warn("Presence being sent from unknown user " + name, e); 316 } 317 catch (PacketException e) { 318 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 319 } 320 321 } 322 else if (update.getFrom().getResource() != null){ 323 keepTrack = true; 325 } 326 if (keepTrack) { 327 map = directedPresences.get(update.getFrom().toString()); 328 if (map == null) { 329 map = new WeakHashMap<ChannelHandler, Set<String >>(); 334 map.put(handler, new ConcurrentHashSet<String >()); 335 directedPresences.put(update.getFrom().toString(), map); 336 } 337 if (Presence.Type.unavailable.equals(update.getType())) { 338 if (handler instanceof ClientSession) { 340 map.remove(handler); 343 if (map.isEmpty()) { 344 directedPresences.remove(update.getFrom().toString()); 347 } 348 } 349 else { 350 Set<String > jids = map.get(handler); 354 if (jids != null) { 355 jids.remove(jid); 356 } 357 358 } 359 } 360 else { 361 if (map.get(handler) == null) { 365 map.put(handler, new ConcurrentHashSet<String >()); 366 } 367 map.get(handler).add(jid); 368 } 369 } 370 } 371 } 372 373 379 private void broadcastUnavailableForDirectedPresences(Presence update) { 380 if (update.getFrom() == null) { 381 return; 382 } 383 if (localServer.isLocal(update.getFrom())) { 384 Map <ChannelHandler, Set<String >> map = directedPresences.get(update.getFrom().toString()); 385 if (map != null) { 386 for (ChannelHandler handler : new HashSet<ChannelHandler>(map.keySet())) { 388 Set<String > jids = map.get(handler); 389 if (jids == null) { 390 continue; 391 } 392 for (String jid : jids) { 393 Presence presence = update.createCopy(); 394 presence.setTo(new JID(jid)); 395 try { 396 handler.process(presence); 397 } 398 catch (UnauthorizedException ue) { 399 Log.error(ue); 400 } 401 } 402 } 403 directedPresences.remove(update.getFrom().toString()); 405 } 406 } 407 } 408 409 public void initialize(XMPPServer server) { 410 super.initialize(server); 411 localServer = server; 412 rosterManager = server.getRosterManager(); 413 presenceManager = server.getPresenceManager(); 414 deliverer = server.getPacketDeliverer(); 415 messageStore = server.getOfflineMessageStore(); 416 sessionManager = server.getSessionManager(); 417 } 418 } 419 | Popular Tags |