1 11 12 package org.jivesoftware.messenger.spi; 13 14 import org.dom4j.Document; 15 import org.dom4j.DocumentHelper; 16 import org.dom4j.DocumentException; 17 import org.jivesoftware.messenger.*; 18 import org.jivesoftware.messenger.component.InternalComponentManager; 19 import org.jivesoftware.messenger.auth.UnauthorizedException; 20 import org.jivesoftware.messenger.container.BasicModule; 21 import org.jivesoftware.messenger.roster.Roster; 22 import org.jivesoftware.messenger.roster.RosterItem; 23 import org.jivesoftware.messenger.user.User; 24 import org.jivesoftware.messenger.user.UserManager; 25 import org.jivesoftware.messenger.user.UserNotFoundException; 26 import org.jivesoftware.util.CacheManager; 27 import org.jivesoftware.util.LocaleUtils; 28 import org.jivesoftware.util.Log; 29 import org.xmpp.component.Component; 30 import org.xmpp.packet.JID; 31 import org.xmpp.packet.PacketError; 32 import org.xmpp.packet.Presence; 33 34 import java.util.ArrayList ; 35 import java.util.Collection ; 36 import java.util.Collections ; 37 import java.util.List ; 38 39 44 public class PresenceManagerImpl extends BasicModule implements PresenceManager { 45 46 private static final String LAST_PRESENCE_PROP = "lastUnavailablePresence"; 47 private static final String LAST_ACTIVITY_PROP = "lastActivity"; 48 49 private SessionManager sessionManager; 50 private XMPPServer server; 51 private PacketDeliverer deliverer; 52 53 private InternalComponentManager componentManager; 54 55 public PresenceManagerImpl() { 56 super("Presence manager"); 57 58 componentManager = InternalComponentManager.getInstance(); 60 } 61 62 public boolean isAvailable(User user) { 63 return sessionManager.getSessionCount(user.getUsername()) > 0; 64 } 65 66 public Presence getPresence(User user) { 67 if (user == null) { 68 return null; 69 } 70 Presence presence = null; 71 72 for (ClientSession session : sessionManager.getSessions(user.getUsername())) { 73 if (presence == null) { 74 presence = session.getPresence(); 75 } 76 else { 77 int o1 = presence.getShow() != null ? presence.getShow().ordinal() : -1; 80 int o2 = session.getPresence().getShow() != null ? 81 session.getPresence().getShow().ordinal() : -1; 82 if (o1 > o2) { 84 presence = session.getPresence(); 85 } 86 } 87 } 88 return presence; 89 } 90 91 public Collection <Presence> getPresences(String username) { 92 if (username == null) { 93 return null; 94 } 95 List <Presence> presences = new ArrayList <Presence>(); 96 97 for (ClientSession session : sessionManager.getSessions(username)) { 98 presences.add(session.getPresence()); 99 } 100 return Collections.unmodifiableCollection(presences); 101 } 102 103 public String getLastPresenceStatus(User user) { 104 String answer = null; 105 String presenceXML = user.getProperties().get(LAST_PRESENCE_PROP); 106 if (presenceXML != null) { 107 try { 108 Document element = DocumentHelper.parseText(presenceXML); 110 answer = element.getRootElement().elementTextTrim("status"); 111 } 112 catch (DocumentException e) { 113 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 114 } 115 } 116 return answer; 117 } 118 119 public long getLastActivity(User user) { 120 long answer = -1; 121 String offline = user.getProperties().get(LAST_ACTIVITY_PROP); 122 if (offline != null) { 123 try { 124 answer = (System.currentTimeMillis() - Long.parseLong(offline)) / 1000; 125 } 126 catch (NumberFormatException e) { 127 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 128 } 129 } 130 return answer; 131 } 132 133 public void userAvailable(Presence presence) { 134 if (presence.getTo() == null && server.isLocal(presence.getFrom())) { 138 String username = presence.getFrom().getNode(); 139 if (username == null) { 140 return; 142 } 143 try { 144 User probeeUser = UserManager.getInstance().getUser(username); 145 probeeUser.getProperties().remove(LAST_PRESENCE_PROP); 146 } 147 catch (UserNotFoundException e) { 148 } 149 } 150 } 151 152 public void userUnavailable(Presence presence) { 153 if (presence.getTo() == null && server.isLocal(presence.getFrom())) { 157 String username = presence.getFrom().getNode(); 158 if (username == null) { 159 return; 161 } 162 try { 163 User probeeUser = UserManager.getInstance().getUser(username); 164 if (!presence.getElement().elements().isEmpty()) { 165 probeeUser.getProperties().put(LAST_PRESENCE_PROP, presence.toXML()); 168 } 169 probeeUser.getProperties().put(LAST_ACTIVITY_PROP, 171 String.valueOf(System.currentTimeMillis())); 172 } 173 catch (UserNotFoundException e) { 174 } 175 } 176 } 177 178 public void handleProbe(Presence packet) throws UnauthorizedException { 179 String username = packet.getTo().getNode(); 180 Roster roster = (Roster)CacheManager.getCache("username2roster").get(username); 182 if (roster == null) { 183 synchronized(username.intern()) { 184 roster = (Roster)CacheManager.getCache("username2roster").get(username); 185 if (roster == null) { 186 roster = new Roster(username); 188 CacheManager.getCache("username2roster").put(username, roster); 189 } 190 } 191 } 192 try { 193 RosterItem item = roster.getRosterItem(packet.getFrom()); 194 if (item.getSubStatus() == RosterItem.SUB_FROM 195 || item.getSubStatus() == RosterItem.SUB_BOTH) { 196 probePresence(packet.getFrom(), packet.getTo()); 197 } 198 else { 199 PacketError.Condition error = PacketError.Condition.not_authorized; 200 if ((item.getSubStatus() == RosterItem.SUB_NONE && 201 item.getRecvStatus() != RosterItem.RECV_SUBSCRIBE) || 202 (item.getSubStatus() == RosterItem.SUB_TO && 203 item.getRecvStatus() != RosterItem.RECV_SUBSCRIBE)) { 204 error = PacketError.Condition.forbidden; 205 } 206 Presence presenceToSend = new Presence(); 207 presenceToSend.setError(error); 208 presenceToSend.setTo(packet.getFrom()); 209 presenceToSend.setFrom(packet.getTo()); 210 deliverer.deliver(presenceToSend); 211 } 212 } 213 catch (UserNotFoundException e) { 214 Presence presenceToSend = new Presence(); 215 presenceToSend.setError(PacketError.Condition.forbidden); 216 presenceToSend.setTo(packet.getFrom()); 217 presenceToSend.setFrom(packet.getTo()); 218 deliverer.deliver(presenceToSend); 219 } 220 } 221 222 public boolean canProbePresence(JID prober, String probee) throws UserNotFoundException { 223 UserManager.getInstance().getUser(probee); 225 Roster roster = (Roster)CacheManager.getCache("username2roster").get(probee); 227 if (roster == null) { 228 synchronized(probee.intern()) { 229 roster = (Roster)CacheManager.getCache("username2roster").get(probee); 230 if (roster == null) { 231 roster = new Roster(probee); 233 CacheManager.getCache("username2roster").put(probee, roster); 234 } 235 } 236 } 237 RosterItem item = roster.getRosterItem(prober); 238 if (item.getSubStatus() == RosterItem.SUB_FROM 239 || item.getSubStatus() == RosterItem.SUB_BOTH) { 240 return true; 241 } 242 return false; 243 } 244 245 public void probePresence(JID prober, JID probee) { 246 try { 247 Component component = getPresenceComponent(probee); 248 if (server.isLocal(probee)) { 249 if (probee.getNode() != null && !"".equals(probee.getNode())) { 252 Collection <ClientSession> sessions = 253 sessionManager.getSessions(probee.getNode()); 254 if (sessions.isEmpty()) { 255 try { 259 User probeeUser = UserManager.getInstance().getUser(probee.getNode()); 260 String presenceXML = probeeUser.getProperties().get(LAST_PRESENCE_PROP); 261 if (presenceXML != null) { 262 try { 263 Document element = DocumentHelper.parseText(presenceXML); 265 Presence presencePacket = new Presence(element.getRootElement()); 267 presencePacket.setFrom(probee.toBareJID()); 268 presencePacket.setTo(prober); 269 deliverer.deliver(presencePacket); 271 } 272 catch (Exception e) { 273 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 274 } 275 276 } 277 } 278 catch (UserNotFoundException e) { 279 } 280 } 281 else { 282 for (ClientSession session : sessions) { 285 Presence presencePacket = session.getPresence().createCopy(); 286 presencePacket.setFrom(session.getAddress()); 287 presencePacket.setTo(prober); 288 try { 289 deliverer.deliver(presencePacket); 290 } 291 catch (Exception e) { 292 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 293 } 294 } 295 } 296 } 297 } 298 else if (component != null) { 299 Presence presence = new Presence(); 302 presence.setType(Presence.Type.probe); 303 presence.setFrom(prober); 304 presence.setTo(probee); 305 component.processPacket(presence); 306 } 307 else { 308 311 if (server.isRemote(probee)) { 312 Presence probePresence = new Presence(); 314 probePresence.setType(Presence.Type.probe); 315 probePresence.setFrom(prober); 316 probePresence.setTo(probee.toBareJID()); 317 deliverer.deliver(probePresence); 319 } 320 else { 321 componentManager.addPresenceRequest(prober, probee); 325 } 326 } 327 } 328 catch (Exception e) { 329 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 330 } 331 } 332 333 public void sendUnavailableFromSessions(JID recipientJID, JID userJID) { 334 if (userJID.getNode() != null && !"".equals(userJID.getNode())) { 335 for (ClientSession session : sessionManager.getSessions(userJID.getNode())) { 336 Presence presencePacket = new Presence(); 337 presencePacket.setType(Presence.Type.unavailable); 338 presencePacket.setFrom(session.getAddress()); 339 presencePacket.setTo(recipientJID); 340 try { 341 deliverer.deliver(presencePacket); 342 } 343 catch (Exception e) { 344 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 345 } 346 } 347 } 348 } 349 350 354 public void initialize(XMPPServer server) { 355 super.initialize(server); 356 this.server = server; 357 deliverer = server.getPacketDeliverer(); 358 sessionManager = server.getSessionManager(); 359 } 360 361 public Component getPresenceComponent(JID probee) { 362 Component component = componentManager.getComponent(probee.toBareJID()); 364 if (component != null) { 365 return component; 366 } 367 return null; 368 } 369 } | Popular Tags |