KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snmp4j > agent > mo > MOScalar


1 /*_############################################################################
2   _##
3   _## SNMP4J-Agent - MOScalar.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 package org.snmp4j.agent.mo;
23
24 import java.io.*;
25 import java.util.*;
26
27 import org.snmp4j.agent.*;
28 import org.snmp4j.agent.io.*;
29 import org.snmp4j.agent.request.*;
30 import org.snmp4j.mp.*;
31 import org.snmp4j.smi.*;
32
33 /**
34  * The <code>MOScalar</code> class represents scalar SNMP managed objects.
35  *
36  * @author Frank Fock
37  * @version 1.0
38  */

39 public class MOScalar implements ManagedObject, MOScope,
40     SerializableManagedObject {
41
42   private OID oid;
43   private volatile OID lowerBound;
44   private volatile OID upperBound;
45   private Variable value;
46   private MOAccess access;
47   private boolean isVolatile;
48   private transient Vector moValueValidationListeners;
49   private transient Vector moChangeListeners;
50
51   /**
52    * Creates a scalar MO instance with OID, maximum access level and initial
53    * value.
54    * @param id
55    * the instance OID of the scalar instance (last sub-identifier should be
56    * zero).
57    * @param access
58    * the maximum access level supported by this instance.
59    * @param value
60    * the initial value of the scalar instance. If the initial value is
61    * <code>null</code> or a Counter syntax, the scalar is created as a
62    * volatile (non-persistent) instance by default.
63    */

64   public MOScalar(OID id, MOAccess access, Variable value) {
65     this.oid = id;
66     this.access = access;
67     this.value = value;
68     this.isVolatile = isVolatileByDefault(value);
69   }
70
71   private static boolean isVolatileByDefault(Variable value) {
72     if (value == null) {
73       return true;
74     }
75     switch (value.getSyntax()) {
76       case SMIConstants.SYNTAX_COUNTER32:
77       case SMIConstants.SYNTAX_COUNTER64: {
78         return true;
79       }
80       default:
81         return false;
82     }
83   }
84
85   /**
86    * Returns the scope of OIDs that are covered by this scalar's object
87    * registration. This range is
88    * <code>1.3.6...n</code> <= x < <code>1.3.6...n+1</code> where n is the
89    * last subidentifier of the OID registred by the corresponding OBJECT-TYPE
90    * definition. Prior to version 1.1.2, this method returned a scope equal
91    * to the scope now returned by {@link #getSingleInstanceScope()}.
92    *
93    * @return
94    * a MOScope that covers the OIDs by this scalar object registration.
95    */

96   public MOScope getScope() {
97     return this;
98   }
99
100   /**
101    * Returns a scope that covers only the scalar instance itself without any
102    * possible OIDs down in the tree or at the same level.
103    * @return
104    * a scope that covers exactly the OID of this scalar.
105    * @since 1.1.2
106    */

107   public MOScope getSingleInstanceScope() {
108     return new DefaultMOScope(oid, true, oid, true);
109   }
110
111   public OID find(MOScope range) {
112     if (access.isAccessibleForRead() &&
113         range.isCovered(getSingleInstanceScope())) {
114       return oid;
115     }
116     return null;
117   }
118
119   public void get(SubRequest request) {
120     RequestStatus status = request.getStatus();
121     if (checkRequestScope(request)) {
122       if (access.isAccessibleForRead()) {
123         VariableBinding vb = request.getVariableBinding();
124         vb.setOid(getOid());
125         vb.setVariable((Variable) getValue().clone());
126         request.completed();
127       }
128       else {
129         status.setErrorStatus(SnmpConstants.SNMP_ERROR_NO_ACCESS);
130       }
131     }
132   }
133
134   private boolean checkRequestScope(SubRequest request) {
135     if (!request.getVariableBinding().getOid().equals(oid)) {
136       VariableBinding vb = request.getVariableBinding();
137       vb.setOid(getOid());
138       vb.setVariable(Null.noSuchInstance);
139       request.completed();
140       return false;
141     }
142     return true;
143   }
144
145   public boolean next(SubRequest request) {
146     if (access.isAccessibleForRead() &&
147         (request.getScope().isCovered(getSingleInstanceScope()))) {
148       VariableBinding vb = request.getVariableBinding();
149       vb.setOid(getOid());
150       vb.setVariable((Variable)getValue().clone());
151       request.completed();
152       return true;
153     }
154     return false;
155   }
156
157   /**
158    * Checks whether the new value contained in the supplied sub-request is a
159    * valid value for this object. The checks are performed by firing a
160    * {@link MOValueValidationEvent} the registered listeners.
161    *
162    * @param request
163    * the <code>SubRequest</code> with the new value.
164    * @return
165    * {@link SnmpConstants#SNMP_ERROR_SUCCESS} if the new value is OK,
166    * any other appropriate SNMPv2/v3 error status if not.
167    */

168   public int isValueOK(SubRequest request) {
169     if (moValueValidationListeners != null) {
170       Variable oldValue = value;
171       Variable newValue =
172            request.getVariableBinding().getVariable();
173       MOValueValidationEvent event =
174           new MOValueValidationEvent(this, oldValue, newValue);
175       fireValidate(event);
176       return event.getValidationStatus();
177     }
178     return SnmpConstants.SNMP_ERROR_SUCCESS;
179   }
180
181   public void prepare(SubRequest request) {
182     RequestStatus status = request.getStatus();
183     if (oid.equals(request.getVariableBinding().getOid())) {
184       if (access.isAccessibleForWrite()) {
185         VariableBinding vb = request.getVariableBinding();
186         if (vb.getVariable().getSyntax() != getValue().getSyntax()) {
187           status.setErrorStatus(SnmpConstants.SNMP_ERROR_WRONG_TYPE);
188           return;
189         }
190         if (moChangeListeners != null) {
191           MOChangeEvent event =
192               new MOChangeEvent(this, this,
193                                 request.getVariableBinding().getOid(),
194                                 getValue(),
195                                 request.getVariableBinding().getVariable(),
196                                 true);
197           fireBeforePrepareMOChange(event);
198           if (event.getDenyReason() != SnmpConstants.SNMP_ERROR_SUCCESS) {
199             status.setErrorStatus(event.getDenyReason());
200             status.setPhaseComplete(true);
201             return;
202           }
203         }
204         int valueOK = isValueOK(request);
205         if ((moChangeListeners != null) &&
206             (valueOK == SnmpConstants.SNMP_ERROR_SUCCESS)) {
207           MOChangeEvent event =
208               new MOChangeEvent(this, this,
209                                 request.getVariableBinding().getOid(),
210                                 getValue(),
211                                 request.getVariableBinding().getVariable(),
212                                 true);
213           fireAfterPrepareMOChange(event);
214           valueOK = event.getDenyReason();
215         }
216         status.setErrorStatus(valueOK);
217         status.setPhaseComplete(true);
218       }
219       else {
220         status.setErrorStatus(SnmpConstants.SNMP_ERROR_NOT_WRITEABLE);
221       }
222     }
223     else {
224       status.setErrorStatus(SnmpConstants.SNMP_ERROR_NO_CREATION);
225     }
226   }
227
228   public void commit(SubRequest request) {
229     RequestStatus status = request.getStatus();
230     VariableBinding vb = request.getVariableBinding();
231     if (moChangeListeners != null) {
232       MOChangeEvent event =
233           new MOChangeEvent(this, this, vb.getOid(), getValue(),
234                             vb.getVariable(), false);
235       fireBeforeMOChange(event);
236     }
237     request.setUndoValue(getValue());
238     setValue(vb.getVariable());
239     status.setPhaseComplete(true);
240     if (moChangeListeners != null) {
241       MOChangeEvent event =
242           new MOChangeEvent(this, this, request.getVariableBinding().getOid(),
243                             (Variable)request.getUndoValue(),
244                             vb.getVariable(), false);
245       fireAfterMOChange(event);
246     }
247   }
248
249   public void undo(SubRequest request) {
250     RequestStatus status = request.getStatus();
251     if ((request.getUndoValue() != null) &&
252         (request.getUndoValue() instanceof Variable)) {
253       int errorStatus = setValue((Variable)request.getUndoValue());
254       status.setErrorStatus(errorStatus);
255       status.setPhaseComplete(true);
256     }
257     else {
258       status.setErrorStatus(SnmpConstants.SNMP_ERROR_UNDO_FAILED);
259     }
260   }
261
262   public void cleanup(SubRequest request) {
263     request.setUndoValue(null);
264     request.getStatus().setPhaseComplete(true);
265   }
266
267   /**
268    * Gets the instance OID of this scalar managed object.
269    * @return
270    * the instance OID (by reference).
271    */

272   public OID getOid() {
273     return oid;
274   }
275
276   public OID getLowerBound() {
277     if (lowerBound == null) {
278       lowerBound = new OID(oid.getValue(), 0, oid.size()-1);
279     }
280     return lowerBound;
281   }
282
283   public OID getUpperBound() {
284     if (upperBound == null) {
285       upperBound = new OID(getLowerBound().nextPeer());
286     }
287     return upperBound;
288   }
289
290   public boolean isCovered(MOScope other) {
291     return (other.getLowerBound().startsWith(oid) &&
292             (other.getLowerBound().size() > oid.size() ||
293              other.isLowerIncluded())) &&
294             (other.getUpperBound().startsWith(oid) &&
295              ((other.getUpperBound().size() > oid.size()) ||
296               other.isUpperIncluded()));
297   }
298
299   public boolean isLowerIncluded() {
300     return false;
301   }
302
303   public boolean isUpperIncluded() {
304     return false;
305   }
306
307   /**
308    * Returns the actual value of this scalar managed object. For a basic
309    * instrumentation, overwrite this method to provide always the actual
310    * value and/or to update the internal <code>value</code> member and
311    * call <code>super.</code>{@link #getValue()}.
312    *
313    * @return
314    * a non <code>null</code> Variable with the same syntax defined for
315    * this scalar object.
316    */

317   public Variable getValue() {
318     return value;
319   }
320
321   public boolean isVolatile() {
322     return isVolatile;
323   }
324
325   /**
326    * Sets the value of this scalar managed object without checking it for
327    * the correct syntax.
328    * @param value
329    * a Variable with the with the same syntax defined for
330    * this scalar object (not checked).
331    * @return
332    * a SNMP error code (zero indicating success by default).
333    */

334   public int setValue(Variable value) {
335     this.value = value;
336     return SnmpConstants.SNMP_ERROR_SUCCESS;
337   }
338
339   /**
340    * Sets the volatile flag for this instance.
341    * @param isVolatile
342    * if <code>true</code> the state of this object will not be persistently
343    * stored, otherwise the agent may save the state of this object
344    * persistently.
345    */

346   public void setVolatile(boolean isVolatile) {
347     this.isVolatile = isVolatile;
348   }
349
350   public boolean isOverlapping(MOScope other) {
351     return DefaultMOScope.overlaps(this, other);
352   }
353
354   /**
355    * Adds a value validation listener to check new values.
356    * @param l
357    * a <code>MOValueValidationListener</code> instance.
358    */

359   public synchronized void addMOValueValidationListener(
360       MOValueValidationListener l) {
361       if (moValueValidationListeners == null) {
362         moValueValidationListeners = new Vector(2);
363       }
364       moValueValidationListeners.add(l);
365   }
366
367   /**
368    * Removes a value validation listener
369    * @param l
370    * a <code>MOValueValidationListener</code> instance.
371    */

372   public synchronized void removeMOValueValidationListener(
373       MOValueValidationListener l) {
374       if (moValueValidationListeners != null) {
375         moValueValidationListeners.remove(l);
376       }
377   }
378
379   protected void fireValidate(MOValueValidationEvent validationEvent) {
380     if (moValueValidationListeners != null) {
381       Vector listeners = moValueValidationListeners;
382       int count = listeners.size();
383       for (int i = 0; i < count; i++) {
384         ((MOValueValidationListener) listeners.elementAt(i)).validate(
385             validationEvent);
386       }
387     }
388   }
389
390   public OID getID() {
391     return getOid();
392   }
393
394   public synchronized void load(MOInput input) throws IOException {
395     Variable v = input.readVariable();
396     setValue(v);
397   }
398
399   public synchronized void save(MOOutput output) throws IOException {
400     output.writeVariable(value);
401   }
402
403   public boolean covers(OID oid) {
404     return oid.startsWith(this.oid);
405   }
406
407   public String JavaDoc toString() {
408     return getClass().getName()+"[oid="+getOid()+",access="+access+
409         ",value="+getValue()+
410         ",volatile="+isVolatile()+toStringDetails()+"]";
411   }
412
413   protected String JavaDoc toStringDetails() {
414     return "";
415   }
416
417   /**
418    * Adds a <code>MOChangeListener</code> that needs to be informed about
419    * state changes of this scalar.
420    * @param l
421    * a <code>MOChangeListener</code> instance.
422    * @since 1.1
423    */

424   public synchronized void addMOChangeListener(MOChangeListener l) {
425     if (moChangeListeners == null) {
426       moChangeListeners = new Vector(2);
427     }
428     moChangeListeners.add(l);
429   }
430
431   /**
432    * Removes a <code>MOChangeListener</code>.
433    * @param l
434    * a <code>MOChangeListener</code> instance.
435    * @since 1.1
436    */

437   public synchronized void removeMOChangeListener(MOChangeListener l) {
438     if (moChangeListeners != null) {
439       moChangeListeners.remove(l);
440     }
441   }
442
443   protected void fireBeforePrepareMOChange(MOChangeEvent changeEvent) {
444     if (moChangeListeners != null) {
445       Vector listeners = moChangeListeners;
446       int count = listeners.size();
447       for (int i = 0; i < count; i++) {
448         ((MOChangeListener) listeners.get(i)).beforePrepareMOChange(
449             changeEvent);
450       }
451     }
452   }
453
454   protected void fireAfterPrepareMOChange(MOChangeEvent changeEvent) {
455     if (moChangeListeners != null) {
456       Vector listeners = moChangeListeners;
457       int count = listeners.size();
458       for (int i = 0; i < count; i++) {
459         ((MOChangeListener) listeners.get(i)).afterPrepareMOChange(changeEvent);
460       }
461     }
462   }
463
464   protected void fireBeforeMOChange(MOChangeEvent changeEvent) {
465     if (moChangeListeners != null) {
466       Vector listeners = moChangeListeners;
467       int count = listeners.size();
468       for (int i = 0; i < count; i++) {
469         ((MOChangeListener) listeners.get(i)).beforeMOChange(changeEvent);
470       }
471     }
472   }
473
474   protected void fireAfterMOChange(MOChangeEvent changeEvent) {
475     if (moChangeListeners != null) {
476       Vector listeners = moChangeListeners;
477       int count = listeners.size();
478       for (int i = 0; i < count; i++) {
479         ((MOChangeListener) listeners.get(i)).afterMOChange(changeEvent);
480       }
481     }
482   }
483 }
484
Popular Tags