1 20 21 22 23 package org.snmp4j.agent; 24 25 import java.util.*; 26 27 import org.snmp4j.log.*; 28 import org.snmp4j.smi.*; 29 import java.util.Map.Entry; 30 31 37 public class DefaultMOServer implements MOServer { 38 39 private static final LogAdapter logger = 40 LogFactory.getLogger(DefaultMOServer.class); 41 42 private Set contexts; 43 private SortedMap registry; 44 private Map lockList; 45 private Map lookupListener; 46 private transient Vector contextListeners; 47 48 49 public DefaultMOServer() { 50 this.registry = 51 Collections.synchronizedSortedMap(new TreeMap(new MOScopeComparator())); 52 this.contexts = new LinkedHashSet(10); 53 this.lockList = new Hashtable(10); 54 } 55 56 public ManagedObject lookup(MOQuery query) { 57 SortedMap scope = registry.tailMap(query); 58 Iterator it = scope.entrySet().iterator(); 59 while (it.hasNext()) { 60 Map.Entry entry = (Entry) it.next(); 61 MOScope key = (MOScope) entry.getKey(); 62 if (!DefaultMOContextScope.isContextMatching(query.getScope(), key)) { 63 continue; 64 } 65 Object o = entry.getValue(); 66 if (o instanceof ManagedObject) { 67 ManagedObject mo = (ManagedObject) o; 68 MOScope moScope = mo.getScope(); 69 if (query.getScope().isOverlapping(moScope)) { 70 fireQueryEvent(mo, query); 71 if (query.matchesQuery(mo)) { 72 fireLookupEvent(mo, query); 73 return mo; 74 } 75 } 76 } 77 else if (logger.isWarnEnabled()) { 78 logger.warn("Object looked up is not a ManagedObject: "+o); 79 } 80 } 81 return null; 82 } 83 84 102 public ManagedObject getManagedObject(OID key, OctetString context) { 103 MOContextScope scope = 104 new DefaultMOContextScope(context, key, true, key, true); 105 return lookup(new DefaultMOQuery(scope)); 106 } 107 108 protected void fireLookupEvent(ManagedObject mo, MOQuery query) { 109 if (lookupListener != null) { 110 List l = (List) lookupListener.get(mo); 111 if (l != null) { 112 MOServerLookupEvent event = new MOServerLookupEvent(this, mo, query); 113 for (Iterator it = l.iterator(); it.hasNext(); ) { 114 MOServerLookupListener item = (MOServerLookupListener) it.next(); 115 item.lookupEvent(event); 116 } 117 } 118 } 119 } 120 121 protected void fireQueryEvent(ManagedObject mo, MOQuery query) { 122 if (lookupListener != null) { 123 List l = (List) lookupListener.get(mo); 124 if (l != null) { 125 MOServerLookupEvent event = new MOServerLookupEvent(this, mo, query); 126 for (Iterator it = l.iterator(); it.hasNext(); ) { 127 MOServerLookupListener item = (MOServerLookupListener) it.next(); 128 item.queryEvent(event); 129 } 130 } 131 } 132 } 133 134 public OctetString[] getContexts() { 135 return (OctetString[]) contexts.toArray(new OctetString[0]); 136 } 137 138 public boolean isContextSupported(OctetString context) { 139 if ((context == null) || (context.length() == 0)) { 140 return true; 141 } 142 return contexts.contains(context); 143 } 144 145 public SortedMap getRegistry() { 146 return registry; 147 } 148 149 public void register(ManagedObject mo, OctetString context) 150 throws DuplicateRegistrationException 151 { 152 if (context == null) { 153 MOContextScope contextScope = 154 new DefaultMOContextScope(null, mo.getScope()); 155 ManagedObject other = lookup(new DefaultMOQuery(contextScope)); 156 if (other != null) { 157 throw new DuplicateRegistrationException(contextScope, 158 other.getScope()); 159 } 160 registry.put(mo.getScope(), mo); 161 if (logger.isInfoEnabled()) { 162 logger.info("Registered MO "+mo+" in default context with scope "+ 163 mo.getScope()); 164 } 165 } 166 else { 167 DefaultMOContextScope contextScope = 168 new DefaultMOContextScope(context, mo.getScope()); 169 ManagedObject other = lookup(new DefaultMOQuery(contextScope)); 170 if (other != null) { 171 throw new DuplicateRegistrationException(contextScope, other.getScope()); 172 } 173 registry.put(contextScope, mo); 174 if (logger.isInfoEnabled()) { 175 logger.info("Registered MO "+mo+" in context "+context+" with scope "+ 176 contextScope); 177 } 178 } 179 } 180 181 public void unregister(ManagedObject mo, OctetString context) { 182 MOScope key; 183 if (context == null) { 184 key = mo.getScope(); 185 } 186 else { 187 key = new DefaultMOContextScope(context, mo.getScope()); 188 } 189 Object r = registry.remove(key); 190 if (r == null) { 191 SortedMap tailMap = registry.tailMap(key); 194 for (Iterator it = tailMap.entrySet().iterator(); it.hasNext();) { 195 Map.Entry entry = (Entry) it.next(); 196 MOScope entryKey = (MOScope) entry.getKey(); 197 if ((entry.getValue().equals(mo)) && 198 (((context != null) && 199 (entryKey instanceof MOContextScope) && 200 (context.equals(((MOContextScope)entryKey).getContext()))) || 201 (context == null))) { 202 r = entry.getValue(); 203 it.remove(); 204 break; 205 } 206 } 207 } 208 if (logger.isInfoEnabled()) { 209 if (r != null) { 210 logger.info("Removed registration " + r + " for " + mo + 211 " in context '" + context + "' sucessfully"); 212 } 213 else { 214 logger.warn("Removing registration failed for " + mo + 215 " in context '" + context + "'"); 216 } 217 } 218 } 219 220 public void addContext(OctetString context) { 221 contexts.add(context); 222 } 223 224 public void removeContext(OctetString context) { 225 contexts.remove(context); 226 } 227 228 public synchronized void lock(Object owner, ManagedObject managedObject) { 229 Lock lock; 230 do { 231 lock = (Lock) lockList.get(managedObject); 232 if (lock == null) { 233 lockList.put(managedObject, new Lock(owner)); 234 if (logger.isDebugEnabled()) { 235 logger.debug("Acquired lock on "+managedObject+ " for "+owner); 236 } 237 } 238 else if (lock.getOwner() != owner) { 239 try { 240 if (logger.isDebugEnabled()) { 241 logger.debug("Waiting for lock on "+managedObject); 242 } 243 wait(); 244 } 245 catch (InterruptedException ex) { 246 logger.warn("Waiting for lock on "+managedObject+ 247 " has been interrupted!"); 248 break; 249 } 250 } 251 else { 252 lock.add(); 253 if (logger.isDebugEnabled()) { 254 logger.debug("Added lock on "+managedObject+ " for "+owner); 255 } 256 return; 257 } 258 } 259 while (lock != null); 260 } 261 262 public synchronized void unlock(Object owner, ManagedObject managedObject) { 263 Lock lock = (Lock) lockList.get(managedObject); 264 if (lock == null) { 265 return; 266 } 267 if (lock.getOwner() != owner) { 268 if (logger.isDebugEnabled()) { 269 logger.debug("Object '" + owner + "' is not owner of lock: " + lock); 270 } 271 return; 272 } 273 if (lock.remove()) { 274 lockList.remove(managedObject); 275 if (logger.isDebugEnabled()) { 276 logger.debug("Removed lock on "+managedObject+ " by "+owner); 277 } 278 notify(); 279 } 280 } 281 282 public Iterator iterator() { 283 return getRegistry().values().iterator(); 284 } 285 286 public void addLookupListener(MOServerLookupListener listener, 287 ManagedObject mo) { 288 if (lookupListener == null) { 289 lookupListener = Collections.synchronizedMap(new HashMap()); 290 } 291 List l = (List) lookupListener.get(mo); 292 if (l == null) { 293 l = Collections.synchronizedList(new LinkedList()); 294 lookupListener.put(mo, l); 295 } 296 l.add(listener); 297 } 298 299 public boolean removeLookupListener(MOServerLookupListener listener, 300 ManagedObject mo) { 301 if (lookupListener != null) { 302 List l = (List) lookupListener.get(mo); 303 if (l != null) { 304 return l.remove(listener); 305 } 306 } 307 return false; 308 } 309 310 public synchronized void addContextListener(ContextListener l) { 311 if (contextListeners == null) { 312 contextListeners = new Vector(2); 313 } 314 contextListeners.add(l); 315 } 316 317 public synchronized void removeContextListener(ContextListener l) { 318 if (contextListeners != null) { 319 contextListeners.remove(l); 320 } 321 } 322 323 protected void fireContextChanged(ContextEvent event) { 324 if (contextListeners != null) { 325 Vector listeners = contextListeners; 326 int count = listeners.size(); 327 for (int i = 0; i < count; i++) { 328 ((ContextListener) listeners.elementAt(i)).contextChanged(event); 329 } 330 } 331 } 332 333 public String toString() { 334 StringBuffer buf = new StringBuffer (getClass().getName()); 335 buf.append("[contexts="+contexts); 336 buf.append("[keys={"); 337 for (Iterator it = registry.keySet().iterator(); it.hasNext();) { 338 MOScope scope = (MOScope) it.next(); 339 buf.append(scope.getLowerBound()); 340 if (scope.isLowerIncluded()) { 341 buf.append("+"); 342 } 343 buf.append("-"); 344 buf.append(scope.getUpperBound()); 345 if (scope.isUpperIncluded()) { 346 buf.append("+"); 347 } 348 if (scope instanceof MOContextScope) { 349 buf.append("("+((MOContextScope)scope).getContext()+")"); 350 } 351 if (it.hasNext()) { 352 buf.append(","); 353 } 354 } 355 buf.append("}"); 356 buf.append(",registry="+registry); 357 buf.append(",lockList="+lockList); 358 buf.append(",lookupListener="+lookupListener); 359 buf.append("]"); 360 return buf.toString(); 361 } 362 363 static class Lock { 364 private Object owner; 365 private long creationTime; 366 private int count = 0; 367 368 private Lock() { 369 this.creationTime = System.currentTimeMillis(); 370 this.count = 0; 371 } 372 373 Lock(Object owner) { 374 this(); 375 this.owner = owner; 376 } 377 378 public long getCreationTime() { 379 return creationTime; 380 } 381 382 public int getCount() { 383 return count; 384 } 385 386 public synchronized void add() { 387 count++; 388 } 389 390 public synchronized boolean remove() { 391 return (--count) <= 0; 392 } 393 394 public Object getOwner() { 395 return owner; 396 } 397 } 398 399 } 400 | Popular Tags |