1 package com.ubermq.jms.common.routing.impl; 2 3 import com.ubermq.jms.common.routing.*; 4 5 import java.util.*; 6 import java.io.*; 7 8 21 public final class Router 22 implements IRouter, IConfigurableRouter 23 { 24 private final List excludedRoutes, routes; 25 private final Set nodes; 26 private String myLabel = "undefined"; 27 28 private transient final Map memoization; 30 private transient volatile int nCacheHits, nCacheRequests; 31 private static final int MEMOIZATION_INITIAL_SIZE = 50; 32 33 public static final long serialVersionUID=15; 35 36 public Router() 37 { 38 this.excludedRoutes = new ArrayList(); 39 this.routes = new ArrayList(); 40 this.nodes = new HashSet(); 41 this.memoization = new HashMap(MEMOIZATION_INITIAL_SIZE); 42 } 43 44 public Router(String label) 45 { 46 this(); 47 setNodeLabel(label); 48 } 49 50 public void setNodeLabel(String label) 51 { 52 myLabel = label; 53 } 54 55 public String getNodeLabel() 56 { 57 return myLabel; 58 } 59 60 public void reset() 61 { 62 excludedRoutes.clear(); 63 routes.clear(); 64 nodes.clear(); 65 resetCache(); 66 } 67 68 private void resetCache() 69 { 70 memoization.clear(); 71 } 72 73 public Collection getRoutes(SourceDescriptor source) 74 { 75 Object cached; 76 nCacheRequests++; 77 78 if ((cached = memoization.get(source)) != null) 80 { 81 nCacheHits++; 83 return ((Collection)cached); 84 } 85 else 86 { 87 return reallyGetRoutes(source); 90 } 91 } 92 93 103 public Collection getRoutesTo(RouteDestNode dest) 104 { 105 Set toRemove = new HashSet(); 106 107 for(Iterator i = routes.iterator();i.hasNext();) 108 { 109 BoundRoute br = (BoundRoute)i.next(); 110 if (br.dest.equals(dest)) 111 toRemove.add(br.src); 112 } 113 114 return toRemove; 115 } 116 117 125 private Collection getBoundRoutesTo(RouteDestNode dest) 126 { 127 Set toRemove = new HashSet(); 128 129 for(Iterator i = routes.iterator();i.hasNext();) 130 { 131 BoundRoute br = (BoundRoute)i.next(); 132 if (br.dest.equals(dest)) 133 toRemove.add(br); 134 } 135 136 return toRemove; 137 } 138 139 private Set getExcludedSet(SourceDescriptor spec) 140 { 141 Set exclusionSet = new TreeSet(); 142 for(Iterator i = excludedRoutes.iterator();i.hasNext();) 144 { 145 BoundRoute br = (BoundRoute)i.next(); 146 147 if (br.src.matches(spec)) 148 { 149 exclusionSet.add(br.dest); 150 } 151 } 152 153 return exclusionSet; 154 } 155 156 public Set getKnownNodes() 157 { 158 return nodes; 159 } 160 161 private Collection reallyGetRoutes(SourceDescriptor spec) 162 { 163 Set exclusionSet, sendSet; 164 165 exclusionSet = getExcludedSet( spec ); 168 if (exclusionSet.containsAll(nodes)) 169 return Collections.EMPTY_SET; 170 171 Map preSendMap = new TreeMap(); 174 boolean cacheable = true; 175 for(Iterator i = routes.iterator();i.hasNext();) 176 { 177 BoundRoute br = (BoundRoute)i.next(); 178 179 if (br.src.matches(spec)) 180 { 181 Object existingSource = preSendMap.get(br.dest); 182 if (existingSource == null || 183 br.src.isMoreSpecificThan(((BoundRoute)existingSource).src)) 184 { 185 preSendMap.put(br.dest, br); 186 } 187 } 188 189 if (cacheable && !br.src.isIdempotentForEqualDescriptors()) 191 cacheable = false; 192 } 193 194 sendSet = new TreeSet(); 196 for(Iterator i = preSendMap.values().iterator();i.hasNext();) 197 { 198 sendSet.add( ((BoundRoute)i.next()).getDestination() ); 199 } 200 201 sendSet.retainAll(nodes); 204 sendSet.removeAll(exclusionSet); 205 206 if (cacheable) 208 memoization.put(spec, sendSet); 209 210 return sendSet; 211 } 212 213 public void addRoute(SourceSpec spec, RouteDestNode rdn) 214 { 215 routes.remove( new BoundRoute(spec, rdn) ); 216 routes.add( new BoundRoute(spec, rdn) ); 217 218 resetCache(); 219 } 220 221 public void excludeRoute(SourceSpec spec, RouteDestNode rdn) 222 { 223 excludedRoutes.add( new BoundRoute(spec, rdn) ); 224 resetCache(); 225 } 226 227 public void remove(SourceSpec spec, RouteDestNode rdn) 228 { 229 BoundRoute br = new BoundRoute(spec, rdn); 231 routes.remove(br); 232 resetCache(); 233 } 234 235 public void removeExclusion(SourceSpec spec, RouteDestNode rdn) 236 { 237 BoundRoute br = new BoundRoute(spec, rdn); 239 excludedRoutes.remove(br); 240 resetCache(); 241 } 242 243 public void removeRoutesTo(RouteDestNode node) 244 { 245 Collection toRemove = getBoundRoutesTo(node); 247 for(Iterator j = toRemove.iterator();j.hasNext();) 248 routes.remove(j.next()); 249 250 toRemove.clear(); 252 for(Iterator i = excludedRoutes.iterator();i.hasNext();) 253 { 254 BoundRoute br = (BoundRoute)i.next(); 255 if (br.dest.equals(node)) 256 toRemove.add(br); 257 } 258 for(Iterator j = toRemove.iterator();j.hasNext();) 259 excludedRoutes.remove(j.next()); 260 } 261 262 public void addKnownNode(RouteDestNode node) 263 { 264 nodes.add(node); 265 resetCache(); 266 } 267 268 public void removeKnownNode(RouteDestNode node) 269 { 270 nodes.remove(node); 271 resetCache(); 272 } 273 274 public String toString() 275 { 276 StringBuffer sb = new StringBuffer (); 277 sb.append("Routes:\n"); 278 for(Iterator i = routes.iterator();i.hasNext();) 279 { 280 BoundRoute br = (BoundRoute)i.next(); 281 282 sb.append(br.toString()); sb.append("\n"); 283 } 284 285 if (excludedRoutes.size() > 0) { 286 sb.append("\nExcluded Routes:\n"); 287 for(Iterator i = excludedRoutes.iterator();i.hasNext();) 288 { 289 BoundRoute br = (BoundRoute)i.next(); 290 sb.append(br.toString()); sb.append("\n"); 291 } 292 } 293 294 sb.append("\nNodes: "); 295 for(Iterator i = nodes.iterator();i.hasNext();) 296 { 297 sb.append( ((RouteDestNode)i.next()).toString() ).append(" "); 298 } 299 sb.append("\n"); 300 301 return sb.toString(); 302 } 303 304 private static class BoundRoute 305 { 306 private SourceSpec src; 307 private RouteDestNode dest; 308 309 private BoundRoute(SourceSpec src, RouteDestNode rdn) 310 { 311 this.src = src; 312 this.dest = rdn; 313 } 314 315 public BoundRoute() 316 { 317 } 318 319 public RouteDestNode getDestination() {return dest;} 320 321 public String toString() 322 { 323 return src.getDisplayName() + " -> " + dest.toString(); 324 } 325 326 public boolean equals(Object obj) 327 { 328 try { 329 BoundRoute br = (BoundRoute)obj; 330 return (br.src.equals(src) && 331 br.dest.equals(dest)); 332 } catch(ClassCastException cce) { 333 return false; 334 } 335 } 336 } 337 } 338 | Popular Tags |