1 11 12 package org.jivesoftware.messenger; 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 26 import java.util.Map ; 27 import java.util.concurrent.ConcurrentHashMap ; 28 29 41 public class InternalComponentManager implements ComponentManager, RoutableChannelHandler { 42 43 private Map <String , Component> components = new ConcurrentHashMap <String , Component>(); 44 private Map <JID, JID> presenceMap = new ConcurrentHashMap <JID, JID>(); 45 46 private static InternalComponentManager instance = new InternalComponentManager(); 47 50 private JID serviceAddress; 51 55 private String serverDomain; 56 57 public static InternalComponentManager getInstance() { 58 return instance; 59 } 60 61 public void start() { 62 ComponentManagerFactory.setComponentManager(instance); 64 65 XMPPServer server = XMPPServer.getInstance(); 66 serverDomain = server.getServerInfo().getName(); 67 serviceAddress = new JID(null, "component." + serverDomain, null); 69 if (!server.isSetupMode()) { 70 server.getRoutingTable().addRoute(getAddress(), this); 72 } 73 } 74 75 public void addComponent(String subdomain, Component component) throws ComponentException { 76 components.put(subdomain, component); 77 78 JID componentJID = new JID(subdomain + "." + serverDomain); 79 80 XMPPServer.getInstance().getRoutingTable().addRoute(componentJID, 82 new RoutableComponent(componentJID, component)); 83 84 try { 86 component.initialize(componentJID, this); 87 component.start(); 88 } 89 catch (ComponentException e) { 90 XMPPServer.getInstance().getRoutingTable().removeRoute(componentJID); 92 throw e; 94 } 95 96 checkPresences(); 98 checkDiscoSupport(component, componentJID); 101 } 102 103 public void removeComponent(String subdomain) { 104 components.remove(subdomain); 105 106 JID componentJID = new JID(subdomain + "." + serverDomain); 107 108 if (XMPPServer.getInstance().getRoutingTable() != null) { 110 XMPPServer.getInstance().getRoutingTable().removeRoute(componentJID); 111 } 112 113 if (XMPPServer.getInstance().getIQDiscoItemsHandler() != null) { 115 XMPPServer.getInstance().getIQDiscoItemsHandler().removeComponentItem(componentJID.toBareJID()); 116 } 117 } 118 119 public void sendPacket(Component component, Packet packet) { 120 PacketRouter router; 121 router = XMPPServer.getInstance().getPacketRouter(); 122 if (router != null) { 123 router.route(packet); 124 } 125 } 126 127 public String getProperty(String name) { 128 return JiveGlobals.getProperty(name); 129 } 130 131 public void setProperty(String name, String value) { 132 } 134 135 public String getServerName() { 136 return serverDomain; 137 } 138 139 public String getHomeDirectory() { 140 return JiveGlobals.getHomeDirectory(); 141 } 142 143 public boolean isExternalMode() { 144 return false; } 146 147 public org.xmpp.component.Log getLog() { 148 return new org.xmpp.component.Log() { 149 public void error(String msg) { 150 Log.error(msg); 151 } 152 153 public void error(String msg, Throwable throwable) { 154 Log.error(msg, throwable); 155 } 156 157 public void error(Throwable throwable) { 158 Log.error(throwable); 159 } 160 161 public void warn(String msg) { 162 Log.warn(msg); 163 } 164 165 public void warn(String msg, Throwable throwable) { 166 Log.warn(msg, throwable); 167 } 168 169 public void warn(Throwable throwable) { 170 Log.warn(throwable); 171 } 172 173 public void info(String msg) { 174 Log.info(msg); 175 } 176 177 public void info(String msg, Throwable throwable) { 178 Log.info(msg, throwable); 179 } 180 181 public void info(Throwable throwable) { 182 Log.info(throwable); 183 } 184 185 public void debug(String msg) { 186 Log.debug(msg); 187 } 188 189 public void debug(String msg, Throwable throwable) { 190 Log.debug(msg, throwable); 191 } 192 193 public void debug(Throwable throwable) { 194 Log.debug(throwable); 195 } 196 }; 197 } 198 199 206 public Component getComponent(JID componentJID) { 207 String jid = componentJID.toBareJID(); 208 if (components.containsKey(jid)) { 209 return components.get(jid); 210 } 211 else { 212 String serverName = new JID(jid).getDomain(); 213 int index = serverName.indexOf("."); 214 if (index != -1) { 215 String serviceName = serverName.substring(0, index); 216 jid = serviceName; 217 } 218 } 219 return components.get(jid); 220 } 221 222 229 public Component getComponent(String jid) { 230 return getComponent(new JID(jid)); 231 } 232 233 239 public void addPresenceRequest(JID prober, JID probee) { 240 presenceMap.put(prober, probee); 241 } 242 243 private void checkPresences() { 244 for (JID prober : presenceMap.keySet()) { 245 JID probee = presenceMap.get(prober); 246 247 Component component = getComponent(probee.toBareJID()); 248 if (component != null) { 249 Presence presence = new Presence(); 250 presence.setFrom(prober); 251 presence.setTo(probee); 252 component.processPacket(presence); 253 254 presenceMap.remove(prober); 256 } 257 } 258 } 259 260 267 private void checkDiscoSupport(Component component, JID componentJID) { 268 IQ iq = new IQ(IQ.Type.get); 270 iq.setFrom(getAddress()); 271 iq.setTo(componentJID); 272 iq.setChildElement("query", "http://jabber.org/protocol/disco#info"); 273 sendPacket(component, iq); 276 } 277 278 public JID getAddress() { 279 return serviceAddress; 280 } 281 282 290 public void process(Packet packet) throws PacketException { 291 Component component = getComponent(packet.getFrom().getDomain()); 292 if (component != null) { 294 if (packet instanceof IQ && IQ.Type.result == ((IQ) packet).getType()) { 295 IQ iq = (IQ) packet; 296 Element childElement = iq.getChildElement(); 297 String namespace = null; 298 if (childElement != null) { 299 namespace = childElement.getNamespaceURI(); 300 } 301 if ("http://jabber.org/protocol/disco#info".equals(namespace)) { 302 XMPPServer.getInstance().getIQDiscoItemsHandler().addComponentItem(packet.getFrom() 304 .toBareJID(), 305 childElement.element("identity").attributeValue("name")); 306 } 307 } 308 } 309 } 310 311 314 public static class RoutableComponent implements RoutableChannelHandler { 315 316 private JID jid; 317 private Component component; 318 319 public RoutableComponent(JID jid, Component component) { 320 this.jid = jid; 321 this.component = component; 322 } 323 324 public JID getAddress() { 325 return jid; 326 } 327 328 public void process(Packet packet) throws PacketException { 329 component.processPacket(packet); 330 } 331 } 332 } | Popular Tags |