KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snmp4j > agent > DefaultMOServer


1 /*_############################################################################
2   _##
3   _## SNMP4J-Agent - DefaultMOServer.java
4   _##
5   _## Copyright (C) 2005-2007 Frank Fock (SNMP4J.org)
6   _##
7   _## Licensed under the Apache License, Version 2.0 (the "License");
8   _## you may not use this file except in compliance with the License.
9   _## You may obtain a copy of the License at
10   _##
11   _## http://www.apache.org/licenses/LICENSE-2.0
12   _##
13   _## Unless required by applicable law or agreed to in writing, software
14   _## distributed under the License is distributed on an "AS IS" BASIS,
15   _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   _## See the License for the specific language governing permissions and
17   _## limitations under the License.
18   _##
19   _##########################################################################*/

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 /**
32  * The default MO server implementation uses a sorted map for the managed object
33  * registry.
34  * @author Frank Fock
35  * @version 1.1
36  */

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 JavaDoc 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   /**
85    * Returns the <code>ManagedObject</code> with the specified <code>OID</code>
86    * and registered in the supplied context.
87    * <p>
88    * Note: The query used to lookup the managed object will indicate an intended
89    * read-only access for the {@link MOServerLookupEvent}s fired on behalf of
90    * this method.
91    * @param key
92    * the OID identifying the key (lower bound) of the
93    * <code>ManagedObject</code>.
94    * @param context
95    * the optional context to look in. A <code>null</code> value searches
96    * in all contexts.
97    * @return
98    * the <code>ManagedObject</code> instance or <code>null</code> if such
99    * an instance does not exists.
100    * @since 1.1
101    */

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 JavaDoc r = registry.remove(key);
190     if (r == null) {
191       // OK, may be the upper bound of the scope has been adjusted so we need to
192
// check that by iterating
193
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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc toString() {
334     StringBuffer JavaDoc buf = new StringBuffer JavaDoc(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 JavaDoc 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 JavaDoc 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 JavaDoc getOwner() {
395       return owner;
396     }
397   }
398
399 }
400
Popular Tags