1 11 12 package org.jivesoftware.messenger.spi; 13 14 import org.jivesoftware.messenger.*; 15 import org.jivesoftware.messenger.component.InternalComponentManager; 16 import org.jivesoftware.messenger.server.OutgoingServerSession; 17 import org.jivesoftware.messenger.container.BasicModule; 18 import org.jivesoftware.util.Log; 19 import org.xmpp.packet.JID; 20 21 import java.util.*; 22 import java.util.concurrent.locks.ReadWriteLock ; 23 import java.util.concurrent.locks.ReentrantReadWriteLock ; 24 import java.util.concurrent.ConcurrentHashMap ; 25 26 34 public class RoutingTableImpl extends BasicModule implements RoutingTable { 35 36 39 private Map routes = new ConcurrentHashMap (); 40 41 44 private ReadWriteLock routeLock = new ReentrantReadWriteLock (); 45 private String serverName; 46 private InternalComponentManager componentManager; 47 48 public RoutingTableImpl() { 49 super("Routing table"); 50 componentManager = InternalComponentManager.getInstance(); 51 } 52 53 public void addRoute(JID node, RoutableChannelHandler destination) { 54 55 String nodeJID = node.getNode() == null ? "" : node.getNode(); 56 String resourceJID = node.getResource() == null ? "" : node.getResource(); 57 58 routeLock.writeLock().lock(); 59 try { 60 if (destination instanceof ClientSession) { 61 Object nameRoutes = routes.get(node.getDomain()); 62 if (nameRoutes == null) { 63 nameRoutes = new Hashtable(); 64 routes.put(node.getDomain(), nameRoutes); 65 } 66 Object resourceRoutes = ((Hashtable)nameRoutes).get(nodeJID); 67 if (resourceRoutes == null) { 68 resourceRoutes = new Hashtable(); 69 ((Hashtable)nameRoutes).put(nodeJID, resourceRoutes); 70 } 71 ((Hashtable)resourceRoutes).put(resourceJID, destination); 72 } 73 else { 74 routes.put(node.getDomain(), destination); 75 } 76 } 77 finally { 78 routeLock.writeLock().unlock(); 79 } 80 } 81 82 public RoutableChannelHandler getRoute(JID node) throws NoSuchRouteException { 83 RoutableChannelHandler route = null; 84 String nodeJID = node.getNode() == null ? "" : node.getNode(); 85 String resourceJID = node.getResource() == null ? "" : node.getResource(); 86 87 if (!serverName.equals(node.getDomain()) && routes.get(node.getDomain()) == null && 89 componentManager.getComponent(node.getDomain()) == null) { 90 OutgoingServerSession.authenticateDomain(serverName, node.getDomain()); 93 } 94 95 routeLock.readLock().lock(); 96 try { 97 Object nameRoutes = routes.get(node.getDomain()); 98 if (nameRoutes instanceof ChannelHandler) { 99 route = (RoutableChannelHandler)nameRoutes; 100 } 101 else { 102 Object resourceRoutes = ((Hashtable)nameRoutes).get(nodeJID); 103 if (resourceRoutes instanceof ChannelHandler) { 104 route = (RoutableChannelHandler)resourceRoutes; 105 } 106 else if (resourceRoutes != null) { 107 route = (RoutableChannelHandler) ((Hashtable)resourceRoutes).get(resourceJID); 108 } 109 else { 110 throw new NoSuchRouteException(node.toString()); 111 } 112 } 113 } 114 catch (Exception e) { 115 throw new NoSuchRouteException(node == null ? "No node" : node.toString(), e); 116 } 117 finally { 118 routeLock.readLock().unlock(); 119 } 120 121 if (route == null) { 122 throw new NoSuchRouteException(node == null ? "No node" : node.toString()); 123 } 124 return route; 125 } 126 127 public Iterator getRoutes(JID node) { 128 if (!serverName.equals(node.getDomain()) && routes.get(node.getDomain()) == null && 130 componentManager.getComponent(node.getDomain()) == null) { 131 OutgoingServerSession.authenticateDomain(serverName, node.getDomain()); 134 } 135 136 LinkedList list = null; 137 routeLock.readLock().lock(); 138 try { 139 if (node == null || node.getDomain() == null) { 140 list = new LinkedList(); 141 getRoutes(list, routes); 142 } 143 else { 144 Object nameRoutes = routes.get(node.getDomain()); 145 if (nameRoutes != null) { 146 if (nameRoutes instanceof ChannelHandler) { 147 list = new LinkedList(); 148 list.add(nameRoutes); 149 } 150 else if (node.getNode() == null) { 151 list = new LinkedList(); 152 getRoutes(list, (Hashtable)nameRoutes); 153 } 154 else { 155 Object resourceRoutes = 156 ((Hashtable)nameRoutes).get(node.getNode()); 157 if (resourceRoutes != null) { 158 if (resourceRoutes instanceof ChannelHandler) { 159 list = new LinkedList(); 160 list.add(resourceRoutes); 161 } 162 else if (node.getResource() == null || node.getResource().length() == 0) { 163 list = new LinkedList(); 164 getRoutes(list, (Hashtable)resourceRoutes); 165 } 166 else { 167 Object entry = 168 ((Hashtable)resourceRoutes).get(node.getResource()); 169 if (entry != null) { 170 list = new LinkedList(); 171 list.add(entry); 172 } 173 } 174 } 175 } 176 } 177 } 178 } 179 finally { 180 routeLock.readLock().unlock(); 181 } 182 if (list == null) { 183 return Collections.EMPTY_LIST.iterator(); 184 } 185 else { 186 return list.iterator(); 187 } 188 } 189 190 199 private void getRoutes(LinkedList list, Map table) { 200 Iterator entryIter = table.values().iterator(); 201 while (entryIter.hasNext()) { 202 Object entry = entryIter.next(); 203 if (entry instanceof Hashtable) { 204 getRoutes(list, (Hashtable)entry); 205 } 206 else { 207 if (!list.contains(entry)) { 210 list.add(entry); 211 } 212 } 213 } 214 } 215 216 public ChannelHandler getBestRoute(JID node) throws NoSuchRouteException { 217 218 ChannelHandler route = null; 219 try { 220 route = getRoute(node); 221 } 222 catch (NoSuchRouteException e) { 223 JID defaultNode = new JID(node.getNode(), node.getDomain(), ""); 224 route = getRoute(defaultNode); 225 } 226 if (route == null) { 227 throw new NoSuchRouteException(); 228 } 229 return route; 230 } 231 232 public ChannelHandler removeRoute(JID node) { 233 234 ChannelHandler route = null; 235 String nodeJID = node.getNode() == null ? "" : node.getNode(); 236 String resourceJID = node.getResource() == null ? "" : node.getResource(); 237 238 routeLock.writeLock().lock(); 239 try { 240 Object nameRoutes = routes.get(node.getDomain()); 241 if (nameRoutes instanceof Hashtable) { 242 Object resourceRoutes = ((Hashtable)nameRoutes).get(nodeJID); 243 if (resourceRoutes instanceof Hashtable) { 244 route = (ChannelHandler) ((Hashtable)resourceRoutes).remove(resourceJID); 246 if (((Hashtable)resourceRoutes).isEmpty()) { 247 ((Hashtable)nameRoutes).remove(nodeJID); 248 if (((Hashtable)nameRoutes).isEmpty()) { 249 routes.remove(node.getDomain()); 250 251 } 252 } 253 } 254 else { 255 ((Hashtable)nameRoutes).remove(nodeJID); 257 } 258 } 259 else if (nameRoutes != null) { 260 if (((RoutableChannelHandler)nameRoutes).getAddress().equals(node)) { 262 routes.remove(node.getDomain()); 264 } 265 } 266 } 267 catch (Exception e) { 268 Log.error("Error removing route", e); 269 } 270 finally { 271 routeLock.writeLock().unlock(); 272 } 273 return route; 274 } 275 276 public void initialize(XMPPServer server) { 277 super.initialize(server); 278 serverName = server.getServerInfo().getName(); 279 } 280 } | Popular Tags |