1 11 12 package org.jivesoftware.messenger.component; 13 14 import org.dom4j.Element; 15 import org.xmpp.component.Component; 16 import org.xmpp.component.ComponentManager; 17 import org.xmpp.component.ComponentManagerFactory; 18 import org.xmpp.component.ComponentException; 19 import org.xmpp.packet.IQ; 20 import org.xmpp.packet.JID; 21 import org.xmpp.packet.Packet; 22 import org.xmpp.packet.Presence; 23 import org.jivesoftware.util.Log; 24 import org.jivesoftware.util.JiveGlobals; 25 import org.jivesoftware.messenger.component.ComponentSession; 26 import org.jivesoftware.messenger.RoutableChannelHandler; 27 import org.jivesoftware.messenger.XMPPServer; 28 import org.jivesoftware.messenger.PacketRouter; 29 import org.jivesoftware.messenger.PacketException; 30 31 import java.util.Map ; 32 import java.util.concurrent.ConcurrentHashMap ; 33 34 46 public class InternalComponentManager implements ComponentManager, RoutableChannelHandler { 47 48 private Map <String , Component> components = new ConcurrentHashMap <String , Component>(); 49 private Map <JID, JID> presenceMap = new ConcurrentHashMap <JID, JID>(); 50 51 private static InternalComponentManager instance = new InternalComponentManager(); 52 55 private JID serviceAddress; 56 60 private String serverDomain; 61 62 public static InternalComponentManager getInstance() { 63 return instance; 64 } 65 66 public void start() { 67 ComponentManagerFactory.setComponentManager(instance); 69 70 XMPPServer server = XMPPServer.getInstance(); 71 serverDomain = server.getServerInfo().getName(); 72 serviceAddress = new JID(null, "component." + serverDomain, null); 74 if (!server.isSetupMode()) { 75 server.getRoutingTable().addRoute(getAddress(), this); 77 } 78 } 79 80 public void addComponent(String subdomain, Component component) throws ComponentException { 81 components.put(subdomain, component); 82 83 JID componentJID = new JID(subdomain + "." + serverDomain); 84 85 XMPPServer.getInstance().getRoutingTable().addRoute(componentJID, 87 new RoutableComponent(componentJID, component)); 88 89 try { 91 component.initialize(componentJID, this); 92 component.start(); 93 } 94 catch (ComponentException e) { 95 XMPPServer.getInstance().getRoutingTable().removeRoute(componentJID); 97 throw e; 99 } 100 101 checkPresences(); 103 checkDiscoSupport(component, componentJID); 106 } 107 108 public void removeComponent(String subdomain) { 109 components.remove(subdomain); 110 111 JID componentJID = new JID(subdomain + "." + serverDomain); 112 113 if (XMPPServer.getInstance().getRoutingTable() != null) { 115 XMPPServer.getInstance().getRoutingTable().removeRoute(componentJID); 116 } 117 118 if (XMPPServer.getInstance().getIQDiscoItemsHandler() != null) { 120 XMPPServer.getInstance().getIQDiscoItemsHandler().removeComponentItem(componentJID.toBareJID()); 121 } 122 } 123 124 public void sendPacket(Component component, Packet packet) { 125 PacketRouter router; 126 router = XMPPServer.getInstance().getPacketRouter(); 127 if (router != null) { 128 router.route(packet); 129 } 130 } 131 132 public String getProperty(String name) { 133 return JiveGlobals.getProperty(name); 134 } 135 136 public void setProperty(String name, String value) { 137 } 139 140 public String getServerName() { 141 return serverDomain; 142 } 143 144 public String getHomeDirectory() { 145 return JiveGlobals.getHomeDirectory(); 146 } 147 148 public boolean isExternalMode() { 149 return false; } 151 152 public org.xmpp.component.Log getLog() { 153 return new org.xmpp.component.Log() { 154 public void error(String msg) { 155 Log.error(msg); 156 } 157 158 public void error(String msg, Throwable throwable) { 159 Log.error(msg, throwable); 160 } 161 162 public void error(Throwable throwable) { 163 Log.error(throwable); 164 } 165 166 public void warn(String msg) { 167 Log.warn(msg); 168 } 169 170 public void warn(String msg, Throwable throwable) { 171 Log.warn(msg, throwable); 172 } 173 174 public void warn(Throwable throwable) { 175 Log.warn(throwable); 176 } 177 178 public void info(String msg) { 179 Log.info(msg); 180 } 181 182 public void info(String msg, Throwable throwable) { 183 Log.info(msg, throwable); 184 } 185 186 public void info(Throwable throwable) { 187 Log.info(throwable); 188 } 189 190 public void debug(String msg) { 191 Log.debug(msg); 192 } 193 194 public void debug(String msg, Throwable throwable) { 195 Log.debug(msg, throwable); 196 } 197 198 public void debug(Throwable throwable) { 199 Log.debug(throwable); 200 } 201 }; 202 } 203 204 211 public Component getComponent(JID componentJID) { 212 String jid = componentJID.toBareJID(); 213 if (components.containsKey(jid)) { 214 return components.get(jid); 215 } 216 else { 217 String serverName = new JID(jid).getDomain(); 218 int index = serverName.indexOf("."); 219 if (index != -1) { 220 String serviceName = serverName.substring(0, index); 221 jid = serviceName; 222 } 223 } 224 return components.get(jid); 225 } 226 227 234 public Component getComponent(String jid) { 235 return getComponent(new JID(jid)); 236 } 237 238 244 public void addPresenceRequest(JID prober, JID probee) { 245 presenceMap.put(prober, probee); 246 } 247 248 private void checkPresences() { 249 for (JID prober : presenceMap.keySet()) { 250 JID probee = presenceMap.get(prober); 251 252 Component component = getComponent(probee.toBareJID()); 253 if (component != null) { 254 Presence presence = new Presence(); 255 presence.setFrom(prober); 256 presence.setTo(probee); 257 component.processPacket(presence); 258 259 presenceMap.remove(prober); 261 } 262 } 263 } 264 265 272 private void checkDiscoSupport(Component component, JID componentJID) { 273 IQ iq = new IQ(IQ.Type.get); 275 iq.setFrom(getAddress()); 276 iq.setTo(componentJID); 277 iq.setChildElement("query", "http://jabber.org/protocol/disco#info"); 278 sendPacket(component, iq); 281 } 282 283 public JID getAddress() { 284 return serviceAddress; 285 } 286 287 295 public void process(Packet packet) throws PacketException { 296 Component component = getComponent(packet.getFrom().getDomain()); 297 if (component != null) { 299 if (packet instanceof IQ && IQ.Type.result == ((IQ) packet).getType()) { 300 IQ iq = (IQ) packet; 301 Element childElement = iq.getChildElement(); 302 String namespace = null; 303 if (childElement != null) { 304 namespace = childElement.getNamespaceURI(); 305 } 306 if ("http://jabber.org/protocol/disco#info".equals(namespace)) { 307 Element identity = childElement.element("identity"); 309 XMPPServer.getInstance().getIQDiscoItemsHandler().addComponentItem(packet.getFrom() 310 .toBareJID(), 311 identity.attributeValue("name")); 312 if (component instanceof ComponentSession.ExternalComponent) { 313 ComponentSession.ExternalComponent externalComponent = 314 (ComponentSession.ExternalComponent) component; 315 externalComponent.setName(identity.attributeValue("name")); 316 externalComponent.setType(identity.attributeValue("type")); 317 externalComponent.setCategory(identity.attributeValue("category")); 318 } 319 } 320 } 321 } 322 } 323 324 327 public static class RoutableComponent implements RoutableChannelHandler { 328 329 private JID jid; 330 private Component component; 331 332 public RoutableComponent(JID jid, Component component) { 333 this.jid = jid; 334 this.component = component; 335 } 336 337 public JID getAddress() { 338 return jid; 339 } 340 341 public void process(Packet packet) throws PacketException { 342 component.processPacket(packet); 343 } 344 } 345 } | Popular Tags |