2.2.4 Bulk Getters and Setters
The DynamicMBean interface includes bulk getter and setter methods for reading
or writing more than one attribute at once. These methods rely on the classes
shown in Table 2-2.
Table 2-2 Bulk Getter and Setter Classes
Class Name | Description |
Attribute | A simple object that contains the name string and value object
of any attribute |
AttributeList | A dynamically extendable list of Attribute objects (extends java.util.ArrayList) |
The AttributeList class extends the java.util.ArrayList class.
The bulk getter and setter methods usually rely on the generic getter
and setter, respectively. This makes them independent of the management interface,
which can simplify certain modifications. In this case, their implementation
consists mostly of error checking on the list of attributes. However, all
bulk getters and setters must be implemented so that an error on any one attribute
does not interrupt or invalidate the bulk operation on the other attributes.
If an attribute cannot be read, then its name-value pair is not included
in the list of results. If an attribute cannot be written, it will not be
copied to the returned list of successful set operations. As a result, if
there are any errors, the lists returned by bulk operators will not have the
same length as the array or list passed to them. In any case, the bulk operators do not guarantee that their returned lists have the same ordering
of attributes as the input array or list.
The SimpleDynamic MBean shows one way of implementing
the bulk getter and setter methods.
Example 2-5 Implementation of the Bulk Getter and Setter Methods
public AttributeList getAttributes(String[] attributeNames) {
// Check attributeNames to avoid NullPointerException later on
if (attributeNames == null) {
throw new RuntimeOperationsException(
new IllegalArgumentException(
"attributeNames[] cannot be null"),
"Cannot invoke a getter of " + dClassName);
}
AttributeList resultList = new AttributeList();
// if attributeNames is empty, return an empty result list
if (attributeNames.length == 0)
return resultList;
// build the result attribute list
for (int i=0 ; i<attributeNames.length ; i++){
try {
Object value = getAttribute((String) attributeNames[i]);
resultList.add(new Attribute(attributeNames[i],value));
} catch (Exception e) {
// print debug info but continue processing list
e.printStackTrace();
}
}
return(resultList);
}
public AttributeList setAttributes(AttributeList attributes) {
// Check attributes to avoid NullPointerException later on
if (attributes == null) {
throw new RuntimeOperationsException(
new IllegalArgumentException(
"AttributeList attributes cannot be null"),
"Cannot invoke a setter of " + dClassName);
}
AttributeList resultList = new AttributeList();
// if attributeNames is empty, nothing more to do
if (attributes.isEmpty())
return resultList;
// try to set each attribute and add to result list if successful
for (Iterator i = attributes.iterator(); i.hasNext();) {
Attribute attr = (Attribute) i.next();
try {
setAttribute(attr);
String name = attr.getName();
Object value = getAttribute(name);
resultList.add(new Attribute(name,value));
} catch(Exception e) {
// print debug info but keep processing list
e.printStackTrace();
}
}
return(resultList);
}
|
2.2.5 Generic Operation Invoker
A dynamic MBean must implement
the invoke method so that operations in the management
interface can be called. This method requires the same considerations as the
generic getter and setter:
Operations and their parameters must be correctly mapped to
their internal representation and the result must be returned.
Operation names and parameter types must be verified.
These verifications are usually hard-coded, again making modifications
to the management interface more difficult than in a standard MBean.
The implementation in the SimpleDynamic MBean
is relatively simple due to the one operation with no parameters.
Example 2-6 Implementation of the invoke Method
public Object invoke(
String operationName, Object params[], String signature[])
throws MBeanException, ReflectionException {
// Check operationName to avoid NullPointerException later on
if (operationName == null) {
throw new RuntimeOperationsException(
new IllegalArgumentException(
"Operation name cannot be null"),
"Cannot invoke a null operation in " + dClassName);
}
// Call the corresponding operation for a recognized name
if (operationName.equals("reset")){
// this code is specific to the internal "reset" method:
reset(); // no parameters to check
return null; // and no return value
} else {
// unrecognized operation name:
throw new ReflectionException(
new NoSuchMethodException(operationName),
"Cannot find the operation " + operationName +
" in " + dClassName);
}
}
// internal variable
private int nbResets = 0;
// internal method for implementing the reset operation
public void reset() {
AttributeChangeNotification acn =
new AttributeChangeNotification(this,
0,
0,
"NbChanges reset",
"NbChanges",
"Integer",
new Integer(nbChanges),
new Integer(0));
state = "initial state";
nbChanges = 0;
nbResets++;
sendNotification(acn);
}
|
|